]>
Commit | Line | Data |
---|---|---|
6644c1c7 MT |
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 | |
697b4f04 MT |
4 | Subject: [PATCH 007/113] Improve RFC-compliance when unable to supply |
5 | addresses in DHCPv6 | |
6644c1c7 MT |
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 |