-
Notifications
You must be signed in to change notification settings - Fork 0
/
reverseproxy_svc.go
109 lines (96 loc) · 2.51 KB
/
reverseproxy_svc.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
package adaptiveservice
import (
"io"
"net"
)
// SrvReverseProxy : service reverseProxy
const SrvReverseProxy = "reverseProxy"
type proxyRegServiceInWAN struct {
publisher string
service string
providerID string
}
func (msg *proxyRegServiceInWAN) Handle(stream ContextStream) (reply interface{}) {
s := stream.GetContext().(*Server)
chanServerConn := make(chan net.Conn)
onServerConnection := func(netconn Netconn) bool {
chanServerConn <- netconn.(net.Conn)
return true
}
reversesvc := &service{
s: s,
fnOnConnect: onServerConnection,
}
reversetran, err := reversesvc.newTCPTransport("")
if err != nil {
return err
}
s.addCloser(reversetran)
_, port, _ := net.SplitHostPort(reversetran.lnr.Addr().String()) // from [::]:43807
var proxytran *streamTransport
go func() {
if err := stream.Recv(nil); err != nil {
s.lg.Debugf("service cmdconn read lost, closing its proxy")
reversetran.close()
close(chanServerConn)
if proxytran != nil {
proxytran.close()
}
}
}()
onClientConnection := func(netconn Netconn) bool {
clientConn := netconn.(net.Conn)
s.lg.Debugf("reverse proxy: starting for client: %s", clientConn.RemoteAddr().String())
if err := stream.Send(port); err != nil {
s.lg.Debugf("service cmdconn write lost, closing its proxy")
reversetran.close()
proxytran.close()
clientConn.Close()
return true
}
serverConn := <-chanServerConn
if serverConn == nil {
clientConn.Close()
return true
}
go func() {
io.Copy(serverConn, clientConn)
serverConn.Close()
s.lg.Debugf("io copy client => server done")
}()
go func() {
// acknowledge client real server connected
clientConn.Write([]byte{0})
io.Copy(clientConn, serverConn)
clientConn.Close()
s.lg.Debugf("io copy server => client done")
}()
return true
}
proxysvc := &service{
publisherName: msg.publisher,
serviceName: msg.service,
providerID: msg.providerID,
s: s,
scope: ScopeWAN,
fnOnConnect: onClientConnection,
}
proxytran, err = proxysvc.newTCPTransport("")
if err != nil {
return err
}
s.addCloser(proxytran)
return OK
}
// publishReverseProxyService declares the reverse proxy service.
func (s *Server) publishReverseProxyService(scope Scope) error {
knownMsgs := []KnownMessage{(*proxyRegServiceInWAN)(nil)}
return s.publish(scope, BuiltinPublisher, SrvReverseProxy,
knownMsgs,
OnNewStreamFunc(func(ctx Context) {
ctx.SetContext(s)
}))
}
func init() {
RegisterType((*proxyRegServiceInWAN)(nil))
}