Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>

This commit is contained in:
arraykeys@gmail.com
2017-10-26 10:34:41 +08:00
parent ccca75ecbd
commit 2d225a6cdb
6 changed files with 161 additions and 71 deletions

View File

@ -25,7 +25,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
- ...   - ...  
本页是最新v3.3手册,其他版本手册请点击下面链接查看. 本页是v3.4手册,其他版本手册请点击下面链接查看.
- [v3.3手册](https://github.com/snail007/goproxy/tree/v3.3)
- [v3.2手册](https://github.com/snail007/goproxy/tree/v3.2) - [v3.2手册](https://github.com/snail007/goproxy/tree/v3.2)
- [v3.1手册](https://github.com/snail007/goproxy/tree/v3.1) - [v3.1手册](https://github.com/snail007/goproxy/tree/v3.1)
- [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0) - [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0)

View File

@ -6,7 +6,7 @@ fi
mkdir /tmp/proxy mkdir /tmp/proxy
cd /tmp/proxy cd /tmp/proxy
wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz
wget https://github.com/snail007/goproxy/releases/download/v3.3/proxy-linux-amd64.tar.gz wget https://github.com/snail007/goproxy/releases/download/v3.4/proxy-linux-amd64.tar.gz
# install monexec # install monexec
tar zxvf monexec_0.1.1_linux_amd64.tar.gz tar zxvf monexec_0.1.1_linux_amd64.tar.gz

View File

@ -6,15 +6,16 @@ import "golang.org/x/crypto/ssh"
// t := tcp.Flag("tcp-timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int() // t := tcp.Flag("tcp-timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
const ( const (
TYPE_TCP = "tcp" TYPE_TCP = "tcp"
TYPE_UDP = "udp" TYPE_UDP = "udp"
TYPE_HTTP = "http" TYPE_HTTP = "http"
TYPE_TLS = "tls" TYPE_TLS = "tls"
TYPE_KCP = "kcp" TYPE_KCP = "kcp"
CONN_CLIENT_CONTROL = uint8(1) CONN_CLIENT_CONTROL = uint8(1)
CONN_SERVER_CONTROL = uint8(2) CONN_CLIENT_HEARBEAT = uint8(2)
CONN_SERVER = uint8(3) CONN_SERVER_HEARBEAT = uint8(3)
CONN_CLIENT = uint8(4) CONN_SERVER = uint8(4)
CONN_CLIENT = uint8(5)
) )
type TunnelServerArgs struct { type TunnelServerArgs struct {

View File

@ -137,28 +137,15 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
} }
s.clientControlConns.Set(key, &inConn) s.clientControlConns.Set(key, &inConn)
log.Printf("set client %s control conn", key) log.Printf("set client %s control conn", key)
go func() {
for { case CONN_SERVER_HEARBEAT:
var b = make([]byte, 1)
_, err = inConn.Read(b)
if err != nil {
inConn.Close()
log.Printf("%s control conn from client released", key)
s.cmClient.Remove(key)
break
} else {
// log.Printf("heartbeat from client %s", key)
}
}
}()
case CONN_SERVER_CONTROL:
var serverID string var serverID string
err = utils.ReadPacketData(reader, &serverID) err = utils.ReadPacketData(reader, &serverID)
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) log.Printf("read error,ERR:%s", err)
return return
} }
log.Printf("server control connection, id: %s", serverID) log.Printf("server heartbeat connection, id: %s", serverID)
writeDie := make(chan bool) writeDie := make(chan bool)
readDie := make(chan bool) readDie := make(chan bool)
go func() { go func() {
@ -167,7 +154,7 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
_, err = inConn.Write([]byte{0x00}) _, err = inConn.Write([]byte{0x00})
inConn.SetWriteDeadline(time.Time{}) inConn.SetWriteDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("server control connection write err %s", err) log.Printf("server heartbeat connection write err %s", err)
break break
} }
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
@ -177,11 +164,11 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
go func() { go func() {
for { for {
signal := make([]byte, 1) signal := make([]byte, 1)
inConn.SetReadDeadline(time.Now().Add(time.Second * 10)) inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
_, err := inConn.Read(signal) _, err := inConn.Read(signal)
inConn.SetReadDeadline(time.Time{}) inConn.SetReadDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("server control connection read err: %s", err) log.Printf("server heartbeat connection read err: %s", err)
break break
} else { } else {
// log.Printf("heartbeat from server ,id:%s", serverID) // log.Printf("heartbeat from server ,id:%s", serverID)
@ -195,7 +182,57 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
} }
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
s.cmServer.Remove(serverID) s.cmServer.Remove(serverID)
log.Printf("server control conn %s released", serverID) log.Printf("server heartbeat conn %s released", serverID)
case CONN_CLIENT_HEARBEAT:
var clientID string
err = utils.ReadPacketData(reader, &clientID)
if err != nil {
log.Printf("read error,ERR:%s", err)
return
}
log.Printf("client heartbeat connection, id: %s", clientID)
writeDie := make(chan bool)
readDie := make(chan bool)
go func() {
for {
inConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
_, err = inConn.Write([]byte{0x00})
inConn.SetWriteDeadline(time.Time{})
if err != nil {
log.Printf("client heartbeat connection write err %s", err)
break
}
time.Sleep(time.Second * 3)
}
close(writeDie)
}()
go func() {
for {
signal := make([]byte, 1)
inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
_, err := inConn.Read(signal)
inConn.SetReadDeadline(time.Time{})
if err != nil {
log.Printf("client control connection read err: %s", err)
break
} else {
// log.Printf("heartbeat from client ,id:%s", clientID)
}
}
close(readDie)
}()
select {
case <-readDie:
case <-writeDie:
}
utils.CloseConn(&inConn)
s.cmClient.Remove(clientID)
if s.clientControlConns.Has(clientID) {
item, _ := s.clientControlConns.Get(clientID)
(*item.(*net.Conn)).Close()
}
s.clientControlConns.Remove(clientID)
log.Printf("client heartbeat conn %s released", clientID)
} }
}) })
if err != nil { if err != nil {

View File

@ -11,8 +11,9 @@ import (
) )
type TunnelClient struct { type TunnelClient struct {
cfg TunnelClientArgs cfg TunnelClientArgs
cm utils.ConnManager cm utils.ConnManager
ctrlConn net.Conn
} }
func NewTunnelClient() Service { func NewTunnelClient() Service {
@ -23,6 +24,65 @@ func NewTunnelClient() Service {
} }
func (s *TunnelClient) InitService() { func (s *TunnelClient) InitService() {
s.InitHeartbeatDeamon()
}
func (s *TunnelClient) InitHeartbeatDeamon() {
log.Printf("heartbeat started")
go func() {
var heartbeatConn net.Conn
var ID = *s.cfg.Key
for {
//close all connection
s.cm.RemoveAll()
if s.ctrlConn != nil {
s.ctrlConn.Close()
}
utils.CloseConn(&heartbeatConn)
heartbeatConn, err := s.GetInConn(CONN_CLIENT_HEARBEAT, ID)
if err != nil {
log.Printf("heartbeat connection err: %s, retrying...", err)
time.Sleep(time.Second * 3)
utils.CloseConn(&heartbeatConn)
continue
}
log.Printf("heartbeat connection created,id:%s", ID)
writeDie := make(chan bool)
readDie := make(chan bool)
go func() {
for {
heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
_, err = heartbeatConn.Write([]byte{0x00})
heartbeatConn.SetWriteDeadline(time.Time{})
if err != nil {
log.Printf("heartbeat connection write err %s", err)
break
}
time.Sleep(time.Second * 3)
}
close(writeDie)
}()
go func() {
for {
signal := make([]byte, 1)
heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
_, err := heartbeatConn.Read(signal)
heartbeatConn.SetReadDeadline(time.Time{})
if err != nil {
log.Printf("heartbeat connection read err: %s", err)
break
} else {
log.Printf("heartbeat from bridge")
}
}
close(readDie)
}()
select {
case <-readDie:
case <-writeDie:
}
}
}()
} }
func (s *TunnelClient) CheckArgs() { func (s *TunnelClient) CheckArgs() {
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
@ -43,40 +103,30 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
s.CheckArgs() s.CheckArgs()
s.InitService() s.InitService()
log.Printf("proxy on tunnel client mode") log.Printf("proxy on tunnel client mode")
var ctrlConn net.Conn
for { for {
//close all conn //close all conn
s.cm.Remove(*s.cfg.Key) s.cm.Remove(*s.cfg.Key)
utils.CloseConn(&ctrlConn) if s.ctrlConn != nil {
s.ctrlConn.Close()
}
ctrlConn, err = s.GetInConn(CONN_CLIENT_CONTROL, *s.cfg.Key) s.ctrlConn, err = s.GetInConn(CONN_CLIENT_CONTROL, *s.cfg.Key)
if err != nil { if err != nil {
log.Printf("control connection err: %s, retrying...", err) log.Printf("control connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
utils.CloseConn(&ctrlConn) if s.ctrlConn != nil {
s.ctrlConn.Close()
}
continue continue
} }
go func() {
for {
if ctrlConn == nil {
break
}
ctrlConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
_, err = ctrlConn.Write([]byte{0x00})
ctrlConn.SetWriteDeadline(time.Time{})
if err != nil {
utils.CloseConn(&ctrlConn)
log.Printf("ctrlConn err %s", err)
break
}
time.Sleep(time.Second * 3)
}
}()
for { for {
var ID, clientLocalAddr, serverID string var ID, clientLocalAddr, serverID string
err = utils.ReadPacketData(ctrlConn, &ID, &clientLocalAddr, &serverID) err = utils.ReadPacketData(s.ctrlConn, &ID, &clientLocalAddr, &serverID)
if err != nil { if err != nil {
utils.CloseConn(&ctrlConn) if s.ctrlConn != nil {
s.ctrlConn.Close()
}
log.Printf("read connection signal err: %s, retrying...", err) log.Printf("read connection signal err: %s, retrying...", err)
break break
} }

View File

@ -100,33 +100,34 @@ func (s *TunnelServerManager) CheckArgs() {
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile) s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
} }
func (s *TunnelServerManager) InitService() { func (s *TunnelServerManager) InitService() {
s.InitControlDeamon() s.InitHeartbeatDeamon()
} }
func (s *TunnelServerManager) InitControlDeamon() { func (s *TunnelServerManager) InitHeartbeatDeamon() {
log.Printf("heartbeat started")
go func() { go func() {
var ctrlConn net.Conn var heartbeatConn net.Conn
var ID string var ID string
for { for {
//close all connection //close all connection
s.cm.Remove(ID) s.cm.Remove(ID)
utils.CloseConn(&ctrlConn) utils.CloseConn(&heartbeatConn)
ctrlConn, ID, err := s.GetOutConn(CONN_SERVER_CONTROL) heartbeatConn, ID, err := s.GetOutConn(CONN_SERVER_HEARBEAT)
if err != nil { if err != nil {
log.Printf("control connection err: %s, retrying...", err) log.Printf("heartbeat connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
utils.CloseConn(&ctrlConn) utils.CloseConn(&heartbeatConn)
continue continue
} }
log.Printf("control connection created,id:%s", ID) log.Printf("heartbeat connection created,id:%s", ID)
writeDie := make(chan bool) writeDie := make(chan bool)
readDie := make(chan bool) readDie := make(chan bool)
go func() { go func() {
for { for {
ctrlConn.SetWriteDeadline(time.Now().Add(time.Second * 3)) heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
_, err = ctrlConn.Write([]byte{0x00}) _, err = heartbeatConn.Write([]byte{0x00})
ctrlConn.SetWriteDeadline(time.Time{}) heartbeatConn.SetWriteDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("control connection write err %s", err) log.Printf("heartbeat connection write err %s", err)
break break
} }
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
@ -136,11 +137,11 @@ func (s *TunnelServerManager) InitControlDeamon() {
go func() { go func() {
for { for {
signal := make([]byte, 1) signal := make([]byte, 1)
ctrlConn.SetReadDeadline(time.Now().Add(time.Second * 10)) heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
_, err := ctrlConn.Read(signal) _, err := heartbeatConn.Read(signal)
ctrlConn.SetReadDeadline(time.Time{}) heartbeatConn.SetReadDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("control connection read err: %s", err) log.Printf("heartbeat connection read err: %s", err)
break break
} else { } else {
// log.Printf("heartbeat from bridge") // log.Printf("heartbeat from bridge")