Print this page
11547 Want connstat(1M) command to display per-connection TCP statistics
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Portions contributed by: Ahmed G <ahmedg@delphix.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>


 577         }
 578 
 579         if ((tcp->tcp_rnxt - tcp->tcp_rack) > tcp->tcp_mss) {
 580                 /*
 581                  * Make sure we don't allow deferred ACKs to result in
 582                  * timer-based ACKing.  If we have held off an ACK
 583                  * when there was more than an mss here, and the timer
 584                  * goes off, we have to worry about the possibility
 585                  * that the sender isn't doing slow-start, or is out
 586                  * of step with us for some other reason.  We fall
 587                  * permanently back in the direction of
 588                  * ACK-every-other-packet as suggested in RFC 1122.
 589                  */
 590                 if (tcp->tcp_rack_abs_max > 2)
 591                         tcp->tcp_rack_abs_max--;
 592                 tcp->tcp_rack_cur_max = 2;
 593         }
 594         mp = tcp_ack_mp(tcp);
 595 
 596         if (mp != NULL) {
 597                 BUMP_LOCAL(tcp->tcp_obsegs);
 598                 TCPS_BUMP_MIB(tcps, tcpOutAck);
 599                 TCPS_BUMP_MIB(tcps, tcpOutAckDelayed);
 600                 tcp_send_data(tcp, mp);
 601         }
 602 }
 603 
 604 /*
 605  * Notify IP that we are having trouble with this connection.  IP should
 606  * make note so it can potentially use a different IRE.
 607  */
 608 static void
 609 tcp_ip_notify(tcp_t *tcp)
 610 {
 611         conn_t          *connp = tcp->tcp_connp;
 612         ire_t           *ire;
 613 
 614         /*
 615          * Note: in the case of source routing we want to blow away the
 616          * route to the first source route hop.
 617          */


 836                          */
 837                         if (tcp->tcp_snd_zcopy_aware && !tcp->tcp_xmit_zc_clean)
 838                                 tcp->tcp_xmit_head = tcp_zcopy_backoff(tcp,
 839                                     tcp->tcp_xmit_head, B_TRUE);
 840 
 841                         if (tcp->tcp_cwnd == 0) {
 842                                 /*
 843                                  * Set tcp_cwnd to 1 MSS so that a
 844                                  * new segment can be sent out.  We
 845                                  * are "clocking out" new data when
 846                                  * the network is really congested.
 847                                  */
 848                                 ASSERT(tcp->tcp_ecn_ok);
 849                                 tcp->tcp_cwnd = tcp->tcp_mss;
 850                         }
 851                         if (tcp->tcp_swnd == 0) {
 852                                 /* Extend window for zero window probe */
 853                                 tcp->tcp_swnd++;
 854                                 tcp->tcp_zero_win_probe = B_TRUE;
 855                                 TCPS_BUMP_MIB(tcps, tcpOutWinProbe);

 856                         } else {
 857                                 /*
 858                                  * Handle timeout from sender SWS avoidance.
 859                                  * Reset our knowledge of the max send window
 860                                  * since the receiver might have reduced its
 861                                  * receive buffer.  Avoid setting tcp_max_swnd
 862                                  * to one since that will essentially disable
 863                                  * the SWS checks.
 864                                  *
 865                                  * Note that since we don't have a SWS
 866                                  * state variable, if the timeout is set
 867                                  * for ECN but not for SWS, this
 868                                  * code will also be executed.  This is
 869                                  * fine as tcp_max_swnd is updated
 870                                  * constantly and it will not affect
 871                                  * anything.
 872                                  */
 873                                 tcp->tcp_max_swnd = MAX(tcp->tcp_swnd, 2);
 874                         }
 875                         tcp_wput_data(tcp, NULL, B_FALSE);


1064             (tcp->tcp_unsent == 0)) {
1065                 tcp->tcp_rexmit_max = tcp->tcp_fss;
1066         } else {
1067                 tcp->tcp_rexmit_max = tcp->tcp_snxt;
1068         }
1069         tcp->tcp_rexmit = B_TRUE;
1070         tcp->tcp_dupack_cnt = 0;
1071 
1072         /*
1073          * Remove all rexmit SACK blk to start from fresh.
1074          */
1075         if (tcp->tcp_snd_sack_ok)
1076                 TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list, tcp);
1077         if (mp == NULL) {
1078                 return;
1079         }
1080 
1081         tcp->tcp_csuna = tcp->tcp_snxt;
1082         TCPS_BUMP_MIB(tcps, tcpRetransSegs);
1083         TCPS_UPDATE_MIB(tcps, tcpRetransBytes, mss);


