forked from eoscanada/eos-go
-
Notifications
You must be signed in to change notification settings - Fork 4
/
relay.go
92 lines (72 loc) · 2.17 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
91
92
package p2p
import (
"fmt"
"net"
"github.com/pkg/errors"
"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()
p2pLog.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()
p2pLog.Error("Started proxy error",
zap.String("peer1", remoteAddress),
zap.String("peer2", r.destinationPeerAddress),
zap.Error(err))
destinationPeer.connection.Close()
remotePeer.connection.Close()
p2pLog.Warn("Closing connection",
zap.String("peer1", remoteAddress),
zap.String("peer2", r.destinationPeerAddress))
break
case err := <-errorChannel:
p2pLog.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 errors.Wrapf(err, "peer init: listening %s", r.listeningAddress)
}
p2pLog.Info("Accepting connection", zap.String("listen", r.listeningAddress))
for {
conn, err := ln.Accept()
if err != nil {
logErr("lost listening connection", err)
break
}
p2pLog.Info("Connected to", zap.Stringer("remote", conn.RemoteAddr()))
go r.startProxy(conn)
}
}
}