-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
local.go
159 lines (151 loc) · 4.67 KB
/
local.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package client
import (
"github.com/cnlh/nps/lib/common"
"github.com/cnlh/nps/lib/config"
"github.com/cnlh/nps/lib/conn"
"github.com/cnlh/nps/lib/crypt"
"github.com/cnlh/nps/lib/file"
"github.com/cnlh/nps/lib/mux"
"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
"github.com/cnlh/nps/vender/github.com/xtaci/kcp"
"net"
"net/http"
)
var LocalServer []*net.TCPListener
var udpConn net.Conn
var muxSession *mux.Mux
var fileServer []*http.Server
func CloseLocalServer() {
for _, v := range LocalServer {
v.Close()
}
for _, v := range fileServer {
v.Close()
}
}
func startLocalFileServer(config *config.CommonConfig, t *file.Tunnel, vkey string) {
remoteConn, err := NewConn(config.Tp, vkey, config.Server, common.WORK_FILE, config.ProxyUrl)
if err != nil {
logs.Error("Local connection server failed ", err.Error())
return
}
srv := &http.Server{
Handler: http.StripPrefix(t.StripPre, http.FileServer(http.Dir(t.LocalPath))),
}
logs.Info("start local file system, local path %s, strip prefix %s ,remote port %s ", t.LocalPath, t.StripPre, t.Ports)
fileServer = append(fileServer, srv)
listener := mux.NewMux(remoteConn.Conn, common.CONN_TCP)
logs.Warn(srv.Serve(listener))
}
func StartLocalServer(l *config.LocalServer, config *config.CommonConfig) error {
listener, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), l.Port, ""})
if err != nil {
logs.Error("local listener startup failed port %d, error %s", l.Port, err.Error())
return err
}
LocalServer = append(LocalServer, listener)
logs.Info("successful start-up of local monitoring, port", l.Port)
conn.Accept(listener, func(c net.Conn) {
if l.Type == "secret" {
processSecret(c, config, l)
} else {
processP2P(c, config, l)
}
})
return nil
}
func processSecret(localTcpConn net.Conn, config *config.CommonConfig, l *config.LocalServer) {
remoteConn, err := NewConn(config.Tp, config.VKey, config.Server, common.WORK_SECRET, config.ProxyUrl)
if err != nil {
logs.Error("Local connection server failed ", err.Error())
return
}
if _, err := remoteConn.Write([]byte(crypt.Md5(l.Password))); err != nil {
logs.Error("Local connection server failed ", err.Error())
return
}
conn.CopyWaitGroup(remoteConn.Conn, localTcpConn, false, false, nil, nil, false, nil)
}
func processP2P(localTcpConn net.Conn, config *config.CommonConfig, l *config.LocalServer) {
if udpConn == nil {
newUdpConn(config, l)
if udpConn == nil {
return
}
muxSession = mux.NewMux(udpConn, "kcp")
}
nowConn, err := muxSession.NewConn()
if err != nil {
logs.Error(err)
return
}
//TODO just support compress now because there is not tls file in client packages
link := conn.NewLink(common.CONN_TCP, l.Target, false, config.Client.Cnf.Compress, localTcpConn.LocalAddr().String())
if _, err := conn.NewConn(nowConn).SendInfo(link, ""); err != nil {
logs.Error(err)
return
}
conn.CopyWaitGroup(nowConn, localTcpConn, false, config.Client.Cnf.Compress, nil, nil, false, nil)
}
func newUdpConn(config *config.CommonConfig, l *config.LocalServer) {
remoteConn, err := NewConn(config.Tp, config.VKey, config.Server, common.WORK_P2P, config.ProxyUrl)
if err != nil {
logs.Error("Local connection server failed ", err.Error())
return
}
if _, err := remoteConn.Write([]byte(crypt.Md5(l.Password))); err != nil {
logs.Error("Local connection server failed ", err.Error())
return
}
var rAddr []byte
//读取服务端地址、密钥 继续做处理
if rAddr, err = remoteConn.GetShortLenContent(); err != nil {
logs.Error(err)
return
}
//与服务端udp建立连接
tmpConn, err := common.GetLocalUdpAddr()
if err != nil {
logs.Warn(err)
return
}
//与服务端建立udp连接
localAddr, _ := net.ResolveUDPAddr("udp", tmpConn.LocalAddr().String())
localConn, err := net.ListenUDP("udp", localAddr)
if err != nil {
logs.Error(err)
return
}
localKcpConn, err := kcp.NewConn(string(rAddr), nil, 150, 3, localConn)
if err != nil {
logs.Error(err)
return
}
conn.SetUdpSession(localKcpConn)
//写入密钥、provider身份
if _, err := localKcpConn.Write([]byte(crypt.Md5(l.Password))); err != nil {
logs.Error(err)
return
}
if _, err := localKcpConn.Write([]byte(common.WORK_P2P_VISITOR)); err != nil {
logs.Error(err)
return
}
//接收服务端传的visitor地址
if b, err := conn.NewConn(localKcpConn).GetShortLenContent(); err != nil {
logs.Error(err)
return
} else {
//关闭与服务端连接
localConn.Close()
//建立新的连接
localConn, err = net.ListenUDP("udp", localAddr)
udpTunnel, err := kcp.NewConn(string(b), nil, 150, 3, localConn)
if err != nil || udpTunnel == nil {
logs.Warn(err)
return
}
conn.SetUdpSession(udpTunnel)
udpConn = udpTunnel
}
}