forked from eoscanada/eos-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelay.go
90 lines (71 loc) · 2.15 KB
/
relay.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
package p2p
import (
"fmt"
"net"
"go.uber.org/zap"
)
type Relay struct {
listeningAddress string
destinationPeerAddress string
handlers []Handler
}
func NewRelay(listeningAddress string, destinationPeerAddress string) *Relay {
return &Relay{
listeningAddress: listeningAddress,
destinationPeerAddress: destinationPeerAddress,
}
}
func (r *Relay) RegisterHandler(handler Handler) {
r.handlers = append(r.handlers, handler)
}
func (r *Relay) startProxy(conn net.Conn) {
remoteAddress := conn.RemoteAddr().String()
zlog.Info("Initiating proxy",
zap.String("peer1", remoteAddress),
zap.String("peer2", r.destinationPeerAddress))
destinationPeer := NewOutgoingPeer(r.destinationPeerAddress, "eos-relay", nil)
errorChannel := make(chan error)
destinationReadyChannel := destinationPeer.Connect(errorChannel)
select {
case <-destinationReadyChannel:
remotePeer := newPeer(remoteAddress, fmt.Sprintf("agent-%s", remoteAddress), false, nil)
remotePeer.SetConnection(conn)
proxy := NewProxy(remotePeer, destinationPeer)
proxy.RegisterHandlers(r.handlers)
err := proxy.Start()
zlog.Error("Started proxy error",
zap.String("peer1", remoteAddress),
zap.String("peer2", r.destinationPeerAddress),
zap.Error(err))
destinationPeer.connection.Close()
remotePeer.connection.Close()
zlog.Warn("Closing connection",
zap.String("peer1", remoteAddress),
zap.String("peer2", r.destinationPeerAddress))
break
case err := <-errorChannel:
zlog.Error("Proxy error between %s and %s : %s",
zap.Stringer("peer1", conn.RemoteAddr()),
zap.String("peer2", r.destinationPeerAddress),
zap.Error(err))
break
}
}
func (r *Relay) Start() error {
for {
ln, err := net.Listen("tcp", r.listeningAddress)
if err != nil {
return fmt.Errorf("peer init: listening %s: %w", r.listeningAddress, err)
}
zlog.Info("Accepting connection", zap.String("listen", r.listeningAddress))
for {
conn, err := ln.Accept()
if err != nil {
zlog.Error("lost listening connection", zap.Error(err))
break
}
zlog.Info("Connected to", zap.Stringer("remote", conn.RemoteAddr()))
go r.startProxy(conn)
}
}
}