summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timer.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-11-23 17:21:30 +0000
committerrwatson <rwatson@FreeBSD.org>2004-11-23 17:21:30 +0000
commit75d5a09a05cfc84f37a727d8c1598a9337b21c70 (patch)
tree3ce39c4cb642096bc4f16bb881a2f0e32e4e0a8e /sys/netinet/tcp_timer.c
parent53e97a895b3965eb3ce51576bbbc5b9c4f91d736 (diff)
downloadFreeBSD-src-75d5a09a05cfc84f37a727d8c1598a9337b21c70.zip
FreeBSD-src-75d5a09a05cfc84f37a727d8c1598a9337b21c70.tar.gz
tcp_timewait() performs multiple non-atomic reads on the tcptw
structure, so assert the inpcb lock associated with the tcptw. Also assert the tcbinfo lock, as tcp_timewait() may call tcp_twclose() or tcp_2msl_rest(), which require it. Since tcp_timewait() is already called with that lock from tcp_input(), this doesn't change current locking, merely documents reasons for it. In tcp_twstart(), assert the tcbinfo lock, as tcp_timer_2msl_rest() is called, which requires that lock. In tcp_twclose(), assert the tcbinfo lock, as tcp_timer_2msl_stop() is called, which requires that lock. Document the locking strategy for the time wait queues in tcp_timer.c, which consists of protecting the time wait queues in the same manner as the tcbinfo structure (using the tcbinfo lock). In tcp_timer_2msl_reset(), assert the tcbinfo lock, as the time wait queues are modified. In tcp_timer_2msl_stop(), assert the tcbinfo lock, as the time wait queues may be modified. In tcp_timer_2msl_tw(), assert the tcbinfo lock, as the time wait queues may be modified. MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/tcp_timer.c')
-rw-r--r--sys/netinet/tcp_timer.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index d4ae4a9..8fb49eb 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -246,6 +246,12 @@ tcp_timer_2msl(xtp)
INP_INFO_WUNLOCK(&tcbinfo);
}
+/*
+ * The timed wait lists contain references to each of the TCP sessions
+ * currently TIME_WAIT state. The list pointers, including the list pointers
+ * in each tcptw structure, are protected using the global tcbinfo lock,
+ * which must be held over list iteration and modification.
+ */
struct twlist {
LIST_HEAD(, tcptw) tw_list;
struct tcptw tw_tail;
@@ -273,6 +279,7 @@ tcp_timer_2msl_reset(struct tcptw *tw, int timeo)
int i;
struct tcptw *tw_tail;
+ INP_INFO_WLOCK_ASSERT(&tcbinfo);
if (tw->tw_time != 0)
LIST_REMOVE(tw, tw_2msl);
tw->tw_time = timeo + ticks;
@@ -285,6 +292,7 @@ void
tcp_timer_2msl_stop(struct tcptw *tw)
{
+ INP_INFO_WLOCK_ASSERT(&tcbinfo);
if (tw->tw_time != 0)
LIST_REMOVE(tw, tw_2msl);
}
@@ -296,6 +304,7 @@ tcp_timer_2msl_tw(int reuse)
struct twlist *twl;
int i;
+ INP_INFO_WLOCK_ASSERT(&tcbinfo);
for (i = 0; i < 2; i++) {
twl = tw_2msl_list[i];
tw_tail = &twl->tw_tail;
OpenPOWER on IntegriCloud