Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_output.c
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/protosw.h> | #include <sys/protosw.h> | ||||
#include <sys/sdt.h> | #include <sys/sdt.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/socketvar.h> | #include <sys/socketvar.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/syslog.h> | |||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_kdtrace.h> | #include <netinet/in_kdtrace.h> | ||||
#include <netinet/in_systm.h> | #include <netinet/in_systm.h> | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | again: | ||||
*/ | */ | ||||
/* | /* | ||||
* Still in sack recovery , reset rxmit flag to zero. | * Still in sack recovery , reset rxmit flag to zero. | ||||
*/ | */ | ||||
sack_rxmit = 0; | sack_rxmit = 0; | ||||
sack_bytes_rxmt = 0; | sack_bytes_rxmt = 0; | ||||
len = 0; | len = 0; | ||||
p = NULL; | p = NULL; | ||||
if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags) && | |||||
(p = tcp_sack_output(tp, &sack_bytes_rxmt))) { | LOGTCPCBSTATE2; | ||||
if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags)) { | |||||
p = tcp_sack_output(tp, &sack_bytes_rxmt); | |||||
/* | |||||
* RFC6675 Rescue Retransmission | |||||
* when no new data is available, and | |||||
* all Scoreboard Holes were retransmitted, | |||||
* resend 1 MSS just beneath snd_max | |||||
*/ | |||||
uint32_t cwin; | uint32_t cwin; | ||||
cwin = | cwin = | ||||
imax(min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt, 0); | imax(min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt, 0); | ||||
/* if (V_tcp_do_rfc6675_pipe && (p == NULL) && | |||||
SEQ_GT(tp->snd_max, tp->snd_una) && | |||||
((tp->snd_max - tp->snd_una) == sbavail(&so->so_snd))) { | |||||
// if (so->so_options & SO_DEBUG) { | |||||
// log(LOG_DEBUG,"rfc6675 rescue retransmission"); | |||||
// } | |||||
len = ((int32_t)ulmin(tp->t_maxseg, cwin)); | |||||
tp->snd_nxt = tp->snd_max - len - tp->snd_una; | |||||
sendalot = 1; | |||||
TCPSTAT_INC(tcps_sack_rescxmits); | |||||
TCPSTAT_ADD(tcps_sack_rescxmit_bytes, len); | |||||
} | |||||
*/ if (p != NULL) { | |||||
/* Do not retransmit SACK segments beyond snd_recover */ | /* Do not retransmit SACK segments beyond snd_recover */ | ||||
if (SEQ_GT(p->end, tp->snd_recover)) { | if (SEQ_GT(p->end, tp->snd_recover)) { | ||||
/* | /* | ||||
* (At least) part of sack hole extends beyond | * (At least) part of sack hole extends beyond | ||||
* snd_recover. Check to see if we can rexmit data | * snd_recover. Check to see if we can rexmit data | ||||
* for this hole. | * for this hole. | ||||
*/ | */ | ||||
if (SEQ_GEQ(p->rxmit, tp->snd_recover)) { | if (SEQ_GEQ(p->rxmit, tp->snd_recover)) { | ||||
/* | /* | ||||
* Can't rexmit any more data for this hole. | * Can't rexmit any more data for this hole. | ||||
* That data will be rexmitted in the next | * That data will be rexmitted in the next | ||||
* sack recovery episode, when snd_recover | * sack recovery episode, when snd_recover | ||||
* moves past p->rxmit. | * moves past p->rxmit. | ||||
*/ | */ | ||||
p = NULL; | p = NULL; | ||||
goto after_sack_rexmit; | goto after_sack_rexmit; | ||||
} else | } else | ||||
/* Can rexmit part of the current hole */ | /* Can rexmit part of the current hole */ | ||||
len = ((int32_t)ulmin(cwin, | len = ((int32_t)ulmin(cwin, | ||||
tp->snd_recover - p->rxmit)); | tp->snd_recover - p->rxmit)); | ||||
} else | } else | ||||
len = ((int32_t)ulmin(cwin, p->end - p->rxmit)); | len = ((int32_t)ulmin(cwin, p->end - p->rxmit)); | ||||
off = p->rxmit - tp->snd_una; | off = p->rxmit - tp->snd_una; | ||||
if (off < 0) { | |||||
log(LOG_DEBUG,"near panic: una: %u, rxmit: %u, start: %u, end:%u, len: %i\n", | |||||
tp->snd_una - tp->iss, p->rxmit - tp->iss, p->start - tp->iss, p->end - tp->iss, len); | |||||
off = 0; | |||||
} | |||||
KASSERT(off >= 0,("%s: sack block to the left of una : %d", | KASSERT(off >= 0,("%s: sack block to the left of una : %d", | ||||
__func__, off)); | __func__, off)); | ||||
if (len > 0) { | if (len > 0) { | ||||
sack_rxmit = 1; | sack_rxmit = 1; | ||||
sendalot = 1; | sendalot = 1; | ||||
TCPSTAT_INC(tcps_sack_rexmits); | TCPSTAT_INC(tcps_sack_rexmits); | ||||
TCPSTAT_ADD(tcps_sack_rexmit_bytes, | TCPSTAT_ADD(tcps_sack_rexmit_bytes, | ||||
min(len, tp->t_maxseg)); | min(len, tp->t_maxseg)); | ||||
} | } | ||||
} | } | ||||
} | |||||
after_sack_rexmit: | after_sack_rexmit: | ||||
/* | /* | ||||
* Get standard flags, and add SYN or FIN if requested by 'hidden' | * Get standard flags, and add SYN or FIN if requested by 'hidden' | ||||
* state flags. | * state flags. | ||||
*/ | */ | ||||
if (tp->t_flags & TF_NEEDFIN) | if (tp->t_flags & TF_NEEDFIN) | ||||
flags |= TH_FIN; | flags |= TH_FIN; | ||||
if (tp->t_flags & TF_NEEDSYN) | if (tp->t_flags & TF_NEEDSYN) | ||||
▲ Show 20 Lines • Show All 1,065 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
} else { | } else { | ||||
tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; | tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; | ||||
} | } | ||||
if (tp->t_state == TCPS_SYN_SENT) | if (tp->t_state == TCPS_SYN_SENT) | ||||
TCP_PROBE5(connect__request, NULL, tp, ip, tp, th); | TCP_PROBE5(connect__request, NULL, tp, ip, tp, th); | ||||
TCP_PROBE5(send, NULL, tp, ip, tp, th); | TCP_PROBE5(send, NULL, tp, ip, tp, th); | ||||
if (so->so_options & SO_DEBUG) | |||||
log(LOG_DEBUG, "tcp_output:1444 hand off to IP\n"); | |||||
#ifdef TCPPCAP | #ifdef TCPPCAP | ||||
/* Save packet, if requested. */ | /* Save packet, if requested. */ | ||||
tcp_pcap_add(th, m, &(tp->t_outpkts)); | tcp_pcap_add(th, m, &(tp->t_outpkts)); | ||||
#endif | #endif | ||||
error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, | error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, | ||||
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0, | ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0, | ||||
▲ Show 20 Lines • Show All 592 Lines • Show Last 20 Lines |