summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-04-09 16:59:19 +0000
committerrwatson <rwatson@FreeBSD.org>2006-04-09 16:59:19 +0000
commite194ddde243c3305592a9f5b8085cbedc87a9cb4 (patch)
treefc07b90db4c9ecf85366bbc3fb22dbbe8160fc22 /sys/netinet
parent9fbf53f0d048171e070fa8b051fddf64573108f8 (diff)
downloadFreeBSD-src-e194ddde243c3305592a9f5b8085cbedc87a9cb4.zip
FreeBSD-src-e194ddde243c3305592a9f5b8085cbedc87a9cb4.tar.gz
Modify tcp_timewait() to accept an inpcb reference, not a tcptw
reference. For now, we allow the possibility that the in_ppcb pointer in the inpcb may be NULL if a timewait socket has had its tcptw structure recycled. This allows tcp_timewait() to consistently unlock the inpcb. Reported by: Kazuaki Oda <kaakun at highway dot ne dot jp> MFC after: 3 months
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_input.c23
-rw-r--r--sys/netinet/tcp_reass.c23
2 files changed, 24 insertions, 22 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 0532f71..c31892c 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -173,7 +173,7 @@ static int tcp_reass(struct tcpcb *, struct tcphdr *, int *,
struct mbuf *);
static void tcp_xmit_timer(struct tcpcb *, int);
static void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
-static int tcp_timewait(struct tcptw *, struct tcpopt *,
+static int tcp_timewait(struct inpcb *, struct tcpopt *,
struct tcphdr *, struct mbuf *, int);
/* Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint. */
@@ -760,7 +760,7 @@ findpcb:
*/
if (thflags & TH_SYN)
tcp_dooptions(&to, optp, optlen, 1);
- if (tcp_timewait(intotw(inp), &to, th, m, tlen))
+ if (tcp_timewait(inp, &to, th, m, tlen))
goto findpcb;
/*
* tcp_timewait unlocks inp.
@@ -3141,13 +3141,14 @@ tcp_newreno_partial_ack(tp, th)
* looking for a pcb in the listen state. Returns 0 otherwise.
*/
static int
-tcp_timewait(tw, to, th, m, tlen)
- struct tcptw *tw;
+tcp_timewait(inp, to, th, m, tlen)
+ struct inpcb *inp;
struct tcpopt *to;
struct tcphdr *th;
struct mbuf *m;
int tlen;
{
+ struct tcptw *tw;
int thflags;
tcp_seq seq;
#ifdef INET6
@@ -3156,19 +3157,20 @@ tcp_timewait(tw, to, th, m, tlen)
const int isipv6 = 0;
#endif
+ /* tcbinfo lock required for tcp_twclose(), tcp_2msl_reset. */
+ INP_INFO_WLOCK_ASSERT(&tcbinfo);
+ INP_LOCK_ASSERT(inp);
+
/*
* XXXRW: Time wait state for inpcb has been recycled, but inpcb is
* still present. This is undesirable, but temporarily necessary
* until we work out how to handle inpcb's who's timewait state has
* been removed.
*/
+ tw = intotw(inp);
if (tw == NULL)
goto drop;
- /* tcbinfo lock required for tcp_twclose(), tcp_2msl_reset. */
- INP_INFO_WLOCK_ASSERT(&tcbinfo);
- INP_LOCK_ASSERT(tw->tw_inpcb);
-
thflags = th->th_flags;
/*
@@ -3268,12 +3270,11 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_respond(NULL,
mtod(m, void *), th, m, seq, 0, TH_RST|TH_ACK);
}
- INP_UNLOCK(tw->tw_inpcb);
+ INP_UNLOCK(inp);
return (0);
drop:
- if (tw != NULL)
- INP_UNLOCK(tw->tw_inpcb);
+ INP_UNLOCK(inp);
m_freem(m);
return (0);
}
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 0532f71..c31892c 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -173,7 +173,7 @@ static int tcp_reass(struct tcpcb *, struct tcphdr *, int *,
struct mbuf *);
static void tcp_xmit_timer(struct tcpcb *, int);
static void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
-static int tcp_timewait(struct tcptw *, struct tcpopt *,
+static int tcp_timewait(struct inpcb *, struct tcpopt *,
struct tcphdr *, struct mbuf *, int);
/* Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint. */
@@ -760,7 +760,7 @@ findpcb:
*/
if (thflags & TH_SYN)
tcp_dooptions(&to, optp, optlen, 1);
- if (tcp_timewait(intotw(inp), &to, th, m, tlen))
+ if (tcp_timewait(inp, &to, th, m, tlen))
goto findpcb;
/*
* tcp_timewait unlocks inp.
@@ -3141,13 +3141,14 @@ tcp_newreno_partial_ack(tp, th)
* looking for a pcb in the listen state. Returns 0 otherwise.
*/
static int
-tcp_timewait(tw, to, th, m, tlen)
- struct tcptw *tw;
+tcp_timewait(inp, to, th, m, tlen)
+ struct inpcb *inp;
struct tcpopt *to;
struct tcphdr *th;
struct mbuf *m;
int tlen;
{
+ struct tcptw *tw;
int thflags;
tcp_seq seq;
#ifdef INET6
@@ -3156,19 +3157,20 @@ tcp_timewait(tw, to, th, m, tlen)
const int isipv6 = 0;
#endif
+ /* tcbinfo lock required for tcp_twclose(), tcp_2msl_reset. */
+ INP_INFO_WLOCK_ASSERT(&tcbinfo);
+ INP_LOCK_ASSERT(inp);
+
/*
* XXXRW: Time wait state for inpcb has been recycled, but inpcb is
* still present. This is undesirable, but temporarily necessary
* until we work out how to handle inpcb's who's timewait state has
* been removed.
*/
+ tw = intotw(inp);
if (tw == NULL)
goto drop;
- /* tcbinfo lock required for tcp_twclose(), tcp_2msl_reset. */
- INP_INFO_WLOCK_ASSERT(&tcbinfo);
- INP_LOCK_ASSERT(tw->tw_inpcb);
-
thflags = th->th_flags;
/*
@@ -3268,12 +3270,11 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_respond(NULL,
mtod(m, void *), th, m, seq, 0, TH_RST|TH_ACK);
}
- INP_UNLOCK(tw->tw_inpcb);
+ INP_UNLOCK(inp);
return (0);
drop:
- if (tw != NULL)
- INP_UNLOCK(tw->tw_inpcb);
+ INP_UNLOCK(inp);
m_freem(m);
return (0);
}
OpenPOWER on IntegriCloud