dhcp-4.2.0-sendDecline.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. diff -up dhcp-4.2.0/client/dhc6.c.sendDecline dhcp-4.2.0/client/dhc6.c
  2. --- dhcp-4.2.0/client/dhc6.c.sendDecline 2009-11-20 02:48:58.000000000 +0100
  3. +++ dhcp-4.2.0/client/dhc6.c 2010-07-21 16:18:51.000000000 +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. @@ -2140,6 +2142,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;
  19. /*
  20. @@ -2790,6 +2793,7 @@ dhc6_check_reply(struct client_state *cl
  21. break;
  22. case S_STOPPED:
  23. + case S_DECLINED:
  24. action = dhc6_stop_action;
  25. break;
  26. @@ -2891,6 +2895,7 @@ dhc6_check_reply(struct client_state *cl
  27. break;
  28. case S_STOPPED:
  29. + case S_DECLINED:
  30. /* Nothing critical to do at this stage. */
  31. break;
  32. @@ -3933,17 +3938,23 @@ reply_handler(struct packet *packet, str
  33. cancel_timeout(do_select6, client);
  34. cancel_timeout(do_refresh6, client);
  35. cancel_timeout(do_release6, client);
  36. + cancel_timeout(do_decline6, client);
  37. /* If this is in response to a Release/Decline, clean up and return. */
  38. - if (client->state == S_STOPPED) {
  39. - if (client->active_lease == NULL)
  40. - return;
  41. + if ((client->state == S_STOPPED) ||
  42. + (client->state == S_DECLINED)) {
  43. +
  44. + if (client->active_lease != NULL) {
  45. + dhc6_lease_destroy(&client->active_lease, MDL);
  46. + client->active_lease = NULL;
  47. + /* We should never wait for nothing!? */
  48. + if (stopping_finished())
  49. + exit(0);
  50. + }
  51. +
  52. + if (client->state == S_DECLINED)
  53. + start_init6(client);
  54. - dhc6_lease_destroy(&client->active_lease, MDL);
  55. - client->active_lease = NULL;
  56. - /* We should never wait for nothing!? */
  57. - if (stopping_finished())
  58. - exit(0);
  59. return;
  60. }
  61. @@ -4470,7 +4481,11 @@ start_bound(struct client_state *client)
  62. oldia, oldaddr);
  63. dhc6_marshall_values("new_", client, lease, ia, addr);
  64. - script_go(client);
  65. + // when script returns 3, DAD failed
  66. + if (script_go(client) == 3) {
  67. + start_decline6(client);
  68. + return;
  69. + }
  70. }
  71. /* XXX: maybe we should loop on the old values instead? */
  72. @@ -4516,6 +4531,151 @@ start_bound(struct client_state *client)
  73. dhc6_check_times(client);
  74. }
  75. +/*
  76. + * Decline addresses.
  77. + */
  78. +void
  79. +start_decline6(struct client_state *client)
  80. +{
  81. + /* Cancel any pending transmissions */
  82. + cancel_timeout(do_confirm6, client);
  83. + cancel_timeout(do_select6, client);
  84. + cancel_timeout(do_refresh6, client);
  85. + cancel_timeout(do_release6, client);
  86. + cancel_timeout(do_decline6, client);
  87. + client->state = S_DECLINED;
  88. +
  89. + if (client->active_lease == NULL)
  90. + return;
  91. +
  92. + /* Set timers per RFC3315 section 18.1.7. */
  93. + client->IRT = DEC_TIMEOUT * 100;
  94. + client->MRT = 0;
  95. + client->MRC = DEC_MAX_RC;
  96. + client->MRD = 0;
  97. +
  98. + dhc6_retrans_init(client);
  99. + client->v6_handler = reply_handler;
  100. +
  101. + client->refresh_type = DHCPV6_DECLINE;
  102. + do_decline6(client);
  103. +}
  104. +
  105. +/*
  106. + * do_decline6() creates a Decline packet and transmits it.
  107. + */
  108. +static void
  109. +do_decline6(void *input)
  110. +{
  111. + struct client_state *client;
  112. + struct data_string ds;
  113. + int send_ret;
  114. + struct timeval elapsed, tv;
  115. +
  116. + client = input;
  117. +
  118. + if ((client->active_lease == NULL) || !active_prefix(client))
  119. + return;
  120. +
  121. + if ((client->MRC != 0) && (client->txcount > client->MRC)) {
  122. + log_info("Max retransmission count exceeded.");
  123. + goto decline_done;
  124. + }
  125. +
  126. + /*
  127. + * Start_time starts at the first transmission.
  128. + */
  129. + if (client->txcount == 0) {
  130. + client->start_time.tv_sec = cur_tv.tv_sec;
  131. + client->start_time.tv_usec = cur_tv.tv_usec;
  132. + }
  133. +
  134. + /* elapsed = cur - start */
  135. + elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
  136. + elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
  137. + if (elapsed.tv_usec < 0) {
  138. + elapsed.tv_sec -= 1;
  139. + elapsed.tv_usec += 1000000;
  140. + }
  141. +
  142. + memset(&ds, 0, sizeof(ds));
  143. + if (!buffer_allocate(&ds.buffer, 4, MDL)) {
  144. + log_error("Unable to allocate memory for Decline.");
  145. + goto decline_done;
  146. + }
  147. +
  148. + ds.data = ds.buffer->data;
  149. + ds.len = 4;
  150. + ds.buffer->data[0] = DHCPV6_DECLINE;
  151. + memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
  152. +
  153. + /* Form an elapsed option. */
  154. + /* Maximum value is 65535 1/100s coded as 0xffff. */
  155. + if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
  156. + ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
  157. + client->elapsed = 0xffff;
  158. + } else {
  159. + client->elapsed = elapsed.tv_sec * 100;
  160. + client->elapsed += elapsed.tv_usec / 10000;
  161. + }
  162. +
  163. + client->elapsed = htons(client->elapsed);
  164. +
  165. + log_debug("XMT: Forming Decline.");
  166. + make_client6_options(client, &client->sent_options,
  167. + client->active_lease, DHCPV6_DECLINE);
  168. + dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
  169. + client->sent_options, &global_scope,
  170. + &dhcpv6_universe);
  171. +
  172. + /* Append IA's (but don't release temporary addresses). */
  173. + if (wanted_ia_na &&
  174. + dhc6_add_ia_na(client, &ds, client->active_lease,
  175. + DHCPV6_DECLINE) != ISC_R_SUCCESS) {
  176. + data_string_forget(&ds, MDL);
  177. + goto decline_done;
  178. + }
  179. + if (wanted_ia_pd &&
  180. + dhc6_add_ia_pd(client, &ds, client->active_lease,
  181. + DHCPV6_DECLINE) != ISC_R_SUCCESS) {
  182. + data_string_forget(&ds, MDL);
  183. + goto decline_done;
  184. + }
  185. +
  186. + /* Transmit and wait. */
  187. + log_info("XMT: Decline on %s, interval %ld0ms.",
  188. + client->name ? client->name : client->interface->name,
  189. + (long int)client->RT);
  190. +
  191. + send_ret = send_packet6(client->interface, ds.data, ds.len,
  192. + &DHCPv6DestAddr);
  193. + if (send_ret != ds.len) {
  194. + log_error("dhc6: sendpacket6() sent %d of %d bytes",
  195. + send_ret, ds.len);
  196. + }
  197. +
  198. + data_string_forget(&ds, MDL);
  199. +
  200. + /* Wait RT */
  201. + tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
  202. + tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
  203. + if (tv.tv_usec >= 1000000) {
  204. + tv.tv_sec += 1;
  205. + tv.tv_usec -= 1000000;
  206. + }
  207. + add_timeout(&tv, do_decline6, client, NULL, NULL);
  208. + dhc6_retrans_advance(client);
  209. + return;
  210. +
  211. +decline_done:
  212. + if (client->active_lease != NULL) {
  213. + dhc6_lease_destroy(&client->active_lease, MDL);
  214. + client->active_lease = NULL;
  215. + }
  216. + start_init6(client);
  217. + return;
  218. +}
  219. +
  220. /* While bound, ignore packets. In the future we'll want to answer
  221. * Reconfigure-Request messages and the like.
  222. */