ref: fa3bd966a39b588e91ed8d4f31267e92bc3e1acf
parent: 29485e6d2b3f83c46f76d190041e3c70599ed351
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 21 09:35:56 EDT 2025
tcp: remove "tcpporthogdefense" cruft The ctl message lacks permission check for hostowner and the whole scheme interferes with keep-alive timers.
--- a/sys/man/3/ip
+++ b/sys/man/3/ip
@@ -795,31 +795,6 @@
.I n
is zero; otherwise, and by default,
TCP checksums are computed and sent normally.
-.TP
-.BI tcpporthogdefense \ onoff
-.I onoff
-of
-.L on
-enables the TCP port-hog defense for all TCP connections;
-.I onoff
-of
-.L off
-disables it.
-The defense is a solution to hijacked systems staking out ports
-as a form of denial-of-service attack.
-To avoid stateless TCP conversation hogs,
-.I ip
-picks a TCP sequence number at random for keepalives.
-If that number gets acked by the other end,
-.I ip
-shuts down the connection.
-Some firewalls,
-notably ones that perform stateful inspection,
-discard such out-of-specification keepalives,
-so connections through such firewalls
-will be killed after five minutes
-by the lack of keepalives.
-.
.SS UDP
UDP connections carry unreliable and unordered datagrams. A read from
.B data
--- a/sys/src/9/ip/tcp.c
+++ b/sys/src/9/ip/tcp.c
@@ -399,17 +399,6 @@
uvlong stats[Nstats];
};
-/*
- * Setting tcpporthogdefense to non-zero enables Dong Lin's
- * solution to hijacked systems staking out port's as a form
- * of DoS attack.
- *
- * To avoid stateless Conv hogs, we pick a sequence number at random. If
- * that number gets acked by the other end, we shut down the connection.
- * Look for tcpporthogdefense in the code.
- */
-int tcpporthogdefense = 0;
-
static int addreseq(Fs*, Tcpctl*, Tcppriv*, Tcp*, Block**, ushort);
static int dumpreseq(Tcpctl*);
static void getreseq(Tcpctl*, Tcp*, Block**, ushort*);
@@ -2268,22 +2257,6 @@
break;
}
- /*
- * One DOS attack is to open connections to us and then forget about them,
- * thereby tying up a conv at no long term cost to the attacker.
- * This is an attempt to defeat these stateless DOS attacks. See
- * corresponding code in tcpsendka().
- */
- if(tcb->state != Syn_received && (seg.flags & RST) == 0){- if(tcpporthogdefense
- && seq_within(seg.ack, tcb->snd.una-(1<<31), tcb->snd.una-(1<<29))){- print("stateless hog %I.%d->%I.%d f %ux %lux - %lux - %lux\n",- source, seg.source, dest, seg.dest, seg.flags,
- tcb->snd.una-(1<<31), seg.ack, tcb->snd.una-(1<<29));
- localclose(s, "stateless hog");
- }
- }
-
/* Cut the data to fit the receive window */
tcprcvwin(s);
if(tcptrim(tcb, &seg, &bp, &length) == -1) {@@ -2764,10 +2737,7 @@
seg.flags = ACK|PSH;
seg.mss = 0;
seg.ws = 0;
- if(tcpporthogdefense)
- seg.seq = tcb->snd.una-(1<<30)-nrand(1<<20);
- else
- seg.seq = tcb->snd.una-1;
+ seg.seq = tcb->snd.una-1;
seg.ack = tcb->rcv.nxt;
tcb->rcv.ackptr = seg.ack;
tcprcvwin(s);
@@ -3343,18 +3313,6 @@
}
}
-static char*
-tcpporthogdefensectl(char *val)
-{- if(strcmp(val, "on") == 0)
- tcpporthogdefense = 1;
- else if(strcmp(val, "off") == 0)
- tcpporthogdefense = 0;
- else
- return "unknown value for tcpporthogdefense";
- return nil;
-}
-
/* called with c qlocked */
static char*
tcpctl(Conv* c, char** f, int n)
@@ -3367,8 +3325,6 @@
return tcpstartka(c, f, n);
if(n >= 1 && strcmp(f[0], "checksum") == 0)
return tcpsetchecksum(c, f, n);
- if(n >= 1 && strcmp(f[0], "tcpporthogdefense") == 0)
- return tcpporthogdefensectl(f[1]);
return "unknown control request";
}
--
⑨