11#include " net/proxy/shadowsocks/connector.h"
22
33#include < chrono>
4+ #include < limits>
45#include < memory>
56#include < utility>
67
@@ -19,13 +20,7 @@ class Connector::TcpStream : public net::Stream {
1920 explicit TcpStream (Connector &connector);
2021
2122 void start (
22- const tcp::endpoint &endpoint,
23- const_buffer initial_data,
24- absl::AnyInvocable<void (std::error_code) &&> callback);
25-
26- void start (
27- std::string_view host,
28- uint16_t port,
23+ const HostPort &target,
2924 const_buffer initial_data,
3025 absl::AnyInvocable<void (std::error_code) &&> callback);
3126
@@ -78,34 +73,13 @@ bool Connector::init(const InitOptions &options) {
7873}
7974
8075void Connector::connect (
81- const tcp::endpoint &endpoint ,
76+ const HostPort &target ,
8277 const_buffer initial_data,
8378 absl::AnyInvocable<void (
8479 std::error_code, std::unique_ptr<Stream>) &&> callback) {
8580 auto stream = std::make_unique<TcpStream>(*this );
8681 stream->start (
87- endpoint,
88- initial_data,
89- [stream = std::move (stream), callback = std::move (callback)](
90- std::error_code ec) mutable {
91- if (ec) {
92- std::move (callback)(ec, nullptr );
93- return ;
94- }
95- std::move (callback)({}, std::move (stream));
96- });
97- }
98-
99- void Connector::connect (
100- std::string_view host,
101- uint16_t port,
102- const_buffer initial_data,
103- absl::AnyInvocable<void (
104- std::error_code, std::unique_ptr<Stream>) &&> callback) {
105- auto stream = std::make_unique<TcpStream>(*this );
106- stream->start (
107- host,
108- port,
82+ target,
10983 initial_data,
11084 [stream = std::move (stream), callback = std::move (callback)](
11185 std::error_code ec) mutable {
@@ -128,79 +102,61 @@ Connector::TcpStream::TcpStream(Connector &connector)
128102 : connector_(connector) {}
129103
130104void Connector::TcpStream::start (
131- const tcp::endpoint &endpoint ,
105+ const HostPort &target ,
132106 const_buffer initial_data,
133107 absl::AnyInvocable<void (std::error_code) &&> callback) {
134108 encryptor_.init (connector_.pre_shared_key_ );
135109 connector_.salt_filter_ .insert ({
136110 encryptor_.salt (), connector_.pre_shared_key_ .method ().salt_size ()});
137- // TODO: split chunks if too large
111+
112+ // Request fixed-length header.
138113 encryptor_.start_chunk ();
139- address address = endpoint.address ();
140- size_t address_size = address.is_v4 () ? 4 : 16 ;
141- size_t padding_size = absl::Uniform<size_t >(
142- connector_.bit_gen_ ,
143- connector_.min_padding_length_ ,
144- connector_.max_padding_length_ );
114+ size_t header_size;
115+ if (target.is_name_port ()) {
116+ header_size = 4 + target.name ().size ();
117+ } else if (target.address ().is_v4 ()) {
118+ header_size = 7 ;
119+ } else {
120+ header_size = 19 ;
121+ }
122+ size_t padding_size;
145123 if (connector_.pre_shared_key_ .method ().is_spec_2022 ()) {
146124 encryptor_.push_u8 (0 ); // request
147125 encryptor_.push_big_u64 (
148126 std::chrono::duration_cast<std::chrono::seconds>(
149127 std::chrono::system_clock::now ().time_since_epoch ()).count ());
150- encryptor_.push_big_u16 (
151- address_size + padding_size + initial_data.size () + 5 );
152- } else {
153- encryptor_.push_big_u16 (address_size + initial_data.size () + 3 );
128+ padding_size = absl::Uniform<size_t >(
129+ connector_.bit_gen_ ,
130+ connector_.min_padding_length_ ,
131+ connector_.max_padding_length_ );
132+ header_size += 2 + padding_size;
154133 }
155- encryptor_.finish_chunk ();
156- encryptor_.start_chunk ();
157- if (address.is_v4 ()) {
158- encryptor_.push_u8 (1 ); // ipv4
159- encryptor_.push_buffer (address.to_v4 ().to_bytes ());
160- } else {
161- encryptor_.push_u8 (4 ); // ipv6
162- encryptor_.push_buffer (address.to_v6 ().to_bytes ());
163- }
164- encryptor_.push_big_u16 (endpoint.port ());
165- if (connector_.pre_shared_key_ .method ().is_spec_2022 ()) {
166- encryptor_.push_big_u16 (padding_size);
167- encryptor_.push_random (padding_size);
134+ header_size += initial_data.size ();
135+ if (header_size > std::numeric_limits<uint16_t >::max ()) {
136+ std::move (callback)(make_error_code (std::errc::message_size));
137+ return ;
168138 }
169- encryptor_.push_buffer ({initial_data. data (), initial_data. size ()} );
139+ encryptor_.push_big_u16 (header_size );
170140 encryptor_.finish_chunk ();
171- connect (std::move (callback));
172- }
173141
174- void Connector::TcpStream::start (
175- std::string_view host,
176- uint16_t port,
177- const_buffer initial_data,
178- absl::AnyInvocable<void (std::error_code) &&> callback) {
179- encryptor_.init (connector_.pre_shared_key_ );
180- connector_.salt_filter_ .insert ({
181- encryptor_.salt (), connector_.pre_shared_key_ .method ().salt_size ()});
182- // TODO: split chunks if too large
142+ // Request variable-length header.
183143 encryptor_.start_chunk ();
184- size_t padding_size = absl::Uniform< size_t >(
185- connector_. bit_gen_ ,
186- connector_. min_padding_length_ ,
187- connector_. max_padding_length_ );
188- if (connector_. pre_shared_key_ . method (). is_spec_2022 ()) {
189- encryptor_. push_u8 ( 0 ); // request
190- encryptor_.push_big_u64 (
191- std::chrono::duration_cast<std::chrono::seconds>(
192- std::chrono::system_clock::now (). time_since_epoch ()). count ());
193- encryptor_.push_big_u16 (
194- host. size () + padding_size + initial_data. size () + 6 );
144+ if (target. is_name_port ()) {
145+ encryptor_. push_u8 ( 3 ); // host
146+ if (target. name (). size () > std::numeric_limits< uint8_t >:: max ()) {
147+ std::move (callback)( make_error_code (std::errc::invalid_argument) );
148+ return ;
149+ }
150+ encryptor_.push_u8 (target. name (). size ());
151+ encryptor_. push_buffer (target. name ());
152+ } else if (target. address (). is_v4 ()) {
153+ encryptor_.push_u8 ( 1 ); // ipv4
154+ encryptor_. push_buffer (target. address (). to_v4 (). to_bytes () );
195155 } else {
196- encryptor_.push_big_u16 (host.size () + initial_data.size () + 4 );
156+ encryptor_.push_u8 (4 ); // ipv6
157+ encryptor_.push_buffer (target.address ().to_v6 ().to_bytes ());
197158 }
198- encryptor_.finish_chunk ();
199- encryptor_.start_chunk ();
200- encryptor_.push_u8 (3 ); // host
201- encryptor_.push_u8 (host.size ());
202- encryptor_.push_buffer (host);
203- encryptor_.push_big_u16 (port);
159+ encryptor_.push_big_u16 (target.port ());
204160 if (connector_.pre_shared_key_ .method ().is_spec_2022 ()) {
205161 encryptor_.push_big_u16 (padding_size);
206162 encryptor_.push_random (padding_size);
0 commit comments