Skip to content

Commit 5b7066f

Browse files
committed
feat: split keepalive protocol into client and server
Fixes #118
1 parent 82d0663 commit 5b7066f

File tree

5 files changed

+142
-112
lines changed

5 files changed

+142
-112
lines changed

ouroboros.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ func (o *Ouroboros) setupConnection() error {
171171
o.TxSubmission = txsubmission.New(protoOptions, o.txSubmissionConfig)
172172
if versionNtN.EnableKeepAliveProtocol {
173173
o.KeepAlive = keepalive.New(protoOptions, o.keepAliveConfig)
174-
if o.sendKeepAlives {
175-
o.KeepAlive.Start()
174+
if !o.server && o.sendKeepAlives {
175+
o.KeepAlive.Client.Start()
176176
}
177177
}
178178
} else {

protocol/handshake/handshake.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,3 @@ func New(protoOptions protocol.ProtocolOptions, cfg *Config) *Handshake {
6767
}
6868
return h
6969
}
70-
71-
/*
72-
func (h *Handshake) Start() {
73-
h.Protocol.Start()
74-
}
75-
76-
func (h *Handshake) ProposeVersions() error {
77-
// Create our request
78-
versionMap := make(map[uint16]interface{})
79-
diffusionMode := DIFFUSION_MODE_INITIATOR_ONLY
80-
if h.config.ClientFullDuplex {
81-
diffusionMode = DIFFUSION_MODE_INITIATOR_AND_RESPONDER
82-
}
83-
for _, version := range h.config.ProtocolVersions {
84-
if h.Mode() == protocol.ProtocolModeNodeToNode {
85-
versionMap[version] = []interface{}{h.config.NetworkMagic, diffusionMode}
86-
} else {
87-
versionMap[version] = h.config.NetworkMagic
88-
}
89-
}
90-
msg := NewMsgProposeVersions(versionMap)
91-
return h.SendMessage(msg)
92-
}
93-
*/

protocol/keepalive/client.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package keepalive
2+
3+
import (
4+
"fmt"
5+
"github.com/cloudstruct/go-ouroboros-network/protocol"
6+
"time"
7+
)
8+
9+
type Client struct {
10+
*protocol.Protocol
11+
config *Config
12+
timer *time.Timer
13+
}
14+
15+
func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client {
16+
c := &Client{
17+
config: cfg,
18+
}
19+
protoConfig := protocol.ProtocolConfig{
20+
Name: PROTOCOL_NAME,
21+
ProtocolId: PROTOCOL_ID,
22+
Muxer: protoOptions.Muxer,
23+
ErrorChan: protoOptions.ErrorChan,
24+
Mode: protoOptions.Mode,
25+
Role: protocol.ProtocolRoleClient,
26+
MessageHandlerFunc: c.messageHandler,
27+
MessageFromCborFunc: NewMsgFromCbor,
28+
StateMap: StateMap,
29+
InitialState: STATE_CLIENT,
30+
}
31+
c.Protocol = protocol.New(protoConfig)
32+
return c
33+
}
34+
35+
func (c *Client) Start() {
36+
c.Protocol.Start()
37+
c.startTimer()
38+
}
39+
40+
func (c *Client) startTimer() {
41+
c.timer = time.AfterFunc(KEEP_ALIVE_PERIOD*time.Second, func() {
42+
msg := NewMsgKeepAlive(0)
43+
if err := c.SendMessage(msg); err != nil {
44+
c.SendError(err)
45+
}
46+
})
47+
}
48+
49+
func (c *Client) messageHandler(msg protocol.Message, isResponse bool) error {
50+
var err error
51+
switch msg.Type() {
52+
case MESSAGE_TYPE_KEEP_ALIVE_RESPONSE:
53+
err = c.handleKeepAliveResponse(msg)
54+
default:
55+
err = fmt.Errorf("%s: received unexpected message type %d", PROTOCOL_NAME, msg.Type())
56+
}
57+
return err
58+
}
59+
60+
func (c *Client) handleKeepAliveResponse(msgGeneric protocol.Message) error {
61+
msg := msgGeneric.(*MsgKeepAliveResponse)
62+
// Start the timer again if we had one previously
63+
if c.timer != nil {
64+
defer c.startTimer()
65+
}
66+
if c.config != nil && c.config.KeepAliveResponseFunc != nil {
67+
// Call the user callback function
68+
return c.config.KeepAliveResponseFunc(msg.Cookie)
69+
}
70+
return nil
71+
}

protocol/keepalive/keepalive.go

Lines changed: 5 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package keepalive
22

33
import (
4-
"fmt"
54
"github.com/cloudstruct/go-ouroboros-network/protocol"
6-
"time"
75
)
86

97
const (
@@ -49,9 +47,8 @@ var StateMap = protocol.StateMap{
4947
}
5048

5149
type KeepAlive struct {
52-
*protocol.Protocol
53-
config *Config
54-
timer *time.Timer
50+
Client *Client
51+
Server *Server
5552
}
5653

5754
type Config struct {
@@ -65,88 +62,10 @@ type KeepAliveFunc func(uint16) error
6562
type KeepAliveResponseFunc func(uint16) error
6663
type DoneFunc func() error
6764

68-
func New(options protocol.ProtocolOptions, cfg *Config) *KeepAlive {
65+
func New(protoOptions protocol.ProtocolOptions, cfg *Config) *KeepAlive {
6966
k := &KeepAlive{
70-
config: cfg,
67+
Client: NewClient(protoOptions, cfg),
68+
Server: NewServer(protoOptions, cfg),
7169
}
72-
protoConfig := protocol.ProtocolConfig{
73-
Name: PROTOCOL_NAME,
74-
ProtocolId: PROTOCOL_ID,
75-
Muxer: options.Muxer,
76-
ErrorChan: options.ErrorChan,
77-
Mode: options.Mode,
78-
Role: options.Role,
79-
MessageHandlerFunc: k.messageHandler,
80-
MessageFromCborFunc: NewMsgFromCbor,
81-
StateMap: StateMap,
82-
InitialState: STATE_CLIENT,
83-
}
84-
k.Protocol = protocol.New(protoConfig)
8570
return k
8671
}
87-
88-
func (k *KeepAlive) Start() {
89-
k.Protocol.Start()
90-
k.startTimer()
91-
}
92-
93-
func (k *KeepAlive) messageHandler(msg protocol.Message, isResponse bool) error {
94-
var err error
95-
switch msg.Type() {
96-
case MESSAGE_TYPE_KEEP_ALIVE:
97-
err = k.handleKeepAlive(msg)
98-
case MESSAGE_TYPE_KEEP_ALIVE_RESPONSE:
99-
err = k.handleKeepAliveResponse(msg)
100-
case MESSAGE_TYPE_DONE:
101-
err = k.handleDone()
102-
default:
103-
err = fmt.Errorf("%s: received unexpected message type %d", PROTOCOL_NAME, msg.Type())
104-
}
105-
return err
106-
}
107-
108-
func (k *KeepAlive) startTimer() {
109-
k.timer = time.AfterFunc(KEEP_ALIVE_PERIOD*time.Second, func() {
110-
if err := k.KeepAlive(0); err != nil {
111-
k.SendError(err)
112-
}
113-
})
114-
}
115-
116-
func (k *KeepAlive) KeepAlive(cookie uint16) error {
117-
msg := NewMsgKeepAlive(cookie)
118-
return k.SendMessage(msg)
119-
}
120-
121-
func (k *KeepAlive) handleKeepAlive(msgGeneric protocol.Message) error {
122-
msg := msgGeneric.(*MsgKeepAlive)
123-
if k.config != nil && k.config.KeepAliveFunc != nil {
124-
// Call the user callback function
125-
return k.config.KeepAliveFunc(msg.Cookie)
126-
} else {
127-
// Send the keep-alive response
128-
resp := NewMsgKeepAliveResponse(msg.Cookie)
129-
return k.SendMessage(resp)
130-
}
131-
}
132-
133-
func (k *KeepAlive) handleKeepAliveResponse(msgGeneric protocol.Message) error {
134-
msg := msgGeneric.(*MsgKeepAliveResponse)
135-
// Start the timer again if we had one previously
136-
if k.timer != nil {
137-
defer k.startTimer()
138-
}
139-
if k.config != nil && k.config.KeepAliveResponseFunc != nil {
140-
// Call the user callback function
141-
return k.config.KeepAliveResponseFunc(msg.Cookie)
142-
}
143-
return nil
144-
}
145-
146-
func (k *KeepAlive) handleDone() error {
147-
if k.config != nil && k.config.DoneFunc != nil {
148-
// Call the user callback function
149-
return k.config.DoneFunc()
150-
}
151-
return nil
152-
}

protocol/keepalive/server.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package keepalive
2+
3+
import (
4+
"fmt"
5+
"github.com/cloudstruct/go-ouroboros-network/protocol"
6+
)
7+
8+
type Server struct {
9+
*protocol.Protocol
10+
config *Config
11+
}
12+
13+
func NewServer(protoOptions protocol.ProtocolOptions, cfg *Config) *Server {
14+
s := &Server{
15+
config: cfg,
16+
}
17+
protoConfig := protocol.ProtocolConfig{
18+
Name: PROTOCOL_NAME,
19+
ProtocolId: PROTOCOL_ID,
20+
Muxer: protoOptions.Muxer,
21+
ErrorChan: protoOptions.ErrorChan,
22+
Mode: protoOptions.Mode,
23+
Role: protocol.ProtocolRoleServer,
24+
MessageHandlerFunc: s.messageHandler,
25+
MessageFromCborFunc: NewMsgFromCbor,
26+
StateMap: StateMap,
27+
InitialState: STATE_CLIENT,
28+
}
29+
s.Protocol = protocol.New(protoConfig)
30+
return s
31+
}
32+
33+
func (s *Server) messageHandler(msg protocol.Message, isResponse bool) error {
34+
var err error
35+
switch msg.Type() {
36+
case MESSAGE_TYPE_KEEP_ALIVE:
37+
err = s.handleKeepAlive(msg)
38+
case MESSAGE_TYPE_DONE:
39+
err = s.handleDone()
40+
default:
41+
err = fmt.Errorf("%s: received unexpected message type %d", PROTOCOL_NAME, msg.Type())
42+
}
43+
return err
44+
}
45+
46+
func (s *Server) handleKeepAlive(msgGeneric protocol.Message) error {
47+
msg := msgGeneric.(*MsgKeepAlive)
48+
if s.config != nil && s.config.KeepAliveFunc != nil {
49+
// Call the user callback function
50+
return s.config.KeepAliveFunc(msg.Cookie)
51+
} else {
52+
// Send the keep-alive response
53+
resp := NewMsgKeepAliveResponse(msg.Cookie)
54+
return s.SendMessage(resp)
55+
}
56+
}
57+
58+
func (s *Server) handleDone() error {
59+
if s.config != nil && s.config.DoneFunc != nil {
60+
// Call the user callback function
61+
return s.config.DoneFunc()
62+
}
63+
return nil
64+
}

0 commit comments

Comments
 (0)