]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Improve DHCPv6 leasequery
authorFrancis Dupont <fdupont@isc.org>
Mon, 17 Mar 2008 15:45:05 +0000 (15:45 +0000)
committerFrancis Dupont <fdupont@isc.org>
Mon, 17 Mar 2008 15:45:05 +0000 (15:45 +0000)
includes/dhcpd.h
server/confpars.c
server/db.c
server/dhcpleasequery.c
server/dhcpv6.c

index 75f6ffe6017743ffaaf184ee8295a03788fd2d61..fd86ab25607d70ba5c6fecd29da84d8a86ab8b25 100644 (file)
@@ -1347,6 +1347,8 @@ struct iaaddr {
        struct binding_scope *scope;            /* "set var = value;" */
        time_t hard_lifetime_end_time;          /* time address expires */
        time_t soft_lifetime_end_time;          /* time ephemeral expires */
+       u_int32_t prefer;                       /* cached preferred lifetime */
+       u_int32_t valid;                        /* cached valid lifetime */
        struct ia_xx *ia;                       /* IA for this lease */
        struct ipv6_pool *ipv6_pool;            /* pool for this lease */
 /*
@@ -1365,6 +1367,7 @@ struct ia_xx {
        u_int16_t ia_type;              /* IA_XX */
        int num_iaaddr;                 /* number of IAADDR for this IA */
        int max_iaaddr;                 /* space available for IAADDR */
+       time_t cltt;                    /* client last transaction time */
        struct iaaddr **iaaddr;         /* pointers to the various IAADDRs */
 };
 
