Compare commits
12 Commits
v2.76test1
...
v2.76test1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c0c36f54b | ||
|
|
d6b749af91 | ||
|
|
14ffa0770b | ||
|
|
87985855ad | ||
|
|
a2bc254bed | ||
|
|
a7b27e84fa | ||
|
|
529b030228 | ||
|
|
4caa86dd7d | ||
|
|
e1abeeeec2 | ||
|
|
40205a053e | ||
|
|
b8ac466209 | ||
|
|
d1377fa3c4 |
@@ -56,6 +56,15 @@ version 2.76
|
||||
Add --tftp-mtu option. Thanks to Patrick McLean for the
|
||||
initial patch.
|
||||
|
||||
Check return-code of inet_pton() when parsing dhcp-option.
|
||||
Bad addresses could fail to generate errors and result in
|
||||
garbage dhcp-options being sent. Thanks to Marc Branchaud
|
||||
for spotting this.
|
||||
|
||||
Fix wrong value for EDNS UDP packet size when using
|
||||
--servers-file to define upstream DNS servers. Thanks to
|
||||
Scott Bonar for the bug report.
|
||||
|
||||
|
||||
version 2.75
|
||||
Fix reversion on 2.74 which caused 100% CPU use when a
|
||||
|
||||
20
src/arp.c
20
src/arp.c
@@ -129,17 +129,17 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
|
||||
|
||||
for (arp = arps; arp; arp = arp->next)
|
||||
{
|
||||
if (addr->sa.sa_family == arp->family)
|
||||
{
|
||||
if (arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
|
||||
continue;
|
||||
}
|
||||
if (addr->sa.sa_family != arp->family)
|
||||
continue;
|
||||
|
||||
if (arp->family == AF_INET &&
|
||||
arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
|
||||
continue;
|
||||
}
|
||||
if (arp->family == AF_INET6 &&
|
||||
!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Only accept positive entries unless in lazy mode. */
|
||||
|
||||
@@ -651,7 +651,7 @@ int address_allocate(struct dhcp_context *context,
|
||||
/* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
|
||||
dispersal even with similarly-valued "strings". */
|
||||
for (j = 0, i = 0; i < hw_len; i++)
|
||||
j += hwaddr[i] + (j << 6) + (j << 16) - j;
|
||||
j = hwaddr[i] + (j << 6) + (j << 16) - j;
|
||||
|
||||
for (pass = 0; pass <= 1; pass++)
|
||||
for (c = context; c; c = c->current)
|
||||
|
||||
@@ -420,7 +420,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
||||
j = rand64();
|
||||
else
|
||||
for (j = iaid, i = 0; i < clid_len; i++)
|
||||
j += clid[i] + (j << 6) + (j << 16) - j;
|
||||
j = clid[i] + (j << 6) + (j << 16) - j;
|
||||
|
||||
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
||||
for (c = context; c; c = c->current)
|
||||
|
||||
10
src/dnssec.c
10
src/dnssec.c
@@ -1697,7 +1697,15 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
return 0;
|
||||
|
||||
p++; /* flags */
|
||||
|
||||
GETSHORT (iterations, p);
|
||||
/* Upper-bound iterations, to avoid DoS.
|
||||
Strictly, there are lower bounds for small keys, but
|
||||
since we don't have key size info here, at least limit
|
||||
to the largest bound, for 4096-bit keys. RFC 5155 10.3 */
|
||||
if (iterations > 2500)
|
||||
return 0;
|
||||
|
||||
salt_len = *p++;
|
||||
salt = p;
|
||||
if (!CHECK_LEN(header, salt, plen, salt_len))
|
||||
@@ -1783,7 +1791,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
}
|
||||
while ((closest_encloser = strchr(closest_encloser, '.')));
|
||||
|
||||
if (!closest_encloser)
|
||||
if (!closest_encloser || !next_closest)
|
||||
return 0;
|
||||
|
||||
/* Look for NSEC3 that proves the non-existence of the next-closest encloser */
|
||||
|
||||
13
src/edns0.c
13
src/edns0.c
@@ -95,6 +95,8 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* replace == 2 ->delete existing option only. */
|
||||
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace)
|
||||
{
|
||||
@@ -151,7 +153,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
|
||||
if (code == optno)
|
||||
{
|
||||
if (!replace)
|
||||
if (replace == 0)
|
||||
return plen;
|
||||
|
||||
/* delete option if we're to replace it. */
|
||||
@@ -213,7 +215,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
return plen; /* Too big */
|
||||
|
||||
/* Add new option */
|
||||
if (optno != 0)
|
||||
if (optno != 0 && replace != 2)
|
||||
{
|
||||
PUTSHORT(optno, p);
|
||||
PUTSHORT(optlen, p);
|
||||
@@ -244,12 +246,14 @@ static void encoder(unsigned char *in, char *out)
|
||||
|
||||
static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned char *limit, union mysockaddr *l3, time_t now)
|
||||
{
|
||||
int maclen;
|
||||
int maclen, replace = 2; /* can't get mac address, just delete any incoming. */
|
||||
unsigned char mac[DHCP_CHADDR_MAX];
|
||||
char encode[18]; /* handle 6 byte MACs */
|
||||
|
||||
if ((maclen = find_mac(l3, mac, 1, now)) == 6)
|
||||
{
|
||||
replace = 1;
|
||||
|
||||
if (option_bool(OPT_MAC_HEX))
|
||||
print_mac(encode, mac, maclen);
|
||||
else
|
||||
@@ -258,10 +262,9 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch
|
||||
encoder(mac+3, encode+4);
|
||||
encode[8] = 0;
|
||||
}
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, 1);
|
||||
}
|
||||
|
||||
return plen;
|
||||
return add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, replace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,10 @@ static char *my_readlink(char *path)
|
||||
{
|
||||
/* Not link or doesn't exist. */
|
||||
if (errno == EINVAL || errno == ENOENT)
|
||||
return NULL;
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
die(_("cannot access path %s: %s"), path, EC_MISC);
|
||||
}
|
||||
@@ -200,6 +203,8 @@ void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revh
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir_stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -532,13 +532,14 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
||||
{
|
||||
union mysockaddr addr;
|
||||
int prefix, bit;
|
||||
|
||||
(void)broadcast; /* warning */
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
addr.in.sin_len = sizeof(addr.in);
|
||||
#endif
|
||||
addr.in.sin_family = AF_INET;
|
||||
addr.in.sin_addr = broadcast; /* warning */
|
||||
addr.in.sin_addr = local;
|
||||
addr.in.sin_port = htons(daemon->port);
|
||||
|
||||
@@ -809,10 +810,11 @@ int tcp_interface(int fd, int af)
|
||||
int opt = 1;
|
||||
struct cmsghdr *cmptr;
|
||||
struct msghdr msg;
|
||||
socklen_t len;
|
||||
|
||||
/* use mshdr do that the CMSDG_* macros are available */
|
||||
/* use mshdr so that the CMSDG_* macros are available */
|
||||
msg.msg_control = daemon->packet;
|
||||
msg.msg_controllen = daemon->packet_buff_sz;
|
||||
msg.msg_controllen = len = daemon->packet_buff_sz;
|
||||
|
||||
/* we overwrote the buffer... */
|
||||
daemon->srv_save = NULL;
|
||||
@@ -820,18 +822,21 @@ int tcp_interface(int fd, int af)
|
||||
if (af == AF_INET)
|
||||
{
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
|
||||
getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
union {
|
||||
unsigned char *c;
|
||||
struct in_pktinfo *p;
|
||||
} p;
|
||||
|
||||
p.c = CMSG_DATA(cmptr);
|
||||
if_index = p.p->ipi_ifindex;
|
||||
}
|
||||
getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
|
||||
{
|
||||
msg.msg_controllen = len;
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
union {
|
||||
unsigned char *c;
|
||||
struct in_pktinfo *p;
|
||||
} p;
|
||||
|
||||
p.c = CMSG_DATA(cmptr);
|
||||
if_index = p.p->ipi_ifindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
@@ -849,9 +854,10 @@ int tcp_interface(int fd, int af)
|
||||
#endif
|
||||
|
||||
if (set_ipv6pktinfo(fd) &&
|
||||
getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
|
||||
getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
|
||||
{
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
msg.msg_controllen = len;
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
|
||||
{
|
||||
union {
|
||||
@@ -1403,7 +1409,6 @@ void add_update_server(int flags,
|
||||
serv->domain = domain_str;
|
||||
serv->next = next;
|
||||
serv->queries = serv->failed_queries = 0;
|
||||
serv->edns_pktsz = daemon->edns_pktsz;
|
||||
#ifdef HAVE_LOOP
|
||||
serv->uid = rand32();
|
||||
#endif
|
||||
@@ -1441,6 +1446,10 @@ void check_servers(void)
|
||||
{
|
||||
if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
|
||||
{
|
||||
/* Init edns_pktsz for newly created server records. */
|
||||
if (serv->edns_pktsz == 0)
|
||||
serv->edns_pktsz = daemon->edns_pktsz;
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (option_bool(OPT_DNSSEC_VALID))
|
||||
{
|
||||
|
||||
31
src/option.c
31
src/option.c
@@ -1199,7 +1199,8 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
|
||||
cp = comma;
|
||||
comma = split(cp);
|
||||
slash = split_chr(cp, '/');
|
||||
inet_pton(AF_INET, cp, &in);
|
||||
if (!inet_pton(AF_INET, cp, &in))
|
||||
ret_err(_("bad IPv4 address"));
|
||||
if (!slash)
|
||||
{
|
||||
memcpy(op, &in, INADDRSZ);
|
||||
@@ -3658,8 +3659,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
(!(inet_pton(AF_INET, a[1], &new->out) > 0)))
|
||||
option = '?';
|
||||
|
||||
if (k == 3)
|
||||
inet_pton(AF_INET, a[2], &new->mask);
|
||||
if (k == 3 && !inet_pton(AF_INET, a[2], &new->mask))
|
||||
option = '?';
|
||||
|
||||
if (dash &&
|
||||
(!(inet_pton(AF_INET, dash, &new->end) > 0) ||
|
||||
@@ -3799,7 +3800,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_RR: /* dns-rr */
|
||||
{
|
||||
struct txt_record *new;
|
||||
size_t len = len;
|
||||
size_t len = 0;
|
||||
char *data;
|
||||
int val;
|
||||
|
||||
@@ -4611,21 +4612,17 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
||||
{
|
||||
struct server *tmp;
|
||||
for (tmp = daemon->servers; tmp; tmp = tmp->next)
|
||||
{
|
||||
tmp->edns_pktsz = daemon->edns_pktsz;
|
||||
|
||||
if (!(tmp->flags & SERV_HAS_SOURCE))
|
||||
{
|
||||
if (tmp->source_addr.sa.sa_family == AF_INET)
|
||||
tmp->source_addr.in.sin_port = htons(daemon->query_port);
|
||||
if (!(tmp->flags & SERV_HAS_SOURCE))
|
||||
{
|
||||
if (tmp->source_addr.sa.sa_family == AF_INET)
|
||||
tmp->source_addr.in.sin_port = htons(daemon->query_port);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (tmp->source_addr.sa.sa_family == AF_INET6)
|
||||
tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
|
||||
else if (tmp->source_addr.sa.sa_family == AF_INET6)
|
||||
tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (daemon->host_records)
|
||||
{
|
||||
struct host_record *hr;
|
||||
|
||||
@@ -346,14 +346,15 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
{
|
||||
if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
|
||||
{
|
||||
/* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
|
||||
int overhead = (listen->family == AF_INET) ? 32 : 52;
|
||||
transfer->blocksize = atoi(opt);
|
||||
if (transfer->blocksize < 1)
|
||||
transfer->blocksize = 1;
|
||||
if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
|
||||
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
|
||||
/* 32 bytes for IP, UDP and TFTP headers */
|
||||
if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
|
||||
transfer->blocksize = (unsigned)mtu - 32;
|
||||
if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead)
|
||||
transfer->blocksize = (unsigned)mtu - overhead;
|
||||
transfer->opt_blocksize = 1;
|
||||
transfer->block = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user