Commit c4d7c151 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

tcpkeepalive: support TCP_KEEPIDLE/TCP_KEEPINTVL on win32

Patch by: Robert Wruck
Bug: http://curl.haxx.se/bug/view.cgi?id=1209
parent e839e7c6
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -87,13 +87,23 @@

static bool verifyconnect(curl_socket_t sockfd, int *error);

#ifdef __DragonFly__
/* DragonFlyBSD uses millisecond as KEEPIDLE and KEEPINTVL units */
#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
/* DragonFlyBSD and Windows use millisecond units */
#define KEEPALIVE_FACTOR(x) (x *= 1000)
#else
#define KEEPALIVE_FACTOR(x)
#endif

#if defined(HAVE_WINSOCK_H) && !defined(SIO_KEEPALIVE_VALS)
#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)

struct tcp_keepalive {
  u_long onoff;
  u_long keepalivetime;
  u_long keepaliveinterval;
};
#endif

static void
tcpkeepalive(struct SessionHandle *data,
             curl_socket_t sockfd)
@@ -106,6 +116,22 @@ tcpkeepalive(struct SessionHandle *data,
    infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
  }
  else {
#if defined(SIO_KEEPALIVE_VALS)
    struct tcp_keepalive vals;
    DWORD dummy;
    vals.onoff = 1;
    optval = curlx_sltosi(data->set.tcp_keepidle);
    KEEPALIVE_FACTOR(optval);
    vals.keepalivetime = optval;
    optval = curlx_sltosi(data->set.tcp_keepintvl);
    KEEPALIVE_FACTOR(optval);
    vals.keepaliveinterval = optval;
    if (WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
                 NULL, 0, &dummy, NULL, NULL) != 0) {
      infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
            (int)sockfd, WSAGetLastError());
    }
#else
#ifdef TCP_KEEPIDLE
    optval = curlx_sltosi(data->set.tcp_keepidle);
    KEEPALIVE_FACTOR(optval);
@@ -121,6 +147,7 @@ tcpkeepalive(struct SessionHandle *data,
          (void *)&optval, sizeof(optval)) < 0) {
      infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
    }
#endif
#endif
  }
}