/** * Build a V6BindingAddress given an IaAddress loaded from the database * and a static binding for the client request. * * @param iaAddr * @param staticBinding * @return */ private V6BindingAddress BuildV6StaticBindingFromIaAddr(IaAddress iaAddr, StaticBinding staticBinding) { V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, staticBinding); return(bindingAddr); }
/** * Build a BindingAddress for the given InetAddress and DhcpLink. * * @param inetAddr the inet addr * @param clientLink the client link * @param requestMsg the request msg * * @return the binding address */ protected override BindingObject BuildBindingObject(IPAddress inetAddr, DhcpLink clientLink, DhcpMessage requestMsg) { V6AddressBindingPool bp = (V6AddressBindingPool)FindBindingPool(clientLink.GetLink(), inetAddr, requestMsg); if (bp != null) { bp.SetUsed(inetAddr); // TODO check if this is necessary IaAddress iaAddr = new IaAddress(); iaAddr.SetIpAddress(inetAddr); V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, bp); SetBindingObjectTimes(bindingAddr, bp.GetPreferredLifetimeMs(), bp.GetPreferredLifetimeMs()); // TODO store the configured options in the persisted binding? // bindingAddr.setDhcpOptions(bp.getDhcpOptions()); return(bindingAddr); } 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> /// Release an IaAddress. If policy dictates, the address will be deleted, /// otherwise the state will be marked as released instead. In either case, /// a DDNS delete will be issued for the address binding. /// </summary> /// <param name="ia">iaAddr the IaAddress to be released</param> /// <param name="iaAddr">iaAddr the IaAddress to be released</param> public void ReleaseIaAddress(IdentityAssoc ia, IaAddress iaAddr) { try { log.Info("Releasing address: " + iaAddr.GetIpAddress().ToString()); //DdnsDelete(ia, iaAddr); if (DhcpServerPolicies.GlobalPolicyAsBoolean( Property.BINDING_MANAGER_DELETE_OLD_BINDINGS)) { iaMgr.DeleteIaAddr(iaAddr); // free the address only if it is deleted from the db, // otherwise, we will get a unique constraint violation // if another client obtains this released IP address FreeAddress(iaAddr.GetIpAddress()); } else { iaAddr.SetStartTime(DateTime.Now); iaAddr.SetPreferredEndTime(DateTime.Now); iaAddr.SetValidEndTime(DateTime.Now); iaAddr.SetState(IaAddress.RELEASED); iaMgr.UpdateIaAddr(iaAddr); log.Info("Address released: " + iaAddr.ToString()); } } catch (Exception ex) { log.Error("Failed to release address"); } }
/// <summary> /// Create a binding in from a StaticBinding /// </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="staticBinding">static binding</param> /// <param name="requestMsg">client request message</param> /// <returns>created Binding</returns> protected Binding CreateStaticBinding(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, StaticBinding staticBinding, DhcpMessage requestMsg) { Binding binding = null; if (staticBinding != null) { binding = BuildBinding(clientLink, duid, iatype, iaid, IaAddress.STATIC); IPAddress inetAddr = staticBinding.GetInetAddress(); if (inetAddr != null) { IaAddress iaAddr = new IaAddress(); iaAddr.SetIpAddress(inetAddr); iaAddr.SetState(IaAddress.STATIC); V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, staticBinding); SetBindingObjectTimes(bindingAddr, staticBinding.GetPreferredLifetimeMs(), staticBinding.GetPreferredLifetimeMs()); // TODO store the configured options in the persisted binding? // bindingAddr.setDhcpOptions(bp.getDhcpOptions()); HashSet <BindingObject> bindingObjs = new HashSet <BindingObject>(); bindingObjs.Add(bindingAddr); binding.SetBindingObjects(bindingObjs); try { iaMgr.CreateIA(binding); } catch (Exception ex) { _log.Error("Failed to create persistent binding"); return(null); } } else { _log.Error("Failed to build binding object(s)"); return(null); } } else { _log.Error("StaticBinding object is null"); } String bindingType = (iatype == IdentityAssoc.V4_TYPE) ? "discover" : "solicit"; if (binding != null) { _log.Info("Created static " + bindingType + " binding: " + binding.ToString()); } else { _log.Warn("Failed to create static " + bindingType + " binding"); } return(binding); }
/// <summary> /// Build a BindingObject from a static binding. Because the StaticBinding /// implements the DhcpConfigObject interface, it can be used directly in /// creating the BindingObject, unlike buildBindingObject above which is /// abstract because each implementation must lookup the object in that /// binding manager's map of binding pools. /// </summary> /// <param name="inetAddr">IP address for this binding object</param> /// <param name="staticBinding">static binding</param> /// <returns>binding object</returns> protected BindingObject BuildStaticBindingObject(IPAddress inetAddr, PIXIS.DHCP.Request.Bind.StaticBinding staticBinding) { IaAddress iaAddr = new IaAddress(); iaAddr.SetIpAddress(inetAddr); V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, staticBinding); SetBindingObjectTimes(bindingAddr, staticBinding.GetPreferredLifetimeMs(), staticBinding.GetPreferredLifetimeMs()); return(bindingAddr); }
public V6BindingAddress(IaAddress iaAddr, DhcpConfigObject configObj) { // populate *this* IaAddress from the given one this.SetDhcpOptions(iaAddr.GetDhcpOptions()); this.SetId(iaAddr.GetId()); this.SetIdentityAssocId(iaAddr.GetIdentityAssocId()); this.SetIpAddress(iaAddr.GetIpAddress()); this.SetPreferredEndTime(iaAddr.GetPreferredEndTime()); this.SetStartTime(iaAddr.GetStartTime()); this.SetState(iaAddr.GetState()); this.SetValidEndTime(iaAddr.GetValidEndTime()); this.configObj = configObj; }
/// <summary> /// Decline an IaAddress. This is done when the client declines an address. /// Perform a DDNS delete just in case it was already registered, then mark /// the address as declined (unavailable). /// </summary> /// <param name="ia">iaAddr the declined IaAddress.</param> /// <param name="iaAddr">iaAddr the declined IaAddress.</param> public void DeclineIaAddress(IdentityAssoc ia, IaAddress iaAddr) { try { log.Info("Declining address: " + iaAddr.GetIpAddress().ToString()); //DdnsDelete(ia, iaAddr); iaAddr.SetStartTime(DateTime.Now); iaAddr.SetPreferredEndTime(DateTime.Now); iaAddr.SetValidEndTime(DateTime.Now); iaAddr.SetState(IaAddress.DECLINED); iaMgr.UpdateIaAddr(iaAddr); log.Info("Address declined: " + iaAddr.ToString()); } catch (Exception ex) { log.Error("Failed to decline address"); } }
/// <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); }
/** * Start expire timer task. * * @param iaAddr the ia addr * @param secsUntilExpiration the secs until expiration */ public void StartExpireTimerTask(IaAddress iaAddr, long secsUntilExpiration) { // convert delay from seconds (lifetime) --> milliseconds (delay) // reaper.schedule(new ExpireTimerTask(iaAddr), secsUntilExpiration*1000); }
/** * Perform the DDNS delete processing when a lease is released or expired. * * @param ia the IdentityAssoc of the client * @param iaAddr the released or expired IaAddress */ protected override void DdnsDelete(IdentityAssoc ia, IaAddress iaAddr) { DhcpV6ClientFqdnOption clientFqdnOption = null; try { if ((ia != null) && (iaAddr != null)) { List <DhcpOption> opts = iaAddr.GetDhcpOptions(); if (opts != null) { foreach (DhcpOption opt in opts) { if (opt.GetCode() == DhcpConstants.V6OPTION_CLIENT_FQDN) { clientFqdnOption = new DhcpV6ClientFqdnOption(); //clientFqdnOption.Decode(ByteBuffer.Wrap(opt.GetValue())); break; } } } if (clientFqdnOption != null) { string fqdn = clientFqdnOption.GetDomainName(); if (!String.IsNullOrEmpty(fqdn)) { DhcpLink link = serverConfig.FindLinkForAddress(iaAddr.GetIpAddress()); if (link != null) { V6BindingAddress bindingAddr = null; StaticBinding staticBinding = FindStaticBinding(link.GetLink(), ia.GetDuid(), ia.GetIatype(), ia.GetIaid(), null); if (staticBinding != null) { bindingAddr = BuildV6StaticBindingFromIaAddr(iaAddr, staticBinding); } else { bindingAddr = BuildV6BindingAddressFromIaAddr(iaAddr, link, null); // safe to send null requestMsg } if (bindingAddr != null) { DdnsCallback ddnsComplete = new DhcpV6DdnsComplete(bindingAddr, clientFqdnOption); DhcpConfigObject configObj = bindingAddr.GetConfigObj(); DdnsUpdater ddns = new DdnsUpdater(link.GetLink(), configObj, bindingAddr.GetIpAddress(), fqdn, ia.GetDuid(), configObj.GetValidLifetime(), clientFqdnOption.GetUpdateAaaaBit(), true, ddnsComplete); ddns.ProcessUpdates(); } else { log.Error("Failed to find binding for address: " + iaAddr.GetIpAddress().ToString()); } } else { log.Error("Failed to find link for binding address: " + iaAddr.GetIpAddress().ToString()); } } else { log.Error("FQDN is null or empty. No DDNS deletes performed."); } } else { log.Warn("No Client FQDN option in current binding. No DDNS deletes performed."); } } } catch (Exception ex) { log.Error("Failed to perform DDNS delete"); } }
/// <summary> /// Perform the DDNS delete processing when a lease is released or expired. /// </summary> /// <param name="ia">iaAddr the released or expired IaAddress </param> /// <param name="iaAddr">iaAddr the released or expired IaAddress </param> protected abstract void DdnsDelete(IdentityAssoc ia, IaAddress iaAddr);