Compare commits

...
14 Commits
14 changed files with 246 additions and 81 deletions

No files matched your search

+15 -4
View File
@@ -40,12 +40,23 @@ version 2.76
Extend --add-mac to allow a new encoding of the MAC address
as base64, by configurting --add-mac=base64
Add --add-cpe-id option.
Don't crash with divide-by-zero if an IPv6 dhcp-range
is declared as a whole /64.
(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.
version 2.75
Fix reversion on 2.74 which caused 100% CPU use when a
dhcp-script is configured. Thanks to Adrian Davey for
+24 -9
View File
@@ -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
@@ -604,7 +615,7 @@ configured a zero is added in front of the label. ::1 becomes 0--1.
The address range can be of the form
<ip address>,<ip address> or <ip address>/<netmask>
.TP
.B --add-mac[=base64]
.B --add-mac[=base64|text]
Add the MAC address of the requestor to DNS queries which are
forwarded upstream. This may be used to DNS filtering by the upstream
server. The MAC address can only be added if the requestor is on the same
@@ -613,7 +624,7 @@ is not yet standardised, so this should be considered
experimental. Also note that exposing MAC addresses in this way may
have security and privacy implications. The warning about caching
given for --add-subnet applies to --add-mac too. An alternative encoding of the
MAC, as base64, is enabled by adding the "base64" parameter.
MAC, as base64, is enabled by adding the "base64" parameter and a human-readable encoding of hex-and-colons is enabled by added the "text" parameter.
.TP
.B --add-cpe-id=<string>
Add a arbitrary identifying string to o DNS queries which are
@@ -1552,7 +1563,7 @@ with an "old" event.
There are four further actions which may appear as the first argument
to the script, "init", "arp", "arp-old" and "tftp". More may be added in the future, so
to the script, "init", "arp-add", "arp-del" and "tftp". More may be added in the future, so
scripts should be written to ignore unknown actions. "init" is
described below in
.B --leasefile-ro
@@ -1560,10 +1571,10 @@ The "tftp" action is invoked when a TFTP file transfer completes: the
arguments are the file size in bytes, the address to which the file
was sent, and the complete pathname of the file.
The "arp" and "arp-old" actions are only called if enabled with
The "arp-add" and "arp-del" actions are only called if enabled with
.B --script-arp
They are are supplied with a MAC address and IP address as arguments. "arp" indicates
the arrival of a new entry in the ARP or neighbour table, and arp-old indicates the deletion of same.
They are are supplied with a MAC address and IP address as arguments. "arp-add" indicates
the arrival of a new entry in the ARP or neighbour table, and "arp-del" indicates the deletion of same.
.TP
.B --dhcp-luascript=<path>
@@ -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
+6 -1
View File
@@ -44,6 +44,11 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
if (maclen > DHCP_CHADDR_MAX)
return 1;
#ifndef HAVE_IPV6
if (family != AF_INET)
return 1;
#endif
/* Look for existing entry */
for (arp = arps; arp; arp = arp->next)
{
@@ -216,7 +221,7 @@ int do_arp_script_run(void)
{
#ifdef HAVE_SCRIPT
if (option_bool(OPT_SCRIPT_ARP))
queue_arp(ACTION_ARP_OLD, old->hwaddr, old->hwlen, old->family, &old->addr);
queue_arp(ACTION_ARP_DEL, old->hwaddr, old->hwlen, old->family, &old->addr);
#endif
arp = old;
old = arp->next;
+1 -1
View File
@@ -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;
}
+2
View File
@@ -20,7 +20,9 @@
#include <ifaddrs.h>
#include <sys/param.h>
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
#include <sys/sysctl.h>
#endif
#include <net/if.h>
#include <net/route.h>
#include <net/if_dl.h>
+7
View File
@@ -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);
}
+10 -1
View File
@@ -434,7 +434,16 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
/* seed is largest extant lease addr in this context */
start = lease_find_max_addr6(c) + serial;
else
start = addr6part(&c->start6) + ((j + c->addr_epoch) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
{
u64 range = 1 + addr6part(&c->end6) - addr6part(&c->start6);
u64 offset = j + c->addr_epoch;
/* don't divide by zero if range is whole 2^64 */
if (range != 0)
offset = offset % range;
start = addr6part(&c->start6) + offset;
}
/* iterate until we find a free address. */
addr = start;
+8 -5
View File
@@ -237,7 +237,8 @@ struct event_desc {
#define OPT_TFTP_NO_FAIL 52
#define OPT_SCRIPT_ARP 53
#define OPT_MAC_B64 54
#define OPT_LAST 55
#define OPT_MAC_HEX 55
#define OPT_LAST 56
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
@@ -307,6 +308,7 @@ struct ptr_record {
};
struct cname {
int ttl;
char *alias, *target;
struct cname *next;
};
@@ -343,6 +345,7 @@ struct auth_zone {
struct host_record {
int ttl;
struct name_list {
char *name;
struct name_list *next;
@@ -637,7 +640,7 @@ struct frec {
#define ACTION_ADD 4
#define ACTION_TFTP 5
#define ACTION_ARP 6
#define ACTION_ARP_OLD 7
#define ACTION_ARP_DEL 7
#define LEASE_NEW 1 /* newly created */
#define LEASE_CHANGED 2 /* modified */
@@ -952,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;
@@ -972,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;
@@ -1520,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);
+58 -26
View File
@@ -96,7 +96,7 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
}
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 +120,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 +136,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;
islast = 0;
break;
}
if (code == optno)
return plen;
p += len;
{
if (!replace)
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 */
@@ -203,7 +226,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)
@@ -223,14 +246,19 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch
{
int maclen;
unsigned char mac[DHCP_CHADDR_MAX];
char encode[8]; /* handle 6 byte MACs */
char encode[18]; /* handle 6 byte MACs */
if ((maclen = find_mac(l3, mac, 1, now)) == 6)
{
encoder(mac, encode);
encoder(mac+3, encode+4);
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, 8, 0);
if (option_bool(OPT_MAC_HEX))
print_mac(encode, mac, maclen);
else
{
encoder(mac, encode);
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;
@@ -243,7 +271,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;
}
@@ -276,8 +304,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)
@@ -288,8 +319,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)
@@ -297,26 +329,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;
}
@@ -328,7 +360,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)
@@ -377,12 +409,12 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
if (option_bool(OPT_ADD_MAC))
plen = add_mac(header, plen, limit, source, now);
if (option_bool(OPT_MAC_B64))
if (option_bool(OPT_MAC_B64) || option_bool(OPT_MAC_HEX))
plen = add_dns_client(header, plen, limit, source, now);
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))
{
+4 -4
View File
@@ -221,12 +221,12 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
}
else if (data.action == ACTION_ARP)
{
action_str = "arp";
action_str = "arp-add";
is6 = (data.flags != AF_INET);
}
else if (data.action == ACTION_ARP_OLD)
else if (data.action == ACTION_ARP_DEL)
{
action_str = "arp-old";
action_str = "arp-del";
is6 = (data.flags != AF_INET);
data.action = ACTION_ARP;
}
@@ -300,7 +300,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if (!is6)
inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
#ifdef HAVE_DHCP6
#ifdef HAVE_IPV6
else
inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
#endif
+69 -19
View File
@@ -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]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), 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 }
};
@@ -1641,12 +1647,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 +1665,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;
@@ -2164,7 +2171,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
@@ -2172,6 +2179,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
unhide_metas(arg);
if (strcmp(arg, "base64") == 0)
set_option_bool(OPT_MAC_B64);
else if (strcmp(arg, "text") == 0)
set_option_bool(OPT_MAC_HEX);
else
ret_err(gen_err);
}
@@ -2578,6 +2587,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))
@@ -2596,6 +2606,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;
@@ -2614,6 +2629,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)
@@ -3690,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);
@@ -3711,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;
@@ -3911,14 +3935,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))
@@ -4599,7 +4631,25 @@ void read_opts(int argc, char **argv, char *compile_opts)
}
}
}
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;
+14 -5
View File
@@ -28,11 +28,12 @@
struct ra_param {
time_t now;
int ind, managed, other, found_context, first, adv_router;
int ind, managed, other, first, adv_router;
char *if_name;
struct dhcp_netid *tags;
struct in6_addr link_local, link_global, ula;
unsigned int glob_pref_time, link_pref_time, ula_pref_time, adv_interval, prio;
struct dhcp_context *found_context;
};
struct search_param {
@@ -251,7 +252,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
parm.ind = iface;
parm.managed = 0;
parm.other = 0;
parm.found_context = 0;
parm.found_context = NULL;
parm.adv_router = 0;
parm.if_name = iface_name;
parm.first = 1;
@@ -308,8 +309,14 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
unsigned int old = difftime(now, context->address_lost_time);
if (old > context->saved_valid)
{
{
/* We've advertised this enough, time to go */
/* If this context held the timeout, and there's another context in use
transfer the timeout there. */
if (context->ra_time != 0 && parm.found_context && parm.found_context->ra_time == 0)
new_timeout(parm.found_context, iface_name, now);
*up = context->next;
free(context);
}
@@ -636,8 +643,10 @@ static int add_prefixes(struct in6_addr *local, int prefix,
off_link = (context->flags & CONTEXT_RA_OFF_LINK);
}
param->first = 0;
param->found_context = 1;
param->first = 0;
/* found_context is the _last_ one we found, so if there's
more than one, it's not the first. */
param->found_context = context;
}
/* configured time is ceiling */
+16 -4
View File
@@ -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;
+12 -2
View File
@@ -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 */