/// <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);
        }
Esempio n. 4
0
        /**
         * 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);
        }