package org.anarres.dhcp.v6.service; import com.google.common.annotations.Beta; import com.google.common.net.InetAddresses; import java.net.InetAddress; import javax.annotation.Nonnull; import org.anarres.dhcp.v6.Dhcp6Exception; import org.anarres.dhcp.v6.io.Dhcp6RequestContext; import org.anarres.dhcp.v6.options.DuidOption; import org.anarres.dhcp.v6.options.IaOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Basic implementation of a lease manager providing IPs from an IP pool */ @Beta public class PooledDhcp6LeaseManager extends AbstractDhcp6LeaseManager { private static final Logger LOG = LoggerFactory.getLogger(PooledDhcp6LeaseManager.class); private final InetAddress startingAddress; private final InetAddress endingAddress; // TODO should we use utilities from package org.anarres.dhcp.common.address here ?? public PooledDhcp6LeaseManager(@Nonnull final InetAddress startingAddress, @Nonnull final InetAddress endingAddress, @Nonnull final Lifetimes lifetimes) { super(lifetimes, ClientBindingRegistry.createForIaNa(), ClientBindingRegistry.createForIaTa()); this.startingAddress = startingAddress; this.endingAddress = endingAddress; } /** * Invoked during renew, rebind and confirm. Each address needs to be checked if still appropriate * * @throws org.anarres.dhcp.v6.Dhcp6Exception.UnableToAnswerException in case the test can not be performed */ @Override protected boolean isAppropriate(final Dhcp6RequestContext requestContext, final DuidOption.Duid clientId, final int iaid, final InetAddress ip) throws Dhcp6Exception.UnableToAnswerException { return true; } /** * @return next available IP */ @Override protected InetAddress newIp(final Dhcp6RequestContext requestContext, final DuidOption.Duid clientId, final IaOption iaOption) throws Dhcp6Exception { // Client provided address hints final Iterable<InetAddress> requestedAddresses = getAddressesFromIa(iaOption); // TODO try to use hints in address allocation // Warning, this is highly inefficient InetAddress current = startingAddress; while (true) { if(current.equals(endingAddress)) { LOG.warn("IP pool exhausted"); return null; } if(!getIaNaRegistry().containsIp(current) && !getIaTaRegistry().containsIp(current)) { return current; } current = InetAddresses.increment(current); } } }