diff options
author | hsu <hsu@FreeBSD.org> | 2003-02-24 00:52:03 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2003-02-24 00:52:03 +0000 |
commit | 90305f610e4b2182611ab7bfa314ae25de0f12d2 (patch) | |
tree | 37630d99818b41fcf8172ae65ec007354258e187 /sys | |
parent | 06f0413c15c9b30e7951763c79d1d49358f870f6 (diff) | |
download | FreeBSD-src-90305f610e4b2182611ab7bfa314ae25de0f12d2.zip FreeBSD-src-90305f610e4b2182611ab7bfa314ae25de0f12d2.tar.gz |
tcp_twstart() need to be called with the TCP protocol lock held to avoid
a race condition with the TCP timer routines.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_input.c | 14 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 14 |
2 files changed, 16 insertions, 12 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 1284689..63d1c1c 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1963,9 +1963,9 @@ process_ACK: case TCPS_CLOSING: if (ourfinisacked) { KASSERT(headlocked, ("headlocked")); + tcp_twstart(tp); INP_INFO_WUNLOCK(&tcbinfo); m_freem(m); - tcp_twstart(tp); return; } break; @@ -2078,8 +2078,10 @@ step6: } dodata: /* XXX */ KASSERT(headlocked, ("headlocked")); - INP_INFO_WUNLOCK(&tcbinfo); - headlocked = 0; + if (!(thflags & TH_FIN && tp->t_state == TCPS_FIN_WAIT_2)) { + INP_INFO_WUNLOCK(&tcbinfo); + headlocked = 0; + } /* * Process the segment text, merging it into the TCP sequencing queue, * and arranging for acknowledgment of receipt if necessary. @@ -2183,8 +2185,9 @@ dodata: /* XXX */ * standard timers. */ case TCPS_FIN_WAIT_2: - KASSERT(headlocked == 0, ("headlocked")); + KASSERT(headlocked == 1, ("headlocked should be 1")); tcp_twstart(tp); + INP_INFO_WUNLOCK(&tcbinfo); return; /* @@ -2211,11 +2214,10 @@ dodata: /* XXX */ check_delack: if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; - KASSERT(!callout_active(tp->tt_delack), - ("delayed ack already active")); callout_reset(tp->tt_delack, tcp_delacktime, tcp_timer_delack, tp); } + KASSERT(headlocked == 0, ("headlocked should be 0")); INP_UNLOCK(inp); return; diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 1284689..63d1c1c 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -1963,9 +1963,9 @@ process_ACK: case TCPS_CLOSING: if (ourfinisacked) { KASSERT(headlocked, ("headlocked")); + tcp_twstart(tp); INP_INFO_WUNLOCK(&tcbinfo); m_freem(m); - tcp_twstart(tp); return; } break; @@ -2078,8 +2078,10 @@ step6: } dodata: /* XXX */ KASSERT(headlocked, ("headlocked")); - INP_INFO_WUNLOCK(&tcbinfo); - headlocked = 0; + if (!(thflags & TH_FIN && tp->t_state == TCPS_FIN_WAIT_2)) { + INP_INFO_WUNLOCK(&tcbinfo); + headlocked = 0; + } /* * Process the segment text, merging it into the TCP sequencing queue, * and arranging for acknowledgment of receipt if necessary. @@ -2183,8 +2185,9 @@ dodata: /* XXX */ * standard timers. */ case TCPS_FIN_WAIT_2: - KASSERT(headlocked == 0, ("headlocked")); + KASSERT(headlocked == 1, ("headlocked should be 1")); tcp_twstart(tp); + INP_INFO_WUNLOCK(&tcbinfo); return; /* @@ -2211,11 +2214,10 @@ dodata: /* XXX */ check_delack: if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; - KASSERT(!callout_active(tp->tt_delack), - ("delayed ack already active")); callout_reset(tp->tt_delack, tcp_delacktime, tcp_timer_delack, tp); } + KASSERT(headlocked == 0, ("headlocked should be 0")); INP_UNLOCK(inp); return; |