Lines Matching +full:wakeup +full:- +full:rtt +full:- +full:timer
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.
188 "Slow-start flight size (initial congestion window) in number of segments");
198 "Cap the max cwnd increment during slow-start to this number of segments");
264 return ((tp->t_flags & TF_SACK_PERMIT) && in tcp_is_sack_recovery()
265 ((to->to_flags & TOF_SACK) || in tcp_is_sack_recovery()
266 (!TAILQ_EMPTY(&tp->snd_holes)))); in tcp_is_sack_recovery()
278 if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) { in hhook_run_tcp_est_in()
284 &tp->t_osd); in hhook_run_tcp_est_in()
302 tp->t_ccv.nsegs = nsegs; in cc_ack_received()
303 tp->t_ccv.bytes_this_ack = BYTES_THIS_ACK(tp, th); in cc_ack_received()
304 if ((!V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd)) || in cc_ack_received()
305 (V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd) && in cc_ack_received()
306 (tp->snd_cwnd < (tcp_compute_pipe(tp) * 2)))) in cc_ack_received()
307 tp->t_ccv.flags |= CCF_CWND_LIMITED; in cc_ack_received()
309 tp->t_ccv.flags &= ~CCF_CWND_LIMITED; in cc_ack_received()
313 stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, in cc_ack_received()
314 ((int32_t)tp->snd_cwnd) - tp->snd_wnd); in cc_ack_received()
315 if (!IN_RECOVERY(tp->t_flags)) in cc_ack_received()
316 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_ACKLEN, in cc_ack_received()
317 tp->t_ccv.bytes_this_ack / (tcp_maxseg(tp) * nsegs)); in cc_ack_received()
318 if ((tp->t_flags & TF_GPUTINPROG) && in cc_ack_received()
319 SEQ_GEQ(th->th_ack, tp->gput_ack)) { in cc_ack_received()
323 gput = (((int64_t)SEQ_SUB(th->th_ack, tp->gput_seq)) << 3) / in cc_ack_received()
324 max(1, tcp_ts_getticks() - tp->gput_ts); in cc_ack_received()
325 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, in cc_ack_received()
332 if (tp->t_stats_gput_prev > 0) in cc_ack_received()
333 stats_voi_update_abs_s32(tp->t_stats, in cc_ack_received()
335 ((gput - tp->t_stats_gput_prev) * 100) / in cc_ack_received()
336 tp->t_stats_gput_prev); in cc_ack_received()
337 tp->t_flags &= ~TF_GPUTINPROG; in cc_ack_received()
338 tp->t_stats_gput_prev = gput; in cc_ack_received()
341 if (tp->snd_cwnd > tp->snd_ssthresh) { in cc_ack_received()
342 tp->t_bytes_acked += tp->t_ccv.bytes_this_ack; in cc_ack_received()
343 if (tp->t_bytes_acked >= tp->snd_cwnd) { in cc_ack_received()
344 tp->t_bytes_acked -= tp->snd_cwnd; in cc_ack_received()
345 tp->t_ccv.flags |= CCF_ABC_SENTAWND; in cc_ack_received()
348 tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; in cc_ack_received()
349 tp->t_bytes_acked = 0; in cc_ack_received()
353 if (CC_ALGO(tp)->ack_received != NULL) { in cc_ack_received()
355 tp->t_ccv.curack = th->th_ack; in cc_ack_received()
356 CC_ALGO(tp)->ack_received(&tp->t_ccv, type); in cc_ack_received()
359 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, tp->snd_cwnd); in cc_ack_received()
369 int rtt; in cc_conn_init() local
373 tcp_hc_get(&inp->inp_inc, &metrics); in cc_conn_init()
376 if (tp->t_srtt == 0 && (rtt = metrics.hc_rtt)) { in cc_conn_init()
377 tp->t_srtt = rtt; in cc_conn_init()
380 tp->t_rttvar = metrics.hc_rttvar; in cc_conn_init()
383 /* default variation is +- 1 rtt */ in cc_conn_init()
384 tp->t_rttvar = in cc_conn_init()
385 tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; in cc_conn_init()
387 TCPT_RANGESET(tp->t_rxtcur, in cc_conn_init()
388 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, in cc_conn_init()
389 tp->t_rttmin, TCPTV_REXMTMAX); in cc_conn_init()
398 tp->snd_ssthresh = max(2 * maxseg, metrics.hc_ssthresh); in cc_conn_init()
403 * Set the initial slow-start flight size. in cc_conn_init()
409 if (tp->snd_cwnd == 1) in cc_conn_init()
410 tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ in cc_conn_init()
412 tp->snd_cwnd = tcp_compute_initwnd(maxseg); in cc_conn_init()
414 if (CC_ALGO(tp)->conn_init != NULL) in cc_conn_init()
415 CC_ALGO(tp)->conn_init(&tp->t_ccv); in cc_conn_init()
424 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); in cc_cong_signal()
429 if (!IN_FASTRECOVERY(tp->t_flags)) { in cc_cong_signal()
430 tp->snd_recover = tp->snd_max; in cc_cong_signal()
431 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
432 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
436 if (!IN_CONGRECOVERY(tp->t_flags) || in cc_cong_signal()
441 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in cc_cong_signal()
442 EXIT_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
444 tp->snd_recover = tp->snd_max + 1; in cc_cong_signal()
445 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
446 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
450 tp->t_dupacks = 0; in cc_cong_signal()
451 tp->t_bytes_acked = 0; in cc_cong_signal()
452 EXIT_RECOVERY(tp->t_flags); in cc_cong_signal()
453 if (tp->t_flags2 & TF2_ECN_PERMIT) in cc_cong_signal()
454 tp->t_flags2 |= TF2_ECN_SND_CWR; in cc_cong_signal()
459 tp->snd_cwnd = tp->snd_cwnd_prev; in cc_cong_signal()
460 tp->snd_ssthresh = tp->snd_ssthresh_prev; in cc_cong_signal()
461 tp->snd_recover = tp->snd_recover_prev; in cc_cong_signal()
462 if (tp->t_flags & TF_WASFRECOVERY) in cc_cong_signal()
463 ENTER_FASTRECOVERY(tp->t_flags); in cc_cong_signal()
464 if (tp->t_flags & TF_WASCRECOVERY) in cc_cong_signal()
465 ENTER_CONGRECOVERY(tp->t_flags); in cc_cong_signal()
466 tp->snd_nxt = tp->snd_max; in cc_cong_signal()
467 tp->t_flags &= ~TF_PREVVALID; in cc_cong_signal()
468 tp->t_badrxtwin = 0; in cc_cong_signal()
471 if (SEQ_LT(tp->snd_fack, tp->snd_una) || in cc_cong_signal()
472 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_cong_signal()
473 tp->snd_fack = tp->snd_una; in cc_cong_signal()
476 if (CC_ALGO(tp)->cong_signal != NULL) { in cc_cong_signal()
478 tp->t_ccv.curack = th->th_ack; in cc_cong_signal()
479 CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); in cc_cong_signal()
488 if (CC_ALGO(tp)->post_recovery != NULL) { in cc_post_recovery()
489 if (SEQ_LT(tp->snd_fack, th->th_ack) || in cc_post_recovery()
490 SEQ_GT(tp->snd_fack, tp->snd_max)) { in cc_post_recovery()
491 tp->snd_fack = th->th_ack; in cc_post_recovery()
493 tp->t_ccv.curack = th->th_ack; in cc_post_recovery()
494 CC_ALGO(tp)->post_recovery(&tp->t_ccv); in cc_post_recovery()
496 EXIT_RECOVERY(tp->t_flags); in cc_post_recovery()
498 tp->t_bytes_acked = 0; in cc_post_recovery()
499 tp->sackhint.delivered_data = 0; in cc_post_recovery()
500 tp->sackhint.prr_delivered = 0; in cc_post_recovery()
501 tp->sackhint.prr_out = 0; in cc_post_recovery()
507 * - There is no delayed ack timer in progress.
508 * - Our last ack wasn't a 0-sized window. We never want to delay
509 * the ack that opens up a 0-sized window.
510 * - LRO wasn't used for this segment. We make sure by checking that the
515 (tp->t_flags & TF_RXWIN0SENT) == 0) && \
516 (tlen <= tp->t_maxseg) && \
517 (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
524 if (CC_ALGO(tp)->ecnpkt_handler != NULL) { in cc_ecnpkt_handler_flags()
527 tp->t_ccv.flags |= CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
534 tp->t_ccv.flags &= ~CCF_IPHDR_CE; in cc_ecnpkt_handler_flags()
539 tp->t_ccv.flags |= CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
541 tp->t_ccv.flags &= ~CCF_TCPHDR_CWR; in cc_ecnpkt_handler_flags()
543 CC_ALGO(tp)->ecnpkt_handler(&tp->t_ccv); in cc_ecnpkt_handler_flags()
545 if (tp->t_ccv.flags & CCF_ACKNOW) { in cc_ecnpkt_handler_flags()
547 tp->t_flags |= TF_ACKNOW; in cc_ecnpkt_handler_flags()
576 if (m->m_len < *offp + sizeof(struct tcphdr)) { in tcp6_input_with_port()
586 * draft-itojun-ipv6-tcp-to-anycast in tcp6_input_with_port()
590 ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); in tcp6_input_with_port()
591 if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { in tcp6_input_with_port()
593 (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); in tcp6_input_with_port()
645 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; in tcp_input_with_port()
654 m->m_pkthdr.tcp_tun_port = port; in tcp_input_with_port()
659 tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0; in tcp_input_with_port()
662 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { in tcp_input_with_port()
663 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
664 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
666 th->th_sum = in6_cksum_pseudo(ip6, tlen, in tcp_input_with_port()
667 IPPROTO_TCP, m->m_pkthdr.csum_data); in tcp_input_with_port()
668 th->th_sum ^= 0xffff; in tcp_input_with_port()
670 th->th_sum = in6_cksum(m, IPPROTO_TCP, off0, tlen); in tcp_input_with_port()
671 if (th->th_sum) { in tcp_input_with_port()
678 * As we use all-zero to indicate unbounded/unconnected pcb, in tcp_input_with_port()
684 KASSERT(!IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst), in tcp_input_with_port()
686 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { in tcp_input_with_port()
706 if (m->m_len < sizeof (struct tcpiphdr)) { in tcp_input_with_port()
715 tlen = ntohs(ip->ip_len) - off0; in tcp_input_with_port()
717 iptos = ip->ip_tos; in tcp_input_with_port()
720 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { in tcp_input_with_port()
721 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) in tcp_input_with_port()
722 th->th_sum = m->m_pkthdr.csum_data; in tcp_input_with_port()
724 th->th_sum = in_pseudo(ip->ip_src.s_addr, in tcp_input_with_port()
725 ip->ip_dst.s_addr, in tcp_input_with_port()
726 htonl(m->m_pkthdr.csum_data + tlen + in tcp_input_with_port()
728 th->th_sum ^= 0xffff; in tcp_input_with_port()
736 ipttl = ip->ip_ttl; in tcp_input_with_port()
737 bzero(ipov->ih_x1, sizeof(ipov->ih_x1)); in tcp_input_with_port()
738 ipov->ih_len = htons(tlen); in tcp_input_with_port()
739 th->th_sum = in_cksum(m, len); in tcp_input_with_port()
741 ip->ip_len = htons(len); in tcp_input_with_port()
743 ip->ip_tos = iptos; in tcp_input_with_port()
744 /* Re-initialization for later version check */ in tcp_input_with_port()
745 ip->ip_ttl = ipttl; in tcp_input_with_port()
746 ip->ip_v = IPVERSION; in tcp_input_with_port()
747 ip->ip_hl = off0 >> 2; in tcp_input_with_port()
750 if (th->th_sum && (port == 0)) { in tcp_input_with_port()
754 KASSERT(ip->ip_dst.s_addr != INADDR_ANY, in tcp_input_with_port()
756 if (__predict_false(ip->ip_src.s_addr == INADDR_ANY)) { in tcp_input_with_port()
767 off = th->th_off << 2; in tcp_input_with_port()
772 tlen -= off; /* tlen is used instead of ti->ti_len */ in tcp_input_with_port()
776 if (m->m_len < off0 + off) { in tcp_input_with_port()
792 if (m->m_len < sizeof(struct ip) + off) { in tcp_input_with_port()
803 optlen = off - sizeof (struct tcphdr); in tcp_input_with_port()
823 (isipv6 && (m->m_flags & M_IP6_NEXTHOP)) in tcp_input_with_port()
825 || (!isipv6 && (m->m_flags & M_IP_NEXTHOP)) in tcp_input_with_port()
829 (m->m_flags & M_IP_NEXTHOP) in tcp_input_with_port()
855 &ip6->ip6_src, th->th_sport, &ip6->ip6_dst, th->th_dport, in tcp_input_with_port()
856 lookupflag & ~INPLOOKUP_WILDCARD, m->m_pkthdr.rcvif, m); in tcp_input_with_port()
861 * any hardware-generated hash is ignored. in tcp_input_with_port()
863 inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
864 th->th_sport, &next_hop6->sin6_addr, in tcp_input_with_port()
865 next_hop6->sin6_port ? ntohs(next_hop6->sin6_port) : in tcp_input_with_port()
866 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
869 inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src, in tcp_input_with_port()
870 th->th_sport, &ip6->ip6_dst, th->th_dport, lookupflag, in tcp_input_with_port()
871 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
886 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport, in tcp_input_with_port()
887 ip->ip_dst, th->th_dport, lookupflag & ~INPLOOKUP_WILDCARD, in tcp_input_with_port()
888 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
893 * any hardware-generated hash is ignored. in tcp_input_with_port()
895 inp = in_pcblookup(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
896 th->th_sport, next_hop->sin_addr, in tcp_input_with_port()
897 next_hop->sin_port ? ntohs(next_hop->sin_port) : in tcp_input_with_port()
898 th->th_dport, lookupflag, m->m_pkthdr.rcvif); in tcp_input_with_port()
901 inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, in tcp_input_with_port()
902 th->th_sport, ip->ip_dst, th->th_dport, lookupflag, in tcp_input_with_port()
903 m->m_pkthdr.rcvif, m); in tcp_input_with_port()
932 if ((inp->inp_flowtype == M_HASHTYPE_NONE) && in tcp_input_with_port()
933 !SOLISTENING(inp->inp_socket)) { in tcp_input_with_port()
935 inp->inp_flowid = m->m_pkthdr.flowid; in tcp_input_with_port()
936 inp->inp_flowtype = M_HASHTYPE_GET(m); in tcp_input_with_port()
942 rss_proto_software_hash_v6(&inp->in6p_faddr, in tcp_input_with_port()
943 &inp->in6p_laddr, in tcp_input_with_port()
944 inp->inp_fport, in tcp_input_with_port()
945 inp->inp_lport, in tcp_input_with_port()
947 &inp->inp_flowid, in tcp_input_with_port()
948 &inp->inp_flowtype); in tcp_input_with_port()
952 rss_proto_software_hash_v4(inp->inp_faddr, in tcp_input_with_port()
953 inp->inp_laddr, in tcp_input_with_port()
954 inp->inp_fport, in tcp_input_with_port()
955 inp->inp_lport, in tcp_input_with_port()
957 &inp->inp_flowid, in tcp_input_with_port()
958 &inp->inp_flowtype); in tcp_input_with_port()
984 if (inp->inp_ip_minttl != 0) { in tcp_input_with_port()
987 if (inp->inp_ip_minttl > ip6->ip6_hlim) in tcp_input_with_port()
991 if (inp->inp_ip_minttl > ip->ip_ttl) in tcp_input_with_port()
996 switch (tp->t_state) { in tcp_input_with_port()
1022 if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { in tcp_input_with_port()
1028 if (tp->t_flags & TF_TOE) { in tcp_input_with_port()
1039 so = inp->inp_socket; in tcp_input_with_port()
1046 KASSERT(tp->t_state == TCPS_LISTEN || !SOLISTENING(so), in tcp_input_with_port()
1048 if (tp->t_state == TCPS_LISTEN && SOLISTENING(so)) { in tcp_input_with_port()
1055 if (inp->inp_inc.inc_flags & INC_IPV6MINMTU) in tcp_input_with_port()
1057 inc.inc6_faddr = ip6->ip6_src; in tcp_input_with_port()
1058 inc.inc6_laddr = ip6->ip6_dst; in tcp_input_with_port()
1062 inc.inc_faddr = ip->ip_src; in tcp_input_with_port()
1063 inc.inc_laddr = ip->ip_dst; in tcp_input_with_port()
1065 inc.inc_fport = th->th_sport; in tcp_input_with_port()
1066 inc.inc_lport = th->th_dport; in tcp_input_with_port()
1067 inc.inc_fibnum = so->so_fibnum; in tcp_input_with_port()
1119 * We completed the 3-way handshake in tcp_input_with_port()
1146 * then listening socket is read-locked. in tcp_input_with_port()
1156 KASSERT(tp->t_state == TCPS_SYN_RECEIVED, in tcp_input_with_port()
1164 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, in tcp_input_with_port()
1254 * communication is okay - "SHOULD continue to be in tcp_input_with_port()
1261 * our source address selection - we must obey the peer. in tcp_input_with_port()
1265 * handling - worse, they are not exactly the same. in tcp_input_with_port()
1271 ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); in tcp_input_with_port()
1273 (ia6->ia6_flags & IN6_IFF_DEPRECATED)) { in tcp_input_with_port()
1290 * global or subnet broad- or multicast address. in tcp_input_with_port()
1292 * link-layer packets with a broadcast IP address. Use in tcp_input_with_port()
1295 if (m->m_flags & (M_BCAST|M_MCAST)) { in tcp_input_with_port()
1298 "Connection attempt from broad- or multicast " in tcp_input_with_port()
1304 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1305 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &ip6->ip6_src)) { in tcp_input_with_port()
1312 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_input_with_port()
1313 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { in tcp_input_with_port()
1327 if (th->th_dport == th->th_sport && in tcp_input_with_port()
1328 ip->ip_dst.s_addr == ip->ip_src.s_addr) { in tcp_input_with_port()
1335 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_input_with_port()
1336 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_input_with_port()
1337 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_input_with_port()
1338 in_ifnet_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { in tcp_input_with_port()
1341 "Connection attempt from/to broad- " in tcp_input_with_port()
1365 if (tp->t_flags & TF_SIGNATURE) { in tcp_input_with_port()
1387 * write-lock on PCB. If upgrade fails, drop the SYN. in tcp_input_with_port()
1392 tp->t_fb->tfb_tcp_do_segment(tp, m, th, drop_hdrlen, tlen, iptos); in tcp_input_with_port()
1405 isipv6 ? !in6_localaddr(&ip6->ip6_src) : in tcp_input_with_port()
1408 !in_localip(ip->ip_src) in tcp_input_with_port()
1438 * bandwidth and high delay (eg. trans-continental/oceanic links).
1460 * of slow-start but also makes it so our peer never gets limited
1463 * This algorithm does two steps per RTT at most and only if
1477 if (V_tcp_do_autorcvbuf && (so->so_rcv.sb_flags & SB_AUTOSIZE) && in tcp_autorcvbuf()
1478 tp->t_srtt != 0 && tp->rfbuf_ts != 0 && in tcp_autorcvbuf()
1479 TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > in tcp_autorcvbuf()
1480 ((tp->t_srtt >> TCP_RTT_SHIFT)/2)) { in tcp_autorcvbuf()
1481 if (tp->rfbuf_cnt > ((so->so_rcv.sb_hiwat / 2)/ 4 * 3) && in tcp_autorcvbuf()
1482 so->so_rcv.sb_hiwat < V_tcp_autorcvbuf_max) { in tcp_autorcvbuf()
1483 newsize = min((so->so_rcv.sb_hiwat + (so->so_rcv.sb_hiwat/2)), V_tcp_autorcvbuf_max); in tcp_autorcvbuf()
1487 /* Start over with next RTT. */ in tcp_autorcvbuf()
1488 tp->rfbuf_ts = 0; in tcp_autorcvbuf()
1489 tp->rfbuf_cnt = 0; in tcp_autorcvbuf()
1491 tp->rfbuf_cnt += tlen; /* add up */ in tcp_autorcvbuf()
1508 if (tp->t_flags & TF_WAKESOR) { in tcp_handle_wakeup()
1511 tp->t_flags &= ~TF_WAKESOR; in tcp_handle_wakeup()
1530 struct in_conninfo *inc = &inp->inp_inc; in tcp_do_segment()
1537 tp->sackhint.last_sack_ack = 0; in tcp_do_segment()
1539 nsegs = max(1, m->m_pkthdr.lro_nsegs); in tcp_do_segment()
1543 KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", in tcp_do_segment()
1545 KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", in tcp_do_segment()
1550 tcp_pcap_add(th, m, &(tp->t_inpkts)); in tcp_do_segment()
1552 TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, in tcp_do_segment()
1566 * If a segment with the ACK-bit set arrives in the SYN-SENT state in tcp_do_segment()
1569 if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && in tcp_do_segment()
1570 (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1578 * Reset idle time and keep-alive timer. in tcp_do_segment()
1582 if (tp->t_idle_reduce && in tcp_do_segment()
1583 (tp->snd_max == tp->snd_una) && in tcp_do_segment()
1584 ((ticks - tp->t_rcvtime) >= tp->t_rxtcur)) in tcp_do_segment()
1586 tp->t_rcvtime = ticks; in tcp_do_segment()
1591 * Scale up the window into a 32-bit value. in tcp_do_segment()
1594 tiwin = th->th_win << tp->snd_scale; in tcp_do_segment()
1596 stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); in tcp_do_segment()
1603 tcp_packets_this_ack(tp, th->th_ack), in tcp_do_segment()
1611 (th->th_off << 2) - sizeof(struct tcphdr), in tcp_do_segment()
1613 if (tp->t_flags2 & TF2_PROC_SACK_PROHIBIT) { in tcp_do_segment()
1622 if ((tp->t_flags & TF_SIGNATURE) != 0 && in tcp_do_segment()
1630 * fall back to non RFC1323 RTT calculation. Normalize in tcp_do_segment()
1635 to.to_tsecr -= tp->ts_offset; in tcp_do_segment()
1638 } else if (tp->t_rxtshift == 1 && in tcp_do_segment()
1639 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1640 tp->t_badrxtwin != 0 && in tcp_do_segment()
1641 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) { in tcp_do_segment()
1652 if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { in tcp_do_segment()
1656 (tp->t_flags & TF_REQ_SCALE) && in tcp_do_segment()
1657 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1658 tp->t_flags |= TF_RCVD_SCALE; in tcp_do_segment()
1659 tp->snd_scale = to.to_wscale; in tcp_do_segment()
1661 tp->t_flags &= ~TF_REQ_SCALE; in tcp_do_segment()
1667 tp->snd_wnd = th->th_win; in tcp_do_segment()
1669 (tp->t_flags & TF_REQ_TSTMP) && in tcp_do_segment()
1670 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1671 tp->t_flags |= TF_RCVD_TSTMP; in tcp_do_segment()
1672 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1673 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1675 tp->t_flags &= ~TF_REQ_TSTMP; in tcp_do_segment()
1680 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
1682 (tp->t_flags & TF_NOOPT))) { in tcp_do_segment()
1683 tp->t_flags &= ~TF_SACK_PERMIT; in tcp_do_segment()
1685 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
1687 !(tp->t_flags & TF_NOOPT)) { in tcp_do_segment()
1693 if ((inp->inp_vflag & INP_IPV6) != 0) { in tcp_do_segment()
1714 if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { in tcp_do_segment()
1737 if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) { in tcp_do_segment()
1747 * of a uni-directional data xfer. If the packet has in tcp_do_segment()
1748 * no control flags, is in-sequence, the window didn't in tcp_do_segment()
1754 * is non-zero and the ack didn't move, we're the in tcp_do_segment()
1755 * receiver side. If we're getting packets in-order in tcp_do_segment()
1758 * Make sure that the hidden state-flags are also off. in tcp_do_segment()
1762 if (tp->t_state == TCPS_ESTABLISHED && in tcp_do_segment()
1763 th->th_seq == tp->rcv_nxt && in tcp_do_segment()
1765 tp->snd_nxt == tp->snd_max && in tcp_do_segment()
1766 tiwin && tiwin == tp->snd_wnd && in tcp_do_segment()
1767 ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && in tcp_do_segment()
1770 TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { in tcp_do_segment()
1778 SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { in tcp_do_segment()
1779 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
1780 tp->ts_recent = to.to_tsval; in tcp_do_segment()
1784 if (SEQ_GT(th->th_ack, tp->snd_una) && in tcp_do_segment()
1785 SEQ_LEQ(th->th_ack, tp->snd_max) && in tcp_do_segment()
1786 !IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
1788 TAILQ_EMPTY(&tp->snd_holes)) { in tcp_do_segment()
1798 tp->t_rxtshift == 1 && in tcp_do_segment()
1799 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
1800 tp->t_badrxtwin != 0 && in tcp_do_segment()
1801 TSTMP_LT(ticks, tp->t_badrxtwin)) { in tcp_do_segment()
1806 * Recalculate the transmit timer / rtt. in tcp_do_segment()
1811 * huge RTT and blow up the retransmit timer. in tcp_do_segment()
1817 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
1818 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
1819 tp->t_rttlow = t; in tcp_do_segment()
1822 } else if (tp->t_rtttime && in tcp_do_segment()
1823 SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
1824 if (!tp->t_rttlow || in tcp_do_segment()
1825 tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
1826 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
1828 ticks - tp->t_rtttime); in tcp_do_segment()
1839 sbdrop(&so->so_snd, acked); in tcp_do_segment()
1840 if (SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
1841 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
1842 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
1852 tp->snd_una = th->th_ack; in tcp_do_segment()
1857 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
1858 tp->t_dupacks = 0; in tcp_do_segment()
1863 * retransmit timer, otherwise restart timer in tcp_do_segment()
1864 * using current (possibly backed-off) value. in tcp_do_segment()
1866 * wakeup/selwakeup/signal. If data in tcp_do_segment()
1877 if (sbavail(&so->so_snd) == 0) in tcp_do_segment()
1878 tp->t_acktime = 0; in tcp_do_segment()
1880 tp->t_acktime = ticks; in tcp_do_segment()
1881 if (tp->snd_una == tp->snd_max) in tcp_do_segment()
1892 if ((tp->t_flags & TF_ACKNOW) || in tcp_do_segment()
1893 (sbavail(&so->so_snd) >= in tcp_do_segment()
1894 SEQ_SUB(tp->snd_max, tp->snd_una))) { in tcp_do_segment()
1899 } else if (th->th_ack == tp->snd_una && in tcp_do_segment()
1900 tlen <= sbspace(&so->so_rcv)) { in tcp_do_segment()
1904 * This is a pure, in-sequence data packet with in tcp_do_segment()
1909 if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks) in tcp_do_segment()
1912 tp->rcv_nxt += tlen; in tcp_do_segment()
1914 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
1915 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
1916 tp->t_fbyte_in = ticks; in tcp_do_segment()
1917 if (tp->t_fbyte_in == 0) in tcp_do_segment()
1918 tp->t_fbyte_in = 1; in tcp_do_segment()
1919 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
1920 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
1926 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
1931 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
1940 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
1950 so->so_rcv.sb_flags &= ~SB_AUTOSIZE; in tcp_do_segment()
1952 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
1957 tp->t_flags |= TF_DELACK; in tcp_do_segment()
1959 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
1972 win = sbspace(&so->so_rcv); in tcp_do_segment()
1975 tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); in tcp_do_segment()
1977 switch (tp->t_state) { in tcp_do_segment()
1988 (SEQ_LEQ(th->th_ack, tp->snd_una) || in tcp_do_segment()
1989 SEQ_GT(th->th_ack, tp->snd_max))) { in tcp_do_segment()
1994 if (tp->t_flags & TF_FASTOPEN) { in tcp_do_segment()
2007 /* non-initial SYN is ignored */ in tcp_do_segment()
2024 * initialize tp->rcv_nxt and tp->irs in tcp_do_segment()
2025 * if seg contains ack then advance tp->snd_una in tcp_do_segment()
2044 tp->irs = th->th_seq; in tcp_do_segment()
2055 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2057 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2059 tp->rcv_adv += min(tp->rcv_wnd, in tcp_do_segment()
2060 TCP_MAXWIN << tp->rcv_scale); in tcp_do_segment()
2061 tp->snd_una++; /* SYN is acked */ in tcp_do_segment()
2062 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
2063 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
2068 if ((tp->t_flags & TF_FASTOPEN) && in tcp_do_segment()
2069 (tp->snd_una != tp->snd_max)) { in tcp_do_segment()
2070 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2081 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2088 * SYN_SENT --> ESTABLISHED in tcp_do_segment()
2089 * SYN_SENT* --> FIN_WAIT_1 in tcp_do_segment()
2091 tp->t_starttime = ticks; in tcp_do_segment()
2092 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2093 tp->t_acktime = ticks; in tcp_do_segment()
2095 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2107 * Received initial SYN in SYN-SENT[*] state => in tcp_do_segment()
2109 * If it succeeds, connection is * half-synchronized. in tcp_do_segment()
2110 * Otherwise, do 3-way handshake: in tcp_do_segment()
2111 * SYN-SENT -> SYN-RECEIVED in tcp_do_segment()
2112 * SYN-SENT* -> SYN-RECEIVED* in tcp_do_segment()
2114 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); in tcp_do_segment()
2120 * Advance th->th_seq to correspond to first data byte. in tcp_do_segment()
2124 th->th_seq++; in tcp_do_segment()
2125 if (tlen > tp->rcv_wnd) { in tcp_do_segment()
2126 todrop = tlen - tp->rcv_wnd; in tcp_do_segment()
2127 m_adj(m, -todrop); in tcp_do_segment()
2128 tlen = tp->rcv_wnd; in tcp_do_segment()
2133 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2134 tp->rcv_up = th->th_seq; in tcp_do_segment()
2167 * - RST drops connection only if SEG.SEQ == RCV.NXT. in tcp_do_segment()
2168 * - If RST is in window, we send challenge ACK. in tcp_do_segment()
2175 if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2176 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || in tcp_do_segment()
2177 (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { in tcp_do_segment()
2178 KASSERT(tp->t_state != TCPS_SYN_SENT, in tcp_do_segment()
2183 tp->last_ack_sent == th->th_seq) { in tcp_do_segment()
2186 switch (tp->t_state) { in tcp_do_segment()
2188 so->so_error = ECONNREFUSED; in tcp_do_segment()
2196 so->so_error = ECONNRESET; in tcp_do_segment()
2216 if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT && in tcp_do_segment()
2217 tp->t_state != TCPS_SYN_RECEIVED) { in tcp_do_segment()
2220 SEQ_GEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2221 SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { in tcp_do_segment()
2237 if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && in tcp_do_segment()
2238 TSTMP_LT(to.to_tsval, tp->ts_recent)) { in tcp_do_segment()
2240 if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { in tcp_do_segment()
2249 * because we don't want out-of-order segments to be in tcp_do_segment()
2252 tp->ts_recent = 0; in tcp_do_segment()
2264 * In the SYN-RECEIVED state, validate that the packet belongs to in tcp_do_segment()
2270 if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { in tcp_do_segment()
2276 todrop = tp->rcv_nxt - th->th_seq; in tcp_do_segment()
2280 th->th_seq++; in tcp_do_segment()
2281 if (th->th_urp > 1) in tcp_do_segment()
2282 th->th_urp--; in tcp_do_segment()
2285 todrop--; in tcp_do_segment()
2303 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2312 * DSACK - add SACK block for dropped range in tcp_do_segment()
2314 if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2315 tcp_update_sack_list(tp, th->th_seq, in tcp_do_segment()
2316 th->th_seq + todrop); in tcp_do_segment()
2318 * ACK now, as the next in-sequence segment in tcp_do_segment()
2321 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2324 th->th_seq += todrop; in tcp_do_segment()
2325 tlen -= todrop; in tcp_do_segment()
2326 if (th->th_urp > todrop) in tcp_do_segment()
2327 th->th_urp -= todrop; in tcp_do_segment()
2330 th->th_urp = 0; in tcp_do_segment()
2339 if ((tp->t_flags & TF_CLOSED) && tlen > 0 && in tcp_do_segment()
2340 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
2345 s, __func__, tcpstates[tp->t_state], tlen); in tcp_do_segment()
2349 /* tcp_close will kill the inp pre-log the Reset */ in tcp_do_segment()
2361 todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); in tcp_do_segment()
2373 if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { in tcp_do_segment()
2374 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2380 m_adj(m, -todrop); in tcp_do_segment()
2381 tlen -= todrop; in tcp_do_segment()
2401 * RTT correctly when RCV.NXT == Last.ACK.Sent. in tcp_do_segment()
2404 SEQ_LEQ(th->th_seq, tp->last_ack_sent) && in tcp_do_segment()
2405 SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + in tcp_do_segment()
2407 tp->ts_recent_age = tcp_ts_getticks(); in tcp_do_segment()
2408 tp->ts_recent = to.to_tsval; in tcp_do_segment()
2412 * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN in tcp_do_segment()
2413 * flag is on (half-synchronized state), then queue data for in tcp_do_segment()
2417 if (tp->t_state == TCPS_SYN_RECEIVED || in tcp_do_segment()
2418 (tp->t_flags & TF_NEEDSYN)) { in tcp_do_segment()
2419 if (tp->t_state == TCPS_SYN_RECEIVED && in tcp_do_segment()
2420 (tp->t_flags & TF_FASTOPEN)) { in tcp_do_segment()
2421 tp->snd_wnd = tiwin; in tcp_do_segment()
2425 } else if (tp->t_flags & TF_ACKNOW) in tcp_do_segment()
2434 if (SEQ_GEQ(tp->snd_una, tp->iss + (TCP_MAXWIN << tp->snd_scale))) { in tcp_do_segment()
2436 tp->t_flags2 |= TF2_NO_ISS_CHECK; in tcp_do_segment()
2442 if (tp->t_flags2 & TF2_NO_ISS_CHECK) { in tcp_do_segment()
2444 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2447 if (SEQ_GT(tp->iss + 1, tp->snd_una - tp->max_sndwnd)) { in tcp_do_segment()
2449 seq_min = tp->iss + 1; in tcp_do_segment()
2456 seq_min = tp->snd_una - tp->max_sndwnd; in tcp_do_segment()
2460 if (SEQ_LT(th->th_ack, seq_min)) { in tcp_do_segment()
2470 switch (tp->t_state) { in tcp_do_segment()
2479 if (tp->t_flags & TF_SONOTCONN) { in tcp_do_segment()
2489 tp->t_flags &= ~TF_SONOTCONN; in tcp_do_segment()
2493 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2495 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2497 tp->snd_wnd = tiwin; in tcp_do_segment()
2500 * SYN-RECEIVED -> ESTABLISHED in tcp_do_segment()
2501 * SYN-RECEIVED* -> FIN-WAIT-1 in tcp_do_segment()
2503 tp->t_starttime = ticks; in tcp_do_segment()
2504 if ((tp->t_flags & TF_FASTOPEN) && tp->t_tfo_pending) { in tcp_do_segment()
2505 tcp_fastopen_decrement_counter(tp->t_tfo_pending); in tcp_do_segment()
2506 tp->t_tfo_pending = NULL; in tcp_do_segment()
2508 if (tp->t_flags & TF_NEEDFIN) { in tcp_do_segment()
2509 tp->t_acktime = ticks; in tcp_do_segment()
2511 tp->t_flags &= ~TF_NEEDFIN; in tcp_do_segment()
2523 if (!(tp->t_flags & TF_FASTOPEN)) in tcp_do_segment()
2532 if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) in tcp_do_segment()
2543 tp->snd_wl1 = th->th_seq - 1; in tcp_do_segment()
2549 * tp->snd_una < th->th_ack <= tp->snd_max in tcp_do_segment()
2550 * then advance tp->snd_una to th->th_ack and drop in tcp_do_segment()
2560 if (SEQ_GT(th->th_ack, tp->snd_max)) { in tcp_do_segment()
2565 sack_changed = tcp_sack_doack(tp, &to, th->th_ack); in tcp_do_segment()
2567 (tp->t_flags & TF_LRD)) { in tcp_do_segment()
2575 tp->sackhint.sacked_bytes = 0; in tcp_do_segment()
2582 if (SEQ_LEQ(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2585 (tiwin == tp->snd_wnd || in tcp_do_segment()
2586 (tp->t_flags & TF_SACK_PERMIT))) { in tcp_do_segment()
2595 (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { in tcp_do_segment()
2596 tp->t_dupacks = 0; in tcp_do_segment()
2637 if (th->th_ack != tp->snd_una || in tcp_do_segment()
2642 tp->t_dupacks = 0; in tcp_do_segment()
2643 } else if (++tp->t_dupacks > tcprexmtthresh || in tcp_do_segment()
2644 IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2648 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2649 (tp->t_flags & TF_SACK_PERMIT)) { in tcp_do_segment()
2653 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2654 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2664 if (awnd < tp->snd_ssthresh) { in tcp_do_segment()
2665 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2667 tp->sackhint.delivered_data)); in tcp_do_segment()
2668 if (tp->snd_cwnd > tp->snd_ssthresh) in tcp_do_segment()
2669 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2672 IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2673 SEQ_LT(tp->snd_nxt, tp->snd_max)) { in tcp_do_segment()
2674 tp->snd_cwnd += imax(maxseg, in tcp_do_segment()
2676 tp->sackhint.delivered_data)); in tcp_do_segment()
2678 tp->snd_cwnd += maxseg; in tcp_do_segment()
2682 } else if (tp->t_dupacks == tcprexmtthresh || in tcp_do_segment()
2683 (tp->t_flags & TF_SACK_PERMIT && in tcp_do_segment()
2685 tp->sackhint.sacked_bytes > in tcp_do_segment()
2686 (tcprexmtthresh - 1) * maxseg)) { in tcp_do_segment()
2690 * more than (dupthresh-1)*maxseg sacked data. in tcp_do_segment()
2696 tp->t_dupacks = tcprexmtthresh; in tcp_do_segment()
2697 tcp_seq onxt = tp->snd_nxt; in tcp_do_segment()
2707 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2708 tp->t_dupacks = 0; in tcp_do_segment()
2712 if (SEQ_LEQ(th->th_ack, in tcp_do_segment()
2713 tp->snd_recover)) { in tcp_do_segment()
2714 tp->t_dupacks = 0; in tcp_do_segment()
2723 tp->t_rtttime = 0; in tcp_do_segment()
2734 tp->sackhint.prr_delivered = in tcp_do_segment()
2735 imin(tp->snd_max - th->th_ack, in tcp_do_segment()
2736 (tp->snd_limited + 1) * maxseg); in tcp_do_segment()
2738 tp->sackhint.prr_delivered = in tcp_do_segment()
2741 tp->sackhint.recover_fs = max(1, in tcp_do_segment()
2742 tp->snd_nxt - tp->snd_una); in tcp_do_segment()
2744 tp->snd_limited = 0; in tcp_do_segment()
2754 tp->snd_nxt = tp->snd_max; in tcp_do_segment()
2755 tp->snd_cwnd = tcp_compute_pipe(tp) + in tcp_do_segment()
2759 tp->snd_cwnd = tp->snd_ssthresh; in tcp_do_segment()
2760 if (SEQ_GT(th->th_ack, tp->snd_una)) { in tcp_do_segment()
2765 tp->snd_nxt = th->th_ack; in tcp_do_segment()
2766 tp->snd_cwnd = maxseg; in tcp_do_segment()
2768 KASSERT(tp->snd_limited <= 2, in tcp_do_segment()
2769 ("%s: tp->snd_limited too big", in tcp_do_segment()
2771 tp->snd_cwnd = tp->snd_ssthresh + in tcp_do_segment()
2773 (tp->t_dupacks - tp->snd_limited); in tcp_do_segment()
2774 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_do_segment()
2775 tp->snd_nxt = onxt; in tcp_do_segment()
2789 uint32_t oldcwnd = tp->snd_cwnd; in tcp_do_segment()
2790 tcp_seq oldsndmax = tp->snd_max; in tcp_do_segment()
2794 KASSERT(tp->t_dupacks == 1 || in tcp_do_segment()
2795 tp->t_dupacks == 2, in tcp_do_segment()
2798 if (tp->t_dupacks == 1) in tcp_do_segment()
2799 tp->snd_limited = 0; in tcp_do_segment()
2800 if ((tp->snd_nxt == tp->snd_max) && in tcp_do_segment()
2801 (tp->t_rxtshift == 0)) in tcp_do_segment()
2802 tp->snd_cwnd = in tcp_do_segment()
2803 SEQ_SUB(tp->snd_nxt, in tcp_do_segment()
2804 tp->snd_una) - in tcp_do_segment()
2806 tp->snd_cwnd += in tcp_do_segment()
2807 (tp->t_dupacks - tp->snd_limited) * in tcp_do_segment()
2808 maxseg - tcp_sack_adjust(tp); in tcp_do_segment()
2815 avail = sbavail(&so->so_snd); in tcp_do_segment()
2817 if (tp->t_flags & TF_ACKNOW || in tcp_do_segment()
2819 SEQ_SUB(tp->snd_nxt, tp->snd_una))) { in tcp_do_segment()
2822 sent = SEQ_SUB(tp->snd_max, oldsndmax); in tcp_do_segment()
2824 KASSERT((tp->t_dupacks == 2 && in tcp_do_segment()
2825 tp->snd_limited == 0) || in tcp_do_segment()
2827 tp->t_flags & TF_SENTFIN), in tcp_do_segment()
2830 tp->snd_limited = 2; in tcp_do_segment()
2832 ++tp->snd_limited; in tcp_do_segment()
2834 tp->snd_cwnd = oldcwnd; in tcp_do_segment()
2844 tp->t_dupacks = 0; in tcp_do_segment()
2855 (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || in tcp_do_segment()
2856 ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && in tcp_do_segment()
2857 (tp->snd_nxt == tp->snd_max)) { in tcp_do_segment()
2858 tp->t_dupacks++; in tcp_do_segment()
2860 if (!IN_FASTRECOVERY(tp->t_flags) && in tcp_do_segment()
2861 (tp->sackhint.sacked_bytes > in tcp_do_segment()
2862 ((tcprexmtthresh - 1) * in tcp_do_segment()
2870 KASSERT(SEQ_GT(th->th_ack, tp->snd_una), in tcp_do_segment()
2877 if (SEQ_LT(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
2878 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_segment()
2879 if (tp->t_flags & TF_SACK_PERMIT) { in tcp_do_segment()
2884 tp->t_rtttime = 0; in tcp_do_segment()
2887 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
2896 } else if (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_segment()
2898 tp->sackhint.delivered_data = in tcp_do_segment()
2900 tp->snd_fack = th->th_ack; in tcp_do_segment()
2903 * always use PRR-SSRB in tcp_do_segment()
2914 if (tp->t_flags & TF_NEEDSYN) { in tcp_do_segment()
2916 * T/TCP: Connection was half-synchronized, and our in tcp_do_segment()
2918 * synchronized). Go to non-starred state, in tcp_do_segment()
2922 tp->t_flags &= ~TF_NEEDSYN; in tcp_do_segment()
2923 tp->snd_una++; in tcp_do_segment()
2925 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == in tcp_do_segment()
2927 tp->rcv_scale = tp->request_r_scale; in tcp_do_segment()
2938 * This is for the SYN_RECEIVED, non-simultaneous in tcp_do_segment()
2943 tp->snd_una++; in tcp_do_segment()
2946 "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__, in tcp_do_segment()
2947 tp->snd_una, th->th_ack, tp, m)); in tcp_do_segment()
2958 if (tp->t_rxtshift == 1 && in tcp_do_segment()
2959 tp->t_flags & TF_PREVVALID && in tcp_do_segment()
2960 tp->t_badrxtwin != 0 && in tcp_do_segment()
2963 TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) in tcp_do_segment()
2969 * transmit timer is running and timed sequence in tcp_do_segment()
2971 * Since we now have an rtt measurement, cancel the in tcp_do_segment()
2972 * timer backoff (cf., Phil Karn's retransmit alg.). in tcp_do_segment()
2973 * Recompute the initial retransmit timer. in tcp_do_segment()
2978 * huge RTT and blow up the retransmit timer. in tcp_do_segment()
2983 t = tcp_ts_getticks() - to.to_tsecr; in tcp_do_segment()
2984 if (!tp->t_rttlow || tp->t_rttlow > t) in tcp_do_segment()
2985 tp->t_rttlow = t; in tcp_do_segment()
2987 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { in tcp_do_segment()
2988 if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) in tcp_do_segment()
2989 tp->t_rttlow = ticks - tp->t_rtttime; in tcp_do_segment()
2990 tcp_xmit_timer(tp, ticks - tp->t_rtttime); in tcp_do_segment()
3000 if ((tp->t_state <= TCPS_CLOSE_WAIT && in tcp_do_segment()
3001 acked == sbavail(&so->so_snd)) || in tcp_do_segment()
3002 acked > sbavail(&so->so_snd)) in tcp_do_segment()
3003 tp->t_acktime = 0; in tcp_do_segment()
3005 tp->t_acktime = ticks; in tcp_do_segment()
3009 * timer and remember to restart (more output or persist). in tcp_do_segment()
3011 * timer, using current (possibly backed-off) value. in tcp_do_segment()
3013 if (th->th_ack == tp->snd_max) { in tcp_do_segment()
3035 if (acked > sbavail(&so->so_snd)) { in tcp_do_segment()
3036 if (tp->snd_wnd >= sbavail(&so->so_snd)) in tcp_do_segment()
3037 tp->snd_wnd -= sbavail(&so->so_snd); in tcp_do_segment()
3039 tp->snd_wnd = 0; in tcp_do_segment()
3040 mfree = sbcut_locked(&so->so_snd, in tcp_do_segment()
3041 (int)sbavail(&so->so_snd)); in tcp_do_segment()
3044 mfree = sbcut_locked(&so->so_snd, acked); in tcp_do_segment()
3045 if (tp->snd_wnd >= (uint32_t) acked) in tcp_do_segment()
3046 tp->snd_wnd -= acked; in tcp_do_segment()
3048 tp->snd_wnd = 0; in tcp_do_segment()
3055 if (!IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3056 SEQ_GT(tp->snd_una, tp->snd_recover) && in tcp_do_segment()
3057 SEQ_LEQ(th->th_ack, tp->snd_recover)) in tcp_do_segment()
3058 tp->snd_recover = th->th_ack - 1; in tcp_do_segment()
3059 tp->snd_una = th->th_ack; in tcp_do_segment()
3060 if (IN_RECOVERY(tp->t_flags) && in tcp_do_segment()
3061 SEQ_GEQ(th->th_ack, tp->snd_recover)) { in tcp_do_segment()
3064 if (SEQ_GT(tp->snd_una, tp->snd_recover)) { in tcp_do_segment()
3065 tp->snd_recover = tp->snd_una; in tcp_do_segment()
3067 if (SEQ_LT(tp->snd_nxt, tp->snd_una)) in tcp_do_segment()
3068 tp->snd_nxt = tp->snd_una; in tcp_do_segment()
3070 switch (tp->t_state) { in tcp_do_segment()
3081 * Starting the timer is contrary to the in tcp_do_segment()
3085 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { in tcp_do_segment()
3100 * then enter the TIME-WAIT state, otherwise ignore in tcp_do_segment()
3134 (SEQ_LT(tp->snd_wl1, th->th_seq) || in tcp_do_segment()
3135 (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || in tcp_do_segment()
3136 (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { in tcp_do_segment()
3139 tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) in tcp_do_segment()
3141 tp->snd_wnd = tiwin; in tcp_do_segment()
3142 tp->snd_wl1 = th->th_seq; in tcp_do_segment()
3143 tp->snd_wl2 = th->th_ack; in tcp_do_segment()
3144 if (tp->snd_wnd > tp->max_sndwnd) in tcp_do_segment()
3145 tp->max_sndwnd = tp->snd_wnd; in tcp_do_segment()
3152 if ((thflags & TH_URG) && th->th_urp && in tcp_do_segment()
3153 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3161 if (th->th_urp + sbavail(&so->so_rcv) > sb_max) { in tcp_do_segment()
3162 th->th_urp = 0; /* XXX */ in tcp_do_segment()
3181 if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { in tcp_do_segment()
3182 tp->rcv_up = th->th_seq + th->th_urp; in tcp_do_segment()
3183 so->so_oobmark = sbavail(&so->so_rcv) + in tcp_do_segment()
3184 (tp->rcv_up - tp->rcv_nxt) - 1; in tcp_do_segment()
3185 if (so->so_oobmark == 0) in tcp_do_segment()
3186 so->so_rcv.sb_state |= SBS_RCVATMARK; in tcp_do_segment()
3188 tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); in tcp_do_segment()
3194 * but if two URG's are pending at once, some out-of-band in tcp_do_segment()
3197 if (th->th_urp <= (uint32_t)tlen && in tcp_do_segment()
3198 !(so->so_options & SO_OOBINLINE)) { in tcp_do_segment()
3208 if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) in tcp_do_segment()
3209 tp->rcv_up = tp->rcv_nxt; in tcp_do_segment()
3217 * This process logically involves adjusting tp->rcv_wnd as data in tcp_do_segment()
3222 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && in tcp_do_segment()
3223 (tp->t_flags & TF_FASTOPEN)); in tcp_do_segment()
3225 TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3226 tcp_seq save_start = th->th_seq; in tcp_do_segment()
3227 tcp_seq save_rnxt = tp->rcv_nxt; in tcp_do_segment()
3242 if (th->th_seq == tp->rcv_nxt && in tcp_do_segment()
3244 (TCPS_HAVEESTABLISHED(tp->t_state) || in tcp_do_segment()
3247 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3249 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3250 tp->rcv_nxt += tlen; in tcp_do_segment()
3252 ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && in tcp_do_segment()
3253 (tp->t_fbyte_in == 0)) { in tcp_do_segment()
3254 tp->t_fbyte_in = ticks; in tcp_do_segment()
3255 if (tp->t_fbyte_in == 0) in tcp_do_segment()
3256 tp->t_fbyte_in = 1; in tcp_do_segment()
3257 if (tp->t_fbyte_out && tp->t_fbyte_in) in tcp_do_segment()
3258 tp->t_flags2 |= TF2_FBYTES_COMPLETE; in tcp_do_segment()
3264 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) in tcp_do_segment()
3267 sbappendstream_locked(&so->so_rcv, m, 0); in tcp_do_segment()
3268 tp->t_flags |= TF_WAKESOR; in tcp_do_segment()
3279 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3281 if ((tp->t_flags & TF_SACK_PERMIT) && in tcp_do_segment()
3283 TCPS_HAVEESTABLISHED(tp->t_state)) { in tcp_do_segment()
3291 } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { in tcp_do_segment()
3292 if ((tp->rcv_numsacks >= 1) && in tcp_do_segment()
3293 (tp->sackblks[0].end == save_start)) { in tcp_do_segment()
3299 tp->sackblks[0].start, in tcp_do_segment()
3300 tp->sackblks[0].end); in tcp_do_segment()
3322 if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) in tcp_do_segment()
3323 len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); in tcp_do_segment()
3325 len = so->so_rcv.sb_hiwat; in tcp_do_segment()
3336 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3343 tcpstates[tp->t_state], tlen); in tcp_do_segment()
3352 tcpstates[tp->t_state]); in tcp_do_segment()
3366 if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { in tcp_do_segment()
3370 * If connection is half-synchronized in tcp_do_segment()
3376 if (tp->t_flags & TF_NEEDSYN) in tcp_do_segment()
3377 tp->t_flags |= TF_DELACK; in tcp_do_segment()
3379 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3380 tp->rcv_nxt++; in tcp_do_segment()
3382 switch (tp->t_state) { in tcp_do_segment()
3388 tp->t_starttime = ticks; in tcp_do_segment()
3404 * starting the time-wait timer, turning off the other in tcp_do_segment()
3417 if (needoutput || (tp->t_flags & TF_ACKNOW)) { in tcp_do_segment()
3423 if (tp->t_flags & TF_DELACK) { in tcp_do_segment()
3424 tp->t_flags &= ~TF_DELACK; in tcp_do_segment()
3439 * In the SYN-RECEIVED state, don't send an ACK unless the in tcp_do_segment()
3440 * segment we received passes the SYN-RECEIVED ACK test. in tcp_do_segment()
3446 if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && in tcp_do_segment()
3447 (SEQ_GT(tp->snd_una, th->th_ack) || in tcp_do_segment()
3448 SEQ_GT(th->th_ack, tp->snd_max)) ) { in tcp_do_segment()
3454 tp->t_flags |= TF_ACKNOW; in tcp_do_segment()
3500 if ((tcp_get_flags(th) & TH_RST) || m->m_flags & (M_BCAST|M_MCAST)) in tcp_dropwithreset()
3503 if (mtod(m, struct ip *)->ip_v == 6) { in tcp_dropwithreset()
3505 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || in tcp_dropwithreset()
3506 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) in tcp_dropwithreset()
3517 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in tcp_dropwithreset()
3518 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || in tcp_dropwithreset()
3519 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in tcp_dropwithreset()
3520 in_ifnet_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) in tcp_dropwithreset()
3532 th->th_ack, TH_RST); in tcp_dropwithreset()
3538 tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, in tcp_dropwithreset()
3554 to->to_flags = 0; in tcp_dooptions()
3555 for (; cnt > 0; cnt -= optlen, cp += optlen) { in tcp_dooptions()
3574 to->to_flags |= TOF_MSS; in tcp_dooptions()
3576 (char *)&to->to_mss, sizeof(to->to_mss)); in tcp_dooptions()
3577 to->to_mss = ntohs(to->to_mss); in tcp_dooptions()
3584 to->to_flags |= TOF_SCALE; in tcp_dooptions()
3585 to->to_wscale = min(cp[2], TCP_MAX_WINSHIFT); in tcp_dooptions()
3590 to->to_flags |= TOF_TS; in tcp_dooptions()
3592 (char *)&to->to_tsval, sizeof(to->to_tsval)); in tcp_dooptions()
3593 to->to_tsval = ntohl(to->to_tsval); in tcp_dooptions()
3595 (char *)&to->to_tsecr, sizeof(to->to_tsecr)); in tcp_dooptions()
3596 to->to_tsecr = ntohl(to->to_tsecr); in tcp_dooptions()
3608 to->to_flags |= TOF_SIGNATURE; in tcp_dooptions()
3609 to->to_signature = cp + 2; in tcp_dooptions()
3618 to->to_flags |= TOF_SACKPERM; in tcp_dooptions()
3621 if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) in tcp_dooptions()
3625 to->to_flags |= TOF_SACK; in tcp_dooptions()
3626 to->to_nsacks = (optlen - 2) / TCPOLEN_SACK; in tcp_dooptions()
3627 to->to_sacks = cp + 2; in tcp_dooptions()
3641 to->to_flags |= TOF_FASTOPEN; in tcp_dooptions()
3642 to->to_tfo_len = optlen - 2; in tcp_dooptions()
3643 to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL; in tcp_dooptions()
3661 int cnt = off + th->th_urp - 1; in tcp_pulloutofband()
3664 if (m->m_len > cnt) { in tcp_pulloutofband()
3670 tp->t_iobc = *cp; in tcp_pulloutofband()
3671 tp->t_oobflags |= TCPOOB_HAVEDATA; in tcp_pulloutofband()
3672 bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); in tcp_pulloutofband()
3673 m->m_len--; in tcp_pulloutofband()
3674 if (m->m_flags & M_PKTHDR) in tcp_pulloutofband()
3675 m->m_pkthdr.len--; in tcp_pulloutofband()
3678 cnt -= m->m_len; in tcp_pulloutofband()
3679 m = m->m_next; in tcp_pulloutofband()
3687 * Collect new round-trip time estimate
3691 tcp_xmit_timer(struct tcpcb *tp, int rtt) in tcp_xmit_timer() argument
3698 if (tp->t_rttupdated < UCHAR_MAX) in tcp_xmit_timer()
3699 tp->t_rttupdated++; in tcp_xmit_timer()
3701 stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, in tcp_xmit_timer()
3702 imax(0, rtt * 1000 / hz)); in tcp_xmit_timer()
3704 if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { in tcp_xmit_timer()
3709 * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed in tcp_xmit_timer()
3710 * point). Adjust rtt to origin 0. in tcp_xmit_timer()
3712 delta = ((rtt - 1) << TCP_DELTA_SHIFT) in tcp_xmit_timer()
3713 - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); in tcp_xmit_timer()
3715 if ((tp->t_srtt += delta) <= 0) in tcp_xmit_timer()
3716 tp->t_srtt = 1; in tcp_xmit_timer()
3719 * We accumulate a smoothed rtt variance (actually, a in tcp_xmit_timer()
3721 * timer to smoothed rtt + 4 times the smoothed variance. in tcp_xmit_timer()
3726 * rfc793's wired-in beta. in tcp_xmit_timer()
3729 delta = -delta; in tcp_xmit_timer()
3730 delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); in tcp_xmit_timer()
3731 if ((tp->t_rttvar += delta) <= 0) in tcp_xmit_timer()
3732 tp->t_rttvar = 1; in tcp_xmit_timer()
3735 * No rtt measurement yet - use the unsmoothed rtt. in tcp_xmit_timer()
3736 * Set the variance to half the rtt (so our first in tcp_xmit_timer()
3737 * retransmit happens at 3*rtt). in tcp_xmit_timer()
3739 tp->t_srtt = rtt << TCP_RTT_SHIFT; in tcp_xmit_timer()
3740 tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); in tcp_xmit_timer()
3742 tp->t_rtttime = 0; in tcp_xmit_timer()
3743 tp->t_rxtshift = 0; in tcp_xmit_timer()
3746 * the retransmit should happen at rtt + 4 * rttvar. in tcp_xmit_timer()
3749 * the retransmit timer, we want 1/2 tick of rounding and in tcp_xmit_timer()
3750 * 1 extra tick because of +-1/2 tick uncertainty in the in tcp_xmit_timer()
3751 * firing of the timer. The bias will give us exactly the in tcp_xmit_timer()
3754 * the minimum feasible timer (which is 2 ticks). in tcp_xmit_timer()
3756 TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), in tcp_xmit_timer()
3757 max(tp->t_rttmin, rtt + 2), TCPTV_REXMTMAX); in tcp_xmit_timer()
3766 tp->t_softerror = 0; in tcp_xmit_timer()
3779 * While looking at the routing entry, we also initialize other path-dependent
3780 * parameters from pre-set or cached values in the routing entry.
3799 int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; in tcp_mss_update()
3809 if (tp->t_port) in tcp_mss_update()
3811 if (mtuoffer != -1) { in tcp_mss_update()
3812 KASSERT(offer == -1, ("%s: conflict", __func__)); in tcp_mss_update()
3813 offer = mtuoffer - min_protoh; in tcp_mss_update()
3819 maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); in tcp_mss_update()
3820 tp->t_maxseg = V_tcp_v6mssdflt; in tcp_mss_update()
3828 maxmtu = tcp_maxmtu(&inp->inp_inc, cap); in tcp_mss_update()
3829 tp->t_maxseg = V_tcp_mssdflt; in tcp_mss_update()
3855 offer = tp->t_maxseg; in tcp_mss_update()
3858 case -1: in tcp_mss_update()
3860 * Offer == -1 means that we didn't receive SYN yet. in tcp_mss_update()
3874 tcp_hc_get(&inp->inp_inc, metricptr); in tcp_mss_update()
3880 if (metricptr->hc_mtu) in tcp_mss_update()
3881 mss = min(metricptr->hc_mtu, maxmtu) - min_protoh; in tcp_mss_update()
3885 mss = maxmtu - min_protoh; in tcp_mss_update()
3887 !in6_localaddr(&inp->in6p_faddr)) in tcp_mss_update()
3896 mss = maxmtu - min_protoh; in tcp_mss_update()
3898 !in_localaddr(inp->inp_faddr)) in tcp_mss_update()
3903 * XXX - The above conditional (mss = maxmtu - min_protoh) in tcp_mss_update()
3933 tp->t_maxseg = mss; in tcp_mss_update()
3934 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss_update()
3940 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3942 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss_update()
3960 tcp_mss_update(tp, offer, -1, &metrics, &cap); in tcp_mss()
3962 mss = tp->t_maxseg; in tcp_mss()
3971 so = inp->inp_socket; in tcp_mss()
3973 if ((so->so_snd.sb_hiwat == V_tcp_sendspace) && metrics.hc_sendpipe) in tcp_mss()
3976 bufsize = so->so_snd.sb_hiwat; in tcp_mss()
3983 if (bufsize > so->so_snd.sb_hiwat) in tcp_mss()
3995 tp->t_maxseg = max(mss, 64); in tcp_mss()
3996 if (tp->t_maxseg < V_tcp_mssdflt) { in tcp_mss()
4002 tp->t_flags2 |= TF2_PROC_SACK_PROHIBIT; in tcp_mss()
4004 tp->t_flags2 &= ~TF2_PROC_SACK_PROHIBIT; in tcp_mss()
4008 if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.hc_recvpipe) in tcp_mss()
4011 bufsize = so->so_rcv.sb_hiwat; in tcp_mss()
4016 if (bufsize > so->so_rcv.sb_hiwat) in tcp_mss()
4023 tp->t_flags |= TF_TSO; in tcp_mss()
4024 tp->t_tsomax = cap.tsomax; in tcp_mss()
4025 tp->t_tsomaxsegcount = cap.tsomaxsegcount; in tcp_mss()
4026 tp->t_tsomaxsegsize = cap.tsomaxsegsize; in tcp_mss()
4028 tp->t_flags2 |= TF2_IPSEC_TSO; in tcp_mss()
4046 if (inc->inc_flags & INC_ISIPV6) { in tcp_mssopt()
4067 mss = min(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4069 mss = max(maxmtu, thcmtu) - min_protoh; in tcp_mssopt()
4093 (IN_CONGRECOVERY(tp->t_flags) && in tcp_do_prr_ack()
4094 !IN_FASTRECOVERY(tp->t_flags))) { in tcp_do_prr_ack()
4095 del_data = tp->sackhint.delivered_data; in tcp_do_prr_ack()
4098 if (tp->sackhint.prr_delivered < (tcprexmtthresh * maxseg + in tcp_do_prr_ack()
4099 tp->snd_recover - tp->snd_una)) { in tcp_do_prr_ack()
4102 pipe = imax(0, tp->snd_max - tp->snd_una - in tcp_do_prr_ack()
4103 imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); in tcp_do_prr_ack()
4105 tp->sackhint.prr_delivered += del_data; in tcp_do_prr_ack()
4109 if (pipe >= tp->snd_ssthresh) { in tcp_do_prr_ack()
4110 if (tp->sackhint.recover_fs == 0) in tcp_do_prr_ack()
4111 tp->sackhint.recover_fs = in tcp_do_prr_ack()
4112 imax(1, tp->snd_nxt - tp->snd_una); in tcp_do_prr_ack()
4113 snd_cnt = howmany((long)tp->sackhint.prr_delivered * in tcp_do_prr_ack()
4114 tp->snd_ssthresh, tp->sackhint.recover_fs) - in tcp_do_prr_ack()
4115 tp->sackhint.prr_out + maxseg - 1; in tcp_do_prr_ack()
4119 * - A partial ack without SACK block beneath snd_recover in tcp_do_prr_ack()
4121 * - An SACK scoreboard update adding a new hole indicates in tcp_do_prr_ack()
4124 * - Prevent ACK splitting attacks, by being conservative in tcp_do_prr_ack()
4128 limit = tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4129 tp->sackhint.prr_out; in tcp_do_prr_ack()
4131 limit = imax(tp->sackhint.prr_delivered - in tcp_do_prr_ack()
4132 tp->sackhint.prr_out, del_data) + in tcp_do_prr_ack()
4135 snd_cnt = imin((tp->snd_ssthresh - pipe), limit); in tcp_do_prr_ack()
4143 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4145 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4147 tp->snd_cwnd = (tp->snd_max - tp->snd_una) + in tcp_do_prr_ack()
4150 } else if (IN_CONGRECOVERY(tp->t_flags)) { in tcp_do_prr_ack()
4151 tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); in tcp_do_prr_ack()
4153 tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); in tcp_do_prr_ack()
4158 * next unacknowledged segment. Do not clear tp->t_dupacks.
4159 * By setting snd_nxt to ti_ack, this forces retransmission timer to
4165 tcp_seq onxt = tp->snd_nxt; in tcp_newreno_partial_ack()
4166 uint32_t ocwnd = tp->snd_cwnd; in tcp_newreno_partial_ack()
4172 tp->t_rtttime = 0; in tcp_newreno_partial_ack()
4173 if (IN_FASTRECOVERY(tp->t_flags)) { in tcp_newreno_partial_ack()
4174 tp->snd_nxt = th->th_ack; in tcp_newreno_partial_ack()
4177 * (tp->snd_una has not yet been updated when this function is called.) in tcp_newreno_partial_ack()
4179 tp->snd_cwnd = maxseg + BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4180 tp->t_flags |= TF_ACKNOW; in tcp_newreno_partial_ack()
4182 tp->snd_cwnd = ocwnd; in tcp_newreno_partial_ack()
4183 if (SEQ_GT(onxt, tp->snd_nxt)) in tcp_newreno_partial_ack()
4184 tp->snd_nxt = onxt; in tcp_newreno_partial_ack()
4187 * Partial window deflation. Relies on fact that tp->snd_una in tcp_newreno_partial_ack()
4190 if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) in tcp_newreno_partial_ack()
4191 tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); in tcp_newreno_partial_ack()
4193 tp->snd_cwnd = 0; in tcp_newreno_partial_ack()
4194 tp->snd_cwnd += maxseg; in tcp_newreno_partial_ack()
4202 if (tp->t_fb->tfb_compute_pipe != NULL) { in tcp_compute_pipe()
4203 pipe = (*tp->t_fb->tfb_compute_pipe)(tp); in tcp_compute_pipe()
4205 pipe = tp->snd_max - tp->snd_una + in tcp_compute_pipe()
4206 tp->sackhint.sack_bytes_rexmit - in tcp_compute_pipe()
4207 tp->sackhint.sacked_bytes - in tcp_compute_pipe()
4208 tp->sackhint.lost_bytes; in tcp_compute_pipe()
4210 pipe = tp->snd_nxt - tp->snd_fack + tp->sackhint.sack_bytes_rexmit; in tcp_compute_pipe()