Skip to content

Commit 40f6e7b

Browse files
committed
Fixes to ssl.alpn_port_override
1 parent 2cdb425 commit 40f6e7b

File tree

6 files changed

+33
-26
lines changed

6 files changed

+33
-26
lines changed

docs/config.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ The NAT config is for transparent proxy. You'll need to [setup iptables rules](h
174174
"alpn": [
175175
"http/1.1"
176176
],
177-
"alpn_port_override" : {
177+
"alpn_port_override": {
178178
"h2": 81
179179
},
180180
"reuse_session": true,
@@ -219,7 +219,7 @@ The NAT config is for transparent proxy. You'll need to [setup iptables rules](h
219219
- `cipher_tls13`: a cipher list for TLS 1.3 to use
220220
- `prefer_server_cipher`: whether to prefer server cipher list in a connection
221221
- `alpn`: a list of `ALPN` protocols to reply
222-
- alpn_port_override: overrides the remote port to the specified value if an ALPN is matched. Useful for running nginx http1.1 and http2 on different ports (#226).
222+
- `alpn_port_override`: overrides the remote port to the specified value if an `ALPN` is matched. Useful for running NGINX with HTTP/1.1 and HTTP/2 Cleartext on different ports.
223223
- `reuse_session`: whether to reuse `SSL` session
224224
- `session_ticket`: whether to use session tickets for session resumption
225225
- `session_timeout`: if `reuse_session` is set to `true`, specify `SSL` session timeout

examples/server.json-example

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"alpn": [
2020
"http/1.1"
2121
],
22-
"alpn_port_override" : {
22+
"alpn_port_override": {
2323
"h2": 81
2424
},
2525
"reuse_session": true,

src/core/config.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ void Config::populate(const ptree &tree) {
5959
target_addr = tree.get("target_addr", string());
6060
target_port = tree.get("target_port", uint16_t());
6161
map<string, string>().swap(password);
62-
for (auto& item: tree.get_child("password")) {
63-
string p = item.second.get_value<string>();
64-
password[SHA224(p)] = p;
62+
if (tree.get_child_optional("password")) {
63+
for (auto& item: tree.get_child("password")) {
64+
string p = item.second.get_value<string>();
65+
password[SHA224(p)] = p;
66+
}
6567
}
6668
udp_timeout = tree.get("udp_timeout", 60);
6769
log_level = static_cast<Log::Level>(tree.get("log_level", 1));
68-
map<string, uint16_t>().swap(alpn_port);
6970
ssl.verify = tree.get("ssl.verify", true);
7071
ssl.verify_hostname = tree.get("ssl.verify_hostname", true);
7172
ssl.cert = tree.get("ssl.cert", string());
@@ -76,14 +77,17 @@ void Config::populate(const ptree &tree) {
7677
ssl.prefer_server_cipher = tree.get("ssl.prefer_server_cipher", true);
7778
ssl.sni = tree.get("ssl.sni", string());
7879
ssl.alpn = "";
79-
auto alpn_port_override = tree.get_child_optional("ssl.alpn_port_override");
80-
for (auto& item: tree.get_child("ssl.alpn")) {
81-
string proto = item.second.get_value<string>();
82-
ssl.alpn += (char)((unsigned char)(proto.length()));
83-
ssl.alpn += proto;
84-
if (alpn_port_override) {
85-
auto it = alpn_port_override->find(proto);
86-
alpn_port[proto] = it != alpn_port_override->not_found() ? it->second.get_value<uint16_t>() : remote_port;
80+
if (tree.get_child_optional("ssl.alpn")) {
81+
for (auto& item: tree.get_child("ssl.alpn")) {
82+
string proto = item.second.get_value<string>();
83+
ssl.alpn += (char)((unsigned char)(proto.length()));
84+
ssl.alpn += proto;
85+
}
86+
}
87+
map<string, uint16_t>().swap(ssl.alpn_port_override);
88+
if (tree.get_child_optional("ssl.alpn_port_override")) {
89+
for (auto& item: tree.get_child("ssl.alpn_port_override")) {
90+
ssl.alpn_port_override[item.first] = item.second.get_value<uint16_t>();
8791
}
8892
}
8993
ssl.reuse_session = tree.get("ssl.reuse_session", true);

src/core/config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class Config {
4242
std::map<std::string, std::string> password;
4343
int udp_timeout;
4444
Log::Level log_level;
45-
std::map<std::string, uint16_t> alpn_port;
4645
class SSLConfig {
4746
public:
4847
bool verify;
@@ -55,6 +54,7 @@ class Config {
5554
bool prefer_server_cipher;
5655
std::string sni;
5756
std::string alpn;
57+
std::map<std::string, uint16_t> alpn_port_override;
5858
bool reuse_session;
5959
bool session_ticket;
6060
long session_timeout;

src/session/serversession.cpp

+12-10
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,19 @@ void ServerSession::in_recv(const string &data) {
153153
}
154154
}
155155
string query_addr = valid ? req.address.address : config.remote_addr;
156-
string query_port = [&]() {
156+
string query_port = to_string([&]() {
157157
if (valid) {
158-
return to_string(req.address.port);
159-
} else {
160-
const unsigned char *alpn_out = nullptr;
161-
unsigned int alpn_len = 0;
162-
SSL_get0_alpn_selected(in_socket.native_handle(), &alpn_out, &alpn_len);
163-
auto it = config.alpn_port.find(std::string(alpn_out, alpn_out + alpn_len));
164-
return to_string((it != config.alpn_port.end()) ? it->second : config.remote_port);
158+
return req.address.port;
159+
}
160+
const unsigned char *alpn_out;
161+
unsigned int alpn_len;
162+
SSL_get0_alpn_selected(in_socket.native_handle(), &alpn_out, &alpn_len);
163+
if (alpn_out == NULL) {
164+
return config.remote_port;
165165
}
166-
}();
166+
auto it = config.ssl.alpn_port_override.find(std::string(alpn_out, alpn_out + alpn_len));
167+
return it == config.ssl.alpn_port_override.end() ? config.remote_port : it->second;
168+
}());
167169
if (valid) {
168170
out_write_buf = req.payload;
169171
if (req.command == TrojanRequest::UDP_ASSOCIATE) {
@@ -176,7 +178,7 @@ void ServerSession::in_recv(const string &data) {
176178
Log::log_with_endpoint(in_endpoint, "requested connection to " + req.address.address + ':' + to_string(req.address.port), Log::INFO);
177179
}
178180
} else {
179-
Log::log_with_endpoint(in_endpoint, "not trojan request, connecting to " + config.remote_addr + ':' + query_port, Log::WARN);
181+
Log::log_with_endpoint(in_endpoint, "not trojan request, connecting to " + query_addr + ':' + query_port, Log::WARN);
180182
out_write_buf = data;
181183
}
182184
sent_len += out_write_buf.length();

tests/LinuxSmokeTest/server.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"cipher_tls13": "",
1515
"prefer_server_cipher": true,
1616
"alpn": [],
17+
"alpn_port_override": {},
1718
"reuse_session": false,
1819
"session_ticket": false,
1920
"session_timeout": 600,

0 commit comments

Comments
 (0)