mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
6
Commits
v2.82test1
...
v2.83test1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45903b7776 | ||
|
|
f60fea1fb0 | ||
|
|
4d85e409cd | ||
|
|
2bd02d2f59 | ||
|
|
7e194a0a7d | ||
|
|
9beb4d9ea2 |
No files matched your search
@@ -1,6 +1,33 @@
|
|||||||
|
version 2.83
|
||||||
|
Fix a remote buffer overflow problem in the DNSSEC code. Any
|
||||||
|
dnsmasq with DNSSEC compiled in and enabled is vulnerable to this,
|
||||||
|
referenced by CERT VU#434904.
|
||||||
|
|
||||||
|
|
||||||
|
version 2.82
|
||||||
|
Improve behaviour in the face of network interfaces which come
|
||||||
|
and go and change index. Thanks to Petr Mensik for the patch.
|
||||||
|
|
||||||
|
Convert hard startup failure on NETLINK_NO_ENOBUFS under qemu-user
|
||||||
|
to a warning.
|
||||||
|
|
||||||
|
Allow IPv6 addresses ofthe form [::ffff:1.2.3.4] in --dhcp-option.
|
||||||
|
|
||||||
|
Fix crash under heavy TCP connection load introduced in 2.81.
|
||||||
|
Thanks to Frank for good work chasing this down.
|
||||||
|
|
||||||
|
Change default lease time for DHCPv6 to one day.
|
||||||
|
|
||||||
|
Alter calculation of preferred and valid times in router
|
||||||
|
advertisements, so that these do not have a floor applied
|
||||||
|
of the lease time in the dhcp-range if this is not explicitly
|
||||||
|
specified and is merely the default.
|
||||||
|
Thanks to Martin-Éric Racine for suggestions on this.
|
||||||
|
|
||||||
|
|
||||||
version 2.81
|
version 2.81
|
||||||
Improve cache behaviour for TCP connections. For ease of
|
Improve cache behaviour for TCP connections. For ease of
|
||||||
implementaion, dnsmasq has always forked a new process to handle
|
implementation, dnsmasq has always forked a new process to handle
|
||||||
each incoming TCP connection. A side-effect of this is that
|
each incoming TCP connection. A side-effect of this is that
|
||||||
any DNS queries answered from TCP connections are not cached:
|
any DNS queries answered from TCP connections are not cached:
|
||||||
when TCP connections were rare, this was not a problem.
|
when TCP connections were rare, this was not a problem.
|
||||||
|
|||||||
+2
-2
@@ -428,7 +428,7 @@ Tells dnsmasq to never forward A or AAAA queries for plain names, without dots
|
|||||||
or domain parts, to upstream nameservers. If the name is not known
|
or domain parts, to upstream nameservers. If the name is not known
|
||||||
from /etc/hosts or DHCP then a "not found" answer is returned.
|
from /etc/hosts or DHCP then a "not found" answer is returned.
|
||||||
.TP
|
.TP
|
||||||
.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
|
.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>]][@<source-ip>|<interface>[#<port>]]
|
||||||
Specify IP address of upstream servers directly. Setting this flag does
|
Specify IP address of upstream servers directly. Setting this flag does
|
||||||
not suppress reading of /etc/resolv.conf, use \fB--no-resolv\fP to do that. If one or more
|
not suppress reading of /etc/resolv.conf, use \fB--no-resolv\fP to do that. If one or more
|
||||||
optional domains are given, that server is used only for those domains
|
optional domains are given, that server is used only for those domains
|
||||||
@@ -861,7 +861,7 @@ in
|
|||||||
options. If the lease time is given, then leases
|
options. If the lease time is given, then leases
|
||||||
will be given for that length of time. The lease time is in seconds,
|
will be given for that length of time. The lease time is in seconds,
|
||||||
or minutes (eg 45m) or hours (eg 1h) or "infinite". If not given,
|
or minutes (eg 45m) or hours (eg 1h) or "infinite". If not given,
|
||||||
the default lease time is one hour. The
|
the default lease time is one hour for IPv4 and one day for IPv6. The
|
||||||
minimum lease time is two minutes. For IPv6 ranges, the lease time
|
minimum lease time is two minutes. For IPv6 ranges, the lease time
|
||||||
maybe "deprecated"; this sets the preferred lifetime sent in a DHCP
|
maybe "deprecated"; this sets the preferred lifetime sent in a DHCP
|
||||||
lease or router advertisement to zero, which causes clients to use
|
lease or router advertisement to zero, which causes clients to use
|
||||||
|
|||||||
+16
-3
@@ -472,11 +472,24 @@ void cache_start_insert(void)
|
|||||||
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
|
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
|
||||||
time_t now, unsigned long ttl, unsigned int flags)
|
time_t now, unsigned long ttl, unsigned int flags)
|
||||||
{
|
{
|
||||||
/* Don't log DNSSEC records here, done elsewhere */
|
#ifdef HAVE_DNSSEC
|
||||||
if (flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV))
|
if (flags & (F_DNSKEY | F_DS))
|
||||||
{
|
{
|
||||||
|
/* The DNSSEC validation process works by getting needed records into the
|
||||||
|
cache, then retrying the validation until they are all in place.
|
||||||
|
This can be messed up by very short TTLs, and _really_ messed up by
|
||||||
|
zero TTLs, so we force the TTL to be at least long enough to do a validation.
|
||||||
|
Ideally, we should use some kind of reference counting so that records are
|
||||||
|
locked until the validation that asked for them is complete, but this
|
||||||
|
is much easier, and just as effective. */
|
||||||
|
if (ttl < DNSSEC_MIN_TTL)
|
||||||
|
ttl = DNSSEC_MIN_TTL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Don't log DNSSEC records here, done elsewhere */
|
||||||
log_query(flags | F_UPSTREAM, name, addr, NULL);
|
log_query(flags | F_UPSTREAM, name, addr, NULL);
|
||||||
/* Don't mess with TTL for DNSSEC records. */
|
|
||||||
if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
|
if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
|
||||||
ttl = daemon->max_cache_ttl;
|
ttl = daemon->max_cache_ttl;
|
||||||
if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
|
if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
|
||||||
|
|||||||
+3
-1
@@ -40,9 +40,11 @@
|
|||||||
#define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
|
#define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
|
||||||
#define SMALLDNAME 50 /* most domain names are smaller than this */
|
#define SMALLDNAME 50 /* most domain names are smaller than this */
|
||||||
#define CNAME_CHAIN 10 /* chains longer than this atr dropped for loop protection */
|
#define CNAME_CHAIN 10 /* chains longer than this atr dropped for loop protection */
|
||||||
|
#define DNSSEC_MIN_TTL 60 /* DNSKEY and DS records in cache last at least this long */
|
||||||
#define HOSTSFILE "/etc/hosts"
|
#define HOSTSFILE "/etc/hosts"
|
||||||
#define ETHERSFILE "/etc/ethers"
|
#define ETHERSFILE "/etc/ethers"
|
||||||
#define DEFLEASE 3600 /* default lease time, 1 hour */
|
#define DEFLEASE 3600 /* default DHCPv4 lease time, one hour */
|
||||||
|
#define DEFLEASE6 (3600*24) /* default lease time for DHCPv6. One day. */
|
||||||
#define CHUSER "nobody"
|
#define CHUSER "nobody"
|
||||||
#define CHGRP "dip"
|
#define CHGRP "dip"
|
||||||
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
||||||
|
|||||||
@@ -942,6 +942,7 @@ struct shared_network {
|
|||||||
#define CONTEXT_OLD (1u<<16)
|
#define CONTEXT_OLD (1u<<16)
|
||||||
#define CONTEXT_V6 (1u<<17)
|
#define CONTEXT_V6 (1u<<17)
|
||||||
#define CONTEXT_RA_OFF_LINK (1u<<18)
|
#define CONTEXT_RA_OFF_LINK (1u<<18)
|
||||||
|
#define CONTEXT_SETLEASE (1u<<19)
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|||||||
+147
-116
@@ -223,138 +223,147 @@ static int check_date_range(unsigned long curtime, u32 date_start, u32 date_end)
|
|||||||
&& serial_compare_32(curtime, date_end) == SERIAL_LT;
|
&& serial_compare_32(curtime, date_end) == SERIAL_LT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
|
/* Return bytes of canonicalised rrdata one by one.
|
||||||
data, pointed to by *p, should be used raw. */
|
Init state->ip with the RR, and state->end with the end of same.
|
||||||
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
|
Init state->op to NULL.
|
||||||
unsigned char **p, u16 **desc)
|
Init state->desc to RR descriptor.
|
||||||
|
Init state->buff with a MAXDNAME * 2 buffer.
|
||||||
|
|
||||||
|
After each call which returns 1, state->op points to the next byte of data.
|
||||||
|
On returning 0, the end has been reached.
|
||||||
|
*/
|
||||||
|
struct rdata_state {
|
||||||
|
u16 *desc;
|
||||||
|
size_t c;
|
||||||
|
unsigned char *end, *ip, *op;
|
||||||
|
char *buff;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_rdata(struct dns_header *header, size_t plen, struct rdata_state *state)
|
||||||
{
|
{
|
||||||
int d = **desc;
|
int d;
|
||||||
|
|
||||||
/* No more data needs mangling */
|
if (state->op && state->c != 1)
|
||||||
if (d == (u16)-1)
|
|
||||||
{
|
{
|
||||||
/* If there's more data than we have space for, just return what fits,
|
state->op++;
|
||||||
we'll get called again for more chunks */
|
state->c--;
|
||||||
if (end - *p > bufflen)
|
return 1;
|
||||||
{
|
|
||||||
memcpy(buff, *p, bufflen);
|
|
||||||
*p += bufflen;
|
|
||||||
return bufflen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*desc)++;
|
while (1)
|
||||||
|
|
||||||
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
|
|
||||||
/* domain-name, canonicalise */
|
|
||||||
return to_wire(buff);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* plain data preceding a domain-name, don't run off the end of the data */
|
d = *(state->desc);
|
||||||
if ((end - *p) < d)
|
|
||||||
d = end - *p;
|
|
||||||
|
|
||||||
if (d != 0)
|
if (d == (u16)-1)
|
||||||
{
|
{
|
||||||
memcpy(buff, *p, d);
|
/* all the bytes to the end. */
|
||||||
*p += d;
|
if ((state->c = state->end - state->ip) != 0)
|
||||||
|
{
|
||||||
|
state->op = state->ip;
|
||||||
|
state->ip = state->end;;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->desc++;
|
||||||
|
|
||||||
|
if (d == (u16)0)
|
||||||
|
{
|
||||||
|
/* domain-name, canonicalise */
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!extract_name(header, plen, &state->ip, state->buff, 1, 0) ||
|
||||||
|
(len = to_wire(state->buff)) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
state->c = len;
|
||||||
|
state->op = (unsigned char *)state->buff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* plain data preceding a domain-name, don't run off the end of the data */
|
||||||
|
if ((state->end - state->ip) < d)
|
||||||
|
d = state->end - state->ip;
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
state->op = state->ip;
|
||||||
|
state->c = d;
|
||||||
|
state->ip += d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return d;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bubble sort the RRset into the canonical order.
|
/* Bubble sort the RRset into the canonical order. */
|
||||||
Note that the byte-streams from two RRs may get unsynced: consider
|
|
||||||
RRs which have two domain-names at the start and then other data.
|
|
||||||
The domain-names may have different lengths in each RR, but sort equal
|
|
||||||
|
|
||||||
------------
|
|
||||||
|abcde|fghi|
|
|
||||||
------------
|
|
||||||
|abcd|efghi|
|
|
||||||
------------
|
|
||||||
|
|
||||||
leaving the following bytes as deciding the order. Hence the nasty left1 and left2 variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx,
|
static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx,
|
||||||
unsigned char **rrset, char *buff1, char *buff2)
|
unsigned char **rrset, char *buff1, char *buff2)
|
||||||
{
|
{
|
||||||
int swap, quit, i, j;
|
int swap, i, j;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for (swap = 0, i = 0; i < rrsetidx-1; i++)
|
for (swap = 0, i = 0; i < rrsetidx-1; i++)
|
||||||
{
|
{
|
||||||
int rdlen1, rdlen2, left1, left2, len1, len2, len, rc;
|
int rdlen1, rdlen2;
|
||||||
u16 *dp1, *dp2;
|
struct rdata_state state1, state2;
|
||||||
unsigned char *end1, *end2;
|
|
||||||
/* Note that these have been determined to be OK previously,
|
/* Note that these have been determined to be OK previously,
|
||||||
so we don't need to check for NULL return here. */
|
so we don't need to check for NULL return here. */
|
||||||
unsigned char *p1 = skip_name(rrset[i], header, plen, 10);
|
state1.ip = skip_name(rrset[i], header, plen, 10);
|
||||||
unsigned char *p2 = skip_name(rrset[i+1], header, plen, 10);
|
state2.ip = skip_name(rrset[i+1], header, plen, 10);
|
||||||
|
state1.op = state2.op = NULL;
|
||||||
|
state1.buff = buff1;
|
||||||
|
state2.buff = buff2;
|
||||||
|
state1.desc = state2.desc = rr_desc;
|
||||||
|
|
||||||
p1 += 8; /* skip class, type, ttl */
|
state1.ip += 8; /* skip class, type, ttl */
|
||||||
GETSHORT(rdlen1, p1);
|
GETSHORT(rdlen1, state1.ip);
|
||||||
end1 = p1 + rdlen1;
|
if (!CHECK_LEN(header, state1.ip, plen, rdlen1))
|
||||||
|
return rrsetidx; /* short packet */
|
||||||
|
state1.end = state1.ip + rdlen1;
|
||||||
|
|
||||||
p2 += 8; /* skip class, type, ttl */
|
state2.ip += 8; /* skip class, type, ttl */
|
||||||
GETSHORT(rdlen2, p2);
|
GETSHORT(rdlen2, state2.ip);
|
||||||
end2 = p2 + rdlen2;
|
if (!CHECK_LEN(header, state2.ip, plen, rdlen2))
|
||||||
|
return rrsetidx; /* short packet */
|
||||||
|
state2.end = state2.ip + rdlen2;
|
||||||
|
|
||||||
dp1 = dp2 = rr_desc;
|
while (1)
|
||||||
|
|
||||||
for (quit = 0, left1 = 0, left2 = 0, len1 = 0, len2 = 0; !quit;)
|
|
||||||
{
|
{
|
||||||
if (left1 != 0)
|
int ok1, ok2;
|
||||||
memmove(buff1, buff1 + len1 - left1, left1);
|
|
||||||
|
|
||||||
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, (MAXDNAME * 2) - left1, &p1, &dp1)) == 0)
|
ok1 = get_rdata(header, plen, &state1);
|
||||||
{
|
ok2 = get_rdata(header, plen, &state2);
|
||||||
quit = 1;
|
|
||||||
len1 = end1 - p1;
|
|
||||||
memcpy(buff1 + left1, p1, len1);
|
|
||||||
}
|
|
||||||
len1 += left1;
|
|
||||||
|
|
||||||
if (left2 != 0)
|
if (!ok1 && !ok2)
|
||||||
memmove(buff2, buff2 + len2 - left2, left2);
|
|
||||||
|
|
||||||
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, (MAXDNAME *2) - left2, &p2, &dp2)) == 0)
|
|
||||||
{
|
|
||||||
quit = 1;
|
|
||||||
len2 = end2 - p2;
|
|
||||||
memcpy(buff2 + left2, p2, len2);
|
|
||||||
}
|
|
||||||
len2 += left2;
|
|
||||||
|
|
||||||
if (len1 > len2)
|
|
||||||
left1 = len1 - len2, left2 = 0, len = len2;
|
|
||||||
else
|
|
||||||
left2 = len2 - len1, left1 = 0, len = len1;
|
|
||||||
|
|
||||||
rc = (len == 0) ? 0 : memcmp(buff1, buff2, len);
|
|
||||||
|
|
||||||
if (rc > 0 || (rc == 0 && quit && len1 > len2))
|
|
||||||
{
|
|
||||||
unsigned char *tmp = rrset[i+1];
|
|
||||||
rrset[i+1] = rrset[i];
|
|
||||||
rrset[i] = tmp;
|
|
||||||
swap = quit = 1;
|
|
||||||
}
|
|
||||||
else if (rc == 0 && quit && len1 == len2)
|
|
||||||
{
|
{
|
||||||
/* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
|
/* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
|
||||||
for (j = i+1; j < rrsetidx-1; j++)
|
for (j = i+1; j < rrsetidx-1; j++)
|
||||||
rrset[j] = rrset[j+1];
|
rrset[j] = rrset[j+1];
|
||||||
rrsetidx--;
|
rrsetidx--;
|
||||||
i--;
|
i--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (rc < 0)
|
else if (ok1 && (!ok2 || *state1.op > *state2.op))
|
||||||
quit = 1;
|
{
|
||||||
|
unsigned char *tmp = rrset[i+1];
|
||||||
|
rrset[i+1] = rrset[i];
|
||||||
|
rrset[i] = tmp;
|
||||||
|
swap = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ok2 && (!ok1 || *state2.op > *state1.op))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* arrive here when bytes are equal, go round the loop again
|
||||||
|
and compare the next ones. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (swap);
|
} while (swap);
|
||||||
@@ -570,11 +579,14 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
|
hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
|
||||||
from_wire(keyname);
|
from_wire(keyname);
|
||||||
|
|
||||||
|
#define RRBUFLEN 300 /* Most RRs are smaller than this. */
|
||||||
|
|
||||||
for (i = 0; i < rrsetidx; ++i)
|
for (i = 0; i < rrsetidx; ++i)
|
||||||
{
|
{
|
||||||
int seg;
|
int j;
|
||||||
unsigned char *end, *cp;
|
struct rdata_state state;
|
||||||
u16 len, *dp;
|
u16 len;
|
||||||
|
unsigned char rrbuf[RRBUFLEN];
|
||||||
|
|
||||||
p = rrset[i];
|
p = rrset[i];
|
||||||
|
|
||||||
@@ -586,12 +598,11 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
/* if more labels than in RRsig name, hash *.<no labels in rrsig labels field> 4035 5.3.2 */
|
/* if more labels than in RRsig name, hash *.<no labels in rrsig labels field> 4035 5.3.2 */
|
||||||
if (labels < name_labels)
|
if (labels < name_labels)
|
||||||
{
|
{
|
||||||
int k;
|
for (j = name_labels - labels; j != 0; j--)
|
||||||
for (k = name_labels - labels; k != 0; k--)
|
|
||||||
{
|
{
|
||||||
while (*name_start != '.' && *name_start != 0)
|
while (*name_start != '.' && *name_start != 0)
|
||||||
name_start++;
|
name_start++;
|
||||||
if (k != 1 && *name_start == '.')
|
if (j != 1 && *name_start == '.')
|
||||||
name_start++;
|
name_start++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,24 +623,44 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
end = p + rdlen;
|
/* canonicalise rdata and calculate length of same, use
|
||||||
|
name buffer as workspace for get_rdata. */
|
||||||
|
state.ip = p;
|
||||||
|
state.op = NULL;
|
||||||
|
state.desc = rr_desc;
|
||||||
|
state.buff = name;
|
||||||
|
state.end = p + rdlen;
|
||||||
|
|
||||||
/* canonicalise rdata and calculate length of same, use name buffer as workspace.
|
for (j = 0; get_rdata(header, plen, &state); j++)
|
||||||
Note that name buffer is twice MAXDNAME long in DNSSEC mode. */
|
if (j < RRBUFLEN)
|
||||||
cp = p;
|
rrbuf[j] = *state.op;
|
||||||
dp = rr_desc;
|
|
||||||
for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)) != 0; len += seg);
|
len = htons((u16)j);
|
||||||
len += end - cp;
|
|
||||||
len = htons(len);
|
|
||||||
hash->update(ctx, 2, (unsigned char *)&len);
|
hash->update(ctx, 2, (unsigned char *)&len);
|
||||||
|
|
||||||
/* Now canonicalise again and digest. */
|
/* If the RR is shorter than RRBUFLEN (most of them, in practice)
|
||||||
cp = p;
|
then we can just digest it now. If it exceeds RRBUFLEN we have to
|
||||||
dp = rr_desc;
|
go back to the start and do it in chunks. */
|
||||||
while ((seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)))
|
if (j >= RRBUFLEN)
|
||||||
hash->update(ctx, seg, (unsigned char *)name);
|
{
|
||||||
if (cp != end)
|
state.ip = p;
|
||||||
hash->update(ctx, end - cp, cp);
|
state.op = NULL;
|
||||||
|
state.desc = rr_desc;
|
||||||
|
|
||||||
|
for (j = 0; get_rdata(header, plen, &state); j++)
|
||||||
|
{
|
||||||
|
rrbuf[j] = *state.op;
|
||||||
|
|
||||||
|
if (j == RRBUFLEN - 1)
|
||||||
|
{
|
||||||
|
hash->update(ctx, RRBUFLEN, rrbuf);
|
||||||
|
j = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j != 0)
|
||||||
|
hash->update(ctx, j, rrbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash->digest(ctx, hash->digest_size, digest);
|
hash->digest(ctx, hash->digest_size, digest);
|
||||||
|
|||||||
+8
-2
@@ -2991,7 +2991,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
|
struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
|
||||||
|
|
||||||
memset (new, 0, sizeof(*new));
|
memset (new, 0, sizeof(*new));
|
||||||
new->lease_time = DEFLEASE;
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
@@ -3041,6 +3040,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
if (inet_pton(AF_INET, a[0], &new->start))
|
if (inet_pton(AF_INET, a[0], &new->start))
|
||||||
{
|
{
|
||||||
new->next = daemon->dhcp;
|
new->next = daemon->dhcp;
|
||||||
|
new->lease_time = DEFLEASE;
|
||||||
daemon->dhcp = new;
|
daemon->dhcp = new;
|
||||||
new->end = new->start;
|
new->end = new->start;
|
||||||
if (strcmp(a[1], "static") == 0)
|
if (strcmp(a[1], "static") == 0)
|
||||||
@@ -3088,6 +3088,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new->flags |= CONTEXT_V6;
|
new->flags |= CONTEXT_V6;
|
||||||
new->prefix = 64; /* default */
|
new->prefix = 64; /* default */
|
||||||
new->end6 = new->start6;
|
new->end6 = new->start6;
|
||||||
|
new->lease_time = DEFLEASE6;
|
||||||
new->next = daemon->dhcp6;
|
new->next = daemon->dhcp6;
|
||||||
daemon->dhcp6 = new;
|
daemon->dhcp6 = new;
|
||||||
|
|
||||||
@@ -3187,7 +3188,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(a[leasepos], "infinite") == 0)
|
if (strcmp(a[leasepos], "infinite") == 0)
|
||||||
new->lease_time = 0xffffffff;
|
{
|
||||||
|
new->lease_time = 0xffffffff;
|
||||||
|
new->flags |= CONTEXT_SETLEASE;
|
||||||
|
}
|
||||||
else if (strcmp(a[leasepos], "deprecated") == 0)
|
else if (strcmp(a[leasepos], "deprecated") == 0)
|
||||||
new->flags |= CONTEXT_DEPRECATE;
|
new->flags |= CONTEXT_DEPRECATE;
|
||||||
else
|
else
|
||||||
@@ -3226,6 +3230,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
ret_err_free(_("bad dhcp-range"), new);
|
ret_err_free(_("bad dhcp-range"), new);
|
||||||
|
|
||||||
new->lease_time = atoi(a[leasepos]) * fac;
|
new->lease_time = atoi(a[leasepos]) * fac;
|
||||||
|
new->flags |= CONTEXT_SETLEASE;
|
||||||
/* Leases of a minute or less confuse
|
/* Leases of a minute or less confuse
|
||||||
some clients, notably Apple's */
|
some clients, notably Apple's */
|
||||||
if (new->lease_time < 120)
|
if (new->lease_time < 120)
|
||||||
@@ -3233,6 +3238,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -626,8 +626,11 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
real_prefix = context->prefix;
|
real_prefix = context->prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find floor time, don't reduce below 3 * RA interval. */
|
/* find floor time, don't reduce below 3 * RA interval.
|
||||||
if (time > context->lease_time)
|
If the lease time has been left as default, don't
|
||||||
|
use that as a floor. */
|
||||||
|
if ((context->flags & CONTEXT_SETLEASE) &&
|
||||||
|
time > context->lease_time)
|
||||||
{
|
{
|
||||||
time = context->lease_time;
|
time = context->lease_time;
|
||||||
if (time < ((unsigned int)(3 * param->adv_interval)))
|
if (time < ((unsigned int)(3 * param->adv_interval)))
|
||||||
|
|||||||
Reference in new issue
Block a user