Lines Matching full:tp

258 tcp_is_sack_recovery(struct tcpcb *tp, struct tcpopt *to)  in tcp_is_sack_recovery()  argument
260 return ((tp->t_flags & TF_SACK_PERMIT) && in tcp_is_sack_recovery()
262 (!TAILQ_EMPTY(&tp->snd_holes)))); in tcp_is_sack_recovery()
270 hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) in hhook_run_tcp_est_in() argument
275 hhook_data.tp = tp; in hhook_run_tcp_est_in()
280 &tp->t_osd); in hhook_run_tcp_est_in()
289 cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t nsegs, in cc_ack_received() argument
296 INP_WLOCK_ASSERT(tptoinpcb(tp)); in cc_ack_received()
298 tp->t_ccv.nsegs = nsegs; in cc_ack_received()
299 tp->t_ccv.bytes_this_ack = BYTES_THIS_ACK(tp, th); in cc_ack_received()
300 if ((!V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd)) || in cc_ack_received()
301 (V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd) && in cc_ack_received()
302 (tp->snd_cwnd < (tcp_compute_pipe(tp) * 2)))) in cc_ack_received()
303 tp->t_ccv.flags |= CCF_CWND_LIMITED; in cc_ack_received()
305 tp->t_ccv.flags &= ~CCF_CWND_LIMITED; in cc_ack_received()
309 stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, in cc_ack_received()
310 ((int32_t)tp->snd_cwnd) - tp->snd_wnd); in cc_ack_received()
311 if (!IN_RECOVERY(tp->t_flags)) in cc_ack_received()
312 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_ACKLEN, in cc_ack_received()
313 tp->t_ccv.bytes_this_ack / (tcp_maxseg(tp) * nsegs)); in cc_ack_received()
314 if ((tp->t_flags & TF_GPUTINPROG) && in cc_ack_received()
315 SEQ_GEQ(th->th_ack, tp->gput_ack)) { in cc_ack_received()
319 gput = (((int64_t)SEQ_SUB(th->th_ack, tp->gput_seq)) << 3) / in cc_ack_received()
320 max(1, tcp_ts_getticks() - tp->gput_ts); in cc_ack_received()
321 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, in cc_ack_received()
328 if (tp->t_stats_gput_prev > 0) in cc_ack_received()
329 stats_voi_update_abs_s32(tp->t_stats, in cc_ack_received()
331 ((gput - tp->t_stats_gput_prev) * 100) / in cc_ack_received()
332 tp->t_stats_gput_prev); in cc_ack_received()
333 tp->t_flags &= ~TF_GPUTINPROG; in cc_ack_received()
334 tp->t_stats_gput_prev = gput; in cc_ack_received()
337 if (tp->snd_cwnd > tp->snd_ssthresh) { in cc_ack_received()
338 tp->t_bytes_acked += tp->t_ccv.bytes_this_ack; in cc_ack_received()
339 if (tp->t_bytes_acked >= tp->snd_cwnd) { in cc_ack_received()
340 tp->t_bytes_acked -= tp->snd_cwnd; in cc_ack_received()
341 tp->t_ccv.flags |= CCF_ABC_SENTAWND; in cc_ack_received()
344 tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; in cc_ack_received()
345 tp->t_bytes_acked = 0; in cc_ack_received()
349 if (CC_ALGO(tp)->ack_received != NULL) { in cc_ack_received()
351 tp->t_ccv.curack = th->th_ack; in cc_ack_received()
352 CC_ALGO(tp)->ack_received(&tp->t_ccv, type); in cc_ack_received()
355 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, tp->snd_cwnd); in cc_ack_received()
360 cc_conn_init(struct tcpcb *tp) in cc_conn_init() argument
363 struct inpcb *inp = tptoinpcb(tp); in cc_conn_init()
370 maxseg = tcp_maxseg(tp); in cc_conn_init()
372 if (tp->t_srtt == 0 && (rtt = metrics.hc_rtt)) { in cc_conn_init()
373 tp->t_srtt = rtt; in cc_conn_init()
376 tp->t_rttvar = metrics.hc_rttvar; in cc_conn_init()
380 tp->t_rttvar = in cc_conn_init()
381 tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; in cc_conn_init()
383 TCPT_RANGESET(tp->t_rxtcur, in cc_conn_init()
384 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, in cc_conn_init()
385 tp->t_rttmin, tcp_rexmit_max); in cc_conn_init()
394 tp->snd_ssthresh = max(2 * maxseg, metrics.hc_ssthresh); in cc_conn_init()
405 if (tp->snd_cwnd == 1) in cc_conn_init()
406 tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ in cc_conn_init()
408 tp->snd_cwnd = tcp_compute_initwnd(maxseg); in cc_conn_init()
410 if (CC_ALGO(tp)->conn_init != NULL) in cc_conn_init()
411 CC_ALGO(tp)->conn_init(&tp->t_ccv); in cc_conn_init()
415 cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) in cc_cong_signal() argument
417 INP_WLOCK_ASSERT(tptoinpcb(tp)); in cc_cong_signal()
420 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); in cc_cong_signal()
425 if (!IN_FASTRECOVERY(tp->t_flags)) { in cc_cong_signal()
426 tp->snd_recover = tp->snd_max; in cc_cong_signal()
427 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
428 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
432 if (!IN_CONGRECOVERY(tp->t_flags) || in cc_cong_signal()
437 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in cc_cong_signal()
438 EXIT_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
440 tp->snd_recover = tp->snd_max + 1; in cc_cong_signal()
441 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
442 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
446 tp->t_dupacks = 0; in cc_cong_signal()
447 tp->t_bytes_acked = 0; in cc_cong_signal()
448 EXIT_RECOVERY(tp->t_flags); in cc_cong_signal()
449 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
450 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
455 tp->snd_cwnd = tp->snd_cwnd_prev; in cc_cong_signal()
456 tp->snd_ssthresh = tp->snd_ssthresh_prev; in cc_cong_signal()
457 tp->snd_recover = tp->snd_recover_prev; in cc_cong_signal()
458 if (tp->t_flags & TF_WASFRECOVERY) in cc_cong_signal()
459 ENTER_FASTRECOVERY(tp->t_flags); in cc_cong_signal()
460 if (tp->t_flags & TF_WASCRECOVERY) in cc_cong_signal()
461 ENTER_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
462 tp->snd_nxt = tp->snd_max; in cc_cong_signal()
463 tp->t_flags &= ~TF_PREVVALID; in cc_cong_signal()
464 tp->t_rxtshift = 0; in cc_cong_signal()
465 tp->t_badrxtwin = 0; in cc_cong_signal()
468 if (SEQ_LT(tp->snd_fack, tp->snd_una) || in cc_cong_signal()
469 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_cong_signal()
470 tp->snd_fack = tp->snd_una; in cc_cong_signal()
473 if (CC_ALGO(tp)->cong_signal != NULL) { in cc_cong_signal()
475 tp->t_ccv.curack = th->th_ack; in cc_cong_signal()
476 CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); in cc_cong_signal()
481 cc_post_recovery(struct tcpcb *tp, struct tcphdr *th) in cc_post_recovery() argument
483 INP_WLOCK_ASSERT(tptoinpcb(tp)); in cc_post_recovery()
485 if (CC_ALGO(tp)->post_recovery != NULL) { in cc_post_recovery()
486 if (SEQ_LT(tp->snd_fack, th->th_ack) || in cc_post_recovery()
487 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_post_recovery()
488 tp->snd_fack = th->th_ack; in cc_post_recovery()
490 tp->t_ccv.curack = th->th_ack; in cc_post_recovery()
491 CC_ALGO(tp)->post_recovery(&tp->t_ccv); in cc_post_recovery()
493 EXIT_RECOVERY(tp->t_flags); in cc_post_recovery()
495 tp->t_bytes_acked = 0; in cc_post_recovery()
496 tp->sackhint.delivered_data = 0; in cc_post_recovery()
497 tp->sackhint.prr_delivered = 0; in cc_post_recovery()
498 tp->sackhint.prr_out = 0; in cc_post_recovery()
499 tp->snd_cwnd = tp->snd_ssthresh; in cc_post_recovery()
511 #define DELAY_ACK(tp, tlen) \ argument
512 ((!tcp_timer_active(tp, TT_DELACK) && \
513 (tp->t_flags & TF_RXWIN0SENT) == 0) && \
514 (tlen <= tp->t_maxseg) && \
515 (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
518 cc_ecnpkt_handler_flags(struct tcpcb *tp, uint16_t flags, uint8_t iptos) in cc_ecnpkt_handler_flags() argument
520 INP_WLOCK_ASSERT(tptoinpcb(tp)); in cc_ecnpkt_handler_flags()
522 if (CC_ALGO(tp)->ecnpkt_handler != NULL) { in cc_ecnpkt_handler_flags()
525 tp->t_ccv.flags |= CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
532 tp->t_ccv.flags &= ~CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
537 tp->t_ccv.flags |= CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
539 tp->t_ccv.flags &= ~CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
541 CC_ALGO(tp)->ecnpkt_handler(&tp->t_ccv); in cc_ecnpkt_handler_flags()
543 if (((tp->t_state == TCPS_ESTABLISHED) || in cc_ecnpkt_handler_flags()
544 (tp->t_state == TCPS_FIN_WAIT_1) || in cc_ecnpkt_handler_flags()
545 (tp->t_state == TCPS_FIN_WAIT_2)) && in cc_ecnpkt_handler_flags()
546 (tp->t_ccv.flags & CCF_ACKNOW)) { in cc_ecnpkt_handler_flags()
547 tp->t_flags |= TF_ACKNOW; in cc_ecnpkt_handler_flags()
548 tp->t_ccv.flags &= ~CCF_ACKNOW; in cc_ecnpkt_handler_flags()
554 cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos) in cc_ecnpkt_handler() argument
556 cc_ecnpkt_handler_flags(tp, tcp_get_flags(th), iptos); in cc_ecnpkt_handler()
603 struct tcpcb *tp = NULL; in tcp_input_with_port() local
839 tp = NULL; in tcp_input_with_port()
959 tp = intotcpcb(inp); in tcp_input_with_port()
960 switch (tp->t_state) { in tcp_input_with_port()
986 if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { in tcp_input_with_port()
992 if (tp->t_flags & TF_TOE) { in tcp_input_with_port()
993 tcp_offload_input(tp, m); in tcp_input_with_port()
1010 KASSERT(tp->t_state == TCPS_LISTEN || !SOLISTENING(so), in tcp_input_with_port()
1011 ("%s: so accepting but tp %p not listening", __func__, tp)); in tcp_input_with_port()
1012 if (tp->t_state == TCPS_LISTEN && SOLISTENING(so)) { in tcp_input_with_port()
1109 * created socket and update the tp variable. in tcp_input_with_port()
1120 tp = intotcpcb(inp); in tcp_input_with_port()
1121 KASSERT(tp->t_state == TCPS_SYN_RECEIVED, in tcp_input_with_port()
1128 TCP_PROBE5(receive, NULL, tp, m, tp, th); in tcp_input_with_port()
1129 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, in tcp_input_with_port()
1314 TCP_PROBE3(debug__input, tp, th, m); in tcp_input_with_port()
1327 if (tp->t_flags & TF_SIGNATURE) { in tcp_input_with_port()
1338 TCP_PROBE5(receive, NULL, tp, m, tp, th); in tcp_input_with_port()
1354 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, tlen, iptos); in tcp_input_with_port()
1376 TCP_PROBE5(receive, NULL, tp, m, tp, th); in tcp_input_with_port()
1377 tcp_dropwithreset(m, th, tp, tlen); in tcp_input_with_port()
1382 TCP_PROBE5(receive, NULL, tp, m, tp, th); in tcp_input_with_port()
1435 struct tcpcb *tp, int tlen) in tcp_autorcvbuf() argument
1440 tp->t_srtt != 0 && tp->rfbuf_ts != 0 && in tcp_autorcvbuf()
1441 TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > in tcp_autorcvbuf()
1442 ((tp->t_srtt >> TCP_RTT_SHIFT)/2)) { in tcp_autorcvbuf()
1443 if (tp->rfbuf_cnt > ((so->so_rcv.sb_hiwat / 2)/ 4 * 3) && in tcp_autorcvbuf()
1447 TCP_PROBE6(receive__autoresize, NULL, tp, m, tp, th, newsize); in tcp_autorcvbuf()
1450 tp->rfbuf_ts = 0; in tcp_autorcvbuf()
1451 tp->rfbuf_cnt = 0; in tcp_autorcvbuf()
1453 tp->rfbuf_cnt += tlen; /* add up */ in tcp_autorcvbuf()
1465 tcp_handle_wakeup(struct tcpcb *tp) in tcp_handle_wakeup() argument
1468 INP_WLOCK_ASSERT(tptoinpcb(tp)); in tcp_handle_wakeup()
1470 if (tp->t_flags & TF_WAKESOR) { in tcp_handle_wakeup()
1471 struct socket *so = tptosocket(tp); in tcp_handle_wakeup()
1473 tp->t_flags &= ~TF_WAKESOR; in tcp_handle_wakeup()
1480 tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, in tcp_do_segment() argument
1490 struct inpcb *inp = tptoinpcb(tp); in tcp_do_segment()
1491 struct socket *so = tptosocket(tp); in tcp_do_segment()
1502 tp->sackhint.last_sack_ack = 0; in tcp_do_segment()
1508 KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", in tcp_do_segment()
1510 KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", in tcp_do_segment()
1513 TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, in tcp_do_segment()
1530 if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && in tcp_do_segment()
1531 (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1532 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
1542 if (tp->t_idle_reduce && in tcp_do_segment()
1543 (tp->snd_max == tp->snd_una) && in tcp_do_segment()
1544 ((ticks - tp->t_rcvtime) >= tp->t_rxtcur)) in tcp_do_segment()
1545 cc_after_idle(tp); in tcp_do_segment()
1546 tp->t_rcvtime = ticks; in tcp_do_segment()
1549 tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN); in tcp_do_segment()
1554 tiwin = th->th_win << tp->snd_scale; in tcp_do_segment()
1556 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); in tcp_do_segment()
1562 if (tcp_ecn_input_segment(tp, thflags, tlen, in tcp_do_segment()
1563 tcp_packets_this_ack(tp, th->th_ack), in tcp_do_segment()
1565 cc_cong_signal(tp, th, CC_ECN); in tcp_do_segment()
1573 if (tp->t_flags2 & TF2_PROC_SACK_PROHIBIT) { in tcp_do_segment()
1582 if ((tp->t_flags & TF_SIGNATURE) == 0 && in tcp_do_segment()
1593 to.to_tsecr -= tp->ts_offset; in tcp_do_segment()
1605 if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { in tcp_do_segment()
1607 tcp_ecn_input_parallel_syn(tp, thflags, iptos); in tcp_do_segment()
1609 (tp->t_flags & TF_REQ_SCALE) && in tcp_do_segment()
1610 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1611 tp->t_flags |= TF_RCVD_SCALE; in tcp_do_segment()
1612 tp->snd_scale = to.to_wscale; in tcp_do_segment()
1614 tp->t_flags &= ~TF_REQ_SCALE; in tcp_do_segment()
1620 tp->snd_wnd = th->th_win; in tcp_do_segment()
1622 (tp->t_flags & TF_REQ_TSTMP) && in tcp_do_segment()
1623 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1624 tp->t_flags |= TF_RCVD_TSTMP; in tcp_do_segment()
1625 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1626 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1628 tp->t_flags &= ~TF_REQ_TSTMP; in tcp_do_segment()
1631 tcp_mss(tp, to.to_mss); in tcp_do_segment()
1633 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
1635 (tp->t_flags & TF_NOOPT))) { in tcp_do_segment()
1636 tp->t_flags &= ~TF_SACK_PERMIT; in tcp_do_segment()
1638 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1640 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1652 tcp_fastopen_update_cache(tp, mss, in tcp_do_segment()
1655 tcp_fastopen_disable_path(tp); in tcp_do_segment()
1667 if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { in tcp_do_segment()
1690 if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) { in tcp_do_segment()
1715 if (tp->t_state == TCPS_ESTABLISHED && in tcp_do_segment()
1716 th->th_seq == tp->rcv_nxt && in tcp_do_segment()
1718 tp->snd_nxt == tp->snd_max && in tcp_do_segment()
1719 tiwin && tiwin == tp->snd_wnd && in tcp_do_segment()
1720 ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && in tcp_do_segment()
1721 SEGQ_EMPTY(tp) && in tcp_do_segment()
1723 TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { in tcp_do_segment()
1731 SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { in tcp_do_segment()
1732 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1733 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1737 if (SEQ_GT(th->th_ack, tp->snd_una) && in tcp_do_segment()
1738 SEQ_LEQ(th->th_ack, tp->snd_max) && in tcp_do_segment()
1739 !IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
1741 TAILQ_EMPTY(&tp->snd_holes)) { in tcp_do_segment()
1750 if (tp->t_rxtshift == 1 && in tcp_do_segment()
1751 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1752 tp->t_badrxtwin != 0 && in tcp_do_segment()
1755 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) || in tcp_do_segment()
1757 TSTMP_LT(ticks, tp->t_badrxtwin)))) in tcp_do_segment()
1758 cc_cong_signal(tp, th, CC_RTO_ERR); in tcp_do_segment()
1773 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
1774 tp->t_rttlow = t; in tcp_do_segment()
1775 tcp_xmit_timer(tp, in tcp_do_segment()
1777 } else if (tp->t_rtttime && in tcp_do_segment()
1778 SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
1779 if (!tp->t_rttlow || in tcp_do_segment()
1780 tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
1781 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
1782 tcp_xmit_timer(tp, in tcp_do_segment()
1783 ticks - tp->t_rtttime); in tcp_do_segment()
1785 acked = BYTES_THIS_ACK(tp, th); in tcp_do_segment()
1789 hhook_run_tcp_est_in(tp, th, &to); in tcp_do_segment()
1795 if (SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
1796 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
1797 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
1805 cc_ack_received(tp, th, nsegs, CC_ACK); in tcp_do_segment()
1807 tp->snd_una = th->th_ack; in tcp_do_segment()
1812 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
1813 tp->t_dupacks = 0; in tcp_do_segment()
1825 TCP_PROBE3(debug__input, tp, th, m); in tcp_do_segment()
1833 tp->t_acktime = 0; in tcp_do_segment()
1835 tp->t_acktime = ticks; in tcp_do_segment()
1836 if (tp->snd_una == tp->snd_max) in tcp_do_segment()
1837 tcp_timer_activate(tp, TT_REXMT, 0); in tcp_do_segment()
1838 else if (!tcp_timer_active(tp, TT_PERSIST)) in tcp_do_segment()
1839 tcp_timer_activate(tp, TT_REXMT, in tcp_do_segment()
1840 TP_RXTCUR(tp)); in tcp_do_segment()
1847 if ((tp->t_flags & TF_ACKNOW) || in tcp_do_segment()
1849 SEQ_SUB(tp->snd_max, tp->snd_una))) { in tcp_do_segment()
1850 (void) tcp_output(tp); in tcp_do_segment()
1854 } else if (th->th_ack == tp->snd_una && in tcp_do_segment()
1864 if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks) in tcp_do_segment()
1865 tcp_clean_sackreport(tp); in tcp_do_segment()
1867 tp->rcv_nxt += tlen; in tcp_do_segment()
1869 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
1870 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
1871 tp->t_fbyte_in = ticks; in tcp_do_segment()
1872 if (tp->t_fbyte_in == 0) in tcp_do_segment()
1873 tp->t_fbyte_in = 1; in tcp_do_segment()
1874 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
1875 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
1881 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
1886 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
1889 TCP_PROBE3(debug__input, tp, th, m); in tcp_do_segment()
1891 newsize = tcp_autorcvbuf(m, th, so, tp, tlen); in tcp_do_segment()
1911 if (DELAY_ACK(tp, tlen)) { in tcp_do_segment()
1912 tp->t_flags |= TF_DELACK; in tcp_do_segment()
1914 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
1915 (void) tcp_output(tp); in tcp_do_segment()
1930 tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); in tcp_do_segment()
1932 switch (tp->t_state) { in tcp_do_segment()
1943 (SEQ_LEQ(th->th_ack, tp->snd_una) || in tcp_do_segment()
1944 SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1945 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
1948 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1957 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
1961 if ((tcp_timer_active(tp, TT_DELACK) || in tcp_do_segment()
1962 tcp_timer_active(tp, TT_REXMT))) in tcp_do_segment()
1977 * initialize tp->rcv_nxt and tp->irs in tcp_do_segment()
1978 * if seg contains ack then advance tp->snd_una in tcp_do_segment()
1987 TCP_PROBE5(connect__refused, NULL, tp, in tcp_do_segment()
1988 m, tp, th); in tcp_do_segment()
1989 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
1990 tp = tcp_drop(tp, ECONNREFUSED); in tcp_do_segment()
1997 tp->irs = th->th_seq; in tcp_do_segment()
1998 tcp_rcvseqinit(tp); in tcp_do_segment()
2008 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2010 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2012 tp->rcv_adv += min(tp->rcv_wnd, in tcp_do_segment()
2013 TCP_MAXWIN << tp->rcv_scale); in tcp_do_segment()
2014 tp->snd_una++; /* SYN is acked */ in tcp_do_segment()
2015 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
2016 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
2021 if ((tp->t_flags & TF_FASTOPEN) && in tcp_do_segment()
2022 (tp->snd_una != tp->snd_max)) { in tcp_do_segment()
2023 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2030 if (DELAY_ACK(tp, tlen) && tlen != 0 && !tfo_partial_ack) in tcp_do_segment()
2031 tcp_timer_activate(tp, TT_DELACK, in tcp_do_segment()
2034 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2036 tcp_ecn_input_syn_sent(tp, thflags, iptos); in tcp_do_segment()
2044 tp->t_starttime = ticks; in tcp_do_segment()
2045 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2046 tp->t_acktime = ticks; in tcp_do_segment()
2047 tcp_state_change(tp, TCPS_FIN_WAIT_1); in tcp_do_segment()
2048 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2051 tcp_state_change(tp, TCPS_ESTABLISHED); in tcp_do_segment()
2052 TCP_PROBE5(connect__established, NULL, tp, in tcp_do_segment()
2053 m, tp, th); in tcp_do_segment()
2054 cc_conn_init(tp); in tcp_do_segment()
2055 tcp_timer_activate(tp, TT_KEEP, in tcp_do_segment()
2056 TP_KEEPIDLE(tp)); in tcp_do_segment()
2067 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); in tcp_do_segment()
2068 tcp_timer_activate(tp, TT_REXMT, 0); in tcp_do_segment()
2069 tcp_state_change(tp, TCPS_SYN_RECEIVED); in tcp_do_segment()
2078 if (tlen > tp->rcv_wnd) { in tcp_do_segment()
2079 todrop = tlen - tp->rcv_wnd; in tcp_do_segment()
2081 tlen = tp->rcv_wnd; in tcp_do_segment()
2086 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2087 tp->rcv_up = th->th_seq; in tcp_do_segment()
2128 * tp->rcv_nxt + tp->rcv_wnd. in tcp_do_segment()
2130 if ((tp->rcv_wnd > 0 && in tcp_do_segment()
2131 SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2132 SEQ_LT(th->th_seq, tp->rcv_nxt + tp->rcv_wnd)) || in tcp_do_segment()
2133 (tp->rcv_wnd == 0 && in tcp_do_segment()
2134 (tp->last_ack_sent == th->th_seq || in tcp_do_segment()
2135 tp->rcv_nxt == th->th_seq))) { in tcp_do_segment()
2136 KASSERT(tp->t_state != TCPS_SYN_SENT, in tcp_do_segment()
2137 ("%s: TH_RST for TCPS_SYN_SENT th %p tp %p", in tcp_do_segment()
2138 __func__, th, tp)); in tcp_do_segment()
2141 tp->last_ack_sent == th->th_seq || in tcp_do_segment()
2142 tp->rcv_nxt == th->th_seq) { in tcp_do_segment()
2145 switch (tp->t_state) { in tcp_do_segment()
2159 tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_RST); in tcp_do_segment()
2160 tp = tcp_close(tp); in tcp_do_segment()
2164 tcp_send_challenge_ack(tp, th, m); in tcp_do_segment()
2175 if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT && in tcp_do_segment()
2176 tp->t_state != TCPS_SYN_RECEIVED) { in tcp_do_segment()
2179 SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2180 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { in tcp_do_segment()
2181 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
2182 tp = tcp_drop(tp, ECONNRESET); in tcp_do_segment()
2184 tcp_ecn_input_syn_sent(tp, thflags, iptos); in tcp_do_segment()
2185 tcp_send_challenge_ack(tp, th, m); in tcp_do_segment()
2195 if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && in tcp_do_segment()
2196 TSTMP_LT(to.to_tsval, tp->ts_recent)) { in tcp_do_segment()
2198 if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { in tcp_do_segment()
2210 tp->ts_recent = 0; in tcp_do_segment()
2228 if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { in tcp_do_segment()
2229 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
2233 todrop = tp->rcv_nxt - th->th_seq; in tcp_do_segment()
2260 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2271 if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2272 tcp_update_sack_list(tp, th->th_seq, in tcp_do_segment()
2278 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2296 if ((tp->t_flags & TF_CLOSED) && tlen > 0 && in tcp_do_segment()
2297 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
2302 s, __func__, tcpstates[tp->t_state], tlen); in tcp_do_segment()
2305 tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); in tcp_do_segment()
2307 tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); in tcp_do_segment()
2308 tp = tcp_close(tp); in tcp_do_segment()
2317 todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); in tcp_do_segment()
2329 if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { in tcp_do_segment()
2330 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2360 SEQ_LEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2361 SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + in tcp_do_segment()
2363 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
2364 tp->ts_recent = to.to_tsval; in tcp_do_segment()
2373 if (tp->t_state == TCPS_SYN_RECEIVED || in tcp_do_segment()
2374 (tp->t_flags & TF_NEEDSYN)) { in tcp_do_segment()
2375 if (tp->t_state == TCPS_SYN_RECEIVED && in tcp_do_segment()
2376 (tp->t_flags & TF_FASTOPEN)) { in tcp_do_segment()
2377 tp->snd_wnd = tiwin; in tcp_do_segment()
2378 cc_conn_init(tp); in tcp_do_segment()
2381 } else if (tp->t_flags & TF_ACKNOW) in tcp_do_segment()
2390 if (SEQ_GT(tp->snd_una, tp->iss + (TCP_MAXWIN << tp->snd_scale))) { in tcp_do_segment()
2392 tp->t_flags2 |= TF2_NO_ISS_CHECK; in tcp_do_segment()
2398 if (tp->t_flags2 & TF2_NO_ISS_CHECK) { in tcp_do_segment()
2400 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2403 if (SEQ_GT(tp->iss + 1, tp->snd_una - tp->max_sndwnd)) { in tcp_do_segment()
2405 seq_min = tp->iss + 1; in tcp_do_segment()
2412 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2421 tcp_send_challenge_ack(tp, th, m); in tcp_do_segment()
2426 switch (tp->t_state) { in tcp_do_segment()
2435 if (tp->t_flags & TF_SONOTCONN) { in tcp_do_segment()
2440 * only with an accept_filter(9), then the tp is marked in tcp_do_segment()
2445 tp->t_flags &= ~TF_SONOTCONN; in tcp_do_segment()
2449 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2451 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2453 tp->snd_wnd = tiwin; in tcp_do_segment()
2459 tp->t_starttime = ticks; in tcp_do_segment()
2460 if ((tp->t_flags & TF_FASTOPEN) && tp->t_tfo_pending) { in tcp_do_segment()
2461 tcp_fastopen_decrement_counter(tp->t_tfo_pending); in tcp_do_segment()
2462 tp->t_tfo_pending = NULL; in tcp_do_segment()
2464 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2465 tp->t_acktime = ticks; in tcp_do_segment()
2466 tcp_state_change(tp, TCPS_FIN_WAIT_1); in tcp_do_segment()
2467 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2469 tcp_state_change(tp, TCPS_ESTABLISHED); in tcp_do_segment()
2470 TCP_PROBE5(accept__established, NULL, tp, in tcp_do_segment()
2471 m, tp, th); in tcp_do_segment()
2479 if (!(tp->t_flags & TF_FASTOPEN)) in tcp_do_segment()
2480 cc_conn_init(tp); in tcp_do_segment()
2481 tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); in tcp_do_segment()
2488 if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) in tcp_do_segment()
2495 (void) tcp_reass(tp, (struct tcphdr *)0, NULL, 0, in tcp_do_segment()
2497 tcp_handle_wakeup(tp); in tcp_do_segment()
2499 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2505 * tp->snd_una < th->th_ack <= tp->snd_max in tcp_do_segment()
2506 * then advance tp->snd_una to th->th_ack and drop in tcp_do_segment()
2516 if (SEQ_GT(th->th_ack, tp->snd_max)) { in tcp_do_segment()
2520 if (tcp_is_sack_recovery(tp, &to)) { in tcp_do_segment()
2521 prev_sacked_bytes = tp->sackhint.sacked_bytes; in tcp_do_segment()
2522 sack_changed = tcp_sack_doack(tp, &to, th->th_ack); in tcp_do_segment()
2524 (tp->t_flags & TF_LRD)) { in tcp_do_segment()
2525 tcp_sack_lost_retransmission(tp, th); in tcp_do_segment()
2532 tp->sackhint.sacked_bytes = 0; in tcp_do_segment()
2536 hhook_run_tcp_est_in(tp, th, &to); in tcp_do_segment()
2539 if (SEQ_LT(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2543 if (th->th_ack == tp->snd_una) { in tcp_do_segment()
2545 if (tp->t_flags & TF_SACK_PERMIT) { in tcp_do_segment()
2561 if (!no_data || tiwin != tp->snd_wnd) { in tcp_do_segment()
2573 (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { in tcp_do_segment()
2574 tp->t_dupacks = 0; in tcp_do_segment()
2579 maxseg = tcp_maxseg(tp); in tcp_do_segment()
2580 if (!tcp_timer_active(tp, TT_REXMT)) { in tcp_do_segment()
2581 tp->t_dupacks = 0; in tcp_do_segment()
2582 } else if (++tp->t_dupacks > tcprexmtthresh || in tcp_do_segment()
2583 IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2584 cc_ack_received(tp, th, nsegs, CC_DUPACK); in tcp_do_segment()
2586 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2587 (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2588 tcp_do_prr_ack(tp, th, &to, in tcp_do_segment()
2590 } else if (tcp_is_sack_recovery(tp, &to) && in tcp_do_segment()
2591 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2592 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2601 awnd = tcp_compute_pipe(tp); in tcp_do_segment()
2602 if (awnd < tp->snd_ssthresh) { in tcp_do_segment()
2603 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2605 tp->sackhint.delivered_data)); in tcp_do_segment()
2606 if (tp->snd_cwnd > tp->snd_ssthresh) in tcp_do_segment()
2607 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2609 } else if (tcp_is_sack_recovery(tp, &to) && in tcp_do_segment()
2610 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2611 SEQ_LT(tp->snd_nxt, tp->snd_max)) { in tcp_do_segment()
2612 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2614 tp->sackhint.delivered_data)); in tcp_do_segment()
2616 tp->snd_cwnd += maxseg; in tcp_do_segment()
2618 (void) tcp_output(tp); in tcp_do_segment()
2620 } else if (tp->t_dupacks == tcprexmtthresh || in tcp_do_segment()
2621 (tp->t_flags & TF_SACK_PERMIT && in tcp_do_segment()
2622 tp->sackhint.sacked_bytes > in tcp_do_segment()
2633 tp->t_dupacks = tcprexmtthresh; in tcp_do_segment()
2634 tcp_seq onxt = tp->snd_nxt; in tcp_do_segment()
2643 if (tcp_is_sack_recovery(tp, &to)) { in tcp_do_segment()
2644 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2645 tp->t_dupacks = 0; in tcp_do_segment()
2650 tp->snd_recover)) { in tcp_do_segment()
2651 tp->t_dupacks = 0; in tcp_do_segment()
2656 cc_cong_signal(tp, th, CC_NDUPACK); in tcp_do_segment()
2657 cc_ack_received(tp, th, nsegs, CC_DUPACK); in tcp_do_segment()
2658 tcp_timer_activate(tp, TT_REXMT, 0); in tcp_do_segment()
2659 tp->t_rtttime = 0; in tcp_do_segment()
2665 if (tcp_is_sack_recovery(tp, &to)) { in tcp_do_segment()
2670 tp->sackhint.prr_delivered = in tcp_do_segment()
2671 imin(tp->snd_max - th->th_ack, in tcp_do_segment()
2672 (tp->snd_limited + 1) * maxseg); in tcp_do_segment()
2673 tp->sackhint.recover_fs = imax(1, in tcp_do_segment()
2674 (tp->snd_nxt - tp->snd_una) - prev_sacked_bytes in tcp_do_segment()
2675 + tp->sackhint.delivered_data); in tcp_do_segment()
2677 tp->sackhint.prr_delivered = in tcp_do_segment()
2679 tp->sackhint.recover_fs = max(1, in tcp_do_segment()
2680 tp->snd_nxt - tp->snd_una); in tcp_do_segment()
2683 tp->snd_limited = 0; in tcp_do_segment()
2684 if (tcp_is_sack_recovery(tp, &to)) { in tcp_do_segment()
2691 tcp_resend_sackholes(tp); in tcp_do_segment()
2693 tp->snd_nxt = tp->snd_max; in tcp_do_segment()
2694 tp->snd_cwnd = tcp_compute_pipe(tp) + in tcp_do_segment()
2696 (void) tcp_output(tp); in tcp_do_segment()
2698 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2701 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2702 tp->snd_cwnd = maxseg; in tcp_do_segment()
2703 (void) tcp_output(tp); in tcp_do_segment()
2704 KASSERT(tp->snd_limited <= 2, in tcp_do_segment()
2705 ("%s: tp->snd_limited too big", in tcp_do_segment()
2707 tp->snd_cwnd = tp->snd_ssthresh + in tcp_do_segment()
2709 (tp->t_dupacks - tp->snd_limited); in tcp_do_segment()
2710 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_do_segment()
2711 tp->snd_nxt = onxt; in tcp_do_segment()
2724 cc_ack_received(tp, th, nsegs, CC_DUPACK); in tcp_do_segment()
2725 uint32_t oldcwnd = tp->snd_cwnd; in tcp_do_segment()
2726 tcp_seq oldsndmax = tp->snd_max; in tcp_do_segment()
2730 KASSERT(tp->t_dupacks == 1 || in tcp_do_segment()
2731 tp->t_dupacks == 2, in tcp_do_segment()
2734 if (tp->t_dupacks == 1) in tcp_do_segment()
2735 tp->snd_limited = 0; in tcp_do_segment()
2736 if ((tp->snd_nxt == tp->snd_max) && in tcp_do_segment()
2737 (tp->t_rxtshift == 0)) in tcp_do_segment()
2738 tp->snd_cwnd = in tcp_do_segment()
2739 SEQ_SUB(tp->snd_nxt, tp->snd_una); in tcp_do_segment()
2740 tp->snd_cwnd += in tcp_do_segment()
2741 (tp->t_dupacks - tp->snd_limited) * maxseg; in tcp_do_segment()
2742 tp->snd_cwnd -= tcp_sack_adjust(tp); in tcp_do_segment()
2751 if (tp->t_flags & TF_ACKNOW || in tcp_do_segment()
2753 SEQ_SUB(tp->snd_nxt, tp->snd_una))) { in tcp_do_segment()
2754 (void) tcp_output(tp); in tcp_do_segment()
2756 sent = SEQ_SUB(tp->snd_max, oldsndmax); in tcp_do_segment()
2758 KASSERT((tp->t_dupacks == 2 && in tcp_do_segment()
2759 tp->snd_limited == 0) || in tcp_do_segment()
2761 tp->t_flags & TF_SENTFIN) || in tcp_do_segment()
2763 tp->t_flags & TF_NODELAY), in tcp_do_segment()
2766 tp->snd_limited = 2; in tcp_do_segment()
2768 ++tp->snd_limited; in tcp_do_segment()
2770 tp->snd_cwnd = oldcwnd; in tcp_do_segment()
2775 KASSERT(SEQ_GT(th->th_ack, tp->snd_una), in tcp_do_segment()
2781 tp->t_dupacks = 0; in tcp_do_segment()
2791 if (tcp_is_sack_recovery(tp, &to) && in tcp_do_segment()
2792 (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || in tcp_do_segment()
2793 ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && in tcp_do_segment()
2794 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2795 tp->t_dupacks++; in tcp_do_segment()
2797 if (!IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2798 (tp->sackhint.sacked_bytes > in tcp_do_segment()
2799 (tcprexmtthresh - 1) * (maxseg = tcp_maxseg(tp)))) { in tcp_do_segment()
2807 if (SEQ_LT(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
2808 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2809 if (tp->t_flags & TF_SACK_PERMIT) { in tcp_do_segment()
2812 tcp_timer_activate(tp, in tcp_do_segment()
2814 tp->t_rtttime = 0; in tcp_do_segment()
2815 tcp_do_prr_ack(tp, th, &to, in tcp_do_segment()
2817 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2818 (void) tcp_output(tp); in tcp_do_segment()
2820 tcp_sack_partialack(tp, th, in tcp_do_segment()
2824 tcp_newreno_partial_ack(tp, th); in tcp_do_segment()
2826 } else if (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_segment()
2828 tp->sackhint.delivered_data = in tcp_do_segment()
2829 BYTES_THIS_ACK(tp, th); in tcp_do_segment()
2830 tp->snd_fack = th->th_ack; in tcp_do_segment()
2835 tcp_do_prr_ack(tp, th, &to, SACK_CHANGE, in tcp_do_segment()
2837 (void) tcp_output(tp); in tcp_do_segment()
2844 if (tp->t_flags & TF_NEEDSYN) { in tcp_do_segment()
2852 tp->t_flags &= ~TF_NEEDSYN; in tcp_do_segment()
2853 tp->snd_una++; in tcp_do_segment()
2855 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2857 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2873 tp->snd_una++; in tcp_do_segment()
2874 acked = BYTES_THIS_ACK(tp, th); in tcp_do_segment()
2876 "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__, in tcp_do_segment()
2877 tp->snd_una, th->th_ack, tp, m)); in tcp_do_segment()
2888 if (tp->t_rxtshift == 1 && in tcp_do_segment()
2889 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
2890 tp->t_badrxtwin != 0 && in tcp_do_segment()
2893 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) in tcp_do_segment()
2894 cc_cong_signal(tp, th, CC_RTO_ERR); in tcp_do_segment()
2914 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
2915 tp->t_rttlow = t; in tcp_do_segment()
2916 tcp_xmit_timer(tp, TCP_TS_TO_TICKS(t) + 1); in tcp_do_segment()
2917 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
2918 if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
2919 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
2920 tcp_xmit_timer(tp, ticks - tp->t_rtttime); in tcp_do_segment()
2930 if ((tp->t_state <= TCPS_CLOSE_WAIT && in tcp_do_segment()
2933 tp->t_acktime = 0; in tcp_do_segment()
2935 tp->t_acktime = ticks; in tcp_do_segment()
2943 if (th->th_ack == tp->snd_max) { in tcp_do_segment()
2944 tcp_timer_activate(tp, TT_REXMT, 0); in tcp_do_segment()
2946 } else if (!tcp_timer_active(tp, TT_PERSIST)) in tcp_do_segment()
2947 tcp_timer_activate(tp, TT_REXMT, TP_RXTCUR(tp)); in tcp_do_segment()
2963 cc_ack_received(tp, th, nsegs, CC_ACK); in tcp_do_segment()
2966 if (tp->snd_wnd >= sbavail(&so->so_snd)) in tcp_do_segment()
2967 tp->snd_wnd -= sbavail(&so->so_snd); in tcp_do_segment()
2969 tp->snd_wnd = 0; in tcp_do_segment()
2975 if (tp->snd_wnd >= (uint32_t) acked) in tcp_do_segment()
2976 tp->snd_wnd -= acked; in tcp_do_segment()
2978 tp->snd_wnd = 0; in tcp_do_segment()
2985 if (!IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
2986 SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
2987 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
2988 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
2989 tp->snd_una = th->th_ack; in tcp_do_segment()
2990 if (IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
2991 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
2992 cc_post_recovery(tp, th); in tcp_do_segment()
2994 if (SEQ_GT(tp->snd_una, tp->snd_recover)) { in tcp_do_segment()
2995 tp->snd_recover = tp->snd_una; in tcp_do_segment()
2997 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
2998 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
3000 switch (tp->t_state) { in tcp_do_segment()
3016 tcp_free_sackholes(tp); in tcp_do_segment()
3018 tcp_timer_activate(tp, TT_2MSL, in tcp_do_segment()
3021 TP_MAXIDLE(tp))); in tcp_do_segment()
3023 tcp_state_change(tp, TCPS_FIN_WAIT_2); in tcp_do_segment()
3035 tcp_twstart(tp); in tcp_do_segment()
3049 tp = tcp_close(tp); in tcp_do_segment()
3064 (SEQ_LT(tp->snd_wl1, th->th_seq) || in tcp_do_segment()
3065 (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || in tcp_do_segment()
3066 (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { in tcp_do_segment()
3068 if (no_data && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) in tcp_do_segment()
3070 tp->snd_wnd = tiwin; in tcp_do_segment()
3071 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
3072 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
3073 if (tp->snd_wnd > tp->max_sndwnd) in tcp_do_segment()
3074 tp->max_sndwnd = tp->snd_wnd; in tcp_do_segment()
3082 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3110 if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { in tcp_do_segment()
3111 tp->rcv_up = th->th_seq + th->th_urp; in tcp_do_segment()
3113 (tp->rcv_up - tp->rcv_nxt) - 1; in tcp_do_segment()
3117 tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); in tcp_do_segment()
3137 if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) in tcp_do_segment()
3138 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
3146 * This process logically involves adjusting tp->rcv_wnd as data in tcp_do_segment()
3151 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && in tcp_do_segment()
3152 (tp->t_flags & TF_FASTOPEN)); in tcp_do_segment()
3154 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3156 tcp_seq save_rnxt = tp->rcv_nxt; in tcp_do_segment()
3161 * with control block tp. Set thflags to whether reassembly now in tcp_do_segment()
3171 if (th->th_seq == tp->rcv_nxt && in tcp_do_segment()
3172 SEGQ_EMPTY(tp) && in tcp_do_segment()
3173 (TCPS_HAVEESTABLISHED(tp->t_state) || in tcp_do_segment()
3175 if (DELAY_ACK(tp, tlen) || tfo_syn) in tcp_do_segment()
3176 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3178 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3179 tp->rcv_nxt += tlen; in tcp_do_segment()
3181 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
3182 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
3183 tp->t_fbyte_in = ticks; in tcp_do_segment()
3184 if (tp->t_fbyte_in == 0) in tcp_do_segment()
3185 tp->t_fbyte_in = 1; in tcp_do_segment()
3186 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
3187 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
3197 tp->t_flags |= TF_WAKESOR; in tcp_do_segment()
3207 thflags = tcp_reass(tp, th, &temp, &tlen, m); in tcp_do_segment()
3208 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3210 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
3212 TCPS_HAVEESTABLISHED(tp->t_state)) { in tcp_do_segment()
3218 tcp_update_sack_list(tp, save_start, in tcp_do_segment()
3220 } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { in tcp_do_segment()
3221 if ((tp->rcv_numsacks >= 1) && in tcp_do_segment()
3222 (tp->sackblks[0].end == save_start)) { in tcp_do_segment()
3227 tcp_update_sack_list(tp, in tcp_do_segment()
3228 tp->sackblks[0].start, in tcp_do_segment()
3229 tp->sackblks[0].end); in tcp_do_segment()
3231 tcp_update_dsack_list(tp, save_start, in tcp_do_segment()
3236 tcp_update_dsack_list(tp, save_start, in tcp_do_segment()
3239 tcp_update_dsack_list(tp, save_start, in tcp_do_segment()
3243 tcp_handle_wakeup(tp); in tcp_do_segment()
3251 if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) in tcp_do_segment()
3252 len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); in tcp_do_segment()
3265 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3272 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3281 tcpstates[tp->t_state]); in tcp_do_segment()
3295 if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3305 if (tp->t_flags & TF_NEEDSYN) in tcp_do_segment()
3306 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3308 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3309 tp->rcv_nxt++; in tcp_do_segment()
3311 switch (tp->t_state) { in tcp_do_segment()
3317 tp->t_starttime = ticks; in tcp_do_segment()
3320 tcp_state_change(tp, TCPS_CLOSE_WAIT); in tcp_do_segment()
3328 tcp_state_change(tp, TCPS_CLOSING); in tcp_do_segment()
3337 tcp_twstart(tp); in tcp_do_segment()
3341 TCP_PROBE3(debug__input, tp, th, m); in tcp_do_segment()
3346 if (needoutput || (tp->t_flags & TF_ACKNOW)) { in tcp_do_segment()
3347 (void) tcp_output(tp); in tcp_do_segment()
3352 if (tp->t_flags & TF_DELACK) { in tcp_do_segment()
3353 tp->t_flags &= ~TF_DELACK; in tcp_do_segment()
3354 tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); in tcp_do_segment()
3375 if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && in tcp_do_segment()
3376 (SEQ_GT(tp->snd_una, th->th_ack) || in tcp_do_segment()
3377 SEQ_GT(th->th_ack, tp->snd_max)) ) { in tcp_do_segment()
3378 tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); in tcp_do_segment()
3381 TCP_PROBE3(debug__input, tp, th, m); in tcp_do_segment()
3382 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3383 (void) tcp_output(tp); in tcp_do_segment()
3389 tcp_dropwithreset(m, th, tp, tlen); in tcp_do_segment()
3390 if (tp != NULL) { in tcp_do_segment()
3399 TCP_PROBE3(debug__input, tp, th, m); in tcp_do_segment()
3400 if (tp != NULL) { in tcp_do_segment()
3409 * tp may be NULL.
3412 tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int tlen) in tcp_dropwithreset() argument
3421 if (tp != NULL) { in tcp_dropwithreset()
3422 INP_LOCK_ASSERT(tptoinpcb(tp)); in tcp_dropwithreset()
3457 tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, in tcp_dropwithreset()
3464 tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, in tcp_dropwithreset()
3592 struct tcpcb *tp = sototcpcb(so); in tcp_pulloutofband() local
3594 INP_WLOCK_ASSERT(tptoinpcb(tp)); in tcp_pulloutofband()
3596 tp->t_iobc = *cp; in tcp_pulloutofband()
3597 tp->t_oobflags |= TCPOOB_HAVEDATA; in tcp_pulloutofband()
3617 tcp_xmit_timer(struct tcpcb *tp, int rtt) in tcp_xmit_timer() argument
3621 INP_WLOCK_ASSERT(tptoinpcb(tp)); in tcp_xmit_timer()
3624 if (tp->t_rttupdated < UCHAR_MAX) in tcp_xmit_timer()
3625 tp->t_rttupdated++; in tcp_xmit_timer()
3627 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, in tcp_xmit_timer()
3630 if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { in tcp_xmit_timer()
3639 - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); in tcp_xmit_timer()
3641 if ((tp->t_srtt += delta) <= 0) in tcp_xmit_timer()
3642 tp->t_srtt = 1; in tcp_xmit_timer()
3656 delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); in tcp_xmit_timer()
3657 if ((tp->t_rttvar += delta) <= 0) in tcp_xmit_timer()
3658 tp->t_rttvar = 1; in tcp_xmit_timer()
3665 tp->t_srtt = rtt << TCP_RTT_SHIFT; in tcp_xmit_timer()
3666 tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); in tcp_xmit_timer()
3668 tp->t_rtttime = 0; in tcp_xmit_timer()
3669 tp->t_rxtshift = 0; in tcp_xmit_timer()
3682 TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), in tcp_xmit_timer()
3683 max(tp->t_rttmin, rtt + 2), tcp_rexmit_max); in tcp_xmit_timer()
3692 tp->t_softerror = 0; in tcp_xmit_timer()
3717 tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, in tcp_mss_update() argument
3722 struct inpcb *inp = tptoinpcb(tp); in tcp_mss_update()
3735 if (tp->t_port) in tcp_mss_update()
3746 tp->t_maxseg = V_tcp_v6mssdflt; in tcp_mss_update()
3755 tp->t_maxseg = V_tcp_mssdflt; in tcp_mss_update()
3781 offer = tp->t_maxseg; in tcp_mss_update()
3859 tp->t_maxseg = mss; in tcp_mss_update()
3860 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss_update()
3866 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3868 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3874 tcp_mss(struct tcpcb *tp, int offer) in tcp_mss() argument
3878 struct inpcb *inp = tptoinpcb(tp); in tcp_mss()
3883 KASSERT(tp != NULL, ("%s: tp == NULL", __func__)); in tcp_mss()
3886 tcp_mss_update(tp, offer, -1, &metrics, &cap); in tcp_mss()
3888 mss = tp->t_maxseg; in tcp_mss()
3921 tp->t_maxseg = max(mss, 64); in tcp_mss()
3922 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss()
3928 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss()
3930 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss()
3949 tp->t_flags |= TF_TSO; in tcp_mss()
3950 tp->t_tsomax = cap.tsomax; in tcp_mss()
3951 tp->t_tsomaxsegcount = cap.tsomaxsegcount; in tcp_mss()
3952 tp->t_tsomaxsegsize = cap.tsomaxsegsize; in tcp_mss()
3954 tp->t_flags2 |= TF2_IPSEC_TSO; in tcp_mss()
4001 tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, in tcp_do_prr_ack() argument
4008 INP_WLOCK_ASSERT(tptoinpcb(tp)); in tcp_do_prr_ack()
4011 *maxsegp = tcp_maxseg(tp); in tcp_do_prr_ack()
4019 if (tcp_is_sack_recovery(tp, to) || in tcp_do_prr_ack()
4020 (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_prr_ack()
4021 !IN_FASTRECOVERY(tp->t_flags))) { in tcp_do_prr_ack()
4022 del_data = tp->sackhint.delivered_data; in tcp_do_prr_ack()
4023 pipe = tcp_compute_pipe(tp); in tcp_do_prr_ack()
4025 if (tp->sackhint.prr_delivered < (tcprexmtthresh * maxseg + in tcp_do_prr_ack()
4026 tp->snd_recover - tp->snd_una)) { in tcp_do_prr_ack()
4029 pipe = imax(0, tp->snd_max - tp->snd_una - in tcp_do_prr_ack()
4030 imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); in tcp_do_prr_ack()
4036 tp->sackhint.prr_delivered += del_data; in tcp_do_prr_ack()
4040 if (pipe >= tp->snd_ssthresh) { in tcp_do_prr_ack()
4041 if (tp->sackhint.recover_fs == 0) in tcp_do_prr_ack()
4042 tp->sackhint.recover_fs = in tcp_do_prr_ack()
4043 imax(1, tp->snd_nxt - tp->snd_una); in tcp_do_prr_ack()
4044 snd_cnt = howmany((long)tp->sackhint.prr_delivered * in tcp_do_prr_ack()
4045 tp->snd_ssthresh, tp->sackhint.recover_fs) - in tcp_do_prr_ack()
4046 tp->sackhint.prr_out + maxseg - 1; in tcp_do_prr_ack()
4048 safe_ack = SEQ_GT(th->th_ack, tp->snd_una) && (sack_changed != SACK_NEWLOSS); in tcp_do_prr_ack()
4049 snd_cnt = imax(tp->sackhint.prr_delivered - tp->sackhint.prr_out, del_data); in tcp_do_prr_ack()
4053 snd_cnt = imin(tp->snd_ssthresh - pipe, snd_cnt); in tcp_do_prr_ack()
4056 if (tp->sackhint.prr_out == 0 && snd_cnt == 0) { in tcp_do_prr_ack()
4065 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4066 if (tcp_is_sack_recovery(tp, to)) { in tcp_do_prr_ack()
4067 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4069 tp->snd_cwnd = (tp->snd_max - tp->snd_una) + in tcp_do_prr_ack()
4072 } else if (IN_CONGRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4073 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4075 tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); in tcp_do_prr_ack()
4080 * next unacknowledged segment. Do not clear tp->t_dupacks.
4085 tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th) in tcp_newreno_partial_ack() argument
4087 tcp_seq onxt = tp->snd_nxt; in tcp_newreno_partial_ack()
4088 uint32_t ocwnd = tp->snd_cwnd; in tcp_newreno_partial_ack()
4089 u_int maxseg = tcp_maxseg(tp); in tcp_newreno_partial_ack()
4091 INP_WLOCK_ASSERT(tptoinpcb(tp)); in tcp_newreno_partial_ack()
4093 tcp_timer_activate(tp, TT_REXMT, 0); in tcp_newreno_partial_ack()
4094 tp->t_rtttime = 0; in tcp_newreno_partial_ack()
4095 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_newreno_partial_ack()
4096 tp->snd_nxt = th->th_ack; in tcp_newreno_partial_ack()
4099 * (tp->snd_una has not yet been updated when this function is called.) in tcp_newreno_partial_ack()
4101 tp->snd_cwnd = maxseg + BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4102 tp->t_flags |= TF_ACKNOW; in tcp_newreno_partial_ack()
4103 (void) tcp_output(tp); in tcp_newreno_partial_ack()
4104 tp->snd_cwnd = ocwnd; in tcp_newreno_partial_ack()
4105 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_newreno_partial_ack()
4106 tp->snd_nxt = onxt; in tcp_newreno_partial_ack()
4109 * Partial window deflation. Relies on fact that tp->snd_una in tcp_newreno_partial_ack()
4112 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) in tcp_newreno_partial_ack()
4113 tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4115 tp->snd_cwnd = 0; in tcp_newreno_partial_ack()
4116 tp->snd_cwnd += maxseg; in tcp_newreno_partial_ack()
4120 tcp_compute_pipe(struct tcpcb *tp) in tcp_compute_pipe() argument
4124 if (tp->t_fb->tfb_compute_pipe != NULL) { in tcp_compute_pipe()
4125 pipe = (*tp->t_fb->tfb_compute_pipe)(tp); in tcp_compute_pipe()
4127 pipe = tp->snd_max - tp->snd_una + in tcp_compute_pipe()
4128 tp->sackhint.sack_bytes_rexmit - in tcp_compute_pipe()
4129 tp->sackhint.sacked_bytes - in tcp_compute_pipe()
4130 tp->sackhint.lost_bytes; in tcp_compute_pipe()