summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2003-05-07 05:26:27 +0000
committerrwatson <rwatson@FreeBSD.org>2003-05-07 05:26:27 +0000
commitf332b502284cf247d9ce1dfe30f6378c9bc2afc8 (patch)
tree4bf0def48b8e6b582f1bbfe666aaa3118c608844 /sys/netinet
parente1aef65def425d59eed46af0910c0f1df5461703 (diff)
downloadFreeBSD-src-f332b502284cf247d9ce1dfe30f6378c9bc2afc8.zip
FreeBSD-src-f332b502284cf247d9ce1dfe30f6378c9bc2afc8.tar.gz
Correct a bug introduced with reduced TCP state handling; make
sure that the MAC label on TCP responses during TIMEWAIT is properly set from either the socket (if available), or the mbuf that it's responding to. Unfortunately, this is made somewhat difficult by the TCP code, as tcp_twstart() calls tcp_twrespond() after discarding the socket but without a reference to the mbuf that causes the "response". Passing both the socket and the mbuf works arounds this--eventually it might be good to make sure the mbuf always gets passed in in "response" scenarios but working through this provided to complicate things too much. Approved by: re (scottl) Reviewed by: hsu Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_reass.c2
-rw-r--r--sys/netinet/tcp_subr.c21
-rw-r--r--sys/netinet/tcp_timewait.c21
-rw-r--r--sys/netinet/tcp_var.h2
5 files changed, 39 insertions, 9 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index b01b01e..0683047 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -2950,7 +2950,7 @@ tcp_timewait(tw, to, th, m, tlen)
*/
if (thflags != TH_ACK || tlen != 0 ||
th->th_seq != tw->rcv_nxt || th->th_ack != tw->snd_nxt)
- tcp_twrespond(tw, TH_ACK);
+ tcp_twrespond(tw, NULL, m, TH_ACK);
goto drop;
reset:
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index b01b01e..0683047 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -2950,7 +2950,7 @@ tcp_timewait(tw, to, th, m, tlen)
*/
if (thflags != TH_ACK || tlen != 0 ||
th->th_seq != tw->rcv_nxt || th->th_ack != tw->snd_nxt)
- tcp_twrespond(tw, TH_ACK);
+ tcp_twrespond(tw, NULL, m, TH_ACK);
goto drop;
reset:
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 58395f5..8816bc6 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1661,13 +1661,13 @@ tcp_twstart(tp)
so->so_pcb = NULL;
tw->tw_cred = crhold(so->so_cred);
tw->tw_so_options = so->so_options;
+ if (acknow)
+ tcp_twrespond(tw, so, NULL, TH_ACK);
sotryfree(so);
inp->inp_socket = NULL;
inp->inp_ppcb = (caddr_t)tw;
inp->inp_vflag |= INP_TIMEWAIT;
tcp_timer_2msl_reset(tw, tw_time);
- if (acknow)
- tcp_twrespond(tw, TH_ACK);
INP_UNLOCK(inp);
}
@@ -1693,8 +1693,13 @@ tcp_twclose(struct tcptw *tw, int reuse)
return (NULL);
}
+/*
+ * One of so and msrc must be non-NULL for use by the MAC Framework to
+ * construct a label for ay resulting packet.
+ */
int
-tcp_twrespond(struct tcptw *tw, int flags)
+tcp_twrespond(struct tcptw *tw, struct socket *so, struct mbuf *msrc,
+ int flags)
{
struct inpcb *inp = tw->tw_inpcb;
struct tcphdr *th;
@@ -1708,11 +1713,21 @@ tcp_twrespond(struct tcptw *tw, int flags)
int isipv6 = inp->inp_inc.inc_isipv6;
#endif
+ KASSERT(so != NULL || msrc != NULL,
+ ("tcp_twrespond: so and msrc NULL"));
+
m = m_gethdr(M_DONTWAIT, MT_HEADER);
if (m == NULL)
return (ENOBUFS);
m->m_data += max_linkhdr;
+#ifdef MAC
+ if (so != NULL)
+ mac_create_mbuf_from_socket(so, m);
+ else
+ mac_create_mbuf_netlayer(msrc, m);
+#endif
+
#ifdef INET6
if (isipv6) {
hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 58395f5..8816bc6 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -1661,13 +1661,13 @@ tcp_twstart(tp)
so->so_pcb = NULL;
tw->tw_cred = crhold(so->so_cred);
tw->tw_so_options = so->so_options;
+ if (acknow)
+ tcp_twrespond(tw, so, NULL, TH_ACK);
sotryfree(so);
inp->inp_socket = NULL;
inp->inp_ppcb = (caddr_t)tw;
inp->inp_vflag |= INP_TIMEWAIT;
tcp_timer_2msl_reset(tw, tw_time);
- if (acknow)
- tcp_twrespond(tw, TH_ACK);
INP_UNLOCK(inp);
}
@@ -1693,8 +1693,13 @@ tcp_twclose(struct tcptw *tw, int reuse)
return (NULL);
}
+/*
+ * One of so and msrc must be non-NULL for use by the MAC Framework to
+ * construct a label for ay resulting packet.
+ */
int
-tcp_twrespond(struct tcptw *tw, int flags)
+tcp_twrespond(struct tcptw *tw, struct socket *so, struct mbuf *msrc,
+ int flags)
{
struct inpcb *inp = tw->tw_inpcb;
struct tcphdr *th;
@@ -1708,11 +1713,21 @@ tcp_twrespond(struct tcptw *tw, int flags)
int isipv6 = inp->inp_inc.inc_isipv6;
#endif
+ KASSERT(so != NULL || msrc != NULL,
+ ("tcp_twrespond: so and msrc NULL"));
+
m = m_gethdr(M_DONTWAIT, MT_HEADER);
if (m == NULL)
return (ENOBUFS);
m->m_data += max_linkhdr;
+#ifdef MAC
+ if (so != NULL)
+ mac_create_mbuf_from_socket(so, m);
+ else
+ mac_create_mbuf_netlayer(msrc, m);
+#endif
+
#ifdef INET6
if (isipv6) {
hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 2424705..11474b0 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -491,7 +491,7 @@ struct inpcb *
tcp_quench(struct inpcb *, int);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
-int tcp_twrespond(struct tcptw *, int);
+int tcp_twrespond(struct tcptw *, struct socket *, struct mbuf *, int);
struct rtentry *
tcp_rtlookup(struct in_conninfo *);
void tcp_setpersist(struct tcpcb *);
OpenPOWER on IntegriCloud