This repository has been archived by the owner on Jan 2, 2024. It is now read-only.
/
server_conn.go
111 lines (95 loc) · 2.48 KB
/
server_conn.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
package subnet
import (
"encoding/gob"
"log"
"net"
"github.com/twitchyliquid64/subnet/subnet/conn"
)
type serverConn struct {
conn net.Conn
id int
outboundIPPkts chan *IPPacket
server *Server
canSendIP bool
remoteAddrs []net.IP
connectionOk bool
}
func (c *serverConn) initClient(s *Server) {
c.outboundIPPkts = make(chan *IPPacket, servPerClientPktQueue)
c.connectionOk = true
c.server = s
log.Printf("New connection from %s (%d)\n", c.conn.RemoteAddr().String(), c.id)
go c.readRoutine(&s.isShuttingDown, s.inboundIPPkts)
go c.writeRoutine(&s.isShuttingDown)
}
func (c *serverConn) writeRoutine(isShuttingDown *bool) {
encoder := gob.NewEncoder(c.conn)
for !*isShuttingDown && c.connectionOk {
select {
case pkt := <-c.outboundIPPkts:
encoder.Encode(conn.PktIPPkt)
err := encoder.Encode(pkt)
if err != nil {
log.Printf("Write error for %s: %s\n", c.conn.RemoteAddr().String(), err.Error())
c.hadError(false)
return
}
}
}
}
func (c *serverConn) readRoutine(isShuttingDown *bool, ipPacketSink chan *inboundIPPkt) {
decoder := gob.NewDecoder(c.conn)
for !*isShuttingDown && c.connectionOk {
var pktType conn.PktType
err := decoder.Decode(&pktType)
if err != nil {
if !*isShuttingDown {
log.Printf("Client read error: %s\n", err.Error())
}
c.hadError(true)
return
}
switch pktType {
case conn.PktLocalAddr:
var localAddr net.IP
err := decoder.Decode(&localAddr)
if err != nil {
log.Printf("Could not decode net.IP: %s", err.Error())
c.hadError(false)
return
}
c.remoteAddrs = append(c.remoteAddrs, localAddr)
c.server.setAddrForClient(c.id, localAddr)
case conn.PktIPPkt:
var ipPkt IPPacket
err := decoder.Decode(&ipPkt)
if err != nil {
log.Printf("Could not decode IPPacket: %s", err.Error())
c.hadError(false)
return
}
//log.Printf("Packet Received from %d: dest %s, len %d\n", c.id, ipPkt.Dest.String(), len(ipPkt.Raw))
ipPacketSink <- &inboundIPPkt{pkt: &ipPkt, clientID: c.id}
}
}
}
func (c *serverConn) queueIP(pkt *IPPacket) {
select {
case c.outboundIPPkts <- pkt:
default:
log.Printf("Warning: Dropping packets for %s as outbound msg queue is full.\n", c.remoteAddressStr())
}
}
func (c *serverConn) remoteAddressStr() string {
if len(c.remoteAddrs) == 0 {
return ""
}
return c.remoteAddrs[0].String()
}
func (c *serverConn) hadError(errInRead bool) {
if !errInRead {
c.conn.Close()
}
c.connectionOk = false
c.server.removeClientConn(c.id)
}