Add some fixes from upstream..

- crash at startup when an empty suffix is supplied to --conf-dir
- Improve RFC-compliance when unable to supply addresses in DHCPv6

ok sthen@
This commit is contained in:
brad 2014-10-25 08:57:39 +00:00
parent 352231fc60
commit b37c95cf98
3 changed files with 159 additions and 1 deletions

View File

@ -1,8 +1,9 @@
# $OpenBSD: Makefile,v 1.39 2014/09/28 17:34:01 brad Exp $
# $OpenBSD: Makefile,v 1.40 2014/10/25 08:57:39 brad Exp $
COMMENT= lightweight caching DNS forwarder, DHCP and TFTP server
DISTNAME= dnsmasq-2.72
REVISION= 0
CATEGORIES= net
MASTER_SITES= http://www.thekelleys.org.uk/dnsmasq/
EXTRACT_SUFX= .tar.xz

View File

@ -0,0 +1,60 @@
$OpenBSD: patch-src_option_c,v 1.3 2014/10/25 08:57:39 brad Exp $
crash at startup when an empty suffix is supplied to --conf-dir
--- src/option.c.orig Tue Sep 23 17:16:15 2014
+++ src/option.c Fri Oct 24 23:45:06 2014
@@ -1474,22 +1474,25 @@ static int one_opt(int option, char *arg, char *errstr
for (arg = comma; arg; arg = comma)
{
comma = split(arg);
- li = opt_malloc(sizeof(struct list));
- if (*arg == '*')
+ if (strlen(arg) != 0)
{
- li->next = match_suffix;
- match_suffix = li;
- /* Have to copy: buffer is overwritten */
- li->suffix = opt_string_alloc(arg+1);
+ li = opt_malloc(sizeof(struct list));
+ if (*arg == '*')
+ {
+ li->next = match_suffix;
+ match_suffix = li;
+ /* Have to copy: buffer is overwritten */
+ li->suffix = opt_string_alloc(arg+1);
+ }
+ else
+ {
+ li->next = ignore_suffix;
+ ignore_suffix = li;
+ /* Have to copy: buffer is overwritten */
+ li->suffix = opt_string_alloc(arg);
+ }
}
- else
- {
- li->next = ignore_suffix;
- ignore_suffix = li;
- /* Have to copy: buffer is overwritten */
- li->suffix = opt_string_alloc(arg);
- }
- };
+ }
if (!(dir_stream = opendir(directory)))
die(_("cannot access directory %s: %s"), directory, EC_FILE);
@@ -1555,7 +1558,12 @@ static int one_opt(int option, char *arg, char *errstr
free(ignore_suffix->suffix);
free(ignore_suffix);
}
-
+ for(; match_suffix; match_suffix = li)
+ {
+ li = match_suffix->next;
+ free(match_suffix->suffix);
+ free(match_suffix);
+ }
break;
}

View File

@ -0,0 +1,97 @@
$OpenBSD: patch-src_rfc3315_c,v 1.1 2014/10/25 08:57:39 brad Exp $
Improve RFC-compliance when unable to supply addresses in DHCPv6
While testing https://github.com/sbyx/odhcp6c client I have noticed it
permanently crashes after startup.
The reason was it (odhcp6c) doesn't expect empty IA options in ADVERTISE
message without any suboptions.
Despite this validation bug of odhcp6c, dnsmasq should not generate
ADVERTISE messages with IA if there's nothing to advert per RFC 3315
17.2.2:
If the server will not assign any addresses to any IAs in a
subsequent Request from the client, the server MUST send an Advertise
message to the client that includes only a Status Code option with
code NoAddrsAvail and a status message for the user, a Server
Identifier option with the server's DUID, and a Client Identifier
option with the client's DUID.
Meanwhile it's need to add status code for every IA in REPLY message per
RFC3315 18.2.1:
If the server cannot assign any addresses to an IA in the message
from the client, the server MUST include the IA in the Reply message
with no addresses in the IA and a Status Code option in the IA
containing status code NoAddrsAvail.
So, I've changed the logic to skip IA completely from ADVERTISE messages and
to add NoAddrsAvail subcode into IA of REPLY messages.
As for overhead, yes, I believe it's ok to return NoAddrsAvail twice in IA
and in global section for compatibility with all old and new clients.
--- src/rfc3315.c.orig Wed Oct 22 04:04:43 2014
+++ src/rfc3315.c Wed Oct 22 04:07:57 2014
@@ -691,6 +691,8 @@ static int dhcp6_no_relay(struct state *state, int msg
#endif
o = build_ia(state, &t1cntr);
+ if (address_assigned)
+ address_assigned = 2;
for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
{
@@ -781,6 +783,27 @@ static int dhcp6_no_relay(struct state *state, int msg
address_assigned = 1;
}
+ if (address_assigned != 1)
+ {
+ /* If the server will not assign any addresses to any IAs in a
+ subsequent Request from the client, the server MUST send an Advertise
+ message to the client that doesn't include any IA options. */
+ if (!state->lease_allocate)
+ {
+ save_counter(o);
+ continue;
+ }
+
+ /* If the server cannot assign any addresses to an IA in the message
+ from the client, the server MUST include the IA in the Reply message
+ with no addresses in the IA and a Status Code option in the IA
+ containing status code NoAddrsAvail. */
+ o1 = new_opt6(OPTION6_STATUS_CODE);
+ put_opt6_short(DHCP6NOADDRS);
+ put_opt6_string(_("address unavailable"));
+ end_opt6(o1);
+ }
+
end_ia(t1cntr, min_time, 0);
end_opt6(o);
}
@@ -806,7 +829,7 @@ static int dhcp6_no_relay(struct state *state, int msg
put_opt6_short(DHCP6NOADDRS);
put_opt6_string(_("no addresses available"));
end_opt6(o1);
- log6_packet(state, "DHCPADVERTISE", NULL, _("no addresses available"));
+ log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
}
break;
@@ -862,7 +885,7 @@ static int dhcp6_no_relay(struct state *state, int msg
{
/* Static range, not configured. */
o1 = new_opt6(OPTION6_STATUS_CODE);
- put_opt6_short(DHCP6UNSPEC);
+ put_opt6_short(DHCP6NOADDRS);
put_opt6_string(_("address unavailable"));
end_opt6(o1);
}