summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2009-08-10 10:13:43 +0000
committerclaudio <claudio@openbsd.org>2009-08-10 10:13:43 +0000
commitb26c24edebabd01e0fe73a6c62c752e9676ef633 (patch)
tree624adefac3d328968e14f46c5fc1dc4bbddbf8b6
parentAnother (diff)
downloadwireguard-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@
-rw-r--r--sys/netinet/tcp_input.c32
-rw-r--r--sys/netinet/tcp_subr.c6
-rw-r--r--sys/netinet/tcp_var.h9
3 files changed, 30 insertions, 17 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) {
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index e6b0cf18732..92ac414980b 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.106 2009/06/05 00:05:22 claudio Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.107 2009/08/10 10:13:43 claudio Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -759,7 +759,7 @@ tcp6_ctlinput(cmd, sa, d)
inet6ctlerrmap[cmd] == ENETUNREACH ||
inet6ctlerrmap[cmd] == EHOSTDOWN))
syn_cache_unreach((struct sockaddr *)sa6_src,
- sa, &th);
+ sa, &th, /* XXX */ 0);
} else {
(void) in6_pcbnotify(&tcbtable, sa, 0,
(struct sockaddr *)sa6_src, 0, cmd, NULL, notify);
@@ -889,7 +889,7 @@ tcp_ctlinput(cmd, sa, v)
sin.sin_port = th->th_sport;
sin.sin_addr = ip->ip_src;
syn_cache_unreach((struct sockaddr *)&sin,
- sa, th);
+ sa, th, /* XXX */ 0);
}
} else
in_pcbnotifyall(&tcbtable, sa, errno, notify);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 4fa1bda8c61..090ba4f6d3e 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.91 2009/06/05 00:05:22 claudio Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.92 2009/08/10 10:13:43 claudio Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -274,6 +274,7 @@ struct syn_cache {
union syn_cache_sa sc_dst;
tcp_seq sc_irs;
tcp_seq sc_iss;
+ u_int sc_rdomain;
u_int sc_rxtcur; /* current rxt timeout */
u_int sc_rxttot; /* total time spend on queues */
u_short sc_rxtshift; /* for computing backoff */
@@ -628,16 +629,16 @@ int syn_cache_add(struct sockaddr *, struct sockaddr *,
struct tcphdr *, unsigned int, struct socket *,
struct mbuf *, u_char *, int, struct tcp_opt_info *, tcp_seq *);
void syn_cache_unreach(struct sockaddr *, struct sockaddr *,
- struct tcphdr *);
+ struct tcphdr *, u_int);
struct socket *syn_cache_get(struct sockaddr *, struct sockaddr *,
struct tcphdr *, unsigned int, unsigned int,
struct socket *so, struct mbuf *);
void syn_cache_init(void);
void syn_cache_insert(struct syn_cache *, struct tcpcb *);
struct syn_cache *syn_cache_lookup(struct sockaddr *, struct sockaddr *,
- struct syn_cache_head **);
+ struct syn_cache_head **, u_int);
void syn_cache_reset(struct sockaddr *, struct sockaddr *,
- struct tcphdr *);
+ struct tcphdr *, u_int);
int syn_cache_respond(struct syn_cache *, struct mbuf *);
void syn_cache_timer(void *);
void syn_cache_cleanup(struct tcpcb *);