From 977b1aba1c777025e4b2a83befce8dd94a676d14 Mon Sep 17 00:00:00 2001 From: arraykeys Date: Sat, 2 Dec 2017 14:02:17 +0800 Subject: [PATCH] no message --- CHANGELOG | 5 ++++ README.md | 20 +++++++++------ config.go | 2 ++ services/args.go | 55 +++++++++++++++++++++-------------------- services/mux_bridge.go | 19 ++------------ services/mux_client.go | 31 ++++++++++++++++++++--- services/mux_server.go | 56 +++++++++++++++++++++++++++++------------- 7 files changed, 117 insertions(+), 71 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7b80d0e..3f09407 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,9 @@ proxy更新日志 +v4.0 +1.内网穿透三端重构了一个multiplexing版本,对应的子命令分别是server,client,bridge + 使用方式和参数与之前的子命令tserver,tclient,tserver完全一样,另外server,client增加了 + 压缩传输参数--c,使用压缩传输速度更快。 + v3.9 1.增加了守护运行参数--forever,比如: proxy http --forever , proxy会fork子进程,然后监控子进程,如果子进程异常退出,5秒后重启子进程. diff --git a/README.md b/README.md index 4fc088c..d7fc87e 100644 --- a/README.md +++ b/README.md @@ -352,12 +352,19 @@ VPS(IP:22.22.22.33)执行: ### **4.内网穿透** #### **4.1、原理说明** -内网穿透,由三部分组成:client端,server端,bridge端;client和server主动连接bridge端进行桥接. -当用户访问server端,流程是: -1. server主动和bridge端建立连接; -1. 然后bridge端通知client端连接bridge端,并连接内网目标端口; -1. 然后绑定client端到bridge端和client端到内网端口的连接; -1. 然后bridge端把client过来的连接与server端过来的连接绑定; +内网穿透,分为两个版本。 +1. 多链接版本,对应的子命令是tserver,tclient,tbridge。 +1. 多路复用版本,对应的子命令是server,client,bridge。 +1. 多链接版本和多路复用版本的参数和使用方式完全一样。 +1. **多路复用版本的server,client可以开启压缩传输,参数是--c。** +1. **server,client要么都开启压缩,要么都不开启,不能只开一个。** +下面的教程以“多链接版本”为例子,说明使用方法。 +内网穿透由三部分组成:tclient端,tserver端,tbridge端;tclient和tserver主动连接tbridge端进行桥接. +当用户访问tserver端,流程是: +1. tserver主动和tbridge端建立连接; +1. 然后tbridge端通知tclient端连接tbridge端,并连接内网目标端口; +1. 然后绑定tclient端到tbridge端和tclient端到内网端口的连接; +1. 然后tbridge端把tclient过来的连接与tserver端过来的连接绑定; 1. 整个通道建立完成; #### **4.2、TCP普通用法** @@ -571,7 +578,6 @@ KCP协议需要-B参数设置一个密码用于加密解密数据 ### TODO - http,socks代理多个上级负载均衡? -- 内网穿透增加multiplexing模式? - 欢迎加群反馈... ### 如何使用源码? diff --git a/config.go b/config.go index d8e1e9d..190faa2 100755 --- a/config.go +++ b/config.go @@ -111,6 +111,7 @@ func initConfig() (err error) { muxServerArgs.IsUDP = muxServer.Flag("udp", "proxy on udp mux server mode").Default("false").Bool() muxServerArgs.Key = muxServer.Flag("k", "client key").Default("default").String() muxServerArgs.Route = muxServer.Flag("route", "local route to client's network, such as: PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings() + muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp mode").Default("false").Bool() //########mux-client######### muxClient := app.Command("client", "proxy on mux client mode").Hidden() @@ -119,6 +120,7 @@ func initConfig() (err error) { muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int() muxClientArgs.Key = muxClient.Flag("k", "key same with server").Default("default").String() + muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp mode").Default("false").Bool() //########mux-bridge######### muxBridge := app.Command("bridge", "proxy on mux bridge mode").Hidden() diff --git a/services/args.go b/services/args.go index d5cb9d7..3a845f6 100644 --- a/services/args.go +++ b/services/args.go @@ -21,36 +21,39 @@ const ( ) type MuxServerArgs struct { - Parent *string - CertFile *string - KeyFile *string - CertBytes []byte - KeyBytes []byte - Local *string - IsUDP *bool - Key *string - Remote *string - Timeout *int - Route *[]string - Mgr *MuxServerManager + Parent *string + CertFile *string + KeyFile *string + CertBytes []byte + KeyBytes []byte + Local *string + IsUDP *bool + Key *string + Remote *string + Timeout *int + Route *[]string + Mgr *MuxServerManager + IsCompress *bool } type MuxClientArgs struct { - Parent *string - CertFile *string - KeyFile *string - CertBytes []byte - KeyBytes []byte - Key *string - Timeout *int + Parent *string + CertFile *string + KeyFile *string + CertBytes []byte + KeyBytes []byte + Key *string + Timeout *int + IsCompress *bool } type MuxBridgeArgs struct { - Parent *string - CertFile *string - KeyFile *string - CertBytes []byte - KeyBytes []byte - Local *string - Timeout *int + Parent *string + CertFile *string + KeyFile *string + CertBytes []byte + KeyBytes []byte + Local *string + Timeout *int + IsCompress *bool } type TunnelServerArgs struct { Parent *string diff --git a/services/mux_bridge.go b/services/mux_bridge.go index f6899ae..f6bc0ab 100644 --- a/services/mux_bridge.go +++ b/services/mux_bridge.go @@ -97,15 +97,6 @@ func (s *MuxBridge) Clean() { s.StopService() } func (s *MuxBridge) callback(inConn net.Conn, key string) { - reader := bufio.NewReader(inConn) - var err error - var ID, clientLocalAddr, serverID string - err = utils.ReadPacketData(reader, &ID, &clientLocalAddr, &serverID) - if err != nil { - log.Printf("read error,ERR:%s", err) - return - } - packet := utils.BuildPacketData(ID, clientLocalAddr, serverID) try := 20 for { try-- @@ -124,13 +115,7 @@ func (s *MuxBridge) callback(inConn net.Conn, key string) { time.Sleep(time.Second * 3) continue } else { - _, err := stream.Write(packet) - if err != nil { - log.Printf("server %s stream write fail, err: %s, retrying...", key, err) - time.Sleep(time.Second * 3) - continue - } - log.Printf("server stream %s created", ID) + log.Printf("%s stream created", key) die1 := make(chan bool, 1) die2 := make(chan bool, 1) go func() { @@ -147,7 +132,7 @@ func (s *MuxBridge) callback(inConn net.Conn, key string) { } stream.Close() inConn.Close() - log.Printf("server stream %s released", ID) + log.Printf("%s stream released", key) break } } diff --git a/services/mux_client.go b/services/mux_client.go index 8b6c400..c2cdf55 100644 --- a/services/mux_client.go +++ b/services/mux_client.go @@ -2,11 +2,13 @@ package services import ( "crypto/tls" + "io" "log" "net" "proxy/utils" "time" + "github.com/golang/snappy" "github.com/xtaci/smux" ) @@ -42,7 +44,7 @@ func (s *MuxClient) Start(args interface{}) (err error) { s.cfg = args.(MuxClientArgs) s.CheckArgs() s.InitService() - log.Printf("proxy on mux client mode") + log.Printf("proxy on mux client mode, compress %v", *s.cfg.IsCompress) for { var _conn tls.Conn _conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes) @@ -176,8 +178,29 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) { log.Printf("build connection error, err: %s", err) return } - utils.IoBind(inConn, outConn, func(err interface{}) { - log.Printf("conn %s released", ID) - }) + log.Printf("conn %s created", ID) + if *s.cfg.IsCompress { + die1 := make(chan bool, 1) + die2 := make(chan bool, 1) + go func() { + io.Copy(outConn, snappy.NewReader(inConn)) + die1 <- true + }() + go func() { + io.Copy(snappy.NewWriter(inConn), outConn) + die2 <- true + }() + select { + case <-die1: + case <-die2: + } + outConn.Close() + inConn.Close() + log.Printf("%s stream %s released", *s.cfg.Key, ID) + } else { + utils.IoBind(inConn, outConn, func(err interface{}) { + log.Printf("conn %s released", ID) + }) + } } diff --git a/services/mux_server.go b/services/mux_server.go index 4d9ca95..204d3bc 100644 --- a/services/mux_server.go +++ b/services/mux_server.go @@ -3,6 +3,7 @@ package services import ( "crypto/tls" "fmt" + "io" "log" "net" "proxy/utils" @@ -11,6 +12,7 @@ import ( "strings" "time" + "github.com/golang/snappy" "github.com/xtaci/smux" ) @@ -72,17 +74,18 @@ func (s *MuxServerManager) Start(args interface{}) (err error) { remote = fmt.Sprintf("127.0.0.1%s", remote) } err = server.Start(MuxServerArgs{ - CertBytes: s.cfg.CertBytes, - KeyBytes: s.cfg.KeyBytes, - Parent: s.cfg.Parent, - CertFile: s.cfg.CertFile, - KeyFile: s.cfg.KeyFile, - Local: &local, - IsUDP: &IsUDP, - Remote: &remote, - Key: &KEY, - Timeout: s.cfg.Timeout, - Mgr: s, + CertBytes: s.cfg.CertBytes, + KeyBytes: s.cfg.KeyBytes, + Parent: s.cfg.Parent, + CertFile: s.cfg.CertFile, + KeyFile: s.cfg.KeyFile, + Local: &local, + IsUDP: &IsUDP, + Remote: &remote, + Key: &KEY, + Timeout: s.cfg.Timeout, + Mgr: s, + IsCompress: s.cfg.IsCompress, }) if err != nil { @@ -167,16 +170,35 @@ func (s *MuxServer) Start(args interface{}) (err error) { break } } - utils.IoBind(inConn, outConn, func(err interface{}) { - log.Printf("%s conn %s released", *s.cfg.Key, ID) - }) - //add conn - log.Printf("%s conn %s created", *s.cfg.Key, ID) + log.Printf("%s stream %s created", *s.cfg.Key, ID) + if *s.cfg.IsCompress { + die1 := make(chan bool, 1) + die2 := make(chan bool, 1) + go func() { + io.Copy(inConn, snappy.NewReader(outConn)) + die1 <- true + }() + go func() { + io.Copy(snappy.NewWriter(outConn), inConn) + die2 <- true + }() + select { + case <-die1: + case <-die2: + } + outConn.Close() + inConn.Close() + log.Printf("%s stream %s released", *s.cfg.Key, ID) + } else { + utils.IoBind(inConn, outConn, func(err interface{}) { + log.Printf("%s conn %s released", *s.cfg.Key, ID) + }) + } }) if err != nil { return } - log.Printf("proxy on mux server mode %s", (*s.sc.Listener).Addr()) + log.Printf("proxy on mux server mode %s, compress %v", (*s.sc.Listener).Addr(), *s.cfg.IsCompress) } return }