Lines Matching +full:ext +full:- +full:push +full:- +full:pull
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.
183 "Slow-start flight size (initial congestion window) in number of segments");
193 "Cap the max cwnd increment during slow-start to this number of segments");
259 return ((tp->t_flags & TF_SACK_PERMIT) && in tcp_is_sack_recovery()
260 ((to->to_flags & TOF_SACK) || in tcp_is_sack_recovery()
261 (!TAILQ_EMPTY(&tp->snd_holes)))); in tcp_is_sack_recovery()
273 if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) { in hhook_run_tcp_est_in()
279 &tp->t_osd); in hhook_run_tcp_est_in()
297 tp->t_ccv.nsegs = nsegs; in cc_ack_received()
298 tp->t_ccv.bytes_this_ack = BYTES_THIS_ACK(tp, th); in cc_ack_received()
299 if ((!V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd)) || in cc_ack_received()
300 (V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd) && in cc_ack_received()
301 (tp->snd_cwnd < (tcp_compute_pipe(tp) * 2)))) in cc_ack_received()
302 tp->t_ccv.flags |= CCF_CWND_LIMITED; in cc_ack_received()
304 tp->t_ccv.flags &= ~CCF_CWND_LIMITED; in cc_ack_received()
308 stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, in cc_ack_received()
309 ((int32_t)tp->snd_cwnd) - tp->snd_wnd); in cc_ack_received()
310 if (!IN_RECOVERY(tp->t_flags)) in cc_ack_received()
311 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_ACKLEN, in cc_ack_received()
312 tp->t_ccv.bytes_this_ack / (tcp_maxseg(tp) * nsegs)); in cc_ack_received()
313 if ((tp->t_flags & TF_GPUTINPROG) && in cc_ack_received()
314 SEQ_GEQ(th->th_ack, tp->gput_ack)) { in cc_ack_received()
318 gput = (((int64_t)SEQ_SUB(th->th_ack, tp->gput_seq)) << 3) / in cc_ack_received()
319 max(1, tcp_ts_getticks() - tp->gput_ts); in cc_ack_received()
320 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, in cc_ack_received()
327 if (tp->t_stats_gput_prev > 0) in cc_ack_received()
328 stats_voi_update_abs_s32(tp->t_stats, in cc_ack_received()
330 ((gput - tp->t_stats_gput_prev) * 100) / in cc_ack_received()
331 tp->t_stats_gput_prev); in cc_ack_received()
332 tp->t_flags &= ~TF_GPUTINPROG; in cc_ack_received()
333 tp->t_stats_gput_prev = gput; in cc_ack_received()
336 if (tp->snd_cwnd > tp->snd_ssthresh) { in cc_ack_received()
337 tp->t_bytes_acked += tp->t_ccv.bytes_this_ack; in cc_ack_received()
338 if (tp->t_bytes_acked >= tp->snd_cwnd) { in cc_ack_received()
339 tp->t_bytes_acked -= tp->snd_cwnd; in cc_ack_received()
340 tp->t_ccv.flags |= CCF_ABC_SENTAWND; in cc_ack_received()
343 tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; in cc_ack_received()
344 tp->t_bytes_acked = 0; in cc_ack_received()
348 if (CC_ALGO(tp)->ack_received != NULL) { in cc_ack_received()
350 tp->t_ccv.curack = th->th_ack; in cc_ack_received()
351 CC_ALGO(tp)->ack_received(&tp->t_ccv, type); in cc_ack_received()
354 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, tp->snd_cwnd); in cc_ack_received()
368 tcp_hc_get(&inp->inp_inc, &metrics); in cc_conn_init()
371 if (tp->t_srtt == 0 && (rtt = metrics.hc_rtt)) { in cc_conn_init()
372 tp->t_srtt = rtt; in cc_conn_init()
375 tp->t_rttvar = metrics.hc_rttvar; in cc_conn_init()
378 /* default variation is +- 1 rtt */ in cc_conn_init()
379 tp->t_rttvar = in cc_conn_init()
380 tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; in cc_conn_init()
382 TCPT_RANGESET(tp->t_rxtcur, in cc_conn_init()
383 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, in cc_conn_init()
384 tp->t_rttmin, TCPTV_REXMTMAX); in cc_conn_init()
393 tp->snd_ssthresh = max(2 * maxseg, metrics.hc_ssthresh); in cc_conn_init()
398 * Set the initial slow-start flight size. in cc_conn_init()
404 if (tp->snd_cwnd == 1) in cc_conn_init()
405 tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ in cc_conn_init()
407 tp->snd_cwnd = tcp_compute_initwnd(maxseg); in cc_conn_init()
409 if (CC_ALGO(tp)->conn_init != NULL) in cc_conn_init()
410 CC_ALGO(tp)->conn_init(&tp->t_ccv); in cc_conn_init()
419 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); in cc_cong_signal()
424 if (!IN_FASTRECOVERY(tp->t_flags)) { in cc_cong_signal()
425 tp->snd_recover = tp->snd_max; in cc_cong_signal()
426 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
427 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
431 if (!IN_CONGRECOVERY(tp->t_flags) || in cc_cong_signal()
436 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in cc_cong_signal()
437 EXIT_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
439 tp->snd_recover = tp->snd_max + 1; in cc_cong_signal()
440 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
441 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
445 tp->t_dupacks = 0; in cc_cong_signal()
446 tp->t_bytes_acked = 0; in cc_cong_signal()
447 EXIT_RECOVERY(tp->t_flags); in cc_cong_signal()
448 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
449 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
454 tp->snd_cwnd = tp->snd_cwnd_prev; in cc_cong_signal()
455 tp->snd_ssthresh = tp->snd_ssthresh_prev; in cc_cong_signal()
456 tp->snd_recover = tp->snd_recover_prev; in cc_cong_signal()
457 if (tp->t_flags & TF_WASFRECOVERY) in cc_cong_signal()
458 ENTER_FASTRECOVERY(tp->t_flags); in cc_cong_signal()
459 if (tp->t_flags & TF_WASCRECOVERY) in cc_cong_signal()
460 ENTER_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
461 tp->snd_nxt = tp->snd_max; in cc_cong_signal()
462 tp->t_flags &= ~TF_PREVVALID; in cc_cong_signal()
463 tp->t_badrxtwin = 0; in cc_cong_signal()
466 if (SEQ_LT(tp->snd_fack, tp->snd_una) || in cc_cong_signal()
467 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_cong_signal()
468 tp->snd_fack = tp->snd_una; in cc_cong_signal()
471 if (CC_ALGO(tp)->cong_signal != NULL) { in cc_cong_signal()
473 tp->t_ccv.curack = th->th_ack; in cc_cong_signal()
474 CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); in cc_cong_signal()
483 if (CC_ALGO(tp)->post_recovery != NULL) { in cc_post_recovery()
484 if (SEQ_LT(tp->snd_fack, th->th_ack) || in cc_post_recovery()
485 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_post_recovery()
486 tp->snd_fack = th->th_ack; in cc_post_recovery()
488 tp->t_ccv.curack = th->th_ack; in cc_post_recovery()
489 CC_ALGO(tp)->post_recovery(&tp->t_ccv); in cc_post_recovery()
491 EXIT_RECOVERY(tp->t_flags); in cc_post_recovery()
493 tp->t_bytes_acked = 0; in cc_post_recovery()
494 tp->sackhint.delivered_data = 0; in cc_post_recovery()
495 tp->sackhint.prr_delivered = 0; in cc_post_recovery()
496 tp->sackhint.prr_out = 0; in cc_post_recovery()
502 * - There is no delayed ack timer in progress.
503 * - Our last ack wasn't a 0-sized window. We never want to delay
504 * the ack that opens up a 0-sized window.
505 * - LRO wasn't used for this segment. We make sure by checking that the
510 (tp->t_flags & TF_RXWIN0SENT) == 0) && \
511 (tlen <= tp->t_maxseg) && \
512 (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
519 if (CC_ALGO(tp)->ecnpkt_handler != NULL) { in cc_ecnpkt_handler_flags()
522 tp->t_ccv.flags |= CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
529 tp->t_ccv.flags &= ~CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
534 tp->t_ccv.flags |= CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
536 tp->t_ccv.flags &= ~CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
538 CC_ALGO(tp)->ecnpkt_handler(&tp->t_ccv); in cc_ecnpkt_handler_flags()
540 if (tp->t_ccv.flags & CCF_ACKNOW) { in cc_ecnpkt_handler_flags()
542 tp->t_flags |= TF_ACKNOW; in cc_ecnpkt_handler_flags()
571 if (m->m_len < *offp + sizeof(struct tcphdr)) { in tcp6_input_with_port()
581 * draft-itojun-ipv6-tcp-to-anycast in tcp6_input_with_port()
585 ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); in tcp6_input_with_port()
586 if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { in tcp6_input_with_port()
588 (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); in tcp6_input_with_port()
640 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; in tcp_input_with_port()
649 m->m_pkthdr.tcp_tun_port = port; in tcp_input_with_port()
654 tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0; in tcp_input_with_port()
657 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { in tcp_input_with_port()
658 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
659 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
661 th->th_sum = in6_cksum_pseudo(ip6, tlen, in tcp_input_with_port()
662 IPPROTO_TCP, m->m_pkthdr.csum_data); in tcp_input_with_port()
663 th->th_sum ^= 0xffff; in tcp_input_with_port()
665 th->th_sum = in6_cksum(m, IPPROTO_TCP, off0, tlen); in tcp_input_with_port()
666 if (th->th_sum) { in tcp_input_with_port()
673 * As we use all-zero to indicate unbounded/unconnected pcb, in tcp_input_with_port()
679 KASSERT(!IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst), in tcp_input_with_port()
681 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { in tcp_input_with_port()
701 if (m->m_len < sizeof (struct tcpiphdr)) { in tcp_input_with_port()
710 tlen = ntohs(ip->ip_len) - off0; in tcp_input_with_port()
712 iptos = ip->ip_tos; in tcp_input_with_port()
715 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { in tcp_input_with_port()
716 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
717 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
719 th->th_sum = in_pseudo(ip->ip_src.s_addr, in tcp_input_with_port()
720 ip->ip_dst.s_addr, in tcp_input_with_port()
721 htonl(m->m_pkthdr.csum_data + tlen + in tcp_input_with_port()
723 th->th_sum ^= 0xffff; 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()
760 * pull out TCP options and adjust length. XXX 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()
809 * Delay dropping TCP, IP headers, IPv6 ext headers, and TCP options. 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()
849 &ip6->ip6_src, th->th_sport, &ip6->ip6_dst, th->th_dport, in tcp_input_with_port()
850 lookupflag & ~INPLOOKUP_WILDCARD, m->m_pkthdr.rcvif, m); in tcp_input_with_port()
855 * any hardware-generated hash is ignored. in tcp_input_with_port()
857 inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
858 th->th_sport, &next_hop6->sin6_addr, in tcp_input_with_port()
859 next_hop6->sin6_port ? ntohs(next_hop6->sin6_port) : in tcp_input_with_port()
860 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
863 inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
864 th->th_sport, &ip6->ip6_dst, th->th_dport, lookupflag, in tcp_input_with_port()
865 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
880 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport, in tcp_input_with_port()
881 ip->ip_dst, th->th_dport, lookupflag & ~INPLOOKUP_WILDCARD, in tcp_input_with_port()
882 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
887 * any hardware-generated hash is ignored. in tcp_input_with_port()
889 inp = in_pcblookup(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
890 th->th_sport, next_hop->sin_addr, in tcp_input_with_port()
891 next_hop->sin_port ? ntohs(next_hop->sin_port) : in tcp_input_with_port()
892 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
895 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
896 th->th_sport, ip->ip_dst, th->th_dport, lookupflag, in tcp_input_with_port()
897 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
926 if ((inp->inp_flowtype == M_HASHTYPE_NONE) && in tcp_input_with_port()
927 !SOLISTENING(inp->inp_socket)) { in tcp_input_with_port()
929 inp->inp_flowid = m->m_pkthdr.flowid; in tcp_input_with_port()
930 inp->inp_flowtype = M_HASHTYPE_GET(m); in tcp_input_with_port()
936 rss_proto_software_hash_v6(&inp->in6p_faddr, in tcp_input_with_port()
937 &inp->in6p_laddr, in tcp_input_with_port()
938 inp->inp_fport, in tcp_input_with_port()
939 inp->inp_lport, in tcp_input_with_port()
941 &inp->inp_flowid, in tcp_input_with_port()
942 &inp->inp_flowtype); in tcp_input_with_port()
946 rss_proto_software_hash_v4(inp->inp_faddr, in tcp_input_with_port()
947 inp->inp_laddr, in tcp_input_with_port()
948 inp->inp_fport, in tcp_input_with_port()
949 inp->inp_lport, in tcp_input_with_port()
951 &inp->inp_flowid, in tcp_input_with_port()
952 &inp->inp_flowtype); in tcp_input_with_port()
978 if (inp->inp_ip_minttl != 0) { in tcp_input_with_port()
981 if (inp->inp_ip_minttl > ip6->ip6_hlim) in tcp_input_with_port()
985 if (inp->inp_ip_minttl > ip->ip_ttl) in tcp_input_with_port()
990 switch (tp->t_state) { in tcp_input_with_port()
1016 if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { in tcp_input_with_port()
1022 if (tp->t_flags & TF_TOE) { in tcp_input_with_port()
1033 so = inp->inp_socket; in tcp_input_with_port()
1040 KASSERT(tp->t_state == TCPS_LISTEN || !SOLISTENING(so), in tcp_input_with_port()
1042 if (tp->t_state == TCPS_LISTEN && SOLISTENING(so)) { in tcp_input_with_port()
1049 if (inp->inp_inc.inc_flags & INC_IPV6MINMTU) in tcp_input_with_port()
1051 inc.inc6_faddr = ip6->ip6_src; in tcp_input_with_port()
1052 inc.inc6_laddr = ip6->ip6_dst; in tcp_input_with_port()
1056 inc.inc_faddr = ip->ip_src; in tcp_input_with_port()
1057 inc.inc_laddr = ip->ip_dst; in tcp_input_with_port()
1059 inc.inc_fport = th->th_sport; in tcp_input_with_port()
1060 inc.inc_lport = th->th_dport; in tcp_input_with_port()
1061 inc.inc_fibnum = so->so_fibnum; in tcp_input_with_port()
1113 * We completed the 3-way handshake in tcp_input_with_port()
1140 * then listening socket is read-locked. in tcp_input_with_port()
1150 KASSERT(tp->t_state == TCPS_SYN_RECEIVED, in tcp_input_with_port()
1158 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()
1284 * global or subnet broad- or multicast address. in tcp_input_with_port()
1286 * link-layer packets with a broadcast IP address. Use in tcp_input_with_port()
1289 if (m->m_flags & (M_BCAST|M_MCAST)) { in tcp_input_with_port()
1292 "Connection attempt from broad- or multicast " in tcp_input_with_port()
1298 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1299 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &ip6->ip6_src)) { in tcp_input_with_port()
1306 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_input_with_port()
1307 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { in tcp_input_with_port()
1321 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1322 ip->ip_dst.s_addr == ip->ip_src.s_addr) { in tcp_input_with_port()
1329 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_input_with_port()
1330 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_input_with_port()
1331 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_input_with_port()
1332 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { in tcp_input_with_port()
1335 "Connection attempt from/to broad- " in tcp_input_with_port()
1357 } else if (tp->t_state == TCPS_LISTEN) { in tcp_input_with_port()
1368 if (tp->t_flags & TF_SIGNATURE) { in tcp_input_with_port()
1390 * write-lock on PCB. If upgrade fails, drop the SYN. in tcp_input_with_port()
1395 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, tlen, iptos); in tcp_input_with_port()
1408 isipv6 ? !in6_localaddr(&ip6->ip6_src) : in tcp_input_with_port()
1411 !in_localip(ip->ip_src) in tcp_input_with_port()
1441 * bandwidth and high delay (eg. trans-continental/oceanic links).
1463 * of slow-start but also makes it so our peer never gets limited
1480 if (V_tcp_do_autorcvbuf && (so->so_rcv.sb_flags & SB_AUTOSIZE) && in tcp_autorcvbuf()
1481 tp->t_srtt != 0 && tp->rfbuf_ts != 0 && in tcp_autorcvbuf()
1482 TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > in tcp_autorcvbuf()
1483 ((tp->t_srtt >> TCP_RTT_SHIFT)/2)) { in tcp_autorcvbuf()
1484 if (tp->rfbuf_cnt > ((so->so_rcv.sb_hiwat / 2)/ 4 * 3) && in tcp_autorcvbuf()
1485 so->so_rcv.sb_hiwat < V_tcp_autorcvbuf_max) { in tcp_autorcvbuf()
1486 newsize = min((so->so_rcv.sb_hiwat + (so->so_rcv.sb_hiwat/2)), V_tcp_autorcvbuf_max); in tcp_autorcvbuf()
1491 tp->rfbuf_ts = 0; in tcp_autorcvbuf()
1492 tp->rfbuf_cnt = 0; in tcp_autorcvbuf()
1494 tp->rfbuf_cnt += tlen; /* add up */ in tcp_autorcvbuf()
1511 if (tp->t_flags & TF_WAKESOR) { in tcp_handle_wakeup()
1514 tp->t_flags &= ~TF_WAKESOR; in tcp_handle_wakeup()
1533 struct in_conninfo *inc = &inp->inp_inc; in tcp_do_segment()
1540 tp->sackhint.last_sack_ack = 0; in tcp_do_segment()
1542 nsegs = max(1, m->m_pkthdr.lro_nsegs); in tcp_do_segment()
1546 KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", in tcp_do_segment()
1548 KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", in tcp_do_segment()
1553 tcp_pcap_add(th, m, &(tp->t_inpkts)); in tcp_do_segment()
1555 TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, in tcp_do_segment()
1569 * If a segment with the ACK-bit set arrives in the SYN-SENT state in tcp_do_segment()
1572 if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && in tcp_do_segment()
1573 (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1581 * Reset idle time and keep-alive timer. in tcp_do_segment()
1585 if (tp->t_idle_reduce && in tcp_do_segment()
1586 (tp->snd_max == tp->snd_una) && in tcp_do_segment()
1587 ((ticks - tp->t_rcvtime) >= tp->t_rxtcur)) in tcp_do_segment()
1589 tp->t_rcvtime = ticks; in tcp_do_segment()
1594 * Scale up the window into a 32-bit value. in tcp_do_segment()
1597 tiwin = th->th_win << tp->snd_scale; in tcp_do_segment()
1599 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); in tcp_do_segment()
1606 tcp_packets_this_ack(tp, th->th_ack), in tcp_do_segment()
1614 (th->th_off << 2) - sizeof(struct tcphdr), in tcp_do_segment()
1616 if (tp->t_flags2 & TF2_PROC_SACK_PROHIBIT) { in tcp_do_segment()
1625 if ((tp->t_flags & TF_SIGNATURE) != 0 && in tcp_do_segment()
1638 to.to_tsecr -= tp->ts_offset; in tcp_do_segment()
1641 } else if (tp->t_rxtshift == 1 && in tcp_do_segment()
1642 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1643 tp->t_badrxtwin != 0 && in tcp_do_segment()
1644 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) { in tcp_do_segment()
1655 if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { in tcp_do_segment()
1659 (tp->t_flags & TF_REQ_SCALE) && in tcp_do_segment()
1660 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1661 tp->t_flags |= TF_RCVD_SCALE; in tcp_do_segment()
1662 tp->snd_scale = to.to_wscale; in tcp_do_segment()
1664 tp->t_flags &= ~TF_REQ_SCALE; in tcp_do_segment()
1670 tp->snd_wnd = th->th_win; in tcp_do_segment()
1672 (tp->t_flags & TF_REQ_TSTMP) && in tcp_do_segment()
1673 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1674 tp->t_flags |= TF_RCVD_TSTMP; in tcp_do_segment()
1675 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1676 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1678 tp->t_flags &= ~TF_REQ_TSTMP; in tcp_do_segment()
1683 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
1685 (tp->t_flags & TF_NOOPT))) { in tcp_do_segment()
1686 tp->t_flags &= ~TF_SACK_PERMIT; in tcp_do_segment()
1688 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1690 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1696 if ((inp->inp_vflag & INP_IPV6) != 0) { in tcp_do_segment()
1717 if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { in tcp_do_segment()
1740 if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) { in tcp_do_segment()
1750 * of a uni-directional data xfer. If the packet has in tcp_do_segment()
1751 * no control flags, is in-sequence, the window didn't in tcp_do_segment()
1757 * is non-zero and the ack didn't move, we're the in tcp_do_segment()
1758 * receiver side. If we're getting packets in-order in tcp_do_segment()
1761 * Make sure that the hidden state-flags are also off. in tcp_do_segment()
1765 if (tp->t_state == TCPS_ESTABLISHED && in tcp_do_segment()
1766 th->th_seq == tp->rcv_nxt && in tcp_do_segment()
1768 tp->snd_nxt == tp->snd_max && in tcp_do_segment()
1769 tiwin && tiwin == tp->snd_wnd && in tcp_do_segment()
1770 ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && in tcp_do_segment()
1773 TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { in tcp_do_segment()
1781 SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { in tcp_do_segment()
1782 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1783 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1787 if (SEQ_GT(th->th_ack, tp->snd_una) && in tcp_do_segment()
1788 SEQ_LEQ(th->th_ack, tp->snd_max) && in tcp_do_segment()
1789 !IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
1791 TAILQ_EMPTY(&tp->snd_holes)) { in tcp_do_segment()
1801 tp->t_rxtshift == 1 && in tcp_do_segment()
1802 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1803 tp->t_badrxtwin != 0 && in tcp_do_segment()
1804 TSTMP_LT(ticks, tp->t_badrxtwin)) { in tcp_do_segment()
1820 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
1821 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
1822 tp->t_rttlow = t; in tcp_do_segment()
1825 } else if (tp->t_rtttime && in tcp_do_segment()
1826 SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
1827 if (!tp->t_rttlow || in tcp_do_segment()
1828 tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
1829 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
1831 ticks - tp->t_rtttime); in tcp_do_segment()
1842 sbdrop(&so->so_snd, acked); in tcp_do_segment()
1843 if (SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
1844 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
1845 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
1855 tp->snd_una = th->th_ack; in tcp_do_segment()
1857 * Pull snd_wl2 up to prevent seq wrap relative in tcp_do_segment()
1860 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
1861 tp->t_dupacks = 0; in tcp_do_segment()
1867 * using current (possibly backed-off) value. in tcp_do_segment()
1880 if (sbavail(&so->so_snd) == 0) in tcp_do_segment()
1881 tp->t_acktime = 0; in tcp_do_segment()
1883 tp->t_acktime = ticks; in tcp_do_segment()
1884 if (tp->snd_una == tp->snd_max) in tcp_do_segment()
1895 if ((tp->t_flags & TF_ACKNOW) || in tcp_do_segment()
1896 (sbavail(&so->so_snd) >= in tcp_do_segment()
1897 SEQ_SUB(tp->snd_max, tp->snd_una))) { in tcp_do_segment()
1902 } else if (th->th_ack == tp->snd_una && in tcp_do_segment()
1903 tlen <= sbspace(&so->so_rcv)) { in tcp_do_segment()
1907 * This is a pure, in-sequence data packet with in tcp_do_segment()
1912 if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks) in tcp_do_segment()
1915 tp->rcv_nxt += tlen; in tcp_do_segment()
1917 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
1918 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
1919 tp->t_fbyte_in = ticks; in tcp_do_segment()
1920 if (tp->t_fbyte_in == 0) in tcp_do_segment()
1921 tp->t_fbyte_in = 1; in tcp_do_segment()
1922 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
1923 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
1926 * Pull snd_wl1 up to prevent seq wrap relative to in tcp_do_segment()
1929 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
1931 * Pull rcv_up up to prevent seq wrap relative to in tcp_do_segment()
1934 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
1943 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
1953 so->so_rcv.sb_flags &= ~SB_AUTOSIZE; in tcp_do_segment()
1955 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
1960 tp->t_flags |= TF_DELACK; in tcp_do_segment()
1962 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
1975 win = sbspace(&so->so_rcv); in tcp_do_segment()
1978 tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); in tcp_do_segment()
1980 switch (tp->t_state) { in tcp_do_segment()
1991 (SEQ_LEQ(th->th_ack, tp->snd_una) || in tcp_do_segment()
1992 SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1997 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
2010 /* non-initial SYN is ignored */ in tcp_do_segment()
2027 * initialize tp->rcv_nxt and tp->irs in tcp_do_segment()
2028 * if seg contains ack then advance tp->snd_una in tcp_do_segment()
2047 tp->irs = th->th_seq; in tcp_do_segment()
2058 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2060 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2062 tp->rcv_adv += min(tp->rcv_wnd, in tcp_do_segment()
2063 TCP_MAXWIN << tp->rcv_scale); in tcp_do_segment()
2064 tp->snd_una++; /* SYN is acked */ in tcp_do_segment()
2065 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
2066 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
2071 if ((tp->t_flags & TF_FASTOPEN) && in tcp_do_segment()
2072 (tp->snd_una != tp->snd_max)) { in tcp_do_segment()
2073 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2084 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2091 * SYN_SENT --> ESTABLISHED in tcp_do_segment()
2092 * SYN_SENT* --> FIN_WAIT_1 in tcp_do_segment()
2094 tp->t_starttime = ticks; in tcp_do_segment()
2095 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2096 tp->t_acktime = ticks; in tcp_do_segment()
2098 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2110 * Received initial SYN in SYN-SENT[*] state => in tcp_do_segment()
2112 * If it succeeds, connection is * half-synchronized. in tcp_do_segment()
2113 * Otherwise, do 3-way handshake: in tcp_do_segment()
2114 * SYN-SENT -> SYN-RECEIVED in tcp_do_segment()
2115 * SYN-SENT* -> SYN-RECEIVED* in tcp_do_segment()
2117 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); in tcp_do_segment()
2123 * Advance th->th_seq to correspond to first data byte. in tcp_do_segment()
2127 th->th_seq++; in tcp_do_segment()
2128 if (tlen > tp->rcv_wnd) { in tcp_do_segment()
2129 todrop = tlen - tp->rcv_wnd; in tcp_do_segment()
2130 m_adj(m, -todrop); in tcp_do_segment()
2131 tlen = tp->rcv_wnd; in tcp_do_segment()
2136 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2137 tp->rcv_up = th->th_seq; in tcp_do_segment()
2170 * - RST drops connection only if SEG.SEQ == RCV.NXT. in tcp_do_segment()
2171 * - If RST is in window, we send challenge ACK. in tcp_do_segment()
2178 if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2179 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || in tcp_do_segment()
2180 (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { in tcp_do_segment()
2181 KASSERT(tp->t_state != TCPS_SYN_SENT, in tcp_do_segment()
2186 tp->last_ack_sent == th->th_seq) { in tcp_do_segment()
2189 switch (tp->t_state) { in tcp_do_segment()
2191 so->so_error = ECONNREFUSED; in tcp_do_segment()
2199 so->so_error = ECONNRESET; in tcp_do_segment()
2219 if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT && in tcp_do_segment()
2220 tp->t_state != TCPS_SYN_RECEIVED) { in tcp_do_segment()
2223 SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2224 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { in tcp_do_segment()
2240 if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && in tcp_do_segment()
2241 TSTMP_LT(to.to_tsval, tp->ts_recent)) { in tcp_do_segment()
2243 if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { in tcp_do_segment()
2252 * because we don't want out-of-order segments to be in tcp_do_segment()
2255 tp->ts_recent = 0; in tcp_do_segment()
2267 * In the SYN-RECEIVED state, validate that the packet belongs to in tcp_do_segment()
2273 if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { in tcp_do_segment()
2279 todrop = tp->rcv_nxt - th->th_seq; in tcp_do_segment()
2283 th->th_seq++; in tcp_do_segment()
2284 if (th->th_urp > 1) in tcp_do_segment()
2285 th->th_urp--; in tcp_do_segment()
2288 todrop--; in tcp_do_segment()
2306 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2315 * DSACK - add SACK block for dropped range in tcp_do_segment()
2317 if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2318 tcp_update_sack_list(tp, th->th_seq, in tcp_do_segment()
2319 th->th_seq + todrop); in tcp_do_segment()
2321 * ACK now, as the next in-sequence segment in tcp_do_segment()
2324 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2327 th->th_seq += todrop; in tcp_do_segment()
2328 tlen -= todrop; in tcp_do_segment()
2329 if (th->th_urp > todrop) in tcp_do_segment()
2330 th->th_urp -= todrop; in tcp_do_segment()
2333 th->th_urp = 0; in tcp_do_segment()
2342 if ((tp->t_flags & TF_CLOSED) && tlen > 0 && in tcp_do_segment()
2343 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
2348 s, __func__, tcpstates[tp->t_state], tlen); in tcp_do_segment()
2352 /* tcp_close will kill the inp pre-log the Reset */ in tcp_do_segment()
2362 * (and PUSH and FIN); if nothing left, just ACK. in tcp_do_segment()
2364 todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); in tcp_do_segment()
2371 * window edge, and have to drop data and PUSH from in tcp_do_segment()
2376 if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { in tcp_do_segment()
2377 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2383 m_adj(m, -todrop); in tcp_do_segment()
2384 tlen -= todrop; in tcp_do_segment()
2407 SEQ_LEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2408 SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + in tcp_do_segment()
2410 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
2411 tp->ts_recent = to.to_tsval; in tcp_do_segment()
2415 * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN in tcp_do_segment()
2416 * flag is on (half-synchronized state), then queue data for in tcp_do_segment()
2420 if (tp->t_state == TCPS_SYN_RECEIVED || in tcp_do_segment()
2421 (tp->t_flags & TF_NEEDSYN)) { in tcp_do_segment()
2422 if (tp->t_state == TCPS_SYN_RECEIVED && in tcp_do_segment()
2423 (tp->t_flags & TF_FASTOPEN)) { in tcp_do_segment()
2424 tp->snd_wnd = tiwin; in tcp_do_segment()
2428 } else if (tp->t_flags & TF_ACKNOW) in tcp_do_segment()
2437 if (SEQ_GEQ(tp->snd_una, tp->iss + (TCP_MAXWIN << tp->snd_scale))) { in tcp_do_segment()
2439 tp->t_flags2 |= TF2_NO_ISS_CHECK; in tcp_do_segment()
2445 if (tp->t_flags2 & TF2_NO_ISS_CHECK) { in tcp_do_segment()
2447 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2450 if (SEQ_GT(tp->iss + 1, tp->snd_una - tp->max_sndwnd)) { in tcp_do_segment()
2452 seq_min = tp->iss + 1; in tcp_do_segment()
2459 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2463 if (SEQ_LT(th->th_ack, seq_min)) { in tcp_do_segment()
2473 switch (tp->t_state) { in tcp_do_segment()
2482 if (tp->t_flags & TF_SONOTCONN) { in tcp_do_segment()
2492 tp->t_flags &= ~TF_SONOTCONN; in tcp_do_segment()
2496 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2498 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2500 tp->snd_wnd = tiwin; in tcp_do_segment()
2503 * SYN-RECEIVED -> ESTABLISHED in tcp_do_segment()
2504 * SYN-RECEIVED* -> FIN-WAIT-1 in tcp_do_segment()
2506 tp->t_starttime = ticks; in tcp_do_segment()
2507 if ((tp->t_flags & TF_FASTOPEN) && tp->t_tfo_pending) { in tcp_do_segment()
2508 tcp_fastopen_decrement_counter(tp->t_tfo_pending); in tcp_do_segment()
2509 tp->t_tfo_pending = NULL; in tcp_do_segment()
2511 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2512 tp->t_acktime = ticks; in tcp_do_segment()
2514 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2526 if (!(tp->t_flags & TF_FASTOPEN)) in tcp_do_segment()
2535 if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) in tcp_do_segment()
2546 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2552 * tp->snd_una < th->th_ack <= tp->snd_max in tcp_do_segment()
2553 * then advance tp->snd_una to th->th_ack and drop in tcp_do_segment()
2563 if (SEQ_GT(th->th_ack, tp->snd_max)) { in tcp_do_segment()
2568 sack_changed = tcp_sack_doack(tp, &to, th->th_ack); in tcp_do_segment()
2570 (tp->t_flags & TF_LRD)) { in tcp_do_segment()
2578 tp->sackhint.sacked_bytes = 0; in tcp_do_segment()
2585 if (SEQ_LEQ(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2588 (tiwin == tp->snd_wnd || in tcp_do_segment()
2589 (tp->t_flags & TF_SACK_PERMIT))) { in tcp_do_segment()
2598 (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { in tcp_do_segment()
2599 tp->t_dupacks = 0; in tcp_do_segment()
2619 * and pull our congestion window back to in tcp_do_segment()
2640 if (th->th_ack != tp->snd_una || in tcp_do_segment()
2645 tp->t_dupacks = 0; in tcp_do_segment()
2646 } else if (++tp->t_dupacks > tcprexmtthresh || in tcp_do_segment()
2647 IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2651 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2652 (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2656 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2657 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2669 awnd = (tp->snd_nxt - tp->snd_fack) + in tcp_do_segment()
2670 tp->sackhint.sack_bytes_rexmit; in tcp_do_segment()
2672 if (awnd < tp->snd_ssthresh) { in tcp_do_segment()
2673 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2675 tp->sackhint.delivered_data)); in tcp_do_segment()
2676 if (tp->snd_cwnd > tp->snd_ssthresh) in tcp_do_segment()
2677 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2680 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2681 SEQ_LT(tp->snd_nxt, tp->snd_max)) { in tcp_do_segment()
2682 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2684 tp->sackhint.delivered_data)); in tcp_do_segment()
2686 tp->snd_cwnd += maxseg; in tcp_do_segment()
2690 } else if (tp->t_dupacks == tcprexmtthresh || in tcp_do_segment()
2691 (tp->t_flags & TF_SACK_PERMIT && in tcp_do_segment()
2693 tp->sackhint.sacked_bytes > in tcp_do_segment()
2694 (tcprexmtthresh - 1) * maxseg)) { in tcp_do_segment()
2698 * more than (dupthresh-1)*maxseg sacked data. in tcp_do_segment()
2704 tp->t_dupacks = tcprexmtthresh; in tcp_do_segment()
2705 tcp_seq onxt = tp->snd_nxt; in tcp_do_segment()
2715 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2716 tp->t_dupacks = 0; in tcp_do_segment()
2720 if (SEQ_LEQ(th->th_ack, in tcp_do_segment()
2721 tp->snd_recover)) { in tcp_do_segment()
2722 tp->t_dupacks = 0; in tcp_do_segment()
2731 tp->t_rtttime = 0; in tcp_do_segment()
2742 tp->sackhint.prr_delivered = in tcp_do_segment()
2743 imin(tp->snd_max - th->th_ack, in tcp_do_segment()
2744 (tp->snd_limited + 1) * maxseg); in tcp_do_segment()
2746 tp->sackhint.prr_delivered = in tcp_do_segment()
2749 tp->sackhint.recover_fs = max(1, in tcp_do_segment()
2750 tp->snd_nxt - tp->snd_una); in tcp_do_segment()
2752 tp->snd_limited = 0; in tcp_do_segment()
2762 tp->snd_nxt = tp->snd_max; in tcp_do_segment()
2763 tp->snd_cwnd = tcp_compute_pipe(tp) + in tcp_do_segment()
2767 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2768 if (SEQ_GT(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2773 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2774 tp->snd_cwnd = maxseg; in tcp_do_segment()
2776 KASSERT(tp->snd_limited <= 2, in tcp_do_segment()
2777 ("%s: tp->snd_limited too big", in tcp_do_segment()
2779 tp->snd_cwnd = tp->snd_ssthresh + in tcp_do_segment()
2781 (tp->t_dupacks - tp->snd_limited); in tcp_do_segment()
2782 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_do_segment()
2783 tp->snd_nxt = onxt; in tcp_do_segment()
2797 uint32_t oldcwnd = tp->snd_cwnd; in tcp_do_segment()
2798 tcp_seq oldsndmax = tp->snd_max; in tcp_do_segment()
2802 KASSERT(tp->t_dupacks == 1 || in tcp_do_segment()
2803 tp->t_dupacks == 2, in tcp_do_segment()
2806 if (tp->t_dupacks == 1) in tcp_do_segment()
2807 tp->snd_limited = 0; in tcp_do_segment()
2808 if ((tp->snd_nxt == tp->snd_max) && in tcp_do_segment()
2809 (tp->t_rxtshift == 0)) in tcp_do_segment()
2810 tp->snd_cwnd = in tcp_do_segment()
2811 SEQ_SUB(tp->snd_nxt, in tcp_do_segment()
2812 tp->snd_una) - in tcp_do_segment()
2814 tp->snd_cwnd += in tcp_do_segment()
2815 (tp->t_dupacks - tp->snd_limited) * in tcp_do_segment()
2816 maxseg - tcp_sack_adjust(tp); in tcp_do_segment()
2823 avail = sbavail(&so->so_snd); in tcp_do_segment()
2825 if (tp->t_flags & TF_ACKNOW || in tcp_do_segment()
2827 SEQ_SUB(tp->snd_nxt, tp->snd_una))) { in tcp_do_segment()
2830 sent = SEQ_SUB(tp->snd_max, oldsndmax); in tcp_do_segment()
2832 KASSERT((tp->t_dupacks == 2 && in tcp_do_segment()
2833 tp->snd_limited == 0) || in tcp_do_segment()
2835 tp->t_flags & TF_SENTFIN), in tcp_do_segment()
2838 tp->snd_limited = 2; in tcp_do_segment()
2840 ++tp->snd_limited; in tcp_do_segment()
2842 tp->snd_cwnd = oldcwnd; in tcp_do_segment()
2852 tp->t_dupacks = 0; in tcp_do_segment()
2863 (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || in tcp_do_segment()
2864 ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && in tcp_do_segment()
2865 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2866 tp->t_dupacks++; in tcp_do_segment()
2868 if (!IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2869 (tp->sackhint.sacked_bytes > in tcp_do_segment()
2870 ((tcprexmtthresh - 1) * in tcp_do_segment()
2878 KASSERT(SEQ_GT(th->th_ack, tp->snd_una), in tcp_do_segment()
2885 if (SEQ_LT(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
2886 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2887 if (tp->t_flags & TF_SACK_PERMIT) { in tcp_do_segment()
2892 tp->t_rtttime = 0; in tcp_do_segment()
2895 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2904 } else if (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_segment()
2906 tp->sackhint.delivered_data = in tcp_do_segment()
2908 tp->snd_fack = th->th_ack; in tcp_do_segment()
2911 * always use PRR-SSRB in tcp_do_segment()
2922 if (tp->t_flags & TF_NEEDSYN) { in tcp_do_segment()
2924 * T/TCP: Connection was half-synchronized, and our in tcp_do_segment()
2926 * synchronized). Go to non-starred state, in tcp_do_segment()
2930 tp->t_flags &= ~TF_NEEDSYN; in tcp_do_segment()
2931 tp->snd_una++; in tcp_do_segment()
2933 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2935 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2946 * This is for the SYN_RECEIVED, non-simultaneous in tcp_do_segment()
2951 tp->snd_una++; in tcp_do_segment()
2954 "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__, in tcp_do_segment()
2955 tp->snd_una, th->th_ack, tp, m)); in tcp_do_segment()
2966 if (tp->t_rxtshift == 1 && in tcp_do_segment()
2967 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
2968 tp->t_badrxtwin != 0 && in tcp_do_segment()
2971 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) in tcp_do_segment()
2991 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
2992 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
2993 tp->t_rttlow = t; in tcp_do_segment()
2995 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
2996 if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
2997 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
2998 tcp_xmit_timer(tp, ticks - tp->t_rtttime); in tcp_do_segment()
3008 if ((tp->t_state <= TCPS_CLOSE_WAIT && in tcp_do_segment()
3009 acked == sbavail(&so->so_snd)) || in tcp_do_segment()
3010 acked > sbavail(&so->so_snd)) in tcp_do_segment()
3011 tp->t_acktime = 0; in tcp_do_segment()
3013 tp->t_acktime = ticks; in tcp_do_segment()
3019 * timer, using current (possibly backed-off) value. in tcp_do_segment()
3021 if (th->th_ack == tp->snd_max) { in tcp_do_segment()
3043 if (acked > sbavail(&so->so_snd)) { in tcp_do_segment()
3044 if (tp->snd_wnd >= sbavail(&so->so_snd)) in tcp_do_segment()
3045 tp->snd_wnd -= sbavail(&so->so_snd); in tcp_do_segment()
3047 tp->snd_wnd = 0; in tcp_do_segment()
3048 mfree = sbcut_locked(&so->so_snd, in tcp_do_segment()
3049 (int)sbavail(&so->so_snd)); in tcp_do_segment()
3052 mfree = sbcut_locked(&so->so_snd, acked); in tcp_do_segment()
3053 if (tp->snd_wnd >= (uint32_t) acked) in tcp_do_segment()
3054 tp->snd_wnd -= acked; in tcp_do_segment()
3056 tp->snd_wnd = 0; in tcp_do_segment()
3063 if (!IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3064 SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
3065 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
3066 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
3067 tp->snd_una = th->th_ack; in tcp_do_segment()
3068 if (IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3069 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
3072 if (SEQ_GT(tp->snd_una, tp->snd_recover)) { in tcp_do_segment()
3073 tp->snd_recover = tp->snd_una; in tcp_do_segment()
3075 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
3076 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
3078 switch (tp->t_state) { in tcp_do_segment()
3093 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
3108 * then enter the TIME-WAIT state, otherwise ignore in tcp_do_segment()
3142 (SEQ_LT(tp->snd_wl1, th->th_seq) || in tcp_do_segment()
3143 (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || in tcp_do_segment()
3144 (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { in tcp_do_segment()
3147 tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) in tcp_do_segment()
3149 tp->snd_wnd = tiwin; in tcp_do_segment()
3150 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
3151 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
3152 if (tp->snd_wnd > tp->max_sndwnd) in tcp_do_segment()
3153 tp->max_sndwnd = tp->snd_wnd; in tcp_do_segment()
3160 if ((thflags & TH_URG) && th->th_urp && in tcp_do_segment()
3161 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3169 if (th->th_urp + sbavail(&so->so_rcv) > sb_max) { in tcp_do_segment()
3170 th->th_urp = 0; /* XXX */ in tcp_do_segment()
3189 if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { in tcp_do_segment()
3190 tp->rcv_up = th->th_seq + th->th_urp; in tcp_do_segment()
3191 so->so_oobmark = sbavail(&so->so_rcv) + in tcp_do_segment()
3192 (tp->rcv_up - tp->rcv_nxt) - 1; in tcp_do_segment()
3193 if (so->so_oobmark == 0) in tcp_do_segment()
3194 so->so_rcv.sb_state |= SBS_RCVATMARK; in tcp_do_segment()
3196 tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); in tcp_do_segment()
3202 * but if two URG's are pending at once, some out-of-band in tcp_do_segment()
3205 if (th->th_urp <= (uint32_t)tlen && in tcp_do_segment()
3206 !(so->so_options & SO_OOBINLINE)) { in tcp_do_segment()
3213 * pull receive urgent pointer along in tcp_do_segment()
3216 if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) in tcp_do_segment()
3217 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
3225 * This process logically involves adjusting tp->rcv_wnd as data in tcp_do_segment()
3230 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && in tcp_do_segment()
3231 (tp->t_flags & TF_FASTOPEN)); in tcp_do_segment()
3233 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3234 tcp_seq save_start = th->th_seq; in tcp_do_segment()
3235 tcp_seq save_rnxt = tp->rcv_nxt; in tcp_do_segment()
3250 if (th->th_seq == tp->rcv_nxt && in tcp_do_segment()
3252 (TCPS_HAVEESTABLISHED(tp->t_state) || in tcp_do_segment()
3255 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3257 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3258 tp->rcv_nxt += tlen; in tcp_do_segment()
3260 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
3261 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
3262 tp->t_fbyte_in = ticks; in tcp_do_segment()
3263 if (tp->t_fbyte_in == 0) in tcp_do_segment()
3264 tp->t_fbyte_in = 1; in tcp_do_segment()
3265 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
3266 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
3272 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) in tcp_do_segment()
3275 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
3276 tp->t_flags |= TF_WAKESOR; in tcp_do_segment()
3287 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3289 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
3291 TCPS_HAVEESTABLISHED(tp->t_state)) { in tcp_do_segment()
3299 } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { in tcp_do_segment()
3300 if ((tp->rcv_numsacks >= 1) && in tcp_do_segment()
3301 (tp->sackblks[0].end == save_start)) { in tcp_do_segment()
3307 tp->sackblks[0].start, in tcp_do_segment()
3308 tp->sackblks[0].end); in tcp_do_segment()
3330 if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) in tcp_do_segment()
3331 len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); in tcp_do_segment()
3333 len = so->so_rcv.sb_hiwat; in tcp_do_segment()
3344 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3351 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3360 tcpstates[tp->t_state]); in tcp_do_segment()
3374 if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3378 * If connection is half-synchronized in tcp_do_segment()
3384 if (tp->t_flags & TF_NEEDSYN) in tcp_do_segment()
3385 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3387 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3388 tp->rcv_nxt++; in tcp_do_segment()
3390 switch (tp->t_state) { in tcp_do_segment()
3396 tp->t_starttime = ticks; in tcp_do_segment()
3412 * starting the time-wait timer, turning off the other in tcp_do_segment()
3425 if (needoutput || (tp->t_flags & TF_ACKNOW)) { in tcp_do_segment()
3431 if (tp->t_flags & TF_DELACK) { in tcp_do_segment()
3432 tp->t_flags &= ~TF_DELACK; in tcp_do_segment()
3447 * In the SYN-RECEIVED state, don't send an ACK unless the in tcp_do_segment()
3448 * segment we received passes the SYN-RECEIVED ACK test. in tcp_do_segment()
3454 if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && in tcp_do_segment()
3455 (SEQ_GT(tp->snd_una, th->th_ack) || in tcp_do_segment()
3456 SEQ_GT(th->th_ack, tp->snd_max)) ) { in tcp_do_segment()
3462 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3508 if ((tcp_get_flags(th) & TH_RST) || m->m_flags & (M_BCAST|M_MCAST)) in tcp_dropwithreset()
3511 if (mtod(m, struct ip *)->ip_v == 6) { in tcp_dropwithreset()
3513 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_dropwithreset()
3514 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) in tcp_dropwithreset()
3525 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_dropwithreset()
3526 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_dropwithreset()
3527 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_dropwithreset()
3528 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) in tcp_dropwithreset()
3540 th->th_ack, TH_RST); in tcp_dropwithreset()
3546 tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, in tcp_dropwithreset()
3562 to->to_flags = 0; in tcp_dooptions()
3563 for (; cnt > 0; cnt -= optlen, cp += optlen) { in tcp_dooptions()
3582 to->to_flags |= TOF_MSS; in tcp_dooptions()
3584 (char *)&to->to_mss, sizeof(to->to_mss)); in tcp_dooptions()
3585 to->to_mss = ntohs(to->to_mss); in tcp_dooptions()
3592 to->to_flags |= TOF_SCALE; in tcp_dooptions()
3593 to->to_wscale = min(cp[2], TCP_MAX_WINSHIFT); in tcp_dooptions()
3598 to->to_flags |= TOF_TS; in tcp_dooptions()
3600 (char *)&to->to_tsval, sizeof(to->to_tsval)); in tcp_dooptions()
3601 to->to_tsval = ntohl(to->to_tsval); in tcp_dooptions()
3603 (char *)&to->to_tsecr, sizeof(to->to_tsecr)); in tcp_dooptions()
3604 to->to_tsecr = ntohl(to->to_tsecr); in tcp_dooptions()
3616 to->to_flags |= TOF_SIGNATURE; in tcp_dooptions()
3617 to->to_signature = cp + 2; in tcp_dooptions()
3626 to->to_flags |= TOF_SACKPERM; in tcp_dooptions()
3629 if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) in tcp_dooptions()
3633 to->to_flags |= TOF_SACK; in tcp_dooptions()
3634 to->to_nsacks = (optlen - 2) / TCPOLEN_SACK; in tcp_dooptions()
3635 to->to_sacks = cp + 2; in tcp_dooptions()
3649 to->to_flags |= TOF_FASTOPEN; in tcp_dooptions()
3650 to->to_tfo_len = optlen - 2; in tcp_dooptions()
3651 to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL; in tcp_dooptions()
3660 * Pull out of band byte out of a segment so
3669 int cnt = off + th->th_urp - 1; in tcp_pulloutofband()
3672 if (m->m_len > cnt) { in tcp_pulloutofband()
3678 tp->t_iobc = *cp; in tcp_pulloutofband()
3679 tp->t_oobflags |= TCPOOB_HAVEDATA; in tcp_pulloutofband()
3680 bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); in tcp_pulloutofband()
3681 m->m_len--; in tcp_pulloutofband()
3682 if (m->m_flags & M_PKTHDR) in tcp_pulloutofband()
3683 m->m_pkthdr.len--; in tcp_pulloutofband()
3686 cnt -= m->m_len; in tcp_pulloutofband()
3687 m = m->m_next; in tcp_pulloutofband()
3695 * Collect new round-trip time estimate
3706 if (tp->t_rttupdated < UCHAR_MAX) in tcp_xmit_timer()
3707 tp->t_rttupdated++; in tcp_xmit_timer()
3709 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, in tcp_xmit_timer()
3712 if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { in tcp_xmit_timer()
3720 delta = ((rtt - 1) << TCP_DELTA_SHIFT) in tcp_xmit_timer()
3721 - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); in tcp_xmit_timer()
3723 if ((tp->t_srtt += delta) <= 0) in tcp_xmit_timer()
3724 tp->t_srtt = 1; in tcp_xmit_timer()
3734 * rfc793's wired-in beta. in tcp_xmit_timer()
3737 delta = -delta; in tcp_xmit_timer()
3738 delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); in tcp_xmit_timer()
3739 if ((tp->t_rttvar += delta) <= 0) in tcp_xmit_timer()
3740 tp->t_rttvar = 1; in tcp_xmit_timer()
3743 * No rtt measurement yet - use the unsmoothed rtt. in tcp_xmit_timer()
3747 tp->t_srtt = rtt << TCP_RTT_SHIFT; in tcp_xmit_timer()
3748 tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); in tcp_xmit_timer()
3750 tp->t_rtttime = 0; in tcp_xmit_timer()
3751 tp->t_rxtshift = 0; in tcp_xmit_timer()
3758 * 1 extra tick because of +-1/2 tick uncertainty in the in tcp_xmit_timer()
3764 TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), in tcp_xmit_timer()
3765 max(tp->t_rttmin, rtt + 2), TCPTV_REXMTMAX); in tcp_xmit_timer()
3774 tp->t_softerror = 0; in tcp_xmit_timer()
3787 * While looking at the routing entry, we also initialize other path-dependent
3788 * parameters from pre-set or cached values in the routing entry.
3807 int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; in tcp_mss_update()
3817 if (tp->t_port) in tcp_mss_update()
3819 if (mtuoffer != -1) { in tcp_mss_update()
3820 KASSERT(offer == -1, ("%s: conflict", __func__)); in tcp_mss_update()
3821 offer = mtuoffer - min_protoh; in tcp_mss_update()
3827 maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); in tcp_mss_update()
3828 tp->t_maxseg = V_tcp_v6mssdflt; in tcp_mss_update()
3836 maxmtu = tcp_maxmtu(&inp->inp_inc, cap); in tcp_mss_update()
3837 tp->t_maxseg = V_tcp_mssdflt; in tcp_mss_update()
3863 offer = tp->t_maxseg; in tcp_mss_update()
3866 case -1: in tcp_mss_update()
3868 * Offer == -1 means that we didn't receive SYN yet. in tcp_mss_update()
3882 tcp_hc_get(&inp->inp_inc, metricptr); in tcp_mss_update()
3888 if (metricptr->hc_mtu) in tcp_mss_update()
3889 mss = min(metricptr->hc_mtu, maxmtu) - min_protoh; in tcp_mss_update()
3893 mss = maxmtu - min_protoh; in tcp_mss_update()
3895 !in6_localaddr(&inp->in6p_faddr)) in tcp_mss_update()
3904 mss = maxmtu - min_protoh; in tcp_mss_update()
3906 !in_localaddr(inp->inp_faddr)) in tcp_mss_update()
3911 * XXX - The above conditional (mss = maxmtu - min_protoh) in tcp_mss_update()
3941 tp->t_maxseg = mss; in tcp_mss_update()
3942 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss_update()
3948 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3950 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3968 tcp_mss_update(tp, offer, -1, &metrics, &cap); in tcp_mss()
3970 mss = tp->t_maxseg; in tcp_mss()
3979 so = inp->inp_socket; in tcp_mss()
3981 if ((so->so_snd.sb_hiwat == V_tcp_sendspace) && metrics.hc_sendpipe) in tcp_mss()
3984 bufsize = so->so_snd.sb_hiwat; in tcp_mss()
3991 if (bufsize > so->so_snd.sb_hiwat) in tcp_mss()
4003 tp->t_maxseg = max(mss, 64); in tcp_mss()
4004 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss()
4010 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss()
4012 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss()
4016 if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.hc_recvpipe) in tcp_mss()
4019 bufsize = so->so_rcv.sb_hiwat; in tcp_mss()
4024 if (bufsize > so->so_rcv.sb_hiwat) in tcp_mss()
4031 tp->t_flags |= TF_TSO; in tcp_mss()
4032 tp->t_tsomax = cap.tsomax; in tcp_mss()
4033 tp->t_tsomaxsegcount = cap.tsomaxsegcount; in tcp_mss()
4034 tp->t_tsomaxsegsize = cap.tsomaxsegsize; in tcp_mss()
4036 tp->t_flags2 |= TF2_IPSEC_TSO; in tcp_mss()
4054 if (inc->inc_flags & INC_ISIPV6) { in tcp_mssopt()
4075 mss = min(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4077 mss = max(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4101 (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_prr_ack()
4102 !IN_FASTRECOVERY(tp->t_flags))) { in tcp_do_prr_ack()
4103 del_data = tp->sackhint.delivered_data; in tcp_do_prr_ack()
4107 pipe = (tp->snd_nxt - tp->snd_fack) + in tcp_do_prr_ack()
4108 tp->sackhint.sack_bytes_rexmit; in tcp_do_prr_ack()
4110 if (tp->sackhint.prr_delivered < (tcprexmtthresh * maxseg + in tcp_do_prr_ack()
4111 tp->snd_recover - tp->snd_una)) { in tcp_do_prr_ack()
4114 pipe = imax(0, tp->snd_max - tp->snd_una - in tcp_do_prr_ack()
4115 imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); in tcp_do_prr_ack()
4117 tp->sackhint.prr_delivered += del_data; in tcp_do_prr_ack()
4121 if (pipe >= tp->snd_ssthresh) { in tcp_do_prr_ack()
4122 if (tp->sackhint.recover_fs == 0) in tcp_do_prr_ack()
4123 tp->sackhint.recover_fs = in tcp_do_prr_ack()
4124 imax(1, tp->snd_nxt - tp->snd_una); in tcp_do_prr_ack()
4125 snd_cnt = howmany((long)tp->sackhint.prr_delivered * in tcp_do_prr_ack()
4126 tp->snd_ssthresh, tp->sackhint.recover_fs) - in tcp_do_prr_ack()
4127 tp->sackhint.prr_out + maxseg - 1; in tcp_do_prr_ack()
4131 * - A partial ack without SACK block beneath snd_recover in tcp_do_prr_ack()
4133 * - An SACK scoreboard update adding a new hole indicates in tcp_do_prr_ack()
4136 * - Prevent ACK splitting attacks, by being conservative in tcp_do_prr_ack()
4140 limit = tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4141 tp->sackhint.prr_out; in tcp_do_prr_ack()
4143 limit = imax(tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4144 tp->sackhint.prr_out, del_data) + in tcp_do_prr_ack()
4147 snd_cnt = imin((tp->snd_ssthresh - pipe), limit); in tcp_do_prr_ack()
4155 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4157 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4159 tp->snd_cwnd = (tp->snd_max - tp->snd_una) + in tcp_do_prr_ack()
4162 } else if (IN_CONGRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4163 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4165 tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); in tcp_do_prr_ack()
4170 * next unacknowledged segment. Do not clear tp->t_dupacks.
4177 tcp_seq onxt = tp->snd_nxt; in tcp_newreno_partial_ack()
4178 uint32_t ocwnd = tp->snd_cwnd; in tcp_newreno_partial_ack()
4184 tp->t_rtttime = 0; in tcp_newreno_partial_ack()
4185 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_newreno_partial_ack()
4186 tp->snd_nxt = th->th_ack; in tcp_newreno_partial_ack()
4189 * (tp->snd_una has not yet been updated when this function is called.) in tcp_newreno_partial_ack()
4191 tp->snd_cwnd = maxseg + BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4192 tp->t_flags |= TF_ACKNOW; in tcp_newreno_partial_ack()
4194 tp->snd_cwnd = ocwnd; in tcp_newreno_partial_ack()
4195 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_newreno_partial_ack()
4196 tp->snd_nxt = onxt; in tcp_newreno_partial_ack()
4199 * Partial window deflation. Relies on fact that tp->snd_una in tcp_newreno_partial_ack()
4202 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) in tcp_newreno_partial_ack()
4203 tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4205 tp->snd_cwnd = 0; in tcp_newreno_partial_ack()
4206 tp->snd_cwnd += maxseg; in tcp_newreno_partial_ack()
4212 if (tp->t_fb->tfb_compute_pipe == NULL) { in tcp_compute_pipe()
4213 return (tp->snd_max - tp->snd_una + in tcp_compute_pipe()
4214 tp->sackhint.sack_bytes_rexmit - in tcp_compute_pipe()
4215 tp->sackhint.sacked_bytes - in tcp_compute_pipe()
4216 tp->sackhint.lost_bytes); in tcp_compute_pipe()
4218 return((*tp->t_fb->tfb_compute_pipe)(tp)); in tcp_compute_pipe()