-
Notifications
You must be signed in to change notification settings - Fork 1
/
tcpserver.go
144 lines (122 loc) · 3.41 KB
/
tcpserver.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
143
144
package main
import (
"fmt"
"net"
"log"
"strings"
)
type Client struct {
conn *net.TCPConn
serverRecord *ServerRecord
}
func NewClient(conn *net.TCPConn) *Client {
return &Client{
conn: conn,
}
}
type TCPServer struct {
serverManager *ServerManager
running bool
listener *net.TCPListener
}
func NewTCPServer(serverManager *ServerManager) *TCPServer{
return &TCPServer {
serverManager: serverManager,
running: false,
}
}
func (tcpserver *TCPServer) Stop() error {
tcpserver.listener.Close()
return nil
}
func (tcpserver *TCPServer) Run(host string, port int) error {
if tcpserver.running {
return nil
}
var err error
laddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d",host,port))
if err != nil {
return err
}
tcpserver.listener, err = net.ListenTCP("tcp", laddr)
if err != nil {
return err
}
log.Printf("Listening on %s:%d", host, port)
for {
conn, err := tcpserver.listener.AcceptTCP()
if err != nil {
log.Println("Error accepting: ", err.Error())
}
go tcpserver.handleRequest(conn)
}
}
func (tcpserver *TCPServer) handleRequest(conn *net.TCPConn) {
buf := make([]byte, 4096)
client := NewClient(conn) // Create client struct to contain the state for this connection
for {
reqLen, err := conn.Read(buf)
if err != nil {
log.Println("Error reading:", err.Error())
break
}
shouldClose, err := tcpserver.handleCommand(client, string(buf[:reqLen]))
if err != nil {
log.Println("Error handling command: ", err.Error())
break
}
if shouldClose {
break
}
}
conn.Close()
}
func (tcpserver *TCPServer) handleCommand(client *Client, command string) (bool, error) {
command = strings.TrimSpace(command)
log.Printf("Parsing command from %s: %s", client.conn.RemoteAddr().String(), command)
if strings.HasPrefix(command, "list ") || command == "list" {
var name string
var version int
_, err := fmt.Sscanf(command, "list %s %d", &name, &version)
if err != nil {
return true, err
} else {
log.Printf("Sending serverlist to %s %s (%d)", client.conn.RemoteAddr().String(), name, version)
client.conn.Write([]byte(tcpserver.serverManager.GetServerListString()))
return true, nil
}
}
if strings.HasPrefix(command, "regserv ") {
var port int
var name string
var version int
var key int
n, err := fmt.Sscanf(command, "regserv %d %s %d %d", &port, &name, &version, &key)
if err != nil {
return true, err
}
if n < 1 {
return true, fmt.Errorf("Invalid number of arguments to regserv")
}
if (port < 0 || port > 0xFFFF-1) {
client.conn.Write([]byte("failreg invalid port\n"))
return true, fmt.Errorf("Port is out of range")
}
if (client.serverRecord != nil && client.serverRecord.Info.Port != port) {
client.conn.Write([]byte("failreg invalid port\n"))
return true, fmt.Errorf("Port is getting reuseds")
}
remoteAddr := client.conn.RemoteAddr()
tcpAddr, _ := remoteAddr.(*net.TCPAddr)
log.Printf("Received server registration request from %s. Port %d Name: %s Version %d Key %d", tcpAddr.IP.String(), port, name, version, key)
serverInfo := NewServerInfo(tcpAddr.IP, port, name, version, key)
record, message := tcpserver.serverManager.RegisterServer(serverInfo)
if record.Status == RegistrationStatusSuccess {
client.conn.Write([]byte("succreg\n"))
} else {
client.conn.Write([]byte(fmt.Sprintf("failreg %s\n", message)))
}
return false, nil
}
return true, fmt.Errorf("No Valid command found")
}