diff options
author | Shawn Routhier <sar@isc.org> | 2012-04-10 00:54:35 +0000 |
---|---|---|
committer | Shawn Routhier <sar@isc.org> | 2012-04-10 00:54:35 +0000 |
commit | bc7f8b8e3933b80d4e241f62b14a1917256d9c14 (patch) | |
tree | e69aedde61428ca3bebdb16e4447545cada80e44 /server/dhcpv6.c | |
parent | 6bc3ebf0880156496eae046d4bd27fbe8007eef6 (diff) | |
download | isc-dhcp-bc7f8b8e3933b80d4e241f62b14a1917256d9c14.tar.gz |
Multiple items to clean up IPv6 address processing.
When processing an IA that we've seen check to see if the
addresses are usable (not in use by somebody else) before
handing it out.
When reading in leases from the file discard expired addresses.
When picking an address for a client include the IA ID in
addition to the client ID to generally pick different addresses
for different IAs.
[ISC-Bugs #23138] [ISC-Bugs #27945] [ISC-Bugs #25586]
[ISC-Bugs #27684]
Diffstat (limited to 'server/dhcpv6.c')
-rw-r--r-- | server/dhcpv6.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/server/dhcpv6.c b/server/dhcpv6.c index 336b3a07..96e2b2f9 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -2228,13 +2228,13 @@ address_is_owned(struct reply_state *reply, struct iaddr *addr) { log_fatal("Impossible condition at %s:%d.", MDL); if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0) - return ISC_TRUE; + return (ISC_TRUE); - return ISC_FALSE; + return (ISC_FALSE); } if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0)) - return ISC_FALSE; + return (ISC_FALSE); for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) { struct iasubopt *tmp; @@ -2242,12 +2242,15 @@ address_is_owned(struct reply_state *reply, struct iaddr *addr) { tmp = reply->old_ia->iasubopt[i]; if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) { + if (lease6_usable(tmp) == ISC_FALSE) { + return (ISC_FALSE); + } iasubopt_reference(&reply->lease, tmp, MDL); - return ISC_TRUE; + return (ISC_TRUE); } } - return ISC_FALSE; + return (ISC_FALSE); } /* Process a client-supplied IA_TA. This may append options to the tail of @@ -2769,7 +2772,8 @@ find_client_address(struct reply_state *reply) { * Look for the best lease on the client's shared * network. */ - if (candidate_shared == reply->shared) { + if ((candidate_shared == reply->shared) && + (lease6_usable(lease) == ISC_TRUE)) { best_lease = lease_compare(lease, best_lease); } } @@ -2780,7 +2784,7 @@ find_client_address(struct reply_state *reply) { */ if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) { status = pick_v6_address(&reply->lease, reply->shared, - &reply->client_id); + &reply->ia->iaid_duid); } else if (best_lease != NULL) { iasubopt_reference(&reply->lease, best_lease, MDL); status = ISC_R_SUCCESS; @@ -3652,14 +3656,14 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { if ((pref->bits == l->cidrnet.bits) && (memcmp(pref->lo_addr.iabuf, l->cidrnet.lo_addr.iabuf, 16) == 0)) - return ISC_TRUE; + return (ISC_TRUE); } - return ISC_FALSE; + return (ISC_FALSE); } if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0)) - return ISC_FALSE; + return (ISC_FALSE); for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) { struct iasubopt *tmp; @@ -3667,13 +3671,16 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { tmp = reply->old_ia->iasubopt[i]; if ((pref->bits == (int) tmp->plen) && - memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0) { + (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) { + if (lease6_usable(tmp) == ISC_FALSE) { + return (ISC_FALSE); + } iasubopt_reference(&reply->lease, tmp, MDL); - return ISC_TRUE; + return (ISC_TRUE); } } - return ISC_FALSE; + return (ISC_FALSE); } /* @@ -3767,8 +3774,9 @@ find_client_prefix(struct reply_state *reply) { * if it is scoped in a pool under the client's shared * network. */ - if (candidate_shared == NULL || - candidate_shared == reply->shared) { + if (((candidate_shared == NULL) || + (candidate_shared == reply->shared)) && + (lease6_usable(prefix) == ISC_TRUE)) { best_prefix = prefix_compare(reply, prefix, best_prefix); } |