1
#include "source/common/network/transport_socket_options_impl.h"
2

            
3
#include <cstdint>
4
#include <memory>
5
#include <string>
6
#include <utility>
7
#include <vector>
8

            
9
#include "envoy/common/hashable.h"
10

            
11
#include "source/common/common/scalar_to_byte_vector.h"
12
#include "source/common/common/utility.h"
13
#include "source/common/network/application_protocol.h"
14
#include "source/common/network/filter_state_proxy_info.h"
15
#include "source/common/network/proxy_protocol_filter_state.h"
16
#include "source/common/network/upstream_server_name.h"
17
#include "source/common/network/upstream_subject_alt_names.h"
18

            
19
namespace Envoy {
20
namespace Network {
21

            
22
void CommonUpstreamTransportSocketFactory::hashKey(
23
46082
    std::vector<uint8_t>& key, TransportSocketOptionsConstSharedPtr options) const {
24
46082
  if (!options) {
25
2
    return;
26
2
  }
27
46080
  const auto& server_name_overide = options->serverNameOverride();
28
46080
  if (server_name_overide.has_value()) {
29
2275
    pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(server_name_overide.value()), key);
30
2275
  }
31

            
32
46080
  const auto& verify_san_list = options->verifySubjectAltNameListOverride();
33
46080
  for (const auto& san : verify_san_list) {
34
120
    pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(san), key);
35
120
  }
36

            
37
46080
  const auto& alpn_list = options->applicationProtocolListOverride();
38
46080
  for (const auto& protocol : alpn_list) {
39
    pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(protocol), key);
40
  }
41

            
42
46080
  const auto& alpn_fallback = options->applicationProtocolFallback();
43
46080
  for (const auto& protocol : alpn_fallback) {
44
    pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(protocol), key);
45
  }
46

            
47
46087
  for (const auto& object : options->downstreamSharedFilterStateObjects()) {
48
37
    if (auto hashable = dynamic_cast<const Hashable*>(object.data_.get()); hashable != nullptr) {
49
1
      if (auto hash = hashable->hash(); hash) {
50
1
        pushScalarToByteVector(hash.value(), key);
51
1
      }
52
1
    }
53
37
  }
54
46080
}
55

            
56
TransportSocketOptionsConstSharedPtr
57
49939
TransportSocketOptionsUtility::fromFilterState(const StreamInfo::FilterState& filter_state) {
58
49939
  absl::string_view server_name;
59
49939
  std::vector<std::string> application_protocols;
60
49939
  std::vector<std::string> subject_alt_names;
61
49939
  std::vector<std::string> alpn_fallback;
62
49939
  absl::optional<Network::ProxyProtocolData> proxy_protocol_options;
63
49939
  std::unique_ptr<const TransportSocketOptions::Http11ProxyInfo> proxy_info;
64

            
65
49939
  bool needs_transport_socket_options = false;
66
49939
  if (auto typed_data = filter_state.getDataReadOnly<UpstreamServerName>(UpstreamServerName::key());
67
49939
      typed_data != nullptr) {
68
2289
    server_name = typed_data->value();
69
2289
    needs_transport_socket_options = true;
70
2289
  }
71

            
72
49939
  if (auto typed_data = filter_state.getDataReadOnly<Network::ApplicationProtocols>(
73
49939
          Network::ApplicationProtocols::key());
74
49939
      typed_data != nullptr) {
75
4
    application_protocols = typed_data->value();
76
4
    needs_transport_socket_options = true;
77
4
  }
78

            
79
49939
  if (auto typed_data =
80
49939
          filter_state.getDataReadOnly<UpstreamSubjectAltNames>(UpstreamSubjectAltNames::key());
81
49939
      typed_data != nullptr) {
82
158
    subject_alt_names = typed_data->value();
83
158
    needs_transport_socket_options = true;
84
158
  }
85

            
86
49939
  if (auto typed_data =
87
49939
          filter_state.getDataReadOnly<ProxyProtocolFilterState>(ProxyProtocolFilterState::key());
88
49939
      typed_data != nullptr) {
89
46604
    proxy_protocol_options.emplace(typed_data->value());
90
46604
    needs_transport_socket_options = true;
91
46604
  }
92

            
93
49939
  if (auto typed_data = filter_state.getDataReadOnly<Http11ProxyInfoFilterState>(
94
49939
          Http11ProxyInfoFilterState::key());
95
49939
      typed_data != nullptr) {
96
16
    proxy_info = std::make_unique<TransportSocketOptions::Http11ProxyInfo>(typed_data->hostname(),
97
16
                                                                           typed_data->address());
98
16
    needs_transport_socket_options = true;
99
16
  }
100

            
101
49939
  StreamInfo::FilterState::ObjectsPtr objects = filter_state.objectsSharedWithUpstreamConnection();
102
49939
  if (!objects->empty()) {
103
43
    needs_transport_socket_options = true;
104
43
  }
105

            
106
49939
  if (needs_transport_socket_options) {
107
46643
    return std::make_shared<Network::TransportSocketOptionsImpl>(
108
46643
        server_name, std::move(subject_alt_names), std::move(application_protocols),
109
46643
        std::move(alpn_fallback), proxy_protocol_options, std::move(objects),
110
46643
        std::move(proxy_info));
111
47809
  } else {
112
3296
    return nullptr;
113
3296
  }
114
49939
}
115

            
116
} // namespace Network
117
} // namespace Envoy