diff options
Diffstat (limited to 'sys/netinet/tcp_syncache.c')
-rw-r--r-- | sys/netinet/tcp_syncache.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 9343bf4..14eb315 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -34,6 +34,7 @@ * $FreeBSD$ */ +#include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" #include "opt_mac.h" @@ -695,6 +696,10 @@ syncache_socket(sc, lso, m) tp->cc_send = sc->sc_cc_send; tp->cc_recv = sc->sc_cc_recv; } +#ifdef TCP_SIGNATURE + if (sc->sc_flags & SCF_SIGNATURE) + tp->t_flags |= TF_SIGNATURE; +#endif /* TCP_SIGNATURE */ /* * Set up MSS and get cached values from tcp_hostcache. @@ -970,6 +975,17 @@ syncache_add(inc, to, th, sop, m) } if (tp->t_flags & TF_NOOPT) sc->sc_flags = SCF_NOOPT; +#ifdef TCP_SIGNATURE + /* + * If listening socket requested TCP digests, and received SYN + * contains the option, flag this in the syncache so that + * syncache_respond() will do the right thing with the SYN+ACK. + * XXX Currently we always record the option by default and will + * attempt to use it in syncache_respond(). + */ + if (to->to_flags & TOF_SIGNATURE) + sc->sc_flags = SCF_SIGNATURE; +#endif /* TCP_SIGNATURE */ /* * XXX @@ -1083,6 +1099,10 @@ syncache_respond(sc, m) ((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) + ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0) + ((sc->sc_flags & SCF_CC) ? TCPOLEN_CC_APPA * 2 : 0); +#ifdef TCP_SIGNATURE + optlen += ((sc->sc_flags & SCF_SIGNATURE) ? + (TCPOLEN_SIGNATURE + 2) : 0); +#endif /* TCP_SIGNATURE */ } tlen = hlen + sizeof(struct tcphdr) + optlen; @@ -1200,6 +1220,26 @@ syncache_respond(sc, m) *lp = htonl(sc->sc_cc_recv); optp += TCPOLEN_CC_APPA * 2; } + +#ifdef TCP_SIGNATURE + /* + * Handle TCP-MD5 passive opener response. + */ + if (sc->sc_flags & SCF_SIGNATURE) { + u_int8_t *bp = optp; + int i; + + *bp++ = TCPOPT_SIGNATURE; + *bp++ = TCPOLEN_SIGNATURE; + for (i = 0; i < TCP_SIGLEN; i++) + *bp++ = 0; + tcpsignature_compute(m, sizeof(struct ip), 0, optlen, + optp + 2, IPSEC_DIR_OUTBOUND); + *bp++ = TCPOPT_NOP; + *bp++ = TCPOPT_EOL; + optp += TCPOLEN_SIGNATURE + 2; + } +#endif /* TCP_SIGNATURE */ } #ifdef INET6 |