diff options
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index c8912fccf68..bc48ce87ee2 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.226 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.227 2009/08/10 10:13:43 claudio Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -719,7 +719,8 @@ findpcb: if (so->so_options & SO_ACCEPTCONN) { if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { if (tiflags & TH_RST) { - syn_cache_reset(&src.sa, &dst.sa, th); + syn_cache_reset(&src.sa, &dst.sa, th, + inp->inp_rdomain); } else if ((tiflags & (TH_ACK|TH_SYN)) == (TH_ACK|TH_SYN)) { /* @@ -3561,7 +3562,7 @@ syn_cache_cleanup(struct tcpcb *tp) */ struct syn_cache * syn_cache_lookup(struct sockaddr *src, struct sockaddr *dst, - struct syn_cache_head **headp) + struct syn_cache_head **headp, u_int rdomain) { struct syn_cache *sc; struct syn_cache_head *scp; @@ -3578,7 +3579,8 @@ syn_cache_lookup(struct sockaddr *src, struct sockaddr *dst, if (sc->sc_hash != hash) continue; if (!bcmp(&sc->sc_src, src, src->sa_len) && - !bcmp(&sc->sc_dst, dst, dst->sa_len)) { + !bcmp(&sc->sc_dst, dst, dst->sa_len) && + rdomain == sc->sc_rdomain) { splx(s); return (sc); } @@ -3623,7 +3625,8 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, struct socket *oso; s = splsoftnet(); - if ((sc = syn_cache_lookup(src, dst, &scp)) == NULL) { + if ((sc = syn_cache_lookup(src, dst, &scp, + m->m_pkthdr.rdomain)) == NULL) { splx(s); return (NULL); } @@ -3656,6 +3659,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, goto resetandabort; inp = sotoinpcb(oso); + #ifdef IPSEC /* * We need to copy the required security levels @@ -3702,6 +3706,9 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, inp = (struct inpcb *)so->so_pcb; #endif /* INET6 */ + /* inherit rdomain from listening socket */ + inp->inp_rdomain = sc->sc_rdomain; + inp->inp_lport = th->th_dport; switch (src->sa_family) { #ifdef INET6 @@ -3856,13 +3863,14 @@ abort: */ void -syn_cache_reset(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th) +syn_cache_reset(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, + u_int rdomain) { struct syn_cache *sc; struct syn_cache_head *scp; int s = splsoftnet(); - if ((sc = syn_cache_lookup(src, dst, &scp)) == NULL) { + if ((sc = syn_cache_lookup(src, dst, &scp, rdomain)) == NULL) { splx(s); return; } @@ -3878,14 +3886,15 @@ syn_cache_reset(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th) } void -syn_cache_unreach(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th) +syn_cache_unreach(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, + u_int rdomain) { struct syn_cache *sc; struct syn_cache_head *scp; int s; s = splsoftnet(); - if ((sc = syn_cache_lookup(src, dst, &scp)) == NULL) { + if ((sc = syn_cache_lookup(src, dst, &scp, rdomain)) == NULL) { splx(s); return; } @@ -3993,7 +4002,8 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, * If we do, resend the SYN,ACK. We do not count this * as a retransmission (XXX though maybe we should). */ - if ((sc = syn_cache_lookup(src, dst, &scp)) != NULL) { + if ((sc = syn_cache_lookup(src, dst, &scp, m->m_pkthdr.rdomain)) != + NULL) { tcpstat.tcps_sc_dupesyn++; if (ipopts) { /* @@ -4027,6 +4037,7 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, bzero(&sc->sc_timer, sizeof(sc->sc_timer)); bcopy(src, &sc->sc_src, src->sa_len); bcopy(dst, &sc->sc_dst, dst->sa_len); + sc->sc_rdomain = m->m_pkthdr.rdomain; sc->sc_flags = 0; sc->sc_ipopts = ipopts; sc->sc_irs = th->th_seq; @@ -4154,6 +4165,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m) m->m_data += max_linkhdr; m->m_len = m->m_pkthdr.len = tlen; m->m_pkthdr.rcvif = NULL; + m->m_pkthdr.rdomain = sc->sc_rdomain; memset(mtod(m, u_char *), 0, tlen); switch (sc->sc_src.sa.sa_family) { |