85 lines
2.4 KiB
Diff
85 lines
2.4 KiB
Diff
From a2a7e040b128a8ec369ba8f22beca2705435b85b Mon Sep 17 00:00:00 2001
|
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
|
Date: Sat, 12 Dec 2020 23:26:45 +0000
|
|
Subject: [PATCH] Use the values of --min-port and --max-port in TCP
|
|
connections.
|
|
|
|
Rather that letting the kernel pick source ports, do it ourselves
|
|
so that the --min-port and --max-port parameters are be obeyed.
|
|
---
|
|
CHANGELOG | 5 +++++
|
|
src/network.c | 37 +++++++++++++++++++++++++++++++++----
|
|
2 files changed, 38 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index e6a2231..34ad22e 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -1,3 +1,8 @@
|
|
+version 2.83
|
|
+ Use the values of --min-port and --max-port in outgoing
|
|
+ TCP connections to upstream DNS servers.
|
|
+
|
|
+
|
|
version 2.82
|
|
Improve behaviour in the face of network interfaces which come
|
|
and go and change index. Thanks to Petr Mensik for the patch.
|
|
diff --git a/src/network.c b/src/network.c
|
|
index c7d002b..7cf2546 100644
|
|
--- a/src/network.c
|
|
+++ b/src/network.c
|
|
@@ -1262,17 +1262,46 @@ int random_sock(int family)
|
|
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
|
|
{
|
|
union mysockaddr addr_copy = *addr;
|
|
+ unsigned short port;
|
|
+ int tries = 1, done = 0;
|
|
+ unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
|
|
+
|
|
+ if (addr_copy.sa.sa_family == AF_INET)
|
|
+ port = addr_copy.in.sin_port;
|
|
+ else
|
|
+ port = addr_copy.in6.sin6_port;
|
|
|
|
/* cannot set source _port_ for TCP connections. */
|
|
if (is_tcp)
|
|
+ port = 0;
|
|
+
|
|
+ /* Bind a random port within the range given by min-port and max-port */
|
|
+ if (port == 0)
|
|
+ {
|
|
+ tries = ports_avail < 30 ? 3 * ports_avail : 100;
|
|
+ port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
|
|
+ }
|
|
+
|
|
+ while (tries--)
|
|
{
|
|
if (addr_copy.sa.sa_family == AF_INET)
|
|
- addr_copy.in.sin_port = 0;
|
|
+ addr_copy.in.sin_port = port;
|
|
else
|
|
- addr_copy.in6.sin6_port = 0;
|
|
+ addr_copy.in6.sin6_port = port;
|
|
+
|
|
+ if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
|
|
+ {
|
|
+ done = 1;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (errno != EADDRINUSE && errno != EACCES)
|
|
+ return 0;
|
|
+
|
|
+ port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
|
|
}
|
|
-
|
|
- if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
|
|
+
|
|
+ if (!done)
|
|
return 0;
|
|
|
|
if (!is_tcp && ifindex > 0)
|
|
--
|
|
1.8.3.1
|
|
|