1
#pragma once
2

            
3
#if defined(__linux__)
4

            
5
#include "envoy/event/timer.h"
6
#include "envoy/extensions/transport_sockets/tcp_stats/v3/tcp_stats.pb.h"
7
#include "envoy/network/connection.h"
8
#include "envoy/network/filter.h"
9
#include "envoy/stats/scope.h"
10
#include "envoy/stats/stats_macros.h"
11

            
12
#include "source/common/common/logger.h"
13
#include "source/extensions/transport_sockets/common/passthrough.h"
14

            
15
// Defined in /usr/include/linux/tcp.h.
16
struct tcp_info;
17

            
18
namespace Envoy {
19
namespace Extensions {
20
namespace TransportSockets {
21
namespace TcpStats {
22

            
23
#define ALL_TCP_STATS(COUNTER, GAUGE, HISTOGRAM)                                                   \
24
8
  COUNTER(cx_tx_segments)                                                                          \
25
8
  COUNTER(cx_rx_segments)                                                                          \
26
8
  COUNTER(cx_tx_data_segments)                                                                     \
27
8
  COUNTER(cx_rx_data_segments)                                                                     \
28
8
  COUNTER(cx_tx_retransmitted_segments)                                                            \
29
8
  COUNTER(cx_rx_bytes_received)                                                                    \
30
8
  COUNTER(cx_tx_bytes_sent)                                                                        \
31
8
  GAUGE(cx_tx_unsent_bytes, Accumulate)                                                            \
32
8
  GAUGE(cx_tx_unacked_segments, Accumulate)                                                        \
33
8
  HISTOGRAM(cx_tx_percent_retransmitted_segments, Percent)                                         \
34
8
  HISTOGRAM(cx_rtt_us, Microseconds)                                                               \
35
8
  HISTOGRAM(cx_rtt_variance_us, Microseconds)
36

            
37
struct TcpStats {
38
  ALL_TCP_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT, GENERATE_HISTOGRAM_STRUCT)
39
};
40

            
41
class Config {
42
public:
43
  Config(const envoy::extensions::transport_sockets::tcp_stats::v3::Config& config_proto,
44
         Stats::Scope& scope);
45

            
46
  TcpStats stats_;
47
  const absl::optional<std::chrono::milliseconds> update_period_;
48

            
49
private:
50
  TcpStats generateStats(Stats::Scope& scope);
51
};
52

            
53
using ConfigConstSharedPtr = std::shared_ptr<const Config>;
54

            
55
class TcpStatsSocket : public TransportSockets::PassthroughSocket,
56
                       Logger::Loggable<Logger::Id::connection> {
57
public:
58
  TcpStatsSocket(ConfigConstSharedPtr config, Network::TransportSocketPtr inner_socket);
59

            
60
  // Network::TransportSocket
61
  void setTransportSocketCallbacks(Network::TransportSocketCallbacks& callbacks) override;
62
  void onConnected() override;
63
  void closeSocket(Network::ConnectionEvent event) override;
64

            
65
private:
66
  absl::optional<struct tcp_info> querySocketInfo();
67
  void recordStats();
68

            
69
  const ConfigConstSharedPtr config_;
70
  Network::TransportSocketCallbacks* callbacks_{};
71
  Event::TimerPtr timer_;
72

            
73
  uint32_t last_cx_tx_segments_{};
74
  uint32_t last_cx_rx_segments_{};
75
  uint32_t last_cx_tx_data_segments_{};
76
  uint32_t last_cx_rx_data_segments_{};
77
  uint32_t last_cx_tx_retransmitted_segments_{};
78
  uint32_t last_cx_rx_bytes_received_{};
79
  uint32_t last_cx_tx_bytes_sent_{};
80
  uint32_t last_cx_tx_unsent_bytes_{};
81
  uint32_t last_cx_tx_unacked_segments_{};
82
};
83

            
84
} // namespace TcpStats
85
} // namespace TransportSockets
86
} // namespace Extensions
87
} // namespace Envoy
88

            
89
#endif // defined(__linux__)