mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Second try at port-limit option.
1) It's expected to fail to bind a new source port when they are scarce, suppress warning in log in this case. 2) Optimse bind_local when max_port - min_port is small. There's no randomness in this case, so we try all possible source ports rather than poking at random ones for an arbitrary number of tries. 3) In allocate_rfd() handle the case that all available source ports are already open. In this case we need to pick an existing socket/port to use, such that it has a different port from any we already hold. This gives the required property that the set of ports utilised by any given query is set by --port-limit and we don't re-use any until we have port-limit different ones.
This commit is contained in:
@@ -2438,13 +2438,18 @@ static int random_sock(struct server *s)
|
||||
if (local_bind(fd, &s->source_addr, s->interface, s->ifindex, 0))
|
||||
return fd;
|
||||
|
||||
if (s->interface[0] == 0)
|
||||
(void)prettyprint_addr(&s->source_addr, daemon->addrbuff);
|
||||
else
|
||||
safe_strncpy(daemon->addrbuff, s->interface, ADDRSTRLEN);
|
||||
|
||||
my_syslog(LOG_ERR, _("failed to bind server socket to %s: %s"),
|
||||
daemon->addrbuff, strerror(errno));
|
||||
/* don't log errors due to running out of available ports, we handle those. */
|
||||
if (!sockaddr_isnull(&s->source_addr) || errno != EADDRINUSE)
|
||||
{
|
||||
if (s->interface[0] == 0)
|
||||
(void)prettyprint_addr(&s->source_addr, daemon->addrbuff);
|
||||
else
|
||||
safe_strncpy(daemon->addrbuff, s->interface, ADDRSTRLEN);
|
||||
|
||||
my_syslog(LOG_ERR, _("failed to bind server socket to %s: %s"),
|
||||
daemon->addrbuff, strerror(errno));
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -2518,16 +2523,6 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We've hit the global limit on sockets before hitting the query limit,
|
||||
use an exsiting socket as source in that case. */
|
||||
if (!rfd && found)
|
||||
{
|
||||
*found_link = found->next;
|
||||
found->next = *fdlp;
|
||||
*fdlp = found;
|
||||
return found->rfd->fd;
|
||||
}
|
||||
|
||||
/* No good existing. Need new link. */
|
||||
if ((rfl = daemon->rfl_spare))
|
||||
daemon->rfl_spare = rfl->next;
|
||||
@@ -2552,10 +2547,19 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
||||
server_isequal(serv, daemon->randomsocks[i].serv) &&
|
||||
daemon->randomsocks[i].refcount != 0xfffe)
|
||||
{
|
||||
finger = i + 1;
|
||||
rfd = &daemon->randomsocks[i];
|
||||
rfd->refcount++;
|
||||
break;
|
||||
struct randfd_list *rl;
|
||||
/* Don't pick one we already have. */
|
||||
for (rl = *fdlp; rl; rl = rl->next)
|
||||
if (rl->rfd == &daemon->randomsocks[i])
|
||||
break;
|
||||
|
||||
if (!rl)
|
||||
{
|
||||
finger = i + 1;
|
||||
rfd = &daemon->randomsocks[i];
|
||||
rfd->refcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user