1
1
#include " source/client/options_impl.h"
2
2
3
+ #include < sys/socket.h>
4
+
5
+ #include < cerrno>
6
+ #include < cstdint>
7
+ #include < exception>
8
+
3
9
#include " external/envoy/source/common/protobuf/message_validator_impl.h"
4
10
#include " external/envoy/source/common/protobuf/protobuf.h"
5
11
#include " external/envoy/source/common/protobuf/utility.h"
12
18
#include " source/common/version_info.h"
13
19
14
20
#include " absl/strings/numbers.h"
21
+ #include " absl/strings/str_cat.h"
15
22
#include " absl/strings/str_split.h"
16
23
#include " absl/types/optional.h"
17
- #include " absl/strings/str_cat.h"
18
-
19
24
#include " fmt/ranges.h"
20
- #include < cerrno>
21
- #include < cstdint>
22
- #include < exception>
23
- #include < sys/socket.h>
24
25
25
26
namespace Nighthawk {
26
27
namespace Client {
@@ -36,8 +37,8 @@ using ::nighthawk::client::Protocol;
36
37
uint16_t OptionsImpl::GetAvailablePort (bool udp) {
37
38
int family = (address_family_ == nighthawk::client::AddressFamily::V4) ? AF_INET : AF_INET6;
38
39
int sock = socket (family, udp ? SOCK_DGRAM : SOCK_STREAM, udp ? 0 : IPPROTO_TCP);
39
- if (sock < 0 ) {
40
- throw NighthawkException (absl::StrCat (" could not create socket: " , strerror (errno)) );
40
+ if (sock < 0 ) {
41
+ throw NighthawkException (absl::StrCat (" could not create socket: " , strerror (errno)));
41
42
return 0 ;
42
43
}
43
44
@@ -53,52 +54,48 @@ uint16_t OptionsImpl::GetAvailablePort(bool udp) {
53
54
struct sockaddr_in6 sin6;
54
55
} addr;
55
56
size_t size;
56
- if (family == AF_INET){
57
+ if (family == AF_INET) {
57
58
size = sizeof (sockaddr_in);
58
59
memset (&addr, 0 , size);
59
60
addr.sin .sin_family = AF_INET;
60
61
addr.sin .sin_addr .s_addr = INADDR_ANY;
61
62
addr.sin .sin_port = 0 ;
62
- }
63
- else {
63
+ } else {
64
64
size = sizeof (sockaddr_in6);
65
65
memset (&addr, 0 , size);
66
66
addr.sin6 .sin6_family = AF_INET6;
67
67
addr.sin6 .sin6_addr = in6addr_any;
68
- addr.sin6 .sin6_port = 0 ;
68
+ addr.sin6 .sin6_port = 0 ;
69
69
}
70
70
71
- if (bind (sock, reinterpret_cast <struct sockaddr *>(&addr), size) < 0 ) {
72
- if (errno == EADDRINUSE) {
73
- throw NighthawkException (absl::StrCat (" Port allocated already in use" ));
74
- } else {
75
- throw NighthawkException (absl::StrCat (" Could not bind to process: " , strerror (errno)) );
76
- }
77
- return 0 ;
71
+ if (bind (sock, reinterpret_cast <struct sockaddr *>(&addr), size) < 0 ) {
72
+ if (errno == EADDRINUSE) {
73
+ throw NighthawkException (absl::StrCat (" Port allocated already in use" ));
74
+ } else {
75
+ throw NighthawkException (absl::StrCat (" Could not bind to process: " , strerror (errno)));
76
+ }
77
+ return 0 ;
78
78
}
79
79
80
80
socklen_t len = size;
81
- if (getsockname (sock, reinterpret_cast <struct sockaddr *>(&addr), &len) == -1 ) {
82
- throw NighthawkException (absl::StrCat (" Could not get sock name: " , strerror (errno)) );
83
- return 0 ;
81
+ if (getsockname (sock, reinterpret_cast <struct sockaddr *>(&addr), &len) == -1 ) {
82
+ throw NighthawkException (absl::StrCat (" Could not get sock name: " , strerror (errno)));
83
+ return 0 ;
84
84
}
85
85
86
- uint16_t port = ntohs (family == AF_INET
87
- ? reinterpret_cast <struct sockaddr_in *>(&addr)->sin_port
88
- : reinterpret_cast <struct sockaddr_in6 *>(&addr)->sin6_port );
86
+ uint16_t port =
87
+ ntohs (family == AF_INET ? reinterpret_cast <struct sockaddr_in *>(&addr)->sin_port
88
+ : reinterpret_cast <struct sockaddr_in6 *>(&addr)->sin6_port );
89
89
90
90
// close the socket, freeing the port to be used later.
91
- if (close (sock) < 0 ) {
92
- throw NighthawkException (absl::StrCat (" Could not close socket: " , strerror (errno)) );
93
- return 0 ;
91
+ if (close (sock) < 0 ) {
92
+ throw NighthawkException (absl::StrCat (" Could not close socket: " , strerror (errno)));
93
+ return 0 ;
94
94
}
95
95
96
96
return port;
97
-
98
97
}
99
98
100
-
101
-
102
99
OptionsImpl::OptionsImpl (int argc, const char * const * argv) {
103
100
setNonTrivialDefaults ();
104
101
// Override some defaults, we are in CLI-mode.
@@ -159,8 +156,8 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
159
156
" {quic_protocol_options:{max_concurrent_streams:1}}" ,
160
157
false , " " , " string" , cmd);
161
158
162
- std::vector<std::string> tunnel_protocols = {" http1" , " http2" , " http3" };
163
- TCLAP::ValuesConstraint<std::string> tunnel_protocols_allowed (tunnel_protocols);
159
+ std::vector<std::string> tunnel_protocols = {" http1" , " http2" , " http3" };
160
+ TCLAP::ValuesConstraint<std::string> tunnel_protocols_allowed (tunnel_protocols);
164
161
TCLAP::ValueArg<std::string> tunnel_protocol (
165
162
" " , " tunnel-protocol" ,
166
163
fmt::format (
@@ -170,7 +167,8 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
170
167
" and protocol = HTTP3 and tunnel_protocol = HTTP3"
171
168
" When protocol is set to HTTP3 and tunneling is enabled, the CONNECT-UDP method is used"
172
169
" Otherwise, the HTTP CONNECT method is used" ,
173
- absl::AsciiStrToLower (nighthawk::client::Protocol_ProtocolOptions_Name (tunnel_protocol_))),
170
+ absl::AsciiStrToLower (
171
+ nighthawk::client::Protocol_ProtocolOptions_Name (tunnel_protocol_))),
174
172
false , " " , &tunnel_protocols_allowed, cmd);
175
173
TCLAP::ValueArg<std::string> tunnel_uri (
176
174
" " , " tunnel-uri" ,
@@ -182,7 +180,8 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
182
180
TCLAP::ValueArg<std::string> tunnel_http3_protocol_options (
183
181
" " , " tunnel-http3-protocol-options" ,
184
182
" Tunnel HTTP3 protocol options (envoy::config::core::v3::Http3ProtocolOptions) in json. If "
185
- " specified, Nighthawk uses these HTTP3 protocol options when encapsulating requests. Only valid "
183
+ " specified, Nighthawk uses these HTTP3 protocol options when encapsulating requests. Only "
184
+ " valid "
186
185
" with --tunnel-protocol http3." ,
187
186
false , " " , " string" , cmd);
188
187
TCLAP::ValueArg<std::string> tunnel_tls_context (
@@ -208,8 +207,7 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
208
207
fmt::format (
209
208
" The number of concurrent event loops that should be used. Specify 'auto' to let "
210
209
" Nighthawk use half the threads specified via the concurrency flag for tunneling." ,
211
- " Default: auto" ,
212
- tunnel_concurrency_),
210
+ " Default: auto" , tunnel_concurrency_),
213
211
false , " auto" , " string" , cmd);
214
212
215
213
std::vector<std::string> log_levels = {" trace" , " debug" , " info" , " warn" , " error" , " critical" };
@@ -797,31 +795,31 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
797
795
if (tunnel_protocol.isSet ()) {
798
796
std::string upper_cased = tunnel_protocol.getValue ();
799
797
absl::AsciiStrToUpper (&upper_cased);
800
- RELEASE_ASSERT (nighthawk::client::Protocol::ProtocolOptions_Parse (upper_cased, &tunnel_protocol_),
801
- " Failed to parse tunnel protocol" );
802
- if (!tunnel_uri.isSet ()){
798
+ RELEASE_ASSERT (
799
+ nighthawk::client::Protocol::ProtocolOptions_Parse (upper_cased, &tunnel_protocol_),
800
+ " Failed to parse tunnel protocol" );
801
+ if (!tunnel_uri.isSet ()) {
803
802
throw MalformedArgvException (" --tunnel-protocol requires --tunnel-uri" );
804
803
}
805
804
tunnel_uri_ = tunnel_uri.getValue ();
806
805
encap_port_ = GetAvailablePort (/* udp=*/ protocol_ == Protocol::HTTP3);
807
806
tunnel_concurrency_ = tunnel_concurrency.getValue ();
808
807
809
- }
810
- else if (tunnel_uri.isSet () ||tunnel_http3_protocol_options.isSet ()
811
- || tunnel_tls_context.isSet () || tunnel_concurrency.isSet ()) {
808
+ } else if (tunnel_uri.isSet () || tunnel_http3_protocol_options.isSet () ||
809
+ tunnel_tls_context.isSet () || tunnel_concurrency.isSet ()) {
812
810
throw MalformedArgvException (" tunnel flags require --tunnel-protocol" );
813
811
}
814
812
815
813
if (!tunnel_tls_context.getValue ().empty ()) {
816
814
try {
817
- tunnel_tls_context_.emplace (envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext ());
815
+ tunnel_tls_context_.emplace (
816
+ envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext ());
818
817
Envoy::MessageUtil::loadFromJson (tunnel_tls_context.getValue (), tunnel_tls_context_.value (),
819
818
Envoy::ProtobufMessage::getStrictValidationVisitor ());
820
- } catch (const Envoy::EnvoyException& e) {
819
+ } catch (const Envoy::EnvoyException& e) {
821
820
throw MalformedArgvException (e.what ());
822
821
}
823
- }
824
- else if (tunnel_protocol_ == Protocol::HTTP3){
822
+ } else if (tunnel_protocol_ == Protocol::HTTP3) {
825
823
throw MalformedArgvException (" --tunnel-tls-context is required to use --tunnel-protocol http3" );
826
824
}
827
825
@@ -841,12 +839,14 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv) {
841
839
}
842
840
}
843
841
844
- if (tunnel_protocol.isSet ()){
845
- if (tunnel_protocol_ == Protocol::HTTP3 && protocol_ == Protocol::HTTP3){
846
- throw MalformedArgvException (" --protocol HTTP3 over --tunnel-protocol HTTP3 is not supported" );
842
+ if (tunnel_protocol.isSet ()) {
843
+ if (tunnel_protocol_ == Protocol::HTTP3 && protocol_ == Protocol::HTTP3) {
844
+ throw MalformedArgvException (
845
+ " --protocol HTTP3 over --tunnel-protocol HTTP3 is not supported" );
847
846
}
848
- if (tunnel_protocol_ == Protocol::HTTP1 && protocol_ == Protocol::HTTP3){
849
- throw MalformedArgvException (" --protocol HTTP3 over --tunnel-protocol HTTP1 is not supported" );
847
+ if (tunnel_protocol_ == Protocol::HTTP1 && protocol_ == Protocol::HTTP3) {
848
+ throw MalformedArgvException (
849
+ " --protocol HTTP3 over --tunnel-protocol HTTP1 is not supported" );
850
850
}
851
851
}
852
852
@@ -863,7 +863,6 @@ Envoy::Http::Protocol OptionsImpl::protocol() const {
863
863
}
864
864
}
865
865
866
-
867
866
Envoy::Http::Protocol OptionsImpl::tunnelProtocol () const {
868
867
if (tunnel_protocol_ == Protocol::HTTP2) {
869
868
return Envoy::Http::Protocol::Http2;
@@ -937,18 +936,20 @@ OptionsImpl::OptionsImpl(const nighthawk::client::CommandLineOptions& options) {
937
936
burst_size_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options, burst_size, burst_size_);
938
937
address_family_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options, address_family, address_family_);
939
938
940
-
941
- if (options.has_tunnel_options ()) {
942
- tunnel_protocol_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options. tunnel_options (), tunnel_protocol, tunnel_protocol_);
939
+ if (options. has_tunnel_options ()) {
940
+ tunnel_protocol_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options.tunnel_options (), tunnel_protocol,
941
+ tunnel_protocol_);
943
942
tunnel_uri_ = options.tunnel_options ().tunnel_uri ();
944
-
943
+
945
944
// we must find an available port for the encap listener
946
945
encap_port_ = GetAvailablePort (/* is_udp=*/ protocol_ == Protocol::HTTP3);
947
- concurrency_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options.tunnel_options (), tunnel_concurrency, tunnel_concurrency_);
946
+ concurrency_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT (options.tunnel_options (), tunnel_concurrency,
947
+ tunnel_concurrency_);
948
948
949
949
if (options.tunnel_options ().has_tunnel_http3_protocol_options ()) {
950
950
tunnel_http3_protocol_options_.emplace (Http3ProtocolOptions ());
951
- tunnel_http3_protocol_options_.value ().MergeFrom (options.tunnel_options ().tunnel_http3_protocol_options ());
951
+ tunnel_http3_protocol_options_.value ().MergeFrom (
952
+ options.tunnel_options ().tunnel_http3_protocol_options ());
952
953
}
953
954
tunnel_tls_context_->MergeFrom (options.tunnel_options ().tunnel_tls_context ());
954
955
}
0 commit comments