diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2007-06-15 18:23:08 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2007-06-15 18:23:08 +0000 |
commit | f436c78cb6491d8683072efdb5f8859e0f47fbc2 (patch) | |
tree | 047d89a7652636c7822d9e6028689289e70bcbf7 /sys/netinet/tcp_subr.c | |
parent | 0bc06951a0d06a0401b4b4079f71d9299e8449b5 (diff) |
Drop the current random timestamps and the current ISN generation
code and replace both with a RFC1948 based method, so TCP clients
now have monotonic ISN/timestamps. The server side uses completely
random ISN/timestamps and does time-wait recycling (on port reuse).
ok djm@, mcbride@; thanks to lots of testers
Diffstat (limited to 'sys/netinet/tcp_subr.c')
-rw-r--r-- | sys/netinet/tcp_subr.c | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 013efcdf795..38dfeea0a56 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.96 2007/06/01 00:52:38 henning Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.97 2007/06/15 18:23:06 markus Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -99,9 +99,7 @@ #include <netinet6/ip6protosw.h> #endif /* INET6 */ -#ifdef TCP_SIGNATURE #include <crypto/md5.h> -#endif /* TCP_SIGNATURE */ /* patchable/settable parameters for tcp */ int tcp_mssdflt = TCP_MSS; @@ -149,9 +147,7 @@ struct pool sackhl_pool; #endif struct tcpstat tcpstat; /* tcp statistics */ -#ifdef TCP_COMPAT_42 tcp_seq tcp_iss; -#endif /* * Tcp initialization @@ -159,9 +155,7 @@ tcp_seq tcp_iss; void tcp_init() { -#ifdef TCP_COMPAT_42 tcp_iss = 1; /* wrong */ -#endif /* TCP_COMPAT_42 */ pool_init(&tcpcb_pool, sizeof(struct tcpcb), 0, 0, 0, "tcpcbpl", NULL); pool_init(&tcpqe_pool, sizeof(struct tcpqent), 0, 0, 0, "tcpqepl", @@ -1016,6 +1010,76 @@ tcp_mtudisc_increase(inp, errno) } } +#define TCP_ISS_CONN_INC 4096 +int tcp_iss_init; +static u_char tcp_iss_secret[128]; +MD5_CTX tcp_iss_ctx; + +void +tcp_set_iss(struct tcpcb *tp) +{ + MD5_CTX ctx; + tcp_seq digest[4]; + + if (tcp_iss_init == 0) { + arc4random_bytes(tcp_iss_secret, sizeof(tcp_iss_secret)); + MD5Init(&tcp_iss_ctx); + MD5Update(&tcp_iss_ctx, tcp_iss_secret, sizeof(tcp_iss_secret)); + tcp_iss_init = 1; + } + ctx = tcp_iss_ctx; + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_lport, sizeof(u_short)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_fport, sizeof(u_short)); + if (tp->pf == AF_INET6) { + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr6, + sizeof(struct in6_addr)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr6, + sizeof(struct in6_addr)); + } else { + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr, + sizeof(struct in_addr)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr, + sizeof(struct in_addr)); + } + MD5Final((u_char *)digest, &ctx); + tcp_iss += TCP_ISS_CONN_INC; + tp->iss = digest[0] + tcp_iss; +} + +int tcp_tsm_init; +static u_char tcp_tsm_secret[128]; +MD5_CTX tcp_tsm_ctx; + +void +tcp_set_tsm(struct tcpcb *tp) +{ + MD5_CTX ctx; + u_int32_t digest[4]; + + if (tcp_tsm_init == 0) { + arc4random_bytes(tcp_tsm_secret, sizeof(tcp_tsm_secret)); + MD5Init(&tcp_tsm_ctx); + MD5Update(&tcp_tsm_ctx, tcp_tsm_secret, sizeof(tcp_tsm_secret)); + tcp_tsm_init = 1; + } + ctx = tcp_tsm_ctx; + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_lport, sizeof(u_short)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_fport, sizeof(u_short)); + if (tp->pf == AF_INET6) { + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr6, + sizeof(struct in6_addr)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr6, + sizeof(struct in6_addr)); + } else { + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr, + sizeof(struct in_addr)); + MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr, + sizeof(struct in_addr)); + } + MD5Final((u_char *)digest, &ctx); + tp->ts_modulate = digest[0]; +} + #ifdef TCP_SIGNATURE int tcp_signature_tdb_attach() |