Пример #1
0
        public override bool Process()
        {
            //            When the server receives a Decline message via unicast from a client
            //            to which the server has not sent a unicast option, the server
            //            discards the Decline message and responds with a Reply message
            //            containing a Status Code option with the value UseMulticast, a Server
            //            Identifier option containing the server's DUID, the Client Identifier
            //            option from the client message, and no other options.
            if (ShouldMulticast())
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                SetReplyStatus(DhcpConstants.V6STATUS_CODE_USEMULTICAST);
                return(true);
            }

            //            Upon the receipt of a valid Decline message, the server examines the
            //            IAs and the addresses in the IAs for validity.  If the IAs in the
            //            message are in a binding for the client, and the addresses in the IAs
            //            have been assigned by the server to those IAs, the server deletes the
            //            addresses from the IAs.  The server ignores addresses not assigned to
            //            the IA (though it may choose to log an error if it finds such an
            //            address).
            //
            //            The client has found any addresses in the Decline messages to be
            //            already in use on its link.  Therefore, the server SHOULD mark the
            //            addresses declined by the client so that those addresses are not
            //            assigned to other clients, and MAY choose to make a notification that
            //            addresses were declined.  Local policy on the server determines when
            //            the addresses identified in a Decline message may be made available
            //            for assignment.
            //
            //            After all the addresses have been processed, the server generates a
            //            Reply message and includes a Status Code option with the value
            //            Success, a Server Identifier option with the server's DUID, and a
            //            Client Identifier option with the client's DUID.  For each IA in the
            //            Decline message for which the server has no binding information, the
            //            server adds an IA option using the IAID from the Release message and
            //            includes a Status Code option with the value NoBinding in the IA
            //            option.  No other options are included in the IA option.
            bool sendReply = true;
            DhcpV6ClientIdOption    clientIdOption = requestMsg.GetDhcpClientIdOption();
            List <DhcpV6IaNaOption> iaNaOptions    = requestMsg.GetIaNaOptions();

            if (((iaNaOptions != null) &&
                 iaNaOptions.Count > 0))
            {
                V6NaAddrBindingManager bindingMgr = dhcpServerConfig.GetNaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaNaOption dhcpIaNaOption in iaNaOptions)
                    {
                        log.Info(("Processing IA_NA Decline: " + dhcpIaNaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaNaOption, requestMsg);
                        if ((binding != null))
                        {
                            HashSet <BindingObject> bindingObjs = binding.GetBindingObjects();
                            if (((bindingObjs != null) &&
                                 bindingObjs.Count > 0))
                            {
                                foreach (BindingObject bindingObj in bindingObjs)
                                {
                                    bindingMgr.DeclineIaAddress(binding, ((V6BindingAddress)(bindingObj)));
                                }
                            }
                        }
                        else
                        {
                            AddIaNaOptionStatusToReply(dhcpIaNaOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_NA Decline:" + " No NaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaTaOption> iaTaOptions = requestMsg.GetIaTaOptions();

            if (((iaTaOptions != null) &&
                 iaTaOptions.Count > 0))
            {
                V6TaAddrBindingManager bindingMgr = dhcpServerConfig.GetTaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaTaOption dhcpIaTaOption in iaTaOptions)
                    {
                        log.Info(("Processing IA_TA Decline: " + dhcpIaTaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaTaOption, requestMsg);
                        if ((binding != null))
                        {
                            HashSet <BindingObject> bindingObjs = binding.GetBindingObjects();
                            if (((bindingObjs != null) &&
                                 bindingObjs.Count > 0))
                            {
                                foreach (BindingObject bindingObj in bindingObjs)
                                {
                                    bindingMgr.DeclineIaAddress(binding, ((V6BindingAddress)(bindingObj)));
                                }
                            }
                        }
                        else
                        {
                            AddIaTaOptionStatusToReply(dhcpIaTaOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_TA Decline:" + " No TaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaPdOption> iaPdOptions = requestMsg.GetIaPdOptions();

            if (((iaPdOptions != null) &&
                 iaPdOptions.Count > 0))
            {
                V6PrefixBindingManager bindingMgr = dhcpServerConfig.GetPrefixBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaPdOption dhcpIaPdOption in iaPdOptions)
                    {
                        log.Info(("Processing IA_PD Decline: " + dhcpIaPdOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaPdOption, requestMsg);
                        if ((binding != null))
                        {
                            HashSet <BindingObject> bindingObjs = binding.GetBindingObjects();
                            if (((bindingObjs != null) &&
                                 bindingObjs.Count > 0))
                            {
                                foreach (BindingObject bindingObj in bindingObjs)
                                {
                                    bindingMgr.DeclineIaPrefix(((V6BindingPrefix)(bindingObj)));
                                }
                            }
                        }
                        else
                        {
                            AddIaPdOptionStatusToReply(dhcpIaPdOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_PD Decline:" + " No PrefixBindingManager available"));
                }
            }

            if (sendReply)
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                SetReplyStatus(DhcpConstants.V6STATUS_CODE_SUCCESS);
            }

            return(sendReply);
        }
        public override bool Process()
        {
            //            If the server cannot find a client entry for the IA and the server
            //            determines that the addresses in the IA are not appropriate for the
            //            link to which the client's interface is attached according to the
            //            server's explicit configuration information, the server MAY send a
            //            Reply message to the client containing the client's IA, with the
            //            lifetimes for the addresses in the IA set to zero.  This Reply
            //            constitutes an explicit notification to the client that the addresses
            //            in the IA are no longer valid.  In this situation, if the server does
            //            not send a Reply message it silently discards the Rebind message.
            //
            //            If the server finds that any of the addresses are no longer
            //            appropriate for the link to which the client is attached, the server
            //            returns the address to the client with lifetimes of 0.
            //
            //            If the server finds the addresses in the IA for the client then the
            //            server SHOULD send back the IA to the client with new lifetimes and
            //            T1/T2 times.
            bool sendReply = true;
            DhcpV6ClientIdOption    clientIdOption = requestMsg.GetDhcpClientIdOption();
            List <DhcpV6IaNaOption> iaNaOptions    = requestMsg.GetIaNaOptions();

            if (((iaNaOptions != null) &&
                 iaNaOptions.Count > 0))
            {
                V6NaAddrBindingManager bindingMgr = dhcpServerConfig.GetNaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaNaOption dhcpIaNaOption in iaNaOptions)
                    {
                        log.Info(("Processing IA_NA Rebind: " + dhcpIaNaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaNaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaNaOption, clientLink))
                            {
                                replyMsg.AddIaNaOption(dhcpIaNaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaNaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaNaOptionStatusToReply(dhcpIaNaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaAddrsOnLink(dhcpIaNaOption, clientLink);
                            replyMsg.AddIaNaOption(dhcpIaNaOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_NA Rebind:" + " No NaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaTaOption> iaTaOptions = requestMsg.GetIaTaOptions();

            if (((iaTaOptions != null) &&
                 iaTaOptions.Count > 0))
            {
                V6TaAddrBindingManager bindingMgr = dhcpServerConfig.GetTaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaTaOption dhcpIaTaOption in iaTaOptions)
                    {
                        log.Info(("Processing IA_TA Rebind: " + dhcpIaTaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaTaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaTaOption, clientLink))
                            {
                                replyMsg.AddIaTaOption(dhcpIaTaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaTaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaTaOptionStatusToReply(dhcpIaTaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaAddrsOnLink(dhcpIaTaOption, clientLink);
                            replyMsg.AddIaTaOption(dhcpIaTaOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_TA Rebind:" + " No TaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaPdOption> iaPdOptions = requestMsg.GetIaPdOptions();

            if (((iaPdOptions != null) &&
                 iaPdOptions.Count > 0))
            {
                V6PrefixBindingManager bindingMgr = dhcpServerConfig.GetPrefixBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaPdOption dhcpIaPdOption in iaPdOptions)
                    {
                        log.Info(("Processing IA_PD Rebind: " + dhcpIaPdOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaPdOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaPrefixesOnLink(dhcpIaPdOption, clientLink))
                            {
                                replyMsg.AddIaPdOption(dhcpIaPdOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaPdOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaPdOptionStatusToReply(dhcpIaPdOption, DhcpConstants.V6STATUS_CODE_NOPREFIXAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaPrefixesOnLink(dhcpIaPdOption, clientLink);
                            replyMsg.AddIaPdOption(dhcpIaPdOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_PD Rebind:" + " No PrefixBindingManager available"));
                }
            }

            if ((bindings.Count == 0 &&
                 !DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND)))
            {
                sendReply = false;
            }

            if (sendReply)
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                if (bindings.Count == 0)
                {
                    PopulateReplyMsgOptions(clientLink);
                    ProcessDdnsUpdates(true);
                }
            }

            return(sendReply);
        }
        public override bool Process()
        {
            //       When the server receives a Renew message via unicast from a client
            //       to which the server has not sent a unicast option, the server
            //       discards the Request message and responds with a Reply message
            //       containing a Status Code option with the value UseMulticast, a Server
            //       Identifier option containing the server's DUID, the Client Identifier
            //       option from the client message, and no other options.
            if (ShouldMulticast())
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                SetReplyStatus(DhcpConstants.V6STATUS_CODE_USEMULTICAST);
                return(true);
            }

            //         If the server cannot find a client entry for the IA the server
            //         returns the IA containing no addresses with a Status Code option set
            //         to NoBinding in the Reply message.
            //
            //         If the server finds that any of the addresses are not appropriate for
            //         the link to which the client is attached, the server returns the
            //         address to the client with lifetimes of 0.
            //
            //         If the server finds the addresses in the IA for the client then the
            //         server sends back the IA to the client with new lifetimes and T1/T2
            //         times.  The server may choose to change the list of addresses and the
            //         lifetimes of addresses in IAs that are returned to the client.
            bool sendReply = true;
            DhcpV6ClientIdOption    clientIdOption = requestMsg.GetDhcpClientIdOption();
            List <DhcpV6IaNaOption> iaNaOptions    = requestMsg.GetIaNaOptions();

            if (((iaNaOptions != null) &&
                 iaNaOptions.Count > 0))
            {
                V6NaAddrBindingManager bindingMgr = dhcpServerConfig.GetNaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaNaOption dhcpIaNaOption in iaNaOptions)
                    {
                        log.Info(("Processing IA_NA Renew: " + dhcpIaNaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaNaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaNaOption, clientLink))
                            {
                                replyMsg.AddIaNaOption(dhcpIaNaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaNaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaNaOptionStatusToReply(dhcpIaNaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else
                        {
                            AddIaNaOptionStatusToReply(dhcpIaNaOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_NA Renew:" + " No NaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaTaOption> iaTaOptions = requestMsg.GetIaTaOptions();

            if (((iaTaOptions != null) &&
                 iaTaOptions.Count > 0))
            {
                V6TaAddrBindingManager bindingMgr = dhcpServerConfig.GetTaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaTaOption dhcpIaTaOption in iaTaOptions)
                    {
                        log.Info(("Processing IA_TA Renew: " + dhcpIaTaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaTaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaTaOption, clientLink))
                            {
                                replyMsg.AddIaTaOption(dhcpIaTaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaTaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaTaOptionStatusToReply(dhcpIaTaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else
                        {
                            AddIaTaOptionStatusToReply(dhcpIaTaOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_TA Renew:" + " No TaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaPdOption> iaPdOptions = requestMsg.GetIaPdOptions();

            if (((iaPdOptions != null) &&
                 iaPdOptions.Count > 0))
            {
                V6PrefixBindingManager bindingMgr = dhcpServerConfig.GetPrefixBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaPdOption dhcpIaPdOption in iaPdOptions)
                    {
                        log.Info(("Processing IA_PD Renew: " + dhcpIaPdOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaPdOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaPrefixesOnLink(dhcpIaPdOption, clientLink))
                            {
                                replyMsg.AddIaPdOption(dhcpIaPdOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaPdOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaPdOptionStatusToReply(dhcpIaPdOption, DhcpConstants.V6STATUS_CODE_NOPREFIXAVAIL);
                                }
                            }
                        }
                        else
                        {
                            AddIaPdOptionStatusToReply(dhcpIaPdOption, DhcpConstants.V6STATUS_CODE_NOBINDING);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_PD Renew:" + " No PrefixBindingManager available"));
                }
            }

            if (sendReply)
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                if (bindings.Count > 0)
                {
                    PopulateReplyMsgOptions(clientLink);
                    ProcessDdnsUpdates(true);
                }
                else
                {
                    log.Warn("Reply message has no bindings");
                }
            }

            return(sendReply);
        }