From db5e14c1e89745a85403ef7ed29bc716300b9371 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Wed, 14 Oct 2026 16:42:27 +0800 Subject: [PATCH] Add --max-dns-queries / max_dns_queries Sizes the resolver's query pool, the last of the capacity settings the no-heap-after-startup design calls for. Defaults are unchanged: the connection limit (plus 64 on ss-server, which also resolves for its statistics). --- doc/shadowsocks-c.md | 1 + src/common.h | 1 + src/jconf.cpp | 2 ++ src/jconf.h | 1 + src/local.cpp | 14 +++++++++++++- src/server.cpp | 16 ++++++++++++++-- src/utils.cpp | 10 ++++++++++ 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/doc/shadowsocks-c.md b/doc/shadowsocks-c.md index 40df44e8..75aa5a4d 100644 --- a/doc/shadowsocks-c.md +++ b/doc/shadowsocks-c.md @@ -81,6 +81,7 @@ The config file equivalent of command line options is listed as examples below. - `--no-delay`: `"no_delay": true` - `--max-connections 1024`: `"max_connections": 1024` - `--max-udp-sessions 512`: `"max_udp_sessions": 512` +- `--max-dns-queries 1024`: `"max_dns_queries": 1024` (ss-server and ss-local) - `--printable-salt`: `"printable_salt": true` (ss-local only) - `--plugin "obfs-server"`: `"plugin": "obfs-server"` - `--plugin-opts "obfs=http"`: `"plugin_opts": "obfs=http"` diff --git a/src/common.h b/src/common.h index d784fc0c..6d90746c 100644 --- a/src/common.h +++ b/src/common.h @@ -56,6 +56,7 @@ enum { GETOPT_VAL_NODELAY, GETOPT_VAL_MAX_CONNECTIONS, GETOPT_VAL_MAX_UDP_SESSIONS, + GETOPT_VAL_MAX_DNS_QUERIES, GETOPT_VAL_PRINTABLE_SALT, GETOPT_VAL_ACL, GETOPT_VAL_MTU, diff --git a/src/jconf.cpp b/src/jconf.cpp index d6c82546..a92c0640 100644 --- a/src/jconf.cpp +++ b/src/jconf.cpp @@ -393,6 +393,8 @@ read_jconf(const char *file) conf.max_connections = to_nonnegative_int(value, name); } else if (strcmp(name, "max_udp_sessions") == 0) { conf.max_udp_sessions = to_nonnegative_int(value, name); + } else if (strcmp(name, "max_dns_queries") == 0) { + conf.max_dns_queries = to_nonnegative_int(value, name); } else if (strcmp(name, "nofile") == 0) { conf.nofile = to_nonnegative_int(value, name); } else if (strcmp(name, "nameserver") == 0) { diff --git a/src/jconf.h b/src/jconf.h index 6e51ce8e..7ca05f71 100644 --- a/src/jconf.h +++ b/src/jconf.h @@ -94,6 +94,7 @@ typedef struct { int no_delay; int max_connections; int max_udp_sessions; + int max_dns_queries; int printable_salt; int tcp_tproxy; char *workdir; diff --git a/src/local.cpp b/src/local.cpp index c29f99eb..4c7f7e85 100644 --- a/src/local.cpp +++ b/src/local.cpp @@ -112,6 +112,7 @@ int fast_open = 0; static int no_delay = 0; static int max_connections = 0; static int max_udp_sessions = 0; +static int max_dns_queries = 0; static int printable_salt = 0; static int udp_fd = 0; static int ret_val = 0; @@ -294,7 +295,8 @@ struct Relays { config.acl_hooks.match_host = &acl_match_host; config.acl_hooks.mode = &get_acl_mode; config.acl_hooks.outbound_blocked = &outbound_block_match_host; - if (!resolver.init(*loop, NULL, ipv6first != 0, config.max_connections)) { + if (!resolver.init(*loop, NULL, ipv6first != 0, + max_dns_queries > 0 ? (uint32_t)max_dns_queries : config.max_connections)) { return false; } resolving = true; @@ -584,6 +586,7 @@ Same behavior as `-S`; see that option for details. Short alias: `-S`. \snippet{doc} utils.cpp cli_long_no_delay \snippet{doc} utils.cpp cli_long_max_connections \snippet{doc} utils.cpp cli_long_max_udp_sessions +\snippet{doc} utils.cpp cli_long_max_dns_queries \snippet{doc} utils.cpp cli_long_acl \snippet{doc} utils.cpp cli_long_mtu \snippet{doc} utils.cpp cli_long_mptcp @@ -628,6 +631,7 @@ Same behavior as `-S`; see that option for details. Short alias: `-S`. { "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY }, { "max-connections", required_argument, NULL, GETOPT_VAL_MAX_CONNECTIONS }, { "max-udp-sessions", required_argument, NULL, GETOPT_VAL_MAX_UDP_SESSIONS }, + { "max-dns-queries", required_argument, NULL, GETOPT_VAL_MAX_DNS_QUERIES }, { "acl", required_argument, NULL, GETOPT_VAL_ACL }, { "mtu", required_argument, NULL, GETOPT_VAL_MTU }, { "mptcp", no_argument, NULL, GETOPT_VAL_MPTCP }, @@ -696,6 +700,11 @@ Same behavior as `-S`; see that option for details. Short alias: `-S`. cli_error("invalid UDP session limit", c, NULL); } break; + case GETOPT_VAL_MAX_DNS_QUERIES: + if (ss_parse_int(optarg, 1, 1 << 20, &max_dns_queries) == -1) { + cli_error("invalid DNS query limit", c, NULL); + } + break; case GETOPT_VAL_NODELAY: no_delay = 1; LOGI("enable TCP no-delay"); @@ -943,6 +952,9 @@ Same behavior as `-S`; see that option for details. Short alias: `-S`. if (max_udp_sessions == 0) { max_udp_sessions = conf->max_udp_sessions; } + if (max_dns_queries == 0) { + max_dns_queries = conf->max_dns_queries; + } if (printable_salt == 0) { printable_salt = conf->printable_salt; } diff --git a/src/server.cpp b/src/server.cpp index b008a27a..ae6c3599 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -131,6 +131,7 @@ int fast_open = 0; static int no_delay = 0; static int max_connections = 0; static int max_udp_sessions = 0; +static int max_dns_queries = 0; static int ret_val = 0; #ifdef HAVE_SETRLIMIT @@ -972,6 +973,7 @@ Same behavior as `-d`; see that option for details. Short alias: `-d`. \snippet{doc} utils.cpp cli_long_no_delay \snippet{doc} utils.cpp cli_long_max_connections \snippet{doc} utils.cpp cli_long_max_udp_sessions +\snippet{doc} utils.cpp cli_long_max_dns_queries \snippet{doc} utils.cpp cli_long_acl \snippet{doc} utils.cpp cli_long_manager_address \snippet{doc} utils.cpp cli_long_mtu @@ -1011,6 +1013,7 @@ Same behavior as `-d`; see that option for details. Short alias: `-d`. { "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY }, { "max-connections", required_argument, NULL, GETOPT_VAL_MAX_CONNECTIONS }, { "max-udp-sessions", required_argument, NULL, GETOPT_VAL_MAX_UDP_SESSIONS }, + { "max-dns-queries", required_argument, NULL, GETOPT_VAL_MAX_DNS_QUERIES }, { "acl", required_argument, NULL, GETOPT_VAL_ACL }, { "manager-address", required_argument, NULL, GETOPT_VAL_MANAGER_ADDRESS }, @@ -1062,6 +1065,11 @@ Same behavior as `-d`; see that option for details. Short alias: `-d`. cli_error("invalid UDP session limit", c, NULL); } break; + case GETOPT_VAL_MAX_DNS_QUERIES: + if (ss_parse_int(optarg, 1, 1 << 20, &max_dns_queries) == -1) { + cli_error("invalid DNS query limit", c, NULL); + } + break; case GETOPT_VAL_NODELAY: no_delay = 1; LOGI("enable TCP no-delay"); @@ -1268,6 +1276,9 @@ Same behavior as `-d`; see that option for details. Short alias: `-d`. if (max_udp_sessions == 0) { max_udp_sessions = conf->max_udp_sessions; } + if (max_dns_queries == 0) { + max_dns_queries = conf->max_dns_queries; + } if (reuse_port == 0) { reuse_port = conf->reuse_port; } @@ -1530,8 +1541,9 @@ Same behavior as `-d`; see that option for details. Short alias: `-d`. ss::relay::TcpRelay tcp_relay; ss::relay::UdpRelay udp_relay; bool tcp_running = false; - if (!tcp_resolver.init(tcp_loop, nameservers, ipv6first != 0, - (max_connections > 0 ? max_connections : DEFAULT_MAX_CONNECTIONS) + 64)) { + if (max_dns_queries == 0) + max_dns_queries = (max_connections > 0 ? max_connections : DEFAULT_MAX_CONNECTIONS) + 64; + if (!tcp_resolver.init(tcp_loop, nameservers, ipv6first != 0, max_dns_queries)) { FATAL("failed to set up the resolver"); } stat_resolver = &tcp_resolver; diff --git a/src/utils.cpp b/src/utils.cpp index e63960b2..e6d20bd6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -498,6 +498,13 @@ for ss-server). When the table is full, the least recently used one is dropped. [cli_long_max_udp_sessions] */ +/* [cli_long_max_dns_queries] +\par `--max-dns-queries ` +Run at most this many DNS lookups at once (default: the connection limit; +ss-server adds 64). Beyond the limit ss-server closes the connection that +needed the lookup, and ss-local applies its ACL without the address. +[cli_long_max_dns_queries] */ + /* [cli_long_tcp_incoming_sndbuf] \par `--tcp-incoming-sndbuf ` Set TCP send buffer size for incoming connections. @@ -721,6 +728,9 @@ usage(void) cli_help_option("--max-connections NUMBER", "TCP connections served at once (default: 1024)."); cli_help_option("--max-udp-sessions NUMBER", "UDP associations kept (default: 256; ss-server 512)."); #endif +#if defined(MODULE_REMOTE) || (defined(MODULE_LOCAL) && !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR)) + cli_help_option("--max-dns-queries NUMBER", "DNS lookups in flight (default: the connection limit)."); +#endif #ifdef MODULE_LOCAL cli_help_option("--printable-salt", "Experimental printable TCP salt (chacha20-ietf-poly1305/aes-256-gcm only)."); #endif