mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea28d0ef8a | ||
|
|
4a8c098840 | ||
|
|
ffa4628faa | ||
|
|
e10a9239e1 | ||
|
|
51f7bc924c | ||
|
|
6c0bf79078 | ||
|
|
4b03170920 | ||
|
|
1de6bbc108 |
No files matched your search
@@ -49,7 +49,23 @@ version 2.85
|
|||||||
source address errors from fatal to run-time. The error will be
|
source address errors from fatal to run-time. The error will be
|
||||||
logged and communiction with the server not possible.
|
logged and communiction with the server not possible.
|
||||||
|
|
||||||
|
Change the method of allocation of random source ports for DNS.
|
||||||
|
Previously, without min-port or max-port configured, dnsmasq would
|
||||||
|
default to the compiled in defaults for those, which are 1024 and
|
||||||
|
65535. Now, when neither are configured, it defaults instead to
|
||||||
|
the kernel's ephemeral port range, which is typically
|
||||||
|
32768 to 60999 on Linux systems. This change eliminates the
|
||||||
|
possibility that dnsmasq may be using a registered port > 1024
|
||||||
|
when a long-running daemon starts up and wishes to claim it.
|
||||||
|
This change does likely slighly reduce the number of random ports
|
||||||
|
and therefore the protection from reply spoofing. The older
|
||||||
|
behaviour can be restored using the min-port and max-port config
|
||||||
|
switches should that be a concern.
|
||||||
|
|
||||||
|
Scale the size of the DNS random-port pool based on the
|
||||||
|
value of the --dns-forward-max configuration.
|
||||||
|
|
||||||
|
|
||||||
version 2.84
|
version 2.84
|
||||||
Fix a problem, introduced in 2.83, which could see DNS replies
|
Fix a problem, introduced in 2.83, which could see DNS replies
|
||||||
being sent via the wrong socket. On machines running both
|
being sent via the wrong socket. On machines running both
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
|
#define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
|
||||||
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
|
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
|
||||||
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
|
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
|
||||||
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
|
||||||
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
|
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
|
||||||
#define CACHESIZ 150 /* default cache size */
|
#define CACHESIZ 150 /* default cache size */
|
||||||
#define TTL_FLOOR_LIMIT 3600 /* don't allow --min-cache-ttl to raise TTL above this under any circumstances */
|
#define TTL_FLOOR_LIMIT 3600 /* don't allow --min-cache-ttl to raise TTL above this under any circumstances */
|
||||||
|
|||||||
+19
-4
@@ -237,9 +237,16 @@ int main (int argc, char **argv)
|
|||||||
die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
|
die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Handle only one of min_port/max_port being set. */
|
||||||
|
if (daemon->min_port != 0 && daemon->max_port == 0)
|
||||||
|
daemon->max_port = MAX_PORT;
|
||||||
|
|
||||||
|
if (daemon->max_port != 0 && daemon->min_port == 0)
|
||||||
|
daemon->min_port = MIN_PORT;
|
||||||
|
|
||||||
if (daemon->max_port < daemon->min_port)
|
if (daemon->max_port < daemon->min_port)
|
||||||
die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
|
die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
|
||||||
|
|
||||||
now = dnsmasq_time();
|
now = dnsmasq_time();
|
||||||
|
|
||||||
if (daemon->auth_zones)
|
if (daemon->auth_zones)
|
||||||
@@ -392,6 +399,14 @@ int main (int argc, char **argv)
|
|||||||
cache_init();
|
cache_init();
|
||||||
blockdata_init();
|
blockdata_init();
|
||||||
hash_questions_init();
|
hash_questions_init();
|
||||||
|
|
||||||
|
/* Scale random socket pool by ftabsize, but
|
||||||
|
limit it based on available fds. */
|
||||||
|
daemon->numrrand = daemon->ftabsize/2;
|
||||||
|
if (daemon->numrrand > max_fd/3)
|
||||||
|
daemon->numrrand = max_fd/3;
|
||||||
|
/* safe_malloc returns zero'd memory */
|
||||||
|
daemon->randomsocks = safe_malloc(daemon->numrrand * sizeof(struct randfd));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_INOTIFY
|
#ifdef HAVE_INOTIFY
|
||||||
@@ -980,7 +995,7 @@ int main (int argc, char **argv)
|
|||||||
a single file will be sent to may clients (the file only needs
|
a single file will be sent to may clients (the file only needs
|
||||||
one fd). */
|
one fd). */
|
||||||
|
|
||||||
max_fd -= 30; /* use other than TFTP */
|
max_fd -= 30 + daemon->numrrand; /* use other than TFTP */
|
||||||
|
|
||||||
if (max_fd < 0)
|
if (max_fd < 0)
|
||||||
max_fd = 5;
|
max_fd = 5;
|
||||||
@@ -1693,7 +1708,7 @@ static int set_dns_listeners(time_t now)
|
|||||||
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
|
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
|
||||||
poll_listen(serverfdp->fd, POLLIN);
|
poll_listen(serverfdp->fd, POLLIN);
|
||||||
|
|
||||||
for (i = 0; i < RANDOM_SOCKS; i++)
|
for (i = 0; i < daemon->numrrand; i++)
|
||||||
if (daemon->randomsocks[i].refcount != 0)
|
if (daemon->randomsocks[i].refcount != 0)
|
||||||
poll_listen(daemon->randomsocks[i].fd, POLLIN);
|
poll_listen(daemon->randomsocks[i].fd, POLLIN);
|
||||||
|
|
||||||
@@ -1745,7 +1760,7 @@ static void check_dns_listeners(time_t now)
|
|||||||
if (poll_check(serverfdp->fd, POLLIN))
|
if (poll_check(serverfdp->fd, POLLIN))
|
||||||
reply_query(serverfdp->fd, now);
|
reply_query(serverfdp->fd, now);
|
||||||
|
|
||||||
for (i = 0; i < RANDOM_SOCKS; i++)
|
for (i = 0; i < daemon->numrrand; i++)
|
||||||
if (daemon->randomsocks[i].refcount != 0 &&
|
if (daemon->randomsocks[i].refcount != 0 &&
|
||||||
poll_check(daemon->randomsocks[i].fd, POLLIN))
|
poll_check(daemon->randomsocks[i].fd, POLLIN))
|
||||||
reply_query(daemon->randomsocks[i].fd, now);
|
reply_query(daemon->randomsocks[i].fd, now);
|
||||||
|
|||||||
+2
-1
@@ -1130,7 +1130,8 @@ extern struct daemon {
|
|||||||
pid_t tcp_pids[MAX_PROCS];
|
pid_t tcp_pids[MAX_PROCS];
|
||||||
int tcp_pipes[MAX_PROCS];
|
int tcp_pipes[MAX_PROCS];
|
||||||
int pipe_to_parent;
|
int pipe_to_parent;
|
||||||
struct randfd randomsocks[RANDOM_SOCKS];
|
int numrrand;
|
||||||
|
struct randfd *randomsocks;
|
||||||
struct randfd_list *rfl_spare, *rfl_poll;
|
struct randfd_list *rfl_spare, *rfl_poll;
|
||||||
int v6pktinfo;
|
int v6pktinfo;
|
||||||
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
|
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
|
||||||
|
|||||||
+87
-112
@@ -245,6 +245,53 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CONNTRACK
|
||||||
|
static void set_outgoing_mark(struct frec *forward, int fd)
|
||||||
|
{
|
||||||
|
/* Copy connection mark of incoming query to outgoing connection. */
|
||||||
|
unsigned int mark;
|
||||||
|
if (get_incoming_mark(&forward->frec_src.source, &forward->frec_src.dest, 0, &mark))
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void log_query_mysockaddr(unsigned int flags, char *name, union mysockaddr *addr, char *arg)
|
||||||
|
{
|
||||||
|
if (addr->sa.sa_family == AF_INET)
|
||||||
|
log_query(flags | F_IPV4, name, (union all_addr *)&addr->in.sin_addr, arg);
|
||||||
|
else
|
||||||
|
log_query(flags | F_IPV6, name, (union all_addr *)&addr->in6.sin6_addr, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void server_send(struct server *server, int fd,
|
||||||
|
const void *header, size_t plen, int flags)
|
||||||
|
{
|
||||||
|
while (retry_send(sendto(fd, header, plen, flags,
|
||||||
|
&server->addr.sa,
|
||||||
|
sa_len(&server->addr))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
static void server_send_log(struct server *server, int fd,
|
||||||
|
const void *header, size_t plen, int dumpflags,
|
||||||
|
unsigned int logflags, char *name, char *arg)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_DUMPFILE
|
||||||
|
dump_packet(dumpflags, (void *)header, (size_t)plen, NULL, &server->addr);
|
||||||
|
#endif
|
||||||
|
log_query_mysockaddr(logflags, name, &server->addr, arg);
|
||||||
|
server_send(server, fd, header, plen, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int server_test_type(const struct server *server,
|
||||||
|
const char *domain, int type, int extratype)
|
||||||
|
{
|
||||||
|
return (type == (server->flags & (SERV_TYPE | extratype)) &&
|
||||||
|
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, server->domain)) &&
|
||||||
|
!(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)));
|
||||||
|
}
|
||||||
|
|
||||||
static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
union all_addr *dst_addr, unsigned int dst_iface,
|
union all_addr *dst_addr, unsigned int dst_iface,
|
||||||
struct dns_header *header, size_t plen, time_t now,
|
struct dns_header *header, size_t plen, time_t now,
|
||||||
@@ -345,17 +392,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
PUTSHORT(SAFE_PKTSZ, pheader);
|
PUTSHORT(SAFE_PKTSZ, pheader);
|
||||||
|
|
||||||
if ((fd = allocate_rfd(&forward->rfds, forward->sentto)) != -1)
|
if ((fd = allocate_rfd(&forward->rfds, forward->sentto)) != -1)
|
||||||
{
|
server_send_log(forward->sentto, fd, header, plen,
|
||||||
if (forward->sentto->addr.sa.sa_family == AF_INET)
|
DUMP_SEC_QUERY,
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
|
F_NOEXTRA | F_DNSSEC, "retry", "dnssec");
|
||||||
else
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
|
|
||||||
|
|
||||||
while (retry_send(sendto(fd, (char *)header, plen, 0,
|
|
||||||
&forward->sentto->addr.sa,
|
|
||||||
sa_len(&forward->sentto->addr))));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -506,20 +546,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
domain may be NULL, in which case server->domain
|
domain may be NULL, in which case server->domain
|
||||||
must be NULL also. */
|
must be NULL also. */
|
||||||
|
|
||||||
if (type == (start->flags & SERV_TYPE) &&
|
if (server_test_type(start, domain, type, 0) &&
|
||||||
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
|
||||||
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)) &&
|
|
||||||
((fd = allocate_rfd(&forward->rfds, start)) != -1))
|
((fd = allocate_rfd(&forward->rfds, start)) != -1))
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef HAVE_CONNTRACK
|
#ifdef HAVE_CONNTRACK
|
||||||
/* Copy connection mark of incoming query to outgoing connection. */
|
/* Copy connection mark of incoming query to outgoing connection. */
|
||||||
if (option_bool(OPT_CONNTRACK))
|
if (option_bool(OPT_CONNTRACK))
|
||||||
{
|
set_outgoing_mark(forward, fd);
|
||||||
unsigned int mark;
|
|
||||||
if (get_incoming_mark(&forward->frec_src.source, &forward->frec_src.dest, 0, &mark))
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
@@ -556,12 +590,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
|
|
||||||
if (!gotname)
|
if (!gotname)
|
||||||
strcpy(daemon->namebuff, "query");
|
strcpy(daemon->namebuff, "query");
|
||||||
if (start->addr.sa.sa_family == AF_INET)
|
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff,
|
||||||
log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
|
&start->addr, NULL);
|
||||||
(union all_addr *)&start->addr.in.sin_addr, NULL);
|
|
||||||
else
|
|
||||||
log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
|
|
||||||
(union all_addr *)&start->addr.in6.sin6_addr, NULL);
|
|
||||||
start->queries++;
|
start->queries++;
|
||||||
forwarded = 1;
|
forwarded = 1;
|
||||||
forward->sentto = start;
|
forward->sentto = start;
|
||||||
@@ -878,22 +908,10 @@ void reply_query(int fd, time_t now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((fd = allocate_rfd(&forward->rfds, start)) == -1)
|
if ((fd = allocate_rfd(&forward->rfds, start)) != -1)
|
||||||
return;
|
server_send_log(start, fd, header, plen,
|
||||||
|
DUMP_SEC_QUERY,
|
||||||
#ifdef HAVE_DUMPFILE
|
F_NOEXTRA | F_DNSSEC, "retry", "dnssec");
|
||||||
dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)plen, NULL, &start->addr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (retry_send(sendto(fd, (char *)header, plen, 0,
|
|
||||||
&start->addr.sa,
|
|
||||||
sa_len(&start->addr))));
|
|
||||||
|
|
||||||
if (start->addr.sa.sa_family == AF_INET)
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&start->addr.in.sin_addr, "dnssec");
|
|
||||||
else
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&start->addr.in6.sin6_addr, "dnssec");
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1064,9 +1082,7 @@ void reply_query(int fd, time_t now)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
|
if (server_test_type(start, domain, type, 0))
|
||||||
((type & SERV_TYPE) != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
|
|
||||||
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
|
||||||
{
|
{
|
||||||
new_server = start;
|
new_server = start;
|
||||||
if (server == start)
|
if (server == start)
|
||||||
@@ -1109,13 +1125,6 @@ void reply_query(int fd, time_t now)
|
|||||||
nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
|
nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
|
||||||
daemon->keyname, forward->class, querytype, server->edns_pktsz);
|
daemon->keyname, forward->class, querytype, server->edns_pktsz);
|
||||||
|
|
||||||
if (server->addr.sa.sa_family == AF_INET)
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (union all_addr *)&(server->addr.in.sin_addr),
|
|
||||||
querystr("dnssec-query", querytype));
|
|
||||||
else
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
|
|
||||||
querystr("dnssec-query", querytype));
|
|
||||||
|
|
||||||
memcpy(new->hash, hash_questions(header, nn, daemon->namebuff), HASH_SIZE);
|
memcpy(new->hash, hash_questions(header, nn, daemon->namebuff), HASH_SIZE);
|
||||||
new->new_id = get_id();
|
new->new_id = get_id();
|
||||||
header->id = htons(new->new_id);
|
header->id = htons(new->new_id);
|
||||||
@@ -1129,22 +1138,12 @@ void reply_query(int fd, time_t now)
|
|||||||
if ((fd = allocate_rfd(&new->rfds, server)) != -1)
|
if ((fd = allocate_rfd(&new->rfds, server)) != -1)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CONNTRACK
|
#ifdef HAVE_CONNTRACK
|
||||||
/* Copy connection mark of incoming query to outgoing connection. */
|
|
||||||
if (option_bool(OPT_CONNTRACK))
|
if (option_bool(OPT_CONNTRACK))
|
||||||
{
|
set_outgoing_mark(orig, fd);
|
||||||
unsigned int mark;
|
|
||||||
if (get_incoming_mark(&orig->frec_src.source, &orig->frec_src.dest, 0, &mark))
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
server_send_log(server, fd, header, nn, DUMP_SEC_QUERY,
|
||||||
#ifdef HAVE_DUMPFILE
|
F_NOEXTRA | F_DNSSEC, daemon->keyname,
|
||||||
dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr);
|
querystr("dnssec-query", querytype));
|
||||||
#endif
|
|
||||||
|
|
||||||
while (retry_send(sendto(fd, (char *)header, nn, 0,
|
|
||||||
&server->addr.sa,
|
|
||||||
sa_len(&server->addr))));
|
|
||||||
server->queries++;
|
server->queries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1503,13 +1502,9 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
struct auth_zone *zone;
|
struct auth_zone *zone;
|
||||||
#endif
|
#endif
|
||||||
char *types = querystr(auth_dns ? "auth" : "query", type);
|
char *types = querystr(auth_dns ? "auth" : "query", type);
|
||||||
|
|
||||||
if (family == AF_INET)
|
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
|
||||||
log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
|
&source_addr, types);
|
||||||
(union all_addr *)&source_addr.in.sin_addr, types);
|
|
||||||
else
|
|
||||||
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
|
||||||
(union all_addr *)&source_addr.in6.sin6_addr, types);
|
|
||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
/* find queries for zones we're authoritative for, and answer them directly */
|
/* find queries for zones we're authoritative for, and answer them directly */
|
||||||
@@ -1671,9 +1666,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != (server->flags & (SERV_TYPE | SERV_DO_DNSSEC)) ||
|
if (!server_test_type(server, domain, type, SERV_DO_DNSSEC))
|
||||||
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
|
|
||||||
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
@@ -1697,9 +1690,8 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MSG_FASTOPEN
|
#ifdef MSG_FASTOPEN
|
||||||
while(retry_send(sendto(server->tcpfd, packet, m + sizeof(u16),
|
server_send(server, server->tcpfd, packet, m + sizeof(u16), MSG_FASTOPEN);
|
||||||
MSG_FASTOPEN, &server->addr.sa, sa_len(&server->addr))));
|
|
||||||
|
|
||||||
if (errno == 0)
|
if (errno == 0)
|
||||||
data_sent = 1;
|
data_sent = 1;
|
||||||
#endif
|
#endif
|
||||||
@@ -1730,14 +1722,9 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, keyname, &server->addr,
|
||||||
|
querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
|
||||||
|
|
||||||
if (server->addr.sa.sa_family == AF_INET)
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (union all_addr *)&(server->addr.in.sin_addr),
|
|
||||||
querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
|
|
||||||
else
|
|
||||||
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
|
|
||||||
querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
|
|
||||||
|
|
||||||
server->flags |= SERV_GOT_TCP;
|
server->flags |= SERV_GOT_TCP;
|
||||||
|
|
||||||
m = (c1 << 8) | c2;
|
m = (c1 << 8) | c2;
|
||||||
@@ -1875,12 +1862,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
#endif
|
#endif
|
||||||
char *types = querystr(auth_dns ? "auth" : "query", qtype);
|
char *types = querystr(auth_dns ? "auth" : "query", qtype);
|
||||||
|
|
||||||
if (peer_addr.sa.sa_family == AF_INET)
|
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
|
||||||
log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
|
&peer_addr, types);
|
||||||
(union all_addr *)&peer_addr.in.sin_addr, types);
|
|
||||||
else
|
|
||||||
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
|
||||||
(union all_addr *)&peer_addr.in6.sin6_addr, types);
|
|
||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
/* find queries for zones we're authoritative for, and answer them directly */
|
/* find queries for zones we're authoritative for, and answer them directly */
|
||||||
@@ -1995,9 +1978,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* server for wrong domain */
|
/* server for wrong domain */
|
||||||
if (type != (last_server->flags & SERV_TYPE) ||
|
if (!server_test_type(last_server, domain, type, 0))
|
||||||
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)) ||
|
|
||||||
(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
@@ -2022,9 +2003,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MSG_FASTOPEN
|
#ifdef MSG_FASTOPEN
|
||||||
while(retry_send(sendto(last_server->tcpfd, packet, size + sizeof(u16),
|
server_send(last_server, last_server->tcpfd, packet, size + sizeof(u16), MSG_FASTOPEN);
|
||||||
MSG_FASTOPEN, &last_server->addr.sa, sa_len(&last_server->addr))));
|
|
||||||
|
|
||||||
if (errno == 0)
|
if (errno == 0)
|
||||||
data_sent = 1;
|
data_sent = 1;
|
||||||
#endif
|
#endif
|
||||||
@@ -2062,13 +2042,9 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
last_server->flags |= SERV_GOT_TCP;
|
last_server->flags |= SERV_GOT_TCP;
|
||||||
|
|
||||||
m = (c1 << 8) | c2;
|
m = (c1 << 8) | c2;
|
||||||
|
|
||||||
if (last_server->addr.sa.sa_family == AF_INET)
|
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff,
|
||||||
log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
|
&last_server->addr, NULL);
|
||||||
(union all_addr *)&last_server->addr.in.sin_addr, NULL);
|
|
||||||
else
|
|
||||||
log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
|
|
||||||
(union all_addr *)&last_server->addr.in6.sin6_addr, NULL);
|
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
|
if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
|
||||||
@@ -2242,7 +2218,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
|||||||
|
|
||||||
/* limit the number of sockets we have open to avoid starvation of
|
/* limit the number of sockets we have open to avoid starvation of
|
||||||
(eg) TFTP. Once we have a reasonable number, randomness should be OK */
|
(eg) TFTP. Once we have a reasonable number, randomness should be OK */
|
||||||
for (i = 0; i < RANDOM_SOCKS; i++)
|
for (i = 0; i < daemon->numrrand; i++)
|
||||||
if (daemon->randomsocks[i].refcount == 0)
|
if (daemon->randomsocks[i].refcount == 0)
|
||||||
{
|
{
|
||||||
if ((fd = random_sock(serv)) != -1)
|
if ((fd = random_sock(serv)) != -1)
|
||||||
@@ -2257,9 +2233,9 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
|||||||
|
|
||||||
/* No free ones or cannot get new socket, grab an existing one */
|
/* No free ones or cannot get new socket, grab an existing one */
|
||||||
if (!rfd)
|
if (!rfd)
|
||||||
for (j = 0; j < RANDOM_SOCKS; j++)
|
for (j = 0; j < daemon->numrrand; j++)
|
||||||
{
|
{
|
||||||
i = (j + finger) % RANDOM_SOCKS;
|
i = (j + finger) % daemon->numrrand;
|
||||||
if (daemon->randomsocks[i].refcount != 0 &&
|
if (daemon->randomsocks[i].refcount != 0 &&
|
||||||
server_isequal(serv, daemon->randomsocks[i].serv) &&
|
server_isequal(serv, daemon->randomsocks[i].serv) &&
|
||||||
daemon->randomsocks[i].refcount != 0xfffe)
|
daemon->randomsocks[i].refcount != 0xfffe)
|
||||||
@@ -2271,7 +2247,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j == RANDOM_SOCKS)
|
if (j == daemon->numrrand)
|
||||||
{
|
{
|
||||||
struct randfd_list *rfl_poll;
|
struct randfd_list *rfl_poll;
|
||||||
|
|
||||||
@@ -2546,9 +2522,8 @@ static struct frec *lookup_frec_by_query(void *hash, unsigned int flags)
|
|||||||
void resend_query()
|
void resend_query()
|
||||||
{
|
{
|
||||||
if (daemon->srv_save)
|
if (daemon->srv_save)
|
||||||
while(retry_send(sendto(daemon->fd_save, daemon->packet, daemon->packet_len, 0,
|
server_send(daemon->srv_save, daemon->fd_save,
|
||||||
&daemon->srv_save->addr.sa,
|
daemon->packet, daemon->packet_len, 0);
|
||||||
sa_len(&daemon->srv_save->addr))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A server record is going away, remove references to it */
|
/* A server record is going away, remove references to it */
|
||||||
@@ -2563,7 +2538,7 @@ void server_gone(struct server *server)
|
|||||||
|
|
||||||
/* If any random socket refers to this server, NULL the reference.
|
/* If any random socket refers to this server, NULL the reference.
|
||||||
No more references to the socket will be created in the future. */
|
No more references to the socket will be created in the future. */
|
||||||
for (i = 0; i < RANDOM_SOCKS; i++)
|
for (i = 0; i < daemon->numrrand; i++)
|
||||||
if (daemon->randomsocks[i].refcount != 0 && daemon->randomsocks[i].serv == server)
|
if (daemon->randomsocks[i].refcount != 0 && daemon->randomsocks[i].serv == server)
|
||||||
daemon->randomsocks[i].serv = NULL;
|
daemon->randomsocks[i].serv = NULL;
|
||||||
|
|
||||||
|
|||||||
+39
-26
@@ -720,13 +720,17 @@ int enumerate_interfaces(int reset)
|
|||||||
to a server is specified by an interface, so cache them.
|
to a server is specified by an interface, so cache them.
|
||||||
Update the cache here. */
|
Update the cache here. */
|
||||||
for (serv = daemon->servers; serv; serv = serv->next)
|
for (serv = daemon->servers; serv; serv = serv->next)
|
||||||
if (strlen(serv->interface) != 0)
|
if (serv->interface[0] != 0)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
struct ifreq ifr;
|
||||||
safe_strncpy(ifr.ifr_name, serv->interface, IF_NAMESIZE);
|
|
||||||
if (ioctl(param.fd, SIOCGIFINDEX, &ifr) != -1)
|
safe_strncpy(ifr.ifr_name, serv->interface, IF_NAMESIZE);
|
||||||
serv->ifindex = ifr.ifr_ifindex;
|
if (ioctl(param.fd, SIOCGIFINDEX, &ifr) != -1)
|
||||||
|
serv->ifindex = ifr.ifr_ifindex;
|
||||||
|
#else
|
||||||
|
serv->ifindex = if_nametoindex(serv->interface);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
@@ -1306,9 +1310,9 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
|
|||||||
{
|
{
|
||||||
union mysockaddr addr_copy = *addr;
|
union mysockaddr addr_copy = *addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int tries = 1, done = 0;
|
int tries = 1;
|
||||||
unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
|
unsigned short ports_avail = 1;
|
||||||
|
|
||||||
if (addr_copy.sa.sa_family == AF_INET)
|
if (addr_copy.sa.sa_family == AF_INET)
|
||||||
port = addr_copy.in.sin_port;
|
port = addr_copy.in.sin_port;
|
||||||
else
|
else
|
||||||
@@ -1317,34 +1321,43 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
|
|||||||
/* cannot set source _port_ for TCP connections. */
|
/* cannot set source _port_ for TCP connections. */
|
||||||
if (is_tcp)
|
if (is_tcp)
|
||||||
port = 0;
|
port = 0;
|
||||||
else if (port == 0)
|
else if (port == 0 && daemon->max_port != 0)
|
||||||
{
|
{
|
||||||
/* Bind a random port within the range given by min-port and max-port */
|
/* Bind a random port within the range given by min-port and max-port if either
|
||||||
|
or both are set. Otherwise use the OS's random ephemeral port allocation by
|
||||||
|
leaving port == 0 and tries == 1 */
|
||||||
|
ports_avail = daemon->max_port - daemon->min_port + 1;
|
||||||
tries = ports_avail < 30 ? 3 * ports_avail : 100;
|
tries = ports_avail < 30 ? 3 * ports_avail : 100;
|
||||||
port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
|
port = htons(daemon->min_port + (rand16() % ports_avail));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (tries--)
|
while (1)
|
||||||
{
|
{
|
||||||
|
/* elide bind() call if it's to port 0, address 0 */
|
||||||
if (addr_copy.sa.sa_family == AF_INET)
|
if (addr_copy.sa.sa_family == AF_INET)
|
||||||
addr_copy.in.sin_port = port;
|
|
||||||
else
|
|
||||||
addr_copy.in6.sin6_port = port;
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
|
|
||||||
{
|
{
|
||||||
done = 1;
|
if (port == 0 && addr_copy.in.sin_addr.s_addr == 0)
|
||||||
break;
|
break;
|
||||||
|
addr_copy.in.sin_port = port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (port == 0 && IN6_IS_ADDR_UNSPECIFIED(&addr_copy.in6.sin6_addr))
|
||||||
|
break;
|
||||||
|
addr_copy.in6.sin6_port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno != EADDRINUSE && errno != EACCES)
|
if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
|
if (errno != EADDRINUSE && errno != EACCES)
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
if (!done)
|
if (--tries == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
port = htons(daemon->min_port + (rand16() % ports_avail));
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_tcp && ifindex > 0)
|
if (!is_tcp && ifindex > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-3
@@ -5076,9 +5076,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
|||||||
daemon->soa_refresh = SOA_REFRESH;
|
daemon->soa_refresh = SOA_REFRESH;
|
||||||
daemon->soa_retry = SOA_RETRY;
|
daemon->soa_retry = SOA_RETRY;
|
||||||
daemon->soa_expiry = SOA_EXPIRY;
|
daemon->soa_expiry = SOA_EXPIRY;
|
||||||
daemon->max_port = MAX_PORT;
|
|
||||||
daemon->min_port = MIN_PORT;
|
|
||||||
|
|
||||||
#ifndef NO_ID
|
#ifndef NO_ID
|
||||||
add_txt("version.bind", "dnsmasq-" VERSION, 0 );
|
add_txt("version.bind", "dnsmasq-" VERSION, 0 );
|
||||||
add_txt("authors.bind", "Simon Kelley", 0);
|
add_txt("authors.bind", "Simon Kelley", 0);
|
||||||
|
|||||||
Reference in new issue
Block a user