public override bool Process() { byte[] chAddr = _requestMsg.GetChAddr(); V4AddrBindingManager bindingMgr = _dhcpServerConfig.GetV4AddrBindingMgr(); if (bindingMgr != null) { log.Info("Processing Decline" + " from chAddr=" + Util.ToHexString(chAddr) + " requestedIp=" + requestedIpAddrOption.GetIpAddress()); Binding binding = bindingMgr.FindCurrentBinding(_clientLink, chAddr, _requestMsg); if (binding != null) { HashSet <BindingObject> bindingObjs = binding.GetBindingObjects(); if ((bindingObjs != null) && bindingObjs.Count != 0) { V4BindingAddress bindingAddr = (V4BindingAddress)bindingObjs.First(); bindingMgr.DeclineIaAddress(binding, bindingAddr); } else { log.Error("No binding addresses in binding for client: " + Util.ToHexString(chAddr)); } } else { log.Error("No Binding available for client: " + Util.ToHexString(chAddr)); } } else { log.Error("Unable to process V4 Decline:" + " No V4AddrBindingManager available"); } return(false); // no reply for v4 decline }
protected void ProcessDdnsUpdates(bool sendUpdates) { bool doForwardUpdate = true; DhcpV4ClientFqdnOption clientFqdnOption = (DhcpV4ClientFqdnOption)_requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_CLIENT_FQDN); DhcpV4HostnameOption hostnameOption = (DhcpV4HostnameOption)_requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_HOSTNAME); if (clientFqdnOption == null && hostnameOption == null) { //TODO allow name generation? log.Debug("No Client FQDN nor hostname option in request. Skipping DDNS update processing."); return; } string fqdn = ""; string domain = DhcpServerPolicies.DffectivePolicy(_clientLink.GetLink(), Property.DDNS_DOMAIN); DhcpV4ClientFqdnOption replyFqdnOption = null; if (clientFqdnOption != null) { replyFqdnOption = new DhcpV4ClientFqdnOption(); replyFqdnOption.SetDomainName(clientFqdnOption.GetDomainName()); replyFqdnOption.SetUpdateABit(false); replyFqdnOption.SetOverrideBit(false); replyFqdnOption.SetNoUpdateBit(false); replyFqdnOption.SetEncodingBit(clientFqdnOption.GetEncodingBit()); replyFqdnOption.SetRcode1((short)0xff); // RFC 4702 says server should set to 255 replyFqdnOption.SetRcode2((short)0xff); // RFC 4702 says server should set to 255 fqdn = clientFqdnOption.GetDomainName(); if ((fqdn == null) || (fqdn.Length <= 0)) { log.Error("Client FQDN option domain name is null/empty. No DDNS udpates performed."); replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates _replyMsg.PutDhcpOption(replyFqdnOption); return; } string policy = DhcpServerPolicies.EffectivePolicy(_requestMsg, _clientLink.GetLink(), Property.DDNS_UPDATE); log.Info("Server configuration for ddns.update policy: " + policy); if ((policy == null) || policy.Contains("none")) { log.Info("Server configuration for ddns.update policy is null or 'none'." + " No DDNS updates performed."); replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates _replyMsg.PutDhcpOption(replyFqdnOption); return; } if (clientFqdnOption.GetNoUpdateBit() && policy.Contains("honorNoUpdate")) { log.Info("Client FQDN NoUpdate flag set. Server configured to honor request." + " No DDNS updates performed."); replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates _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; } if (!clientFqdnOption.GetUpdateABit() && policy.Contains("honorNoA")) { log.Info("Client FQDN NoA flag set. Server configured to honor request." + " No FORWARD DDNS updates performed."); doForwardUpdate = false; } else { replyFqdnOption.SetUpdateABit(true); // server will do update if (!clientFqdnOption.GetUpdateABit()) { replyFqdnOption.SetOverrideBit(true); // tell client that we overrode request flag } } if (!String.IsNullOrEmpty(domain)) { 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); } // since the client DID send option 81, return it in the reply _replyMsg.PutDhcpOption(replyFqdnOption); } else { // The client did not send an FQDN option, so we'll try to formulate the FQDN // from the hostname option combined with the DDNS_DOMAIN policy setting. // A replyFqdnOption is fabricated to be stored with the binding for use // with the release/expire binding processing to remove the DDNS entry. replyFqdnOption = new DhcpV4ClientFqdnOption(); fqdn = hostnameOption.GetString(); if (!String.IsNullOrEmpty(domain)) { log.Info("Server configuration for domain policy: " + domain); fqdn = fqdn + "." + domain; // since the client did NOT send option 81, do not put // the fabricated fqdnOption into the reply packet // but set the option so that is can be used below // when storing the fqdnOption to the database, so // that it can be used if/when the lease expires replyFqdnOption.SetDomainName(fqdn); // server will do the A record update, so set the flag // for the option stored in the database, so server will // remove the A record when the lease expires replyFqdnOption.SetUpdateABit(true); } else { log.Error("No DDNS domain configured. No DDNS udpates performed."); replyFqdnOption.SetNoUpdateBit(true); // tell client that server did no updates _replyMsg.PutDhcpOption(replyFqdnOption); return; } } if (sendUpdates) { foreach (Binding binding in _bindings) { if (binding.GetState() == Binding.COMMITTED) { HashSet <BindingObject> bindingObjs = binding.GetBindingObjects(); if (bindingObjs != null) { foreach (var bindingObj in bindingObjs) { V4BindingAddress bindingAddr = (V4BindingAddress)bindingObj; DhcpConfigObject configObj = bindingAddr.GetConfigObj(); DdnsCallback ddnsComplete = new DhcpV4DdnsComplete(bindingAddr, replyFqdnOption); DdnsUpdater ddns = new DdnsUpdater(_requestMsg, _clientLink.GetLink(), configObj, bindingAddr.GetIpAddress(), fqdn, _requestMsg.GetChAddr(), configObj.GetValidLifetime(), doForwardUpdate, false, ddnsComplete); ddns.ProcessUpdates(); } } } } } }
public DhcpV4DdnsComplete(V4BindingAddress bindingAddr, DhcpV4ClientFqdnOption replyFqdnOption) { _bindingAddr = bindingAddr; _fqdnOption = replyFqdnOption; }