-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelayrequest.go
100 lines (79 loc) · 2.18 KB
/
relayrequest.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
package main
import (
"log"
"net"
"sync"
)
// When a client connects to the relay server, we send a
// string of bytes to the server notifying them that a new
// connection has been made.
// We then expect them to setup a connection to our server.
// This means, we need 2 listeners per request: one for requests
// from clients and one for requests from the server.
type RelayRequestHandler interface {
// Accepts clients, notifies the server and accepts a client
// from the server.
AcceptClients()
// Return client port
GetClientPort() int
// Return server port
GetServerPort() int
}
type RelayRequest struct {
clientL *net.TCPListener // Listener for clients
serverL *net.TCPListener // Listener for servers
c *net.TCPConn // Connection from the server
clientPort, serverPort int
}
func NewRelayRequest(client *net.TCPConn) (RelayRequestHandler, error) {
cl, sl, err := startServers()
if err != nil {
return nil, err
}
cPort := getPort(cl.Addr())
sPort := getPort(sl.Addr())
return &RelayRequest{cl, sl, client, cPort, sPort}, nil
}
func (rr *RelayRequest) AcceptClients() {
var wg sync.WaitGroup
for {
clientSocket, err := rr.clientL.AcceptTCP()
if err != nil {
panic(err)
}
log.Println("Client connected:", clientSocket.RemoteAddr().String())
notifyNewClient(rr.c, rr.serverPort)
serverSocket, err := rr.serverL.AcceptTCP()
if err != nil {
panic(err)
}
log.Println("Server connected:", clientSocket.RemoteAddr().String())
wg.Add(1)
go func() {
defer wg.Done()
ds := NewClientServerSynchronizer(rr.c)
ds.SynchronizeIO(clientSocket, serverSocket)
}()
}
wg.Wait()
}
func (rr *RelayRequest) GetClientPort() int {
return rr.clientPort
}
func (rr *RelayRequest) GetServerPort() int {
return rr.serverPort
}
func startServers() (*net.TCPListener, *net.TCPListener, error) {
clientL, err := net.Listen("tcp", "0.0.0.0:0")
if err != nil {
return nil, nil, err
}
serverL, err := net.Listen("tcp", "0.0.0.0:0")
if err != nil {
return nil, nil, err
}
return clientL.(*net.TCPListener), serverL.(*net.TCPListener), nil
}
func getPort(addr net.Addr) int {
return addr.(*net.TCPAddr).Port
}