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.1手册](https://github.com/snail007/goproxy/tree/v3.1)
- [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0)

View File

@ -6,7 +6,7 @@ fi
mkdir /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/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
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()
const (
TYPE_TCP = "tcp"
TYPE_UDP = "udp"
TYPE_HTTP = "http"
TYPE_TLS = "tls"
TYPE_KCP = "kcp"
CONN_CLIENT_CONTROL = uint8(1)
CONN_SERVER_CONTROL = uint8(2)
CONN_SERVER = uint8(3)
CONN_CLIENT = uint8(4)
TYPE_TCP = "tcp"
TYPE_UDP = "udp"
TYPE_HTTP = "http"
TYPE_TLS = "tls"
TYPE_KCP = "kcp"
CONN_CLIENT_CONTROL = uint8(1)
CONN_CLIENT_HEARBEAT = uint8(2)
CONN_SERVER_HEARBEAT = uint8(3)
CONN_SERVER = uint8(4)
CONN_CLIENT = uint8(5)
)
type TunnelServerArgs struct {

View File

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

View File

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