1 // Copyright 2022 The gRPC Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_INTERNAL_ERRQUEUE_H 16 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_INTERNAL_ERRQUEUE_H 17 18 #include <grpc/support/port_platform.h> 19 #include <stdint.h> 20 21 #include "src/core/lib/iomgr/port.h" 22 23 #ifdef GRPC_POSIX_SOCKET_TCP 24 25 #include <time.h> 26 27 #ifdef GRPC_LINUX_ERRQUEUE 28 #include <linux/errqueue.h> // IWYU pragma: keep 29 #include <sys/socket.h> 30 #endif // GRPC_LINUX_ERRQUEUE 31 32 namespace grpc_event_engine { 33 namespace experimental { 34 35 #ifdef GRPC_LINUX_ERRQUEUE 36 37 // Redefining scm_timestamping in the same way that <linux/errqueue.h> defines 38 // it, so that code compiles on systems that don't have it. 39 struct scm_timestamping { 40 struct timespec ts[3]; 41 }; 42 // Also redefine timestamp types 43 // The timestamp type for when the driver passed skb to NIC, or HW. 44 constexpr int SCM_TSTAMP_SND = 0; 45 // The timestamp type for when data entered the packet scheduler. 46 constexpr int SCM_TSTAMP_SCHED = 1; 47 // The timestamp type for when data acknowledged by peer. 48 constexpr int SCM_TSTAMP_ACK = 2; 49 50 // Control message type containing OPT_STATS 51 #ifndef SCM_TIMESTAMPING_OPT_STATS 52 #define SCM_TIMESTAMPING_OPT_STATS 54 53 #endif 54 55 // Redefine required constants from <linux/net_tstamp.h> 56 constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; 57 constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; 58 constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; 59 constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; 60 constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; 61 constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; 62 constexpr uint32_t SOF_TIMESTAMPING_OPT_STATS = 1u << 12; 63 64 constexpr uint32_t kTimestampingSocketOptions = 65 SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID | 66 SOF_TIMESTAMPING_OPT_TSONLY | SOF_TIMESTAMPING_OPT_STATS; 67 constexpr uint32_t kTimestampingRecordingOptions = 68 SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | 69 SOF_TIMESTAMPING_TX_ACK; 70 71 // Netlink attribute types used for TCP opt stats. 72 enum TCPOptStats { 73 TCP_NLA_PAD, 74 TCP_NLA_BUSY, // Time (usec) busy sending data. 75 TCP_NLA_RWND_LIMITED, // Time (usec) limited by receive window. 76 TCP_NLA_SNDBUF_LIMITED, // Time (usec) limited by send buffer. 77 TCP_NLA_DATA_SEGS_OUT, // Data pkts sent including retransmission. 78 TCP_NLA_TOTAL_RETRANS, // Data pkts retransmitted. 79 TCP_NLA_PACING_RATE, // Pacing rate in Bps. 80 TCP_NLA_DELIVERY_RATE, // Delivery rate in Bps. 81 TCP_NLA_SND_CWND, // Sending congestion window. 82 TCP_NLA_REORDERING, // Reordering metric. 83 TCP_NLA_MIN_RTT, // minimum RTT. 84 TCP_NLA_RECUR_RETRANS, // Recurring retransmits for the current pkt. 85 TCP_NLA_DELIVERY_RATE_APP_LMT, // Delivery rate application limited? 86 TCP_NLA_SNDQ_SIZE, // Data (bytes) pending in send queue 87 TCP_NLA_CA_STATE, // ca_state of socket 88 TCP_NLA_SND_SSTHRESH, // Slow start size threshold 89 TCP_NLA_DELIVERED, // Data pkts delivered incl. out-of-order 90 TCP_NLA_DELIVERED_CE, // Like above but only ones w/ CE marks 91 TCP_NLA_BYTES_SENT, // Data bytes sent including retransmission 92 TCP_NLA_BYTES_RETRANS, // Data bytes retransmitted 93 TCP_NLA_DSACK_DUPS, // DSACK blocks received 94 TCP_NLA_REORD_SEEN, // reordering events seen 95 TCP_NLA_SRTT, // smoothed RTT in usecs 96 }; 97 98 // tcp_info from from linux/tcp.h 99 struct tcp_info { 100 uint8_t tcpi_state; 101 uint8_t tcpi_ca_state; 102 uint8_t tcpi_retransmits; 103 uint8_t tcpi_probes; 104 uint8_t tcpi_backoff; 105 uint8_t tcpi_options; 106 uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; 107 uint8_t tcpi_delivery_rate_app_limited : 1; 108 uint32_t tcpi_rto; 109 uint32_t tcpi_ato; 110 uint32_t tcpi_snd_mss; 111 uint32_t tcpi_rcv_mss; 112 uint32_t tcpi_unacked; 113 uint32_t tcpi_sacked; 114 uint32_t tcpi_lost; 115 uint32_t tcpi_retrans; 116 uint32_t tcpi_fackets; 117 // Times. 118 uint32_t tcpi_last_data_sent; 119 uint32_t tcpi_last_ack_sent; // Not remembered, sorry. 120 uint32_t tcpi_last_data_recv; 121 uint32_t tcpi_last_ack_recv; 122 // Metrics. 123 uint32_t tcpi_pmtu; 124 uint32_t tcpi_rcv_ssthresh; 125 uint32_t tcpi_rtt; 126 uint32_t tcpi_rttvar; 127 uint32_t tcpi_snd_ssthresh; 128 uint32_t tcpi_snd_cwnd; 129 uint32_t tcpi_advmss; 130 uint32_t tcpi_reordering; 131 uint32_t tcpi_rcv_rtt; 132 uint32_t tcpi_rcv_space; 133 uint32_t tcpi_total_retrans; 134 uint64_t tcpi_pacing_rate; 135 uint64_t tcpi_max_pacing_rate; 136 uint64_t tcpi_bytes_acked; // RFC4898 tcpEStatsAppHCThruOctetsAcked 137 uint64_t tcpi_bytes_received; // RFC4898 tcpEStatsAppHCThruOctetsReceived 138 139 uint32_t tcpi_segs_out; // RFC4898 tcpEStatsPerfSegsOut 140 uint32_t tcpi_segs_in; // RFC4898 tcpEStatsPerfSegsIn 141 uint32_t tcpi_notsent_bytes; 142 uint32_t tcpi_min_rtt; 143 144 uint32_t tcpi_data_segs_in; // RFC4898 tcpEStatsDataSegsIn 145 uint32_t tcpi_data_segs_out; // RFC4898 tcpEStatsDataSegsOut 146 147 uint64_t tcpi_delivery_rate; 148 uint64_t tcpi_busy_time; // Time (usec) busy sending data 149 uint64_t tcpi_rwnd_limited; // Time (usec) limited by receive window 150 uint64_t tcpi_sndbuf_limited; // Time (usec) limited by send buffer 151 152 uint32_t tcpi_delivered; 153 uint32_t tcpi_delivered_ce; 154 uint64_t tcpi_bytes_sent; // RFC4898 tcpEStatsPerfHCDataOctetsOut 155 uint64_t tcpi_bytes_retrans; // RFC4898 tcpEStatsPerfOctetsRetrans 156 uint32_t tcpi_dsack_dups; // RFC4898 tcpEStatsStackDSACKDups 157 uint32_t tcpi_reord_seen; // reordering events seen 158 socklen_t length; // Length of struct returned by kernel 159 }; 160 161 #ifndef TCP_INFO 162 #define TCP_INFO 11 163 #endif 164 165 int GetSocketTcpInfo(tcp_info* info, int fd); 166 167 #endif // GRPC_LINUX_ERRQUEUE 168 169 // Returns true if kernel is capable of supporting errqueue and timestamping. 170 // Currently allowing only linux kernels above 4.0.0 171 bool KernelSupportsErrqueue(); 172 173 } // namespace experimental 174 } // namespace grpc_event_engine 175 176 #endif // GRPC_POSIX_SOCKET_TCP 177 178 #endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_INTERNAL_ERRQUEUE_H 179