1084         tcp_send_data(tcp, mp);
1085 
1086 }
1087 
1088 /*
1089  * Handle lingering timeouts. This function is called when the SO_LINGER timeout
1090  * expires.
1091  */
1092 void
1093 tcp_close_linger_timeout(void *arg)
1094 {
1095         conn_t  *connp = (conn_t *)arg;
1096         tcp_t   *tcp = connp->conn_tcp;
1097 
1098         tcp->tcp_client_errno = ETIMEDOUT;
1099         tcp_stop_lingering(tcp);
1100 }


 577         }
 578 
 579         if ((tcp->tcp_rnxt - tcp->tcp_rack) > tcp->tcp_mss) {
 580                 /*
 581                  * Make sure we don't allow deferred ACKs to result in
 582                  * timer-based ACKing.  If we have held off an ACK
 583                  * when there was more than an mss here, and the timer
 584                  * goes off, we have to worry about the possibility
 585                  * that the sender isn't doing slow-start, or is out
 586                  * of step with us for some other reason.  We fall
 587                  * permanently back in the direction of
 588                  * ACK-every-other-packet as suggested in RFC 1122.
 589                  */
 590                 if (tcp->tcp_rack_abs_max > 2)
 591                         tcp->tcp_rack_abs_max--;
 592                 tcp->tcp_rack_cur_max = 2;
 593         }
 594         mp = tcp_ack_mp(tcp);
 595 
 596         if (mp != NULL) {
 597                 TCPS_BUMP_MIB(tcps, tcpHCOutSegs);
 598                 TCPS_BUMP_MIB(tcps, tcpOutAck);
 599                 TCPS_BUMP_MIB(tcps, tcpOutAckDelayed);
 600                 tcp_send_data(tcp, mp);
 601         }
 602 }
 603 
 604 /*
 605  * Notify IP that we are having trouble with this connection.  IP should
 606  * make note so it can potentially use a different IRE.
 607  */
 608 static void
 609 tcp_ip_notify(tcp_t *tcp)
 610 {
 611         conn_t          *connp = tcp->tcp_connp;
 612         ire_t           *ire;
 613 
 614         /*
 615          * Note: in the case of source routing we want to blow away the
 616          * route to the first source route hop.
 617          */


 836                          */
 837                         if (tcp->tcp_snd_zcopy_aware && !tcp->tcp_xmit_zc_clean)
 838                                 tcp->tcp_xmit_head = tcp_zcopy_backoff(tcp,
 839                                     tcp->tcp_xmit_head, B_TRUE);
 840 
 841                         if (tcp->tcp_cwnd == 0) {
 842                                 /*
 843                                  * Set tcp_cwnd to 1 MSS so that a
 844                                  * new segment can be sent out.  We
 845                                  * are "clocking out" new data when
 846                                  * the network is really congested.
 847                                  */
 848                                 ASSERT(tcp->tcp_ecn_ok);
 849                                 tcp->tcp_cwnd = tcp->tcp_mss;
 850                         }
 851                         if (tcp->tcp_swnd == 0) {
 852                                 /* Extend window for zero window probe */
 853                                 tcp->tcp_swnd++;
 854                                 tcp->tcp_zero_win_probe = B_TRUE;
 855                                 TCPS_BUMP_MIB(tcps, tcpOutWinProbe);
 856                                 tcp->tcp_cs.tcp_out_zwnd_probes++;
 857                         } else {
 858                                 /*
 859                                  * Handle timeout from sender SWS avoidance.
 860                                  * Reset our knowledge of the max send window
 861                                  * since the receiver might have reduced its
 862                                  * receive buffer.  Avoid setting tcp_max_swnd
 863                                  * to one since that will essentially disable
 864                                  * the SWS checks.
 865                                  *
 866                                  * Note that since we don't have a SWS
 867                                  * state variable, if the timeout is set
 868                                  * for ECN but not for SWS, this
 869                                  * code will also be executed.  This is
 870                                  * fine as tcp_max_swnd is updated
 871                                  * constantly and it will not affect
 872                                  * anything.
 873                                  */
 874                                 tcp->tcp_max_swnd = MAX(tcp->tcp_swnd, 2);
 875                         }
 876                         tcp_wput_data(tcp, NULL, B_FALSE);


1065             (tcp->tcp_unsent == 0)) {
1066                 tcp->tcp_rexmit_max = tcp->tcp_fss;
1067         } else {
1068                 tcp->tcp_rexmit_max = tcp->tcp_snxt;
1069         }
1070         tcp->tcp_rexmit = B_TRUE;
1071         tcp->tcp_dupack_cnt = 0;
1072 
1073         /*
1074          * Remove all rexmit SACK blk to start from fresh.
1075          */
1076         if (tcp->tcp_snd_sack_ok)
1077                 TCP_NOTSACK_REMOVE_ALL(tcp->tcp_notsack_list, tcp);
1078         if (mp == NULL) {
1079                 return;
1080         }
1081 
1082         tcp->tcp_csuna = tcp->tcp_snxt;
1083         TCPS_BUMP_MIB(tcps, tcpRetransSegs);
1084         TCPS_UPDATE_MIB(tcps, tcpRetransBytes, mss);
1085         tcp->tcp_cs.tcp_out_retrans_segs++;
1086         tcp->tcp_cs.tcp_out_retrans_bytes += mss;
1087         tcp_send_data(tcp, mp);
1088 
1089 }
1090 
1091 /*
1092  * Handle lingering timeouts. This function is called when the SO_LINGER timeout
1093  * expires.
1094  */
1095 void
1096 tcp_close_linger_timeout(void *arg)
1097 {
1098         conn_t  *connp = (conn_t *)arg;
1099         tcp_t   *tcp = connp->conn_tcp;
1100 
1101         tcp->tcp_client_errno = ETIMEDOUT;
1102         tcp_stop_lingering(tcp);
1103 }