]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into next
[ipfire-2.x.git] / src / patches / dnsmasq / 0007-Improve-RFC-compliance-when-unable-to-supply-address.patch
1 From b9ff5c8f435173cfa616e3c398bdc089ef690a07 Mon Sep 17 00:00:00 2001
2 From: Vladislav Grishenko <themiron@mail.ru>
3 Date: Mon, 6 Oct 2014 14:34:24 +0100
4 Subject: [PATCH 007/113] Improve RFC-compliance when unable to supply
5 addresses in DHCPv6
6
7 While testing https://github.com/sbyx/odhcp6c client I have noticed it
8 permanently crashes after startup.
9
10 The reason was it (odhcp6c) doesn't expect empty IA options in ADVERTISE
11 message without any suboptions.
12
13 Despite this validation bug of odhcp6c, dnsmasq should not generate
14 ADVERTISE messages with IA if there's nothing to advert per RFC 3315
15 17.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
29 Meanwhile it's need to add status code for every IA in REPLY message per
30 RFC3315 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
37 So, I've changed the logic to skip IA completely from ADVERTISE messages and
38 to add NoAddrsAvail subcode into IA of REPLY messages.
39
40 As for overhead, yes, I believe it's ok to return NoAddrsAvail twice in IA
41 and 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
46 diff --git a/src/rfc3315.c b/src/rfc3315.c
47 index 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 --
106 2.1.0
107