From: hno <> Date: Fri, 8 Feb 2008 08:56:32 +0000 (+0000) Subject: TCP keepalive support X-Git-Tag: BASIC_TPROXY4~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2130d58e3816ec70c9b06cdbeb7b1ad608eb448;p=thirdparty%2Fsquid.git TCP keepalive support --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 5b419f1996..785cfe3c36 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_cf.cc,v 1.538 2008/01/22 15:34:28 hno Exp $ + * $Id: cache_cf.cc,v 1.539 2008/02/08 01:56:32 hno Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -2914,6 +2914,23 @@ parse_http_port_option(http_port_list * s, char *token) self_destruct(); } #endif + } else if (strcmp(token, "tcpkeepalive") == 0) { + s->tcp_keepalive.enabled = 1; + } else if (strncmp(token, "tcpkeepalive=", 13) == 0) { + char *t = token + 13; + s->tcp_keepalive.enabled = 1; + s->tcp_keepalive.idle = atoi(t); + t = strchr(t, ','); + if (t) { + t++; + s->tcp_keepalive.interval = atoi(t); + t = strchr(t, ','); + } + if (t) { + t++; + s->tcp_keepalive.timeout = atoi(t); + t = strchr(t, ','); + } } else { self_destruct(); } @@ -3007,6 +3024,14 @@ dump_generic_http_port(StoreEntry * e, const char *n, const http_port_list * s) storeAppendPrintf(e, " disable-pmtu-discovery=%s", pmtu); } + + if (s->tcp_keepalive.enabled) { + if (s->tcp_keepalive.idle || s->tcp_keepalive.interval || s->tcp_keepalive.timeout) { + storeAppendPrintf(e, " tcp_keepalive=%d,%d,%d", s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout); + } else { + storeAppendPrintf(e, " tcp_keepalive"); + } + } } static void diff --git a/src/cf.data.pre b/src/cf.data.pre index 3fd01ed178..44ccd56290 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.497 2008/02/06 06:54:14 amosjeffries Exp $ +# $Id: cf.data.pre,v 1.498 2008/02/08 01:56:32 hno Exp $ # # SQUID Web Proxy Cache http://www.squid-cache.org/ # ---------------------------------------------------------- @@ -929,6 +929,12 @@ DOC_START name= Specifies a internal name for the port. Defaults to the port specification (port or addr:port) + keepalive[=idle,interval,timeout] + Enable TCP keepalive probes of idle connections + idle is the initial time before TCP starts probing + the connection, interval how often to probe, and + timeout the time before giving up. + If you run Squid on a dual-homed machine with an internal and an external interface we recommend you to specify the internal address:port in http_port. This way Squid will only be diff --git a/src/client_side.cc b/src/client_side.cc index cbe25d1e05..11c32b56c7 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.773 2008/02/03 10:00:29 amosjeffries Exp $ + * $Id: client_side.cc,v 1.774 2008/02/08 01:56:33 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -2782,6 +2782,10 @@ httpAccept(int sock, int newfd, ConnectionDetail *details, #endif + if (s->tcp_keepalive.enabled) { + commSetTcpKeepalive(newfd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout); + } + connState->readSomeData(); clientdbEstablished(details->peer, 1); @@ -2976,6 +2980,10 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details, #endif + if (s->http.tcp_keepalive.enabled) { + commSetTcpKeepalive(newfd, s->http.tcp_keepalive.idle, s->http.tcp_keepalive.interval, s->http.tcp_keepalive.timeout); + } + commSetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0); clientdbEstablished(details->peer, 1); diff --git a/src/comm.cc b/src/comm.cc index 97382e2a4f..570d762cba 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.442 2008/01/19 07:11:35 amosjeffries Exp $ + * $Id: comm.cc,v 1.443 2008/02/08 01:56:33 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -1956,6 +1956,32 @@ commSetTcpNoDelay(int fd) { #endif +void +commSetTcpKeepalive(int fd, int idle, int interval, int timeout) +{ + int on = 1; +#ifdef TCP_KEEPCNT + if (timeout && interval) { + int count = (timeout + interval - 1) / interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(on)) < 0) + debug(5, 1) ("commSetKeepalive: FD %d: %s\n", fd, xstrerror()); + } +#endif +#ifdef TCP_KEEPIDLE + if (idle) { + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(on)) < 0) + debug(5, 1) ("commSetKeepalive: FD %d: %s\n", fd, xstrerror()); + } +#endif +#ifdef TCP_KEEPINTVL + if (interval) { + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(on)) < 0) + debug(5, 1) ("commSetKeepalive: FD %d: %s\n", fd, xstrerror()); + } +#endif + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) + debug(5, 1) ("commSetKeepalive: FD %d: %s\n", fd, xstrerror()); +} void comm_init(void) { diff --git a/src/comm.h b/src/comm.h index e292eeac21..d0a4fcdb0c 100644 --- a/src/comm.h +++ b/src/comm.h @@ -39,6 +39,7 @@ extern int comm_listen(int fd); SQUIDCEXTERN int commSetNonBlocking(int fd); SQUIDCEXTERN int commUnsetNonBlocking(int fd); SQUIDCEXTERN void commSetCloseOnExec(int fd); +SQUIDCEXTERN void commSetTcpKeepalive(int fd, int idle, int interval, int timeout); extern void _comm_close(int fd, char const *file, int line); #define comm_close(fd) (_comm_close((fd), __FILE__, __LINE__)) SQUIDCEXTERN void comm_reset_close(int fd); diff --git a/src/structs.h b/src/structs.h index 29fd112c12..6408727000 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.573 2008/01/19 07:15:30 amosjeffries Exp $ + * $Id: structs.h,v 1.574 2008/02/08 01:56:33 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -147,6 +147,12 @@ unsigned int vhost: unsigned int tproxy: 1; /* spoof client ip using tproxy */ #endif + struct { + unsigned int enabled; + unsigned int idle; + unsigned int interval; + unsigned int timeout; + } tcp_keepalive; };