From: Francis Dupont Date: Sat, 16 Feb 2008 12:15:05 +0000 (+0000) Subject: Improve NoAddrsAvail & co X-Git-Tag: v4_1_0a2~61 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=892379eca3644f16ba3c5517a9be655e713a55df;p=thirdparty%2Fdhcp.git Improve NoAddrsAvail & co --- diff --git a/server/dhcpv6.c b/server/dhcpv6.c index f20f5db95..4480e6cf4 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -645,6 +645,12 @@ static const int required_opts[] = { D6O_PREFERENCE, 0 }; +static const int required_opts_NAA[] = { + D6O_CLIENTID, + D6O_SERVERID, + D6O_STATUS_CODE, + 0 +}; static const int required_opts_solicit[] = { D6O_CLIENTID, D6O_SERVERID, @@ -1159,28 +1165,12 @@ lease_to_client(struct data_string *reply_ret, * the Reply message with no addresses in the IA and a Status * Code option in the IA containing status code NoAddrsAvail. * - * Section 18.2.3 (Renew): - * - * The server may choose to change the list of addresses and - * the lifetimes of addresses in IAs that are returned to the - * client. - * - * Section 18.2.4 (Rebind): - * - * Absolutely nothing. + * Section 18.1.8 (Client Behavior): * - * INTERPRETATION; - * - * Solicit and Request are fairly explicit; we send NoAddrsAvail. - * We handle SOLICIT here and REQUEST in the reply_process_ia_na() - * function (because SOLICIT only counts if we never get around to - * it). - * - * Renew and Rebind are totally undefined. If we send a reply with - * empty IA's, however, the client will stop renewing or rebinding, - * and this is a problem if they could have gotten addressed from - * another server. So we ignore client packets...they will eventually - * time out in the worst case. + * Leave unchanged any information about addresses the client has + * recorded in the IA but that were not included in the IA from + * the server. + * Sends a Renew/Rebind if the IA is not in the Reply message. */ if (no_addrs_avail && (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) @@ -1198,7 +1188,7 @@ lease_to_client(struct data_string *reply_ret, reply.cursor = REPLY_OPTIONS_INDEX; /* - * Produce an advertise that includes; + * Produce an advertise that includes only: * * Status code. * Server DUID. @@ -1210,12 +1200,8 @@ lease_to_client(struct data_string *reply_ret, sizeof(reply.buf) - reply.cursor, reply.opt_state, reply.packet, - required_opts, + required_opts_NAA, NULL); - } else if (no_addrs_avail && - (reply.packet->dhcpv6_msg_type != DHCPV6_REQUEST)) - { - goto exit; } else { /* * Having stored the client's IA_NA's, store any options that @@ -1370,8 +1356,13 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { reply->cursor += 4; /* - * For each address in this IA_NA, decide what to do about - * it. + * For each address in this IA_NA, decide what to do about it. + * + * Guidelines: + * + * The client leaves unchanged any infomation about addresses + * it has recorded but are not included ("cancel/break" below). + * A not included IA ("cleanup" below) could give a Renew/Rebind. */ oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR); reply->valid = reply->prefer = 0xffffffff; @@ -1405,10 +1396,9 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { switch (reply->packet->dhcpv6_msg_type) { case DHCPV6_SOLICIT: /* - * Solicit is handled by the caller, because - * it has to be the sum of all the IA's. + * No address for all the IA's is handled + * by the caller. */ - goto cleanup; case DHCPV6_REQUEST: /* Section 18.2.1 (Request): @@ -1460,10 +1450,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { * * We don't want to include the IA if we * provide zero addresses including zeroed - * lifetimes...if we did, the client would - * reset its renew/rebind behaviour. If we do - * not, the client may get a success off - * another server. + * lifetimes. */ if (reply->ia_addrs_included) status = ISC_R_SUCCESS; @@ -1812,6 +1799,9 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) { * If the server cannot find a client entry for the IA the * server returns the IA containing no addresses with a Status * Code option set to NoBinding in the Reply message. + * + * On mismatch we (ab)use this pretending we have not the IA + * as soon as we have not an address. */ } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) { /* Rewind the IA_NA to empty. */