]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch
dnsmasq: Import more patches from upstream
[ipfire-2.x.git] / src / patches / dnsmasq / 0007-Improve-RFC-compliance-when-unable-to-supply-address.patch
CommitLineData
6644c1c7
MT
1From b9ff5c8f435173cfa616e3c398bdc089ef690a07 Mon Sep 17 00:00:00 2001
2From: Vladislav Grishenko <themiron@mail.ru>
3Date: Mon, 6 Oct 2014 14:34:24 +0100
d54a2ce4 4Subject: [PATCH 07/78] Improve RFC-compliance when unable to supply addresses
6644c1c7
MT
5 in DHCPv6
6
7While testing https://github.com/sbyx/odhcp6c client I have noticed it
8permanently crashes after startup.
9
10The reason was it (odhcp6c) doesn't expect empty IA options in ADVERTISE
11message without any suboptions.
12
13Despite this validation bug of odhcp6c, dnsmasq should not generate
14ADVERTISE messages with IA if there's nothing to advert per RFC 3315
1517.2.2:
16
17 If the server will not assign any addresses to any IAs in a
18
19 subsequent Request from the client, the server MUST send an Advertise
20
21 message to the client that includes only a Status Code option with
22
23 code NoAddrsAvail and a status message for the user, a Server
24
25 Identifier option with the server's DUID, and a Client Identifier
26
27 option with the client's DUID.
28
29Meanwhile it's need to add status code for every IA in REPLY message per
30RFC3315 18.2.1:
31
32 If the server cannot assign any addresses to an IA in the message
33 from the client, the server MUST include the IA in the Reply message
34 with no addresses in the IA and a Status Code option in the IA
35 containing status code NoAddrsAvail.
36
37So, I've changed the logic to skip IA completely from ADVERTISE messages and
38to add NoAddrsAvail subcode into IA of REPLY messages.
39
40As for overhead, yes, I believe it's ok to return NoAddrsAvail twice in IA
41and in global section for compatibility with all old and new clients.
42---
43 src/rfc3315.c | 27 +++++++++++++++++++++++++--
44 1 file changed, 25 insertions(+), 2 deletions(-)
45
46diff --git a/src/rfc3315.c b/src/rfc3315.c
47index 5ebf09d50ac1..ddb390bf1136 100644
48--- a/src/rfc3315.c
49+++ b/src/rfc3315.c
50@@ -691,6 +691,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
51 #endif
52
53 o = build_ia(state, &t1cntr);
54+ if (address_assigned)
55+ address_assigned = 2;
56
57 for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
58 {
59@@ -781,6 +783,27 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
60 address_assigned = 1;
61 }
62
63+ if (address_assigned != 1)
64+ {
65+ /* If the server will not assign any addresses to any IAs in a
66+ subsequent Request from the client, the server MUST send an Advertise
67+ message to the client that doesn't include any IA options. */
68+ if (!state->lease_allocate)
69+ {
70+ save_counter(o);
71+ continue;
72+ }
73+
74+ /* If the server cannot assign any addresses to an IA in the message
75+ from the client, the server MUST include the IA in the Reply message
76+ with no addresses in the IA and a Status Code option in the IA
77+ containing status code NoAddrsAvail. */
78+ o1 = new_opt6(OPTION6_STATUS_CODE);
79+ put_opt6_short(DHCP6NOADDRS);
80+ put_opt6_string(_("address unavailable"));
81+ end_opt6(o1);
82+ }
83+
84 end_ia(t1cntr, min_time, 0);
85 end_opt6(o);
86 }
87@@ -806,7 +829,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
88 put_opt6_short(DHCP6NOADDRS);
89 put_opt6_string(_("no addresses available"));
90 end_opt6(o1);
91- log6_packet(state, "DHCPADVERTISE", NULL, _("no addresses available"));
92+ log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
93 }
94
95 break;
96@@ -862,7 +885,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
97 {
98 /* Static range, not configured. */
99 o1 = new_opt6(OPTION6_STATUS_CODE);
100- put_opt6_short(DHCP6UNSPEC);
101+ put_opt6_short(DHCP6NOADDRS);
102 put_opt6_string(_("address unavailable"));
103 end_opt6(o1);
104 }
105--
1062.1.0
107