- per socket keepalive settings
- settable connection establishment timeout
This commit is contained in:
parent
d562fea75e
commit
eeff189533
@ -1,4 +1,4 @@
|
||||
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.875 $>
|
||||
LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.876 $>
|
||||
|
||||
|
||||
[Note: This file does not mention every change made to the NetBSD source tree.
|
||||
@ -134,3 +134,5 @@ Changes from NetBSD 4.0 to NetBSD 5.0:
|
||||
i386: Import AMD Geode LX Security Block driver glxsb(4) from
|
||||
OpenBSD. [jmcneill 20070615]
|
||||
ipf: Updated to v4.1.23 [martin 20070616]
|
||||
tcp(4): Per socket keepalive timer settings. Ability to change
|
||||
connection timeout [christos 20070620].
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: tcp.4,v 1.22 2007/03/15 23:43:18 gdt Exp $
|
||||
.\" $NetBSD: tcp.4,v 1.23 2007/06/20 15:29:17 christos Exp $
|
||||
.\" $FreeBSD: tcp.4,v 1.11.2.16 2004/02/16 22:21:47 bms Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
@ -30,7 +30,7 @@
|
||||
.\"
|
||||
.\" @(#)tcp.4 8.1 (Berkeley) 6/5/93
|
||||
.\"
|
||||
.Dd March 15, 2007
|
||||
.Dd June 19, 2007
|
||||
.Dt TCP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -108,7 +108,7 @@ supports a number of socket options which can be set with
|
||||
.Xr setsockopt 2
|
||||
and tested with
|
||||
.Xr getsockopt 2 :
|
||||
.Bl -tag -width TCP_MD5SIGx
|
||||
.Bl -tag -width TCP_KEEPINTVL
|
||||
.It Dv TCP_NODELAY
|
||||
Under most circumstances,
|
||||
.Tn TCP
|
||||
@ -161,6 +161,92 @@ If an SADB entry cannot be found for the destination, the outgoing traffic
|
||||
will have an invalid digest option prepended, and the following error message
|
||||
will be visible on the system console:
|
||||
.Em "tcp_signature_compute: SADB lookup failed for %d.%d.%d.%d" .
|
||||
.It Dv TCP_KEEPIDLE
|
||||
.\" XXX: We always do it.
|
||||
.\" When the
|
||||
.\" .Dv SO_KEEPALIVE
|
||||
.\" option is enabled,
|
||||
TCP probes a connection that
|
||||
has been idle for some amount of time.
|
||||
The default value for this idle period is 4 hours.
|
||||
The
|
||||
.Dv TCP_KEEPIDLE
|
||||
option can be used to affect this value for a given socket, and specifies
|
||||
the number of seconds of idle time between keepalive probes.
|
||||
This option takes an
|
||||
.Vt "unsigned int"
|
||||
value, with a value greater than 0.
|
||||
.\" range of 1 to N (where N is
|
||||
.\" the
|
||||
.\" .Xr sysctl 8
|
||||
.\" variable
|
||||
.\" .Dv net.inet.tcp.keepidle ).
|
||||
.\" divided by
|
||||
.\" .Dv PR_SLOWHZ
|
||||
.\" which is defined in the
|
||||
.\" .In sys/protosw.h
|
||||
.\" header file).
|
||||
.It Dv TCP_KEEPINTVL
|
||||
When the
|
||||
.Dv SO_KEEPALIVE
|
||||
option is enabled, TCP probes a connection that
|
||||
has been idle for some amount of time.
|
||||
If the remote system does not
|
||||
respond to a keepalive probe, TCP retransmits the probe after some
|
||||
amount of time.
|
||||
The default value for this retransmit interval is 150 seconds.
|
||||
The
|
||||
.Dv TCP_KEEPINTVL
|
||||
option can be used to affect this value for
|
||||
a given socket, and specifies the number of seconds to wait before
|
||||
retransmitting a keepalive probe.
|
||||
This option takes an
|
||||
.Vt "unsigned int"
|
||||
value, with a value greater than 0.
|
||||
.\" range of 1 to N (where N is the
|
||||
.\" .Xr sysctl 8
|
||||
.\" variable
|
||||
.\" .Dv net.inet.tcp.keepintvl ).
|
||||
.It Dv TCP_KEEPCNT
|
||||
When the
|
||||
.Dv SO_KEEPALIVE
|
||||
option is enabled, TCP probes a connection that
|
||||
has been idle for some amount of time.
|
||||
If the remote system does not
|
||||
respond to a keepalive probe, TCP retransmits the probe a certain
|
||||
number of times before a connection is considered to be broken.
|
||||
The default value for this keepalive probe retransmit limit is 8.
|
||||
The
|
||||
.Dv TCP_KEEPCNT
|
||||
option can be used to affect this value for a given socket,
|
||||
and specifies the maximum number of keepalive probes to be sent.
|
||||
This option takes an
|
||||
.Vt "unsigned int"
|
||||
value, with a value greater than 0.
|
||||
.\" range of 0 to N (where N is the
|
||||
.\" .Xr sysctl 8
|
||||
.\" variable
|
||||
.\" .Dv net.inet.tcp.keepcnt ).
|
||||
.It Dv TCP_KEEPINIT
|
||||
If a TCP connection cannot be established within some amount of time,
|
||||
TCP will time out the connect attempt.
|
||||
The default value for this initial connection establishment timeout
|
||||
is 150 seconds.
|
||||
The
|
||||
.Dv TCP_KEEPINIT
|
||||
option can be used to affect this initial timeout period for a given
|
||||
socket, and specifies the number of seconds to wait before the connect
|
||||
attempt is timed out.
|
||||
For passive connections, the
|
||||
.Dv TCP_KEEPINIT
|
||||
option value is inherited from the listening socket.
|
||||
This option takes an
|
||||
.Vt "unsigned int"
|
||||
value, with a value greater than 0.
|
||||
.\" range of 0 to N (where N is the
|
||||
.\" .Xr sysctl 8
|
||||
.\" variable
|
||||
.\" .Dv net.inet.tcp.keepinit ).
|
||||
.El
|
||||
.Pp
|
||||
The option level for the
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: sysctl.7,v 1.11 2007/06/13 20:37:07 tnn Exp $
|
||||
.\" $NetBSD: sysctl.7,v 1.12 2007/06/20 15:29:18 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95
|
||||
.\"
|
||||
.Dd June 13, 2007
|
||||
.Dd June 19, 2007
|
||||
.Dt SYSCTL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -969,6 +969,7 @@ The currently defined protocols and names are:
|
||||
.It tcp keepintvl integer yes
|
||||
.It tcp keepcnt integer yes
|
||||
.It tcp slowhz integer no
|
||||
.It tcp keepinit integer yes
|
||||
.It tcp log_refused integer yes
|
||||
.It tcp rstppslimit integer yes
|
||||
.It tcp ident struct no
|
||||
@ -1184,6 +1185,8 @@ another probe is sent.
|
||||
See also tcp.slowhz.
|
||||
.It Li tcp.log_refused
|
||||
If set to 1, refused TCP connections to the host will be logged.
|
||||
.It Li tcp.keepinit
|
||||
Timeout in seconds during connection establishment.
|
||||
.It Li tcp.mss_ifmtu
|
||||
If set to 1, TCP calculates the outgoing maximum segment size based on
|
||||
the MTU of the appropriate interface.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp.h,v 1.25 2006/10/09 16:27:07 rpaulo Exp $ */
|
||||
/* $NetBSD: tcp.h,v 1.26 2007/06/20 15:29:18 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
@ -112,10 +112,19 @@ struct tcphdr {
|
||||
/*
|
||||
* User-settable options (used with setsockopt).
|
||||
*/
|
||||
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
|
||||
#define TCP_MAXSEG 0x02 /* set maximum segment size */
|
||||
/* Bits 0x04, 0x08 reserved for FreeBSD compatibility: TCP_NOPUSH, TCP_NOOPT */
|
||||
#define TCP_MD5SIG 0x10 /* use MD5 digests (RFC2385) */
|
||||
#define TCP_NODELAY 1 /* don't delay send to coalesce packets */
|
||||
#define TCP_MAXSEG 2 /* set maximum segment size */
|
||||
#define TCP_KEEPIDLE 3
|
||||
#ifdef notyet
|
||||
#define TCP_NOPUSH 4 /* reserved for FreeBSD compat */
|
||||
#endif
|
||||
#define TCP_KEEPINTVL 5
|
||||
#define TCP_KEEPCNT 6
|
||||
#define TCP_KEEPINIT 7
|
||||
#ifdef notyet
|
||||
#define TCP_NOOPT 8 /* reserved for FreeBSD compat */
|
||||
#endif
|
||||
#define TCP_MD5SIG 0x10 /* use MD5 digests (RFC2385) */
|
||||
#define TCP_CONGCTL 0x20 /* selected congestion control */
|
||||
|
||||
#endif /* !_NETINET_TCP_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_input.c,v 1.266 2007/05/18 21:48:43 riz Exp $ */
|
||||
/* $NetBSD: tcp_input.c,v 1.267 2007/06/20 15:29:18 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -152,7 +152,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.266 2007/05/18 21:48:43 riz Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.267 2007/06/20 15:29:18 christos Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -1606,7 +1606,7 @@ after_listen:
|
||||
*/
|
||||
tp->t_rcvtime = tcp_now;
|
||||
if (TCPS_HAVEESTABLISHED(tp->t_state))
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
|
||||
|
||||
/*
|
||||
* Process options.
|
||||
@ -2366,9 +2366,9 @@ after_listen:
|
||||
*/
|
||||
if (so->so_state & SS_CANTRCVMORE) {
|
||||
soisdisconnected(so);
|
||||
if (tcp_maxidle > 0)
|
||||
if (tp->t_maxidle > 0)
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL,
|
||||
tcp_maxidle);
|
||||
tp->t_maxidle);
|
||||
}
|
||||
tp->t_state = TCPS_FIN_WAIT_2;
|
||||
}
|
||||
@ -3377,7 +3377,7 @@ syn_cache_timer(void *arg)
|
||||
* than the keep alive timer would allow, expire it.
|
||||
*/
|
||||
sc->sc_rxttot += sc->sc_rxtcur;
|
||||
if (sc->sc_rxttot >= TCPTV_KEEP_INIT)
|
||||
if (sc->sc_rxttot >= tcp_keepinit)
|
||||
goto dropit;
|
||||
|
||||
tcpstat.tcps_sc_retransmitted++;
|
||||
@ -3713,7 +3713,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst,
|
||||
tcp_sendseqinit(tp);
|
||||
tcp_rcvseqinit(tp);
|
||||
tp->t_state = TCPS_SYN_RECEIVED;
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, TCPTV_KEEP_INIT);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
|
||||
tcpstat.tcps_accepts++;
|
||||
|
||||
if ((sc->sc_flags & SCF_SACK_PERMIT) && tcp_do_sack)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_subr.c,v 1.214 2007/05/02 20:40:25 dyoung Exp $ */
|
||||
/* $NetBSD: tcp_subr.c,v 1.215 2007/06/20 15:29:18 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -98,7 +98,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.214 2007/05/02 20:40:25 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.215 2007/06/20 15:29:18 christos Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -379,9 +379,6 @@ tcp_init(void)
|
||||
{
|
||||
int hlen;
|
||||
|
||||
/* Initialize the TCPCB template. */
|
||||
tcp_tcpcb_template();
|
||||
|
||||
in_pcbinit(&tcbtable, tcbhashsize, tcbhashsize);
|
||||
|
||||
hlen = sizeof(struct ip) + sizeof(struct tcphdr);
|
||||
@ -410,6 +407,9 @@ tcp_init(void)
|
||||
/* Initialize the congestion control algorithms. */
|
||||
tcp_congctl_init();
|
||||
|
||||
/* Initialize the TCPCB template. */
|
||||
tcp_tcpcb_template();
|
||||
|
||||
MOWNER_ATTACH(&tcp_tx_mowner);
|
||||
MOWNER_ATTACH(&tcp_rx_mowner);
|
||||
MOWNER_ATTACH(&tcp_reass_mowner);
|
||||
@ -976,6 +976,13 @@ tcp_tcpcb_template(void)
|
||||
tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << (TCP_RTTVAR_SHIFT + 2 - 1);
|
||||
TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
|
||||
TCPTV_MIN, TCPTV_REXMTMAX);
|
||||
|
||||
/* Keep Alive */
|
||||
tp->t_keepinit = tcp_keepinit;
|
||||
tp->t_keepidle = tcp_keepidle;
|
||||
tp->t_keepintvl = tcp_keepintvl;
|
||||
tp->t_keepcnt = tcp_keepcnt;
|
||||
tp->t_maxidle = tp->t_keepcnt * tp->t_keepintvl;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1049,7 +1056,7 @@ tcp_newtcpcb(int family, void *aux)
|
||||
|
||||
tp->t_congctl = tcp_congctl_global;
|
||||
tp->t_congctl->refcnt++;
|
||||
|
||||
|
||||
return (tp);
|
||||
}
|
||||
|
||||
@ -2016,7 +2023,7 @@ tcp_established(struct tcpcb *tp)
|
||||
#endif
|
||||
|
||||
tp->t_state = TCPS_ESTABLISHED;
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
|
||||
|
||||
#ifdef RTV_RPIPE
|
||||
if (rt != NULL && rt->rt_rmx.rmx_recvpipe != 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_timer.c,v 1.76 2006/10/09 16:27:07 rpaulo Exp $ */
|
||||
/* $NetBSD: tcp_timer.c,v 1.77 2007/06/20 15:29:18 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -100,7 +100,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.76 2006/10/09 16:27:07 rpaulo Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.77 2007/06/20 15:29:18 christos Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_tcp_debug.h"
|
||||
@ -148,11 +148,12 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.76 2006/10/09 16:27:07 rpaulo Exp $"
|
||||
* Various tunable timer parameters. These are initialized in tcp_init(),
|
||||
* unless they are patched.
|
||||
*/
|
||||
int tcp_keepidle = 0;
|
||||
int tcp_keepintvl = 0;
|
||||
int tcp_keepcnt = 0; /* max idle probes */
|
||||
u_int tcp_keepinit = 0;
|
||||
u_int tcp_keepidle = 0;
|
||||
u_int tcp_keepintvl = 0;
|
||||
u_int tcp_keepcnt = 0; /* max idle probes */
|
||||
|
||||
int tcp_maxpersistidle = 0; /* max idle time in persist */
|
||||
int tcp_maxidle; /* computed in tcp_slowtimo() */
|
||||
|
||||
/*
|
||||
* Time to delay the ACK. This is initialized in tcp_init(), unless
|
||||
@ -179,6 +180,9 @@ void
|
||||
tcp_timer_init(void)
|
||||
{
|
||||
|
||||
if (tcp_keepinit == 0)
|
||||
tcp_keepinit = TCPTV_KEEP_INIT;
|
||||
|
||||
if (tcp_keepidle == 0)
|
||||
tcp_keepidle = TCPTV_KEEP_IDLE;
|
||||
|
||||
@ -251,7 +255,6 @@ tcp_slowtimo(void)
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
|
||||
tcp_iss_seq += TCP_ISSINCR; /* increment iss */
|
||||
tcp_now++; /* for timestamps */
|
||||
splx(s);
|
||||
@ -542,9 +545,9 @@ tcp_timer_keep(void *arg)
|
||||
KASSERT(so != NULL);
|
||||
if (so->so_options & SO_KEEPALIVE &&
|
||||
tp->t_state <= TCPS_CLOSE_WAIT) {
|
||||
if ((tcp_maxidle > 0) &&
|
||||
if ((tp->t_maxidle > 0) &&
|
||||
((tcp_now - tp->t_rcvtime) >=
|
||||
tcp_keepidle + tcp_maxidle))
|
||||
tp->t_keepidle + tp->t_maxidle))
|
||||
goto dropit;
|
||||
/*
|
||||
* Send a packet designed to force a response
|
||||
@ -572,9 +575,9 @@ tcp_timer_keep(void *arg)
|
||||
(struct mbuf *)NULL, NULL, tp->rcv_nxt,
|
||||
tp->snd_una - 1, 0);
|
||||
}
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepintvl);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl);
|
||||
} else
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
|
||||
|
||||
#ifdef TCP_DEBUG
|
||||
if (tp && so->so_options & SO_DEBUG)
|
||||
@ -634,8 +637,9 @@ tcp_timer_2msl(void *arg)
|
||||
* control block. Otherwise, check again in a bit.
|
||||
*/
|
||||
if (tp->t_state != TCPS_TIME_WAIT &&
|
||||
((tcp_maxidle == 0) || ((tcp_now - tp->t_rcvtime) <= tcp_maxidle)))
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_keepintvl);
|
||||
((tp->t_maxidle == 0) ||
|
||||
((tcp_now - tp->t_rcvtime) <= tp->t_maxidle)))
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_keepintvl);
|
||||
else
|
||||
tp = tcp_close(tp);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_timer.h,v 1.24 2006/09/26 06:39:22 jeremy Exp $ */
|
||||
/* $NetBSD: tcp_timer.h,v 1.25 2007/06/20 15:29:19 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2005 The NetBSD Foundation, Inc.
|
||||
@ -182,11 +182,11 @@ typedef void (*tcp_timer_func_t)(void *);
|
||||
|
||||
extern const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS];
|
||||
|
||||
extern int tcp_keepidle; /* time before keepalive probes begin */
|
||||
extern int tcp_keepintvl; /* time between keepalive probes */
|
||||
extern int tcp_keepcnt; /* number of keepalives, 0=infty */
|
||||
extern u_int tcp_keepinit; /* time before initial connection times out */
|
||||
extern u_int tcp_keepidle; /* time before keepalive probes begin */
|
||||
extern u_int tcp_keepintvl; /* time between keepalive probes */
|
||||
extern u_int tcp_keepcnt; /* number of keepalives, 0=infty */
|
||||
extern int tcp_maxpersistidle; /* max idle time in persist */
|
||||
extern int tcp_maxidle; /* time to drop after starting probes */
|
||||
extern int tcp_ttl; /* time to live for TCP segs */
|
||||
extern const int tcp_backoff[];
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.131 2007/03/04 06:03:22 christos Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.132 2007/06/20 15:29:19 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -102,7 +102,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.131 2007/03/04 06:03:22 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.132 2007/06/20 15:29:19 christos Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -436,7 +436,7 @@ tcp_usrreq(struct socket *so, int req,
|
||||
soisconnecting(so);
|
||||
tcpstat.tcps_connattempt++;
|
||||
tp->t_state = TCPS_SYN_SENT;
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, TCPTV_KEEP_INIT);
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
|
||||
tp->iss = tcp_new_iss(tp, 0);
|
||||
tcp_sendseqinit(tp);
|
||||
error = tcp_output(tp);
|
||||
@ -614,6 +614,28 @@ release:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
change_keepalive(struct socket *so, struct tcpcb *tp)
|
||||
{
|
||||
tp->t_maxidle = tp->t_keepcnt * tp->t_keepintvl;
|
||||
TCP_TIMER_DISARM(tp, TCPT_KEEP);
|
||||
TCP_TIMER_DISARM(tp, TCPT_2MSL);
|
||||
|
||||
if (tp->t_state == TCPS_SYN_RECEIVED ||
|
||||
tp->t_state == TCPS_SYN_SENT) {
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepinit);
|
||||
} else if (so->so_options & SO_KEEPALIVE &&
|
||||
tp->t_state <= TCPS_CLOSE_WAIT) {
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl);
|
||||
} else {
|
||||
TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle);
|
||||
}
|
||||
|
||||
if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
tcp_ctloutput(int op, struct socket *so, int level, int optname,
|
||||
struct mbuf **mp)
|
||||
@ -626,6 +648,7 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
|
||||
struct tcpcb *tp;
|
||||
struct mbuf *m;
|
||||
int i;
|
||||
u_int ui;
|
||||
int family; /* family of the socket */
|
||||
|
||||
family = so->so_proto->pr_domain->dom_family;
|
||||
@ -715,7 +738,8 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
|
||||
break;
|
||||
|
||||
case TCP_MAXSEG:
|
||||
if (m && (i = *mtod(m, int *)) > 0 &&
|
||||
if (m && m->m_len >= sizeof(int) &&
|
||||
(i = *mtod(m, int *)) > 0 &&
|
||||
i <= tp->t_peermss)
|
||||
tp->t_peermss = i; /* limit on send size */
|
||||
else
|
||||
@ -729,6 +753,42 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TCP_KEEPIDLE:
|
||||
if (m && m->m_len >= sizeof(u_int) &&
|
||||
(ui = *mtod(m, u_int *)) > 0) {
|
||||
tp->t_keepidle = ui;
|
||||
change_keepalive(so, tp);
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
case TCP_KEEPINTVL:
|
||||
if (m && m->m_len >= sizeof(u_int) &&
|
||||
(ui = *mtod(m, u_int *)) > 0) {
|
||||
tp->t_keepintvl = ui;
|
||||
change_keepalive(so, tp);
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
case TCP_KEEPCNT:
|
||||
if (m && m->m_len >= sizeof(u_int) &&
|
||||
(ui = *mtod(m, u_int *)) > 0) {
|
||||
tp->t_keepcnt = ui;
|
||||
change_keepalive(so, tp);
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
case TCP_KEEPINIT:
|
||||
if (m && m->m_len >= sizeof(u_int) &&
|
||||
(ui = *mtod(m, u_int *)) > 0) {
|
||||
tp->t_keepinit = ui;
|
||||
change_keepalive(so, tp);
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOPROTOOPT;
|
||||
break;
|
||||
@ -944,8 +1004,8 @@ tcp_usrclosed(struct tcpcb *tp)
|
||||
* a full close, we start a timer to make sure sockets are
|
||||
* not left in FIN_WAIT_2 forever.
|
||||
*/
|
||||
if ((tp->t_state == TCPS_FIN_WAIT_2) && (tcp_maxidle > 0))
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_maxidle);
|
||||
if ((tp->t_state == TCPS_FIN_WAIT_2) && (tp->t_maxidle > 0))
|
||||
TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
|
||||
}
|
||||
return (tp);
|
||||
}
|
||||
@ -1418,6 +1478,27 @@ sysctl_tcp_congctl(SYSCTLFN_ARGS)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_tcp_keep(SYSCTLFN_ARGS)
|
||||
{
|
||||
int error;
|
||||
u_int tmp;
|
||||
struct sysctlnode node;
|
||||
|
||||
node = *rnode;
|
||||
tmp = *(u_int *)rnode->sysctl_data;
|
||||
node.sysctl_data = &tmp;
|
||||
|
||||
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
||||
if (error || newp == NULL)
|
||||
return error;
|
||||
|
||||
*(u_int *)rnode->sysctl_data = tmp;
|
||||
tcp_tcpcb_template(); /* update the template */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* this (second stage) setup routine is a replacement for tcp_sysctl()
|
||||
* (which is currently used for ipv4 and ipv6)
|
||||
@ -1585,19 +1666,19 @@ sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
|
||||
CTLTYPE_INT, "keepidle",
|
||||
SYSCTL_DESCR("Allowed connection idle ticks before a "
|
||||
"keepalive probe is sent"),
|
||||
NULL, 0, &tcp_keepidle, 0,
|
||||
sysctl_tcp_keep, 0, &tcp_keepidle, 0,
|
||||
CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL);
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
|
||||
CTLTYPE_INT, "keepintvl",
|
||||
SYSCTL_DESCR("Ticks before next keepalive probe is sent"),
|
||||
NULL, 0, &tcp_keepintvl, 0,
|
||||
sysctl_tcp_keep, 0, &tcp_keepintvl, 0,
|
||||
CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL);
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
|
||||
CTLTYPE_INT, "keepcnt",
|
||||
SYSCTL_DESCR("Number of keepalive probes to send"),
|
||||
NULL, 0, &tcp_keepcnt, 0,
|
||||
sysctl_tcp_keep, 0, &tcp_keepcnt, 0,
|
||||
CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL);
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
|
||||
@ -1658,6 +1739,12 @@ sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
|
||||
sysctl_inpcblist, 0, &tcbtable, 0,
|
||||
CTL_NET, pf, IPPROTO_TCP, CTL_CREATE,
|
||||
CTL_EOL);
|
||||
sysctl_createv(clog, 0, NULL, NULL,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
|
||||
CTLTYPE_INT, "keepinit",
|
||||
SYSCTL_DESCR("Ticks before initial tcp connection times out"),
|
||||
sysctl_tcp_keep, 0, &tcp_keepinit, 0,
|
||||
CTL_NET, pf, IPPROTO_TCP, CTL_CREATE, CTL_EOL);
|
||||
|
||||
/* ECN subtree */
|
||||
sysctl_createv(clog, 0, NULL, &ecn_node,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_var.h,v 1.146 2007/05/02 20:40:25 dyoung Exp $ */
|
||||
/* $NetBSD: tcp_var.h,v 1.147 2007/06/20 15:29:19 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -331,6 +331,14 @@ struct tcpcb {
|
||||
uint8_t t_ecn_retries; /* # of ECN setup retries */
|
||||
|
||||
struct tcp_congctl *t_congctl; /* per TCB congctl algorithm */
|
||||
|
||||
/* Keepalive per socket */
|
||||
u_int t_keepinit;
|
||||
u_int t_keepidle;
|
||||
u_int t_keepintvl;
|
||||
u_int t_keepcnt;
|
||||
u_int t_maxidle; /* t_keepcnt * t_keepintvl */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user