index 3a54da05c63f86578312ababbbdb134017e3e314..96e4c4b0efcc7c4e4da22980bcbc3aade8fc5bb3 100644 (file)
@@ -4082,6 +4082,8 @@ parse_ia_na_declaration(struct parse *cfile) {
        u_int32_t iaid;
        struct iaddr iaddr;
        binding_state_t state;
+       u_int32_t prefer;
+       u_int32_t valid;
        TIME end_time;
        struct iaaddr *iaaddr;
        struct ipv6_pool *pool;
@@ -4129,6 +4131,11 @@ parse_ia_na_declaration(struct parse *cfile) {
                token = next_token(&val, NULL, cfile);
                if (token == RBRACE) break;
 
+               if (token == CLTT) {
+                       ia->cltt = parse_date (cfile);
+                       continue;
+               }
+
                if (token != IAADDR) {
                        parse_warn(cfile, "corrupt lease file; "
                                          "expecting IAADDR or right brace");
@@ -4152,6 +4159,7 @@ parse_ia_na_declaration(struct parse *cfile) {
                }
 
                state = FTS_LAST+1;
+               prefer = valid = 0;
                end_time = -1;
                for (;;) {
                        token = next_token(&val, NULL, cfile);
@@ -4202,6 +4210,32 @@ parse_ia_na_declaration(struct parse *cfile) {
                                }
                                break;
 
+                               /* Lease preferred lifetime. */
+                             case PREFERRED_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "preferred time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               prefer = atoi (val);
+                               break;
+
+                               /* Lease valid lifetime. */
+                             case MAX_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "max time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               valid = atoi (val);
+                               break;
+
                                /* Lease expiration time. */
                              case ENDS:
                                end_time = parse_date(cfile);
@@ -4315,6 +4349,8 @@ parse_ia_na_declaration(struct parse *cfile) {
                memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr));
                iaaddr->plen = 0;
                iaaddr->state = state;
+               iaaddr->prefer = prefer;
+               iaaddr->valid = valid;
                if (iaaddr->state == FTS_RELEASED)
                        iaaddr->hard_lifetime_end_time = end_time;
 
@@ -4379,6 +4415,8 @@ parse_ia_ta_declaration(struct parse *cfile) {
        u_int32_t iaid;
        struct iaddr iaddr;
        binding_state_t state;
+       u_int32_t prefer;
+       u_int32_t valid;
        TIME end_time;
        struct iaaddr *iaaddr;
        struct ipv6_pool *pool;
@@ -4426,6 +4464,11 @@ parse_ia_ta_declaration(struct parse *cfile) {
                token = next_token(&val, NULL, cfile);
                if (token == RBRACE) break;
 
+               if (token == CLTT) {
+                       ia->cltt = parse_date (cfile);
+                       continue;
+               }
+
                if (token != IAADDR) {
                        parse_warn(cfile, "corrupt lease file; "
                                          "expecting IAADDR or right brace");
@@ -4449,6 +4492,7 @@ parse_ia_ta_declaration(struct parse *cfile) {
                }
 
                state = FTS_LAST+1;
+               prefer = valid = 0;
                end_time = -1;
                for (;;) {
                        token = next_token(&val, NULL, cfile);
@@ -4499,6 +4543,32 @@ parse_ia_ta_declaration(struct parse *cfile) {
                                }
                                break;
 
+                               /* Lease preferred lifetime. */
+                             case PREFERRED_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "preferred time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               prefer = atoi (val);
+                               break;
+
+                               /* Lease valid lifetime. */
+                             case MAX_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "max time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               valid = atoi (val);
+                               break;
+
                                /* Lease expiration time. */
                              case ENDS:
                                end_time = parse_date(cfile);
@@ -4612,6 +4682,8 @@ parse_ia_ta_declaration(struct parse *cfile) {
                memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr));
                iaaddr->plen = 0;
                iaaddr->state = state;
+               iaaddr->prefer = prefer;
+               iaaddr->valid = valid;
                if (iaaddr->state == FTS_RELEASED)
                        iaaddr->hard_lifetime_end_time = end_time;
 
@@ -4677,6 +4749,8 @@ parse_ia_pd_declaration(struct parse *cfile) {
        struct iaddr iaddr;
        u_int8_t plen;
        binding_state_t state;
+       u_int32_t prefer;
+       u_int32_t valid;
        TIME end_time;
        struct iaaddr *iapref;
        struct ipv6_pool *pool;
@@ -4724,6 +4798,11 @@ parse_ia_pd_declaration(struct parse *cfile) {
                token = next_token(&val, NULL, cfile);
                if (token == RBRACE) break;
 
+               if (token == CLTT) {
+                       ia->cltt = parse_date (cfile);
+                       continue;
+               }
+
                if (token != IAPREFIX) {
                        parse_warn(cfile, "corrupt lease file; expecting "
                                   "IAPREFIX or right brace");
@@ -4747,6 +4826,7 @@ parse_ia_pd_declaration(struct parse *cfile) {
                }
 
                state = FTS_LAST+1;
+               prefer = valid = 0;
                end_time = -1;
                for (;;) {
                        token = next_token(&val, NULL, cfile);
@@ -4797,6 +4877,32 @@ parse_ia_pd_declaration(struct parse *cfile) {
                                }
                                break;
 
+                               /* Lease preferred lifetime. */
+                             case PREFERRED_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "preferred time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               prefer = atoi (val);
+                               break;
+
+                               /* Lease valid lifetime. */
+                             case MAX_LIFE:
+                               token = next_token(&val, NULL, cfile);
+                               if (token != NUMBER) {
+                                       parse_warn(cfile, "%s is not a valid "
+                                                         "max time",
+                                                  val);
+                                       skip_to_semi(cfile);
+                                       continue;
+                               }
+                               valid = atoi (val);
+                               break;
+
                                /* Prefix expiration time. */
                              case ENDS:
                                end_time = parse_date(cfile);
@@ -4910,6 +5016,8 @@ parse_ia_pd_declaration(struct parse *cfile) {
                memcpy(&iapref->addr, iaddr.iabuf, sizeof(iapref->addr));
                iapref->plen = plen;
                iapref->state = state;
+               iapref->prefer = prefer;
+               iapref->valid = valid;
                if (iapref->state == FTS_RELEASED)
                        iapref->hard_lifetime_end_time = end_time;
 
index 29b140d35adffbc40421f2c6b7518c95cc346792..42120d3180fcb8f8744214b51ef757b9fb48e344 100644 (file)
@@ -548,6 +548,15 @@ write_ia(const struct ia_xx *ia) {
        if (fprintf_ret < 0) {
                goto error_exit;
        }
+       if (ia->cltt != MIN_TIME) {
+               tval = print_time(ia->cltt);
+               if (tval == NULL) {
+                       goto error_exit;
+               }
+               if (fprintf(db_file, "  cltt %s\n", tval) < 0) {
+                       goto error_exit;
+               }
+       }
        for (i=0; i<ia->num_iaaddr; i++) {
                iaaddr = ia->iaaddr[i];
 
@@ -570,6 +579,14 @@ write_ia(const struct ia_xx *ia) {
                            binding_state) < 0) {
                        goto error_exit;
                }
+               if (fprintf(db_file, "    preferred-life %u\n",
+                           (unsigned)iaaddr->prefer) < 0) {
+                       goto error_exit;
+               }
+               if (fprintf(db_file, "    max-life %u\n",
+                           (unsigned)iaaddr->valid) < 0) {
+                       goto error_exit;
+               }
 
                /* Note that from here on out, the \n is prepended to the
                 * next write, rather than appended to the current write.
index 0c4174a6ba4cb026427933b13c663c5e4d85e118..97fc4e0e82373e1ea4eacf0794be6c5430c0ebe4 100644 (file)
@@ -656,10 +656,6 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
  *
  * TODO: RFC5007 ORO in query-options.
  *
- * TODO: RFC5007 not default preferred and valid time.
- *
- * TODO: RFC5007 not zero Client Last Transaction Time (clt-time).
- *
  * TODO: RFC5007 lq-relay-data.
  *
  * TODO: RFC5007 lq-client-link.
@@ -952,10 +948,9 @@ process_lq_by_address(struct lq6_state *lq) {
        }
        data.data = data.buffer->data;
        memcpy(data.buffer->data, &iaaddr->addr, 16);
-       lifetime = DEFAULT_DEFAULT_LEASE_TIME;
-       lifetime = (lifetime / 2) + (lifetime / 8);
+       lifetime = iaaddr->prefer;
        putULong(data.buffer->data + 16, lifetime);
-       lifetime = DEFAULT_DEFAULT_LEASE_TIME;
+       lifetime = iaaddr->valid;
        putULong(data.buffer->data + 20, lifetime);
        if (!save_option_buffer(&dhcpv6_universe, opt_state,
                                NULL, (unsigned char *)data.data, data.len,
@@ -965,7 +960,7 @@ process_lq_by_address(struct lq6_state *lq) {
        }
        data_string_forget(&data, MDL);
 
-       lifetime = 0;
+       lifetime = htonl(iaaddr->ia->cltt);
        if (!save_option_buffer(&dhcpv6_universe, opt_state,
                                NULL, (unsigned char *)&lifetime, 4,
                                D6O_CLT_TIME, 0)) {
index 2dad33ed202f837eddfb2a9e97125affc0a39103..6fde7584ac227d5b8697a8e2ef9fe34dd4b30c97 100644 (file)
@@ -1827,6 +1827,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                }
 
                /* Put new ia into the hash. */
+               reply->ia->cltt = cur_time;
                ia_id = &reply->ia->iaid_duid;
                ia_hash_add(ia_na_active, (unsigned char *)ia_id->data,
                            ia_id->len, reply->ia, MDL);
@@ -2441,6 +2442,7 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
                }
 
                /* Put new ia into the hash. */
+               reply->ia->cltt = cur_time;
                ia_id = &reply->ia->iaid_duid;
                ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data,
                            ia_id->len, reply->ia, MDL);
@@ -2750,6 +2752,10 @@ reply_process_is_addressed(struct reply_state *reply,
 
        /* Perform dynamic lease related update work. */
        if (reply->lease != NULL) {
+               /* Cached lifetimes */
+               reply->lease->prefer = reply->send_prefer;
+               reply->lease->valid = reply->send_valid;
+
                /* Advance (or rewind) the valid lifetime. */
                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
                        reply->lease->soft_lifetime_end_time =
@@ -3186,6 +3192,7 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                }
 
                /* Put new ia into the hash. */
+               reply->ia->cltt = cur_time;
                ia_id = &reply->ia->iaid_duid;
                ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data,
                            ia_id->len, reply->ia, MDL);
@@ -3698,6 +3705,10 @@ reply_process_is_prefixed(struct reply_state *reply,
 
        /* Perform dynamic prefix related update work. */
        if (reply->lease != NULL) {
+               /* Cached lifetimes */
+               reply->lease->prefer = reply->send_prefer;
+               reply->lease->valid = reply->send_valid;
+
                /* Advance (or rewind) the valid lifetime. */
                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
                        reply->lease->soft_lifetime_end_time =
@@ -4276,6 +4287,7 @@ ia_na_match_decline(const struct data_string *client_id,
                            tmp_addr, sizeof(tmp_addr)));
        if (lease != NULL) {
                decline_lease6(lease->ipv6_pool, lease);
+               lease->ia->cltt = cur_time;
                write_ia(lease->ia);
        }
 }
@@ -4692,6 +4704,7 @@ ia_na_match_release(const struct data_string *client_id,
                 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
        if (lease != NULL) {
                release_lease6(lease->ipv6_pool, lease);
+               lease->ia->cltt = cur_time;
                write_ia(lease->ia);
        }
 }
@@ -4784,6 +4797,7 @@ ia_pd_match_release(const struct data_string *client_id,
                 (unsigned) getUChar(iapref->data + 8));
        if (prefix != NULL) {
                release_lease6(prefix->ipv6_pool, prefix);
+               prefix->ia->cltt = cur_time;
                write_ia(prefix->ia);
        }
 }