diff --git a/README.md b/README.md index 4046b7b97dad21ebc9fd1e202591b4968d2050d1..bacbd76b10dcd7befa4d595341139ec08e997101 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 那么,有什么办法可以解决这一难题?答案就是**内网穿透**。当内网中的主机没有静态IP地址要被外网稳定访问时可以使用内网穿透。 -**go-netbus**【网络直通车】是为解决内网穿透问题开发的工具。 +**go-netbus**【网络巴士】是为解决内网穿透问题开发的工具。 ## 功能列表 diff --git a/config/clientconfig.go b/config/clientconfig.go index e01d7765802261ba504213724a0bb6d0ea7673cf..a57cef2567ec6e00ace9d7cbfbd0cc8878302da2 100644 --- a/config/clientconfig.go +++ b/config/clientconfig.go @@ -21,7 +21,14 @@ type ClientConfig struct { TunnelCount int // 隧道条数(1-5) } -var clientConfig ClientConfig +func (p *ClientConfig) Local(port uint32) NetAddress { + for index := range p.LocalAddr { + if p.LocalAddr[index].Port2 == port { + return p.LocalAddr[index] + } + } + return NetAddress{} +} // 从参数中解析配置 func _parseClientConfig(args []string) ClientConfig { @@ -81,9 +88,7 @@ func _loadClientConfig() ClientConfig { // 初始化客户端配置,支持从参数中读取或者从配置文件中读取 func InitClientConfig(args []string) ClientConfig { if len(args) == 0 { - clientConfig = _loadClientConfig() - } else { - clientConfig = _parseClientConfig(args) + return _loadClientConfig() } - return clientConfig + return _parseClientConfig(args) } diff --git a/config/serverconfig.go b/config/serverconfig.go index c631abf923498fbc3ca78a9b468d6e74b4435bc9..a2f37c9210d14a349adfa853d29b6626e062f54b 100644 --- a/config/serverconfig.go +++ b/config/serverconfig.go @@ -19,8 +19,6 @@ func (c *ServerConfig) PortInRange(port uint32) bool { return port > c.MinAccessPort && port < c.MaxAccessPort } -var serverConfig ServerConfig - // 从参数中解析配置 func _parseServerConfig(args []string) ServerConfig { if len(args) < 2 { @@ -83,9 +81,7 @@ func _loadServerConfig() ServerConfig { // 初始化服务端配置,支持从参数中读取或者从配置文件中读取 func InitServerConfig(args []string) ServerConfig { if len(args) == 0 { - serverConfig = _loadServerConfig() - } else { - serverConfig = _parseServerConfig(args) + return _loadServerConfig() } - return serverConfig + return _parseServerConfig(args) } diff --git a/core/client.go b/core/client.go index ed29fc768bc9e41888328eeb18826ace24a0c9c2..c5cc15be01010d0a34bdc26972b5ffa81dbf97fe 100644 --- a/core/client.go +++ b/core/client.go @@ -1,25 +1,33 @@ package core import ( + "github.com/denisbrodbeck/machineid" "go-netbus/config" "log" "net" + "os" "runtime" + "strings" ) // 客户端ID,启动时就确定了 var clientID string func init() { - clientID = newUUID() - log.Println("Client ID :", clientID) + if id, err := machineid.ID(); err == nil { + clientID = strings.ReplaceAll(id, "-", "") + log.Println("Get client machine ID :", clientID) + } else { + log.Println("Fail to get machine ID") + os.Exit(0) + } } // 请求连接 func requestConnection(serverConn net.Conn, key string, port uint32) Protocol { request := Protocol{ Result: protocolResultSuccess, - Version: protocolVersion, + Version: Version, Port: port, ID: clientID, Key: key, @@ -37,10 +45,8 @@ func handleClientConnection(cfg config.ClientConfig, index int) { // 远程拨号,建桥 go buildTunnelConnection(cfg, index, connChan, flagChan) - // 本地连接拨号,并建立双向通道 go buildLocalConnection(cfg.LocalAddr[index], connChan, flagChan) - // 初始化连接 for i := 0; i < cfg.TunnelCount; i++ { flagChan <- true @@ -129,5 +135,6 @@ func Client(cfg config.ClientConfig) { for index := range cfg.LocalAddr { go handleClientConnection(cfg, index) } + select {} } diff --git a/core/common.go b/core/common.go index 78b224476beda2314228c3e39d5201456f6ef440..a12d36199d551803e216b1ab2be1388b6360f1f2 100644 --- a/core/common.go +++ b/core/common.go @@ -2,12 +2,10 @@ package core import ( "fmt" - uuid "github.com/satori/go.uuid" "go-netbus/config" "io" "log" "net" - "strings" "sync" "time" ) @@ -143,8 +141,3 @@ func accept(listener net.Listener) net.Conn { //log.Println("Accept a new client ->", conn.RemoteAddr()) return conn } - -// 返回长度固定为32位的 uuid -func newUUID() string { - return strings.ReplaceAll(uuid.NewV4().String(), "-", "") -} diff --git a/core/protocol.go b/core/protocol.go index 5e2c702cf15919ddfe2d1508004128308fd6fabe..d131625b2a22bf0fef09caa06b415a31c15300c3 100644 --- a/core/protocol.go +++ b/core/protocol.go @@ -21,15 +21,16 @@ const ( protocolResultPortIsOccupied = 7 // 访问端口被占用 // 协议发送超时时间 - protocolSendTimeout = 5 + protocolSendTimeout = 5 * time.Second // 协议接收超时时间 - protocolReceiveTimeout = 30 * 60 + protocolReceiveTimeout = 30 * 60 * time.Second // 版本序列(单调递增) - protocolVersion = 5 - - // 版本号 - Version = "1.3.0" + // 从右往左 + // 第1位为小版本号,用于修复BUG + // 第2位为次版本号,用于增删功能 + // 第3位为主版本号,用于结构等大的升级 + Version = 130 ) // 协议格式 @@ -110,7 +111,7 @@ func sendProtocol(conn net.Conn, req Protocol) bool { buffer.Write(req.Bytes()) // 设置写超时时间,避免连接断开的问题 - if err := conn.SetWriteDeadline(time.Now().Add(protocolSendTimeout * time.Second)); err != nil { + if err := conn.SetWriteDeadline(time.Now().Add(protocolSendTimeout)); err != nil { log.Println("Fail to set write deadline.", err.Error()) return false } @@ -135,7 +136,7 @@ func receiveProtocol(conn net.Conn) Protocol { var length byte // 设置读超时时间,避免连接断开的问题 - if err := conn.SetReadDeadline(time.Now().Add(protocolReceiveTimeout * time.Second)); err != nil { + if err := conn.SetReadDeadline(time.Now().Add(protocolReceiveTimeout)); err != nil { log.Println("Fail to set read deadline.", err.Error()) return Protocol{Result: protocolResultFailToReceive} } diff --git a/core/server.go b/core/server.go index b0e1063eddae9835a6f0fe9ff761a32a6a0ee428..eb1199dc35575b5b7cf86d4acb395d05b5e964e3 100644 --- a/core/server.go +++ b/core/server.go @@ -14,7 +14,7 @@ type TunnelConn struct { } func (p *TunnelConn) isTimeout() bool { - return p.createTime.Add(protocolReceiveTimeout * time.Second).Before(time.Now()) + return p.createTime.Add(protocolReceiveTimeout).Before(time.Now()) } func (p *TunnelConn) tryRelease() bool { @@ -37,20 +37,24 @@ type TunnelContext struct { // 尝试从连接池中获取可用连接 func (p *TunnelContext) tryConnection() net.Conn { for { + if len(p.connChan) == 0 { + log.Println("Fail to try connection") + return nil + } tunnelConn := <-p.connChan if tunnelConn.tryRelease() { + // 尝试释放过期连接 continue } + // 未过期连接 if sendProtocol(tunnelConn.conn, p.request.NewResult(protocolResultSuccess)) { return tunnelConn.conn - } else { - return nil } } } func (p *TunnelContext) isOffline() bool { - return p.lastTime.Add(protocolReceiveTimeout * time.Second).Before(time.Now()) + return p.lastTime.Add(protocolReceiveTimeout).Before(time.Now()) } func (p *TunnelContext) tryRelease() bool { @@ -143,7 +147,7 @@ func checkRequest(req Protocol, cfg config.ServerConfig) byte { return req.Result } // 检查版本号 - if req.Version != protocolVersion { + if req.Version != Version { log.Println("Version mismatch", req.String()) return protocolResultVersionMismatch } diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 105e22f7177467a5e674090e1d4134c608da96ef..ad8a7e24268b4ccbe61a35057fd9e06bfaec4528 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -49,7 +49,7 @@ - 修复网络波动等因素会导致服务端不能正常提供服务的问题 ## Version 1.3.0 -- 通讯协议增加客户端ID标识 +- 通讯协议增加客户端ID标识,使用机器码 - 服务端增加访问端口校验,一个访问端口不能被重复占用 - 增加超时机制,增加服务可用性 @@ -79,6 +79,7 @@ ```shell script # linux git pull +go env -w GOPROXY=https://goproxy.cn,direct go build -o netbus main.go mkdir netbus_linux_amd64 mv netbus netbus_linux_amd64 diff --git a/go.mod b/go.mod index 1955898f2e04caa08cbf80a3fe88220e73dbac4b..4e66fbc8cf56f6d8f3ea120ac06e8298e32c1507 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,8 @@ module go-netbus go 1.15 require ( + github.com/denisbrodbeck/machineid v1.0.1 github.com/go-ini/ini v1.60.2 - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/satori/go.uuid v1.2.0 github.com/smartystreets/goconvey v1.6.4 // indirect - gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect gopkg.in/ini.v1 v1.60.2 // indirect ) diff --git a/main.go b/main.go index e5d5c49ecc01cb3daca016e00d17a288808bad98..bfe3c2fb067cd5447153371b3e5db95c1ea3ae5f 100644 --- a/main.go +++ b/main.go @@ -12,10 +12,9 @@ func init() { log.SetFlags(log.Ldate | log.Ltime | log.LstdFlags) fmt.Println("+----------------------------------------------------------------+") - fmt.Println("| Welcome to use NetBus version 1.3.0 |") - fmt.Println("| Code by winshu, latest update at 2020/07/05 |") + fmt.Println("| Welcome to use NetBus, code by winshu |") fmt.Println("| If you have any problem when using the tool, |") - fmt.Println("| Please submit issue at : https://gitee.com/winshu/go-netbus |") + fmt.Println("| Please submit issue : https://gitee.com/winshu/go-netbus |") fmt.Println("+----------------------------------------------------------------+") fmt.Println() } diff --git a/test/netbus_test.go b/test/netbus_test.go index d4329192ee8b3eaa9ad62a11bffc8bec7bfdf580..00c0235e98d14469aa6b29722f3ef4defd389457 100644 --- a/test/netbus_test.go +++ b/test/netbus_test.go @@ -2,11 +2,10 @@ package test import ( "fmt" - "github.com/satori/go.uuid" + "github.com/denisbrodbeck/machineid" "go-netbus/config" "go-netbus/core" "log" - "strings" "testing" "time" ) @@ -55,9 +54,8 @@ func TestProtocol(t *testing.T) { fmt.Println(config.CheckKey(seed, key)) } -func TestGenerateUUID(t *testing.T) { - key := uuid.NewV4() - fmt.Println(strings.ReplaceAll(key.String(), "-", "")) +func TestGetMachineID(t *testing.T) { + fmt.Println(machineid.ID()) } func TestClient2(t *testing.T) { diff --git a/test/tcp_test.go b/test/tcp_test.go index 3634f8ea1e84906d329a516fabea9942cbe8a37e..cf6798a309bf800902aa024d361946fca92d378e 100644 --- a/test/tcp_test.go +++ b/test/tcp_test.go @@ -3,7 +3,7 @@ package test import ( "bytes" "encoding/binary" - uuid "github.com/satori/go.uuid" + "github.com/denisbrodbeck/machineid" "log" "net" "testing" @@ -46,7 +46,7 @@ func TestTCPClient(t *testing.T) { log.Println("dial failed") return } - body := uuid.NewV4().String() + body, _ := machineid.ID() var buf = make([]byte, 4) binary.BigEndian.PutUint32(buf, uint32(len(body)))