From 2ecf202a098f82731efe88ed625a463913309124 Mon Sep 17 00:00:00 2001 From: Andrea Barberio Date: Thu, 2 May 2019 16:28:30 +0100 Subject: [dhcpv6] Handle SOLICIT with rapid commit in NewReplyFromMessage NewReplyFromMessage creates a reply from a message. With this patch it can handle Solicit messages with rapid-commit. RFC3315 states that: ``` If the client has included a Rapid Commit option in its Solicit message, the client terminates the waiting process as soon as a Reply message with a Rapid Commit option is received. ``` Signed-off-by: Andrea Barberio --- dhcpv6/dhcpv6_test.go | 6 ++++++ dhcpv6/dhcpv6message.go | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'dhcpv6') diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index 10a7296..5de2294 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -195,6 +195,12 @@ func TestNewReplyFromMessage(t *testing.T) { msg.MessageType = MessageTypeSolicit rep, err = NewReplyFromMessage(&msg) require.Error(t, err) + + msg.MessageType = MessageTypeSolicit + msg.AddOption(&OptionGeneric{OptionCode: OptionRapidCommit}) + rep, err = NewReplyFromMessage(&msg) + require.NoError(t, err) + msg.Options.Del(OptionRapidCommit) } func TestNewMessageTypeSolicit(t *testing.T) { diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 707a65d..f4f5eb1 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -161,17 +161,23 @@ func NewRequestFromAdvertise(adv *Message, modifiers ...Modifier) (*Message, err } // NewReplyFromMessage creates a new REPLY packet based on a -// Message. The function is to be used when generating a reply to -// REQUEST, CONFIRM, RENEW, REBIND, RELEASE and INFORMATION-REQUEST packets. +// Message. The function is to be used when generating a reply to a SOLICIT with +// rapid-commit, REQUEST, CONFIRM, RENEW, REBIND, RELEASE and INFORMATION-REQUEST +// packets. func NewReplyFromMessage(msg *Message, modifiers ...Modifier) (*Message, error) { if msg == nil { - return nil, errors.New("Message cannot be nil") + return nil, errors.New("message cannot be nil") } switch msg.Type() { + case MessageTypeSolicit: + if msg.GetOneOption(OptionRapidCommit) == nil { + return nil, errors.New("cannot create REPLY from a SOLICIT without rapid-commit option") + } + modifiers = append([]Modifier{WithRapidCommit}, modifiers...) case MessageTypeRequest, MessageTypeConfirm, MessageTypeRenew, MessageTypeRebind, MessageTypeRelease, MessageTypeInformationRequest: default: - return nil, errors.New("Cannot create REPLY from the passed message type set") + return nil, errors.New("cannot create REPLY from the passed message type set") } // build REPLY from MESSAGE -- cgit v1.2.3