mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef1a94abaa | ||
|
|
d9fb0be8c7 | ||
|
|
3f3adae6bc | ||
|
|
1ecbaaa382 | ||
|
|
d859ca2f9b | ||
|
|
b4b9308079 |
No files matched your search
@@ -56,7 +56,30 @@ version 2.67
|
|||||||
we can't use SO_BINDTODEVICE. Thanks to Natrio for the bug
|
we can't use SO_BINDTODEVICE. Thanks to Natrio for the bug
|
||||||
report.
|
report.
|
||||||
|
|
||||||
|
Increase timeout/number of retries in TFTP to accomodate
|
||||||
|
AudioCodes Voice Gateways doing streaming writes to flash.
|
||||||
|
Thanks to Damian Kaczkowski for spotting the problem.
|
||||||
|
|
||||||
|
Allow hostnames to start with a number, as allowed in
|
||||||
|
RFC-1123. Thanks to Kyle Mestery for the patch.
|
||||||
|
|
||||||
|
Fixes to DHCP FQDN option handling: don't terminate FQDN
|
||||||
|
if domain not known and allow a FQDN option with blank
|
||||||
|
name to request that a FQDN option is returned in the
|
||||||
|
reply. Thanks to Roy Marples for the patch.
|
||||||
|
|
||||||
|
Make --clear-on-reload apply to setting upstream servers
|
||||||
|
via DBus too.
|
||||||
|
|
||||||
|
When the address which triggered the construction of an
|
||||||
|
advertised IPv6 prefix disappears, continue to advertise
|
||||||
|
the prefix for up to 2 hours, with the preferred lifetime
|
||||||
|
set to zero. This satisfies RFC 6204 4.3 L-13 and makes
|
||||||
|
things work better if a prefix disappears without being
|
||||||
|
deprecated first. Thanks to Uwe Schindler for persuasively
|
||||||
|
arguing for this.
|
||||||
|
|
||||||
|
|
||||||
version 2.66
|
version 2.66
|
||||||
Add the ability to act as an authoritative DNS
|
Add the ability to act as an authoritative DNS
|
||||||
server. Dnsmasq can now answer queries from the wider 'net
|
server. Dnsmasq can now answer queries from the wider 'net
|
||||||
|
|||||||
+2
-1
@@ -338,7 +338,8 @@ by '/', like the --server syntax, eg.
|
|||||||
Don't poll /etc/resolv.conf for changes.
|
Don't poll /etc/resolv.conf for changes.
|
||||||
.TP
|
.TP
|
||||||
.B --clear-on-reload
|
.B --clear-on-reload
|
||||||
Whenever /etc/resolv.conf is re-read, clear the DNS cache.
|
Whenever /etc/resolv.conf is re-read or the upstream servers are set
|
||||||
|
via DBus, clear the DNS cache.
|
||||||
This is useful when new nameservers may have different
|
This is useful when new nameservers may have different
|
||||||
data than that held in cache.
|
data than that held in cache.
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
+16
-7
@@ -305,8 +305,6 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
|||||||
const char *addr_err;
|
const char *addr_err;
|
||||||
char *dup = NULL;
|
char *dup = NULL;
|
||||||
|
|
||||||
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
|
||||||
|
|
||||||
if (!dbus_message_iter_init(message, &iter))
|
if (!dbus_message_iter_init(message, &iter))
|
||||||
{
|
{
|
||||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||||
@@ -478,6 +476,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
|||||||
{
|
{
|
||||||
char *method = (char *)dbus_message_get_member(message);
|
char *method = (char *)dbus_message_get_member(message);
|
||||||
DBusMessage *reply = NULL;
|
DBusMessage *reply = NULL;
|
||||||
|
int clear_cache = 0, new_servers = 0;
|
||||||
|
|
||||||
if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
|
if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
|
||||||
{
|
{
|
||||||
@@ -501,24 +500,34 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
|||||||
}
|
}
|
||||||
else if (strcmp(method, "SetServers") == 0)
|
else if (strcmp(method, "SetServers") == 0)
|
||||||
{
|
{
|
||||||
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
|
||||||
dbus_read_servers(message);
|
dbus_read_servers(message);
|
||||||
check_servers();
|
new_servers = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(method, "SetServersEx") == 0)
|
else if (strcmp(method, "SetServersEx") == 0)
|
||||||
{
|
{
|
||||||
reply = dbus_read_servers_ex(message, 0);
|
reply = dbus_read_servers_ex(message, 0);
|
||||||
check_servers();
|
new_servers = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(method, "SetDomainServers") == 0)
|
else if (strcmp(method, "SetDomainServers") == 0)
|
||||||
{
|
{
|
||||||
reply = dbus_read_servers_ex(message, 1);
|
reply = dbus_read_servers_ex(message, 1);
|
||||||
check_servers();
|
new_servers = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(method, "ClearCache") == 0)
|
else if (strcmp(method, "ClearCache") == 0)
|
||||||
clear_cache_and_reload(dnsmasq_time());
|
clear_cache = 1;
|
||||||
else
|
else
|
||||||
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||||
|
|
||||||
|
if (new_servers)
|
||||||
|
{
|
||||||
|
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
||||||
|
check_servers();
|
||||||
|
if (option_bool(OPT_RELOAD))
|
||||||
|
clear_cache = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clear_cache)
|
||||||
|
clear_cache_and_reload(dnsmasq_time());
|
||||||
|
|
||||||
method = user_data; /* no warning */
|
method = user_data; /* no warning */
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -720,7 +720,7 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
p += sprintf(p, ", ");
|
p += sprintf(p, ", ");
|
||||||
|
|
||||||
if (indextoname(daemon->doing_dhcp6 ? daemon->dhcp6fd : daemon->icmp6fd, context->if_index, ifrn_name))
|
if (indextoname(daemon->doing_dhcp6 ? daemon->dhcp6fd : daemon->icmp6fd, context->if_index, ifrn_name))
|
||||||
sprintf(p, "constructed for %s", ifrn_name);
|
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
|
||||||
}
|
}
|
||||||
else if (context->flags & CONTEXT_TEMPLATE)
|
else if (context->flags & CONTEXT_TEMPLATE)
|
||||||
{
|
{
|
||||||
@@ -731,7 +731,8 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((context->flags & CONTEXT_DHCP) || family == AF_INET)
|
if (!(context->flags & CONTEXT_OLD) &&
|
||||||
|
((context->flags & CONTEXT_DHCP) || family == AF_INET))
|
||||||
{
|
{
|
||||||
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
||||||
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
||||||
@@ -748,9 +749,9 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (context->flags & CONTEXT_RA_NAME)
|
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s%s"), daemon->addrbuff, template);
|
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s%s"), daemon->addrbuff, template);
|
||||||
|
|
||||||
if ((context->flags & CONTEXT_RA) || (option_bool(OPT_RA) && (context->flags & CONTEXT_DHCP) && family == AF_INET6))
|
if ((context->flags & CONTEXT_RA) || (option_bool(OPT_RA) && (context->flags & CONTEXT_DHCP) && family == AF_INET6))
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("router advertisement on %s%s"), daemon->addrbuff, template);
|
my_syslog(MS_DHCP | LOG_INFO, _("router advertisement on %s%s"), daemon->addrbuff, template);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+39
-17
@@ -220,7 +220,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
|||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
{
|
{
|
||||||
if ((context->flags & CONTEXT_DHCP) &&
|
if ((context->flags & CONTEXT_DHCP) &&
|
||||||
!(context->flags & CONTEXT_TEMPLATE) &&
|
!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
|
||||||
prefix == context->prefix &&
|
prefix == context->prefix &&
|
||||||
is_same_net6(local, &context->start6, prefix) &&
|
is_same_net6(local, &context->start6, prefix) &&
|
||||||
is_same_net6(local, &context->end6, prefix))
|
is_same_net6(local, &context->end6, prefix))
|
||||||
@@ -552,7 +552,10 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
|
IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
|
||||||
IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
|
IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
|
||||||
{
|
{
|
||||||
context->flags &= ~CONTEXT_GC;
|
int flags = context->flags;
|
||||||
|
context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
|
||||||
|
if (flags & CONTEXT_OLD)
|
||||||
|
log_context(AF_INET6, context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,6 +568,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
context->flags |= CONTEXT_CONSTRUCTED;
|
context->flags |= CONTEXT_CONSTRUCTED;
|
||||||
context->if_index = if_index;
|
context->if_index = if_index;
|
||||||
context->local6 = *local;
|
context->local6 = *local;
|
||||||
|
context->saved_valid = 0;
|
||||||
|
|
||||||
context->next = daemon->dhcp6;
|
context->next = daemon->dhcp6;
|
||||||
daemon->dhcp6 = context;
|
daemon->dhcp6 = context;
|
||||||
@@ -587,35 +591,53 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
|
|
||||||
void dhcp_construct_contexts(time_t now)
|
void dhcp_construct_contexts(time_t now)
|
||||||
{
|
{
|
||||||
struct dhcp_context *tmp, *context, **up;
|
struct dhcp_context *context, *tmp, **up;
|
||||||
struct cparam param;
|
struct cparam param;
|
||||||
param.newone = 0;
|
param.newone = 0;
|
||||||
param.newname = 0;
|
param.newname = 0;
|
||||||
param.now = now;
|
param.now = now;
|
||||||
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
{
|
if (context->flags & CONTEXT_CONSTRUCTED)
|
||||||
context->if_index = 0;
|
context->flags |= CONTEXT_GC;
|
||||||
if (context->flags & CONTEXT_CONSTRUCTED)
|
|
||||||
context->flags |= CONTEXT_GC;
|
|
||||||
}
|
|
||||||
|
|
||||||
iface_enumerate(AF_INET6, ¶m, construct_worker);
|
iface_enumerate(AF_INET6, ¶m, construct_worker);
|
||||||
|
|
||||||
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
|
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
|
||||||
{
|
{
|
||||||
tmp = context->next;
|
|
||||||
|
|
||||||
if (context->flags & CONTEXT_GC)
|
tmp = context->next;
|
||||||
|
|
||||||
|
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
|
||||||
{
|
{
|
||||||
*up = context->next;
|
|
||||||
param.newone = 1; /* include deletion */
|
if ((context->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) ||
|
||||||
if (context->flags & CONTEXT_RA_NAME)
|
option_bool(OPT_RA))
|
||||||
param.newname = 1;
|
{
|
||||||
free(context);
|
/* previously constructed context has gone. advertise it's demise */
|
||||||
|
context->flags |= CONTEXT_OLD;
|
||||||
|
context->address_lost_time = now;
|
||||||
|
if (context->saved_valid > 7200) /* 2 hours */
|
||||||
|
context->saved_valid = 7200;
|
||||||
|
ra_start_unsolicted(now, context);
|
||||||
|
param.newone = 1; /* include deletion */
|
||||||
|
|
||||||
|
if (context->flags & CONTEXT_RA_NAME)
|
||||||
|
param.newname = 1;
|
||||||
|
|
||||||
|
log_context(AF_INET6, context);
|
||||||
|
|
||||||
|
up = &context->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we were never doing RA for this, so free now */
|
||||||
|
*up = context->next;
|
||||||
|
free(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
up = &context->next;
|
up = &context->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.newone)
|
if (param.newone)
|
||||||
|
|||||||
+4
-2
@@ -706,8 +706,8 @@ struct dhcp_context {
|
|||||||
struct in6_addr start6, end6; /* range of available addresses */
|
struct in6_addr start6, end6; /* range of available addresses */
|
||||||
struct in6_addr local6;
|
struct in6_addr local6;
|
||||||
int prefix, if_index;
|
int prefix, if_index;
|
||||||
unsigned int valid, preferred;
|
unsigned int valid, preferred, saved_valid;
|
||||||
time_t ra_time, ra_short_period_start;
|
time_t ra_time, ra_short_period_start, address_lost_time;
|
||||||
char *template_interface;
|
char *template_interface;
|
||||||
#endif
|
#endif
|
||||||
int flags;
|
int flags;
|
||||||
@@ -732,6 +732,8 @@ struct dhcp_context {
|
|||||||
#define CONTEXT_CONF_USED 16384
|
#define CONTEXT_CONF_USED 16384
|
||||||
#define CONTEXT_USED 32768
|
#define CONTEXT_USED 32768
|
||||||
#define CONTEXT_NOAUTH 65536
|
#define CONTEXT_NOAUTH 65536
|
||||||
|
#define CONTEXT_OLD 131072
|
||||||
|
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|||||||
+97
-27
@@ -47,6 +47,7 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
int scope, int if_index, int flags,
|
int scope, int if_index, int flags,
|
||||||
int prefered, int valid, void *vparam);
|
int prefered, int valid, void *vparam);
|
||||||
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||||
|
static void new_timeout(struct dhcp_context *context, time_t now);
|
||||||
|
|
||||||
static int hop_limit;
|
static int hop_limit;
|
||||||
|
|
||||||
@@ -187,9 +188,8 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
{
|
{
|
||||||
struct ra_packet *ra;
|
struct ra_packet *ra;
|
||||||
struct ra_param parm;
|
struct ra_param parm;
|
||||||
struct ifreq ifr;
|
|
||||||
struct sockaddr_in6 addr;
|
struct sockaddr_in6 addr;
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context, *tmp, **up;
|
||||||
struct dhcp_netid iface_id;
|
struct dhcp_netid iface_id;
|
||||||
struct dhcp_opt *opt_cfg;
|
struct dhcp_opt *opt_cfg;
|
||||||
int done_dns = 0;
|
int done_dns = 0;
|
||||||
@@ -228,12 +228,66 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
context->netid.next = &context->netid;
|
context->netid.next = &context->netid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
|
if (!iface_enumerate(AF_INET6, &parm, add_prefixes))
|
||||||
!parm.found_context)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, iface_name, IF_NAMESIZE);
|
/* Look for constructed contexts associated with addresses which have gone,
|
||||||
|
and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
|
||||||
|
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
|
||||||
|
{
|
||||||
|
tmp = context->next;
|
||||||
|
|
||||||
|
if (context->if_index == iface && (context->flags & CONTEXT_OLD))
|
||||||
|
{
|
||||||
|
unsigned int old = difftime(now, context->address_lost_time);
|
||||||
|
|
||||||
|
if (old > context->saved_valid)
|
||||||
|
{
|
||||||
|
/* We've advertised this enough, time to go */
|
||||||
|
*up = context->next;
|
||||||
|
free(context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct prefix_opt *opt;
|
||||||
|
struct in6_addr local = context->start6;
|
||||||
|
int do_slaac = 0;
|
||||||
|
|
||||||
|
parm.found_context = 1;
|
||||||
|
|
||||||
|
/* zero net part of address */
|
||||||
|
setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU));
|
||||||
|
|
||||||
|
if ((context->flags &
|
||||||
|
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
||||||
|
do_slaac = 1;
|
||||||
|
|
||||||
|
if ((opt = expand(sizeof(struct prefix_opt))))
|
||||||
|
{
|
||||||
|
opt->type = ICMP6_OPT_PREFIX;
|
||||||
|
opt->len = 4;
|
||||||
|
opt->prefix_len = context->prefix;
|
||||||
|
/* autonomous only if we're not doing dhcp, always set "on-link" */
|
||||||
|
opt->flags = do_slaac ? 0xC0 : 0x80;
|
||||||
|
opt->valid_lifetime = htonl(context->saved_valid - old);
|
||||||
|
opt->preferred_lifetime = htonl(0);
|
||||||
|
opt->reserved = 0;
|
||||||
|
opt->prefix = local;
|
||||||
|
|
||||||
|
inet_ntop(AF_INET6, &local, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s old prefix", iface_name, daemon->addrbuff);
|
||||||
|
}
|
||||||
|
|
||||||
|
up = &context->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
up = &context->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parm.found_context)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
|
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
|
||||||
available from SIOCGIFMTU */
|
available from SIOCGIFMTU */
|
||||||
@@ -291,7 +345,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
put_opt6_char(ICMP6_OPT_DNSSL);
|
put_opt6_char(ICMP6_OPT_DNSSL);
|
||||||
put_opt6_char(len + 1);
|
put_opt6_char(len + 1);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(1800); /* lifetime - twice RA retransmit */
|
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
||||||
put_opt6(opt_cfg->val, opt_cfg->len);
|
put_opt6(opt_cfg->val, opt_cfg->len);
|
||||||
|
|
||||||
/* pad */
|
/* pad */
|
||||||
@@ -361,11 +415,13 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
if (!(context->flags & CONTEXT_TEMPLATE) &&
|
if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
|
||||||
prefix == context->prefix &&
|
prefix == context->prefix &&
|
||||||
is_same_net6(local, &context->start6, prefix) &&
|
is_same_net6(local, &context->start6, prefix) &&
|
||||||
is_same_net6(local, &context->end6, prefix))
|
is_same_net6(local, &context->end6, prefix))
|
||||||
{
|
{
|
||||||
|
context->saved_valid = valid;
|
||||||
|
|
||||||
if ((context->flags &
|
if ((context->flags &
|
||||||
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
||||||
{
|
{
|
||||||
@@ -386,12 +442,12 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
param->other = 1;
|
param->other = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find floor time, don't reduce below RA interval. */
|
/* find floor time, don't reduce below 3 * RA interval. */
|
||||||
if (time > context->lease_time)
|
if (time > context->lease_time)
|
||||||
{
|
{
|
||||||
time = context->lease_time;
|
time = context->lease_time;
|
||||||
if (time < ((unsigned int)RA_INTERVAL))
|
if (time < ((unsigned int)(3 * RA_INTERVAL)))
|
||||||
time = RA_INTERVAL;
|
time = 3 * RA_INTERVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->flags & CONTEXT_DEPRECATE)
|
if (context->flags & CONTEXT_DEPRECATE)
|
||||||
@@ -466,6 +522,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
|
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -520,16 +577,25 @@ time_t periodic_ra(time_t now)
|
|||||||
if (!context)
|
if (!context)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* There's a context overdue, but we can't find an interface
|
if ((context->flags & CONTEXT_OLD) && context->if_index != 0)
|
||||||
associated with it, because it's for a subnet we dont
|
{
|
||||||
have an interface on. Probably we're doing DHCP on
|
/* A context for an old address. We'll not find the interface by
|
||||||
a remote subnet via a relay. Zero the timer, since we won't
|
looking for addresses, but we know it anyway, as long as we
|
||||||
ever be able to send ra's and satistfy it. */
|
sent at least one RA whilst the address was current. */
|
||||||
if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
param.iface = context->if_index;
|
||||||
|
new_timeout(context, now);
|
||||||
|
}
|
||||||
|
else if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
||||||
|
/* There's a context overdue, but we can't find an interface
|
||||||
|
associated with it, because it's for a subnet we dont
|
||||||
|
have an interface on. Probably we're doing DHCP on
|
||||||
|
a remote subnet via a relay. Zero the timer, since we won't
|
||||||
|
ever be able to send ra's and satistfy it. */
|
||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
else if (param.iface != 0 &&
|
|
||||||
indextoname(daemon->icmp6fd, param.iface, interface) &&
|
if (param.iface != 0 &&
|
||||||
iface_check(AF_LOCAL, NULL, interface, NULL))
|
indextoname(daemon->icmp6fd, param.iface, interface) &&
|
||||||
|
iface_check(AF_LOCAL, NULL, interface, NULL))
|
||||||
{
|
{
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
@@ -554,7 +620,7 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
(void)valid;
|
(void)valid;
|
||||||
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
if (!(context->flags & CONTEXT_TEMPLATE) &&
|
if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
|
||||||
prefix == context->prefix &&
|
prefix == context->prefix &&
|
||||||
is_same_net6(local, &context->start6, prefix) &&
|
is_same_net6(local, &context->start6, prefix) &&
|
||||||
is_same_net6(local, &context->end6, prefix) &&
|
is_same_net6(local, &context->end6, prefix) &&
|
||||||
@@ -568,12 +634,7 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
if (!(flags & IFACE_TENTATIVE))
|
if (!(flags & IFACE_TENTATIVE))
|
||||||
param->iface = if_index;
|
param->iface = if_index;
|
||||||
|
|
||||||
if (difftime(param->now, context->ra_short_period_start) < 60.0)
|
new_timeout(context, param->now);
|
||||||
/* range 5 - 20 */
|
|
||||||
context->ra_time = param->now + 5 + (rand16()/4400);
|
|
||||||
else
|
|
||||||
/* range 3/4 - 1 times RA_INTERVAL */
|
|
||||||
context->ra_time = param->now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
|
|
||||||
|
|
||||||
/* zero timers for other contexts on the same subnet, so they don't timeout
|
/* zero timers for other contexts on the same subnet, so they don't timeout
|
||||||
independently */
|
independently */
|
||||||
@@ -588,6 +649,15 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
|
|
||||||
return 1; /* keep searching */
|
return 1; /* keep searching */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void new_timeout(struct dhcp_context *context, time_t now)
|
||||||
|
{
|
||||||
|
if (difftime(now, context->ra_short_period_start) < 60.0)
|
||||||
|
/* range 5 - 20 */
|
||||||
|
context->ra_time = now + 5 + (rand16()/4400);
|
||||||
|
else
|
||||||
|
/* range 3/4 - 1 times RA_INTERVAL */
|
||||||
|
context->ra_time = now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+9
-5
@@ -615,7 +615,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
|
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3)))
|
||||||
{
|
{
|
||||||
/* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
|
/* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
|
||||||
int len = option_len(opt);
|
int len = option_len(opt);
|
||||||
@@ -645,7 +645,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fqdn_flags & 0x04)
|
if (fqdn_flags & 0x04)
|
||||||
while (*op != 0 && ((op + (*op) + 1) - pp) < len)
|
while (*op != 0 && ((op + (*op)) - pp) < len)
|
||||||
{
|
{
|
||||||
memcpy(pq, op+1, *op);
|
memcpy(pq, op+1, *op);
|
||||||
pq += *op;
|
pq += *op;
|
||||||
@@ -2289,7 +2289,9 @@ static void do_options(struct dhcp_context *context,
|
|||||||
|
|
||||||
if (domain)
|
if (domain)
|
||||||
len += strlen(domain) + 1;
|
len += strlen(domain) + 1;
|
||||||
|
else if (fqdn_flags & 0x04)
|
||||||
|
len--;
|
||||||
|
|
||||||
if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
|
if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
|
||||||
{
|
{
|
||||||
*(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */
|
*(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */
|
||||||
@@ -2300,8 +2302,10 @@ static void do_options(struct dhcp_context *context,
|
|||||||
{
|
{
|
||||||
p = do_rfc1035_name(p, hostname);
|
p = do_rfc1035_name(p, hostname);
|
||||||
if (domain)
|
if (domain)
|
||||||
p = do_rfc1035_name(p, domain);
|
{
|
||||||
*p++ = 0;
|
p = do_rfc1035_name(p, domain);
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-5
@@ -120,7 +120,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
|||||||
!IN6_IS_ADDR_MULTICAST(link_address))
|
!IN6_IS_ADDR_MULTICAST(link_address))
|
||||||
for (c = daemon->dhcp6; c; c = c->next)
|
for (c = daemon->dhcp6; c; c = c->next)
|
||||||
if ((c->flags & CONTEXT_DHCP) &&
|
if ((c->flags & CONTEXT_DHCP) &&
|
||||||
!(c->flags & CONTEXT_TEMPLATE) &&
|
!(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
|
||||||
is_same_net6(link_address, &c->start6, c->prefix) &&
|
is_same_net6(link_address, &c->start6, c->prefix) &&
|
||||||
is_same_net6(link_address, &c->end6, c->prefix))
|
is_same_net6(link_address, &c->end6, c->prefix))
|
||||||
{
|
{
|
||||||
@@ -1299,16 +1299,18 @@ struct dhcp_netid *add_options(struct state *state, struct in6_addr *fallback, s
|
|||||||
size_t len = strlen(state->hostname);
|
size_t len = strlen(state->hostname);
|
||||||
|
|
||||||
if (state->send_domain)
|
if (state->send_domain)
|
||||||
len += strlen(state->send_domain) + 1;
|
len += strlen(state->send_domain) + 2;
|
||||||
|
|
||||||
o = new_opt6(OPTION6_FQDN);
|
o = new_opt6(OPTION6_FQDN);
|
||||||
if ((p = expand(len + 3)))
|
if ((p = expand(len + 2)))
|
||||||
{
|
{
|
||||||
*(p++) = state->fqdn_flags;
|
*(p++) = state->fqdn_flags;
|
||||||
p = do_rfc1035_name(p, state->hostname);
|
p = do_rfc1035_name(p, state->hostname);
|
||||||
if (state->send_domain)
|
if (state->send_domain)
|
||||||
p = do_rfc1035_name(p, state->send_domain);
|
{
|
||||||
*p = 0;
|
p = do_rfc1035_name(p, state->send_domain);
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end_opt6(o);
|
end_opt6(o);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -38,7 +38,9 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
|
|||||||
lease->slaac_address = NULL;
|
lease->slaac_address = NULL;
|
||||||
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
if ((context->flags & CONTEXT_RA_NAME) && lease->last_interface == context->if_index)
|
if ((context->flags & CONTEXT_RA_NAME) &&
|
||||||
|
!(context->flags & CONTEXT_OLD) &&
|
||||||
|
lease->last_interface == context->if_index)
|
||||||
{
|
{
|
||||||
struct in6_addr addr = context->start6;
|
struct in6_addr addr = context->start6;
|
||||||
if (lease->hwaddr_len == 6 &&
|
if (lease->hwaddr_len == 6 &&
|
||||||
@@ -123,7 +125,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
|
|||||||
time_t next_event = 0;
|
time_t next_event = 0;
|
||||||
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
if ((context->flags & CONTEXT_RA_NAME))
|
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* nothing configured */
|
/* nothing configured */
|
||||||
|
|||||||
+1
-1
@@ -555,7 +555,7 @@ void check_tftp_listeners(fd_set *rset, time_t now)
|
|||||||
}
|
}
|
||||||
/* don't complain about timeout when we're awaiting the last
|
/* don't complain about timeout when we're awaiting the last
|
||||||
ACK, some clients never send it */
|
ACK, some clients never send it */
|
||||||
else if (++transfer->backoff > 5 && len != 0)
|
else if (++transfer->backoff > 7 && len != 0)
|
||||||
{
|
{
|
||||||
endcon = 1;
|
endcon = 1;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|||||||
+4
-5
@@ -151,14 +151,13 @@ int legal_hostname(char *name)
|
|||||||
/* check for legal char a-z A-Z 0-9 - _ . */
|
/* check for legal char a-z A-Z 0-9 - _ . */
|
||||||
{
|
{
|
||||||
if ((c >= 'A' && c <= 'Z') ||
|
if ((c >= 'A' && c <= 'Z') ||
|
||||||
(c >= 'a' && c <= 'z'))
|
(c >= 'a' && c <= 'z') ||
|
||||||
|
(c >= '0' && c <= '9'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!first &&
|
if (!first && (c == '-' || c == '_'))
|
||||||
((c >= '0' && c <= '9') ||
|
|
||||||
c == '-' || c == '_'))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* end of hostname part */
|
/* end of hostname part */
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in new issue
Block a user