예제 #1
0
        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();
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        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();
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        /**
         * 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");
            }
        }