/
openconn.go
80 lines (64 loc) · 1.97 KB
/
openconn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package main
import (
"time"
"github.com/matrix-org/coap-proxy/common"
"github.com/matrix-org/go-coap"
)
// Map of open connections with the host address as the key. Allows us to keep
// track of the last time a message was sent for timeout purposes.
var conns map[string]*openConn
// openConn is a struct that represents an open CoAP connection to another
// coap-proxy instance. We keep a map of these for timeout tracking purposes.
type openConn struct {
*coap.ClientConn
lastMsg time.Time
killswitch chan bool
dead bool
}
func newOpenConn(target string) (c *openConn, err error) {
c = new(openConn)
if c.ClientConn, err = dialTimeout("udp", target, 300*time.Second); err != nil {
return
}
c.killswitch = make(chan bool)
//go c.heartbeat()
return
}
func (c *openConn) Close() error {
c.killswitch <- true
return c.ClientConn.Close()
}
func (c *openConn) heartbeat() {
for {
// Wait before sending the first heatbeat so that the handshake and the
// first exchange can happen.
select {
case <-c.killswitch:
common.Debugf("Got killswitch signal for connection to %s", c.ClientConn.RemoteAddr().String())
return
case <-time.After(30 * time.Second):
common.Debugf("Sending heartbeat to %s", c.ClientConn.RemoteAddr().String())
}
if err := c.ClientConn.Ping(10 * time.Second); err != nil {
common.Debugf("Connection to %s is dead", c.ClientConn.RemoteAddr().String())
c.dead = true
return
}
common.Debugf("Connection to %s is alive", c.ClientConn.RemoteAddr().String())
}
}
// resetConn is a function that given a CoAP target (address and port), closes
// any existing connections to it and opens a new one.
func resetConn(target string) (*openConn, error) {
if c, exists := conns[target]; exists {
common.Debugf("Closing UDP connection to %s", target)
_ = c.Close()
}
common.Debugf("Creating new UDP connection to %s", target)
c, err := newOpenConn(target)
if err != nil {
return nil, err
}
conns[target] = c
return c, nil
}