Index: sys/netinet/tcp_syncache.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_syncache.c,v retrieving revision 1.5.2.8 diff -c -r1.5.2.8 tcp_syncache.c *** sys/netinet/tcp_syncache.c 18 Aug 2002 22:04:47 -0000 1.5.2.8 --- sys/netinet/tcp_syncache.c 23 Feb 2003 14:38:20 -0000 *************** *** 1222,1243 **** /* * The values below are chosen to minimize the size of the tcp_secret ! * table, as well as providing roughly a 4 second lifetime for the cookie. */ ! #define SYNCOOKIE_HASHSHIFT 2 /* log2(# of 32bit words from hash) */ ! #define SYNCOOKIE_WNDBITS 7 /* exposed bits for window indexing */ ! #define SYNCOOKIE_TIMESHIFT 5 /* scale ticks to window time units */ - #define SYNCOOKIE_HASHMASK ((1 << SYNCOOKIE_HASHSHIFT) - 1) #define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1) ! #define SYNCOOKIE_NSECRETS (1 << (SYNCOOKIE_WNDBITS - SYNCOOKIE_HASHSHIFT)) #define SYNCOOKIE_TIMEOUT \ (hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT)) #define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK) static struct { ! u_int32_t ts_secbits; u_int ts_expire; } tcp_secret[SYNCOOKIE_NSECRETS]; --- 1222,1241 ---- /* * The values below are chosen to minimize the size of the tcp_secret ! * table, as well as providing roughly a 16 second lifetime for the cookie. */ ! #define SYNCOOKIE_WNDBITS 5 /* exposed bits for window indexing */ ! #define SYNCOOKIE_TIMESHIFT 1 /* scale ticks to window time units */ #define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1) ! #define SYNCOOKIE_NSECRETS (1 << SYNCOOKIE_WNDBITS) #define SYNCOOKIE_TIMEOUT \ (hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT)) #define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK) static struct { ! u_int32_t ts_secbits[4]; u_int ts_expire; } tcp_secret[SYNCOOKIE_NSECRETS]; *************** *** 1247,1252 **** --- 1245,1260 ---- #define MD5Add(v) MD5Update(&syn_ctx, (u_char *)&v, sizeof(v)) + struct md5_add { + u_int32_t laddr, faddr; + u_int32_t secbits[4]; + u_int16_t lport, fport; + }; + + #ifdef CTASSERT + CTASSERT(sizeof(struct md5_add) == 28); + #endif + /* * Consider the problem of a recreated (and retransmitted) cookie. If the * original SYN was accepted, the connection is established. The second *************** *** 1262,1296 **** { u_int32_t md5_buffer[4]; u_int32_t data; ! int wnd, idx; ! wnd = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK; ! idx = wnd >> SYNCOOKIE_HASHSHIFT; if (tcp_secret[idx].ts_expire < ticks) { ! tcp_secret[idx].ts_secbits = arc4random(); tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT; } for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--) if (tcp_msstab[data] <= sc->sc_peer_mss) break; ! data = (data << SYNCOOKIE_WNDBITS) | wnd; data ^= sc->sc_irs; /* peer's iss */ MD5Init(&syn_ctx); #ifdef INET6 if (sc->sc_inc.inc_isipv6) { MD5Add(sc->sc_inc.inc6_laddr); MD5Add(sc->sc_inc.inc6_faddr); } else #endif { ! MD5Add(sc->sc_inc.inc_laddr); ! MD5Add(sc->sc_inc.inc_faddr); } ! MD5Add(sc->sc_inc.inc_lport); ! MD5Add(sc->sc_inc.inc_fport); ! MD5Add(tcp_secret[idx].ts_secbits); MD5Final((u_char *)&md5_buffer, &syn_ctx); ! data ^= (md5_buffer[wnd & SYNCOOKIE_HASHMASK] & ~SYNCOOKIE_WNDMASK); return (data); } --- 1270,1311 ---- { u_int32_t md5_buffer[4]; u_int32_t data; ! int idx, i; ! struct md5_add add; ! idx = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK; if (tcp_secret[idx].ts_expire < ticks) { ! for (i = 0; i < 4; i++) ! tcp_secret[idx].ts_secbits[i] = arc4random(); tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT; } for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--) if (tcp_msstab[data] <= sc->sc_peer_mss) break; ! data = (data << SYNCOOKIE_WNDBITS) | idx; data ^= sc->sc_irs; /* peer's iss */ MD5Init(&syn_ctx); #ifdef INET6 if (sc->sc_inc.inc_isipv6) { MD5Add(sc->sc_inc.inc6_laddr); MD5Add(sc->sc_inc.inc6_faddr); + add.laddr = 0; + add.faddr = 0; } else #endif { ! add.laddr = sc->sc_inc.inc_laddr.s_addr; ! add.faddr = sc->sc_inc.inc_faddr.s_addr; } ! add.lport = sc->sc_inc.inc_lport; ! add.fport = sc->sc_inc.inc_fport; ! add.secbits[0] = tcp_secret[idx].ts_secbits[0]; ! add.secbits[1] = tcp_secret[idx].ts_secbits[1]; ! add.secbits[2] = tcp_secret[idx].ts_secbits[2]; ! add.secbits[3] = tcp_secret[idx].ts_secbits[3]; ! MD5Add(add); MD5Final((u_char *)&md5_buffer, &syn_ctx); ! data ^= (md5_buffer[0] & ~SYNCOOKIE_WNDMASK); return (data); } *************** *** 1304,1313 **** struct syncache *sc; u_int32_t data; int wnd, idx; data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */ ! wnd = data & SYNCOOKIE_WNDMASK; ! idx = wnd >> SYNCOOKIE_HASHSHIFT; if (tcp_secret[idx].ts_expire < ticks || sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks) return (NULL); --- 1319,1328 ---- struct syncache *sc; u_int32_t data; int wnd, idx; + struct md5_add add; data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */ ! idx = data & SYNCOOKIE_WNDMASK; if (tcp_secret[idx].ts_expire < ticks || sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks) return (NULL); *************** *** 1316,1332 **** if (inc->inc_isipv6) { MD5Add(inc->inc6_laddr); MD5Add(inc->inc6_faddr); } else #endif { ! MD5Add(inc->inc_laddr); ! MD5Add(inc->inc_faddr); } ! MD5Add(inc->inc_lport); ! MD5Add(inc->inc_fport); ! MD5Add(tcp_secret[idx].ts_secbits); MD5Final((u_char *)&md5_buffer, &syn_ctx); ! data ^= md5_buffer[wnd & SYNCOOKIE_HASHMASK]; if ((data & ~SYNCOOKIE_DATAMASK) != 0) return (NULL); data = data >> SYNCOOKIE_WNDBITS; --- 1331,1353 ---- if (inc->inc_isipv6) { MD5Add(inc->inc6_laddr); MD5Add(inc->inc6_faddr); + add.laddr = 0; + add.faddr = 0; } else #endif { ! add.laddr = inc->inc_laddr.s_addr; ! add.faddr = inc->inc_faddr.s_addr; } ! add.lport = inc->inc_lport; ! add.fport = inc->inc_fport; ! add.secbits[0] = tcp_secret[idx].ts_secbits[0]; ! add.secbits[1] = tcp_secret[idx].ts_secbits[1]; ! add.secbits[2] = tcp_secret[idx].ts_secbits[2]; ! add.secbits[3] = tcp_secret[idx].ts_secbits[3]; ! MD5Add(add); MD5Final((u_char *)&md5_buffer, &syn_ctx); ! data ^= md5_buffer[0]; if ((data & ~SYNCOOKIE_DATAMASK) != 0) return (NULL); data = data >> SYNCOOKIE_WNDBITS;