Compare commits
26 Commits
v2.76test1
...
v2.76test1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c0c36f54b | ||
|
|
d6b749af91 | ||
|
|
14ffa0770b | ||
|
|
87985855ad | ||
|
|
a2bc254bed | ||
|
|
a7b27e84fa | ||
|
|
529b030228 | ||
|
|
4caa86dd7d | ||
|
|
e1abeeeec2 | ||
|
|
40205a053e | ||
|
|
b8ac466209 | ||
|
|
d1377fa3c4 | ||
|
|
fa79466c2a | ||
|
|
a93bd4b016 | ||
|
|
407a1f3e95 | ||
|
|
4b6af5d53f | ||
|
|
7aa3f9af66 | ||
|
|
f7cf749943 | ||
|
|
aa300f7167 | ||
|
|
c7f3bd2ac8 | ||
|
|
22fe2fd038 | ||
|
|
7480aeffc8 | ||
|
|
bec366b404 | ||
|
|
e06e6e34bf | ||
|
|
832e47beab | ||
|
|
df3d54f776 |
17
CHANGELOG
17
CHANGELOG
@@ -48,6 +48,23 @@ version 2.76
|
||||
(ie xx::0 to xx::ffff:ffff:ffff:ffff)
|
||||
Thanks to Laurent Bendel for spotting this problem.
|
||||
|
||||
Add support for a TTL parameter in --host-record and
|
||||
--cname.
|
||||
|
||||
Add --dhcp-ttl option.
|
||||
|
||||
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
|
||||
|
||||
@@ -60,7 +60,7 @@ in the same way as for DHCP-derived names. Note that this does not
|
||||
apply to domain names in cnames, PTR records, TXT records etc.
|
||||
.TP
|
||||
.B \-T, --local-ttl=<time>
|
||||
When replying with information from /etc/hosts or the DHCP leases
|
||||
When replying with information from /etc/hosts or configuration or the DHCP leases
|
||||
file dnsmasq by default sets the time-to-live field to zero, meaning
|
||||
that the requester should not itself cache the information. This is
|
||||
the correct thing to do in almost all situations. This option allows a
|
||||
@@ -68,6 +68,9 @@ time-to-live (in seconds) to be given for these replies. This will
|
||||
reduce the load on the server at the expense of clients using stale
|
||||
data under some circumstances.
|
||||
.TP
|
||||
.B --dhcp-ttl=<time>
|
||||
As for --local-ttl, but affects only replies with information from DHCP leases. If both are given, --dhcp-ttl applies for DHCP information, and --local-ttl for others. Setting this to zero eliminates the effect of --local-ttl for DHCP.
|
||||
.TP
|
||||
.B --neg-ttl=<time>
|
||||
Negative replies from upstream servers normally contain time-to-live
|
||||
information in SOA records which dnsmasq uses for caching. If the
|
||||
@@ -529,7 +532,7 @@ zone files: the port, weight and priority numbers are in a different
|
||||
order. More than one SRV record for a given service/domain is allowed,
|
||||
all that match are returned.
|
||||
.TP
|
||||
.B --host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>]
|
||||
.B --host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
|
||||
Add A, AAAA and PTR records to the DNS. This adds one or more names to
|
||||
the DNS with associated IPv4 (A) and IPv6 (AAAA) records. A name may
|
||||
appear in more than one
|
||||
@@ -546,6 +549,10 @@ is in effect. Short and long names may appear in the same
|
||||
.B host-record,
|
||||
eg.
|
||||
.B --host-record=laptop,laptop.thekelleys.org,192.168.0.1,1234::100
|
||||
|
||||
If the time-to-live is given, it overrides the default, which is zero
|
||||
or the value of --local-ttl. The value is a positive integer and gives
|
||||
the time-to-live in seconds.
|
||||
.TP
|
||||
.B \-Y, --txt-record=<name>[[,<text>],<text>]
|
||||
Return a TXT DNS record. The value of TXT record is a set of strings,
|
||||
@@ -559,7 +566,7 @@ Return a PTR DNS record.
|
||||
.B --naptr-record=<name>,<order>,<preference>,<flags>,<service>,<regexp>[,<replacement>]
|
||||
Return an NAPTR DNS record, as specified in RFC3403.
|
||||
.TP
|
||||
.B --cname=<cname>,<target>
|
||||
.B --cname=<cname>,<target>[,<TTL>]
|
||||
Return a CNAME record which indicates that <cname> is really
|
||||
<target>. There are significant limitations on the target; it must be a
|
||||
DNS name which is known to dnsmasq from /etc/hosts (or additional
|
||||
@@ -568,6 +575,10 @@ hosts files), from DHCP, from --interface-name or from another
|
||||
If the target does not satisfy this
|
||||
criteria, the whole cname is ignored. The cname must be unique, but it
|
||||
is permissable to have more than one cname pointing to the same target.
|
||||
|
||||
If the time-to-live is given, it overrides the default, which is zero
|
||||
or the value of -local-ttl. The value is a positive integer and gives
|
||||
the time-to-live in seconds.
|
||||
.TP
|
||||
.B --dns-rr=<name>,<RR-number>,[<hex data>]
|
||||
Return an arbitrary DNS Resource Record. The number is the type of the
|
||||
@@ -772,7 +783,7 @@ compiled in and the kernel must have conntrack support
|
||||
included and configured. This option cannot be combined with
|
||||
--query-port.
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-IPv6addr>[,<end-IPv6addr>|constructor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
|
||||
|
||||
@@ -1799,6 +1810,10 @@ require about (2*n) + 10 descriptors. If
|
||||
.B --tftp-port-range
|
||||
is given, that can affect the number of concurrent connections.
|
||||
.TP
|
||||
.B --tftp-mtu=<mtu size>
|
||||
Use size as the ceiling of the MTU supported by the intervening network when
|
||||
negotiating TFTP blocksize, overriding the MTU setting of the local interface if it is larger.
|
||||
.TP
|
||||
.B --tftp-no-blocksize
|
||||
Stop the TFTP server from negotiating the "blocksize" option with a
|
||||
client. Some buggy clients request this option but then behave badly
|
||||
|
||||
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. */
|
||||
|
||||
@@ -824,7 +824,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
/* Advertise our packet size limit in our reply */
|
||||
if (have_pseudoheader)
|
||||
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit);
|
||||
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
|
||||
|
||||
return ansp - (unsigned char *)header;
|
||||
}
|
||||
|
||||
@@ -778,6 +778,7 @@ static void add_hosts_cname(struct crec *target)
|
||||
(crec = whine_malloc(sizeof(struct crec))))
|
||||
{
|
||||
crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_CONFIG | F_CNAME;
|
||||
crec->ttd = a->ttl;
|
||||
crec->name.namep = a->alias;
|
||||
crec->addr.cname.target.cache = target;
|
||||
crec->addr.cname.uid = target->uid;
|
||||
@@ -981,6 +982,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
|
||||
strcat(cache->name.sname, ".");
|
||||
strcat(cache->name.sname, domain_suffix);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
}
|
||||
@@ -988,6 +990,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
|
||||
{
|
||||
strcpy(cache->name.sname, canon);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
}
|
||||
@@ -1057,6 +1060,7 @@ void cache_reload(void)
|
||||
((cache = whine_malloc(sizeof(struct crec)))))
|
||||
{
|
||||
cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
|
||||
cache->ttd = a->ttl;
|
||||
cache->name.namep = a->alias;
|
||||
cache->addr.cname.target.int_name = intr;
|
||||
cache->addr.cname.uid = SRC_INTERFACE;
|
||||
@@ -1071,6 +1075,7 @@ void cache_reload(void)
|
||||
(cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
{
|
||||
cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
cache->name.namep = ds->name;
|
||||
cache->addr.ds.keylen = ds->digestlen;
|
||||
cache->addr.ds.algo = ds->algo;
|
||||
@@ -1095,6 +1100,7 @@ void cache_reload(void)
|
||||
(cache = whine_malloc(sizeof(struct crec))))
|
||||
{
|
||||
cache->name.namep = nl->name;
|
||||
cache->ttd = hr->ttl;
|
||||
cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG;
|
||||
add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
|
||||
}
|
||||
@@ -1103,6 +1109,7 @@ void cache_reload(void)
|
||||
(cache = whine_malloc(sizeof(struct crec))))
|
||||
{
|
||||
cache->name.namep = nl->name;
|
||||
cache->ttd = hr->ttl;
|
||||
cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG;
|
||||
add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -561,10 +561,13 @@ int main (int argc, char **argv)
|
||||
{
|
||||
/* open stdout etc to /dev/null */
|
||||
int nullfd = open("/dev/null", O_RDWR);
|
||||
dup2(nullfd, STDOUT_FILENO);
|
||||
dup2(nullfd, STDERR_FILENO);
|
||||
dup2(nullfd, STDIN_FILENO);
|
||||
close(nullfd);
|
||||
if (nullfd != -1)
|
||||
{
|
||||
dup2(nullfd, STDOUT_FILENO);
|
||||
dup2(nullfd, STDERR_FILENO);
|
||||
dup2(nullfd, STDIN_FILENO);
|
||||
close(nullfd);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we are to run scripts, we need to fork a helper before dropping root. */
|
||||
|
||||
@@ -308,6 +308,7 @@ struct ptr_record {
|
||||
};
|
||||
|
||||
struct cname {
|
||||
int ttl;
|
||||
char *alias, *target;
|
||||
struct cname *next;
|
||||
};
|
||||
@@ -344,6 +345,7 @@ struct auth_zone {
|
||||
|
||||
|
||||
struct host_record {
|
||||
int ttl;
|
||||
struct name_list {
|
||||
char *name;
|
||||
struct name_list *next;
|
||||
@@ -953,7 +955,7 @@ extern struct daemon {
|
||||
int max_logs; /* queue limit */
|
||||
int cachesize, ftabsize;
|
||||
int port, query_port, min_port, max_port;
|
||||
unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl;
|
||||
unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl;
|
||||
char *dns_client_id;
|
||||
struct hostsfile *addn_hosts;
|
||||
struct dhcp_context *dhcp, *dhcp6;
|
||||
@@ -973,7 +975,7 @@ extern struct daemon {
|
||||
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
|
||||
struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
|
||||
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
|
||||
int dhcp_max, tftp_max;
|
||||
int dhcp_max, tftp_max, tftp_mtu;
|
||||
int dhcp_server_port, dhcp_client_port;
|
||||
int start_tftp_port, end_tftp_port;
|
||||
unsigned int min_leasetime;
|
||||
@@ -1521,7 +1523,7 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new);
|
||||
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
||||
size_t *len, unsigned char **p, int *is_sign, int *is_last);
|
||||
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);
|
||||
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace);
|
||||
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit);
|
||||
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
union mysockaddr *source, time_t now, int *check_subnet);
|
||||
|
||||
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 */
|
||||
|
||||
78
src/edns0.c
78
src/edns0.c
@@ -95,8 +95,10 @@ 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)
|
||||
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace)
|
||||
{
|
||||
unsigned char *lenp, *datap, *p, *udp_len, *buff = NULL;
|
||||
int rdlen = 0, is_sign, is_last;
|
||||
@@ -120,7 +122,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
|
||||
if (set_do)
|
||||
{
|
||||
p -=2;
|
||||
p -= 2;
|
||||
flags |= 0x8000;
|
||||
PUTSHORT(flags, p);
|
||||
}
|
||||
@@ -136,13 +138,36 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
return plen;
|
||||
|
||||
/* check if option already there */
|
||||
for (i = 0; i + 4 < rdlen; i += len + 4)
|
||||
for (i = 0; i + 4 < rdlen;)
|
||||
{
|
||||
GETSHORT(code, p);
|
||||
GETSHORT(len, p);
|
||||
|
||||
/* malformed option, delete the whole OPT RR and start again. */
|
||||
if (i + len > rdlen)
|
||||
{
|
||||
rdlen = 0;
|
||||
is_last = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == optno)
|
||||
return plen;
|
||||
p += len;
|
||||
{
|
||||
if (replace == 0)
|
||||
return plen;
|
||||
|
||||
/* delete option if we're to replace it. */
|
||||
p -= 4;
|
||||
rdlen -= len + 4;
|
||||
memcpy(p, p+len+4, rdlen - i);
|
||||
PUTSHORT(rdlen, lenp);
|
||||
lenp -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += len;
|
||||
i += len + 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're going to extend the RR, it has to be the last RR in the packet */
|
||||
@@ -190,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);
|
||||
@@ -203,7 +228,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
|
||||
|
||||
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit)
|
||||
{
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, 0, NULL, 0, 1);
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, 0, NULL, 0, 1, 0);
|
||||
}
|
||||
|
||||
static unsigned char char64(unsigned char c)
|
||||
@@ -221,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
|
||||
@@ -235,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);
|
||||
}
|
||||
|
||||
return plen;
|
||||
return add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, replace);
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +274,7 @@ static size_t add_mac(struct dns_header *header, size_t plen, unsigned char *lim
|
||||
unsigned char mac[DHCP_CHADDR_MAX];
|
||||
|
||||
if ((maclen = find_mac(l3, mac, 1, now)) != 0)
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_MAC, mac, maclen, 0);
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_MAC, mac, maclen, 0, 0);
|
||||
|
||||
return plen;
|
||||
}
|
||||
@@ -281,8 +307,11 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
void *addrp;
|
||||
int sa_family = source->sa.sa_family;
|
||||
|
||||
opt->source_netmask = 0;
|
||||
opt->scope_netmask = 0;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (source->sa.sa_family == AF_INET6)
|
||||
if (source->sa.sa_family == AF_INET6 && daemon->add_subnet6)
|
||||
{
|
||||
opt->source_netmask = daemon->add_subnet6->mask;
|
||||
if (daemon->add_subnet6->addr_used)
|
||||
@@ -293,8 +322,9 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
else
|
||||
addrp = &source->in6.sin6_addr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (source->sa.sa_family == AF_INET && daemon->add_subnet4)
|
||||
{
|
||||
opt->source_netmask = daemon->add_subnet4->mask;
|
||||
if (daemon->add_subnet4->addr_used)
|
||||
@@ -302,26 +332,26 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
sa_family = daemon->add_subnet4->addr.sa.sa_family;
|
||||
addrp = get_addrp(&daemon->add_subnet4->addr, sa_family);
|
||||
}
|
||||
else
|
||||
addrp = &source->in.sin_addr;
|
||||
else
|
||||
addrp = &source->in.sin_addr;
|
||||
}
|
||||
|
||||
opt->scope_netmask = 0;
|
||||
#ifdef HAVE_IPV6
|
||||
opt->family = htons(sa_family == AF_INET6 ? 2 : 1);
|
||||
#else
|
||||
opt->family = htons(1);
|
||||
#endif
|
||||
|
||||
len = 0;
|
||||
|
||||
if (opt->source_netmask != 0)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
opt->family = htons(sa_family == AF_INET6 ? 2 : 1);
|
||||
#else
|
||||
opt->family = htons(1);
|
||||
#endif
|
||||
len = ((opt->source_netmask - 1) >> 3) + 1;
|
||||
memcpy(opt->addr, addrp, len);
|
||||
if (opt->source_netmask & 7)
|
||||
opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
|
||||
}
|
||||
|
||||
|
||||
return len + 4;
|
||||
}
|
||||
|
||||
@@ -333,7 +363,7 @@ static size_t add_source_addr(struct dns_header *header, size_t plen, unsigned c
|
||||
struct subnet_opt opt;
|
||||
|
||||
len = calc_subnet_opt(&opt, source);
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0);
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0, 0);
|
||||
}
|
||||
|
||||
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
|
||||
@@ -387,7 +417,7 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
|
||||
|
||||
if (daemon->dns_client_id)
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID,
|
||||
(unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0);
|
||||
(unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0, 1);
|
||||
|
||||
if (option_bool(OPT_CLIENT_SUBNET))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
src/lease.c
20
src/lease.c
@@ -1110,18 +1110,22 @@ int do_script_run(time_t now)
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCRIPT
|
||||
/* delim == -1 -> delim = 0, but embeded 0s, creating extra records, are OK. */
|
||||
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* check for embeded NULLs */
|
||||
for (i = 0; i < len; i++)
|
||||
if (data[i] == 0)
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (delim == -1)
|
||||
delim = 0;
|
||||
else
|
||||
/* check for embeded NULLs */
|
||||
for (i = 0; i < len; i++)
|
||||
if (data[i] == 0)
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((lease->extradata_size - lease->extradata_len) < (len + 1))
|
||||
{
|
||||
size_t newsz = lease->extradata_len + len + 100;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
143
src/option.c
143
src/option.c
@@ -157,7 +157,9 @@ struct myoption {
|
||||
#define LOPT_MAXPORT 345
|
||||
#define LOPT_CPE_ID 346
|
||||
#define LOPT_SCRIPT_ARP 347
|
||||
|
||||
#define LOPT_DHCPTTL 348
|
||||
#define LOPT_TFTP_MTU 349
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static const struct option opts[] =
|
||||
#else
|
||||
@@ -243,6 +245,7 @@ static const struct myoption opts[] =
|
||||
{ "tftp-unique-root", 0, 0, LOPT_APREF },
|
||||
{ "tftp-root", 1, 0, LOPT_PREFIX },
|
||||
{ "tftp-max", 1, 0, LOPT_TFTP_MAX },
|
||||
{ "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
|
||||
{ "tftp-lowercase", 0, 0, LOPT_TFTP_LC },
|
||||
{ "ptr-record", 1, 0, LOPT_PTR },
|
||||
{ "naptr-record", 1, 0, LOPT_NAPTR },
|
||||
@@ -319,6 +322,7 @@ static const struct myoption opts[] =
|
||||
{ "quiet-ra", 0, 0, LOPT_QUIET_RA },
|
||||
{ "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
|
||||
{ "script-arp", 0, 0, LOPT_SCRIPT_ARP },
|
||||
{ "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -430,6 +434,7 @@ static struct {
|
||||
{ LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
|
||||
{ LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
|
||||
{ LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
|
||||
{ LOPT_TFTP_MTU, ARG_ONE, "<integer>", gettext_noop("Maximum MTU to use for TFTP transfers."), NULL },
|
||||
{ LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
|
||||
{ LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
|
||||
{ LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
|
||||
@@ -448,20 +453,20 @@ static struct {
|
||||
{ LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
|
||||
{ LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
|
||||
{ LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
|
||||
{ LOPT_CNAME, ARG_DUP, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
|
||||
{ LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
|
||||
{ LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
|
||||
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
|
||||
{ LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
|
||||
{ LOPT_ADD_MAC, ARG_DUP, "[=base64|text]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
|
||||
{ LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
|
||||
{ LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
|
||||
{ LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
|
||||
{ LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
|
||||
{ LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
|
||||
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
||||
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
||||
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
||||
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
||||
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
||||
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
||||
{ LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
|
||||
{ LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
|
||||
{ LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
|
||||
@@ -485,9 +490,10 @@ static struct {
|
||||
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
|
||||
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
|
||||
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
|
||||
{ LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks"), NULL },
|
||||
{ LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops"), NULL },
|
||||
{ LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
|
||||
{ LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
|
||||
{ LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
|
||||
{ LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
|
||||
{ 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -1193,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);
|
||||
@@ -1641,12 +1648,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
|
||||
daemon->add_subnet4 = new;
|
||||
|
||||
new = opt_malloc(sizeof(struct mysubnet));
|
||||
if (comma)
|
||||
{
|
||||
if ((end = split_chr(comma, '/')))
|
||||
{
|
||||
/* has subnet+len */
|
||||
new = opt_malloc(sizeof(struct mysubnet));
|
||||
if ((end = split_chr(comma, '/')))
|
||||
{
|
||||
/* has subnet+len */
|
||||
err = parse_mysockaddr(comma, &new->addr);
|
||||
if (err)
|
||||
ret_err(err);
|
||||
@@ -1659,8 +1666,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
if (!atoi_check(comma, &new->mask))
|
||||
ret_err(gen_err);
|
||||
}
|
||||
}
|
||||
daemon->add_subnet6 = new;
|
||||
|
||||
daemon->add_subnet6 = new;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1983,11 +1991,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
comma = split(arg);
|
||||
daemon->soa_retry = (u32)atoi(arg);
|
||||
if (comma)
|
||||
{
|
||||
arg = comma;
|
||||
comma = split(arg);
|
||||
daemon->soa_expiry = (u32)atoi(arg);
|
||||
}
|
||||
daemon->soa_expiry = (u32)atoi(comma);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2164,7 +2168,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
daemon->dns_client_id = opt_string_alloc(arg);
|
||||
break;
|
||||
|
||||
case LOPT_ADD_MAC:
|
||||
case LOPT_ADD_MAC: /* --add-mac */
|
||||
if (!arg)
|
||||
set_option_bool(OPT_ADD_MAC);
|
||||
else
|
||||
@@ -2580,6 +2584,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_MINCTTL: /* --min-cache-ttl */
|
||||
case LOPT_MAXCTTL: /* --max-cache-ttl */
|
||||
case LOPT_AUTHTTL: /* --auth-ttl */
|
||||
case LOPT_DHCPTTL: /* --dhcp-ttl */
|
||||
{
|
||||
int ttl;
|
||||
if (!atoi_check(arg, &ttl))
|
||||
@@ -2598,6 +2603,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
daemon->max_cache_ttl = (unsigned long)ttl;
|
||||
else if (option == LOPT_AUTHTTL)
|
||||
daemon->auth_ttl = (unsigned long)ttl;
|
||||
else if (option == LOPT_DHCPTTL)
|
||||
{
|
||||
daemon->dhcp_ttl = (unsigned long)ttl;
|
||||
daemon->use_dhcp_ttl = 1;
|
||||
}
|
||||
else
|
||||
daemon->local_ttl = (unsigned long)ttl;
|
||||
break;
|
||||
@@ -2616,6 +2626,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
ret_err(gen_err);
|
||||
break;
|
||||
|
||||
case LOPT_TFTP_MTU: /* --tftp-mtu */
|
||||
if (!atoi_check(arg, &daemon->tftp_mtu))
|
||||
ret_err(gen_err);
|
||||
break;
|
||||
|
||||
case LOPT_PREFIX: /* --tftp-prefix */
|
||||
comma = split(arg);
|
||||
if (comma)
|
||||
@@ -2758,13 +2773,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
leasepos = 3;
|
||||
if (!is_same_net(new->start, new->end, new->netmask))
|
||||
ret_err(_("inconsistent DHCP range"));
|
||||
}
|
||||
|
||||
|
||||
if (k >= 4 && strchr(a[3], '.') &&
|
||||
(inet_pton(AF_INET, a[3], &new->broadcast) > 0))
|
||||
{
|
||||
new->flags |= CONTEXT_BRDCAST;
|
||||
leasepos = 4;
|
||||
if (k >= 4 && strchr(a[3], '.') &&
|
||||
(inet_pton(AF_INET, a[3], &new->broadcast) > 0))
|
||||
{
|
||||
new->flags |= CONTEXT_BRDCAST;
|
||||
leasepos = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
@@ -2854,6 +2870,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
|
||||
if (leasepos < k)
|
||||
{
|
||||
if (leasepos != k-1)
|
||||
ret_err(_("bad dhcp-range"));
|
||||
|
||||
if (strcmp(a[leasepos], "infinite") == 0)
|
||||
new->lease_time = 0xffffffff;
|
||||
else if (strcmp(a[leasepos], "deprecated") == 0)
|
||||
@@ -2948,7 +2967,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
}
|
||||
|
||||
if (len == -1)
|
||||
|
||||
ret_err(_("bad hex constant"));
|
||||
else if ((new->clid = opt_malloc(len)))
|
||||
{
|
||||
@@ -3641,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) ||
|
||||
@@ -3692,12 +3710,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_CNAME: /* --cname */
|
||||
{
|
||||
struct cname *new;
|
||||
char *alias;
|
||||
char *target;
|
||||
char *alias, *target, *ttls;
|
||||
int ttl = -1;
|
||||
|
||||
if (!(comma = split(arg)))
|
||||
ret_err(gen_err);
|
||||
|
||||
if ((ttls = split(comma)) && !atoi_check(ttls, &ttl))
|
||||
ret_err(_("bad TTL"));
|
||||
|
||||
alias = canonicalise_opt(arg);
|
||||
target = canonicalise_opt(comma);
|
||||
|
||||
@@ -3713,6 +3734,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
daemon->cnames = new;
|
||||
new->alias = alias;
|
||||
new->target = target;
|
||||
new->ttl = ttl;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -3778,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;
|
||||
|
||||
@@ -3886,13 +3908,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
if (!atoi_check16(arg, &priority))
|
||||
ret_err(_("invalid priority"));
|
||||
|
||||
if (comma)
|
||||
{
|
||||
arg = comma;
|
||||
comma = split(arg);
|
||||
if (!atoi_check16(arg, &weight))
|
||||
ret_err(_("invalid weight"));
|
||||
}
|
||||
if (comma && !atoi_check16(comma, &weight))
|
||||
ret_err(_("invalid weight"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3913,14 +3930,22 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
{
|
||||
struct host_record *new = opt_malloc(sizeof(struct host_record));
|
||||
memset(new, 0, sizeof(struct host_record));
|
||||
|
||||
new->ttl = -1;
|
||||
|
||||
if (!arg || !(comma = split(arg)))
|
||||
ret_err(_("Bad host-record"));
|
||||
|
||||
while (arg)
|
||||
{
|
||||
struct all_addr addr;
|
||||
if (inet_pton(AF_INET, arg, &addr))
|
||||
char *dig;
|
||||
|
||||
for (dig = arg; *dig != 0; dig++)
|
||||
if (*dig < '0' || *dig > '9')
|
||||
break;
|
||||
if (*dig == 0)
|
||||
new->ttl = atoi(arg);
|
||||
else if (inet_pton(AF_INET, arg, &addr))
|
||||
new->addr = addr.addr.addr4;
|
||||
#ifdef HAVE_IPV6
|
||||
else if (inet_pton(AF_INET6, arg, &addr))
|
||||
@@ -4587,21 +4612,35 @@ 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;
|
||||
|
||||
for (hr = daemon->host_records; hr; hr = hr->next)
|
||||
if (hr->ttl == -1)
|
||||
hr->ttl = daemon->local_ttl;
|
||||
}
|
||||
|
||||
if (daemon->cnames)
|
||||
{
|
||||
struct cname *cn;
|
||||
|
||||
for (cn = daemon->cnames; cn; cn = cn->next)
|
||||
if (cn->ttl == -1)
|
||||
cn->ttl = daemon->local_ttl;
|
||||
}
|
||||
|
||||
if (daemon->if_addrs)
|
||||
{
|
||||
struct iname *tmp;
|
||||
|
||||
@@ -1167,11 +1167,23 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
||||
{
|
||||
/* Return 0 ttl for DHCP entries, which might change
|
||||
before the lease expires. */
|
||||
before the lease expires, unless configured otherwise. */
|
||||
|
||||
if (crecp->flags & (F_IMMORTAL | F_DHCP))
|
||||
return daemon->local_ttl;
|
||||
if (crecp->flags & F_DHCP)
|
||||
{
|
||||
int conf_ttl = daemon->use_dhcp_ttl ? daemon->dhcp_ttl : daemon->local_ttl;
|
||||
|
||||
/* Apply ceiling of actual lease length to configured TTL. */
|
||||
if (!(crecp->flags & F_IMMORTAL) && (crecp->ttd - now) < conf_ttl)
|
||||
return crecp->ttd - now;
|
||||
|
||||
return conf_ttl;
|
||||
}
|
||||
|
||||
/* Immortal entries other than DHCP are local, and hold TTL in TTD field. */
|
||||
if (crecp->flags & F_IMMORTAL)
|
||||
return crecp->ttd;
|
||||
|
||||
/* Return the Max TTL value if it is lower then the actual TTL */
|
||||
if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
|
||||
return crecp->ttd - now;
|
||||
@@ -1835,7 +1847,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
|
||||
/* Advertise our packet size limit in our reply */
|
||||
if (have_pseudoheader)
|
||||
len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit);
|
||||
len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
|
||||
|
||||
if (ad_reqd && sec_data)
|
||||
header->hb4 |= HB4_AD;
|
||||
|
||||
@@ -1308,7 +1308,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
/* If the user-class option started as counted strings, the first byte will be zero. */
|
||||
if (len != 0 && ucp[0] == 0)
|
||||
ucp++, len--;
|
||||
lease_add_extradata(lease, ucp, len, 0);
|
||||
lease_add_extradata(lease, ucp, len, -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -323,12 +323,12 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new)
|
||||
|
||||
new += 5;
|
||||
|
||||
if (!(p = whine_malloc(new * sizeof(unsigned char **))))
|
||||
if (!(p = whine_malloc(new * sizeof(unsigned char *))))
|
||||
return 0;
|
||||
|
||||
if (old != 0 && *wkspc)
|
||||
{
|
||||
memcpy(p, *wkspc, old * sizeof(unsigned char **));
|
||||
memcpy(p, *wkspc, old * sizeof(unsigned char *));
|
||||
free(*wkspc);
|
||||
}
|
||||
|
||||
|
||||
21
src/tftp.c
21
src/tftp.c
@@ -103,8 +103,10 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
if (listen->iface)
|
||||
{
|
||||
addr = listen->iface->addr;
|
||||
mtu = listen->iface->mtu;
|
||||
name = listen->iface->name;
|
||||
mtu = listen->iface->mtu;
|
||||
if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
|
||||
mtu = daemon->tftp_mtu;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -234,9 +236,17 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
|
||||
strncpy(ifr.ifr_name, name, IF_NAMESIZE);
|
||||
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
|
||||
mtu = ifr.ifr_mtu;
|
||||
{
|
||||
mtu = ifr.ifr_mtu;
|
||||
if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
|
||||
mtu = daemon->tftp_mtu;
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed to get interface mtu - can use configured value. */
|
||||
if (mtu == 0)
|
||||
mtu = daemon->tftp_mtu;
|
||||
|
||||
if (name)
|
||||
{
|
||||
/* check for per-interface prefix */
|
||||
@@ -336,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