aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2022-10-31 15:28:36 -0400
committerDavid Goulet <dgoulet@torproject.org>2022-10-31 15:28:36 -0400
commitc733ccda996238d28c8068e7c9e7af95f5573547 (patch)
treec6e9e7e2b699cb2afad441462755537951ee7aeb
parent2a838c196d348f95584fcf16bf5d2895cde94fa2 (diff)
parentb65ffa6f06b2d7bc313e0780f3d76a8acb499ac9 (diff)
downloadtor-c733ccda996238d28c8068e7c9e7af95f5573547.tar.gz
tor-c733ccda996238d28c8068e7c9e7af95f5573547.zip
Merge branch 'tor-gitlab/mr/579'
-rw-r--r--changes/ip_bind_address_no_port5
-rw-r--r--src/core/mainloop/connection.c17
-rw-r--r--src/lib/sandbox/sandbox.c8
3 files changed, 30 insertions, 0 deletions
diff --git a/changes/ip_bind_address_no_port b/changes/ip_bind_address_no_port
new file mode 100644
index 0000000000..9c4f712a9e
--- /dev/null
+++ b/changes/ip_bind_address_no_port
@@ -0,0 +1,5 @@
+ o Minor features (relays):
+ - Set the Linux-specific IP_BIND_ADDRESS_NO_PORT option on outgoing
+ sockets, allowing relays using OutboundBindAddress to make more outgoing
+ connections than ephemeral ports, as long as they are to separate
+ destinations. Related to issue 40597; patch by Alex Xu (Hello71).
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 7c121196a3..8b0ef9a951 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -2234,6 +2234,23 @@ connection_connect_sockaddr,(connection_t *conn,
tor_socket_strerror(errno));
}
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ static int try_ip_bind_address_no_port = 1;
+ if (bindaddr && try_ip_bind_address_no_port &&
+ setsockopt(s, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &(int){1}, sizeof(int))) {
+ if (errno == EINVAL) {
+ log_notice(LD_NET, "Tor was built with support for "
+ "IP_BIND_ADDRESS_NO_PORT, but the current kernel "
+ "doesn't support it. This might cause Tor to run out "
+ "of ephemeral ports more quickly.");
+ try_ip_bind_address_no_port = 0;
+ } else {
+ log_warn(LD_NET, "Error setting IP_BIND_ADDRESS_NO_PORT on new "
+ "connection: %s", tor_socket_strerror(errno));
+ }
+ }
+#endif
+
if (bindaddr && bind(s, bindaddr, bindaddr_len) < 0) {
*socket_error = tor_socket_errno(s);
if (ERRNO_IS_EADDRINUSE(*socket_error)) {
diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c
index 7c024d7e37..a476e57fbc 100644
--- a/src/lib/sandbox/sandbox.c
+++ b/src/lib/sandbox/sandbox.c
@@ -1033,6 +1033,14 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return rc;
#endif /* defined(IPV6_V6ONLY) */
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
+ SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
+ SCMP_CMP(2, SCMP_CMP_EQ, IP_BIND_ADDRESS_NO_PORT));
+ if (rc)
+ return rc;
+#endif
+
return 0;
}