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); }