diff options
author | 2009-08-10 10:13:43 +0000 | |
---|---|---|
committer | 2009-08-10 10:13:43 +0000 | |
commit | b26c24edebabd01e0fe73a6c62c752e9676ef633 (patch) | |
tree | 624adefac3d328968e14f46c5fc1dc4bbddbf8b6 /sys/netinet/tcp_input.c | |
parent | Another (diff) | |
download | wireguard-openbsd-b26c24edebabd01e0fe73a6c62c752e9676ef633.tar.xz wireguard-openbsd-b26c24edebabd01e0fe73a6c62c752e9676ef633.zip |
sockets created via a listening socket lose the rdomain and fail to work
therefore. Inherit the rdomain through the syncache.
There are some interactions that need some more work (ctlinput) so this
can be improved but is good enough for now.
OK markus@
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) { |