/// <summary> /// Find the current binding, if any, for the given client identity association (IA). /// </summary> /// <param name="clientLink">link for the client request message</param> /// <param name="duid">DUID of the client</param> /// <param name="iatype">the IAID of the client request</param> /// <param name="iaid"> IAID of the client request</param> /// <param name="requestMsg">requestMsg the client request message</param> /// <returns>return the existing Binding for this client request</returns> protected Binding FindCurrentBinding(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, DhcpMessage requestMsg) { Binding binding = null; lock (_lock) { try { IdentityAssoc ia = iaMgr.FindIA(duid, iatype, iaid); if (ia != null) { _log.Info("Found current binding for " + IdentityAssoc.KeyToString(duid, iatype, iaid) + " state=" + ia.GetState()); binding = BuildBindingFromIa(ia, clientLink, requestMsg); if (binding != null) { _log.Info("Successfully built Binding object: " + binding); } else { _log.Error("Failed to build Binding object"); } } else { _log.Info("No current binding found for " + IdentityAssoc.KeyToString(duid, iatype, iaid)); } } catch (Exception ex) { _log.Error("Failed to find current binding"); } } return(binding); }
/// <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); }