Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156841717
D36716.id110995.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D36716.id110995.diff
View Options
Index: sys/netinet/tcp_timer.h
===================================================================
--- sys/netinet/tcp_timer.h
+++ sys/netinet/tcp_timer.h
@@ -86,7 +86,7 @@
#define TCPTV_KEEP_IDLE (120*60*hz) /* dflt time before probing */
#define TCPTV_KEEPINTVL ( 75*hz) /* default probe interval */
#define TCPTV_KEEPCNT 8 /* max probes before drop */
-
+#define TCPTV_MAXUNACKTIME 0 /* max time without making progress */
#define TCPTV_FINWAIT2_TIMEOUT (60*hz) /* FIN_WAIT_2 timeout if no receiver */
/*
@@ -183,6 +183,9 @@
#define TP_KEEPINTVL(tp) ((tp)->t_keepintvl ? (tp)->t_keepintvl : tcp_keepintvl)
#define TP_KEEPCNT(tp) ((tp)->t_keepcnt ? (tp)->t_keepcnt : tcp_keepcnt)
#define TP_MAXIDLE(tp) (TP_KEEPCNT(tp) * TP_KEEPINTVL(tp))
+#define TP_MAXUNACKTIME(tp) \
+ ((tp)->t_maxunacktime ? (tp)->t_maxunacktime : tcp_maxunacktime)
+
extern int tcp_persmin; /* minimum persist interval */
extern int tcp_persmax; /* maximum persist interval */
@@ -191,6 +194,7 @@
extern int tcp_keepintvl; /* time between keepalive probes */
extern int tcp_keepcnt; /* number of keepalives */
extern int tcp_delacktime; /* time before sending a delayed ACK */
+extern int tcp_maxunacktime; /* max time without making progress */
extern int tcp_maxpersistidle;
extern int tcp_rexmit_initial;
extern int tcp_rexmit_min;
Index: sys/netinet/tcp_timer.c
===================================================================
--- sys/netinet/tcp_timer.c
+++ sys/netinet/tcp_timer.c
@@ -167,6 +167,12 @@
&tcp_rexmit_drop_options, 0,
"Drop TCP options from 3rd and later retransmitted SYN");
+int tcp_maxunacktime = TCPTV_MAXUNACKTIME;
+SYSCTL_PROC(_net_inet_tcp, OID_AUTO, maxunacktime,
+ CTLTYPE_INT|CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+ &tcp_maxunacktime, 0, sysctl_msec_to_ticks, "I",
+ "Maximum time (in ms) that a session can linger without making progress");
+
VNET_DEFINE(int, tcp_pmtud_blackhole_detect);
SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection,
CTLFLAG_RW|CTLFLAG_VNET,
@@ -503,12 +509,38 @@
CURVNET_RESTORE();
}
+/*
+ * Has this session exceeded the maximum time without seeing a substantive
+ * acknowledgement? If so, return true; otherwise false.
+ */
+static bool
+tcp_maxunacktime_check(struct tcpcb *tp)
+{
+
+ /* Are we tracking this timer for this session? */
+ if (TP_MAXUNACKTIME(tp) == 0)
+ return false;
+
+ /* Do we have a current measurement. */
+ if (tp->t_acktime == 0)
+ return false;
+
+ /* Are we within the acceptable range? */
+ if (TSTMP_GT(TP_MAXUNACKTIME(tp) + tp->t_acktime, (u_int)ticks))
+ return false;
+
+ /* We exceeded the timer. */
+ TCPSTAT_INC(tcps_progdrops);
+ return true;
+}
+
void
tcp_timer_persist(void *xtp)
{
struct tcpcb *tp = xtp;
struct inpcb *inp;
struct epoch_tracker et;
+ bool progdrop;
int outrv;
CURVNET_SET(tp->t_vnet);
#ifdef TCPDEBUG
@@ -545,10 +577,12 @@
* (no responses to probes) reaches the maximum
* backoff that we would use if retransmitting.
*/
- if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
+ progdrop = tcp_maxunacktime_check(tp);
+ if (progdrop || (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
(ticks - tp->t_rcvtime >= tcp_maxpersistidle ||
- ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff)) {
- TCPSTAT_INC(tcps_persistdrop);
+ ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff))) {
+ if (!progdrop)
+ TCPSTAT_INC(tcps_persistdrop);
NET_EPOCH_ENTER(et);
tp = tcp_drop(tp, ETIMEDOUT);
NET_EPOCH_EXIT(et);
@@ -626,8 +660,12 @@
* Retransmission timer went off. Message has not
* been acked within retransmit interval. Back off
* to a longer retransmit interval and retransmit one segment.
+ *
+ * If we've either exceeded the maximum number of retransmissions,
+ * or we've gone long enough without making progress, then drop
+ * the session.
*/
- if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
+ if (++tp->t_rxtshift > TCP_MAXRXTSHIFT || tcp_maxunacktime_check(tp)) {
tp->t_rxtshift = TCP_MAXRXTSHIFT;
TCPSTAT_INC(tcps_timeoutdrop);
NET_EPOCH_ENTER(et);
Index: sys/netinet/tcp_usrreq.c
===================================================================
--- sys/netinet/tcp_usrreq.c
+++ sys/netinet/tcp_usrreq.c
@@ -2375,7 +2375,7 @@
error = ktls_enable_rx(so, &tls);
break;
#endif
-
+ case TCP_MAXUNACKTIME:
case TCP_KEEPIDLE:
case TCP_KEEPINTVL:
case TCP_KEEPINIT:
@@ -2392,6 +2392,10 @@
INP_WLOCK_RECHECK(inp);
switch (sopt->sopt_name) {
+ case TCP_MAXUNACKTIME:
+ tp->t_maxunacktime = ui;
+ break;
+
case TCP_KEEPIDLE:
tp->t_keepidle = ui;
/*
@@ -2658,11 +2662,15 @@
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, buf, len + 1);
break;
+ case TCP_MAXUNACKTIME:
case TCP_KEEPIDLE:
case TCP_KEEPINTVL:
case TCP_KEEPINIT:
case TCP_KEEPCNT:
switch (sopt->sopt_name) {
+ case TCP_MAXUNACKTIME:
+ ui = TP_MAXUNACKTIME(tp) / hz;
+ break;
case TCP_KEEPIDLE:
ui = TP_KEEPIDLE(tp) / hz;
break;
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -707,6 +707,7 @@
uint64_t tcps_keeptimeo; /* keepalive timeouts */
uint64_t tcps_keepprobe; /* keepalive probes sent */
uint64_t tcps_keepdrops; /* connections dropped in keepalive */
+ uint64_t tcps_progdrops; /* drops due to no progress */
uint64_t tcps_sndtotal; /* total packets sent */
uint64_t tcps_sndpack; /* data packets sent */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, May 17, 8:27 PM (7 h, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33207747
Default Alt Text
D36716.id110995.diff (5 KB)
Attached To
Mode
D36716: Tcp progress timeout
Attached
Detach File
Event Timeline
Log In to Comment