summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-07-05 22:51:11 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-07-05 22:51:11 +0000
commit115a196a388cfb8c17ec6acb07d0a231f5e4269b (patch)
tree9a904d4cc4771d5acc22d55e1f23b8f36eb0e464 /sys
parentd52022692cd6e495778e1992a1e586f0c2804c45 (diff)
more cleanup for IPv4 mapped address support. there seem to be some
inconsistency in corner cases (from NRL I believe). todd (fries) and I have seen panic, with the following call chain: ip6_input -> tcp_input -> tcp_respond -> ip_input -> bang! more cleanups should be done, to decrease complexity. for example, INP_IPV6_MAPPED should be nuked.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_input.c169
-rw-r--r--sys/netinet/tcp_subr.c14
-rw-r--r--sys/netinet/tcp_usrreq.c17
3 files changed, 90 insertions, 110 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index ee7650e0487..f4f859523a8 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.61 2000/05/15 03:38:40 angelos Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.62 2000/07/05 22:51:09 itojun Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -987,96 +987,59 @@ findpcb:
goto drop;
#ifdef INET6
if (is_ipv6) {
- /*
- * This is probably the place to set the tp->pf value.
- * (Don't forget to do it in the v4 code as well!)
- *
- * Also, remember to blank out things like flowlabel, or
- * set flowlabel for accepted sockets in v6.
- *
- * FURTHERMORE, this is PROBABLY the place where the whole
- * business of key munging is set up for passive
- * connections.
- */
- am->m_len = sizeof(struct sockaddr_in6);
- sin6 = mtod(am, struct sockaddr_in6 *);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(struct sockaddr_in6);
- sin6->sin6_addr = ipv6->ip6_src;
- sin6->sin6_port = th->th_sport;
- sin6->sin6_flowinfo = htonl(0x0fffffff) &
- inp->inp_ipv6.ip6_flow;
- laddr6 = inp->inp_laddr6;
- if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
- inp->inp_laddr6 = ipv6->ip6_dst;
- /* This is a good optimization. */
- if (in6_pcbconnect(inp, am)) {
- inp->inp_laddr6 = laddr6;
- (void) m_free(am);
- goto drop;
- } /* endif in6_pcbconnect() */
- tp->pf = PF_INET6;
- } else {
- /*
- * Letting v4 incoming datagrams to reach valid
- * PF_INET6 sockets causes some overhead here.
- */
- if (inp->inp_flags & INP_IPV6) {
- if (!(inp->inp_flags & (INP_IPV6_UNDEC|INP_IPV6_MAPPED))) {
- (void) m_free(am);
- goto drop;
- }
-
- am->m_len = sizeof(struct sockaddr_in6);
-
- sin6 = mtod(am, struct sockaddr_in6 *);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(*sin6);
- CREATE_IPV6_MAPPED(sin6->sin6_addr, ti->ti_src.s_addr);
- sin6->sin6_port = th->th_sport;
- sin6->sin6_flowinfo = 0;
-
- laddr6 = inp->inp_laddr6;
- if (inp->inp_laddr.s_addr == INADDR_ANY)
- CREATE_IPV6_MAPPED(inp->inp_laddr6, ti->ti_dst.s_addr);
-
- /*
- * The pcb initially has the v6 default hoplimit
- * set. We're sending v4 packets so we need to set
- * the v4 ttl and tos.
- */
- inp->inp_ip.ip_ttl = ip_defttl;
- inp->inp_ip.ip_tos = 0;
-
- if (in6_pcbconnect(inp, am)) {
- inp->inp_laddr6 = laddr6;
- (void) m_freem(am);
- goto drop;
- }
- tp->pf = PF_INET;
- } else {
-#endif /* INET6 */
- am->m_len = sizeof (struct sockaddr_in);
- sin = mtod(am, struct sockaddr_in *);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_addr = ti->ti_src;
- sin->sin_port = ti->ti_sport;
- bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero));
- laddr = inp->inp_laddr;
- if (inp->inp_laddr.s_addr == INADDR_ANY)
- inp->inp_laddr = ti->ti_dst;
- if (in_pcbconnect(inp, am)) {
- inp->inp_laddr = laddr;
+ /*
+ * This is probably the place to set the tp->pf value.
+ * (Don't forget to do it in the v4 code as well!)
+ *
+ * Also, remember to blank out things like flowlabel, or
+ * set flowlabel for accepted sockets in v6.
+ *
+ * FURTHERMORE, this is PROBABLY the place where the
+ * whole business of key munging is set up for passive
+ * connections.
+ */
+ am->m_len = sizeof(struct sockaddr_in6);
+ sin6 = mtod(am, struct sockaddr_in6 *);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ sin6->sin6_addr = ipv6->ip6_src;
+ sin6->sin6_port = th->th_sport;
+ sin6->sin6_flowinfo = htonl(0x0fffffff) &
+ inp->inp_ipv6.ip6_flow;
+ laddr6 = inp->inp_laddr6;
+ if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
+ inp->inp_laddr6 = ipv6->ip6_dst;
+ /* This is a good optimization. */
+ if (in6_pcbconnect(inp, am)) {
+ inp->inp_laddr6 = laddr6;
+ (void) m_free(am);
+ goto drop;
+ }
+ } else
+#endif
+ {
+ /* drop IPv4 packet to AF_INET6 socket */
+ if (inp->inp_flags & INP_IPV6) {
+ (void) m_free(am);
+ goto drop;
+ }
+ am->m_len = sizeof (struct sockaddr_in);
+ sin = mtod(am, struct sockaddr_in *);
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_addr = ti->ti_src;
+ sin->sin_port = ti->ti_sport;
+ bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero));
+ laddr = inp->inp_laddr;
+ if (inp->inp_laddr.s_addr == INADDR_ANY)
+ inp->inp_laddr = ti->ti_dst;
+ if (in_pcbconnect(inp, am)) {
+ inp->inp_laddr = laddr;
+ (void) m_free(am);
+ goto drop;
+ }
(void) m_free(am);
- goto drop;
}
- (void) m_free(am);
- tp->pf = PF_INET;
-#ifdef INET6
- } /* if (inp->inp_flags & INP_IPV6) */
- } /* if (is_ipv6) */
-#endif /* INET6 */
tp->t_template = tcp_template(tp);
if (tp->t_template == 0) {
tp = tcp_drop(tp, ENOBUFS);
@@ -1995,12 +1958,18 @@ dodata: /* XXX */
}
}
if (so->so_options & SO_DEBUG) {
+ switch (tp->pf == PF_INET6) {
#ifdef INET6
- if (tp->pf == PF_INET6)
- tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
- else
+ case PF_INET6:
+ tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6,
+ 0, tlen);
+ break;
#endif /* INET6 */
- tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
+ case PF_INET:
+ tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti,
+ 0, tlen);
+ break;
+ }
}
/*
@@ -2062,12 +2031,18 @@ drop:
* Drop space held by incoming segment and return.
*/
if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) {
+ switch (tp->pf) {
#ifdef INET6
- if (tp->pf == PF_INET6)
- tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
- else
+ case PF_INET6:
+ tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6,
+ 0, tlen);
+ break;
#endif /* INET6 */
- tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
+ case PF_INET:
+ tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti,
+ 0, tlen);
+ break;
+ }
}
m_freem(m);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 15d34f607bf..5096c5f7539 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.27 2000/06/26 22:45:09 art Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.28 2000/07/05 22:51:10 itojun Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -446,15 +446,11 @@ tcp_newtcpcb(inp)
tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
#ifdef INET6
- /*
- * If we want to use tp->pf for a quick-n-easy way to determine
- * the outbound dgram type, we cannot make this decision
- * until a connection is established! Bzero() sets pf to zero, and
- * that's the way we want it, unless, of course, it's an AF_INET
- * socket...
- */
+ /* we disallow IPv4 mapped address completely. */
if ((inp->inp_flags & INP_IPV6) == 0)
- tp->pf = PF_INET; /* If AF_INET socket, we can't do v6 from it. */
+ tp->pf = PF_INET;
+ else
+ tp->pf = PF_INET6;
#else
tp->pf = PF_INET;
#endif
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 7bd8b4c6240..ad9c8b8cbb5 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.43 2000/06/18 15:13:33 deraadt Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.44 2000/07/05 22:51:10 itojun Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -213,7 +213,7 @@ tcp_usrreq(so, req, m, nam, control)
error = in_pcbbind(inp, nam);
if (error)
break;
-#ifdef INET6
+#if 0 /*INET6*/
/*
* If we bind to an address, set up the tp->pf accordingly!
*/
@@ -305,7 +305,7 @@ tcp_usrreq(so, req, m, nam, control)
if (error)
break;
-#ifdef INET6
+#if 0 /*INET6*/
/*
* With a connection, I now know the version of IP
* is in use and hence can set tp->pf with authority.
@@ -326,7 +326,7 @@ tcp_usrreq(so, req, m, nam, control)
break;
}
-#ifdef INET6
+#if 0 /*INET6*/
if ((inp->inp_flags & INP_IPV6) && (tp->pf == PF_INET)) {
inp->inp_ip.ip_ttl = ip_defttl;
inp->inp_ip.ip_tos = 0;
@@ -716,6 +716,15 @@ tcp_attach(so)
return (ENOBUFS);
}
tp->t_state = TCPS_CLOSED;
+#ifdef INET6
+ /* we disallow IPv4 mapped address completely. */
+ if (inp->inp_flags & INP_IPV6)
+ tp->pf = PF_INET6;
+ else
+ tp->pf = PF_INET;
+#else
+ tp->pf = PF_INET;
+#endif
return (0);
}