--- _CVS_cURL_orig_jan/curl/lib/connect.c	2007-11-05 10:45:09.000000000 +0100
+++ _CVS_cURL_modif_jan/curl/lib/connect.c	2008-01-02 15:13:19.000000000 +0100
@@ -35,7 +35,7 @@
 #include <netinet/in.h> /* <netinet/tcp.h> may need it */
 #endif
 #ifdef HAVE_NETINET_TCP_H
-#include <netinet/tcp.h> /* for TCP_NODELAY */
+#include <netinet/tcp.h> /* for TCP_NODELAY (and TCP_KEEPCNT, TCP_KEEPIDLE, TCP_INTVL, if defined) */
 #endif
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
@@ -644,6 +644,87 @@
 #endif
 }
 
+static void tcpkeepcnt(struct connectdata *conn,
+                       curl_socket_t sockfd)
+{
+#ifdef TCP_KEEPCNT
+  struct SessionHandle *data= conn->data;
+  /* tcp_keepcnt has been converted to an int with str2num, so here is a conversion from int to socklen_t : problem ? */
+  socklen_t keepcnt = (socklen_t) data->set.tcp_keepcnt;
+  int proto = IPPROTO_TCP;
+
+#ifdef HAVE_GETPROTOBYNAME
+  struct protoent *pe = getprotobyname("tcp");
+  if(pe)
+    proto = pe->p_proto;
+#endif
+
+  if(setsockopt(sockfd, proto, TCP_KEEPCNT, (void *)&keepcnt,
+                sizeof(keepcnt)) < 0)
+    infof(data, "Could not set TCP_KEEPCNT: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+  else
+    infof(data,"TCP_KEEPCNT set\n");
+#else
+  (void)conn;
+  (void)sockfd;
+#endif
+}
+
+static void tcpkeepidle(struct connectdata *conn,
+                       curl_socket_t sockfd)
+{
+#ifdef TCP_KEEPIDLE
+  struct SessionHandle *data= conn->data;
+  /* tcp_keepidle has been converted to an int with str2num, so here is a conversion from int to socklen_t : problem ? */
+  socklen_t keepidle = (socklen_t) data->set.tcp_keepidle;
+  int proto = IPPROTO_TCP;
+
+#ifdef HAVE_GETPROTOBYNAME
+  struct protoent *pe = getprotobyname("tcp");
+  if(pe)
+    proto = pe->p_proto;
+#endif
+
+  if(setsockopt(sockfd, proto, TCP_KEEPIDLE, (void *)&keepidle,
+                sizeof(keepidle)) < 0)
+    infof(data, "Could not set TCP_KEEPIDLE: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+  else
+    infof(data,"TCP_KEEPIDLE set\n");
+#else
+  (void)conn;
+  (void)sockfd;
+#endif
+}
+
+static void tcpkeepintvl(struct connectdata *conn,
+                       curl_socket_t sockfd)
+{
+#ifdef TCP_KEEPINTVL
+  struct SessionHandle *data= conn->data;
+  /* tcp_keepintvl has been converted to an int with str2num, so here is a conversion from int to socklen_t : problem ? */
+  socklen_t keepintvl = (socklen_t) data->set.tcp_keepintvl;
+  int proto = IPPROTO_TCP;
+
+#ifdef HAVE_GETPROTOBYNAME
+  struct protoent *pe = getprotobyname("tcp");
+  if(pe)
+    proto = pe->p_proto;
+#endif
+
+  if(setsockopt(sockfd, proto, TCP_KEEPINTVL, (void *)&keepintvl,
+                sizeof(keepintvl)) < 0)
+    infof(data, "Could not set TCP_KEEPINTVL: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+  else
+    infof(data,"TCP_KEEPINTVL set\n");
+#else
+  (void)conn;
+  (void)sockfd;
+#endif
+}
+
 #ifdef SO_NOSIGPIPE
 /* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
    sending data to a dead peer (instead of relying on the 4th argument to send
@@ -721,6 +802,15 @@
   if(data->set.tcp_nodelay)
     tcpnodelay(conn, sockfd);
 
+  if(data->set.tcp_keepcnt)
+    tcpkeepcnt(conn, sockfd);
+
+  if(data->set.tcp_keepidle)
+    tcpkeepidle(conn, sockfd);
+
+  if(data->set.tcp_keepintvl)
+    tcpkeepintvl(conn, sockfd);
+
   nosigpipe(conn, sockfd);
 
   if(data->set.fsockopt) {
