/** * 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"); } }
protected void ProcessDdnsUpdates(bool sendUpdates) { DhcpV6ClientFqdnOption clientFqdnOption = ((DhcpV6ClientFqdnOption)(this.requestMsg.GetDhcpOption(DhcpConstants.V6OPTION_CLIENT_FQDN))); if ((clientFqdnOption == null)) { // TODO allow name generation? log.Debug("No Client FQDN option in request. Skipping DDNS update processing."); return; } bool includeFqdnOptionInReply = false; if (((this.requestMsg.GetRequestedOptionCodes() != null) && this.requestMsg.GetRequestedOptionCodes().Contains(DhcpConstants.V6OPTION_CLIENT_FQDN))) { // RFC 4704 section 6 says: // Servers MUST only include a Client FQDN option in ADVERTISE and REPLY // messages if the client included a Client FQDN option and the Client // FQDN option is requested by the Option Request option in the client's // message to which the server is responding. includeFqdnOptionInReply = true; } DhcpV6ClientFqdnOption replyFqdnOption = new DhcpV6ClientFqdnOption(); replyFqdnOption.SetDomainName(clientFqdnOption.GetDomainName()); replyFqdnOption.SetUpdateAaaaBit(false); replyFqdnOption.SetOverrideBit(false); replyFqdnOption.SetNoUpdateBit(false); string fqdn = clientFqdnOption.GetDomainName(); if (((fqdn == null) || (fqdn.Length <= 0))) { log.Error("Client FQDN option domain name is null/empty. No DDNS udpates performed."); if (includeFqdnOptionInReply) { replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates this.replyMsg.PutDhcpOption(replyFqdnOption); } return; } String policy = DhcpServerPolicies.EffectivePolicy(this.requestMsg, this.clientLink.GetLink(), Property.DDNS_UPDATE); log.Info(("Server configuration for ddns.update policy: " + policy)); if (((policy == null) || policy.ToLower() == "none")) { log.Info(("Server configuration for ddns.update policy is null or \'none\'." + " No DDNS updates performed.")); if (includeFqdnOptionInReply) { replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates this.replyMsg.PutDhcpOption(replyFqdnOption); } return; } if ((clientFqdnOption.GetNoUpdateBit() && policy.ToLower() == "honorNoUpdate".ToLower())) { log.Info(("Client FQDN NoUpdate flag set. Server configured to honor request." + " No DDNS updates performed.")); if (includeFqdnOptionInReply) { replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates this.replyMsg.PutDhcpOption(replyFqdnOption); } // TODO: RFC 4704 Section 6.1 // ...the server SHOULD delete any RRs that it previously added // via DNS updates for the client. return; } bool doForwardUpdate = true; if ((!clientFqdnOption.GetUpdateAaaaBit() && policy.ToLower() == "honorNoAAAA".ToLower())) { log.Info(("Client FQDN NoAAAA flag set. Server configured to honor request." + " No FORWARD DDNS updates performed.")); doForwardUpdate = false; } else { replyFqdnOption.SetUpdateAaaaBit(true); // server will do update if (!clientFqdnOption.GetUpdateAaaaBit()) { replyFqdnOption.SetOverrideBit(true); } // tell client that we overrode request flag } string domain = DhcpServerPolicies.EffectivePolicy(this.clientLink.GetLink(), Property.DDNS_DOMAIN); if (((domain != null) && domain.Count() > 0)) { log.Info(("Server configuration for domain policy: " + domain)); // if there is a configured domain, then replace the domain provide by the client int dot = fqdn.IndexOf('.'); if ((dot > 0)) { fqdn = (fqdn.Substring(0, (dot + 1)) + domain); } else { fqdn = (fqdn + ("." + domain)); } replyFqdnOption.SetDomainName(fqdn); } if (includeFqdnOptionInReply) { this.replyMsg.PutDhcpOption(replyFqdnOption); } if (sendUpdates) { foreach (Binding binding in this.bindings) { if ((binding.GetState() == Binding.COMMITTED)) { HashSet <BindingObject> bindingObjs = binding.GetBindingObjects(); if ((bindingObjs != null)) { foreach (BindingObject bindingObj in bindingObjs) { V6BindingAddress bindingAddr = ((V6BindingAddress)(bindingObj)); DhcpConfigObject configObj = bindingAddr.GetConfigObj(); DdnsCallback ddnsComplete = new DhcpV6DdnsComplete(bindingAddr, replyFqdnOption); DdnsUpdater ddns = new DdnsUpdater(this.requestMsg, this.clientLink.GetLink(), configObj, bindingAddr.GetIpAddress(), fqdn, this.requestMsg.GetDhcpClientIdOption().GetDuid(), configObj.GetValidLifetime(), doForwardUpdate, false, ddnsComplete); ddns.ProcessUpdates(); } } } } } }
public DhcpV6DdnsComplete(V6BindingAddress bindingAddr, DhcpV6ClientFqdnOption fqdnOption) { this.bindingAddr = bindingAddr; this.fqdnOption = fqdnOption; }