Keepalive values can be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this unless you know what you're doing (default are RFC1122 compliant). Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.

Old TCP_KEEPALIVE can always be used, and its only difference with TCP_KEEPIDLE is this last use seconds and not milliseconds with setsockopt.

Some documentation (not perfect, but...):

http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.commtechref/doc/commtrf2/setsockopt.htm
This commit is contained in:
fbernon 2007-03-11 15:53:43 +00:00
parent 41a84ef1d3
commit 5c65d4733b
7 changed files with 97 additions and 21 deletions

View File

@ -22,6 +22,12 @@ HISTORY
* [Enter new changes just after this line - do not remove this line]
++ New features:
2007-03-11 Frédéric Bernon
* tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
unless you know what you're doing (default are RFC1122 compliant). Note
that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.
2007-03-08 Frédéric Bernon
* tcp.h: Keepalive values can be configured at compile time, but don't change

View File

@ -1055,6 +1055,11 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
switch( optname ) {
case TCP_NODELAY:
case TCP_KEEPALIVE:
#if LWIP_TCP_KEEPALIVE
case TCP_KEEPIDLE:
case TCP_KEEPINTVL:
case TCP_KEEPCNT:
#endif /* LWIP_TCP_KEEPALIVE */
break;
default:
@ -1157,9 +1162,25 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );
break;
case TCP_KEEPALIVE:
*(int*)optval = (int)sock->conn->pcb.tcp->keepalive;
*(int*)optval = (int)sock->conn->pcb.tcp->keep_idle;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));
break;
#if LWIP_TCP_KEEPALIVE
case TCP_KEEPIDLE:
*(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", s, *(int *)optval));
break;
case TCP_KEEPINTVL:
*(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", s, *(int *)optval));
break;
case TCP_KEEPCNT:
*(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", s, *(int *)optval));
break;
#endif /* LWIP_TCP_KEEPALIVE */
} /* switch */
break;
}
@ -1252,6 +1273,11 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
switch( optname ) {
case TCP_NODELAY:
case TCP_KEEPALIVE:
#if LWIP_TCP_KEEPALIVE
case TCP_KEEPIDLE:
case TCP_KEEPINTVL:
case TCP_KEEPCNT:
#endif /* LWIP_TCP_KEEPALIVE */
break;
default:
@ -1334,9 +1360,25 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(int *)optval)?"on":"off") );
break;
case TCP_KEEPALIVE:
sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));
sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keep_idle));
break;
#if LWIP_TCP_KEEPALIVE
case TCP_KEEPIDLE:
sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %lu\n", s, sock->conn->pcb.tcp->keep_idle));
break;
case TCP_KEEPINTVL:
sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %lu\n", s, sock->conn->pcb.tcp->keep_intvl));
break;
case TCP_KEEPCNT:
sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %lu\n", s, sock->conn->pcb.tcp->keep_cnt));
break;
#endif /* LWIP_TCP_KEEPALIVE */
} /* switch */
break;
} /* switch */

View File

@ -537,16 +537,24 @@ tcp_slowtmr(void)
/* Check if KEEPALIVE should be sent */
if((pcb->so_options & SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) {
#if LWIP_TCP_KEEPALIVE
if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl)) / TCP_SLOW_INTERVAL) {
#else
if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keep_idle + TCP_MAXIDLE ) / TCP_SLOW_INTERVAL) {
#endif /* LWIP_TCP_KEEPALIVE */
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
tcp_abort(pcb);
}
else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + pcb->keep_cnt * TCP_KEEPINTVL) / TCP_SLOW_INTERVAL) {
#if LWIP_TCP_KEEPALIVE
else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl) / TCP_SLOW_INTERVAL) {
#else
else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) / TCP_SLOW_INTERVAL) {
#endif /* LWIP_TCP_KEEPALIVE */
tcp_keepalive(pcb);
pcb->keep_cnt++;
pcb->keep_cnt_sent++;
}
}
@ -853,8 +861,14 @@ tcp_alloc(u8_t prio)
#endif /* LWIP_CALLBACK_API */
/* Init KEEPALIVE timer */
pcb->keepalive = TCP_KEEPDEFAULT;
pcb->keep_cnt = 0;
pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
#if LWIP_TCP_KEEPALIVE
pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
#endif /* LWIP_TCP_KEEPALIVE */
pcb->keep_cnt_sent = 0;
}
return pcb;
}

View File

@ -476,7 +476,7 @@ tcp_process(struct tcp_pcb *pcb)
/* Update the PCB (in)activity timer. */
pcb->tmr = tcp_ticks;
pcb->keep_cnt = 0;
pcb->keep_cnt_sent = 0;
/* Do different things depending on the TCP state. */
switch (pcb->state) {
@ -825,7 +825,7 @@ tcp_receive(struct tcp_pcb *pcb)
pcb->sv += m;
pcb->rto = (pcb->sa >> 3) + pcb->sv;
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" miliseconds)\n",
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
pcb->rttest = 0;

View File

@ -683,7 +683,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);

View File

@ -420,6 +420,12 @@ a lot of data that needs to be copied, this should be set high. */
#define LWIP_POSIX_SOCKETS_IO_NAMES 1
#endif
/* Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT options processing.
Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. */
#ifndef LWIP_TCP_KEEPALIVE
#define LWIP_TCP_KEEPALIVE 0
#endif
/* Enable SO_RCVTIMEO processing (only for UDP sockets) */
#ifndef LWIP_SO_RCVTIMEO
#define LWIP_SO_RCVTIMEO 0

View File

@ -155,22 +155,26 @@ void tcp_rexmit_rto (struct tcp_pcb *pcb);
* User-settable options (used with setsockopt).
*/
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */
#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt*/
#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
#ifndef TCP_KEEPDEFAULT
#define TCP_KEEPDEFAULT 7200000 /* KEEPALIVE timer in miliseconds */
#ifndef TCP_KEEPIDLE_DEFAULT
#define TCP_KEEPIDLE_DEFAULT 7200000 /* Default KEEPALIVE timer in milliseconds */
#endif
#ifndef TCP_KEEPINTVL
#define TCP_KEEPINTVL 75000 /* Time between KEEPALIVE probes in miliseconds */
#ifndef TCP_KEEPINTVL_DEFAULT
#define TCP_KEEPINTVL_DEFAULT 75000 /* Default Time between KEEPALIVE probes in milliseconds */
#endif
#ifndef TCP_KEEPCNT
#define TCP_KEEPCNT 9 /* Counter for KEEPALIVE probes */
#ifndef TCP_KEEPCNT_DEFAULT
#define TCP_KEEPCNT_DEFAULT 9 /* Default Counter for KEEPALIVE probes */
#endif
#define TCP_MAXIDLE TCP_KEEPCNT * TCP_KEEPINTVL /* Maximum KEEPALIVE probe time */
#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
@ -311,10 +315,14 @@ struct tcp_pcb {
#endif /* LWIP_CALLBACK_API */
/* idle time before KEEPALIVE is sent */
u32_t keepalive;
u32_t keep_idle;
#if LWIP_TCP_KEEPALIVE
u32_t keep_intvl;
u32_t keep_cnt;
#endif /* LWIP_TCP_KEEPALIVE */
/* KEEPALIVE counter */
u8_t keep_cnt;
u8_t keep_cnt_sent;
};
struct tcp_pcb_listen {