Lines Matching +full:uni +full:- +full:directional
1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (c) 2007-2008,2010
8 * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org>
10 * Copyright (c) 2010-2011 Juniper Networks, Inc.
185 "Slow-start flight size (initial congestion window) in number of segments");
195 "Cap the max cwnd increment during slow-start to this number of segments");
261 return ((tp->t_flags & TF_SACK_PERMIT) && in tcp_is_sack_recovery()
262 ((to->to_flags & TOF_SACK) || in tcp_is_sack_recovery()
263 (!TAILQ_EMPTY(&tp->snd_holes)))); in tcp_is_sack_recovery()
275 if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) { in hhook_run_tcp_est_in()
281 &tp->t_osd); in hhook_run_tcp_est_in()
299 tp->t_ccv.nsegs = nsegs; in cc_ack_received()
300 tp->t_ccv.bytes_this_ack = BYTES_THIS_ACK(tp, th); in cc_ack_received()
301 if ((!V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd)) || in cc_ack_received()
302 (V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd) && in cc_ack_received()
303 (tp->snd_cwnd < (tcp_compute_pipe(tp) * 2)))) in cc_ack_received()
304 tp->t_ccv.flags |= CCF_CWND_LIMITED; in cc_ack_received()
306 tp->t_ccv.flags &= ~CCF_CWND_LIMITED; in cc_ack_received()
310 stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, in cc_ack_received()
311 ((int32_t)tp->snd_cwnd) - tp->snd_wnd); in cc_ack_received()
312 if (!IN_RECOVERY(tp->t_flags)) in cc_ack_received()
313 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_ACKLEN, in cc_ack_received()
314 tp->t_ccv.bytes_this_ack / (tcp_maxseg(tp) * nsegs)); in cc_ack_received()
315 if ((tp->t_flags & TF_GPUTINPROG) && in cc_ack_received()
316 SEQ_GEQ(th->th_ack, tp->gput_ack)) { in cc_ack_received()
320 gput = (((int64_t)SEQ_SUB(th->th_ack, tp->gput_seq)) << 3) / in cc_ack_received()
321 max(1, tcp_ts_getticks() - tp->gput_ts); in cc_ack_received()
322 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, in cc_ack_received()
329 if (tp->t_stats_gput_prev > 0) in cc_ack_received()
330 stats_voi_update_abs_s32(tp->t_stats, in cc_ack_received()
332 ((gput - tp->t_stats_gput_prev) * 100) / in cc_ack_received()
333 tp->t_stats_gput_prev); in cc_ack_received()
334 tp->t_flags &= ~TF_GPUTINPROG; in cc_ack_received()
335 tp->t_stats_gput_prev = gput; in cc_ack_received()
338 if (tp->snd_cwnd > tp->snd_ssthresh) { in cc_ack_received()
339 tp->t_bytes_acked += tp->t_ccv.bytes_this_ack; in cc_ack_received()
340 if (tp->t_bytes_acked >= tp->snd_cwnd) { in cc_ack_received()
341 tp->t_bytes_acked -= tp->snd_cwnd; in cc_ack_received()
342 tp->t_ccv.flags |= CCF_ABC_SENTAWND; in cc_ack_received()
345 tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; in cc_ack_received()
346 tp->t_bytes_acked = 0; in cc_ack_received()
350 if (CC_ALGO(tp)->ack_received != NULL) { in cc_ack_received()
352 tp->t_ccv.curack = th->th_ack; in cc_ack_received()
353 CC_ALGO(tp)->ack_received(&tp->t_ccv, type); in cc_ack_received()
356 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, tp->snd_cwnd); in cc_ack_received()
370 tcp_hc_get(&inp->inp_inc, &metrics); in cc_conn_init()
373 if (tp->t_srtt == 0 && (rtt = metrics.hc_rtt)) { in cc_conn_init()
374 tp->t_srtt = rtt; in cc_conn_init()
377 tp->t_rttvar = metrics.hc_rttvar; in cc_conn_init()
380 /* default variation is +- 1 rtt */ in cc_conn_init()
381 tp->t_rttvar = in cc_conn_init()
382 tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; in cc_conn_init()
384 TCPT_RANGESET(tp->t_rxtcur, in cc_conn_init()
385 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, in cc_conn_init()
386 tp->t_rttmin, tcp_rexmit_max); in cc_conn_init()
395 tp->snd_ssthresh = max(2 * maxseg, metrics.hc_ssthresh); in cc_conn_init()
400 * Set the initial slow-start flight size. in cc_conn_init()
406 if (tp->snd_cwnd == 1) in cc_conn_init()
407 tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ in cc_conn_init()
409 tp->snd_cwnd = tcp_compute_initwnd(maxseg); in cc_conn_init()
411 if (CC_ALGO(tp)->conn_init != NULL) in cc_conn_init()
412 CC_ALGO(tp)->conn_init(&tp->t_ccv); in cc_conn_init()
421 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); in cc_cong_signal()
426 if (!IN_FASTRECOVERY(tp->t_flags)) { in cc_cong_signal()
427 tp->snd_recover = tp->snd_max; in cc_cong_signal()
428 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
429 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
433 if (!IN_CONGRECOVERY(tp->t_flags) || in cc_cong_signal()
438 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in cc_cong_signal()
439 EXIT_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
441 tp->snd_recover = tp->snd_max + 1; in cc_cong_signal()
442 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
443 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
447 tp->t_dupacks = 0; in cc_cong_signal()
448 tp->t_bytes_acked = 0; in cc_cong_signal()
449 EXIT_RECOVERY(tp->t_flags); in cc_cong_signal()
450 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
451 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
456 tp->snd_cwnd = tp->snd_cwnd_prev; in cc_cong_signal()
457 tp->snd_ssthresh = tp->snd_ssthresh_prev; in cc_cong_signal()
458 tp->snd_recover = tp->snd_recover_prev; in cc_cong_signal()
459 if (tp->t_flags & TF_WASFRECOVERY) in cc_cong_signal()
460 ENTER_FASTRECOVERY(tp->t_flags); in cc_cong_signal()
461 if (tp->t_flags & TF_WASCRECOVERY) in cc_cong_signal()
462 ENTER_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
463 tp->snd_nxt = tp->snd_max; in cc_cong_signal()
464 tp->t_flags &= ~TF_PREVVALID; in cc_cong_signal()
465 tp->t_rxtshift = 0; in cc_cong_signal()
466 tp->t_badrxtwin = 0; in cc_cong_signal()
469 if (SEQ_LT(tp->snd_fack, tp->snd_una) || in cc_cong_signal()
470 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_cong_signal()
471 tp->snd_fack = tp->snd_una; in cc_cong_signal()
474 if (CC_ALGO(tp)->cong_signal != NULL) { in cc_cong_signal()
476 tp->t_ccv.curack = th->th_ack; in cc_cong_signal()
477 CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); in cc_cong_signal()
486 if (CC_ALGO(tp)->post_recovery != NULL) { in cc_post_recovery()
487 if (SEQ_LT(tp->snd_fack, th->th_ack) || in cc_post_recovery()
488 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_post_recovery()
489 tp->snd_fack = th->th_ack; in cc_post_recovery()
491 tp->t_ccv.curack = th->th_ack; in cc_post_recovery()
492 CC_ALGO(tp)->post_recovery(&tp->t_ccv); in cc_post_recovery()
494 EXIT_RECOVERY(tp->t_flags); in cc_post_recovery()
496 tp->t_bytes_acked = 0; in cc_post_recovery()
497 tp->sackhint.delivered_data = 0; in cc_post_recovery()
498 tp->sackhint.prr_delivered = 0; in cc_post_recovery()
499 tp->sackhint.prr_out = 0; in cc_post_recovery()
505 * - There is no delayed ack timer in progress.
506 * - Our last ack wasn't a 0-sized window. We never want to delay
507 * the ack that opens up a 0-sized window.
508 * - LRO wasn't used for this segment. We make sure by checking that the
513 (tp->t_flags & TF_RXWIN0SENT) == 0) && \
514 (tlen <= tp->t_maxseg) && \
515 (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
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_ccv.flags & CCF_ACKNOW) { in cc_ecnpkt_handler_flags()
545 tp->t_flags |= TF_ACKNOW; in cc_ecnpkt_handler_flags()
572 if (m->m_len < *offp + sizeof(struct tcphdr)) { in tcp6_input_with_port()
628 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; in tcp_input_with_port()
637 m->m_pkthdr.tcp_tun_port = port; in tcp_input_with_port()
642 tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0; in tcp_input_with_port()
645 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { in tcp_input_with_port()
646 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
647 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
649 th->th_sum = in6_cksum_pseudo(ip6, tlen, in tcp_input_with_port()
650 IPPROTO_TCP, m->m_pkthdr.csum_data); in tcp_input_with_port()
651 th->th_sum ^= 0xffff; in tcp_input_with_port()
652 } else if (m->m_pkthdr.csum_flags & CSUM_IP6_TCP) { in tcp_input_with_port()
657 th->th_sum = 0; in tcp_input_with_port()
659 th->th_sum = in6_cksum(m, IPPROTO_TCP, off0, tlen); in tcp_input_with_port()
660 if (th->th_sum) { in tcp_input_with_port()
667 * As we use all-zero to indicate unbounded/unconnected pcb, in tcp_input_with_port()
673 KASSERT(!IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst), in tcp_input_with_port()
675 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { in tcp_input_with_port()
695 if (m->m_len < sizeof (struct tcpiphdr)) { in tcp_input_with_port()
704 tlen = ntohs(ip->ip_len) - off0; in tcp_input_with_port()
706 iptos = ip->ip_tos; in tcp_input_with_port()
709 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { in tcp_input_with_port()
710 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
711 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
713 th->th_sum = in_pseudo(ip->ip_src.s_addr, in tcp_input_with_port()
714 ip->ip_dst.s_addr, in tcp_input_with_port()
715 htonl(m->m_pkthdr.csum_data + tlen + in tcp_input_with_port()
717 th->th_sum ^= 0xffff; in tcp_input_with_port()
718 } else if (m->m_pkthdr.csum_flags & CSUM_IP_TCP) { in tcp_input_with_port()
723 th->th_sum = 0; in tcp_input_with_port()
731 ipttl = ip->ip_ttl; in tcp_input_with_port()
732 bzero(ipov->ih_x1, sizeof(ipov->ih_x1)); in tcp_input_with_port()
733 ipov->ih_len = htons(tlen); in tcp_input_with_port()
734 th->th_sum = in_cksum(m, len); in tcp_input_with_port()
736 ip->ip_len = htons(len); in tcp_input_with_port()
738 ip->ip_tos = iptos; in tcp_input_with_port()
739 /* Re-initialization for later version check */ in tcp_input_with_port()
740 ip->ip_ttl = ipttl; in tcp_input_with_port()
741 ip->ip_v = IPVERSION; in tcp_input_with_port()
742 ip->ip_hl = off0 >> 2; in tcp_input_with_port()
745 if (th->th_sum && (port == 0)) { in tcp_input_with_port()
749 KASSERT(ip->ip_dst.s_addr != INADDR_ANY, in tcp_input_with_port()
751 if (__predict_false(ip->ip_src.s_addr == INADDR_ANY)) { in tcp_input_with_port()
762 off = th->th_off << 2; in tcp_input_with_port()
767 tlen -= off; /* tlen is used instead of ti->ti_len */ in tcp_input_with_port()
771 if (m->m_len < off0 + off) { in tcp_input_with_port()
787 if (m->m_len < sizeof(struct ip) + off) { in tcp_input_with_port()
798 optlen = off - sizeof (struct tcphdr); in tcp_input_with_port()
818 (isipv6 && (m->m_flags & M_IP6_NEXTHOP)) in tcp_input_with_port()
820 || (!isipv6 && (m->m_flags & M_IP_NEXTHOP)) in tcp_input_with_port()
824 (m->m_flags & M_IP_NEXTHOP) in tcp_input_with_port()
850 &ip6->ip6_src, th->th_sport, &ip6->ip6_dst, th->th_dport, in tcp_input_with_port()
851 lookupflag & ~INPLOOKUP_WILDCARD, m->m_pkthdr.rcvif, m); in tcp_input_with_port()
856 * any hardware-generated hash is ignored. in tcp_input_with_port()
858 inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
859 th->th_sport, &next_hop6->sin6_addr, in tcp_input_with_port()
860 next_hop6->sin6_port ? ntohs(next_hop6->sin6_port) : in tcp_input_with_port()
861 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
864 inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
865 th->th_sport, &ip6->ip6_dst, th->th_dport, lookupflag, in tcp_input_with_port()
866 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
881 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport, in tcp_input_with_port()
882 ip->ip_dst, th->th_dport, lookupflag & ~INPLOOKUP_WILDCARD, in tcp_input_with_port()
883 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
888 * any hardware-generated hash is ignored. in tcp_input_with_port()
890 inp = in_pcblookup(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
891 th->th_sport, next_hop->sin_addr, in tcp_input_with_port()
892 next_hop->sin_port ? ntohs(next_hop->sin_port) : in tcp_input_with_port()
893 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
896 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
897 th->th_sport, ip->ip_dst, th->th_dport, lookupflag, in tcp_input_with_port()
898 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
927 if ((inp->inp_flowtype == M_HASHTYPE_NONE) && in tcp_input_with_port()
928 !SOLISTENING(inp->inp_socket)) { in tcp_input_with_port()
930 inp->inp_flowid = m->m_pkthdr.flowid; in tcp_input_with_port()
931 inp->inp_flowtype = M_HASHTYPE_GET(m); in tcp_input_with_port()
937 rss_proto_software_hash_v6(&inp->in6p_faddr, in tcp_input_with_port()
938 &inp->in6p_laddr, in tcp_input_with_port()
939 inp->inp_fport, in tcp_input_with_port()
940 inp->inp_lport, in tcp_input_with_port()
942 &inp->inp_flowid, in tcp_input_with_port()
943 &inp->inp_flowtype); in tcp_input_with_port()
947 rss_proto_software_hash_v4(inp->inp_faddr, in tcp_input_with_port()
948 inp->inp_laddr, in tcp_input_with_port()
949 inp->inp_fport, in tcp_input_with_port()
950 inp->inp_lport, in tcp_input_with_port()
952 &inp->inp_flowid, in tcp_input_with_port()
953 &inp->inp_flowtype); in tcp_input_with_port()
979 if (inp->inp_ip_minttl != 0) { in tcp_input_with_port()
982 if (inp->inp_ip_minttl > ip6->ip6_hlim) in tcp_input_with_port()
986 if (inp->inp_ip_minttl > ip->ip_ttl) in tcp_input_with_port()
991 switch (tp->t_state) { in tcp_input_with_port()
1017 if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { in tcp_input_with_port()
1023 if (tp->t_flags & TF_TOE) { in tcp_input_with_port()
1034 so = inp->inp_socket; in tcp_input_with_port()
1041 KASSERT(tp->t_state == TCPS_LISTEN || !SOLISTENING(so), in tcp_input_with_port()
1043 if (tp->t_state == TCPS_LISTEN && SOLISTENING(so)) { in tcp_input_with_port()
1050 if (inp->inp_inc.inc_flags & INC_IPV6MINMTU) in tcp_input_with_port()
1052 inc.inc6_faddr = ip6->ip6_src; in tcp_input_with_port()
1053 inc.inc6_laddr = ip6->ip6_dst; in tcp_input_with_port()
1057 inc.inc_faddr = ip->ip_src; in tcp_input_with_port()
1058 inc.inc_laddr = ip->ip_dst; in tcp_input_with_port()
1060 inc.inc_fport = th->th_sport; in tcp_input_with_port()
1061 inc.inc_lport = th->th_dport; in tcp_input_with_port()
1062 inc.inc_fibnum = so->so_fibnum; in tcp_input_with_port()
1116 * We completed the 3-way handshake in tcp_input_with_port()
1142 * then listening socket is read-locked. in tcp_input_with_port()
1152 KASSERT(tp->t_state == TCPS_SYN_RECEIVED, in tcp_input_with_port()
1160 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, in tcp_input_with_port()
1248 * communication is okay - "SHOULD continue to be in tcp_input_with_port()
1255 * our source address selection - we must obey the peer. in tcp_input_with_port()
1259 * handling - worse, they are not exactly the same. in tcp_input_with_port()
1265 ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); in tcp_input_with_port()
1267 (ia6->ia6_flags & IN6_IFF_DEPRECATED)) { in tcp_input_with_port()
1283 * global or subnet broad- or multicast address. in tcp_input_with_port()
1285 * link-layer packets with a broadcast IP address. Use in tcp_input_with_port()
1288 if (m->m_flags & (M_BCAST|M_MCAST)) { in tcp_input_with_port()
1291 "Connection attempt from broad- or multicast " in tcp_input_with_port()
1297 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1298 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &ip6->ip6_src)) { in tcp_input_with_port()
1305 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_input_with_port()
1306 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { in tcp_input_with_port()
1320 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1321 ip->ip_dst.s_addr == ip->ip_src.s_addr) { in tcp_input_with_port()
1328 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_input_with_port()
1329 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_input_with_port()
1330 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_input_with_port()
1331 in_ifnet_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { in tcp_input_with_port()
1334 "Connection attempt from/to broad- " in tcp_input_with_port()
1358 if (tp->t_flags & TF_SIGNATURE) { in tcp_input_with_port()
1380 * write-lock on PCB. If upgrade fails, drop the SYN. in tcp_input_with_port()
1385 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, tlen, iptos); in tcp_input_with_port()
1398 isipv6 ? !in6_localip(&ip6->ip6_src) : in tcp_input_with_port()
1401 !in_localip(ip->ip_src) in tcp_input_with_port()
1431 * bandwidth and high delay (eg. trans-continental/oceanic links).
1453 * of slow-start but also makes it so our peer never gets limited
1470 if (V_tcp_do_autorcvbuf && (so->so_rcv.sb_flags & SB_AUTOSIZE) && in tcp_autorcvbuf()
1471 tp->t_srtt != 0 && tp->rfbuf_ts != 0 && in tcp_autorcvbuf()
1472 TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > in tcp_autorcvbuf()
1473 ((tp->t_srtt >> TCP_RTT_SHIFT)/2)) { in tcp_autorcvbuf()
1474 if (tp->rfbuf_cnt > ((so->so_rcv.sb_hiwat / 2)/ 4 * 3) && in tcp_autorcvbuf()
1475 so->so_rcv.sb_hiwat < V_tcp_autorcvbuf_max) { in tcp_autorcvbuf()
1476 newsize = min((so->so_rcv.sb_hiwat + (so->so_rcv.sb_hiwat/2)), V_tcp_autorcvbuf_max); in tcp_autorcvbuf()
1481 tp->rfbuf_ts = 0; in tcp_autorcvbuf()
1482 tp->rfbuf_cnt = 0; in tcp_autorcvbuf()
1484 tp->rfbuf_cnt += tlen; /* add up */ in tcp_autorcvbuf()
1501 if (tp->t_flags & TF_WAKESOR) { in tcp_handle_wakeup()
1504 tp->t_flags &= ~TF_WAKESOR; in tcp_handle_wakeup()
1523 struct in_conninfo *inc = &inp->inp_inc; in tcp_do_segment()
1532 tp->sackhint.last_sack_ack = 0; in tcp_do_segment()
1534 nsegs = max(1, m->m_pkthdr.lro_nsegs); in tcp_do_segment()
1538 KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", in tcp_do_segment()
1540 KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", in tcp_do_segment()
1543 TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, in tcp_do_segment()
1557 * If a segment with the ACK-bit set arrives in the SYN-SENT state in tcp_do_segment()
1560 if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && in tcp_do_segment()
1561 (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1568 * Reset idle time and keep-alive timer. in tcp_do_segment()
1572 if (tp->t_idle_reduce && in tcp_do_segment()
1573 (tp->snd_max == tp->snd_una) && in tcp_do_segment()
1574 ((ticks - tp->t_rcvtime) >= tp->t_rxtcur)) in tcp_do_segment()
1576 tp->t_rcvtime = ticks; in tcp_do_segment()
1581 * Scale up the window into a 32-bit value. in tcp_do_segment()
1584 tiwin = th->th_win << tp->snd_scale; in tcp_do_segment()
1586 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); in tcp_do_segment()
1593 tcp_packets_this_ack(tp, th->th_ack), in tcp_do_segment()
1601 (th->th_off << 2) - sizeof(struct tcphdr), in tcp_do_segment()
1603 if (tp->t_flags2 & TF2_PROC_SACK_PROHIBIT) { in tcp_do_segment()
1612 if ((tp->t_flags & TF_SIGNATURE) != 0 && in tcp_do_segment()
1625 to.to_tsecr -= tp->ts_offset; in tcp_do_segment()
1637 if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { in tcp_do_segment()
1641 (tp->t_flags & TF_REQ_SCALE) && in tcp_do_segment()
1642 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1643 tp->t_flags |= TF_RCVD_SCALE; in tcp_do_segment()
1644 tp->snd_scale = to.to_wscale; in tcp_do_segment()
1646 tp->t_flags &= ~TF_REQ_SCALE; in tcp_do_segment()
1652 tp->snd_wnd = th->th_win; in tcp_do_segment()
1654 (tp->t_flags & TF_REQ_TSTMP) && in tcp_do_segment()
1655 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1656 tp->t_flags |= TF_RCVD_TSTMP; in tcp_do_segment()
1657 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1658 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1660 tp->t_flags &= ~TF_REQ_TSTMP; in tcp_do_segment()
1665 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
1667 (tp->t_flags & TF_NOOPT))) { in tcp_do_segment()
1668 tp->t_flags &= ~TF_SACK_PERMIT; in tcp_do_segment()
1670 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1672 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1678 if ((inp->inp_vflag & INP_IPV6) != 0) { in tcp_do_segment()
1699 if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { in tcp_do_segment()
1722 if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) { in tcp_do_segment()
1732 * of a uni-directional data xfer. If the packet has in tcp_do_segment()
1733 * no control flags, is in-sequence, the window didn't in tcp_do_segment()
1739 * is non-zero and the ack didn't move, we're the in tcp_do_segment()
1740 * receiver side. If we're getting packets in-order in tcp_do_segment()
1743 * Make sure that the hidden state-flags are also off. in tcp_do_segment()
1747 if (tp->t_state == TCPS_ESTABLISHED && in tcp_do_segment()
1748 th->th_seq == tp->rcv_nxt && in tcp_do_segment()
1750 tp->snd_nxt == tp->snd_max && in tcp_do_segment()
1751 tiwin && tiwin == tp->snd_wnd && in tcp_do_segment()
1752 ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && in tcp_do_segment()
1755 TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { in tcp_do_segment()
1763 SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { in tcp_do_segment()
1764 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1765 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1769 if (SEQ_GT(th->th_ack, tp->snd_una) && in tcp_do_segment()
1770 SEQ_LEQ(th->th_ack, tp->snd_max) && in tcp_do_segment()
1771 !IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
1773 TAILQ_EMPTY(&tp->snd_holes)) { in tcp_do_segment()
1782 if (tp->t_rxtshift == 1 && in tcp_do_segment()
1783 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1784 tp->t_badrxtwin != 0 && in tcp_do_segment()
1787 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) || in tcp_do_segment()
1789 TSTMP_LT(ticks, tp->t_badrxtwin)))) in tcp_do_segment()
1804 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
1805 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
1806 tp->t_rttlow = t; in tcp_do_segment()
1809 } else if (tp->t_rtttime && in tcp_do_segment()
1810 SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
1811 if (!tp->t_rttlow || in tcp_do_segment()
1812 tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
1813 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
1815 ticks - tp->t_rtttime); in tcp_do_segment()
1826 sbdrop(&so->so_snd, acked); in tcp_do_segment()
1827 if (SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
1828 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
1829 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
1839 tp->snd_una = th->th_ack; in tcp_do_segment()
1844 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
1845 tp->t_dupacks = 0; in tcp_do_segment()
1851 * using current (possibly backed-off) value. in tcp_do_segment()
1864 if (sbavail(&so->so_snd) == 0) in tcp_do_segment()
1865 tp->t_acktime = 0; in tcp_do_segment()
1867 tp->t_acktime = ticks; in tcp_do_segment()
1868 if (tp->snd_una == tp->snd_max) in tcp_do_segment()
1879 if ((tp->t_flags & TF_ACKNOW) || in tcp_do_segment()
1880 (sbavail(&so->so_snd) >= in tcp_do_segment()
1881 SEQ_SUB(tp->snd_max, tp->snd_una))) { in tcp_do_segment()
1886 } else if (th->th_ack == tp->snd_una && in tcp_do_segment()
1887 tlen <= sbspace(&so->so_rcv)) { in tcp_do_segment()
1891 * This is a pure, in-sequence data packet with in tcp_do_segment()
1896 if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks) in tcp_do_segment()
1899 tp->rcv_nxt += tlen; in tcp_do_segment()
1901 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
1902 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
1903 tp->t_fbyte_in = ticks; in tcp_do_segment()
1904 if (tp->t_fbyte_in == 0) in tcp_do_segment()
1905 tp->t_fbyte_in = 1; in tcp_do_segment()
1906 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
1907 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
1913 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
1918 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
1927 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
1937 so->so_rcv.sb_flags &= ~SB_AUTOSIZE; in tcp_do_segment()
1939 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
1944 tp->t_flags |= TF_DELACK; in tcp_do_segment()
1946 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
1959 win = sbspace(&so->so_rcv); in tcp_do_segment()
1962 tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); in tcp_do_segment()
1964 switch (tp->t_state) { in tcp_do_segment()
1975 (SEQ_LEQ(th->th_ack, tp->snd_una) || in tcp_do_segment()
1976 SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1980 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1992 /* non-initial SYN is ignored */ in tcp_do_segment()
2009 * initialize tp->rcv_nxt and tp->irs in tcp_do_segment()
2010 * if seg contains ack then advance tp->snd_una in tcp_do_segment()
2029 tp->irs = th->th_seq; in tcp_do_segment()
2040 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2042 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2044 tp->rcv_adv += min(tp->rcv_wnd, in tcp_do_segment()
2045 TCP_MAXWIN << tp->rcv_scale); in tcp_do_segment()
2046 tp->snd_una++; /* SYN is acked */ in tcp_do_segment()
2047 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
2048 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
2053 if ((tp->t_flags & TF_FASTOPEN) && in tcp_do_segment()
2054 (tp->snd_una != tp->snd_max)) { in tcp_do_segment()
2055 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2066 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2073 * SYN_SENT --> ESTABLISHED in tcp_do_segment()
2074 * SYN_SENT* --> FIN_WAIT_1 in tcp_do_segment()
2076 tp->t_starttime = ticks; in tcp_do_segment()
2077 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2078 tp->t_acktime = ticks; in tcp_do_segment()
2080 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2092 * Received initial SYN in SYN-SENT[*] state => in tcp_do_segment()
2094 * If it succeeds, connection is * half-synchronized. in tcp_do_segment()
2095 * Otherwise, do 3-way handshake: in tcp_do_segment()
2096 * SYN-SENT -> SYN-RECEIVED in tcp_do_segment()
2097 * SYN-SENT* -> SYN-RECEIVED* in tcp_do_segment()
2099 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); in tcp_do_segment()
2105 * Advance th->th_seq to correspond to first data byte. in tcp_do_segment()
2109 th->th_seq++; in tcp_do_segment()
2110 if (tlen > tp->rcv_wnd) { in tcp_do_segment()
2111 todrop = tlen - tp->rcv_wnd; in tcp_do_segment()
2112 m_adj(m, -todrop); in tcp_do_segment()
2113 tlen = tp->rcv_wnd; in tcp_do_segment()
2118 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2119 tp->rcv_up = th->th_seq; in tcp_do_segment()
2152 * - RST drops connection only if SEG.SEQ == RCV.NXT. in tcp_do_segment()
2153 * - If RST is in window, we send challenge ACK. in tcp_do_segment()
2160 if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2161 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || in tcp_do_segment()
2162 (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { in tcp_do_segment()
2163 KASSERT(tp->t_state != TCPS_SYN_SENT, in tcp_do_segment()
2168 tp->last_ack_sent == th->th_seq) { in tcp_do_segment()
2171 switch (tp->t_state) { in tcp_do_segment()
2173 so->so_error = ECONNREFUSED; in tcp_do_segment()
2181 so->so_error = ECONNRESET; in tcp_do_segment()
2201 if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT && in tcp_do_segment()
2202 tp->t_state != TCPS_SYN_RECEIVED) { in tcp_do_segment()
2205 SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2206 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { in tcp_do_segment()
2221 if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && in tcp_do_segment()
2222 TSTMP_LT(to.to_tsval, tp->ts_recent)) { in tcp_do_segment()
2224 if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { in tcp_do_segment()
2233 * because we don't want out-of-order segments to be in tcp_do_segment()
2236 tp->ts_recent = 0; in tcp_do_segment()
2248 * In the SYN-RECEIVED state, validate that the packet belongs to in tcp_do_segment()
2254 if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { in tcp_do_segment()
2259 todrop = tp->rcv_nxt - th->th_seq; in tcp_do_segment()
2263 th->th_seq++; in tcp_do_segment()
2264 if (th->th_urp > 1) in tcp_do_segment()
2265 th->th_urp--; in tcp_do_segment()
2268 todrop--; in tcp_do_segment()
2286 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2295 * DSACK - add SACK block for dropped range in tcp_do_segment()
2297 if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2298 tcp_update_sack_list(tp, th->th_seq, in tcp_do_segment()
2299 th->th_seq + todrop); in tcp_do_segment()
2301 * ACK now, as the next in-sequence segment in tcp_do_segment()
2304 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2307 th->th_seq += todrop; in tcp_do_segment()
2308 tlen -= todrop; in tcp_do_segment()
2309 if (th->th_urp > todrop) in tcp_do_segment()
2310 th->th_urp -= todrop; in tcp_do_segment()
2313 th->th_urp = 0; in tcp_do_segment()
2322 if ((tp->t_flags & TF_CLOSED) && tlen > 0 && in tcp_do_segment()
2323 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
2328 s, __func__, tcpstates[tp->t_state], tlen); in tcp_do_segment()
2332 /* tcp_close will kill the inp pre-log the Reset */ in tcp_do_segment()
2343 todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); in tcp_do_segment()
2355 if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { in tcp_do_segment()
2356 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2362 m_adj(m, -todrop); in tcp_do_segment()
2363 tlen -= todrop; in tcp_do_segment()
2386 SEQ_LEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2387 SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + in tcp_do_segment()
2389 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
2390 tp->ts_recent = to.to_tsval; in tcp_do_segment()
2394 * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN in tcp_do_segment()
2395 * flag is on (half-synchronized state), then queue data for in tcp_do_segment()
2399 if (tp->t_state == TCPS_SYN_RECEIVED || in tcp_do_segment()
2400 (tp->t_flags & TF_NEEDSYN)) { in tcp_do_segment()
2401 if (tp->t_state == TCPS_SYN_RECEIVED && in tcp_do_segment()
2402 (tp->t_flags & TF_FASTOPEN)) { in tcp_do_segment()
2403 tp->snd_wnd = tiwin; in tcp_do_segment()
2407 } else if (tp->t_flags & TF_ACKNOW) in tcp_do_segment()
2416 if (SEQ_GEQ(tp->snd_una, tp->iss + (TCP_MAXWIN << tp->snd_scale))) { in tcp_do_segment()
2418 tp->t_flags2 |= TF2_NO_ISS_CHECK; in tcp_do_segment()
2424 if (tp->t_flags2 & TF2_NO_ISS_CHECK) { in tcp_do_segment()
2426 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2429 if (SEQ_GT(tp->iss + 1, tp->snd_una - tp->max_sndwnd)) { in tcp_do_segment()
2431 seq_min = tp->iss + 1; in tcp_do_segment()
2438 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2442 if (SEQ_LT(th->th_ack, seq_min)) { in tcp_do_segment()
2452 switch (tp->t_state) { in tcp_do_segment()
2461 if (tp->t_flags & TF_SONOTCONN) { in tcp_do_segment()
2471 tp->t_flags &= ~TF_SONOTCONN; in tcp_do_segment()
2475 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2477 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2479 tp->snd_wnd = tiwin; in tcp_do_segment()
2482 * SYN-RECEIVED -> ESTABLISHED in tcp_do_segment()
2483 * SYN-RECEIVED* -> FIN-WAIT-1 in tcp_do_segment()
2485 tp->t_starttime = ticks; in tcp_do_segment()
2486 if ((tp->t_flags & TF_FASTOPEN) && tp->t_tfo_pending) { in tcp_do_segment()
2487 tcp_fastopen_decrement_counter(tp->t_tfo_pending); in tcp_do_segment()
2488 tp->t_tfo_pending = NULL; in tcp_do_segment()
2490 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2491 tp->t_acktime = ticks; in tcp_do_segment()
2493 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2505 if (!(tp->t_flags & TF_FASTOPEN)) in tcp_do_segment()
2514 if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) in tcp_do_segment()
2525 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2531 * tp->snd_una < th->th_ack <= tp->snd_max in tcp_do_segment()
2532 * then advance tp->snd_una to th->th_ack and drop in tcp_do_segment()
2542 if (SEQ_GT(th->th_ack, tp->snd_max)) { in tcp_do_segment()
2547 sack_changed = tcp_sack_doack(tp, &to, th->th_ack); in tcp_do_segment()
2549 (tp->t_flags & TF_LRD)) { in tcp_do_segment()
2557 tp->sackhint.sacked_bytes = 0; in tcp_do_segment()
2564 if (SEQ_LT(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2568 if (th->th_ack == tp->snd_una) { in tcp_do_segment()
2570 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
2587 if (!no_data || tiwin != tp->snd_wnd) { in tcp_do_segment()
2599 (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { in tcp_do_segment()
2600 tp->t_dupacks = 0; in tcp_do_segment()
2607 tp->t_dupacks = 0; in tcp_do_segment()
2608 } else if (++tp->t_dupacks > tcprexmtthresh || in tcp_do_segment()
2609 IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2612 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2613 (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2617 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2618 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2628 if (awnd < tp->snd_ssthresh) { in tcp_do_segment()
2629 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2631 tp->sackhint.delivered_data)); in tcp_do_segment()
2632 if (tp->snd_cwnd > tp->snd_ssthresh) in tcp_do_segment()
2633 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2636 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2637 SEQ_LT(tp->snd_nxt, tp->snd_max)) { in tcp_do_segment()
2638 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2640 tp->sackhint.delivered_data)); in tcp_do_segment()
2642 tp->snd_cwnd += maxseg; in tcp_do_segment()
2646 } else if (tp->t_dupacks == tcprexmtthresh || in tcp_do_segment()
2647 (tp->t_flags & TF_SACK_PERMIT && in tcp_do_segment()
2649 tp->sackhint.sacked_bytes > in tcp_do_segment()
2650 (tcprexmtthresh - 1) * maxseg)) { in tcp_do_segment()
2654 * more than (dupthresh-1)*maxseg sacked data. in tcp_do_segment()
2660 tp->t_dupacks = tcprexmtthresh; in tcp_do_segment()
2661 tcp_seq onxt = tp->snd_nxt; in tcp_do_segment()
2671 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2672 tp->t_dupacks = 0; in tcp_do_segment()
2676 if (SEQ_LEQ(th->th_ack, in tcp_do_segment()
2677 tp->snd_recover)) { in tcp_do_segment()
2678 tp->t_dupacks = 0; in tcp_do_segment()
2686 tp->t_rtttime = 0; in tcp_do_segment()
2697 tp->sackhint.prr_delivered = in tcp_do_segment()
2698 imin(tp->snd_max - th->th_ack, in tcp_do_segment()
2699 (tp->snd_limited + 1) * maxseg); in tcp_do_segment()
2701 tp->sackhint.prr_delivered = in tcp_do_segment()
2704 tp->sackhint.recover_fs = max(1, in tcp_do_segment()
2705 tp->snd_nxt - tp->snd_una); in tcp_do_segment()
2707 tp->snd_limited = 0; in tcp_do_segment()
2717 tp->snd_nxt = tp->snd_max; in tcp_do_segment()
2718 tp->snd_cwnd = tcp_compute_pipe(tp) + in tcp_do_segment()
2722 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2725 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2726 tp->snd_cwnd = maxseg; in tcp_do_segment()
2728 KASSERT(tp->snd_limited <= 2, in tcp_do_segment()
2729 ("%s: tp->snd_limited too big", in tcp_do_segment()
2731 tp->snd_cwnd = tp->snd_ssthresh + in tcp_do_segment()
2733 (tp->t_dupacks - tp->snd_limited); in tcp_do_segment()
2734 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_do_segment()
2735 tp->snd_nxt = onxt; in tcp_do_segment()
2749 uint32_t oldcwnd = tp->snd_cwnd; in tcp_do_segment()
2750 tcp_seq oldsndmax = tp->snd_max; in tcp_do_segment()
2754 KASSERT(tp->t_dupacks == 1 || in tcp_do_segment()
2755 tp->t_dupacks == 2, in tcp_do_segment()
2758 if (tp->t_dupacks == 1) in tcp_do_segment()
2759 tp->snd_limited = 0; in tcp_do_segment()
2760 if ((tp->snd_nxt == tp->snd_max) && in tcp_do_segment()
2761 (tp->t_rxtshift == 0)) in tcp_do_segment()
2762 tp->snd_cwnd = in tcp_do_segment()
2763 SEQ_SUB(tp->snd_nxt, tp->snd_una); in tcp_do_segment()
2764 tp->snd_cwnd += in tcp_do_segment()
2765 (tp->t_dupacks - tp->snd_limited) * maxseg; in tcp_do_segment()
2766 tp->snd_cwnd -= tcp_sack_adjust(tp); in tcp_do_segment()
2773 avail = sbavail(&so->so_snd); in tcp_do_segment()
2775 if (tp->t_flags & TF_ACKNOW || in tcp_do_segment()
2777 SEQ_SUB(tp->snd_nxt, tp->snd_una))) { in tcp_do_segment()
2780 sent = SEQ_SUB(tp->snd_max, oldsndmax); in tcp_do_segment()
2782 KASSERT((tp->t_dupacks == 2 && in tcp_do_segment()
2783 tp->snd_limited == 0) || in tcp_do_segment()
2785 tp->t_flags & TF_SENTFIN) || in tcp_do_segment()
2787 tp->t_flags & TF_NODELAY), in tcp_do_segment()
2790 tp->snd_limited = 2; in tcp_do_segment()
2792 ++tp->snd_limited; in tcp_do_segment()
2794 tp->snd_cwnd = oldcwnd; in tcp_do_segment()
2799 KASSERT(SEQ_GT(th->th_ack, tp->snd_una), in tcp_do_segment()
2805 tp->t_dupacks = 0; in tcp_do_segment()
2817 (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || in tcp_do_segment()
2818 ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && in tcp_do_segment()
2819 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2820 tp->t_dupacks++; in tcp_do_segment()
2822 if (!IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2823 (tp->sackhint.sacked_bytes > in tcp_do_segment()
2824 (tcprexmtthresh - 1) * (maxseg = tcp_maxseg(tp)))) { in tcp_do_segment()
2832 if (SEQ_LT(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
2833 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2834 if (tp->t_flags & TF_SACK_PERMIT) { in tcp_do_segment()
2839 tp->t_rtttime = 0; in tcp_do_segment()
2842 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2851 } else if (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_segment()
2853 tp->sackhint.delivered_data = in tcp_do_segment()
2855 tp->snd_fack = th->th_ack; in tcp_do_segment()
2858 * always use PRR-SSRB in tcp_do_segment()
2869 if (tp->t_flags & TF_NEEDSYN) { in tcp_do_segment()
2871 * T/TCP: Connection was half-synchronized, and our in tcp_do_segment()
2873 * synchronized). Go to non-starred state, in tcp_do_segment()
2877 tp->t_flags &= ~TF_NEEDSYN; in tcp_do_segment()
2878 tp->snd_una++; in tcp_do_segment()
2880 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2882 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2893 * This is for the SYN_RECEIVED, non-simultaneous in tcp_do_segment()
2898 tp->snd_una++; in tcp_do_segment()
2901 "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__, in tcp_do_segment()
2902 tp->snd_una, th->th_ack, tp, m)); in tcp_do_segment()
2913 if (tp->t_rxtshift == 1 && in tcp_do_segment()
2914 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
2915 tp->t_badrxtwin != 0 && in tcp_do_segment()
2918 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) in tcp_do_segment()
2938 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
2939 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
2940 tp->t_rttlow = t; in tcp_do_segment()
2942 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
2943 if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
2944 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
2945 tcp_xmit_timer(tp, ticks - tp->t_rtttime); in tcp_do_segment()
2955 if ((tp->t_state <= TCPS_CLOSE_WAIT && in tcp_do_segment()
2956 acked == sbavail(&so->so_snd)) || in tcp_do_segment()
2957 acked > sbavail(&so->so_snd)) in tcp_do_segment()
2958 tp->t_acktime = 0; in tcp_do_segment()
2960 tp->t_acktime = ticks; in tcp_do_segment()
2966 * timer, using current (possibly backed-off) value. in tcp_do_segment()
2968 if (th->th_ack == tp->snd_max) { in tcp_do_segment()
2990 if (acked > sbavail(&so->so_snd)) { in tcp_do_segment()
2991 if (tp->snd_wnd >= sbavail(&so->so_snd)) in tcp_do_segment()
2992 tp->snd_wnd -= sbavail(&so->so_snd); in tcp_do_segment()
2994 tp->snd_wnd = 0; in tcp_do_segment()
2995 mfree = sbcut_locked(&so->so_snd, in tcp_do_segment()
2996 (int)sbavail(&so->so_snd)); in tcp_do_segment()
2999 mfree = sbcut_locked(&so->so_snd, acked); in tcp_do_segment()
3000 if (tp->snd_wnd >= (uint32_t) acked) in tcp_do_segment()
3001 tp->snd_wnd -= acked; in tcp_do_segment()
3003 tp->snd_wnd = 0; in tcp_do_segment()
3010 if (!IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3011 SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
3012 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
3013 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
3014 tp->snd_una = th->th_ack; in tcp_do_segment()
3015 if (IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3016 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
3019 if (SEQ_GT(tp->snd_una, tp->snd_recover)) { in tcp_do_segment()
3020 tp->snd_recover = tp->snd_una; in tcp_do_segment()
3022 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
3023 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
3025 switch (tp->t_state) { in tcp_do_segment()
3040 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
3055 * then enter the TIME-WAIT state, otherwise ignore in tcp_do_segment()
3089 (SEQ_LT(tp->snd_wl1, th->th_seq) || in tcp_do_segment()
3090 (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || in tcp_do_segment()
3091 (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { in tcp_do_segment()
3093 if (no_data && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) in tcp_do_segment()
3095 tp->snd_wnd = tiwin; in tcp_do_segment()
3096 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
3097 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
3098 if (tp->snd_wnd > tp->max_sndwnd) in tcp_do_segment()
3099 tp->max_sndwnd = tp->snd_wnd; in tcp_do_segment()
3106 if ((thflags & TH_URG) && th->th_urp && in tcp_do_segment()
3107 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3115 if (th->th_urp + sbavail(&so->so_rcv) > sb_max) { in tcp_do_segment()
3116 th->th_urp = 0; /* XXX */ in tcp_do_segment()
3135 if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { in tcp_do_segment()
3136 tp->rcv_up = th->th_seq + th->th_urp; in tcp_do_segment()
3137 so->so_oobmark = sbavail(&so->so_rcv) + in tcp_do_segment()
3138 (tp->rcv_up - tp->rcv_nxt) - 1; in tcp_do_segment()
3139 if (so->so_oobmark == 0) in tcp_do_segment()
3140 so->so_rcv.sb_state |= SBS_RCVATMARK; in tcp_do_segment()
3142 tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); in tcp_do_segment()
3148 * but if two URG's are pending at once, some out-of-band in tcp_do_segment()
3151 if (th->th_urp <= (uint32_t)tlen && in tcp_do_segment()
3152 !(so->so_options & SO_OOBINLINE)) { in tcp_do_segment()
3162 if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) in tcp_do_segment()
3163 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
3171 * This process logically involves adjusting tp->rcv_wnd as data in tcp_do_segment()
3176 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && in tcp_do_segment()
3177 (tp->t_flags & TF_FASTOPEN)); in tcp_do_segment()
3179 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3180 tcp_seq save_start = th->th_seq; in tcp_do_segment()
3181 tcp_seq save_rnxt = tp->rcv_nxt; in tcp_do_segment()
3196 if (th->th_seq == tp->rcv_nxt && in tcp_do_segment()
3198 (TCPS_HAVEESTABLISHED(tp->t_state) || in tcp_do_segment()
3201 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3203 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3204 tp->rcv_nxt += tlen; in tcp_do_segment()
3206 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
3207 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
3208 tp->t_fbyte_in = ticks; in tcp_do_segment()
3209 if (tp->t_fbyte_in == 0) in tcp_do_segment()
3210 tp->t_fbyte_in = 1; in tcp_do_segment()
3211 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
3212 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
3218 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) in tcp_do_segment()
3221 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
3222 tp->t_flags |= TF_WAKESOR; in tcp_do_segment()
3233 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3235 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
3237 TCPS_HAVEESTABLISHED(tp->t_state)) { in tcp_do_segment()
3245 } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { in tcp_do_segment()
3246 if ((tp->rcv_numsacks >= 1) && in tcp_do_segment()
3247 (tp->sackblks[0].end == save_start)) { in tcp_do_segment()
3253 tp->sackblks[0].start, in tcp_do_segment()
3254 tp->sackblks[0].end); in tcp_do_segment()
3276 if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) in tcp_do_segment()
3277 len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); in tcp_do_segment()
3279 len = so->so_rcv.sb_hiwat; in tcp_do_segment()
3290 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3297 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3306 tcpstates[tp->t_state]); in tcp_do_segment()
3320 if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3324 * If connection is half-synchronized in tcp_do_segment()
3330 if (tp->t_flags & TF_NEEDSYN) in tcp_do_segment()
3331 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3333 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3334 tp->rcv_nxt++; in tcp_do_segment()
3336 switch (tp->t_state) { in tcp_do_segment()
3342 tp->t_starttime = ticks; in tcp_do_segment()
3358 * starting the time-wait timer, turning off the other in tcp_do_segment()
3371 if (needoutput || (tp->t_flags & TF_ACKNOW)) { in tcp_do_segment()
3377 if (tp->t_flags & TF_DELACK) { in tcp_do_segment()
3378 tp->t_flags &= ~TF_DELACK; in tcp_do_segment()
3393 * In the SYN-RECEIVED state, don't send an ACK unless the in tcp_do_segment()
3394 * segment we received passes the SYN-RECEIVED ACK test. in tcp_do_segment()
3400 if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && in tcp_do_segment()
3401 (SEQ_GT(tp->snd_una, th->th_ack) || in tcp_do_segment()
3402 SEQ_GT(th->th_ack, tp->snd_max)) ) { in tcp_do_segment()
3407 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3451 if ((tcp_get_flags(th) & TH_RST) || m->m_flags & (M_BCAST|M_MCAST)) in tcp_dropwithreset()
3454 if (mtod(m, struct ip *)->ip_v == 6) { in tcp_dropwithreset()
3456 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_dropwithreset()
3457 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) in tcp_dropwithreset()
3468 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_dropwithreset()
3469 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_dropwithreset()
3470 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_dropwithreset()
3471 in_ifnet_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) in tcp_dropwithreset()
3483 th->th_ack, TH_RST); in tcp_dropwithreset()
3489 tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, in tcp_dropwithreset()
3505 to->to_flags = 0; in tcp_dooptions()
3506 for (; cnt > 0; cnt -= optlen, cp += optlen) { in tcp_dooptions()
3525 to->to_flags |= TOF_MSS; in tcp_dooptions()
3527 (char *)&to->to_mss, sizeof(to->to_mss)); in tcp_dooptions()
3528 to->to_mss = ntohs(to->to_mss); in tcp_dooptions()
3535 to->to_flags |= TOF_SCALE; in tcp_dooptions()
3536 to->to_wscale = min(cp[2], TCP_MAX_WINSHIFT); in tcp_dooptions()
3541 to->to_flags |= TOF_TS; in tcp_dooptions()
3543 (char *)&to->to_tsval, sizeof(to->to_tsval)); in tcp_dooptions()
3544 to->to_tsval = ntohl(to->to_tsval); in tcp_dooptions()
3546 (char *)&to->to_tsecr, sizeof(to->to_tsecr)); in tcp_dooptions()
3547 to->to_tsecr = ntohl(to->to_tsecr); in tcp_dooptions()
3559 to->to_flags |= TOF_SIGNATURE; in tcp_dooptions()
3560 to->to_signature = cp + 2; in tcp_dooptions()
3569 to->to_flags |= TOF_SACKPERM; in tcp_dooptions()
3572 if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) in tcp_dooptions()
3576 to->to_flags |= TOF_SACK; in tcp_dooptions()
3577 to->to_nsacks = (optlen - 2) / TCPOLEN_SACK; in tcp_dooptions()
3578 to->to_sacks = cp + 2; in tcp_dooptions()
3592 to->to_flags |= TOF_FASTOPEN; in tcp_dooptions()
3593 to->to_tfo_len = optlen - 2; in tcp_dooptions()
3594 to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL; in tcp_dooptions()
3612 int cnt = off + th->th_urp - 1; in tcp_pulloutofband()
3615 if (m->m_len > cnt) { in tcp_pulloutofband()
3621 tp->t_iobc = *cp; in tcp_pulloutofband()
3622 tp->t_oobflags |= TCPOOB_HAVEDATA; in tcp_pulloutofband()
3623 bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); in tcp_pulloutofband()
3624 m->m_len--; in tcp_pulloutofband()
3625 if (m->m_flags & M_PKTHDR) in tcp_pulloutofband()
3626 m->m_pkthdr.len--; in tcp_pulloutofband()
3629 cnt -= m->m_len; in tcp_pulloutofband()
3630 m = m->m_next; in tcp_pulloutofband()
3638 * Collect new round-trip time estimate
3649 if (tp->t_rttupdated < UCHAR_MAX) in tcp_xmit_timer()
3650 tp->t_rttupdated++; in tcp_xmit_timer()
3652 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, in tcp_xmit_timer()
3655 if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { in tcp_xmit_timer()
3663 delta = ((rtt - 1) << TCP_DELTA_SHIFT) in tcp_xmit_timer()
3664 - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); in tcp_xmit_timer()
3666 if ((tp->t_srtt += delta) <= 0) in tcp_xmit_timer()
3667 tp->t_srtt = 1; in tcp_xmit_timer()
3677 * rfc793's wired-in beta. in tcp_xmit_timer()
3680 delta = -delta; in tcp_xmit_timer()
3681 delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); in tcp_xmit_timer()
3682 if ((tp->t_rttvar += delta) <= 0) in tcp_xmit_timer()
3683 tp->t_rttvar = 1; in tcp_xmit_timer()
3686 * No rtt measurement yet - use the unsmoothed rtt. in tcp_xmit_timer()
3690 tp->t_srtt = rtt << TCP_RTT_SHIFT; in tcp_xmit_timer()
3691 tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); in tcp_xmit_timer()
3693 tp->t_rtttime = 0; in tcp_xmit_timer()
3694 tp->t_rxtshift = 0; in tcp_xmit_timer()
3701 * 1 extra tick because of +-1/2 tick uncertainty in the in tcp_xmit_timer()
3707 TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), in tcp_xmit_timer()
3708 max(tp->t_rttmin, rtt + 2), tcp_rexmit_max); in tcp_xmit_timer()
3717 tp->t_softerror = 0; in tcp_xmit_timer()
3730 * While looking at the routing entry, we also initialize other path-dependent
3731 * parameters from pre-set or cached values in the routing entry.
3750 int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; in tcp_mss_update()
3760 if (tp->t_port) in tcp_mss_update()
3762 if (mtuoffer != -1) { in tcp_mss_update()
3763 KASSERT(offer == -1, ("%s: conflict", __func__)); in tcp_mss_update()
3764 offer = mtuoffer - min_protoh; in tcp_mss_update()
3770 maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); in tcp_mss_update()
3771 tp->t_maxseg = V_tcp_v6mssdflt; in tcp_mss_update()
3779 maxmtu = tcp_maxmtu(&inp->inp_inc, cap); in tcp_mss_update()
3780 tp->t_maxseg = V_tcp_mssdflt; in tcp_mss_update()
3806 offer = tp->t_maxseg; in tcp_mss_update()
3809 case -1: in tcp_mss_update()
3811 * Offer == -1 means that we didn't receive SYN yet. in tcp_mss_update()
3825 tcp_hc_get(&inp->inp_inc, metricptr); in tcp_mss_update()
3831 if (metricptr->hc_mtu) in tcp_mss_update()
3832 mss = min(metricptr->hc_mtu, maxmtu) - min_protoh; in tcp_mss_update()
3836 mss = maxmtu - min_protoh; in tcp_mss_update()
3838 !in6_localaddr(&inp->in6p_faddr)) in tcp_mss_update()
3847 mss = maxmtu - min_protoh; in tcp_mss_update()
3849 !in_localaddr(inp->inp_faddr)) in tcp_mss_update()
3854 * XXX - The above conditional (mss = maxmtu - min_protoh) in tcp_mss_update()
3884 tp->t_maxseg = mss; in tcp_mss_update()
3885 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss_update()
3891 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3893 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3911 tcp_mss_update(tp, offer, -1, &metrics, &cap); in tcp_mss()
3913 mss = tp->t_maxseg; in tcp_mss()
3922 so = inp->inp_socket; in tcp_mss()
3924 if ((so->so_snd.sb_hiwat == V_tcp_sendspace) && metrics.hc_sendpipe) in tcp_mss()
3927 bufsize = so->so_snd.sb_hiwat; in tcp_mss()
3934 if (bufsize > so->so_snd.sb_hiwat) in tcp_mss()
3946 tp->t_maxseg = max(mss, 64); in tcp_mss()
3947 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss()
3953 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss()
3955 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss()
3959 if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.hc_recvpipe) in tcp_mss()
3962 bufsize = so->so_rcv.sb_hiwat; in tcp_mss()
3967 if (bufsize > so->so_rcv.sb_hiwat) in tcp_mss()
3974 tp->t_flags |= TF_TSO; in tcp_mss()
3975 tp->t_tsomax = cap.tsomax; in tcp_mss()
3976 tp->t_tsomaxsegcount = cap.tsomaxsegcount; in tcp_mss()
3977 tp->t_tsomaxsegsize = cap.tsomaxsegsize; in tcp_mss()
3979 tp->t_flags2 |= TF2_IPSEC_TSO; in tcp_mss()
3997 if (inc->inc_flags & INC_ISIPV6) { in tcp_mssopt()
4018 mss = min(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4020 mss = max(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4044 (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_prr_ack()
4045 !IN_FASTRECOVERY(tp->t_flags))) { in tcp_do_prr_ack()
4046 del_data = tp->sackhint.delivered_data; in tcp_do_prr_ack()
4049 if (tp->sackhint.prr_delivered < (tcprexmtthresh * maxseg + in tcp_do_prr_ack()
4050 tp->snd_recover - tp->snd_una)) { in tcp_do_prr_ack()
4053 pipe = imax(0, tp->snd_max - tp->snd_una - in tcp_do_prr_ack()
4054 imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); in tcp_do_prr_ack()
4056 tp->sackhint.prr_delivered += del_data; in tcp_do_prr_ack()
4060 if (pipe >= tp->snd_ssthresh) { in tcp_do_prr_ack()
4061 if (tp->sackhint.recover_fs == 0) in tcp_do_prr_ack()
4062 tp->sackhint.recover_fs = in tcp_do_prr_ack()
4063 imax(1, tp->snd_nxt - tp->snd_una); in tcp_do_prr_ack()
4064 snd_cnt = howmany((long)tp->sackhint.prr_delivered * in tcp_do_prr_ack()
4065 tp->snd_ssthresh, tp->sackhint.recover_fs) - in tcp_do_prr_ack()
4066 tp->sackhint.prr_out + maxseg - 1; in tcp_do_prr_ack()
4070 * - A partial ack without SACK block beneath snd_recover in tcp_do_prr_ack()
4072 * - An SACK scoreboard update adding a new hole indicates in tcp_do_prr_ack()
4075 * - Prevent ACK splitting attacks, by being conservative in tcp_do_prr_ack()
4079 limit = tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4080 tp->sackhint.prr_out; in tcp_do_prr_ack()
4082 limit = imax(tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4083 tp->sackhint.prr_out, del_data) + in tcp_do_prr_ack()
4086 snd_cnt = imin((tp->snd_ssthresh - pipe), limit); in tcp_do_prr_ack()
4094 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4096 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4098 tp->snd_cwnd = (tp->snd_max - tp->snd_una) + in tcp_do_prr_ack()
4101 } else if (IN_CONGRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4102 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4104 tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); in tcp_do_prr_ack()
4109 * next unacknowledged segment. Do not clear tp->t_dupacks.
4116 tcp_seq onxt = tp->snd_nxt; in tcp_newreno_partial_ack()
4117 uint32_t ocwnd = tp->snd_cwnd; in tcp_newreno_partial_ack()
4123 tp->t_rtttime = 0; in tcp_newreno_partial_ack()
4124 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_newreno_partial_ack()
4125 tp->snd_nxt = th->th_ack; in tcp_newreno_partial_ack()
4128 * (tp->snd_una has not yet been updated when this function is called.) in tcp_newreno_partial_ack()
4130 tp->snd_cwnd = maxseg + BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4131 tp->t_flags |= TF_ACKNOW; in tcp_newreno_partial_ack()
4133 tp->snd_cwnd = ocwnd; in tcp_newreno_partial_ack()
4134 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_newreno_partial_ack()
4135 tp->snd_nxt = onxt; in tcp_newreno_partial_ack()
4138 * Partial window deflation. Relies on fact that tp->snd_una in tcp_newreno_partial_ack()
4141 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) in tcp_newreno_partial_ack()
4142 tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4144 tp->snd_cwnd = 0; in tcp_newreno_partial_ack()
4145 tp->snd_cwnd += maxseg; in tcp_newreno_partial_ack()
4153 if (tp->t_fb->tfb_compute_pipe != NULL) { in tcp_compute_pipe()
4154 pipe = (*tp->t_fb->tfb_compute_pipe)(tp); in tcp_compute_pipe()
4156 pipe = tp->snd_max - tp->snd_una + in tcp_compute_pipe()
4157 tp->sackhint.sack_bytes_rexmit - in tcp_compute_pipe()
4158 tp->sackhint.sacked_bytes - in tcp_compute_pipe()
4159 tp->sackhint.lost_bytes; in tcp_compute_pipe()
4161 pipe = tp->snd_nxt - tp->snd_fack + tp->sackhint.sack_bytes_rexmit; in tcp_compute_pipe()