diff options
author | kris <kris@FreeBSD.org> | 2001-04-17 18:08:01 +0000 |
---|---|---|
committer | kris <kris@FreeBSD.org> | 2001-04-17 18:08:01 +0000 |
commit | 0c55f2e6dacc3fca03b8d4e465a97fd20e434ca9 (patch) | |
tree | 230f443ebef085afc2464c22248d77ec8f649434 /sys/netinet/tcp_timewait.c | |
parent | f2fbc423a1ad683d0efe728a88f7c66adff62fef (diff) | |
download | FreeBSD-src-0c55f2e6dacc3fca03b8d4e465a97fd20e434ca9.zip FreeBSD-src-0c55f2e6dacc3fca03b8d4e465a97fd20e434ca9.tar.gz |
Randomize the TCP initial sequence numbers more thoroughly.
Obtained from: OpenBSD
Reviewed by: jesper, peter, -developers
Diffstat (limited to 'sys/netinet/tcp_timewait.c')
-rw-r--r-- | sys/netinet/tcp_timewait.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index 2afff53..64f4c06 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -53,6 +53,7 @@ #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/protosw.h> +#include <sys/random.h> #include <vm/vm_zone.h> @@ -181,7 +182,9 @@ tcp_init() { int hashsize; - tcp_iss = arc4random(); /* wrong, but better than a constant */ +#ifdef TCP_COMPAT_42 + tcp_iss = 1; /* wrong */ +#endif /* TCP_COMPAT_42 */ tcp_ccgen = 1; tcp_cleartaocache(); @@ -1100,6 +1103,63 @@ tcp6_ctlinput(cmd, sa, d) } #endif /* INET6 */ +#define TCP_RNDISS_ROUNDS 16 +#define TCP_RNDISS_OUT 7200 +#define TCP_RNDISS_MAX 30000 + +u_int8_t tcp_rndiss_sbox[128]; +u_int16_t tcp_rndiss_msb; +u_int16_t tcp_rndiss_cnt; +long tcp_rndiss_reseed; + +u_int16_t +tcp_rndiss_encrypt(val) + u_int16_t val; +{ + u_int16_t sum = 0, i; + + for (i = 0; i < TCP_RNDISS_ROUNDS; i++) { + sum += 0x79b9; + val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7; + val = ((val & 0xff) << 7) | (val >> 8); + } + + return val; +} + +void +tcp_rndiss_init() +{ + struct timeval time; + + getmicrotime(&time); + read_random(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox)); + + tcp_rndiss_reseed = time.tv_sec + TCP_RNDISS_OUT; + tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; + tcp_rndiss_cnt = 0; +} + +tcp_seq +tcp_rndiss_next() +{ + u_int16_t tmp; + struct timeval time; + + getmicrotime(&time); + + if (tcp_rndiss_cnt >= TCP_RNDISS_MAX || + time.tv_sec > tcp_rndiss_reseed) + tcp_rndiss_init(); + + read_random(&tmp, sizeof(tmp)); + + /* (tmp & 0x7fff) ensures a 32768 byte gap between ISS */ + return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) | + (tmp & 0x7fff); +} + + /* * When a source quench is received, close congestion window * to one segment. We will gradually open it again as we proceed. |