Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 993 Lines • ▼ Show 20 Lines | if (isipv6) { | ||||
if (inp->inp_ip_minttl > ip6->ip6_hlim) | if (inp->inp_ip_minttl > ip6->ip6_hlim) | ||||
goto dropunlock; | goto dropunlock; | ||||
} else | } else | ||||
#endif | #endif | ||||
if (inp->inp_ip_minttl > ip->ip_ttl) | if (inp->inp_ip_minttl > ip->ip_ttl) | ||||
goto dropunlock; | goto dropunlock; | ||||
} | } | ||||
tp = intotcpcb(inp); | |||||
switch (tp->t_state) { | |||||
case TCPS_TIME_WAIT: | |||||
/* | /* | ||||
* A previous connection in TIMEWAIT state is supposed to catch stray | * A previous connection in TIMEWAIT state is supposed to catch | ||||
* or duplicate segments arriving late. If this segment was a | * stray or duplicate segments arriving late. If this segment | ||||
* legitimate new connection attempt, the old INPCB gets removed and | * was a legitimate new connection attempt, the old INPCB gets | ||||
* we can try again to find a listening socket. | * removed and we can try again to find a listening socket. | ||||
*/ | */ | ||||
if (inp->inp_flags & INP_TIMEWAIT) { | |||||
tcp_dooptions(&to, optp, optlen, | tcp_dooptions(&to, optp, optlen, | ||||
(thflags & TH_SYN) ? TO_SYN : 0); | (thflags & TH_SYN) ? TO_SYN : 0); | ||||
/* | /* | ||||
* NB: tcp_twcheck unlocks the INP and frees the mbuf. | * tcp_twcheck unlocks the inp always, and frees the m if fails. | ||||
*/ | */ | ||||
if (tcp_twcheck(inp, &to, th, m, tlen)) | if (tcp_twcheck(inp, &to, th, m, tlen)) | ||||
goto findpcb; | goto findpcb; | ||||
return (IPPROTO_DONE); | return (IPPROTO_DONE); | ||||
} | case TCPS_CLOSED: | ||||
/* | /* | ||||
* The TCPCB may no longer exist if the connection is winding | * The TCPCB may no longer exist if the connection is winding | ||||
* down or it is in the CLOSED state. Either way we drop the | * down or it is in the CLOSED state. Either way we drop the | ||||
* segment and send an appropriate response. | * segment and send an appropriate response. | ||||
*/ | */ | ||||
tp = intotcpcb(inp); | |||||
if (tp == NULL || tp->t_state == TCPS_CLOSED) { | |||||
rstreason = BANDLIM_RST_CLOSEDPORT; | rstreason = BANDLIM_RST_CLOSEDPORT; | ||||
goto dropwithreset; | goto dropwithreset; | ||||
} | } | ||||
if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { | if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { | ||||
rstreason = BANDLIM_RST_CLOSEDPORT; | rstreason = BANDLIM_RST_CLOSEDPORT; | ||||
goto dropwithreset; | goto dropwithreset; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,992 Lines • ▼ Show 20 Lines | process_ACK: | ||||
case TCPS_FIN_WAIT_1: | case TCPS_FIN_WAIT_1: | ||||
if (ourfinisacked) { | if (ourfinisacked) { | ||||
/* | /* | ||||
* If we can't receive any more | * If we can't receive any more | ||||
* data, then closing user can proceed. | * data, then closing user can proceed. | ||||
* Starting the timer is contrary to the | * Starting the timer is contrary to the | ||||
* specification, but if we don't get a FIN | * specification, but if we don't get a FIN | ||||
* we'll hang forever. | * we'll hang forever. | ||||
* | |||||
* XXXjl: | |||||
* we should release the tp also, and use a | |||||
* compressed state. | |||||
*/ | */ | ||||
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | ||||
soisdisconnected(so); | soisdisconnected(so); | ||||
tcp_timer_activate(tp, TT_2MSL, | tcp_timer_activate(tp, TT_2MSL, | ||||
(tcp_fast_finwait2_recycle ? | (tcp_fast_finwait2_recycle ? | ||||
tcp_finwait2_timeout : | tcp_finwait2_timeout : | ||||
TP_MAXIDLE(tp))); | TP_MAXIDLE(tp))); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,097 Lines • Show Last 20 Lines |