-
Notifications
You must be signed in to change notification settings - Fork 36
/
endpoint_server.go
142 lines (116 loc) · 2.93 KB
/
endpoint_server.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package gomavlib
import (
"fmt"
"io"
"net"
"time"
"github.com/pion/transport/v2/udp"
"github.com/bluenviron/gomavlib/v3/pkg/timednetconn"
)
type endpointServerConf interface {
isUDP() bool
getAddress() string
init(*Node) (Endpoint, error)
}
// EndpointTCPServer sets up a endpoint that works with a TCP server.
// TCP is fit for routing frames through the internet, but is not the most
// appropriate way for transferring frames from a UAV to a GCS, since it does
// not allow frame losses.
type EndpointTCPServer struct {
// listen address, example: 0.0.0.0:5600
Address string
}
func (EndpointTCPServer) isUDP() bool {
return false
}
func (conf EndpointTCPServer) getAddress() string {
return conf.Address
}
// EndpointUDPServer sets up a endpoint that works with an UDP server.
// This is the most appropriate way for transferring frames from a UAV to a GCS
// if they are connected to the same network.
type EndpointUDPServer struct {
// listen address, example: 0.0.0.0:5600
Address string
}
func (EndpointUDPServer) isUDP() bool {
return true
}
func (conf EndpointUDPServer) getAddress() string {
return conf.Address
}
type endpointServer struct {
conf endpointServerConf
listener net.Listener
writeTimeout time.Duration
idleTimeout time.Duration
// in
terminate chan struct{}
}
func (conf EndpointTCPServer) init(node *Node) (Endpoint, error) {
return initEndpointServer(node, conf)
}
func (conf EndpointUDPServer) init(node *Node) (Endpoint, error) {
return initEndpointServer(node, conf)
}
func initEndpointServer(node *Node, conf endpointServerConf) (Endpoint, error) {
_, _, err := net.SplitHostPort(conf.getAddress())
if err != nil {
return nil, fmt.Errorf("invalid address")
}
var ln net.Listener
if conf.isUDP() {
var addr *net.UDPAddr
addr, err = net.ResolveUDPAddr("udp4", conf.getAddress())
if err != nil {
return nil, err
}
ln, err = udp.Listen("udp4", addr)
if err != nil {
return nil, err
}
} else {
ln, err = net.Listen("tcp4", conf.getAddress())
if err != nil {
return nil, err
}
}
t := &endpointServer{
conf: conf,
writeTimeout: node.conf.WriteTimeout,
idleTimeout: node.conf.IdleTimeout,
listener: ln,
terminate: make(chan struct{}),
}
return t, nil
}
func (t *endpointServer) isEndpoint() {}
func (t *endpointServer) Conf() EndpointConf {
return t.conf
}
func (t *endpointServer) close() {
close(t.terminate)
t.listener.Close()
}
func (t *endpointServer) oneChannelAtAtime() bool {
return false
}
func (t *endpointServer) provide() (string, io.ReadWriteCloser, error) {
nconn, err := t.listener.Accept()
// wait termination, do not report errors
if err != nil {
<-t.terminate
return "", nil, errTerminated
}
label := fmt.Sprintf("%s:%s", func() string {
if t.conf.isUDP() {
return "udp"
}
return "tcp"
}(), nconn.RemoteAddr())
conn := timednetconn.New(
t.idleTimeout,
t.writeTimeout,
nconn)
return label, conn, nil
}