mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix hang at startup when DHCPv6 enabled on a complex network
configuration - we have to read all the MAC addresses from netlink, not bail when we find a suitable one. Fix thinko in dhcp_update_configs - thanks to Hartmut for spotting that. Get a sensible address for the default DNS server even when using a relay.
This commit is contained in:
@@ -31,9 +31,9 @@ static void put_opt6_long(unsigned int val);
|
||||
static void put_opt6_string(char *s);
|
||||
|
||||
static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in6_addr *addr, int xid, char *iface, char *string);
|
||||
|
||||
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
|
||||
@@ -45,7 +45,8 @@ static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
||||
#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
|
||||
|
||||
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, size_t sz, int is_unicast, time_t now)
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||
struct in6_addr *fallback, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
struct dhcp_netid *relay_tags = NULL;
|
||||
struct dhcp_vendor *vendor;
|
||||
@@ -56,7 +57,7 @@ size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name
|
||||
|
||||
outpacket_counter = 0;
|
||||
|
||||
if (dhcp6_maybe_relay(NULL, &relay_tags, context, interface, iface_name, daemon->dhcp_packet.iov_base, sz, is_unicast, now))
|
||||
if (dhcp6_maybe_relay(NULL, &relay_tags, context, interface, iface_name, fallback, daemon->dhcp_packet.iov_base, sz, is_unicast, now))
|
||||
return outpacket_counter;
|
||||
|
||||
return 0;
|
||||
@@ -64,7 +65,7 @@ size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name
|
||||
|
||||
/* This cost me blood to write, it will probably cost you blood to understand - srk. */
|
||||
static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
void *end = inbuff + sz;
|
||||
void *opts = inbuff + 34;
|
||||
@@ -114,7 +115,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now);
|
||||
return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, fallback, inbuff, sz, is_unicast, now);
|
||||
}
|
||||
|
||||
/* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
|
||||
@@ -159,7 +160,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
memcpy(&link_address, inbuff + 2, IN6ADDRSZ);
|
||||
/* Not, zero is_unicast since that is now known to refer to the
|
||||
relayed packet, not the original sent by the client */
|
||||
if (!dhcp6_maybe_relay(&link_address, relay_tagsp, context, interface, iface_name, opt6_ptr(opt, 0), opt6_len(opt), 0, now))
|
||||
if (!dhcp6_maybe_relay(&link_address, relay_tagsp, context, interface, iface_name, fallback, opt6_ptr(opt, 0), opt6_len(opt), 0, now))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -171,7 +172,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
}
|
||||
|
||||
static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
void *packet_options = inbuff + 4;
|
||||
void *end = inbuff + sz;
|
||||
@@ -685,7 +686,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
/* link temporarily */
|
||||
for (n = context_tags; n && n->next; n = n->next);
|
||||
if (l = n)
|
||||
if ((l = n))
|
||||
l->next = tags;
|
||||
|
||||
for (n = run_tag_if(context_tags); n; n = n->next)
|
||||
@@ -1191,10 +1192,15 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
}
|
||||
|
||||
if (!done_dns)
|
||||
if (!done_dns &&
|
||||
(!IN6_IS_ADDR_UNSPECIFIED(&context->local6) ||
|
||||
!IN6_IS_ADDR_UNSPECIFIED(fallback)))
|
||||
{
|
||||
o = new_opt6(OPTION6_DNS_SERVER);
|
||||
put_opt6(&context->local6, IN6ADDRSZ);
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&context->local6))
|
||||
put_opt6(fallback, IN6ADDRSZ);
|
||||
else
|
||||
put_opt6(&context->local6, IN6ADDRSZ);
|
||||
end_opt6(o);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user