From c9fd2e6c47eabb9044e37d29476367d3b5ce68ea Mon Sep 17 00:00:00 2001 From: Alvar Penning Date: Thu, 5 Sep 2019 11:01:40 +0200 Subject: [PATCH] TCPCL: Keepalive/Session Upkeep Message --- cla/tcpcl/message_keepalive.go | 44 +++++++++++++++++++++++++++++ cla/tcpcl/message_keepalive_test.go | 35 +++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 cla/tcpcl/message_keepalive.go create mode 100644 cla/tcpcl/message_keepalive_test.go diff --git a/cla/tcpcl/message_keepalive.go b/cla/tcpcl/message_keepalive.go new file mode 100644 index 00000000..317e887f --- /dev/null +++ b/cla/tcpcl/message_keepalive.go @@ -0,0 +1,44 @@ +package tcpcl + +import "fmt" + +// KEEPALIVE is the Message Header code for a Keepalive Message. +const KEEPALIVE uint8 = 0x04 + +// KeepaliveMessage is the KEEPALIVE message for session upkeep. +type KeepaliveMessage uint8 + +// NewKeepaliveMessage creates a new KeepaliveMessage. +func NewKeepaliveMessage() KeepaliveMessage { + return KeepaliveMessage(KEEPALIVE) +} + +func (_ KeepaliveMessage) String() string { + return "KEEPALIVE" +} + +// MarshalBinary encodes this KeepaliveMessage into its binary form. +func (km KeepaliveMessage) MarshalBinary() (data []byte, err error) { + if uint8(km) != KEEPALIVE { + err = fmt.Errorf("KEEPALIVE's value is %d instead of %d", uint8(km), KEEPALIVE) + return + } + + data = []byte{KEEPALIVE} + return +} + +// UnmarshalBinary decodes a KeepaliveMessage from its binary form. +func (km *KeepaliveMessage) UnmarshalBinary(data []byte) error { + if len(data) != 1 { + return fmt.Errorf("KEEPALIVE's octet length is %d instead of 1", len(data)) + } + + if x := uint8(data[0]); x != KEEPALIVE { + return fmt.Errorf("KEEPALIVE's value is %d instead of %d", x, KEEPALIVE) + } else { + *km = KeepaliveMessage(x) + } + + return nil +} diff --git a/cla/tcpcl/message_keepalive_test.go b/cla/tcpcl/message_keepalive_test.go new file mode 100644 index 00000000..0287a79d --- /dev/null +++ b/cla/tcpcl/message_keepalive_test.go @@ -0,0 +1,35 @@ +package tcpcl + +import ( + "bytes" + "testing" +) + +func TestKeepaliveMessage(t *testing.T) { + tests := []struct { + valid bool + data []byte + }{ + {true, []byte{KEEPALIVE}}, + {false, []byte{0x21}}, + {false, []byte{}}, + {false, []byte{0x23, 0x42}}, + } + + for _, test := range tests { + var km KeepaliveMessage + + if err := km.UnmarshalBinary(test.data); (err == nil) != test.valid { + t.Fatalf("Error state was not expected; valid := %t, got := %v", test.valid, err) + } else if !test.valid { + continue + } + + if data, err := NewKeepaliveMessage().MarshalBinary(); err != nil { + t.Fatal(err) + } else if !bytes.Equal(data, test.data) { + t.Fatalf("Data does not match, expected %x and got %x", test.data, data) + } + + } +}