1
#include "source/extensions/transport_sockets/tap/tap.h"
2

            
3
#include "envoy/extensions/transport_sockets/tap/v3/tap.pb.h"
4

            
5
#include "source/common/buffer/buffer_impl.h"
6

            
7
namespace Envoy {
8
namespace Extensions {
9
namespace TransportSockets {
10
namespace Tap {
11

            
12
TapSocket::TapSocket(
13
    SocketTapConfigSharedPtr config,
14
    const envoy::extensions::transport_sockets::tap::v3::SocketTapConfig& socket_tap_config,
15
    Stats::Scope& stats_scope, Network::TransportSocketPtr&& transport_socket)
16
8
    : PassthroughSocket(std::move(transport_socket)), config_(config),
17
8
      socket_tap_config_(socket_tap_config),
18
8
      stats_(generateStats(stats_scope, socket_tap_config.stats_prefix())) {}
19

            
20
8
TransportTapStats TapSocket::generateStats(Stats::Scope& stats_scope, const std::string& prefix) {
21
8
  std::string final_prefix;
22
8
  if (prefix.empty()) {
23
6
    final_prefix = fmt::format("transport.tap.");
24
6
  } else {
25
2
    final_prefix = fmt::format("transport.tap.{}.", prefix);
26
2
  }
27
8
  TransportTapStats stats{ALL_TRANSPORT_TAP_STATS(POOL_COUNTER_PREFIX(stats_scope, final_prefix))};
28
8
  return stats;
29
8
}
30

            
31
8
void TapSocket::setTransportSocketCallbacks(Network::TransportSocketCallbacks& callbacks) {
32
8
  ASSERT(!tapper_);
33
8
  transport_socket_->setTransportSocketCallbacks(callbacks);
34
8
  tapper_ = config_
35
8
                ? config_->createPerSocketTapper(socket_tap_config_, stats_, callbacks.connection())
36
8
                : nullptr;
37
8
}
38

            
39
8
void TapSocket::closeSocket(Network::ConnectionEvent event) {
40
8
  if (tapper_ != nullptr) {
41
8
    tapper_->closeSocket(event);
42
8
  }
43

            
44
8
  transport_socket_->closeSocket(event);
45
8
}
46

            
47
29
Network::IoResult TapSocket::doRead(Buffer::Instance& buffer) {
48
29
  Network::IoResult result = transport_socket_->doRead(buffer);
49
29
  if (tapper_ != nullptr && result.bytes_processed_ > 0) {
50
11
    tapper_->onRead(buffer, result.bytes_processed_);
51
11
  }
52

            
53
29
  return result;
54
29
}
55

            
56
53
Network::IoResult TapSocket::doWrite(Buffer::Instance& buffer, bool end_stream) {
57
  // TODO(htuch): avoid copy.
58
53
  Buffer::OwnedImpl copy(buffer);
59
53
  Network::IoResult result = transport_socket_->doWrite(buffer, end_stream);
60
53
  if (tapper_ != nullptr && result.bytes_processed_ > 0) {
61
14
    tapper_->onWrite(copy, result.bytes_processed_, end_stream);
62
14
  }
63
53
  return result;
64
53
}
65

            
66
TapSocketFactory::TapSocketFactory(
67
    const envoy::extensions::transport_sockets::tap::v3::Tap& proto_config,
68
    Common::Tap::TapConfigFactoryPtr&& config_factory, OptRef<Server::Admin> admin,
69
    Singleton::Manager& singleton_manager, ThreadLocal::SlotAllocator& tls,
70
    Event::Dispatcher& main_thread_dispatcher, Stats::Scope& scope,
71
    Network::UpstreamTransportSocketFactoryPtr&& transport_socket_factory)
72
4
    : ExtensionConfigBase(proto_config.common_config(), std::move(config_factory), admin,
73
4
                          singleton_manager, tls, main_thread_dispatcher),
74
4
      PassthroughFactory(std::move(transport_socket_factory)),
75
4
      ts_tap_config_(proto_config.socket_tap_config()), stats_scope_(scope) {}
76

            
77
Network::TransportSocketPtr
78
TapSocketFactory::createTransportSocket(Network::TransportSocketOptionsConstSharedPtr options,
79
2
                                        Upstream::HostDescriptionConstSharedPtr host) const {
80
2
  return std::make_unique<TapSocket>(
81
2
      currentConfigHelper<SocketTapConfig>(), ts_tap_config_, stats_scope_,
82
2
      transport_socket_factory_->createTransportSocket(options, host));
83
2
}
84

            
85
DownstreamTapSocketFactory::DownstreamTapSocketFactory(
86
    const envoy::extensions::transport_sockets::tap::v3::Tap& proto_config,
87
    Common::Tap::TapConfigFactoryPtr&& config_factory, OptRef<Server::Admin> admin,
88
    Singleton::Manager& singleton_manager, ThreadLocal::SlotAllocator& tls,
89
    Event::Dispatcher& main_thread_dispatcher, Stats::Scope& scope,
90
    Network::DownstreamTransportSocketFactoryPtr&& transport_socket_factory)
91
5
    : ExtensionConfigBase(proto_config.common_config(), std::move(config_factory), admin,
92
5
                          singleton_manager, tls, main_thread_dispatcher),
93
5
      DownstreamPassthroughFactory(std::move(transport_socket_factory)),
94
5
      ds_ts_tap_config_(proto_config.socket_tap_config()), stats_scope_(scope) {}
95

            
96
6
Network::TransportSocketPtr DownstreamTapSocketFactory::createDownstreamTransportSocket() const {
97
6
  return std::make_unique<TapSocket>(currentConfigHelper<SocketTapConfig>(), ds_ts_tap_config_,
98
6
                                     stats_scope_,
99
6
                                     transport_socket_factory_->createDownstreamTransportSocket());
100
6
}
101

            
102
} // namespace Tap
103
} // namespace TransportSockets
104
} // namespace Extensions
105
} // namespace Envoy