Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_input.c
Show First 20 Lines • Show All 2,252 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); | ||||
} | } | ||||
/* | |||||
* DSACK - add SACK block for dropped range | |||||
*/ | |||||
if (tp->t_flags & TF_SACK_PERMIT) { | |||||
tcp_update_sack_list(tp, th->th_seq, th->th_seq+tlen); | |||||
/* | |||||
* ACK now, as the next in-sequence segment | |||||
* will clear the DSACK block again | |||||
*/ | |||||
tp->t_flags |= TF_ACKNOW; | |||||
} | |||||
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 712 Lines • ▼ Show 20 Lines | dodata: /* XXX */ | ||||
* case PRU_RCVD). If a FIN has already been received on this | * case PRU_RCVD). If a FIN has already been received on this | ||||
* connection then we just ignore the text. | * connection then we just ignore the text. | ||||
*/ | */ | ||||
tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && | tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && | ||||
IS_FASTOPEN(tp->t_flags)); | IS_FASTOPEN(tp->t_flags)); | ||||
if ((tlen || (thflags & TH_FIN) || tfo_syn) && | if ((tlen || (thflags & TH_FIN) || tfo_syn) && | ||||
TCPS_HAVERCVDFIN(tp->t_state) == 0) { | TCPS_HAVERCVDFIN(tp->t_state) == 0) { | ||||
tcp_seq save_start = th->th_seq; | tcp_seq save_start = th->th_seq; | ||||
tcp_seq save_rnxt = tp->rcv_nxt; | |||||
int save_tlen = tlen; | |||||
m_adj(m, drop_hdrlen); /* delayed header drop */ | m_adj(m, drop_hdrlen); /* delayed header drop */ | ||||
/* | /* | ||||
* Insert segment which includes th into TCP reassembly queue | * Insert segment which includes th into TCP reassembly queue | ||||
* with control block tp. Set thflags to whether reassembly now | * with control block tp. Set thflags to whether reassembly now | ||||
* includes a segment with FIN. This handles the common case | * includes a segment with FIN. This handles the common case | ||||
* inline (segment is the next to be received on an established | * inline (segment is the next to be received on an established | ||||
* connection, and the queue is empty), avoiding linkage into | * connection, and the queue is empty), avoiding linkage into | ||||
* and removal from the queue and repetition of various | * and removal from the queue and repetition of various | ||||
Show All 23 Lines | if (th->th_seq == tp->rcv_nxt && | ||||
sorwakeup_locked(so); | sorwakeup_locked(so); | ||||
} else { | } else { | ||||
/* | /* | ||||
* XXX: Due to the header drop above "th" is | * XXX: Due to the header drop above "th" is | ||||
* theoretically invalid by now. Fortunately | * theoretically invalid by now. Fortunately | ||||
* m_adj() doesn't actually frees any mbufs | * m_adj() doesn't actually frees any mbufs | ||||
* when trimming from the head. | * when trimming from the head. | ||||
*/ | */ | ||||
thflags = tcp_reass(tp, th, &save_start, &tlen, m); | tcp_seq temp = save_start; | ||||
thflags = tcp_reass(tp, th, &temp, &tlen, m); | |||||
tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; | ||||
} | } | ||||
if (tlen > 0 && (tp->t_flags & TF_SACK_PERMIT)) | if (tp->t_flags & TF_SACK_PERMIT) { | ||||
if (((tlen == 0) && (save_tlen > 0) && | |||||
(SEQ_LT(save_start, save_rnxt)))) { | |||||
// DSACK actually handled in the fastpath above | |||||
tcp_update_sack_list(tp, save_start, save_start + save_tlen); | |||||
} else | |||||
if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { | |||||
// cleaning sackblks by using zero length update | |||||
tcp_update_sack_list(tp, save_start, save_start); | |||||
} else | |||||
if ((tlen > 0) && (tlen >= save_tlen)) { | |||||
// update of sackblks | |||||
tcp_update_sack_list(tp, save_start, save_start + save_tlen); | |||||
} else | |||||
if (tlen > 0) { | |||||
tcp_update_sack_list(tp, save_start, save_start + tlen); | tcp_update_sack_list(tp, save_start, save_start+tlen); | ||||
} | |||||
} | |||||
#if 0 | #if 0 | ||||
/* | /* | ||||
* Note the amount of data that peer has sent into | * Note the amount of data that peer has sent into | ||||
* our window, in order to estimate the sender's | * our window, in order to estimate the sender's | ||||
* buffer size. | * buffer size. | ||||
* XXX: Unused. | * XXX: Unused. | ||||
*/ | */ | ||||
if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) | if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) | ||||
▲ Show 20 Lines • Show All 788 Lines • Show Last 20 Lines |