Skip to content

Commit 59d789d

Browse files
author
刘河
committed
结构调整、kcp支持
1 parent 2e8af6f commit 59d789d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+11087
-773
lines changed

README.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ go语言编写,无第三方依赖,各个平台都已经编译在release中
4545
* [与nginx配合](#与nginx配合)
4646
* [关闭http|https代理](#关闭代理)
4747
* [将nps安装到系统](#将nps安装到系统)
48-
* 单隧道模式及介绍
48+
* 单隧道模式及介绍(即将移除)
4949
* [tcp隧道模式](#tcp隧道模式)
5050
* [udp隧道模式](#udp隧道模式)
5151
* [socks5代理模式](#socks5代理模式)
@@ -62,6 +62,7 @@ go语言编写,无第三方依赖,各个平台都已经编译在release中
6262
* [带宽限制](#带宽限制)
6363
* [负载均衡](#负载均衡)
6464
* [守护进程](#守护进程)
65+
* [KCP协议支持](#KCP协议支持)
6566
* [相关说明](#相关说明)
6667
* [流量统计](#流量统计)
6768
* [热更新支持](#热更新支持)
@@ -138,12 +139,13 @@ go语言编写,无第三方依赖,各个平台都已经编译在release中
138139
---|---
139140
httpport | web管理端口
140141
password | web界面管理密码
141-
tcpport | 服务端客户端通信端口
142+
bridePort | 服务端客户端通信端口
142143
pemPath | ssl certFile绝对路径
143144
keyPath | ssl keyFile绝对路径
144145
httpsProxyPort | 域名代理https代理监听端口
145146
httpProxyPort | 域名代理http代理监听端口
146147
authip|web api免验证IP地址
148+
bridgeType|客户端与服务端连接方式kcp或tcp
147149

148150
### 详细说明
149151

@@ -539,12 +541,23 @@ authip | 免验证ip,适用于web api
539541
### 守护进程
540542
本代理支持守护进程,使用示例如下,服务端客户端所有模式通用,支持linux,darwin,windows。
541543
```
542-
./(nps|npc) start|stop|restart|status xxxxxx
544+
./(nps|npc) start|stop|restart|status 若有其他参数可加其他参数
543545
```
544546
```
545-
(nps|npc).exe start|stop|restart|status xxxxxx
547+
(nps|npc).exe start|stop|restart|status 若有其他参数可加其他参数
546548
```
547549

550+
### KCP协议支持
551+
KCP 是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,在弱网环境下对性能能有一定的提升。可在app.conf中修改bridgeType为kcp
552+
,设置后本代理将开启udp端口(bridgePort)
553+
554+
注意:当服务端为kcp时,客户端连接时也需要加上参数
555+
556+
```
557+
-type=kcp
558+
```
559+
560+
548561
## 相关说明
549562

550563
### 获取用户真实ip

bridge/bridge.go

Lines changed: 92 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,113 @@ package bridge
22

33
import (
44
"errors"
5-
"github.com/cnlh/nps/lib"
5+
"github.com/cnlh/nps/lib/conn"
6+
"github.com/cnlh/nps/lib/file"
7+
"github.com/cnlh/nps/lib/kcp"
8+
"github.com/cnlh/nps/lib/lg"
9+
"github.com/cnlh/nps/lib/pool"
10+
"github.com/cnlh/nps/lib/common"
611
"net"
12+
"strconv"
713
"sync"
814
"time"
915
)
1016

1117
type Client struct {
12-
tunnel *lib.Conn
13-
signal *lib.Conn
14-
linkMap map[int]*lib.Link
18+
tunnel *conn.Conn
19+
signal *conn.Conn
20+
linkMap map[int]*conn.Link
1521
linkStatusMap map[int]bool
1622
stop chan bool
1723
sync.RWMutex
1824
}
1925

26+
func NewClient(t *conn.Conn, s *conn.Conn) *Client {
27+
return &Client{
28+
linkMap: make(map[int]*conn.Link),
29+
stop: make(chan bool),
30+
linkStatusMap: make(map[int]bool),
31+
signal: s,
32+
tunnel: t,
33+
}
34+
}
35+
2036
type Bridge struct {
21-
TunnelPort int //通信隧道端口
22-
listener *net.TCPListener //server端监听
23-
Client map[int]*Client
24-
RunList map[int]interface{} //运行中的任务
25-
lock sync.Mutex
26-
tunnelLock sync.Mutex
27-
clientLock sync.Mutex
37+
TunnelPort int //通信隧道端口
38+
tcpListener *net.TCPListener //server端监听
39+
kcpListener *kcp.Listener //server端监听
40+
Client map[int]*Client
41+
RunList map[int]interface{} //运行中的任务
42+
tunnelType string //bridge type kcp or tcp
43+
lock sync.Mutex
44+
tunnelLock sync.Mutex
45+
clientLock sync.RWMutex
2846
}
2947

30-
func NewTunnel(tunnelPort int, runList map[int]interface{}) *Bridge {
48+
func NewTunnel(tunnelPort int, runList map[int]interface{}, tunnelType string) *Bridge {
3149
t := new(Bridge)
3250
t.TunnelPort = tunnelPort
3351
t.Client = make(map[int]*Client)
3452
t.RunList = runList
53+
t.tunnelType = tunnelType
3554
return t
3655
}
3756

3857
func (s *Bridge) StartTunnel() error {
3958
var err error
40-
s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.TunnelPort, ""})
41-
if err != nil {
42-
return err
43-
}
44-
go s.tunnelProcess()
45-
return nil
46-
}
47-
48-
//tcp server
49-
func (s *Bridge) tunnelProcess() error {
50-
var err error
51-
for {
52-
conn, err := s.listener.Accept()
59+
if s.tunnelType == "kcp" {
60+
s.kcpListener, err = kcp.ListenWithOptions(":"+strconv.Itoa(s.TunnelPort), nil, 150, 3)
61+
if err != nil {
62+
return err
63+
}
64+
go func() {
65+
for {
66+
c, err := s.kcpListener.AcceptKCP()
67+
conn.SetUdpSession(c)
68+
if err != nil {
69+
lg.Println(err)
70+
continue
71+
}
72+
go s.cliProcess(conn.NewConn(c))
73+
}
74+
}()
75+
} else {
76+
s.tcpListener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.TunnelPort, ""})
5377
if err != nil {
54-
lib.Println(err)
55-
continue
78+
return err
5679
}
57-
go s.cliProcess(lib.NewConn(conn))
80+
go func() {
81+
for {
82+
c, err := s.tcpListener.Accept()
83+
if err != nil {
84+
lg.Println(err)
85+
continue
86+
}
87+
go s.cliProcess(conn.NewConn(c))
88+
}
89+
}()
5890
}
59-
return err
91+
return nil
6092
}
6193

6294
//验证失败,返回错误验证flag,并且关闭连接
63-
func (s *Bridge) verifyError(c *lib.Conn) {
64-
c.Write([]byte(lib.VERIFY_EER))
95+
func (s *Bridge) verifyError(c *conn.Conn) {
96+
c.Write([]byte(common.VERIFY_EER))
6597
c.Conn.Close()
6698
}
6799

68-
func (s *Bridge) cliProcess(c *lib.Conn) {
69-
c.SetReadDeadline(5)
100+
func (s *Bridge) cliProcess(c *conn.Conn) {
101+
c.SetReadDeadline(5, s.tunnelType)
70102
var buf []byte
71103
var err error
72104
if buf, err = c.ReadLen(32); err != nil {
73105
c.Close()
74106
return
75107
}
76108
//验证
77-
id, err := lib.GetCsvDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
109+
id, err := file.GetCsvDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
78110
if err != nil {
79-
lib.Println("当前客户端连接校验错误,关闭此客户端:", c.Conn.RemoteAddr())
111+
lg.Println("当前客户端连接校验错误,关闭此客户端:", c.Conn.RemoteAddr())
80112
s.verifyError(c)
81113
return
82114
}
@@ -97,40 +129,39 @@ func (s *Bridge) closeClient(id int) {
97129
}
98130

99131
//tcp连接类型区分
100-
func (s *Bridge) typeDeal(typeVal string, c *lib.Conn, id int) {
132+
func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
101133
switch typeVal {
102-
case lib.WORK_MAIN:
134+
case common.WORK_MAIN:
103135
//客户端已经存在,下线
104136
s.clientLock.Lock()
105-
if _, ok := s.Client[id]; ok {
137+
if v, ok := s.Client[id]; ok {
106138
s.clientLock.Unlock()
107-
s.closeClient(id)
139+
if v.signal != nil {
140+
v.signal.WriteClose()
141+
}
142+
v.Lock()
143+
v.signal = c
144+
v.Unlock()
108145
} else {
146+
s.Client[id] = NewClient(nil, c)
109147
s.clientLock.Unlock()
110148
}
111-
s.clientLock.Lock()
112-
113-
s.Client[id] = &Client{
114-
linkMap: make(map[int]*lib.Link),
115-
stop: make(chan bool),
116-
linkStatusMap: make(map[int]bool),
117-
}
118-
lib.Printf("客户端%d连接成功,地址为:%s", id, c.Conn.RemoteAddr())
119-
s.Client[id].signal = c
120-
s.clientLock.Unlock()
149+
lg.Printf("客户端%d连接成功,地址为:%s", id, c.Conn.RemoteAddr())
121150
go s.GetStatus(id)
122-
case lib.WORK_CHAN:
151+
case common.WORK_CHAN:
123152
s.clientLock.Lock()
124153
if v, ok := s.Client[id]; ok {
125154
s.clientLock.Unlock()
155+
v.Lock()
126156
v.tunnel = c
157+
v.Unlock()
127158
} else {
159+
s.Client[id] = NewClient(c, nil)
128160
s.clientLock.Unlock()
129-
return
130161
}
131162
go s.clientCopy(id)
132163
}
133-
c.SetAlive()
164+
c.SetAlive(s.tunnelType)
134165
return
135166
}
136167

@@ -161,13 +192,13 @@ func (s *Bridge) waitStatus(clientId, id int) (bool) {
161192
return false
162193
}
163194

164-
func (s *Bridge) SendLinkInfo(clientId int, link *lib.Link) (tunnel *lib.Conn, err error) {
195+
func (s *Bridge) SendLinkInfo(clientId int, link *conn.Link) (tunnel *conn.Conn, err error) {
165196
s.clientLock.Lock()
166197
if v, ok := s.Client[clientId]; ok {
167198
s.clientLock.Unlock()
168199
v.signal.SendLinkInfo(link)
169200
if err != nil {
170-
lib.Println("send error:", err, link.Id)
201+
lg.Println("send error:", err, link.Id)
171202
s.DelClient(clientId)
172203
return
173204
}
@@ -192,7 +223,7 @@ func (s *Bridge) SendLinkInfo(clientId int, link *lib.Link) (tunnel *lib.Conn, e
192223
}
193224

194225
//得到一个tcp隧道
195-
func (s *Bridge) GetTunnel(id int, en, de int, crypt, mux bool) (conn *lib.Conn, err error) {
226+
func (s *Bridge) GetTunnel(id int, en, de int, crypt, mux bool) (conn *conn.Conn, err error) {
196227
s.clientLock.Lock()
197228
defer s.clientLock.Unlock()
198229
if v, ok := s.Client[id]; !ok {
@@ -204,7 +235,7 @@ func (s *Bridge) GetTunnel(id int, en, de int, crypt, mux bool) (conn *lib.Conn,
204235
}
205236

206237
//得到一个通信通道
207-
func (s *Bridge) GetSignal(id int) (conn *lib.Conn, err error) {
238+
func (s *Bridge) GetSignal(id int) (conn *conn.Conn, err error) {
208239
s.clientLock.Lock()
209240
defer s.clientLock.Unlock()
210241
if v, ok := s.Client[id]; !ok {
@@ -257,19 +288,19 @@ func (s *Bridge) clientCopy(clientId int) {
257288
for {
258289
if id, err := client.tunnel.GetLen(); err != nil {
259290
s.closeClient(clientId)
260-
lib.Println("读取msg id 错误", err, id)
291+
lg.Println("读取msg id 错误", err, id)
261292
break
262293
} else {
263294
client.Lock()
264295
if link, ok := client.linkMap[id]; ok {
265296
client.Unlock()
266297
if content, err := client.tunnel.GetMsgContent(link); err != nil {
267-
lib.PutBufPoolCopy(content)
298+
pool.PutBufPoolCopy(content)
268299
s.closeClient(clientId)
269-
lib.Println("read msg content error", err, "close client")
300+
lg.Println("read msg content error", err, "close client")
270301
break
271302
} else {
272-
if len(content) == len(lib.IO_EOF) && string(content) == lib.IO_EOF {
303+
if len(content) == len(common.IO_EOF) && string(content) == common.IO_EOF {
273304
if link.Conn != nil {
274305
link.Conn.Close()
275306
}
@@ -281,13 +312,12 @@ func (s *Bridge) clientCopy(clientId int) {
281312
}
282313
link.Flow.Add(0, len(content))
283314
}
284-
lib.PutBufPoolCopy(content)
315+
pool.PutBufPoolCopy(content)
285316
}
286317
} else {
287318
client.Unlock()
288319
continue
289320
}
290321
}
291322
}
292-
293323
}

0 commit comments

Comments
 (0)