From b52c519e5dd5d985a5f4892ae989cab82adb48e8 Mon Sep 17 00:00:00 2001 From: Ivan Prisyazhnyy Date: Wed, 31 Jul 2024 11:55:39 +0200 Subject: [PATCH] macos: tcp sock info support Signed-off-by: Ivan Prisyazhnyy --- galerautils/src/gu_asio.hpp | 96 +++++++++++++++++++++++++ galerautils/src/gu_asio_socket_util.hpp | 36 +++++++++- 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/galerautils/src/gu_asio.hpp b/galerautils/src/gu_asio.hpp index c1254d04b..decc92a9c 100644 --- a/galerautils/src/gu_asio.hpp +++ b/galerautils/src/gu_asio.hpp @@ -27,6 +27,102 @@ #include #include +#ifdef __APPLE__ + +struct tcp_info { + uint8_t tcpi_state; + uint8_t tcpi_ca_state; + uint8_t tcpi_retransmits; + uint8_t tcpi_probes; + uint8_t tcpi_backoff; + uint8_t tcpi_options; + uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + uint8_t tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2; + + uint32_t tcpi_rto; + uint32_t tcpi_ato; + uint32_t tcpi_snd_mss; + uint32_t tcpi_rcv_mss; + + uint32_t tcpi_unacked; + uint32_t tcpi_sacked; + uint32_t tcpi_lost; + uint32_t tcpi_retrans; + uint32_t tcpi_fackets; + + /* Times. */ + uint32_t tcpi_last_data_sent; + uint32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ + uint32_t tcpi_last_data_recv; + uint32_t tcpi_last_ack_recv; + + /* Metrics. */ + uint32_t tcpi_pmtu; + uint32_t tcpi_rcv_ssthresh; + uint32_t tcpi_rtt; + uint32_t tcpi_rttvar; + uint32_t tcpi_snd_ssthresh; + uint32_t tcpi_snd_cwnd; + uint32_t tcpi_advmss; + uint32_t tcpi_reordering; + + uint32_t tcpi_rcv_rtt; + uint32_t tcpi_rcv_space; + + uint32_t tcpi_total_retrans; + + uint64_t tcpi_pacing_rate; + uint64_t tcpi_max_pacing_rate; + uint64_t tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ + uint64_t tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ + uint32_t tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ + uint32_t tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ + + uint32_t tcpi_notsent_bytes; + uint32_t tcpi_min_rtt; + uint32_t tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ + uint32_t tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ + + uint64_t tcpi_delivery_rate; + + uint64_t tcpi_busy_time; /* Time (usec) busy sending data */ + uint64_t tcpi_rwnd_limited; /* Time (usec) limited by receive window */ + uint64_t tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ + + uint32_t tcpi_delivered; + uint32_t tcpi_delivered_ce; + + uint64_t tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ + uint64_t tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ + uint32_t tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ + uint32_t tcpi_reord_seen; /* reordering events seen */ + + uint32_t tcpi_rcv_ooopack; /* Out-of-order packets received */ + + uint32_t tcpi_snd_wnd; /* peer's advertised receive window after + * scaling (bytes) + */ + uint32_t tcpi_rcv_wnd; /* local advertised receive window after + * scaling (bytes) + */ + + uint32_t tcpi_rehash; /* PLB or timeout triggered rehash attempts */ + + uint16_t tcpi_total_rto; /* Total number of RTO timeouts, including + * SYN/SYN-ACK and recurring timeouts. + */ + uint16_t tcpi_total_rto_recoveries; /* Total number of RTO + * recoveries, including any + * unfinished recovery. + */ + uint32_t tcpi_total_rto_time; /* Total time spent in RTO recoveries + * in milliseconds, including any + * unfinished recovery. + */ +}; + +#endif + namespace gu { // URI schemes for networking diff --git a/galerautils/src/gu_asio_socket_util.hpp b/galerautils/src/gu_asio_socket_util.hpp index 57b78ba59..65062518c 100644 --- a/galerautils/src/gu_asio_socket_util.hpp +++ b/galerautils/src/gu_asio_socket_util.hpp @@ -143,6 +143,40 @@ static void bind(Socket& socket, const gu::AsioIpAddress& addr) } } +#ifdef __APPLE__ + +template +static struct tcp_info get_tcp_info(Socket& socket) +{ + struct tcp_info tcpi; + memset(&tcpi, 0, sizeof(tcpi)); + // struct tcp_connection_info + // https://developer.apple.com/documentation/kernel/tcp_connection_info + // http://git.haproxy.org/?p=haproxy-2.6.git;a=commitdiff_plain;h=7747d465d54a1e367e9bf9c07c263d7f1f7fd481;hp=5c83e3a1563cd7face299bf08037e51f976eb5e3 + // TODO needed fields: + // ret.rtt = tcpi.tcpi_rtt; + // ret.rttvar = tcpi.tcpi_rttvar; + // ret.rto = tcpi.tcpi_rto; +#if defined(__linux__) + // ret.lost = tcpi.tcpi_lost; +#else + // ret.lost = 0; +#endif /* __linux__ */ + // ret.last_data_recv = tcpi.tcpi_last_data_recv; + // ret.cwnd = tcpi.tcpi_snd_cwnd; + // gu::datetime::Date now(gu::datetime::Date::monotonic()); + // Critical crit(net_); + // ret.last_queued_since = (now - last_queued_tstamp_).get_nsecs(); + // ret.last_delivered_since = (now - last_delivered_tstamp_).get_nsecs(); + // ret.send_queue_length = send_q_.size(); + // ret.send_queue_bytes = send_q_.queued_bytes(); + // ret.send_queue_segments = send_q_.segments(); + + return tcpi; +} + +#else + template static struct tcp_info get_tcp_info(Socket& socket) { @@ -165,7 +199,7 @@ static struct tcp_info get_tcp_info(Socket& socket) #endif /* __linux__ || __FreeBSD__ */ return tcpi; } - +#endif static inline std::string uri_string (const std::string& scheme, const std::string& addr,