Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_stacks/rack.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 1,777 Lines • ▼ Show 20 Lines | if (todrop > tlen | ||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
todrop = tlen; | todrop = tlen; | ||||
TCPSTAT_INC(tcps_rcvduppack); | TCPSTAT_INC(tcps_rcvduppack); | ||||
TCPSTAT_ADD(tcps_rcvdupbyte, todrop); | TCPSTAT_ADD(tcps_rcvdupbyte, todrop); | ||||
} else { | } else { | ||||
TCPSTAT_INC(tcps_rcvpartduppack); | TCPSTAT_INC(tcps_rcvpartduppack); | ||||
TCPSTAT_ADD(tcps_rcvpartdupbyte, todrop); | TCPSTAT_ADD(tcps_rcvpartdupbyte, todrop); | ||||
} | } | ||||
if (tp->t_flags & TF_SACK_PERMIT) { | |||||
/* | |||||
* record the left, to-be-dropped edge of data | |||||
* here, for use as dsack block further down | |||||
*/ | |||||
tcp_update_sack_list(tp, th->th_seq, | |||||
th->th_seq + todrop); | |||||
} | |||||
*drop_hdrlen += todrop; /* drop from the top afterwards */ | *drop_hdrlen += todrop; /* drop from the top afterwards */ | ||||
th->th_seq += todrop; | th->th_seq += todrop; | ||||
tlen -= todrop; | tlen -= todrop; | ||||
if (th->th_urp > todrop) | if (th->th_urp > todrop) | ||||
th->th_urp -= todrop; | th->th_urp -= todrop; | ||||
else { | else { | ||||
thflags &= ~TH_URG; | thflags &= ~TH_URG; | ||||
th->th_urp = 0; | th->th_urp = 0; | ||||
▲ Show 20 Lines • Show All 3,101 Lines • ▼ Show 20 Lines | if ((tlen || (thflags & TH_FIN) || tfo_syn) && | ||||
* segments received in order, but ack immediately when | * segments received in order, but ack immediately when | ||||
* segments are out of order (so fast retransmit can work). | * segments are out of order (so fast retransmit can work). | ||||
*/ | */ | ||||
if (th->th_seq == tp->rcv_nxt && | if (th->th_seq == tp->rcv_nxt && | ||||
SEGQ_EMPTY(tp) && | SEGQ_EMPTY(tp) && | ||||
(TCPS_HAVEESTABLISHED(tp->t_state) || | (TCPS_HAVEESTABLISHED(tp->t_state) || | ||||
tfo_syn)) { | tfo_syn)) { | ||||
if (DELAY_ACK(tp, tlen) || tfo_syn) { | if (DELAY_ACK(tp, tlen) || tfo_syn) { | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, | ||||
rack->r_ctl.rc_rcvtime, __LINE__); | |||||
tp->t_flags |= TF_DELACK; | tp->t_flags |= TF_DELACK; | ||||
} else { | } else { | ||||
rack->r_wanted_output++; | rack->r_wanted_output++; | ||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
} | } | ||||
tp->rcv_nxt += tlen; | tp->rcv_nxt += tlen; | ||||
thflags = th->th_flags & TH_FIN; | thflags = th->th_flags & TH_FIN; | ||||
TCPSTAT_ADD(tcps_rcvpack, nsegs); | TCPSTAT_ADD(tcps_rcvpack, nsegs); | ||||
Show All 17 Lines | if (th->th_seq == tp->rcv_nxt && | ||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
} | } | ||||
if (((tlen == 0) && (save_tlen > 0) && | if (((tlen == 0) && (save_tlen > 0) && | ||||
(SEQ_LT(save_start, save_rnxt)))) { | (SEQ_LT(save_start, save_rnxt)))) { | ||||
/* | /* | ||||
* DSACK actually handled in the fastpath | * DSACK actually handled in the fastpath | ||||
* above. | * above. | ||||
*/ | */ | ||||
tcp_update_sack_list(tp, save_start, save_start + save_tlen); | tcp_update_sack_list(tp, save_start, | ||||
save_start + save_tlen); | |||||
} else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { | } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { | ||||
/* | /* | ||||
* Cleaning sackblks by using zero length | * Cleaning sackblks by using zero length | ||||
* update. | * update. | ||||
*/ | */ | ||||
tcp_update_sack_list(tp, save_start, save_start); | if ((tp->rcv_numsacks >= 1) && | ||||
(tp->sackblks[0].end == save_start)) { | |||||
/* partial overlap, recorded at todrop above */ | |||||
tcp_update_sack_list(tp, tp->sackblks[0].start, | |||||
tp->sackblks[0].end); | |||||
} else { | |||||
tcp_update_dsack_list(tp, save_start, | |||||
save_start + save_tlen); | |||||
} | |||||
} else if ((tlen > 0) && (tlen >= save_tlen)) { | } else if ((tlen > 0) && (tlen >= save_tlen)) { | ||||
/* Update of sackblks. */ | /* Update of sackblks. */ | ||||
tcp_update_sack_list(tp, save_start, save_start + save_tlen); | tcp_update_dsack_list(tp, save_start, | ||||
save_start + save_tlen); | |||||
} else if (tlen > 0) { | } else if (tlen > 0) { | ||||
tcp_update_sack_list(tp, save_start, save_start+tlen); | tcp_update_dsack_list(tp, save_start, | ||||
save_start + tlen); | |||||
} | } | ||||
} else { | } else { | ||||
m_freem(m); | m_freem(m); | ||||
thflags &= ~TH_FIN; | thflags &= ~TH_FIN; | ||||
} | } | ||||
/* | /* | ||||
* If FIN is received ACK the FIN and let the user know that the | * If FIN is received ACK the FIN and let the user know that the | ||||
* connection is closing. | * connection is closing. | ||||
*/ | */ | ||||
if (thflags & TH_FIN) { | if (thflags & TH_FIN) { | ||||
if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { | if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { | ||||
socantrcvmore(so); | socantrcvmore(so); | ||||
/* | /* | ||||
* If connection is half-synchronized (ie NEEDSYN | * If connection is half-synchronized (ie NEEDSYN | ||||
* flag on) then delay ACK, so it may be piggybacked | * flag on) then delay ACK, so it may be piggybacked | ||||
* when SYN is sent. Otherwise, since we received a | * when SYN is sent. Otherwise, since we received a | ||||
* FIN then no more input can be expected, send ACK | * FIN then no more input can be expected, send ACK | ||||
* now. | * now. | ||||
*/ | */ | ||||
if (tp->t_flags & TF_NEEDSYN) { | if (tp->t_flags & TF_NEEDSYN) { | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, | ||||
rack->r_ctl.rc_rcvtime, __LINE__); | |||||
tp->t_flags |= TF_DELACK; | tp->t_flags |= TF_DELACK; | ||||
} else { | } else { | ||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
} | } | ||||
tp->rcv_nxt++; | tp->rcv_nxt++; | ||||
} | } | ||||
switch (tp->t_state) { | switch (tp->t_state) { | ||||
/* | /* | ||||
* In SYN_RECEIVED and ESTABLISHED STATES enter the | * In SYN_RECEIVED and ESTABLISHED STATES enter the | ||||
* CLOSE_WAIT state. | * CLOSE_WAIT state. | ||||
*/ | */ | ||||
case TCPS_SYN_RECEIVED: | case TCPS_SYN_RECEIVED: | ||||
tp->t_starttime = ticks; | tp->t_starttime = ticks; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case TCPS_ESTABLISHED: | case TCPS_ESTABLISHED: | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, | ||||
rack->r_ctl.rc_rcvtime, __LINE__); | |||||
tcp_state_change(tp, TCPS_CLOSE_WAIT); | tcp_state_change(tp, TCPS_CLOSE_WAIT); | ||||
break; | break; | ||||
/* | /* | ||||
* If still in FIN_WAIT_1 STATE FIN has not been | * If still in FIN_WAIT_1 STATE FIN has not been | ||||
* acked so enter the CLOSING state. | * acked so enter the CLOSING state. | ||||
*/ | */ | ||||
case TCPS_FIN_WAIT_1: | case TCPS_FIN_WAIT_1: | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, | ||||
rack->r_ctl.rc_rcvtime, __LINE__); | |||||
tcp_state_change(tp, TCPS_CLOSING); | tcp_state_change(tp, TCPS_CLOSING); | ||||
break; | break; | ||||
/* | /* | ||||
* In FIN_WAIT_2 state enter the TIME_WAIT state, | * In FIN_WAIT_2 state enter the TIME_WAIT state, | ||||
* starting the time-wait timer, turning off the | * starting the time-wait timer, turning off the | ||||
* other standard timers. | * other standard timers. | ||||
*/ | */ | ||||
case TCPS_FIN_WAIT_2: | case TCPS_FIN_WAIT_2: | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, | ||||
rack->r_ctl.rc_rcvtime, __LINE__); | |||||
INP_INFO_RLOCK_ASSERT(&V_tcbinfo); | INP_INFO_RLOCK_ASSERT(&V_tcbinfo); | ||||
tcp_twstart(tp); | tcp_twstart(tp); | ||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Return any desired output. | * Return any desired output. | ||||
*/ | */ | ||||
if ((tp->t_flags & TF_ACKNOW) || (sbavail(&so->so_snd) > (tp->snd_max - tp->snd_una))) { | if ((tp->t_flags & TF_ACKNOW) || | ||||
(sbavail(&so->so_snd) > (tp->snd_max - tp->snd_una))) { | |||||
rack->r_wanted_output++; | rack->r_wanted_output++; | ||||
} | } | ||||
INP_WLOCK_ASSERT(tp->t_inpcb); | INP_WLOCK_ASSERT(tp->t_inpcb); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Here nothing is really faster, its just that we | * Here nothing is really faster, its just that we | ||||
▲ Show 20 Lines • Show All 4,192 Lines • Show Last 20 Lines |