From 2ce044a2350cca73e015aff54c75f22eeade5b30 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Tue, 16 Jul 2024 19:18:45 +0200 Subject: [PATCH] Customizable values for retransmission Close #22 --- pfcp/api/entity_interface.go | 1 + pfcp/api/entity_options_interface.go | 12 +++++++ pfcp/entity.go | 8 ++++- pfcp/entity_cp.go | 7 +++-- pfcp/entity_options.go | 47 ++++++++++++++++++++++++++++ pfcp/entity_up.go | 6 +++- pfcp/peer.go | 4 +-- 7 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 pfcp/api/entity_options_interface.go create mode 100644 pfcp/entity_options.go diff --git a/pfcp/api/entity_interface.go b/pfcp/api/entity_interface.go index 65d6204..c7e1f97 100644 --- a/pfcp/api/entity_interface.go +++ b/pfcp/api/entity_interface.go @@ -24,4 +24,5 @@ type PFCPEntityInterface interface { GetPFCPSession(localIP string, seid SEID) (PFCPSessionInterface, error) AddEstablishedPFCPSession(session PFCPSessionInterface) error PrintPFCPRules() + Options() EntityOptionsInterface } diff --git a/pfcp/api/entity_options_interface.go b/pfcp/api/entity_options_interface.go new file mode 100644 index 0000000..f5997de --- /dev/null +++ b/pfcp/api/entity_options_interface.go @@ -0,0 +1,12 @@ +// Copyright 2024 Louis Royer and the go-pfcp-networking contributors. All rights reserved. +// Use of this source code is governed by a MIT-style license that can be +// found in the LICENSE file. +// SPDX-License-Identifier: MIT +package api + +import "time" + +type EntityOptionsInterface interface { + MessageRetransmissionN1() int + MessageRetransmissionT1() time.Duration +} diff --git a/pfcp/entity.go b/pfcp/entity.go index 75da8ca..bc9a020 100644 --- a/pfcp/entity.go +++ b/pfcp/entity.go @@ -31,6 +31,11 @@ type PFCPEntity struct { // CP function send them to UP functions sessionsMap api.SessionsMapInterface kind string // "CP" or "UP" + options EntityOptions +} + +func (e *PFCPEntity) Options() api.EntityOptionsInterface { + return e.options } // Add an Established PFCP Session @@ -68,7 +73,7 @@ func newDefaultPFCPEntityHandlers() map[pfcputil.MessageType]PFCPMessageHandler return m } -func NewPFCPEntity(nodeID string, kind string) PFCPEntity { +func NewPFCPEntity(nodeID string, kind string, options EntityOptions) PFCPEntity { return PFCPEntity{ nodeID: ie.NewNodeIDHeuristic(nodeID), recoveryTimeStamp: nil, @@ -78,6 +83,7 @@ func NewPFCPEntity(nodeID string, kind string) PFCPEntity { associationsMap: NewAssociationsMap(), sessionsMap: NewSessionsMap(), kind: kind, + options: options, } } diff --git a/pfcp/entity_cp.go b/pfcp/entity_cp.go index 34e5340..77bddc2 100644 --- a/pfcp/entity_cp.go +++ b/pfcp/entity_cp.go @@ -10,6 +10,9 @@ type PFCPEntityCP struct { } func NewPFCPEntityCP(nodeID string) *PFCPEntityCP { - e := PFCPEntityCP{PFCPEntity: NewPFCPEntity(nodeID, "CP")} - return &e + return NewPFCPEntityCPWithOptions(nodeID, EntityOptions{}) +} + +func NewPFCPEntityCPWithOptions(nodeID string, options EntityOptions) *PFCPEntityCP { + return &PFCPEntityCP{PFCPEntity: NewPFCPEntity(nodeID, "CP", options)} } diff --git a/pfcp/entity_options.go b/pfcp/entity_options.go new file mode 100644 index 0000000..816e369 --- /dev/null +++ b/pfcp/entity_options.go @@ -0,0 +1,47 @@ +// Copyright 2024 Louis Royer and the go-pfcp-networking contributors. All rights reserved. +// Use of this source code is governed by a MIT-style license that can be +// found in the LICENSE file. +// SPDX-License-Identifier: MIT + +package pfcp_networking + +import ( + "fmt" + "time" + + "github.com/nextmn/go-pfcp-networking/pfcputil" +) + +type EntityOptions struct { + messageRetransmissionT1 *time.Duration + messageRetransmissionN1 *int +} + +func NewEntityOptions(messageRetransmissionT1 *time.Duration, messageRetransmissionN1 *int) (*EntityOptions, error) { + if (messageRetransmissionT1 != nil) && (*messageRetransmissionT1 < 1*time.Microsecond) { + return nil, fmt.Errorf("messageRetransmissionT1 must be strictly greater than zero.") + } + if (messageRetransmissionN1 != nil) && (*messageRetransmissionN1 < 0) { + return nil, fmt.Errorf("messageRetransmissionN1 must be greater than zero") + } + return &EntityOptions{ + messageRetransmissionT1: messageRetransmissionT1, + messageRetransmissionN1: messageRetransmissionN1, + }, nil +} + +func (eo EntityOptions) MessageRetransmissionT1() time.Duration { + if eo.messageRetransmissionT1 != nil { + return *eo.messageRetransmissionT1 + } else { + return pfcputil.MESSAGE_RETRANSMISSION_T1 + } +} + +func (eo EntityOptions) MessageRetransmissionN1() int { + if eo.messageRetransmissionN1 != nil { + return *eo.messageRetransmissionN1 + } else { + return pfcputil.MESSAGE_RETRANSMISSION_N1 + } +} diff --git a/pfcp/entity_up.go b/pfcp/entity_up.go index 63c2e58..1d2ce13 100644 --- a/pfcp/entity_up.go +++ b/pfcp/entity_up.go @@ -16,7 +16,11 @@ type PFCPEntityUP struct { } func NewPFCPEntityUP(nodeID string) *PFCPEntityUP { - e := PFCPEntityUP{PFCPEntity: NewPFCPEntity(nodeID, "UP")} + return NewPFCPEntityUPWithOptions(nodeID, EntityOptions{}) +} + +func NewPFCPEntityUPWithOptions(nodeID string, options EntityOptions) *PFCPEntityUP { + e := PFCPEntityUP{PFCPEntity: NewPFCPEntity(nodeID, "UP", options)} err := e.initDefaultHandlers() if err != nil { log.Println(err) diff --git a/pfcp/peer.go b/pfcp/peer.go index 6602214..9118818 100644 --- a/pfcp/peer.go +++ b/pfcp/peer.go @@ -211,7 +211,7 @@ func (peer *PFCPPeer) Send(msg message.Message) (m message.Message, err error) { return nil, fmt.Errorf("Error on write: %s\n", err) } - for i := 0; i < pfcputil.MESSAGE_RETRANSMISSION_N1; i++ { + for i := 0; i < peer.LocalEntity().Options().MessageRetransmissionN1(); i++ { select { case r := <-ch: msg, err := message.Parse(r) @@ -222,7 +222,7 @@ func (peer *PFCPPeer) Send(msg message.Message) (m message.Message, err error) { return nil, fmt.Errorf("Unexpected incomming PFCP message type") } return msg, nil - case <-time.After(pfcputil.MESSAGE_RETRANSMISSION_T1): + case <-time.After(peer.LocalEntity().Options().MessageRetransmissionT1()): // retry _, err = peer.conn.WriteToUDP(b, peer.udpAddr) if err != nil {