Lines Matching defs:tcp

26  * tcp.c, Code implementing the TCP protocol.
40 #include <netinet/tcp.h>
111 tcp_t *tcp;
229 #define SET_WS_VALUE(tcp) \
232 uint32_t rwnd = (tcp)->tcp_rwnd; \
236 (tcp)->tcp_rcv_ws = i; \
246 #define SET_ECT(tcp, iph) \
247 if ((tcp)->tcp_ipversion == IPV4_VERSION) { \
276 #define TCP_TIMER_RESTART(tcp, intvl) \
277 (tcp)->tcp_rto_timeout = prom_gettime() + intvl; \
278 (tcp)->tcp_timer_running = B_TRUE;
468 tcp_drain_input(tcp_t *tcp, int sock_id, int timeout)
477 tcp_display(tcp, NULL, DISP_ADDR_AND_PORT));
522 tcp_rput_data(tcp, mp, sock_id);
532 tcp = NULL;
535 if (tcp == NULL || sockets[sock_id].pcb == NULL) {
550 tcp_drain_needed(sock_id, tcp);
565 tcp_t *tcp;
569 if ((tcp = sockets[sock_id].pcb) == NULL)
585 tcp_rput_data(tcp, mp, sock_id);
592 if (tcp->tcp_rcv_list != NULL) {
593 tcp_rcv_drain(sock_id, tcp);
596 if (tcp->tcp_state == TCPS_CLOSE_WAIT) {
610 tcp_send(int sock_id, tcp_t *tcp, const void *msg, int len)
615 int mss = tcp->tcp_mss;
636 if ((mp = allocb(mss + tcp->tcp_ip_hdr_len +
640 mp->b_rptr += tcp->tcp_hdr_len + tcp_wroff_xtra;
672 win_size = (tcp->tcp_swnd > tcp->tcp_cwnd) ? tcp->tcp_cwnd :
673 tcp->tcp_swnd;
674 win_size -= tcp->tcp_snxt;
675 win_size += tcp->tcp_suna;
676 if (win_size < (2 * tcp->tcp_mss))
677 if (tcp_drain_input(tcp, sock_id, 5) < 0)
680 tcp_wput_data(tcp, head, sock_id);
696 tcp_free(tcp_t *tcp)
698 if (tcp->tcp_iphc != NULL) {
699 bkmem_free((caddr_t)tcp->tcp_iphc, tcp->tcp_iphc_len);
700 tcp->tcp_iphc = NULL;
702 if (tcp->tcp_xmit_head != NULL) {
703 freemsg(tcp->tcp_xmit_head);
704 tcp->tcp_xmit_head = NULL;
706 if (tcp->tcp_rcv_list != NULL) {
707 freemsg(tcp->tcp_rcv_list);
708 tcp->tcp_rcv_list = NULL;
710 if (tcp->tcp_reass_head != NULL) {
711 freemsg(tcp->tcp_reass_head);
712 tcp->tcp_reass_head = NULL;
714 if (tcp->tcp_sack_info != NULL) {
715 bkmem_free((caddr_t)tcp->tcp_sack_info,
717 tcp->tcp_sack_info = NULL;
722 tcp_close_detached(tcp_t *tcp)
724 if (tcp->tcp_listener != NULL)
725 tcp_eager_unlink(tcp);
726 tcp_free(tcp);
727 bkmem_free((caddr_t)tcp, sizeof (tcp_t));
736 tcp_eager_unlink(tcp_t *tcp)
738 tcp_t *listener = tcp->tcp_listener;
741 if (tcp->tcp_eager_next_q0 != NULL) {
742 assert(tcp->tcp_eager_prev_q0 != NULL);
744 /* Remove the eager tcp from q0 */
745 tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
746 tcp->tcp_eager_prev_q0;
747 tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
748 tcp->tcp_eager_next_q0;
755 if (tcpp[0] == tcp) {
756 if (listener->tcp_eager_last_q == tcp) {
763 assert(tcp->tcp_eager_next_q == NULL);
779 tcpp[0] = tcp->tcp_eager_next_q;
780 tcp->tcp_eager_next_q = NULL;
781 tcp->tcp_eager_last_q = NULL;
788 tcp->tcp_listener = NULL;
825 tcp_t *tcp;
829 if ((tcp = sockets[sock_id].pcb) == NULL) {
838 if (tcp_drain_input(tcp, sock_id, 5) < 0) {
844 tcp_clean_death(sock_id, tcp, 0);
848 DEBUG_1("tcp_shutdown: tcp_state %x\n", tcp->tcp_state);
849 switch (tcp->tcp_state) {
862 if (tcp_xmit_end(tcp, sock_id) == 0 &&
863 tcp_state_wait(sock_id, tcp, TCPS_FIN_WAIT_2) < 0) {
883 tcp_t *tcp;
886 if ((tcp = sockets[sock_id].pcb) == NULL) {
897 if (tcp_drain_input(tcp, sock_id, 5) < 0) {
903 tcp_clean_death(sock_id, tcp, 0);
907 if (tcp->tcp_conn_req_cnt_q0 != 0 || tcp->tcp_conn_req_cnt_q != 0) {
909 tcp_eager_cleanup(tcp, 0, sock_id);
913 switch (tcp->tcp_state) {
935 if (tcp->tcp_linger && tcp->tcp_lingertime == 0) {
943 if (tcp->tcp_rcv_list != NULL ||
944 tcp->tcp_reass_head != NULL) {
948 if (tcp->tcp_state <= TCPS_LISTEN)
958 (void) tcp_xmit_end(tcp, sock_id);
966 if (tcp->tcp_linger && tcp->tcp_lingertime > 0 &&
967 !(tcp->tcp_fin_acked) &&
968 tcp->tcp_state >= TCPS_ESTABLISHED) {
971 tcp->tcp_client_errno = 0;
973 (tcp->tcp_lingertime * 1000);
974 while (!(tcp->tcp_fin_acked) &&
975 tcp->tcp_state >= TCPS_ESTABLISHED &&
976 tcp->tcp_client_errno == 0 &&
978 if (tcp_drain_input(tcp, sock_id, 5) < 0) {
981 tcp, 0);
986 tcp->tcp_client_errno = 0;
988 if (tcp_state_wait(sock_id, tcp, TCPS_TIME_WAIT) < 0) {
1001 if (tcp->tcp_state == TCPS_ESTABLISHED ||
1002 tcp->tcp_state == TCPS_CLOSE_WAIT)
1004 if (tcp->tcp_state == TCPS_SYN_SENT ||
1005 tcp->tcp_state == TCPS_SYN_RCVD)
1007 tcp_xmit_ctl(msg, tcp, NULL, tcp->tcp_snxt, 0, TH_RST, 0,
1011 tcp_free(tcp);
1012 bkmem_free((caddr_t)tcp, sizeof (tcp_t));
1021 tcp_t *tcp;
1023 if ((tcp = (tcp_t *)(sockets[sock_id].pcb)) == NULL) {
1028 if (tcp->tcp_state > TCPS_LISTEN || tcp->tcp_state < TCPS_BOUND) {
1033 if (tcp->tcp_state != TCPS_LISTEN) {
1034 tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
1035 tcp->tcp_eager_next_q = NULL;
1036 tcp->tcp_state = TCPS_LISTEN;
1037 tcp->tcp_second_ctimer_threshold = tcp_ip_abort_linterval;
1039 if ((tcp->tcp_conn_req_max = backlog) > tcp_conn_req_max_q) {
1040 tcp->tcp_conn_req_max = tcp_conn_req_max_q;
1042 if (tcp->tcp_conn_req_max < tcp_conn_req_min) {
1043 tcp->tcp_conn_req_max = tcp_conn_req_min;
1141 tcp_t *tcp;
1147 ((tcp = (tcp_t *)sockets[i].pcb) == NULL) ||
1148 ntohs(tcp->tcp_lport) != port) {
1156 if (reuseaddr && tcp->tcp_state > TCPS_LISTEN) {
1159 if (tcp->tcp_bound_source != INADDR_ANY &&
1161 tcp->tcp_bound_source != *addr) {
1181 tcp_t *tcp;
1186 if ((tcp = (tcp_t *)sockets[sock_id].pcb) == NULL) {
1191 if (tcp->tcp_state >= TCPS_BOUND) {
1200 tcp->tcp_bound_source = sockets[sock_id].bind.sin_addr.s_addr;
1202 tcp->tcp_ipha->ip_src.s_addr = tcp->tcp_bound_source;
1214 allocated_port = tcp_bindi(requested_port, &(tcp->tcp_bound_source),
1221 tcp->tcp_lport = htons(allocated_port);
1222 *(uint16_t *)tcp->tcp_tcph->th_lport = tcp->tcp_lport;
1223 sockets[sock_id].bind.sin_port = tcp->tcp_lport;
1224 tcp->tcp_state = TCPS_BOUND;
1232 tcp_conn_check(tcp_t *tcp)
1246 if (tmp_tcp->tcp_lport != tcp->tcp_lport ||
1247 tmp_tcp->tcp_fport != tcp->tcp_fport ||
1248 tmp_tcp->tcp_bound_source != tcp->tcp_bound_source ||
1249 tmp_tcp->tcp_remote != tcp->tcp_remote) {
1262 tcp_t *tcp;
1269 if ((tcp = (tcp_t *)(sockets[sock_id].pcb)) == NULL) {
1307 if (tcp->tcp_bound_source == INADDR_ANY) {
1315 tcp->tcp_bound_source = sockets[sock_id].bind.sin_addr.s_addr;
1316 tcp->tcp_ipha->ip_src.s_addr = tcp->tcp_bound_source;
1322 if (dstaddr == tcp->tcp_ipha->ip_src.s_addr &&
1323 dstport == tcp->tcp_lport) {
1328 tcp->tcp_ipha->ip_dst.s_addr = dstaddr;
1329 tcp->tcp_remote = dstaddr;
1330 tcph = tcp->tcp_tcph;
1332 tcp->tcp_fport = dstport;
1338 if (tcp_conn_check(tcp) < 0) {
1354 mss = tcp->tcp_mss - tcp->tcp_hdr_len;
1355 tcp->tcp_rwnd = MAX(MSS_ROUNDUP(tcp->tcp_rwnd, mss),
1357 tcp->tcp_rwnd_max = tcp->tcp_rwnd;
1358 SET_WS_VALUE(tcp);
1359 U32_TO_ABE16((tcp->tcp_rwnd >> tcp->tcp_rcv_ws),
1360 tcp->tcp_tcph->th_win);
1361 if (tcp->tcp_rcv_ws > 0 || tcp_wscale_always)
1362 tcp->tcp_snd_ws_ok = B_TRUE;
1371 (tcp->tcp_rcv_ws && tcp_tstamp_if_wscale)) {
1372 tcp->tcp_snd_ts_ok = B_TRUE;
1376 tcp->tcp_snd_sack_ok) {
1377 assert(tcp->tcp_sack_info == NULL);
1378 if ((tcp->tcp_sack_info = (tcp_sack_info_t *)bkmem_zalloc(
1380 tcp->tcp_snd_sack_ok = B_FALSE;
1382 tcp->tcp_snd_sack_ok = B_TRUE;
1394 tcp->tcp_ecn_ok = B_TRUE;
1396 tcp_iss_init(tcp);
1397 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
1398 tcp->tcp_active_open = B_TRUE;
1400 tcp->tcp_state = TCPS_SYN_SENT;
1401 syn_mp = tcp_xmit_mp(tcp, NULL, 0, NULL, NULL, tcp->tcp_iss, B_FALSE,
1421 return (tcp_state_wait(sock_id, tcp, TCPS_ESTABLISHED));
1571 tcp_drop_q0(tcp_t *tcp)
1575 assert(tcp->tcp_eager_next_q0 != tcp->tcp_eager_prev_q0);
1582 eager = tcp->tcp_eager_prev_q0;
1586 if (eager == tcp) {
1587 eager = tcp->tcp_eager_prev_q0;
1593 tcp->tcp_conn_req_cnt_q0,
1594 tcp_display(tcp, NULL, DISP_PORT_ONLY));
1603 tcp_conn_request(tcp_t *tcp, mblk_t *mp, uint_t sock_id, uint_t ip_hdr_len)
1613 if (tcp->tcp_conn_req_cnt_q >= tcp->tcp_conn_req_max) {
1617 tcp->tcp_conn_req_max, tcp->tcp_conn_req_cnt_q,
1618 tcp_display(tcp, NULL, DISP_PORT_ONLY));
1624 if (tcp->tcp_conn_req_cnt_q0 >=
1625 tcp->tcp_conn_req_max + tcp_conn_req_max_q0) {
1631 tcp->tcp_last_rcv_lbolt = prom_gettime();
1632 if (!tcp_drop_q0(tcp)) {
1638 tcp->tcp_conn_req_cnt_q0,
1639 tcp_display(tcp, NULL, DISP_PORT_ONLY));
1654 * by generating a detached tcp state vector and put it in
1674 eager->tcp_family = tcp->tcp_family;
1676 err = tcp_accept_comm(tcp, eager, mp, ip_hdr_len);
1682 tcp->tcp_eager_next_q0->tcp_eager_prev_q0 = eager;
1683 eager->tcp_eager_next_q0 = tcp->tcp_eager_next_q0;
1684 tcp->tcp_eager_next_q0 = eager;
1685 eager->tcp_eager_prev_q0 = tcp;
1688 eager->tcp_listener = tcp;
1689 tcp->tcp_conn_req_cnt_q0++;
1700 tcp_state_wait(int sock_id, tcp_t *tcp, int state)
1715 if (timeout > tcp->tcp_rto) {
1716 sockets[sock_id].in_timeout = tcp->tcp_rto;
1736 if (tcp != NULL && tcp->tcp_state == state)
1752 tcp_rput_data(tcp, mp, sock_id);
1761 tcp = NULL;
1766 if (tcp == NULL || sockets[sock_id].pcb == NULL) {
1781 if ((state == TCPS_ALL_ACKED) && (tcp->tcp_suna == tcp->tcp_snxt)) {
1784 if (tcp->tcp_state != state) {
1785 if (prom_gettime() > tcp->tcp_rto_timeout)
1786 tcp_timer(tcp, sock_id);
1793 tcp_drain_needed(sock_id, tcp);
1832 tcp_t *tcp;
1836 (tcp = (tcp_t *)sockets[i].pcb) != NULL) {
1837 if (tcph->tha_lport == tcp->tcp_fport &&
1838 tcph->tha_fport == tcp->tcp_lport &&
1839 iph->ip_src.s_addr == tcp->tcp_remote &&
1840 iph->ip_dst.s_addr == tcp->tcp_bound_source &&
1841 tcp->tcp_state >= min_state) {
1843 return (tcp);
1848 for (tcp = tcp_time_wait_head; tcp != NULL;
1849 tcp = tcp->tcp_time_wait_next) {
1850 if (tcph->tha_lport == tcp->tcp_fport &&
1851 tcph->tha_fport == tcp->tcp_lport &&
1852 iph->ip_src.s_addr == tcp->tcp_remote &&
1853 iph->ip_dst.s_addr == tcp->tcp_bound_source &&
1854 tcp->tcp_state >= min_state) {
1856 return (tcp);
1867 tcp_t *tcp;
1871 (tcp = (tcp_t *)sockets[i].pcb) != NULL) {
1872 if (tcp->tcp_lport == port &&
1873 (tcp->tcp_bound_source == addr ||
1874 tcp->tcp_bound_source == INADDR_ANY)) {
1876 return (tcp);
1888 tcp_t *tcp;
1893 for (tcp = listener->tcp_eager_next_q; tcp != NULL;
1894 tcp = tcp->tcp_eager_next_q) {
1895 if (tcph->tha_lport == tcp->tcp_fport &&
1896 tcph->tha_fport == tcp->tcp_lport &&
1897 iph->ip_src.s_addr == tcp->tcp_remote &&
1898 iph->ip_dst.s_addr == tcp->tcp_bound_source) {
1899 return (tcp);
1903 for (tcp = listener->tcp_eager_next_q0; tcp != listener;
1904 tcp = tcp->tcp_eager_next_q0) {
1905 if (tcph->tha_lport == tcp->tcp_fport &&
1906 tcph->tha_fport == tcp->tcp_lport &&
1907 iph->ip_src.s_addr == tcp->tcp_remote &&
1908 iph->ip_dst.s_addr == tcp->tcp_bound_source) {
1909 return (tcp);
1920 tcp_clean_death(int sock_id, tcp_t *tcp, int err)
1922 tcp_free(tcp);
1923 if (tcp->tcp_state == TCPS_TIME_WAIT)
1924 tcp_time_wait_remove(tcp);
1931 bkmem_free((caddr_t)tcp, sizeof (tcp_t));
1954 tcp_rwnd_set(tcp_t *tcp, uint32_t rwnd)
1956 uint32_t mss = tcp->tcp_mss;
1960 if (tcp->tcp_rwnd_max != 0)
1961 old_max_rwnd = tcp->tcp_rwnd_max;
1963 old_max_rwnd = tcp->tcp_rwnd;
1979 if (rwnd < old_max_rwnd && tcp->tcp_state > TCPS_SYN_SENT) {
1988 max_transmittable_rwnd = TCP_MAXWIN << tcp->tcp_rcv_ws;
1999 tcp->tcp_rwnd = old_max_rwnd = rwnd;
2007 tcp->tcp_rwnd += rwnd - old_max_rwnd;
2008 U32_TO_ABE16(tcp->tcp_rwnd >> tcp->tcp_rcv_ws, tcp->tcp_tcph->th_win);
2009 if ((tcp->tcp_rcv_ws > 0) && rwnd > tcp->tcp_cwnd_max)
2010 tcp->tcp_cwnd_max = rwnd;
2011 tcp->tcp_rwnd_max = rwnd;
2017 * Extract option values from a tcp header. We put any found values into the
2030 tcp_t *tcp;
2083 if ((tcp = tcpopt->tcp) == NULL) {
2094 assert(tcp->tcp_sack_info != NULL);
2095 if (tcp->tcp_notsack_list == NULL) {
2096 tcp_notsack_update(&(tcp->tcp_notsack_list),
2097 tcp->tcp_suna, tcp->tcp_snxt,
2098 &(tcp->tcp_num_notsack_blk),
2099 &(tcp->tcp_cnt_notsack_list));
2106 if (tcp->tcp_notsack_list == NULL) {
2110 tcp->tcp_fack = tcp->tcp_suna;
2131 SEQ_LT(sack_begin, tcp->tcp_suna) ||
2132 SEQ_GT(sack_end, tcp->tcp_snxt)) {
2135 tcp_notsack_insert(&(tcp->tcp_notsack_list),
2137 &(tcp->tcp_num_notsack_blk),
2138 &(tcp->tcp_cnt_notsack_list));
2139 if (SEQ_GT(sack_end, tcp->tcp_fack)) {
2140 tcp->tcp_fack = sack_end;
2171 * Set the mss associated with a particular tcp based on its current value,
2183 tcp_mss_set(tcp_t *tcp, uint32_t mss)
2198 if (mss < tcp->tcp_naglim || tcp->tcp_mss == tcp->tcp_naglim)
2199 tcp->tcp_naglim = mss;
2204 if ((mss << 2) > tcp->tcp_xmit_hiwater)
2205 tcp->tcp_xmit_hiwater = mss << 2;
2206 tcp->tcp_mss = mss;
2216 tcp->tcp_cwnd = MIN(tcp_slow_start_initial * mss,
2218 tcp->tcp_cwnd_cnt = 0;
2231 tcp_process_options(tcp_t *tcp, tcph_t *tcph)
2238 tcpopt.tcp = NULL;
2250 if (tcp->tcp_ipversion == IPV4_VERSION)
2260 tcp->tcp_snd_ws = tcpopt.tcp_opt_wscale;
2261 tcp->tcp_snd_ws_ok = B_TRUE;
2263 tcp->tcp_snd_ws = B_FALSE;
2264 tcp->tcp_snd_ws_ok = B_FALSE;
2265 tcp->tcp_rcv_ws = B_FALSE;
2270 (tcp->tcp_snd_ts_ok || !tcp->tcp_active_open)) {
2271 tmp_tcph = (char *)tcp->tcp_tcph;
2273 tcp->tcp_snd_ts_ok = B_TRUE;
2274 tcp->tcp_ts_recent = tcpopt.tcp_opt_ts_val;
2275 tcp->tcp_last_rcv_lbolt = prom_gettime();
2277 assert(tcp->tcp_tcp_hdr_len == TCP_MIN_HEADER_LENGTH);
2280 tmp_tcph += tcp->tcp_tcp_hdr_len;
2285 tcp->tcp_hdr_len += TCPOPT_REAL_TS_LEN;
2286 tcp->tcp_tcp_hdr_len += TCPOPT_REAL_TS_LEN;
2287 tcp->tcp_tcph->th_offset_and_rsrvd[0] += (3 << 4);
2289 tcp->tcp_snd_ts_ok = B_FALSE;
2297 (tcp->tcp_snd_sack_ok ||
2298 (tcp_sack_permitted != 0 && !tcp->tcp_active_open))) {
2300 if (tcp->tcp_sack_info == NULL) {
2301 tcp->tcp_sack_info = (tcp_sack_info_t *)bkmem_zalloc(
2304 if (tcp->tcp_sack_info == NULL) {
2305 tcp->tcp_snd_sack_ok = B_FALSE;
2307 tcp->tcp_snd_sack_ok = B_TRUE;
2308 if (tcp->tcp_snd_ts_ok) {
2309 tcp->tcp_max_sack_blk = 3;
2311 tcp->tcp_max_sack_blk = 4;
2322 if (tcp->tcp_sack_info != NULL) {
2323 bkmem_free((caddr_t)tcp->tcp_sack_info,
2325 tcp->tcp_sack_info = NULL;
2327 tcp->tcp_snd_sack_ok = B_FALSE;
2334 tcp->tcp_mss -= tcp->tcp_hdr_len;
2342 tcpopt.tcp_opt_mss -= tcp->tcp_hdr_len -
2356 tcp_mss_set(tcp, MIN(tcpopt.tcp_opt_mss, tcp->tcp_mss));
2364 tcp_paws_check(tcp_t *tcp, tcph_t *tcph, tcp_opt_t *tcpoptp)
2386 if (tcp->tcp_snd_sack_ok) {
2387 tcpoptp->tcp = tcp;
2389 tcpoptp->tcp = NULL;
2401 tcp->tcp_ts_recent)) {
2403 tcp->tcp_last_rcv_lbolt + PAWS_TIMEOUT)) {
2412 tcp->tcp_ts_recent =
2422 tcp->tcp_snd_ts_ok = B_FALSE;
2424 tcp->tcp_hdr_len -= TCPOPT_REAL_TS_LEN;
2425 tcp->tcp_tcp_hdr_len -= TCPOPT_REAL_TS_LEN;
2426 tcp->tcp_tcph->th_offset_and_rsrvd[0] -= (3 << 4);
2427 tcp_mss_set(tcp, tcp->tcp_mss + TCPOPT_REAL_TS_LEN);
2428 if (tcp->tcp_snd_sack_ok) {
2429 assert(tcp->tcp_sack_info != NULL);
2430 tcp->tcp_max_sack_blk = 4;
2441 * tcp_t *tcp: the tcp instance pointer.
2450 tcp_get_seg_mp(tcp_t *tcp, uint32_t seq, int32_t *off)
2456 if (SEQ_LT(seq, tcp->tcp_suna) || SEQ_GEQ(seq, tcp->tcp_snxt) ||
2460 cnt = seq - tcp->tcp_suna;
2461 mp = tcp->tcp_xmit_head;
2485 * tcp_t *tcp: the tcp structure of the connection.
2491 tcp_sack_rxmit(tcp_t *tcp, int sock_id)
2499 assert(tcp->tcp_sack_info != NULL);
2500 assert(tcp->tcp_notsack_list != NULL);
2501 assert(tcp->tcp_rexmit == B_FALSE);
2504 if (tcp->tcp_notsack_list == NULL) {
2507 notsack_blk = tcp->tcp_notsack_list;
2508 mss = tcp->tcp_mss;
2514 usable_swnd = tcp->tcp_cwnd_ssthresh - tcp->tcp_pipe;
2522 tcp->tcp_csuna = tcp->tcp_snxt;
2524 notsack_blk = tcp->tcp_notsack_list;
2527 tcp_seq begin = tcp->tcp_sack_snxt;
2548 usable_swnd = tcp->tcp_cwnd_ssthresh - tcp->tcp_pipe;
2550 tcp->tcp_cwnd = tcp->tcp_snxt - tcp->tcp_suna;
2551 assert(tcp->tcp_cwnd > 0);
2555 tcp->tcp_cwnd = tcp->tcp_snxt - tcp->tcp_suna +
2568 snxt_mp = tcp_get_seg_mp(tcp, begin, &off);
2575 xmit_mp = tcp_xmit_mp(tcp, snxt_mp, seg_len, &off,
2582 tcp->tcp_pipe += seg_len;
2583 tcp->tcp_sack_snxt = begin + seg_len;
2604 if (SEQ_GT(tcp->tcp_sack_snxt, tcp->tcp_rexmit_max)) {
2605 tcp->tcp_rexmit_max = tcp->tcp_sack_snxt;
2612 tcp_rput_data(tcp_t *tcp, mblk_t *mp, int sock_id)
2680 if (tcp == NULL ||
2681 tcph->tha_lport != tcp->tcp_fport ||
2682 tcph->tha_fport != tcp->tcp_lport ||
2683 iph->ip_src.s_addr != tcp->tcp_remote ||
2684 iph->ip_dst.s_addr != tcp->tcp_bound_source) {
2687 tcp->tcp_state);
2703 if ((tcp = tcp_lookup_eager_ipv4(tcp1,
2711 tcp = tcp1;
2716 tcp_display(tcp, NULL,
2727 tcp = tcp1;
2741 if (tcp->tcp_state == TCPS_TIME_WAIT) {
2742 tcp_time_wait_processing(tcp, mp, seg_seq, seg_ack,
2747 * From this point we can assume that the tcp is not compressed,
2751 assert(tcp != NULL && tcp->tcp_state != TCPS_TIME_WAIT);
2757 tcp->tcp_last_recv_time = prom_gettime();
2768 switch (tcp->tcp_state) {
2788 if (tcp->tcp_conn_req_max > 0) {
2789 tcp = tcp_conn_request(tcp, mp, sock_id, ip_hdr_len);
2790 if (tcp == NULL) {
2795 printf("tcp_rput_data: new tcp created\n");
2798 tcp->tcp_irs = seg_seq;
2799 tcp->tcp_rack = seg_seq;
2800 tcp->tcp_rnxt = seg_seq + 1;
2801 U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
2812 if (SEQ_LEQ(seg_ack, tcp->tcp_iss) ||
2813 SEQ_GT(seg_ack, tcp->tcp_snxt)) {
2819 tcp, mp, seg_ack, 0, TH_RST,
2823 assert(tcp->tcp_suna + 1 == seg_ack);
2828 tcp_clean_death(sock_id, tcp, ECONNREFUSED);
2838 tcp_process_options(tcp, (tcph_t *)tcph);
2843 (void) tcp_rwnd_set(tcp, MSS_ROUNDUP(tcp->tcp_rwnd,
2844 tcp->tcp_mss));
2847 if (tcp->tcp_ecn_ok) {
2849 tcp->tcp_ecn_ok = B_FALSE;
2858 tcp->tcp_irs = seg_seq;
2859 tcp->tcp_rack = seg_seq;
2860 tcp->tcp_rnxt = seg_seq + 1;
2861 U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
2865 tcp->tcp_suna = tcp->tcp_iss + 1;
2866 tcp->tcp_valid_bits &= ~TCP_ISS_VALID;
2867 tcp->tcp_state = TCPS_ESTABLISHED;
2874 if (tcp->tcp_rexmit) {
2875 tcp->tcp_rexmit = B_FALSE;
2876 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
2877 tcp->tcp_rexmit_max = tcp->tcp_snxt;
2878 tcp->tcp_snd_burst = TCP_CWND_NORMAL;
2886 tcp->tcp_cwnd = tcp->tcp_mss;
2889 tcp->tcp_swl1 = seg_seq;
2890 tcp->tcp_swl2 = seg_ack;
2893 tcp->tcp_swnd = new_swnd;
2894 if (new_swnd > tcp->tcp_max_swnd)
2895 tcp->tcp_max_swnd = new_swnd;
2910 if (tcp->tcp_unsent)
2923 tcp->tcp_state = TCPS_SYN_RCVD;
2924 mp1 = tcp_xmit_mp(tcp, tcp->tcp_xmit_head, tcp->tcp_mss,
2925 NULL, NULL, tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
2929 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
2935 if (tcp_state_wait(sock_id, tcp, TCPS_ALL_ACKED) < 0) {
2947 ((flags & TH_SYN) ? 0 : tcp->tcp_snd_ws);
2948 mss = tcp->tcp_mss;
2950 if (tcp->tcp_snd_ts_ok) {
2951 if (!tcp_paws_check(tcp, (tcph_t *)tcph, &tcpopt)) {
2960 } else if (tcp->tcp_snd_sack_ok) {
2961 assert(tcp->tcp_sack_info != NULL);
2962 tcpopt.tcp = tcp;
2970 gap = seg_seq - tcp->tcp_rnxt;
2971 rgap = tcp->tcp_rwnd - (gap + seg_len);
2979 if (seg_seq == tcp->tcp_irs && (flags & TH_SYN) &&
3019 seg_len, tcp->tcp_rnxt, tcp->tcp_snxt,
3020 tcp_display(tcp, NULL, DISP_ADDR_AND_PORT));
3059 seg_seq = tcp->tcp_rnxt;
3081 if (tcp->tcp_rwnd == 0)
3119 if (tcp->tcp_rwnd == 0 && seg_seq == tcp->tcp_rnxt) {
3123 tcp_rcv_drain(sock_id, tcp);
3152 if (tcp->tcp_ecn_ok) {
3156 tcp->tcp_ecn_echo_on = B_FALSE;
3164 tcp->tcp_ecn_echo_on = B_TRUE;
3173 if (tcp->tcp_snd_ts_ok &&
3174 TSTMP_GEQ(tcpopt.tcp_opt_ts_val, tcp->tcp_ts_recent) &&
3175 SEQ_LEQ(seg_seq, tcp->tcp_rack)) {
3176 tcp->tcp_ts_recent = tcpopt.tcp_opt_ts_val;
3177 tcp->tcp_last_rcv_lbolt = prom_gettime();
3180 if (seg_seq != tcp->tcp_rnxt || tcp->tcp_reass_head) {
3189 tcp->tcp_valid_bits |= TCP_OFO_FIN_VALID;
3190 tcp->tcp_ofo_fin_seq = seg_seq + seg_len;
3196 if (tcp->tcp_snd_sack_ok) {
3197 assert(tcp->tcp_sack_info != NULL);
3198 tcp_sack_insert(tcp->tcp_sack_list,
3200 &(tcp->tcp_num_sack_blk));
3207 mp = tcp_reass(tcp, mp, seg_seq);
3215 seg_seq = tcp->tcp_rnxt;
3221 if ((tcp->tcp_valid_bits & TCP_OFO_FIN_VALID) &&
3222 seg_seq + seg_len == tcp->tcp_ofo_fin_seq) {
3224 tcp->tcp_valid_bits &=
3250 if ((tcp->tcp_valid_bits & TCP_OFO_FIN_VALID) &&
3251 seg_seq + seg_len == tcp->tcp_ofo_fin_seq) {
3253 tcp->tcp_valid_bits &= ~TCP_OFO_FIN_VALID;
3259 switch (tcp->tcp_state) {
3261 (void) tcp_clean_death(sock_id, tcp, ECONNREFUSED);
3267 (void) tcp_clean_death(sock_id, tcp, ECONNRESET);
3271 (void) tcp_clean_death(sock_id, tcp, 0);
3274 assert(tcp->tcp_state != TCPS_TIME_WAIT);
3275 (void) tcp_clean_death(sock_id, tcp, ENXIO);
3289 assert(SEQ_GEQ(seg_seq, tcp->tcp_rnxt) &&
3290 SEQ_LEQ(seg_seq, tcp->tcp_rnxt + tcp->tcp_rwnd));
3297 seg_ack = tcp->tcp_snxt;
3299 tcp_xmit_ctl("TH_SYN", tcp, NULL, seg_ack,
3301 assert(tcp->tcp_state != TCPS_TIME_WAIT);
3302 (void) tcp_clean_death(sock_id, tcp, ECONNRESET);
3315 bytes_acked = (int)(seg_ack - tcp->tcp_suna);
3317 if (tcp->tcp_state == TCPS_SYN_RCVD) {
3318 tcp_t *listener = tcp->tcp_listener;
3326 if (bytes_acked < 1 || SEQ_GT(seg_ack, tcp->tcp_snxt)) {
3329 tcp, NULL, seg_ack, 0, TH_RST, 0, sock_id);
3346 tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
3347 tcp->tcp_eager_prev_q0;
3348 tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
3349 tcp->tcp_eager_next_q0;
3350 tcp->tcp_eager_prev_q0 = NULL;
3351 tcp->tcp_eager_next_q0 = NULL;
3362 tail->tcp_eager_next_q = tcp;
3364 listener->tcp_eager_next_q = tcp;
3366 listener->tcp_eager_last_q = tcp;
3367 tcp->tcp_eager_next_q = NULL;
3373 tcp->tcp_conn_def_q0 = B_TRUE;
3375 /* take tcp out of q0 ... */
3376 tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
3377 tcp->tcp_eager_next_q0;
3378 tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
3379 tcp->tcp_eager_prev_q0;
3382 tcp->tcp_eager_prev_q0 = listener->tcp_eager_prev_q0;
3383 tcp->tcp_eager_next_q0 = listener;
3384 listener->tcp_eager_prev_q0->tcp_eager_next_q0 = tcp;
3385 listener->tcp_eager_prev_q0 = tcp;
3388 tcp->tcp_suna = tcp->tcp_iss + 1; /* One for the SYN */
3396 if (tcp->tcp_rexmit) {
3397 tcp->tcp_rexmit = B_FALSE;
3398 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
3399 tcp->tcp_rexmit_max = tcp->tcp_snxt;
3400 tcp->tcp_snd_burst = TCP_CWND_NORMAL;
3401 tcp->tcp_ms_we_have_waited = 0;
3402 tcp->tcp_cwnd = mss;
3416 tcp->tcp_swnd = 0;
3418 if (new_swnd > tcp->tcp_max_swnd)
3419 tcp->tcp_max_swnd = new_swnd;
3420 tcp->tcp_swl1 = seg_seq;
3421 tcp->tcp_swl2 = seg_ack;
3422 tcp->tcp_state = TCPS_ESTABLISHED;
3423 tcp->tcp_valid_bits &= ~TCP_ISS_VALID;
3434 if (tcp->tcp_cwr && SEQ_GT(seg_ack, tcp->tcp_cwr_snd_max))
3435 tcp->tcp_cwr = B_FALSE;
3436 if (tcp->tcp_ecn_ok && (flags & TH_ECE)) {
3437 if (!tcp->tcp_cwr) {
3438 npkt = (MIN(tcp->tcp_cwnd, tcp->tcp_swnd) >> 1) / mss;
3439 tcp->tcp_cwnd_ssthresh = MAX(npkt, 2) * mss;
3440 tcp->tcp_cwnd = npkt * mss;
3446 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
3451 tcp->tcp_cwnd_cnt = 0;
3453 tcp->tcp_cwr = B_TRUE;
3460 tcp->tcp_cwr_snd_max = tcp->tcp_snxt;
3461 tcp->tcp_ecn_cwr_sent = B_FALSE;
3465 mp1 = tcp->tcp_xmit_head;
3467 if (!ofo_seg && seg_len == 0 && new_swnd == tcp->tcp_swnd) {
3479 if (mp1 != NULL && tcp->tcp_suna != tcp->tcp_snxt &&
3480 ! tcp->tcp_rexmit) {
3482 if ((dupack_cnt = ++tcp->tcp_dupack_cnt) <
3505 if (tcp->tcp_unsent > 0 &&
3506 (!tcp->tcp_snd_sack_ok ||
3507 (tcp->tcp_snd_sack_ok &&
3508 tcp->tcp_notsack_list != NULL))) {
3509 tcp->tcp_cwnd += mss <<
3510 (tcp->tcp_dupack_cnt - 1);
3530 if (!tcp->tcp_cwr) {
3531 npkt = (MIN(tcp->tcp_cwnd,
3532 tcp->tcp_swnd) >> 1) / mss;
3535 tcp->tcp_cwnd_ssthresh = npkt * mss;
3536 tcp->tcp_cwnd = (npkt +
3537 tcp->tcp_dupack_cnt) * mss;
3539 if (tcp->tcp_ecn_ok) {
3540 tcp->tcp_cwr = B_TRUE;
3541 tcp->tcp_cwr_snd_max = tcp->tcp_snxt;
3542 tcp->tcp_ecn_cwr_sent = B_FALSE;
3554 if ((tcp->tcp_valid_bits & TCP_FSS_VALID) &&
3555 (tcp->tcp_unsent == 0)) {
3556 tcp->tcp_rexmit_max = tcp->tcp_fss;
3558 tcp->tcp_rexmit_max = tcp->tcp_snxt;
3568 tcp->tcp_snd_burst = TCP_CWND_SS;
3585 if (tcp->tcp_snd_sack_ok) {
3586 assert(tcp->tcp_sack_info != NULL);
3587 if (tcp->tcp_notsack_list != NULL) {
3588 tcp->tcp_pipe = tcp->tcp_snxt -
3589 tcp->tcp_fack;
3590 tcp->tcp_sack_snxt = seg_ack;
3601 tcp->tcp_pipe =
3602 tcp->tcp_cwnd_ssthresh;
3615 if (tcp->tcp_snd_sack_ok &&
3616 tcp->tcp_notsack_list != NULL) {
3618 tcp->tcp_pipe -= mss;
3619 if (tcp->tcp_pipe < 0)
3620 tcp->tcp_pipe = 0;
3627 cwnd = tcp->tcp_cwnd + mss;
3628 if (cwnd > tcp->tcp_cwnd_max)
3629 cwnd = tcp->tcp_cwnd_max;
3630 tcp->tcp_cwnd = cwnd;
3635 } else if (tcp->tcp_zero_win_probe) {
3644 tcp->tcp_zero_win_probe = 0;
3645 tcp->tcp_timer_backoff = 0;
3646 tcp->tcp_ms_we_have_waited = 0;
3658 if (!tcp->tcp_rexmit) {
3659 tcp->tcp_rexmit = B_TRUE;
3660 tcp->tcp_dupack_cnt = 0;
3661 tcp->tcp_rexmit_nxt = tcp->tcp_suna;
3662 tcp->tcp_rexmit_max = tcp->tcp_suna + 1;
3680 if (SEQ_GT(seg_ack, tcp->tcp_snxt)) {
3686 mp = tcp_ack_mp(tcp);
3701 if (tcp->tcp_snd_sack_ok && tcp->tcp_notsack_list != NULL) {
3702 tcp_notsack_remove(&(tcp->tcp_notsack_list), seg_ack,
3703 &(tcp->tcp_num_notsack_blk), &(tcp->tcp_cnt_notsack_list));
3712 if (tcp->tcp_dupack_cnt >= tcp_dupack_fast_retransmit) {
3713 assert(tcp->tcp_rexmit == B_FALSE);
3714 if (SEQ_GEQ(seg_ack, tcp->tcp_rexmit_max)) {
3715 tcp->tcp_dupack_cnt = 0;
3720 if (tcp->tcp_cwnd > tcp->tcp_cwnd_ssthresh) {
3721 tcp->tcp_cwnd = tcp->tcp_cwnd_ssthresh;
3723 tcp->tcp_rexmit_max = seg_ack;
3724 tcp->tcp_cwnd_cnt = 0;
3725 tcp->tcp_snd_burst = TCP_CWND_NORMAL;
3731 if (tcp->tcp_snd_sack_ok &&
3732 tcp->tcp_notsack_list != NULL) {
3733 TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list);
3736 if (tcp->tcp_snd_sack_ok &&
3737 tcp->tcp_notsack_list != NULL) {
3739 tcp->tcp_pipe -= mss;
3740 if (tcp->tcp_pipe < 0)
3741 tcp->tcp_pipe = 0;
3754 tcp->tcp_cwnd = tcp->tcp_cwnd_ssthresh +
3756 tcp->tcp_cwnd_cnt = tcp->tcp_cwnd;
3762 tcp->tcp_dupack_cnt = 0;
3763 if (tcp->tcp_rexmit) {
3777 if (SEQ_LEQ(seg_ack, tcp->tcp_rexmit_max)) {
3778 if (SEQ_GT(seg_ack, tcp->tcp_rexmit_nxt)) {
3779 tcp->tcp_rexmit_nxt = seg_ack;
3781 if (seg_ack != tcp->tcp_rexmit_max) {
3785 tcp->tcp_rexmit = B_FALSE;
3786 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
3787 tcp->tcp_snd_burst = TCP_CWND_NORMAL;
3789 tcp->tcp_ms_we_have_waited = 0;
3795 tcp->tcp_suna = seg_ack;
3796 if (tcp->tcp_zero_win_probe != 0) {
3797 tcp->tcp_zero_win_probe = 0;
3798 tcp->tcp_timer_backoff = 0;
3817 if (!tcp->tcp_ecn_ok || !(flags & TH_ECE)) {
3818 cwnd = tcp->tcp_cwnd;
3821 if (cwnd >= tcp->tcp_cwnd_ssthresh) {
3832 if (tcp->tcp_cwnd_cnt <= 0) {
3833 tcp->tcp_cwnd_cnt = cwnd + add;
3835 tcp->tcp_cwnd_cnt -= add;
3839 tcp->tcp_cwnd = MIN(cwnd + add, tcp->tcp_cwnd_max);
3843 if (tcp->tcp_snd_ts_ok) {
3846 tcp_set_rto(tcp, (int32_t)(prom_gettime() -
3851 if (tcp->tcp_set_timer == 1) {
3852 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
3853 tcp->tcp_set_timer = 0;
3859 tcp->tcp_csuna = tcp->tcp_snxt;
3860 } else if (SEQ_GT(seg_ack, tcp->tcp_csuna)) {
3866 tcp_set_rto(tcp, (int32_t)(prom_gettime() -
3870 tcp->tcp_csuna = seg_ack;
3871 if (tcp->tcp_set_timer == 1) {
3872 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
3873 tcp->tcp_set_timer = 0;
3898 tcp->tcp_xmit_tail = NULL;
3901 if (mp2 != tcp->tcp_xmit_tail)
3903 tcp->tcp_xmit_tail = mp1;
3906 tcp->tcp_xmit_tail_unsent = (int)(mp1->b_wptr -
3917 assert(tcp->tcp_fin_sent);
3918 tcp->tcp_xmit_tail = NULL;
3919 if (tcp->tcp_fin_sent) {
3920 tcp->tcp_fin_acked = B_TRUE;
3937 tcp_xmit_ctl(NULL, tcp, NULL, tcp->tcp_snxt,
3938 tcp->tcp_rnxt, TH_RST|TH_ACK, 0, sock_id);
3941 tcp_display(tcp, NULL,
3949 assert(mp2 != tcp->tcp_xmit_tail);
3951 if (tcp->tcp_unsent) {
3955 tcp->tcp_xmit_head = mp1;
3968 if (SEQ_LT(tcp->tcp_swl2, seg_ack) ||
3969 SEQ_LT(tcp->tcp_swl1, seg_seq) ||
3970 (tcp->tcp_swl1 == seg_seq && new_swnd > tcp->tcp_swnd)) {
3979 if (tcp->tcp_unsent && new_swnd > tcp->tcp_swnd)
3981 tcp->tcp_swnd = new_swnd;
3982 if (new_swnd > tcp->tcp_max_swnd)
3983 tcp->tcp_max_swnd = new_swnd;
3984 tcp->tcp_swl1 = seg_seq;
3985 tcp->tcp_swl2 = seg_ack;
3988 if (tcp->tcp_state > TCPS_ESTABLISHED) {
3989 switch (tcp->tcp_state) {
3991 if (tcp->tcp_fin_acked) {
3992 tcp->tcp_state = TCPS_FIN_WAIT_2;
4009 TCP_TIMER_RESTART(tcp,
4017 if (tcp->tcp_fin_acked) {
4018 (void) tcp_clean_death(sock_id, tcp, 0);
4023 if (tcp->tcp_fin_acked) {
4024 tcp->tcp_state = TCPS_TIME_WAIT;
4025 tcp_time_wait_append(tcp);
4026 TCP_TIMER_RESTART(tcp, tcp_time_wait_interval);
4033 assert(tcp->tcp_state != TCPS_TIME_WAIT);
4040 if (!tcp->tcp_fin_rcvd) {
4041 tcp->tcp_fin_rcvd = B_TRUE;
4042 tcp->tcp_rnxt++;
4043 U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
4045 switch (tcp->tcp_state) {
4048 tcp->tcp_state = TCPS_CLOSE_WAIT;
4052 if (!tcp->tcp_fin_acked) {
4053 tcp->tcp_state = TCPS_CLOSING;
4058 tcp->tcp_state = TCPS_TIME_WAIT;
4059 tcp_time_wait_append(tcp);
4060 TCP_TIMER_RESTART(tcp, tcp_time_wait_interval);
4092 if (++tcp->tcp_rack_cnt == 2 || sockets[sock_id].inq == NULL) {
4094 tcp->tcp_rack_cnt = 0;
4096 tcp->tcp_rnxt += seg_len;
4097 U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
4100 if (tcp->tcp_snd_sack_ok && tcp->tcp_num_sack_blk > 0) {
4101 tcp_sack_remove(tcp->tcp_sack_list, tcp->tcp_rnxt,
4102 &(tcp->tcp_num_sack_blk));
4105 if (tcp->tcp_listener) {
4110 tcp_rcv_enqueue(tcp, mp, seg_len);
4113 tcp_rcv_enqueue(tcp, mp, seg_len);
4119 if (tcp->tcp_rcv_list != NULL)
4131 TH_LIMIT_XMIT)) && tcp->tcp_swnd != 0) {
4133 uint32_t snd_size = tcp->tcp_snxt - tcp->tcp_suna;
4137 if (snd_size > tcp->tcp_swnd)
4138 snd_size = tcp->tcp_swnd;
4139 mp1 = tcp_xmit_mp(tcp, tcp->tcp_xmit_head, snd_size,
4140 NULL, NULL, tcp->tcp_suna, B_TRUE, &snd_size,
4145 tcp->tcp_xmit_head->b_prev =
4147 tcp->tcp_csuna = tcp->tcp_snxt;
4155 if (tcp_sack_rxmit(tcp, sock_id) != 0) {
4165 if (!tcp->tcp_rexmit) {
4166 tcp_wput_data(tcp, NULL, sock_id);
4168 tcp_ss_rexmit(tcp, sock_id);
4183 tcp->tcp_cwnd -= mss << (tcp->tcp_dupack_cnt - 1);
4195 if ((mp1 = tcp_ack_mp(tcp)) != NULL) {
4212 tcp_ss_rexmit(tcp_t *tcp, int sock_id)
4219 int32_t burst = tcp->tcp_snd_burst;
4226 if (SEQ_LT(tcp->tcp_rexmit_nxt, tcp->tcp_rexmit_max)) {
4227 smax = tcp->tcp_rexmit_max;
4228 snxt = tcp->tcp_rexmit_nxt;
4229 if (SEQ_LT(snxt, tcp->tcp_suna)) {
4230 snxt = tcp->tcp_suna;
4232 win = MIN(tcp->tcp_cwnd, tcp->tcp_swnd);
4233 win -= snxt - tcp->tcp_suna;
4234 mss = tcp->tcp_mss;
4235 snxt_mp = tcp_get_seg_mp(tcp, snxt, &off);
4249 xmit_mp = tcp_xmit_mp(tcp, snxt_mp, cnt, &off,
4270 tcp->tcp_rexmit_nxt = snxt;
4285 if (tcp->tcp_unsent) {
4286 tcp_wput_data(tcp, NULL, sock_id);
4292 * a tcp instance except keepalives. It figures out from the state of the
4293 * tcp instance what kind of action needs to be done at the time it is called.
4296 tcp_timer(tcp_t *tcp, int sock_id)
4304 first_threshold = tcp->tcp_first_timer_threshold;
4305 second_threshold = tcp->tcp_second_timer_threshold;
4306 switch (tcp->tcp_state) {
4313 first_threshold = tcp->tcp_first_ctimer_threshold;
4314 second_threshold = tcp->tcp_second_ctimer_threshold;
4322 if (tcp->tcp_suna != tcp->tcp_snxt) {
4326 if (tcp->tcp_xmit_head == NULL)
4330 (uint32_t)(uintptr_t)tcp->tcp_xmit_head->b_prev);
4331 time_to_wait = tcp->tcp_rto - time_to_wait;
4336 TCP_TIMER_RESTART(tcp, time_to_wait);
4349 if (tcp->tcp_swnd == 0 || tcp->tcp_zero_win_probe) {
4368 if (!tcp->tcp_cwr || tcp->tcp_rexmit) {
4369 npkt = (MIN((tcp->tcp_timer_backoff ?
4370 tcp->tcp_cwnd_ssthresh :
4371 tcp->tcp_cwnd),
4372 tcp->tcp_swnd) >> 1) /
4373 tcp->tcp_mss;
4376 tcp->tcp_cwnd_ssthresh = npkt *
4377 tcp->tcp_mss;
4379 tcp->tcp_cwnd = tcp->tcp_mss;
4380 tcp->tcp_cwnd_cnt = 0;
4381 if (tcp->tcp_ecn_ok) {
4382 tcp->tcp_cwr = B_TRUE;
4383 tcp->tcp_cwr_snd_max = tcp->tcp_snxt;
4384 tcp->tcp_ecn_cwr_sent = B_FALSE;
4402 if (tcp->tcp_unsent != 0) {
4403 if (tcp->tcp_cwnd == 0) {
4410 assert(tcp->tcp_ecn_ok);
4411 tcp->tcp_cwnd = tcp->tcp_mss;
4413 if (tcp->tcp_swnd == 0) {
4415 tcp->tcp_swnd++;
4416 tcp->tcp_zero_win_probe = B_TRUE;
4435 tcp->tcp_max_swnd = MAX(tcp->tcp_swnd, 2);
4437 tcp_wput_data(tcp, NULL, sock_id);
4441 if ((tcp->tcp_valid_bits & TCP_FSS_VALID) &&
4442 !tcp->tcp_fin_acked)
4455 (void) tcp_clean_death(sock_id, tcp, 0);
4459 tcp->tcp_state, tcp_display(tcp, NULL,
4463 if ((ms = tcp->tcp_ms_we_have_waited) > second_threshold) {
4469 if ((tcp->tcp_zero_win_probe == 0) ||
4470 ((prom_gettime() - tcp->tcp_last_recv_time) >
4478 if (tcp->tcp_state == TCPS_SYN_RCVD) {
4481 tcp, NULL, tcp->tcp_snxt,
4482 tcp->tcp_rnxt, TH_RST | TH_ACK, 0, sock_id);
4484 (void) tcp_clean_death(sock_id, tcp,
4485 tcp->tcp_client_errno ?
4486 tcp->tcp_client_errno : ETIMEDOUT);
4504 tcp->tcp_ms_we_have_waited = second_threshold;
4506 } else if (ms > first_threshold && tcp->tcp_rtt_sa != 0) {
4515 if (tcp->tcp_zero_win_probe == 0) {
4516 tcp->tcp_rtt_sd += (tcp->tcp_rtt_sa >> 3) +
4517 (tcp->tcp_rtt_sa >> 5);
4518 tcp->tcp_rtt_sa = 0;
4519 tcp->tcp_rtt_update = 0;
4522 tcp->tcp_timer_backoff++;
4523 if ((ms = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
4524 tcp_rexmit_interval_extra + (tcp->tcp_rtt_sa >> 5)) <
4531 ms = tcp_rexmit_interval_min << tcp->tcp_timer_backoff;
4533 ms <<= tcp->tcp_timer_backoff;
4541 tcp->tcp_timer_backoff--;
4543 tcp->tcp_ms_we_have_waited += ms;
4544 if (tcp->tcp_zero_win_probe == 0) {
4545 tcp->tcp_rto = ms;
4547 TCP_TIMER_RESTART(tcp, ms);
4553 tcp->tcp_set_timer = 1;
4554 mss = tcp->tcp_snxt - tcp->tcp_suna;
4555 if (mss > tcp->tcp_mss)
4556 mss = tcp->tcp_mss;
4557 if (mss > tcp->tcp_swnd && tcp->tcp_swnd != 0)
4558 mss = tcp->tcp_swnd;
4560 if ((mp = tcp->tcp_xmit_head) != NULL) {
4564 mp = tcp_xmit_mp(tcp, mp, mss, NULL, NULL, tcp->tcp_suna, B_TRUE, &mss,
4568 tcp->tcp_csuna = tcp->tcp_snxt;
4583 tcp->tcp_rexmit_nxt = tcp->tcp_suna;
4584 tcp->tcp_snd_burst = TCP_CWND_SS;
4585 if ((tcp->tcp_valid_bits & TCP_FSS_VALID) &&
4586 (tcp->tcp_unsent == 0)) {
4587 tcp->tcp_rexmit_max = tcp->tcp_fss;
4589 tcp->tcp_rexmit_max = tcp->tcp_snxt;
4591 tcp->tcp_rexmit = B_TRUE;
4592 tcp->tcp_dupack_cnt = 0;
4597 if (tcp->tcp_snd_sack_ok && tcp->tcp_notsack_list != NULL) {
4598 TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list);
4599 tcp->tcp_num_notsack_blk = 0;
4600 tcp->tcp_cnt_notsack_list = 0;
4609 tcp_wput_data(tcp_t *tcp, mblk_t *mp, int sock_id)
4630 tcpstate = tcp->tcp_state;
4633 len = tcp->tcp_unsent;
4644 (tcp->tcp_valid_bits & TCP_FSS_VALID) != 0) {
4645 if ((tcp->tcp_valid_bits & TCP_FSS_VALID) != 0) {
4647 tcp_display(tcp, NULL, DISP_ADDR_AND_PORT));
4669 if (tcp->tcp_xmit_head == NULL) {
4670 tcp->tcp_xmit_head = mp;
4671 tcp->tcp_xmit_tail = mp;
4672 tcp->tcp_xmit_tail_unsent = len;
4674 tcp->tcp_xmit_last->b_cont = mp;
4675 len += tcp->tcp_unsent;
4694 tcp->tcp_xmit_last = mp;
4695 tcp->tcp_unsent = len;
4698 snxt = tcp->tcp_snxt;
4699 xmit_tail = tcp->tcp_xmit_tail;
4700 tail_unsent = tcp->tcp_xmit_tail_unsent;
4710 if (tcp->tcp_snd_sack_ok && tcp->tcp_num_sack_blk > 0) {
4713 num_sack_blk = MIN(tcp->tcp_max_sack_blk,
4714 tcp->tcp_num_sack_blk);
4717 mss = tcp->tcp_mss - opt_len;
4718 tcp_hdr_len = tcp->tcp_hdr_len + opt_len;
4720 mss = tcp->tcp_mss;
4721 tcp_hdr_len = tcp->tcp_hdr_len;
4724 if ((tcp->tcp_suna == snxt) &&
4725 (prom_gettime() - tcp->tcp_last_recv_time) >= tcp->tcp_rto) {
4726 tcp->tcp_cwnd = MIN(tcp_slow_start_after_idle * mss,
4740 int usable_r = tcp->tcp_swnd;
4748 if (tcp->tcp_cwnd == 0) {
4753 assert(tcp->tcp_ecn_ok ||
4754 tcp->tcp_state < TCPS_ESTABLISHED);
4759 if (usable_r > tcp->tcp_cwnd)
4760 usable_r = tcp->tcp_cwnd;
4764 usable_r += tcp->tcp_suna;
4799 if (usable < (int)tcp->tcp_naglim &&
4800 tcp->tcp_naglim > tcp->tcp_last_sent_len &&
4801 snxt != tcp->tcp_suna &&
4802 !(tcp->tcp_valid_bits & TCP_URG_VALID))
4805 num_burst_seg = tcp->tcp_snd_burst;
4828 if (len < (tcp->tcp_max_swnd >> 1) &&
4829 (tcp->tcp_unsent - (snxt - tcp->tcp_snxt)) > len &&
4830 !((tcp->tcp_valid_bits & TCP_URG_VALID) &&
4831 len == 1) && (! tcp->tcp_zero_win_probe)) {
4838 if (snxt == tcp->tcp_snxt &&
4839 snxt == tcp->tcp_suna) {
4848 * tcp->tcp_rto)
4850 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
4856 tcph = tcp->tcp_tcph;
4866 if (tcp->tcp_valid_bits) {
4868 uint32_t prev_snxt = tcp->tcp_snxt;
4880 mp = tcp_xmit_mp(tcp, xmit_tail, len, NULL, NULL,
4883 tcp->tcp_snxt = prev_snxt;
4895 tcp->tcp_last_sent_len = (ushort_t)len;
4921 tcp->tcp_ipha->ip_len = htons(len);
4937 tcp->tcp_last_sent_len = (ushort_t)len;
4940 if (tcp->tcp_ipversion == IPV4_VERSION)
4941 tcp->tcp_ipha->ip_len = htons(len);
4963 mp1 = allocb(tcp->tcp_ip_hdr_len + TCP_MAX_HDR_LENGTH +
4977 if (tcp->tcp_snd_ts_ok) {
4981 U32_TO_BE32(tcp->tcp_ts_recent,
4984 assert(tcp->tcp_tcp_hdr_len == TCP_MIN_HEADER_LENGTH);
4991 src = (ipaddr_t *)tcp->tcp_iphc;
5002 len = tcp->tcp_hdr_len;
5016 tcph = (tcph_t *)(rptr + tcp->tcp_ip_hdr_len);
5023 if (tcp->tcp_ecn_ok && !tcp->tcp_zero_win_probe) {
5024 SET_ECT(tcp, rptr);
5026 if (tcp->tcp_ecn_echo_on)
5028 if (tcp->tcp_cwr && !tcp->tcp_ecn_cwr_sent) {
5030 tcp->tcp_ecn_cwr_sent = B_TRUE;
5036 uchar_t *wptr = rptr + tcp->tcp_hdr_len;
5047 tmp = tcp->tcp_sack_list;
5095 tcp->tcp_last_sent_len += tail_unsent;
5149 tcp->tcp_xmit_tail = xmit_tail;
5150 tcp->tcp_xmit_tail_unsent = tail_unsent;
5151 len = tcp->tcp_snxt - snxt;
5159 if (tcp->tcp_snd_sack_ok && tcp->tcp_notsack_list != NULL) {
5161 tcp->tcp_pipe -= len;
5162 tcp_notsack_update(&(tcp->tcp_notsack_list),
5163 tcp->tcp_snxt, snxt,
5164 &(tcp->tcp_num_notsack_blk),
5165 &(tcp->tcp_cnt_notsack_list));
5167 tcp->tcp_snxt = snxt + tcp->tcp_fin_sent;
5168 tcp->tcp_rack = tcp->tcp_rnxt;
5169 tcp->tcp_rack_cnt = 0;
5170 if ((snxt + len) == tcp->tcp_suna) {
5171 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
5178 len += tcp->tcp_unsent;
5179 tcp->tcp_unsent = len;
5185 (void) tcp_state_wait(sock_id, tcp, TCPS_ALL_ACKED);
5187 } else if (snxt == tcp->tcp_suna && tcp->tcp_swnd == 0) {
5192 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
5196 len += tcp->tcp_unsent;
5197 tcp->tcp_unsent = len;
5202 tcp_time_wait_processing(tcp_t *tcp, mblk_t *mp,
5218 if ((sockets[sock_id].pcb == NULL) || (sockets[sock_id].pcb != tcp))
5223 ((tcph->th_flags[0] & TH_SYN) ? 0 : tcp->tcp_snd_ws);
5224 if (tcp->tcp_snd_ts_ok) {
5225 if (!tcp_paws_check(tcp, tcph, &tcpopt)) {
5227 tcp_xmit_ctl(NULL, tcp, NULL, tcp->tcp_snxt,
5228 tcp->tcp_rnxt, TH_ACK, 0, -1);
5232 gap = seg_seq - tcp->tcp_rnxt;
5233 rgap = tcp->tcp_rwnd - (gap + seg_len);
5252 tcp_time_wait_remove(tcp);
5253 tcp_time_wait_append(tcp);
5254 TCP_TIMER_RESTART(tcp, tcp_time_wait_interval);
5255 tcp_xmit_ctl(NULL, tcp, NULL, tcp->tcp_snxt,
5256 tcp->tcp_rnxt, TH_ACK, 0, -1);
5266 seg_seq = tcp->tcp_rnxt;
5296 if ((adj = (int32_t)(tcp->tcp_snxt - new_iss)) > 0) {
5304 tcp_clean_death(sock_id, tcp, 0);
5338 if (tcp->tcp_snd_ts_ok &&
5339 TSTMP_GEQ(tcpopt.tcp_opt_ts_val, tcp->tcp_ts_recent) &&
5340 SEQ_LEQ(seg_seq, tcp->tcp_rack)) {
5341 tcp->tcp_ts_recent = tcpopt.tcp_opt_ts_val;
5342 tcp->tcp_last_rcv_lbolt = prom_gettime();
5345 if (seg_seq != tcp->tcp_rnxt && seg_len > 0) {
5355 (void) tcp_clean_death(sock_id, tcp, 0);
5360 tcp_xmit_ctl("TH_SYN", tcp, NULL, seg_ack, seg_seq + 1,
5370 bytes_acked = (int)(seg_ack - tcp->tcp_suna);
5373 new_swnd == tcp->tcp_swnd)
5385 tcp_xmit_ctl(NULL, tcp, NULL, tcp->tcp_snxt,
5386 tcp->tcp_rnxt, TH_ACK, 0, -1);
5391 tcp_init_values(tcp_t *tcp, struct inetboot_socket *isp)
5395 tcp->tcp_family = AF_INET;
5396 tcp->tcp_ipversion = IPV4_VERSION;
5405 tcp->tcp_rtt_sa = tcp_rexmit_interval_initial << 2;
5406 tcp->tcp_rtt_sd = tcp_rexmit_interval_initial >> 1;
5407 tcp->tcp_rto = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
5408 tcp_rexmit_interval_extra + (tcp->tcp_rtt_sa >> 5) +
5410 if (tcp->tcp_rto < tcp_rexmit_interval_min)
5411 tcp->tcp_rto = tcp_rexmit_interval_min;
5412 tcp->tcp_timer_backoff = 0;
5413 tcp->tcp_ms_we_have_waited = 0;
5414 tcp->tcp_last_recv_time = prom_gettime();
5415 tcp->tcp_cwnd_max = tcp_cwnd_max_;
5416 tcp->tcp_snd_burst = TCP_CWND_INFINITE;
5417 tcp->tcp_cwnd_ssthresh = TCP_MAX_LARGEWIN;
5420 tcp->tcp_if_mtu = mac_get_mtu() - 50;
5422 tcp->tcp_if_mtu = mac_get_mtu();
5424 tcp->tcp_mss = tcp->tcp_if_mtu;
5426 tcp->tcp_first_timer_threshold = tcp_ip_notify_interval;
5427 tcp->tcp_first_ctimer_threshold = tcp_ip_notify_cinterval;
5428 tcp->tcp_second_timer_threshold = tcp_ip_abort_interval;
5433 tcp->tcp_second_ctimer_threshold = tcp_ip_abort_cinterval;
5435 tcp->tcp_naglim = tcp_naglim_def;
5440 if (tcp->tcp_ipversion == IPV4_VERSION) {
5441 err = tcp_header_init_ipv4(tcp);
5450 tcp->tcp_rcv_ws = TCP_MAX_WINSHIFT;
5451 tcp->tcp_xmit_lowater = tcp_xmit_lowat;
5453 tcp->tcp_xmit_hiwater = isp->so_sndbuf;
5454 tcp->tcp_rwnd = isp->so_rcvbuf;
5455 tcp->tcp_rwnd_max = isp->so_rcvbuf;
5457 tcp->tcp_state = TCPS_IDLE;
5465 tcp_header_init_ipv4(tcp_t *tcp)
5474 if (tcp->tcp_iphc != NULL) {
5475 assert(tcp->tcp_iphc_len >= TCP_MAX_COMBINED_HEADER_LENGTH);
5476 bzero(tcp->tcp_iphc, tcp->tcp_iphc_len);
5478 tcp->tcp_iphc_len = TCP_MAX_COMBINED_HEADER_LENGTH;
5479 tcp->tcp_iphc = bkmem_zalloc(tcp->tcp_iphc_len);
5480 if (tcp->tcp_iphc == NULL) {
5481 tcp->tcp_iphc_len = 0;
5485 tcp->tcp_ipha = (struct ip *)tcp->tcp_iphc;
5486 tcp->tcp_ipversion = IPV4_VERSION;
5492 tcp->tcp_hdr_len = sizeof (struct ip) + sizeof (tcph_t);
5493 tcp->tcp_tcp_hdr_len = sizeof (tcph_t);
5494 tcp->tcp_ip_hdr_len = sizeof (struct ip);
5495 tcp->tcp_ipha->ip_v = IP_VERSION;
5497 tcp->tcp_ipha->ip_hl = IP_SIMPLE_HDR_LENGTH_IN_WORDS;
5498 tcp->tcp_ipha->ip_p = IPPROTO_TCP;
5500 tcp->tcp_ipha->ip_sum = 0;
5502 tcph = (tcph_t *)(tcp->tcp_iphc + sizeof (struct ip));
5503 tcp->tcp_tcph = tcph;
5509 * Send out a control packet on the tcp connection specified. This routine
5515 tcp_xmit_ctl(char *str, tcp_t *tcp, mblk_t *mp, uint32_t seq,
5524 tcp_hdr_len = tcp->tcp_hdr_len;
5525 tcp_ip_hdr_len = tcp->tcp_ip_hdr_len;
5554 bcopy(tcp->tcp_iphc, rptr, tcp_hdr_len);
5567 if (tcp->tcp_snd_ts_ok && tcp->tcp_state > TCPS_SYN_SENT) {
5578 if (tcp->tcp_snd_ts_ok) {
5581 U32_TO_BE32(tcp->tcp_ts_recent,
5584 tcp->tcp_rack = ack;
5585 tcp->tcp_rack_cnt = 0;
5601 tcp_ack_mp(tcp_t *tcp)
5603 if (tcp->tcp_valid_bits) {
5613 return (tcp_xmit_mp(tcp, NULL, 0, NULL, NULL,
5614 (tcp->tcp_zero_win_probe) ?
5615 tcp->tcp_suna :
5616 tcp->tcp_snxt, B_FALSE, NULL, B_FALSE));
5630 if (tcp->tcp_snd_sack_ok && tcp->tcp_num_sack_blk > 0) {
5631 num_sack_blk = MIN(tcp->tcp_max_sack_blk,
5632 tcp->tcp_num_sack_blk);
5635 tcp_hdr_len = tcp->tcp_hdr_len + sack_opt_len;
5637 tcp_hdr_len = tcp->tcp_hdr_len;
5647 bcopy(tcp->tcp_iphc, rptr, tcp->tcp_hdr_len);
5649 tcph = (tcph_t *)&rptr[tcp->tcp_ip_hdr_len];
5659 U32_TO_ABE32((tcp->tcp_zero_win_probe) ?
5660 tcp->tcp_suna : tcp->tcp_snxt, tcph->th_seq);
5664 if (tcp->tcp_ecn_echo_on)
5667 tcp->tcp_rack = tcp->tcp_rnxt;
5668 tcp->tcp_rack_cnt = 0;
5671 if (tcp->tcp_snd_ts_ok) {
5676 U32_TO_BE32(tcp->tcp_ts_recent,
5682 uchar_t *wptr = (uchar_t *)tcph + tcp->tcp_tcp_hdr_len;
5693 tmp = tcp->tcp_sack_list;
5713 * ip and tcp header ready to pass down to IP. If the mp passed in is
5726 tcp_xmit_mp(tcp_t *tcp, mblk_t *mp, int32_t max_to_send, int32_t *offset,
5742 mp1 = allocb(tcp->tcp_ip_hdr_len + TCP_MAX_HDR_LENGTH +
5756 if (tcp->tcp_snd_sack_ok && tcp->tcp_num_sack_blk > 0) {
5757 num_sack_blk = MIN(tcp->tcp_max_sack_blk,
5758 tcp->tcp_num_sack_blk);
5761 if (max_to_send + sack_opt_len > tcp->tcp_mss)
5810 mp1->b_wptr = rptr + tcp->tcp_hdr_len + sack_opt_len;
5811 bcopy(tcp->tcp_iphc, rptr, tcp->tcp_hdr_len);
5812 tcph = (tcph_t *)&rptr[tcp->tcp_ip_hdr_len];
5822 if (data_length != 0 && (tcp->tcp_unsent == 0 ||
5823 tcp->tcp_unsent == data_length)) {
5829 if (tcp->tcp_ecn_ok) {
5830 if (tcp->tcp_ecn_echo_on)
5839 SET_ECT(tcp, rptr);
5840 if (tcp->tcp_cwr && !tcp->tcp_ecn_cwr_sent) {
5842 tcp->tcp_ecn_cwr_sent = B_TRUE;
5847 if (tcp->tcp_valid_bits) {
5850 if ((tcp->tcp_valid_bits & TCP_ISS_VALID) &&
5851 seq == tcp->tcp_iss) {
5866 u1 = tcp->tcp_if_mtu - IP_SIMPLE_HDR_LENGTH -
5880 switch (tcp->tcp_state) {
5884 if (tcp->tcp_snd_ws_ok) {
5889 wptr[3] = (uchar_t)tcp->tcp_rcv_ws;
5895 if (tcp->tcp_snd_ts_ok) {
5907 assert(tcp->tcp_ts_recent == 0);
5914 if (tcp->tcp_snd_sack_ok) {
5929 if (tcp->tcp_ecn_ok) {
5936 if (tcp->tcp_snd_ws_ok) {
5941 wptr[3] = (uchar_t)tcp->tcp_rcv_ws;
5946 if (tcp->tcp_snd_sack_ok) {
5961 if (tcp->tcp_ecn_ok) {
5974 if ((tcp->tcp_valid_bits & TCP_FSS_VALID) &&
5975 (seq + data_length) == tcp->tcp_fss) {
5976 if (!tcp->tcp_fin_acked) {
5980 if (!tcp->tcp_fin_sent) {
5981 tcp->tcp_fin_sent = B_TRUE;
5982 switch (tcp->tcp_state) {
5985 tcp->tcp_state = TCPS_FIN_WAIT_1;
5988 tcp->tcp_state = TCPS_LAST_ACK;
5991 if (tcp->tcp_suna == tcp->tcp_snxt)
5992 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
5993 tcp->tcp_snxt = tcp->tcp_fss + 1;
5998 tcp->tcp_rack = tcp->tcp_rnxt;
5999 tcp->tcp_rack_cnt = 0;
6001 if (tcp->tcp_snd_ts_ok) {
6002 if (tcp->tcp_state != TCPS_SYN_SENT) {
6007 U32_TO_BE32(tcp->tcp_ts_recent,
6013 uchar_t *wptr = (uchar_t *)tcph + tcp->tcp_tcp_hdr_len;
6024 tmp = tcp->tcp_sack_list;
6035 if (tcp->tcp_ipversion == IPV4_VERSION)
6092 tcp_xmit_early_reset("no tcp, reset",
6097 tcp_xmit_early_reset("no tcp, reset/ack", sock_id,
6118 * tcp state that we can find.
6379 tcp_iss_init(tcp_t *tcp)
6382 tcp->tcp_iss = tcp_iss_incr_extra;
6383 tcp->tcp_iss += (prom_gettime() >> ISS_NSEC_SHT) + tcp_random();
6384 tcp->tcp_valid_bits = TCP_ISS_VALID;
6385 tcp->tcp_fss = tcp->tcp_iss - 1;
6386 tcp->tcp_suna = tcp->tcp_iss;
6387 tcp->tcp_snxt = tcp->tcp_iss + 1;
6388 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
6389 tcp->tcp_csuna = tcp->tcp_snxt;
6393 * Diagnostic routine used to return a string associated with the tcp state.
6401 tcp_display(tcp_t *tcp, char *sup_buf, char format)
6416 if (tcp == NULL)
6418 switch (tcp->tcp_state) {
6459 (void) sprintf(buf1, "TCPUnkState(%d)", tcp->tcp_state);
6471 addr.s_addr = tcp->tcp_bound_source;
6473 addr.s_addr = tcp->tcp_remote;
6476 local_addrbuf, ntohs(tcp->tcp_lport), remote_addrbuf,
6477 ntohs(tcp->tcp_fport), cp);
6482 ntohs(tcp->tcp_lport), ntohs(tcp->tcp_fport), cp);
6490 * Add a new piece to the tcp reassembly queue. If the gap at the beginning
6496 tcp_reass(tcp_t *tcp, mblk_t *mp, uint32_t start)
6518 mp1 = tcp->tcp_reass_tail;
6520 tcp->tcp_reass_tail = mp;
6521 tcp->tcp_reass_head = mp;
6530 tcp->tcp_reass_tail = mp;
6535 mp1 = tcp->tcp_reass_head;
6541 tcp->tcp_reass_head = mp;
6542 tcp_reass_elim_overlap(tcp, mp);
6559 tcp_reass_elim_overlap(tcp, mp);
6562 tcp_reass_elim_overlap(tcp, mp1);
6565 mp1 = tcp->tcp_reass_head;
6567 if (TCP_REASS_SEQ(mp1) != tcp->tcp_rnxt)
6576 tcp->tcp_reass_tail = NULL;
6585 mp1 = tcp->tcp_reass_head;
6586 tcp->tcp_reass_head = mp;
6592 tcp_reass_elim_overlap(tcp_t *tcp, mblk_t *mp)
6616 tcp->tcp_reass_tail = mp;
6623 tcp_time_wait_remove(tcp_t *tcp)
6625 if (tcp->tcp_time_wait_expire == 0) {
6626 assert(tcp->tcp_time_wait_next == NULL);
6627 assert(tcp->tcp_time_wait_prev == NULL);
6630 assert(tcp->tcp_state == TCPS_TIME_WAIT);
6631 if (tcp == tcp_time_wait_head) {
6632 assert(tcp->tcp_time_wait_prev == NULL);
6633 tcp_time_wait_head = tcp->tcp_time_wait_next;
6639 } else if (tcp == tcp_time_wait_tail) {
6640 assert(tcp != tcp_time_wait_head);
6641 assert(tcp->tcp_time_wait_next == NULL);
6642 tcp_time_wait_tail = tcp->tcp_time_wait_prev;
6646 assert(tcp->tcp_time_wait_prev->tcp_time_wait_next == tcp);
6647 assert(tcp->tcp_time_wait_next->tcp_time_wait_prev == tcp);
6648 tcp->tcp_time_wait_prev->tcp_time_wait_next =
6649 tcp->tcp_time_wait_next;
6650 tcp->tcp_time_wait_next->tcp_time_wait_prev =
6651 tcp->tcp_time_wait_prev;
6653 tcp->tcp_time_wait_next = NULL;
6654 tcp->tcp_time_wait_prev = NULL;
6655 tcp->tcp_time_wait_expire = 0;
6663 tcp_time_wait_append(tcp_t *tcp)
6665 tcp->tcp_time_wait_expire = prom_gettime() + tcp_time_wait_interval;
6666 if (tcp->tcp_time_wait_expire == 0)
6667 tcp->tcp_time_wait_expire = 1;
6671 tcp_time_wait_head = tcp;
6675 tcp_time_wait_tail->tcp_time_wait_next = tcp;
6676 tcp->tcp_time_wait_prev = tcp_time_wait_tail;
6678 tcp_time_wait_tail = tcp;
6695 tcp_t *tcp;
6703 while ((tcp = tcp_time_wait_head) != NULL) {
6708 if ((int32_t)(now - tcp->tcp_time_wait_expire) < 0) {
6715 (void) tcp_clean_death(-1, tcp, 0);
6724 tcp_t *tcp;
6727 for (tcp = tcp_time_wait_head; tcp != NULL;
6728 tcp = tcp->tcp_time_wait_next) {
6729 printf("%s expires at %u\n", tcp_display(tcp, NULL,
6730 DISP_ADDR_AND_PORT), tcp->tcp_time_wait_expire);
6739 tcp_rcv_drain(int sock_id, tcp_t *tcp)
6751 if (tcp->tcp_rcv_list == NULL)
6758 if ((in_mp = allocb(tcp->tcp_rcv_cnt, 0)) == NULL) {
6766 while ((mp = tcp->tcp_rcv_list) != NULL) {
6767 tcp->tcp_rcv_list = mp->b_cont;
6774 tcp->tcp_rcv_last_tail = NULL;
6775 tcp->tcp_rcv_cnt = 0;
6787 (tcp->tcp_rwnd_max - tcp->tcp_rwnd >= tcp->tcp_mss)) {
6788 tcp->tcp_rwnd = tcp->tcp_rwnd_max;
6789 U32_TO_ABE16(tcp->tcp_rwnd >> tcp->tcp_rcv_ws,
6790 tcp->tcp_tcph->th_win);
6800 tcp_t *tcp;
6801 if ((tcp = sockets[sock_id].pcb) == NULL)
6803 tcp_rcv_drain(sock_id, tcp);
6812 tcp_drain_needed(int sock_id, tcp_t *tcp)
6817 sockets[sock_id].inq, tcp->tcp_rcv_list);
6820 (tcp->tcp_rcv_list == NULL))
6842 tcp_rcv_enqueue(tcp_t *tcp, mblk_t *mp, uint_t seg_len)
6845 if (tcp->tcp_rcv_list == NULL) {
6846 tcp->tcp_rcv_list = mp;
6848 tcp->tcp_rcv_last_tail->b_cont = mp;
6852 tcp->tcp_rcv_last_tail = mp;
6853 tcp->tcp_rcv_cnt += seg_len;
6854 tcp->tcp_rwnd -= seg_len;
6856 printf("tcp_rcv_enqueue rwnd %d\n", tcp->tcp_rwnd);
6858 U32_TO_ABE16(tcp->tcp_rwnd >> tcp->tcp_rcv_ws, tcp->tcp_tcph->th_win);
6874 tcp_set_rto(tcp_t *tcp, int32_t rtt)
6877 uint32_t sa = tcp->tcp_rtt_sa;
6878 uint32_t sv = tcp->tcp_rtt_sd;
6882 tcp->tcp_rtt_update++;
6934 tcp->tcp_rtt_sa = sa;
6935 tcp->tcp_rtt_sd = sv;
6951 tcp->tcp_rto = tcp_rexmit_interval_max;
6953 tcp->tcp_rto = tcp_rexmit_interval_min;
6955 tcp->tcp_rto = rto;
6959 tcp->tcp_timer_backoff = 0;
6967 tcp_xmit_end(tcp_t *tcp, int sock_id)
6971 if (tcp->tcp_state < TCPS_SYN_RCVD ||
6972 tcp->tcp_state > TCPS_CLOSE_WAIT) {
6980 tcp->tcp_fss = tcp->tcp_snxt + tcp->tcp_unsent;
6981 tcp->tcp_valid_bits |= TCP_FSS_VALID;
6986 if (tcp->tcp_unsent == 0) {
6987 mp = tcp_xmit_mp(tcp, NULL, 0, NULL, NULL,
6988 tcp->tcp_fss, B_FALSE, NULL, B_FALSE);
7000 tcp->tcp_snxt = tcp->tcp_fss + 1;
7001 TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
7008 if (tcp->tcp_rexmit && tcp->tcp_rexmit_nxt == tcp->tcp_fss) {
7009 tcp->tcp_rexmit_nxt = tcp->tcp_snxt;
7012 tcp_wput_data(tcp, NULL, B_FALSE);
7019 tcp_opt_set(tcp_t *tcp, int level, int option, const void *optval,
7035 val = MSS_ROUNDUP(val, tcp->tcp_mss);
7036 (void) tcp_rwnd_set(tcp, val);
7044 tcp->tcp_xmit_hiwater = *(int *)optval;
7045 if (tcp->tcp_xmit_hiwater > tcp_max_buf)
7046 tcp->tcp_xmit_hiwater = tcp_max_buf;
7056 tcp->tcp_linger = 1;
7057 tcp->tcp_lingertime = lgr->l_linger;
7059 tcp->tcp_linger = 0;
7060 tcp->tcp_lingertime = 0;