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
This commit is contained in:
Robert Watson 2003-05-07 05:26:27 +00:00
parent 713ed07eeb
commit 430c635447
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114794
5 changed files with 39 additions and 9 deletions

View file

@ -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:

View file

@ -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:

View file

@ -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);

View file

@ -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);

View file

@ -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 *);