1 diff -up dhcp-4.2.1-P1/client/dhc6.c.sendDecline dhcp-4.2.1-P1/client/dhc6.c
2 --- dhcp-4.2.1-P1/client/dhc6.c.sendDecline 2010-09-10 22:27:11.000000000 +0200
3 +++ dhcp-4.2.1-P1/client/dhc6.c 2011-06-17 14:19:48.992099868 +0200
4 @@ -95,6 +95,8 @@ void do_select6(void *input);
5 void do_refresh6(void *input);
6 static void do_release6(void *input);
7 static void start_bound(struct client_state *client);
8 +static void start_decline6(struct client_state *client);
9 +static void do_decline6(void *input);
10 static void start_informed(struct client_state *client);
11 void informed_handler(struct packet *packet, struct client_state *client);
12 void bound_handler(struct packet *packet, struct client_state *client);
13 @@ -2075,6 +2077,7 @@ start_release6(struct client_state *clie
14 cancel_timeout(do_select6, client);
15 cancel_timeout(do_refresh6, client);
16 cancel_timeout(do_release6, client);
17 + cancel_timeout(do_decline6, client);
18 client->state = S_STOPPED;
21 @@ -2708,6 +2711,7 @@ dhc6_check_reply(struct client_state *cl
26 action = dhc6_stop_action;
29 @@ -2809,6 +2813,7 @@ dhc6_check_reply(struct client_state *cl
34 /* Nothing critical to do at this stage. */
37 @@ -3799,17 +3804,23 @@ reply_handler(struct packet *packet, str
38 cancel_timeout(do_select6, client);
39 cancel_timeout(do_refresh6, client);
40 cancel_timeout(do_release6, client);
41 + cancel_timeout(do_decline6, client);
43 /* If this is in response to a Release/Decline, clean up and return. */
44 - if (client->state == S_STOPPED) {
45 - if (client->active_lease == NULL)
47 + if ((client->state == S_STOPPED) ||
48 + (client->state == S_DECLINED)) {
50 + if (client->active_lease != NULL) {
51 + dhc6_lease_destroy(&client->active_lease, MDL);
52 + client->active_lease = NULL;
53 + /* We should never wait for nothing!? */
54 + if (stopping_finished())
58 + if (client->state == S_DECLINED)
59 + start_init6(client);
61 - dhc6_lease_destroy(&client->active_lease, MDL);
62 - client->active_lease = NULL;
63 - /* We should never wait for nothing!? */
64 - if (stopping_finished())
69 @@ -4336,7 +4347,11 @@ start_bound(struct client_state *client)
71 dhc6_marshall_values("new_", client, lease, ia, addr);
74 + // when script returns 3, DAD failed
75 + if (script_go(client) == 3) {
76 + start_decline6(client);
81 /* XXX: maybe we should loop on the old values instead? */
82 @@ -4382,6 +4397,149 @@ start_bound(struct client_state *client)
83 dhc6_check_times(client);
87 + * Decline addresses.
90 +start_decline6(struct client_state *client)
92 + /* Cancel any pending transmissions */
93 + cancel_timeout(do_confirm6, client);
94 + cancel_timeout(do_select6, client);
95 + cancel_timeout(do_refresh6, client);
96 + cancel_timeout(do_release6, client);
97 + cancel_timeout(do_decline6, client);
98 + client->state = S_DECLINED;
100 + if (client->active_lease == NULL)
103 + /* Set timers per RFC3315 section 18.1.7. */
104 + client->IRT = DEC_TIMEOUT * 100;
106 + client->MRC = DEC_MAX_RC;
109 + dhc6_retrans_init(client);
110 + client->v6_handler = reply_handler;
112 + client->refresh_type = DHCPV6_DECLINE;
113 + do_decline6(client);
117 + * do_decline6() creates a Decline packet and transmits it.
120 +do_decline6(void *input)
122 + struct client_state *client;
123 + struct data_string ds;
125 + struct timeval elapsed, tv;
129 + if ((client->active_lease == NULL) || !active_prefix(client))
132 + if ((client->MRC != 0) && (client->txcount > client->MRC)) {
133 + log_info("Max retransmission count exceeded.");
138 + * Start_time starts at the first transmission.
140 + if (client->txcount == 0) {
141 + client->start_time.tv_sec = cur_tv.tv_sec;
142 + client->start_time.tv_usec = cur_tv.tv_usec;
145 + /* elapsed = cur - start */
146 + elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
147 + elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
148 + if (elapsed.tv_usec < 0) {
149 + elapsed.tv_sec -= 1;
150 + elapsed.tv_usec += 1000000;
153 + memset(&ds, 0, sizeof(ds));
154 + if (!buffer_allocate(&ds.buffer, 4, MDL)) {
155 + log_error("Unable to allocate memory for Decline.");
159 + ds.data = ds.buffer->data;
161 + ds.buffer->data[0] = DHCPV6_DECLINE;
162 + memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
164 + /* Form an elapsed option. */
165 + /* Maximum value is 65535 1/100s coded as 0xffff. */
166 + if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
167 + ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
168 + client->elapsed = 0xffff;
170 + client->elapsed = elapsed.tv_sec * 100;
171 + client->elapsed += elapsed.tv_usec / 10000;
174 + client->elapsed = htons(client->elapsed);
176 + log_debug("XMT: Forming Decline.");
177 + make_client6_options(client, &client->sent_options,
178 + client->active_lease, DHCPV6_DECLINE);
179 + dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
180 + client->sent_options, &global_scope,
183 + /* Append IA's (but don't release temporary addresses). */
184 + if (wanted_ia_na &&
185 + dhc6_add_ia_na(client, &ds, client->active_lease,
186 + DHCPV6_DECLINE) != ISC_R_SUCCESS) {
187 + data_string_forget(&ds, MDL);
190 + if (wanted_ia_pd &&
191 + dhc6_add_ia_pd(client, &ds, client->active_lease,
192 + DHCPV6_DECLINE) != ISC_R_SUCCESS) {
193 + data_string_forget(&ds, MDL);
197 + /* Transmit and wait. */
198 + log_info("XMT: Decline on %s, interval %ld0ms.",
199 + client->name ? client->name : client->interface->name,
200 + (long int)client->RT);
202 + send_ret = send_packet6(client->interface, ds.data, ds.len,
204 + if (send_ret != ds.len) {
205 + log_error("dhc6: sendpacket6() sent %d of %d bytes",
209 + data_string_forget(&ds, MDL);
212 + tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
213 + tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
214 + if (tv.tv_usec >= 1000000) {
216 + tv.tv_usec -= 1000000;
218 + add_timeout(&tv, do_decline6, client, NULL, NULL);
219 + dhc6_retrans_advance(client);
223 + dhc6_lease_destroy(&client->active_lease, MDL);
224 + client->active_lease = NULL;
225 + start_init6(client);
229 /* While bound, ignore packets. In the future we'll want to answer
230 * Reconfigure-Request messages and the like.