/// <summary> /// Sets an IP address as in-use in it's binding pool. /// </summary> /// <param name="link">link for the message</param> /// <param name="inetAddr">IP address to set used</param> protected void SetIpAsUsed(link link, IPAddress inetAddr) { BindingPool bindingPool = FindBindingPool(link, inetAddr, null); if (bindingPool != null) { bindingPool.SetUsed(inetAddr); } else { _log.Warn("Unable to set address used: No BindingPool found for IP=" + inetAddr.ToString()); } }
/** * Sets and IP address as free in it's binding pool. * * @param inetAddr the IP address to free */ protected void FreeAddress(IPAddress inetAddr) { BindingPool bp = FindBindingPool(inetAddr); if (bp != null) { bp.SetFree(inetAddr); } else { _log.Error("Failed to free address: no BindingPool found for address: " + inetAddr.ToString()); } }
/// <summary> /// Find an address that can be reused. This method is invoked only /// when no "virgin" leases can be found for a new client request. /// </summary> /// <param name="bp"> binding pool</param> /// <returns>the oldest available address, if any</returns> protected IPAddress ReuseAvailableAddress(BindingPool bp) { Monitor.Enter(_lock); try { if (_log.IsDebugEnabled) { _log.Debug("Finding available addresses in pool: " + bp.ToString()); } List <IaAddress> iaAddrs = iaMgr.FindUnusedIaAddresses(bp.GetStartAddress(), bp.GetEndAddress()); if ((iaAddrs != null) && iaAddrs.Count > 0) { if (_log.IsDebugEnabled) { foreach (IaAddress iaAddre in iaAddrs) { _log.Debug("Found available address: " + iaAddre.ToString()); } } // list is ordered by validendtime // so the first one is the oldest one IaAddress iaAddr = iaAddrs.First(); _log.Info("Deleting oldest available address: " + iaAddr.ToString()); // delete the oldest one and return the IP // allowing that IP to be used again iaMgr.DeleteIaAddr(iaAddr); return(iaAddr.GetIpAddress()); // TODO: should we clear the rest of unused IPs // now, or wait for them to expire or be needed // for (int i=1; i<iaAddrs.size(); i++) { // // } } } finally { Monitor.Exit(_lock); } return(null); }
/** * Create a V6BindingAddress given an IaAddress loaded from the database. * * @param iaAddr the ia addr * @param clientLink the client link * @param requestMsg the request msg * * @return the binding address */ private V6BindingAddress BuildV6BindingAddressFromIaAddr(IaAddress iaAddr, DhcpLink clientLink, DhcpMessage requestMsg) { IPAddress inetAddr = iaAddr.GetIpAddress(); BindingPool bp = FindBindingPool(clientLink.GetLink(), inetAddr, requestMsg); if (bp != null) { // TODO store the configured options in the persisted binding? // ipAddr.setDhcpOptions(bp.getDhcpOptions()); return(new V6BindingAddress(iaAddr, (V6AddressBindingPool)bp)); } else { log.Error("Failed to create BindingAddress: No BindingPool found for IP=" + inetAddr.ToString()); } // MUST have a BindingPool, otherwise something's broke return(null); }
/// <summary> /// Get list of IP addresses for the given client IA request. /// </summary> /// <param name="clientLink">link for the client request message</param> /// <param name="duid">DUID of the client</param> /// <param name="iatype">IA type of the client request</param> /// <param name="iaid">IAID of the client request</param> /// <param name="requestAddrs">list of requested IP addresses, if any</param> /// <param name="requestMsg">client request message</param> /// <returns>list of IPAddress</returns> protected List <IPAddress> GetInetAddrs(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, List <IPAddress> requestAddrs, DhcpMessage requestMsg, IPAddress clientV4IPAddress) { List <IPAddress> inetAddrs = new List <IPAddress>(); if ((requestAddrs != null) && requestAddrs.Count > 0) { foreach (IPAddress reqAddr in requestAddrs) { IPAddress addr = reqAddr; if (!addr.Equals(DhcpConstants.ZEROADDR_V6)) { BindingPool bp = FindBindingPool(clientLink.GetLink(), addr, requestMsg); if (bp.IsFree(new BigInteger(addr.GetAddressBytes())) == false) { continue; } if (bp == null) { _log.Warn("No BindingPool found for requested client address: " + addr.ToString()); if (iatype == IdentityAssoc.PD_TYPE) { // TAHI tests want NoPrefixAvail in this case _log.Warn("Requested prefix is not available, returning"); return(inetAddrs); } // if there is no pool for the requested address, then skip it // because that address is either off-link or no longer valid continue; } _log.Info("Searching existing bindings for requested IP=" + addr.ToString()); IdentityAssoc ia = null; try { ia = iaMgr.FindIA(addr); if (ia != null) { // the address is assigned to an IA, which we // don't expect to be this IA, because we would // have found it using findCurrentBinding... // but, perhaps another thread just created it? if (IsMyIa(duid, iatype, iaid, ia)) { _log.Warn("Requested IP=" + addr.ToString() + " is already held by THIS client " + IdentityAssoc.KeyToString(duid, iatype, iaid) + ". Allowing this requested IP."); } else { _log.Info("Requested IP=" + addr.ToString() + " is held by ANOTHER client " + IdentityAssoc.KeyToString(duid, iatype, iaid)); // the address is held by another IA, so get a new one addr = GetNextFreeAddress(clientLink, requestMsg, clientV4IPAddress); } } if (addr != null) { inetAddrs.Add(addr); } } catch { _log.Error("Failure finding IA for address"); } } } } if (inetAddrs == null || inetAddrs.Count == 0) { // the client did not request any valid addresses, so get the next one IPAddress inetAddr = GetNextFreeAddress(clientLink, requestMsg, clientV4IPAddress); if (inetAddr != null) { inetAddrs.Add(inetAddr); } } return(inetAddrs); }