Remove the defunct remains of the TCPS_TIME_WAIT cases from tcp_do_segment

and change it to a void function.

We use a compressed structure for TCPS_TIME_WAIT to save memory.  Any late
late segments arriving for such a connection is handled directly in the TW
code.
This commit is contained in:
Andre Oppermann 2007-05-06 15:16:05 +00:00
parent f0256e71f1
commit 679d9708b6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169314
2 changed files with 34 additions and 130 deletions

View File

@ -175,7 +175,7 @@ struct inpcbhead tcb;
struct inpcbinfo tcbinfo;
static void tcp_dooptions(struct tcpopt *, u_char *, int, int);
static int tcp_do_segment(struct mbuf *, struct tcphdr *,
static void tcp_do_segment(struct mbuf *, struct tcphdr *,
struct socket *, struct tcpcb *, int, int);
static void tcp_dropwithreset(struct mbuf *, struct tcphdr *,
struct tcpcb *, int, int);
@ -867,13 +867,10 @@ tcp_input(struct mbuf *m, int off0)
* Process the segment and the data it
* contains. tcp_do_segment() consumes
* the mbuf chain and unlocks the inpcb.
* XXX: The potential return value of
* TIME_WAIT nuked is supposed to be
* handled above.
*/
if (tcp_do_segment(m, th, so, tp,
drop_hdrlen, tlen))
goto findpcb; /* TIME_WAIT nuked */
tcp_do_segment(m, th, so, tp, drop_hdrlen,
tlen);
INP_INFO_UNLOCK_ASSERT(&tcbinfo);
return;
}
if (thflags & TH_RST) {
@ -989,8 +986,8 @@ tcp_input(struct mbuf *m, int off0)
* state. tcp_do_segment() always consumes the mbuf chain, unlocks the
* inpcb, and unlocks the pcbinfo.
*/
if (tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen))
goto findpcb; /* XXX: TIME_WAIT was nuked. */
tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen);
INP_INFO_UNLOCK_ASSERT(&tcbinfo);
return;
dropwithreset:
@ -1009,7 +1006,7 @@ tcp_input(struct mbuf *m, int off0)
return;
}
static int
static void
tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct tcpcb *tp, int drop_hdrlen, int tlen)
{
@ -1032,7 +1029,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_INFO_WLOCK_ASSERT(&tcbinfo);
INP_LOCK_ASSERT(tp->t_inpcb);
KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__));
KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN",
__func__));
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT",
__func__));
/*
* Segment received on connection.
@ -1512,9 +1512,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
case TCPS_LAST_ACK:
case TCPS_CLOSING:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
break; /* continue normal processing */
}
@ -1616,11 +1613,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
"tcp_close.2: head not locked", __func__));
tp = tcp_close(tp);
break;
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
break;
}
}
goto drop;
@ -1738,23 +1730,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcpstat.tcps_rcvpackafterwin++;
if (todrop >= tlen) {
tcpstat.tcps_rcvbyteafterwin += tlen;
/*
* If a new connection request is received
* while in TIME_WAIT, drop the old connection
* and start over if the sequence numbers
* are above the previous ones.
*/
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
if (thflags & TH_SYN &&
tp->t_state == TCPS_TIME_WAIT &&
SEQ_GT(th->th_seq, tp->rcv_nxt)) {
KASSERT(headlocked, ("%s: trimthenstep6: "
"tcp_close.4: head not locked", __func__));
tp = tcp_close(tp);
/* XXX: Shouldn't be possible. */
return (1);
}
/*
* If window is closed can only take segments at
* window edge, and have to drop data and PUSH from
@ -1884,9 +1859,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
case TCPS_CLOSE_WAIT:
case TCPS_CLOSING:
case TCPS_LAST_ACK:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
if (SEQ_GT(th->th_ack, tp->snd_max)) {
tcpstat.tcps_rcvacktoomuch++;
goto dropafterack;
@ -2258,7 +2230,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_INFO_WUNLOCK(&tcbinfo);
headlocked = 0;
m_freem(m);
return (0);
return;
}
break;
@ -2276,17 +2248,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
goto drop;
}
break;
/*
* In TIME_WAIT state the only thing that should arrive
* is a retransmission of the remote FIN. Acknowledge
* it and restart the finack timer.
*/
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
tcp_timer_activate(tp, TT_2MSL, 2 * tcp_msl);
goto dropafterack;
}
}
@ -2494,16 +2455,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
"TCP_FIN_WAIT_2: head not locked", __func__));
tcp_twstart(tp);
INP_INFO_WUNLOCK(&tcbinfo);
return (0);
/*
* In TIME_WAIT state restart the 2 MSL time_wait timer.
*/
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
tcp_timer_activate(tp, TT_2MSL, 2 * tcp_msl);
break;
return;
}
}
INP_INFO_WUNLOCK(&tcbinfo);
@ -2530,7 +2482,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcp_timer_activate(tp, TT_DELACK, tcp_delacktime);
}
INP_UNLOCK(tp->t_inpcb);
return (0);
return;
dropafterack:
KASSERT(headlocked, ("%s: dropafterack: head not locked", __func__));
@ -2566,7 +2518,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(void) tcp_output(tp);
INP_UNLOCK(tp->t_inpcb);
m_freem(m);
return (0);
return;
dropwithreset:
KASSERT(headlocked, ("%s: dropwithreset: head not locked", __func__));
@ -2577,7 +2529,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_UNLOCK(tp->t_inpcb);
if (headlocked)
INP_INFO_WUNLOCK(&tcbinfo);
return (0);
return;
drop:
/*
@ -2593,7 +2545,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (headlocked)
INP_INFO_WUNLOCK(&tcbinfo);
m_freem(m);
return (0);
return;
}

View File

@ -175,7 +175,7 @@ struct inpcbhead tcb;
struct inpcbinfo tcbinfo;
static void tcp_dooptions(struct tcpopt *, u_char *, int, int);
static int tcp_do_segment(struct mbuf *, struct tcphdr *,
static void tcp_do_segment(struct mbuf *, struct tcphdr *,
struct socket *, struct tcpcb *, int, int);
static void tcp_dropwithreset(struct mbuf *, struct tcphdr *,
struct tcpcb *, int, int);
@ -867,13 +867,10 @@ tcp_input(struct mbuf *m, int off0)
* Process the segment and the data it
* contains. tcp_do_segment() consumes
* the mbuf chain and unlocks the inpcb.
* XXX: The potential return value of
* TIME_WAIT nuked is supposed to be
* handled above.
*/
if (tcp_do_segment(m, th, so, tp,
drop_hdrlen, tlen))
goto findpcb; /* TIME_WAIT nuked */
tcp_do_segment(m, th, so, tp, drop_hdrlen,
tlen);
INP_INFO_UNLOCK_ASSERT(&tcbinfo);
return;
}
if (thflags & TH_RST) {
@ -989,8 +986,8 @@ tcp_input(struct mbuf *m, int off0)
* state. tcp_do_segment() always consumes the mbuf chain, unlocks the
* inpcb, and unlocks the pcbinfo.
*/
if (tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen))
goto findpcb; /* XXX: TIME_WAIT was nuked. */
tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen);
INP_INFO_UNLOCK_ASSERT(&tcbinfo);
return;
dropwithreset:
@ -1009,7 +1006,7 @@ tcp_input(struct mbuf *m, int off0)
return;
}
static int
static void
tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct tcpcb *tp, int drop_hdrlen, int tlen)
{
@ -1032,7 +1029,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_INFO_WLOCK_ASSERT(&tcbinfo);
INP_LOCK_ASSERT(tp->t_inpcb);
KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__));
KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN",
__func__));
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT",
__func__));
/*
* Segment received on connection.
@ -1512,9 +1512,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
case TCPS_LAST_ACK:
case TCPS_CLOSING:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
break; /* continue normal processing */
}
@ -1616,11 +1613,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
"tcp_close.2: head not locked", __func__));
tp = tcp_close(tp);
break;
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
break;
}
}
goto drop;
@ -1738,23 +1730,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcpstat.tcps_rcvpackafterwin++;
if (todrop >= tlen) {
tcpstat.tcps_rcvbyteafterwin += tlen;
/*
* If a new connection request is received
* while in TIME_WAIT, drop the old connection
* and start over if the sequence numbers
* are above the previous ones.
*/
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
if (thflags & TH_SYN &&
tp->t_state == TCPS_TIME_WAIT &&
SEQ_GT(th->th_seq, tp->rcv_nxt)) {
KASSERT(headlocked, ("%s: trimthenstep6: "
"tcp_close.4: head not locked", __func__));
tp = tcp_close(tp);
/* XXX: Shouldn't be possible. */
return (1);
}
/*
* If window is closed can only take segments at
* window edge, and have to drop data and PUSH from
@ -1884,9 +1859,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
case TCPS_CLOSE_WAIT:
case TCPS_CLOSING:
case TCPS_LAST_ACK:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: timewait",
__func__));
if (SEQ_GT(th->th_ack, tp->snd_max)) {
tcpstat.tcps_rcvacktoomuch++;
goto dropafterack;
@ -2258,7 +2230,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_INFO_WUNLOCK(&tcbinfo);
headlocked = 0;
m_freem(m);
return (0);
return;
}
break;
@ -2276,17 +2248,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
goto drop;
}
break;
/*
* In TIME_WAIT state the only thing that should arrive
* is a retransmission of the remote FIN. Acknowledge
* it and restart the finack timer.
*/
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
tcp_timer_activate(tp, TT_2MSL, 2 * tcp_msl);
goto dropafterack;
}
}
@ -2494,16 +2455,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
"TCP_FIN_WAIT_2: head not locked", __func__));
tcp_twstart(tp);
INP_INFO_WUNLOCK(&tcbinfo);
return (0);
/*
* In TIME_WAIT state restart the 2 MSL time_wait timer.
*/
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT,
("%s: timewait", __func__));
tcp_timer_activate(tp, TT_2MSL, 2 * tcp_msl);
break;
return;
}
}
INP_INFO_WUNLOCK(&tcbinfo);
@ -2530,7 +2482,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcp_timer_activate(tp, TT_DELACK, tcp_delacktime);
}
INP_UNLOCK(tp->t_inpcb);
return (0);
return;
dropafterack:
KASSERT(headlocked, ("%s: dropafterack: head not locked", __func__));
@ -2566,7 +2518,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(void) tcp_output(tp);
INP_UNLOCK(tp->t_inpcb);
m_freem(m);
return (0);
return;
dropwithreset:
KASSERT(headlocked, ("%s: dropwithreset: head not locked", __func__));
@ -2577,7 +2529,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
INP_UNLOCK(tp->t_inpcb);
if (headlocked)
INP_INFO_WUNLOCK(&tcbinfo);
return (0);
return;
drop:
/*
@ -2593,7 +2545,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (headlocked)
INP_INFO_WUNLOCK(&tcbinfo);
m_freem(m);
return (0);
return;
}