From 317743fed855c5b20c96fb1b12a80e2011d91a4e Mon Sep 17 00:00:00 2001 From: "dmy@lab" Date: Sat, 24 Oct 2015 16:30:10 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=A5=BD=E4=BA=86=EF=BC=8C?= =?UTF-8?q?=E6=8A=8Atunnel=E5=8D=95=E7=8B=AC=E6=8B=BF=E5=87=BA=E6=9D=A5?= =?UTF-8?q?=E4=BA=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dmy@lab --- tcp.go | 80 +++--------------------------------------- tunnel.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 76 deletions(-) create mode 100644 tunnel.go diff --git a/tcp.go b/tcp.go index 9775244..2c12f56 100644 --- a/tcp.go +++ b/tcp.go @@ -1,24 +1,11 @@ package main import ( - "bytes" - "crypto/md5" - "encoding/hex" "github.com/TransX/log" - "github.com/TransX/tscipher" "net" "os" - "strconv" - "sync/atomic" - "time" ) -var seed int32 - -func init() { - seed = 0 -} - type TransTCP struct { } @@ -50,61 +37,6 @@ func (this *TransTCP) createTCPListener(ip, port string) (listen net.Listener, e return } -func (this *TransTCP) tunnel(src, dest net.Conn, id string, encrypDirection string) { //单向的,从src发送到dest - defer func() { - if r := recover(); r != nil { - if src != nil { - src.Close() - } - if dest != nil { - dest.Close() - } - - } - }() - cache := make([]byte, 1024*2) //128kB - for { - //构建Carrier - revCarrier := &tscipher.Carrier{ - src, - tscipher.NewCipher("XOR"), - cache, - } - log.Debug("Encrypt Direction %s ID %s", encrypDirection, id) - if encrypDirection != "receive" { - revCarrier.Cipher = nil - log.Debug("Read not crypted. Tunnel: %s", id) - } - nByte, err := tscipher.ReceiveData(revCarrier) - if err != nil { - log.Panic("Read panic. Tunnel id: %s. Remote Add: %s. Err:%s", id, src.RemoteAddr().String(), err) - } - log.Info("Reived %d bytes from %s. Tunnel: id %s", nByte, src.RemoteAddr().String(), id) - sendCarrier := &tscipher.Carrier{ - dest, - tscipher.NewCipher("XOR"), - cache, //TODO:危险,cache的容量容易被不小心修改 - } - if encrypDirection != "send" { - sendCarrier.Cipher = nil - log.Debug("Write not crypted. Tunnel: %s", id) - } - n, err := tscipher.SendData(sendCarrier, nByte) - log.Info("Write %d bytes from %s to %s. Tunnel: %s", n, dest.LocalAddr(), dest.RemoteAddr().String(), id) - if err != nil { - log.Panic("Write panic. ID: %s, Err: %s, Remote Add: %s", id, err, dest.RemoteAddr().String()) - } - } - -} - -func (this *TransTCP) tunnelID() string { - nowString := time.Now().String() + strconv.Itoa(int(seed)) - atomic.AddInt32(&seed, 1) //避免多线程情况下获得的种子相同 - md5Byte := md5.Sum(bytes.NewBufferString(nowString).Bytes()) - return hex.EncodeToString(md5Byte[:]) -} - func (this *TransTCP) Start(listenPort, destIP, destPort string, clientOrServer string) { listener, err := this.createTCPListener("0.0.0.0", listenPort) if err != nil { @@ -123,17 +55,13 @@ func (this *TransTCP) Start(listenPort, destIP, destPort string, clientOrServer } log.Info("Dial %s", destConn.RemoteAddr().String()) //tunnel model : [ -->>server ---- client -->> ](this is a tunnel) - tunnelIDA := this.tunnelID() - tunnelIDB := this.tunnelID() if clientOrServer == "client" { - go this.tunnel(listenerConn, destConn, tunnelIDA, "send") - go this.tunnel(destConn, listenerConn, tunnelIDB, "receive") - log.Debug("two tunnel created: %s %s %s %s", tunnelIDA, "send", tunnelIDB, "receive") + go NewTunnel(listenerConn, destConn, "send").run() + go NewTunnel(destConn, listenerConn, "receive").run() } if clientOrServer == "server" { - go this.tunnel(listenerConn, destConn, tunnelIDA, "receive") - go this.tunnel(destConn, listenerConn, tunnelIDB, "send") - log.Debug("two tunnel created: %s %s %s %s", tunnelIDA, "receive", tunnelIDB, "send") + go NewTunnel(listenerConn, destConn, "receive").run() + go NewTunnel(destConn, listenerConn, "send").run() } }() diff --git a/tunnel.go b/tunnel.go new file mode 100644 index 0000000..2f48d4a --- /dev/null +++ b/tunnel.go @@ -0,0 +1,103 @@ +package main + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "github.com/TransX/log" + "github.com/TransX/tscipher" + "net" + "strconv" + "sync/atomic" + "time" +) + +var seed int32 + +func init() { + seed = 0 +} + +type Tunnel struct { + id string + src net.Conn + dest net.Conn + cipherDirection string +} + +func NewTunnel(src, dest net.Conn, cipherDirection string) *Tunnel { + return &Tunnel{ + id: tunnelID(), + src: src, + dest: dest, + cipherDirection: cipherDirection, + } +} + +func (this *Tunnel) GetID(id string) string { + return this.id +} + +func (this *Tunnel) SetID(id string) { //rarely used + this.id = id +} + +//tunnel model : [ -->>server ---- client -->> ](this is a tunnel) +func (this *Tunnel) run() { //单向的,从src发送到dest + src := this.src + dest := this.dest + cipherDirection := this.cipherDirection + id := this.id + defer func() { + if r := recover(); r != nil { + if src != nil { + src.Close() + } + if dest != nil { + dest.Close() + } + + } + }() + cache := make([]byte, 1024*2) //128kB + for { + //构建Carrier + revCarrier := &tscipher.Carrier{ + src, + tscipher.NewCipher("XOR"), + cache, + } + log.Debug("Encrypt Direction %s ID %s", cipherDirection, id) + if cipherDirection != "receive" { + revCarrier.Cipher = nil + log.Debug("Read not crypted. Tunnel: %s", id) + } + nByte, err := tscipher.ReceiveData(revCarrier) + if err != nil { + log.Panic("Read panic. Tunnel id: %s. Remote Add: %s. Err:%s", id, src.RemoteAddr().String(), err) + } + log.Info("Reived %d bytes from %s. Tunnel: id %s", nByte, src.RemoteAddr().String(), id) + sendCarrier := &tscipher.Carrier{ + dest, + tscipher.NewCipher("XOR"), + cache, //TODO:危险,cache的容量容易被不小心修改 + } + if cipherDirection != "send" { + sendCarrier.Cipher = nil + log.Debug("Write not crypted. Tunnel: %s", id) + } + n, err := tscipher.SendData(sendCarrier, nByte) + log.Info("Write %d bytes from %s to %s. Tunnel: %s", n, dest.LocalAddr(), dest.RemoteAddr().String(), id) + if err != nil { + log.Panic("Write panic. ID: %s, Err: %s, Remote Add: %s", id, err, dest.RemoteAddr().String()) + } + } + +} + +func tunnelID() string { + nowString := time.Now().String() + strconv.Itoa(int(seed)) + atomic.AddInt32(&seed, 1) //避免多线程情况下获得的种子相同 + md5Byte := md5.Sum(bytes.NewBufferString(nowString).Bytes()) + return hex.EncodeToString(md5Byte[:]) +}