-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.go
124 lines (107 loc) · 3.15 KB
/
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
package minq
import (
"net"
)
// TransportFactory makes transports bound to a specific remote
// address.
type TransportFactory interface {
// Make a transport object bound to |remote|.
MakeTransport(remote *net.UDPAddr) (Transport, error)
}
// Server represents a QUIC server. A server can be fed an arbitrary
// number of packets and will create Connections as needed, passing
// each packet to the right connection.
type Server struct {
handler ServerHandler
transFactory TransportFactory
tls *TlsConfig
addrTable map[string]*Connection
idTable map[string]*Connection
AddressHelper *AddressHelper
}
// Interface for the handler object which the Server will call
// to notify of events.
type ServerHandler interface {
// A new connection has been created and can be found in |c|.
NewConnection(c *Connection)
}
// SetHandler sets a handler function.
func (s *Server) SetHandler(h ServerHandler) {
s.handler = h
}
// Input passes an incoming packet to the Server.
func (s *Server) Input(addr *net.UDPAddr, data []byte) (*Connection, error) {
logf(logTypeServer, "Received packet from %v", addr)
hdr := packetHeader{shortCidLength: kCidDefaultLength}
newConn := false
_, err := decode(&hdr, data)
if err != nil {
return nil, err
}
var conn *Connection
if len(hdr.DestinationConnectionID) > 0 {
logf(logTypeServer, "Received conn id %v", hdr.DestinationConnectionID)
conn = s.idTable[hdr.DestinationConnectionID.String()]
if conn != nil {
logf(logTypeServer, "Found by conn id")
}
}
if conn == nil {
conn = s.addrTable[addr.String()]
}
if conn == nil {
logf(logTypeServer, "New server connection from addr %v", addr)
trans, err := s.transFactory.MakeTransport(addr)
if err != nil {
return nil, err
}
conn = NewConnection(trans, RoleServer, s.tls, nil)
newConn = true
}
err = conn.Input(data)
if isFatalError(err) {
logf(logTypeServer, "Fatal Error %v killing connection %v", err, conn)
return nil, nil
}
if newConn {
// Wait until handling the first packet before the connection is added
// to the table. Firstly, to avoid having to remove it if there is an
// error, but also because the server-chosen connection ID isn't set
// until after the Initial is handled.
s.idTable[conn.serverConnectionId.String()] = conn
s.addrTable[addr.String()] = conn
if s.handler != nil {
s.handler.NewConnection(conn)
}
}
return conn, nil
}
// Check the server timers.
func (s *Server) CheckTimer() error {
for _, conn := range s.idTable {
_, err := conn.CheckTimer()
if isFatalError(err) {
logf(logTypeServer, "Fatal Error %v killing connection %v", err, conn)
delete(s.idTable, conn.serverConnectionId.String())
// TODO(ekr@rtfm.com): Delete this from the addr table.
}
}
return nil
}
// How many connections do we have?
func (s *Server) ConnectionCount() int {
return len(s.idTable)
}
// Create a new QUIC server with the provide TLS config.
func NewServer(factory TransportFactory, tls *TlsConfig, handler ServerHandler) *Server {
s := Server{
handler,
factory,
tls,
make(map[string]*Connection),
make(map[string]*Connection),
NewAddressHelper(),
}
s.tls.init()
return &s
}