[Dnsmasq-discuss] [PATCH] Add a flag to customize MAX_PROCS
Damian Sawicki
dsawicki at google.com
Wed Oct 18 10:38:07 UTC 2023
Add the flag --max-tcp-connections overwriting the former MAX_PROCS
constant limiting the number of concurrent TCP requests handled.
---
man/dnsmasq.8 | 4 ++++
src/config.h | 2 +-
src/dnsmasq.c | 23 ++++++++++++++++-------
src/dnsmasq.h | 5 +++--
src/option.c | 16 +++++++++++++++-
5 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 30429df..6d37360 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -2254,6 +2254,10 @@ example command to query this, using the
utility would be
dig +short chaos txt cachesize.bind
+.TP
+.B --max-tcp-connections=<number>
+The maximum number of concurrent TCP connections. The application forks to
+handle each TCP request. The default maximum is 20.
.SH CONFIG FILE
At startup, dnsmasq reads
diff --git a/src/config.h b/src/config.h
index 88cf72e..cc1c465 100644
--- a/src/config.h
+++ b/src/config.h
@@ -15,7 +15,7 @@
*/
#define FTABSIZ 150 /* max number of outstanding requests (default) */
-#define MAX_PROCS 20 /* max no children for TCP requests */
+#define MAX_PROCS 20 /* default max no children for TCP requests */
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
#define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index bc6644c..112dbe5 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -36,6 +36,7 @@ static void async_event(int pipe, time_t now);
static void fatal_event(struct event_desc *ev, char *msg);
static int read_event(int fd, struct event_desc *evp, char **msg);
static void poll_resolv(int force, int do_reload, time_t now);
+static void tcp_init(void);
int main (int argc, char **argv)
{
@@ -415,6 +416,8 @@ int main (int argc, char **argv)
daemon->numrrand = max_fd/3;
/* safe_malloc returns zero'd memory */
daemon->randomsocks = safe_malloc(daemon->numrrand * sizeof(struct randfd));
+
+ tcp_init();
}
#ifdef HAVE_INOTIFY
@@ -1043,7 +1046,7 @@ int main (int argc, char **argv)
pid = getpid();
daemon->pipe_to_parent = -1;
- for (i = 0; i < MAX_PROCS; i++)
+ for (i = 0; i < daemon->max_procs; i++)
daemon->tcp_pipes[i] = -1;
#ifdef HAVE_INOTIFY
@@ -1520,7 +1523,7 @@ static void async_event(int pipe, time_t now)
break;
}
else
- for (i = 0 ; i < MAX_PROCS; i++)
+ for (i = 0 ; i < daemon->max_procs; i++)
if (daemon->tcp_pids[i] == p)
daemon->tcp_pids[i] = 0;
break;
@@ -1584,7 +1587,7 @@ static void async_event(int pipe, time_t now)
case EVENT_TERM:
/* Knock all our children on the head. */
- for (i = 0; i < MAX_PROCS; i++)
+ for (i = 0; i < daemon->max_procs; i++)
if (daemon->tcp_pids[i] != 0)
kill(daemon->tcp_pids[i], SIGALRM);
@@ -1761,7 +1764,7 @@ static void set_dns_listeners(void)
poll_listen(rfl->rfd->fd, POLLIN);
/* check to see if we have free tcp process slots. */
- for (i = MAX_PROCS - 1; i >= 0; i--)
+ for (i = daemon->max_procs - 1; i >= 0; i--)
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
break;
@@ -1785,7 +1788,7 @@ static void set_dns_listeners(void)
}
if (!option_bool(OPT_DEBUG))
- for (i = 0; i < MAX_PROCS; i++)
+ for (i = 0; i < daemon->max_procs; i++)
if (daemon->tcp_pipes[i] != -1)
poll_listen(daemon->tcp_pipes[i], POLLIN);
}
@@ -1820,7 +1823,7 @@ static void check_dns_listeners(time_t now)
to free the process slot. Once the child process has gone, poll()
returns POLLHUP, not POLLIN, so have to check for both here. */
if (!option_bool(OPT_DEBUG))
- for (i = 0; i < MAX_PROCS; i++)
+ for (i = 0; i < daemon->max_procs; i++)
if (daemon->tcp_pipes[i] != -1 &&
poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP) &&
!cache_recv_insert(now, daemon->tcp_pipes[i]))
@@ -1844,7 +1847,7 @@ static void check_dns_listeners(time_t now)
at least one a poll() time, that we still do.
There may be more waiting connections after
poll() returns then free process slots. */
- for (i = MAX_PROCS - 1; i >= 0; i--)
+ for (i = daemon->max_procs - 1; i >= 0; i--)
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
break;
@@ -2186,3 +2189,9 @@ int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
return 0;
}
#endif /* HAVE_DHCP */
+
+void tcp_init(void)
+{
+ daemon->tcp_pids = safe_malloc(daemon->max_procs*sizeof(pid_t));
+ daemon->tcp_pipes = safe_malloc(daemon->max_procs*sizeof(int));
+}
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 2f95c12..67c083b 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1252,8 +1252,8 @@ extern struct daemon {
struct server *srv_save; /* Used for resend on DoD */
size_t packet_len; /* " " */
int fd_save; /* " " */
- pid_t tcp_pids[MAX_PROCS];
- int tcp_pipes[MAX_PROCS];
+ pid_t *tcp_pids;
+ int *tcp_pipes;
int pipe_to_parent;
int numrrand;
struct randfd *randomsocks;
@@ -1313,6 +1313,7 @@ extern struct daemon {
/* file for packet dumps. */
int dumpfd;
#endif
+ int max_procs;
} *daemon;
struct server_details {
diff --git a/src/option.c b/src/option.c
index 286f06b..9423582 100644
--- a/src/option.c
+++ b/src/option.c
@@ -190,6 +190,7 @@ struct myoption {
#define LOPT_FILTER_RR 381
#define LOPT_NO_DHCP6 382
#define LOPT_NO_DHCP4 383
+#define LOPT_MAX_PROCS 384
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -384,6 +385,7 @@ static const struct myoption opts[] =
{ "fast-dns-retry", 2, 0, LOPT_FAST_RETRY },
{ "use-stale-cache", 2, 0 , LOPT_STALE_CACHE },
{ "no-ident", 0, 0, LOPT_NO_IDENT },
+ { "max-tcp-connections", 1, 0, LOPT_MAX_PROCS },
{ NULL, 0, 0, 0 }
};
@@ -585,6 +587,7 @@ static struct {
{ LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
+ { LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
{ 0, 0, NULL, NULL, NULL }
};
@@ -5313,7 +5316,17 @@ err:
break;
}
#endif
-
+
+ case LOPT_MAX_PROCS: /* --max-tcp-connections */
+ {
+ int max_procs;
+ /* Don't accept numbers less than 1. */
+ if (!atoi_check(arg, &max_procs) || max_procs < 1)
+ ret_err(gen_err);
+ daemon->max_procs = max_procs;
+ break;
+ }
+
default:
ret_err(_("unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"));
@@ -5841,6 +5854,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon->soa_expiry = SOA_EXPIRY;
daemon->randport_limit = 1;
daemon->host_index = SRC_AH;
+ daemon->max_procs = MAX_PROCS;
/* See comment above make_servers(). Optimises server-read code. */
mark_servers(0);
--
2.42.0.655.g421f12c284-goog
More information about the Dnsmasq-discuss
mailing list