Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
12
config.go
12
config.go
@ -103,17 +103,17 @@ func initConfig() (err error) {
|
|||||||
udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
|
|
||||||
//########mux-server#########
|
//########mux-server#########
|
||||||
muxServer := app.Command("server", "proxy on mux server mode")
|
muxServer := app.Command("server", "proxy on mux server mode").Hidden()
|
||||||
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||||
muxServerArgs.IsUDP = muxServer.Flag("udp", "proxy on udp mux server mode").Default("false").Bool()
|
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.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.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()
|
||||||
|
|
||||||
//########mux-client#########
|
//########mux-client#########
|
||||||
muxClient := app.Command("client", "proxy on mux client mode")
|
muxClient := app.Command("client", "proxy on mux client mode").Hidden()
|
||||||
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
@ -121,7 +121,7 @@ func initConfig() (err error) {
|
|||||||
muxClientArgs.Key = muxClient.Flag("k", "key same with server").Default("default").String()
|
muxClientArgs.Key = muxClient.Flag("k", "key same with server").Default("default").String()
|
||||||
|
|
||||||
//########mux-bridge#########
|
//########mux-bridge#########
|
||||||
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
muxBridge := app.Command("bridge", "proxy on mux bridge mode").Hidden()
|
||||||
muxBridgeArgs.CertFile = muxBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxBridgeArgs.CertFile = muxBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||||
@ -135,7 +135,7 @@ func initConfig() (err error) {
|
|||||||
tunnelServerArgs.Timeout = tunnelServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
tunnelServerArgs.Timeout = tunnelServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||||
tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
|
tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
|
||||||
tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
|
tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
|
||||||
tunnelServerArgs.Route = tunnelServer.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()
|
tunnelServerArgs.Route = tunnelServer.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()
|
||||||
|
|
||||||
//########tunnel-client#########
|
//########tunnel-client#########
|
||||||
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
|
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
|
||||||
@ -259,7 +259,7 @@ func initConfig() (err error) {
|
|||||||
log.Printf("ERR:%s,restarting...", err)
|
log.Printf("ERR:%s,restarting...", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Printf("%s [PID] %d unexpected exited, restarting...\n", os.Args[0], pid)
|
log.Printf("worker %s [PID] %d unexpected exited, restarting...\n", os.Args[0], pid)
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"proxy/utils"
|
"proxy/utils"
|
||||||
@ -11,20 +12,14 @@ import (
|
|||||||
"github.com/xtaci/smux"
|
"github.com/xtaci/smux"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MuxServerConn struct {
|
|
||||||
//ClientLocalAddr string //tcp:2.2.22:333@ID
|
|
||||||
Conn *net.Conn
|
|
||||||
}
|
|
||||||
type MuxBridge struct {
|
type MuxBridge struct {
|
||||||
cfg MuxBridgeArgs
|
cfg MuxBridgeArgs
|
||||||
serverConns utils.ConcurrentMap
|
|
||||||
clientControlConns utils.ConcurrentMap
|
clientControlConns utils.ConcurrentMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMuxBridge() Service {
|
func NewMuxBridge() Service {
|
||||||
return &MuxBridge{
|
return &MuxBridge{
|
||||||
cfg: MuxBridgeArgs{},
|
cfg: MuxBridgeArgs{},
|
||||||
serverConns: utils.NewConcurrentMap(),
|
|
||||||
clientControlConns: utils.NewConcurrentMap(),
|
clientControlConns: utils.NewConcurrentMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,31 +46,46 @@ func (s *MuxBridge) Start(args interface{}) (err error) {
|
|||||||
|
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, func(inConn net.Conn) {
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, func(inConn net.Conn) {
|
||||||
reader := bufio.NewReader(inConn)
|
reader := bufio.NewReader(inConn)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var connType uint8
|
var connType uint8
|
||||||
err = utils.ReadPacket(reader, &connType)
|
var key string
|
||||||
|
err = utils.ReadPacket(reader, &connType, &key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("read error,ERR:%s", err)
|
log.Printf("read error,ERR:%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch connType {
|
switch connType {
|
||||||
case CONN_SERVER:
|
case CONN_SERVER:
|
||||||
|
log.Printf("server connection %s", key)
|
||||||
session, err := smux.Server(inConn, nil)
|
session, err := smux.Server(inConn, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.CloseConn(&inConn)
|
utils.CloseConn(&inConn)
|
||||||
log.Printf("server underlayer connection error,ERR:%s", err)
|
log.Printf("server session error,ERR:%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn, err := session.AcceptStream()
|
for {
|
||||||
|
stream, err := session.AcceptStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.Close()
|
session.Close()
|
||||||
utils.CloseConn(&inConn)
|
utils.CloseConn(&inConn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("server connection %s", conn.RemoteAddr())
|
go s.callback(stream, key)
|
||||||
//s.callback(conn)
|
|
||||||
}
|
}
|
||||||
s.callback(inConn)
|
case CONN_CLIENT:
|
||||||
|
|
||||||
|
log.Printf("client connection %s", key)
|
||||||
|
session, err := smux.Client(inConn, nil)
|
||||||
|
if err != nil {
|
||||||
|
utils.CloseConn(&inConn)
|
||||||
|
log.Printf("client session error,ERR:%s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.clientControlConns.Set(key, session)
|
||||||
|
//log.Printf("set client session,key: %s", key)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -86,86 +96,48 @@ func (s *MuxBridge) Start(args interface{}) (err error) {
|
|||||||
func (s *MuxBridge) Clean() {
|
func (s *MuxBridge) Clean() {
|
||||||
s.StopService()
|
s.StopService()
|
||||||
}
|
}
|
||||||
func (s *MuxBridge) callback(inConn net.Conn) {
|
func (s *MuxBridge) callback(inConn net.Conn, key string) {
|
||||||
reader := bufio.NewReader(inConn)
|
reader := bufio.NewReader(inConn)
|
||||||
var err error
|
var err error
|
||||||
var connType uint8
|
var ID, clientLocalAddr, serverID string
|
||||||
err = utils.ReadPacket(reader, &connType)
|
err = utils.ReadPacketData(reader, &ID, &clientLocalAddr, &serverID)
|
||||||
if err != nil {
|
|
||||||
log.Printf("read error,ERR:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch connType {
|
|
||||||
case CONN_SERVER:
|
|
||||||
var key, ID, clientLocalAddr, serverID string
|
|
||||||
err = utils.ReadPacketData(reader, &key, &ID, &clientLocalAddr, &serverID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("read error,ERR:%s", err)
|
log.Printf("read error,ERR:%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
packet := utils.BuildPacketData(ID, clientLocalAddr, serverID)
|
packet := utils.BuildPacketData(ID, clientLocalAddr, serverID)
|
||||||
log.Printf("server connection, key: %s , id: %s %s %s", key, ID, clientLocalAddr, serverID)
|
try := 20
|
||||||
|
|
||||||
//addr := clientLocalAddr + "@" + ID
|
|
||||||
s.serverConns.Set(ID, MuxServerConn{
|
|
||||||
Conn: &inConn,
|
|
||||||
})
|
|
||||||
for {
|
for {
|
||||||
item, ok := s.clientControlConns.Get(key)
|
try--
|
||||||
|
if try == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
session, ok := s.clientControlConns.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Printf("client %s control conn not exists", key)
|
log.Printf("client %s session not exists", key)
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
(*item.(*net.Conn)).SetWriteDeadline(time.Now().Add(time.Second * 3))
|
stream, err := session.(*smux.Session).OpenStream()
|
||||||
_, err := (*item.(*net.Conn)).Write(packet)
|
|
||||||
(*item.(*net.Conn)).SetWriteDeadline(time.Time{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s client control conn write signal fail, err: %s, retrying...", key, err)
|
log.Printf("%s client session open stream fail, err: %s, retrying...", key, err)
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
continue
|
continue
|
||||||
} else {
|
} 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)
|
||||||
|
go io.Copy(stream, inConn)
|
||||||
|
io.Copy(inConn, stream)
|
||||||
|
stream.Close()
|
||||||
|
inConn.Close()
|
||||||
|
log.Printf("server stream %s released", ID)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case CONN_CLIENT:
|
|
||||||
var key, ID, serverID string
|
|
||||||
err = utils.ReadPacketData(reader, &key, &ID, &serverID)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("read error,ERR:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Printf("client connection , key: %s , id: %s, server id:%s", key, ID, serverID)
|
|
||||||
|
|
||||||
serverConnItem, ok := s.serverConns.Get(ID)
|
|
||||||
if !ok {
|
|
||||||
inConn.Close()
|
|
||||||
log.Printf("server conn %s exists", ID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
serverConn := serverConnItem.(MuxServerConn).Conn
|
|
||||||
utils.IoBind(*serverConn, inConn, func(err interface{}) {
|
|
||||||
s.serverConns.Remove(ID)
|
|
||||||
// s.cmClient.RemoveOne(key, ID)
|
|
||||||
// s.cmServer.RemoveOne(serverID, ID)
|
|
||||||
log.Printf("conn %s released", ID)
|
|
||||||
})
|
|
||||||
// s.cmClient.Add(key, ID, &inConn)
|
|
||||||
log.Printf("conn %s created", ID)
|
|
||||||
|
|
||||||
case CONN_CLIENT_CONTROL:
|
|
||||||
var key string
|
|
||||||
err = utils.ReadPacketData(reader, &key)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("read error,ERR:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Printf("client control connection, key: %s", key)
|
|
||||||
if s.clientControlConns.Has(key) {
|
|
||||||
item, _ := s.clientControlConns.Get(key)
|
|
||||||
(*item.(*net.Conn)).Close()
|
|
||||||
}
|
|
||||||
s.clientControlConns.Set(key, &inConn)
|
|
||||||
log.Printf("set client %s control conn", key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,89 +2,28 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"proxy/utils"
|
"proxy/utils"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/xtaci/smux"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MuxClient struct {
|
type MuxClient struct {
|
||||||
cfg MuxClientArgs
|
cfg MuxClientArgs
|
||||||
// cm utils.ConnManager
|
|
||||||
ctrlConn net.Conn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMuxClient() Service {
|
func NewMuxClient() Service {
|
||||||
return &MuxClient{
|
return &MuxClient{
|
||||||
cfg: MuxClientArgs{},
|
cfg: MuxClientArgs{},
|
||||||
// cm: utils.NewConnManager(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MuxClient) InitService() {
|
func (s *MuxClient) InitService() {
|
||||||
// s.InitHeartbeatDeamon()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (s *MuxClient) 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 *MuxClient) CheckArgs() {
|
func (s *MuxClient) CheckArgs() {
|
||||||
if *s.cfg.Parent != "" {
|
if *s.cfg.Parent != "" {
|
||||||
log.Printf("use tls parent %s", *s.cfg.Parent)
|
log.Printf("use tls parent %s", *s.cfg.Parent)
|
||||||
@ -97,37 +36,47 @@ func (s *MuxClient) 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 *MuxClient) StopService() {
|
func (s *MuxClient) StopService() {
|
||||||
// s.cm.RemoveAll()
|
|
||||||
}
|
}
|
||||||
func (s *MuxClient) Start(args interface{}) (err error) {
|
func (s *MuxClient) Start(args interface{}) (err error) {
|
||||||
s.cfg = args.(MuxClientArgs)
|
s.cfg = args.(MuxClientArgs)
|
||||||
s.CheckArgs()
|
s.CheckArgs()
|
||||||
s.InitService()
|
s.InitService()
|
||||||
log.Printf("proxy on tunnel client mode")
|
log.Printf("proxy on mux client mode")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
//close all conn
|
var _conn tls.Conn
|
||||||
// s.cm.Remove(*s.cfg.Key)
|
_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
||||||
if s.ctrlConn != nil {
|
|
||||||
s.ctrlConn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
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("connection err: %s, retrying...", err)
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
if s.ctrlConn != nil {
|
continue
|
||||||
s.ctrlConn.Close()
|
|
||||||
}
|
}
|
||||||
|
conn := net.Conn(&_conn)
|
||||||
|
_, err = conn.Write(utils.BuildPacket(CONN_CLIENT, *s.cfg.Key))
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
log.Printf("connection err: %s, retrying...", err)
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
session, err := smux.Server(conn, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("session err: %s, retrying...", err)
|
||||||
|
conn.Close()
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var ID, clientLocalAddr, serverID string
|
stream, err := session.AcceptStream()
|
||||||
err = utils.ReadPacketData(s.ctrlConn, &ID, &clientLocalAddr, &serverID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if s.ctrlConn != nil {
|
log.Printf("accept stream err: %s, retrying...", err)
|
||||||
s.ctrlConn.Close()
|
session.Close()
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
var ID, clientLocalAddr, serverID string
|
||||||
|
err = utils.ReadPacketData(stream, &ID, &clientLocalAddr, &serverID)
|
||||||
|
if err != nil {
|
||||||
log.Printf("read connection signal err: %s, retrying...", err)
|
log.Printf("read connection signal err: %s, retrying...", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -135,78 +84,40 @@ func (s *MuxClient) Start(args interface{}) (err error) {
|
|||||||
protocol := clientLocalAddr[:3]
|
protocol := clientLocalAddr[:3]
|
||||||
localAddr := clientLocalAddr[4:]
|
localAddr := clientLocalAddr[4:]
|
||||||
if protocol == "udp" {
|
if protocol == "udp" {
|
||||||
go s.ServeUDP(localAddr, ID, serverID)
|
go s.ServeUDP(stream, localAddr, ID)
|
||||||
} else {
|
} else {
|
||||||
go s.ServeConn(localAddr, ID, serverID)
|
go s.ServeConn(stream, localAddr, ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func (s *MuxClient) Clean() {
|
func (s *MuxClient) Clean() {
|
||||||
s.StopService()
|
s.StopService()
|
||||||
}
|
}
|
||||||
func (s *MuxClient) GetInConn(typ uint8, data ...string) (outConn net.Conn, err error) {
|
|
||||||
outConn, err = s.GetConn()
|
func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("connection err: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = outConn.Write(utils.BuildPacket(typ, data...))
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("write connection data err: %s ,retrying...", err)
|
|
||||||
utils.CloseConn(&outConn)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (s *MuxClient) GetConn() (conn net.Conn, err error) {
|
|
||||||
var _conn tls.Conn
|
|
||||||
_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
|
||||||
if err == nil {
|
|
||||||
conn = net.Conn(&_conn)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (s *MuxClient) ServeUDP(localAddr, ID, serverID string) {
|
|
||||||
var inConn net.Conn
|
|
||||||
var err error
|
|
||||||
// for {
|
|
||||||
for {
|
|
||||||
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
|
||||||
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
|
|
||||||
if err != nil {
|
|
||||||
utils.CloseConn(&inConn)
|
|
||||||
log.Printf("connection err: %s, retrying...", err)
|
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// s.cm.Add(*s.cfg.Key, ID, &inConn)
|
|
||||||
log.Printf("conn %s created", ID)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
srcAddr, body, err := utils.ReadUDPPacket(inConn)
|
srcAddr, body, err := utils.ReadUDPPacket(inConn)
|
||||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
if err != nil {
|
||||||
log.Printf("connection %s released", ID)
|
|
||||||
utils.CloseConn(&inConn)
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
log.Printf("udp packet revecived fail, err: %s", err)
|
log.Printf("udp packet revecived fail, err: %s", err)
|
||||||
|
log.Printf("connection %s released", ID)
|
||||||
|
inConn.Close()
|
||||||
|
break
|
||||||
} else {
|
} else {
|
||||||
//log.Printf("udp packet revecived:%s,%v", srcAddr, body)
|
//log.Printf("udp packet revecived:%s,%v", srcAddr, body)
|
||||||
go s.processUDPPacket(&inConn, srcAddr, localAddr, body)
|
go s.processUDPPacket(inConn, srcAddr, localAddr, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
func (s *MuxClient) processUDPPacket(inConn *net.Conn, srcAddr, localAddr string, body []byte) {
|
func (s *MuxClient) processUDPPacket(inConn *smux.Stream, srcAddr, localAddr string, body []byte) {
|
||||||
dstAddr, err := net.ResolveUDPAddr("udp", localAddr)
|
dstAddr, err := net.ResolveUDPAddr("udp", localAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("can't resolve address: %s", err)
|
log.Printf("can't resolve address: %s", err)
|
||||||
utils.CloseConn(inConn)
|
inConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
|
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
|
||||||
@ -234,26 +145,14 @@ func (s *MuxClient) processUDPPacket(inConn *net.Conn, srcAddr, localAddr string
|
|||||||
_, err = (*inConn).Write(bs)
|
_, err = (*inConn).Write(bs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("send udp response fail ,ERR:%s", err)
|
log.Printf("send udp response fail ,ERR:%s", err)
|
||||||
utils.CloseConn(inConn)
|
inConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs)
|
//log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs)
|
||||||
}
|
}
|
||||||
func (s *MuxClient) ServeConn(localAddr, ID, serverID string) {
|
func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
||||||
var inConn, outConn net.Conn
|
|
||||||
var err error
|
var err error
|
||||||
for {
|
var outConn net.Conn
|
||||||
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
|
|
||||||
if err != nil {
|
|
||||||
utils.CloseConn(&inConn)
|
|
||||||
log.Printf("connection err: %s, retrying...", err)
|
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
i++
|
i++
|
||||||
@ -269,15 +168,13 @@ func (s *MuxClient) ServeConn(localAddr, ID, serverID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.CloseConn(&inConn)
|
inConn.Close()
|
||||||
utils.CloseConn(&outConn)
|
utils.CloseConn(&outConn)
|
||||||
log.Printf("build connection error, err: %s", err)
|
log.Printf("build connection error, err: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||||
log.Printf("conn %s released", ID)
|
log.Printf("conn %s released", ID)
|
||||||
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
|
||||||
})
|
})
|
||||||
// s.cm.Add(*s.cfg.Key, ID, &inConn)
|
|
||||||
log.Printf("conn %s created", ID)
|
log.Printf("conn %s created", ID)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package services
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"proxy/utils"
|
"proxy/utils"
|
||||||
@ -19,8 +18,8 @@ type MuxServer struct {
|
|||||||
cfg MuxServerArgs
|
cfg MuxServerArgs
|
||||||
udpChn chan MuxUDPItem
|
udpChn chan MuxUDPItem
|
||||||
sc utils.ServerChannel
|
sc utils.ServerChannel
|
||||||
underLayerConn net.Conn
|
|
||||||
session *smux.Session
|
session *smux.Session
|
||||||
|
lockChn chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type MuxServerManager struct {
|
type MuxServerManager struct {
|
||||||
@ -28,7 +27,6 @@ type MuxServerManager struct {
|
|||||||
udpChn chan MuxUDPItem
|
udpChn chan MuxUDPItem
|
||||||
sc utils.ServerChannel
|
sc utils.ServerChannel
|
||||||
serverID string
|
serverID string
|
||||||
// cm utils.ConnManager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMuxServerManager() Service {
|
func NewMuxServerManager() Service {
|
||||||
@ -36,7 +34,6 @@ func NewMuxServerManager() Service {
|
|||||||
cfg: MuxServerArgs{},
|
cfg: MuxServerArgs{},
|
||||||
udpChn: make(chan MuxUDPItem, 50000),
|
udpChn: make(chan MuxUDPItem, 50000),
|
||||||
serverID: utils.Uniqueid(),
|
serverID: utils.Uniqueid(),
|
||||||
// cm: utils.NewConnManager(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *MuxServerManager) Start(args interface{}) (err error) {
|
func (s *MuxServerManager) Start(args interface{}) (err error) {
|
||||||
@ -53,6 +50,9 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
|
|||||||
log.Printf("server id: %s", s.serverID)
|
log.Printf("server id: %s", s.serverID)
|
||||||
//log.Printf("route:%v", *s.cfg.Route)
|
//log.Printf("route:%v", *s.cfg.Route)
|
||||||
for _, _info := range *s.cfg.Route {
|
for _, _info := range *s.cfg.Route {
|
||||||
|
if _info == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
IsUDP := *s.cfg.IsUDP
|
IsUDP := *s.cfg.IsUDP
|
||||||
if strings.HasPrefix(_info, "udp://") {
|
if strings.HasPrefix(_info, "udp://") {
|
||||||
IsUDP = true
|
IsUDP = true
|
||||||
@ -95,7 +95,6 @@ func (s *MuxServerManager) Clean() {
|
|||||||
s.StopService()
|
s.StopService()
|
||||||
}
|
}
|
||||||
func (s *MuxServerManager) StopService() {
|
func (s *MuxServerManager) StopService() {
|
||||||
// s.cm.RemoveAll()
|
|
||||||
}
|
}
|
||||||
func (s *MuxServerManager) CheckArgs() {
|
func (s *MuxServerManager) CheckArgs() {
|
||||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||||
@ -104,13 +103,13 @@ func (s *MuxServerManager) 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 *MuxServerManager) InitService() {
|
func (s *MuxServerManager) InitService() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMuxServer() Service {
|
func NewMuxServer() Service {
|
||||||
return &MuxServer{
|
return &MuxServer{
|
||||||
cfg: MuxServerArgs{},
|
cfg: MuxServerArgs{},
|
||||||
udpChn: make(chan MuxUDPItem, 50000),
|
udpChn: make(chan MuxUDPItem, 50000),
|
||||||
|
lockChn: make(chan bool, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,18 +146,18 @@ func (s *MuxServer) Start(args interface{}) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("proxy on udp tunnel server mode %s", (*s.sc.UDPListener).LocalAddr())
|
log.Printf("proxy on udp mux server mode %s", (*s.sc.UDPListener).LocalAddr())
|
||||||
} else {
|
} else {
|
||||||
err = s.sc.ListenTCP(func(inConn net.Conn) {
|
err = s.sc.ListenTCP(func(inConn net.Conn) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
log.Printf("tserver conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
|
log.Printf("server conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var outConn net.Conn
|
var outConn net.Conn
|
||||||
var ID string
|
var ID string
|
||||||
for {
|
for {
|
||||||
outConn, ID, err = s.GetOutConn(CONN_SERVER)
|
outConn, ID, err = s.GetOutConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.CloseConn(&outConn)
|
utils.CloseConn(&outConn)
|
||||||
log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
|
log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
|
||||||
@ -169,24 +168,22 @@ func (s *MuxServer) Start(args interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||||
// s.cfg.Mgr.cm.RemoveOne(s.cfg.Mgr.serverID, ID)
|
|
||||||
log.Printf("%s conn %s released", *s.cfg.Key, ID)
|
log.Printf("%s conn %s released", *s.cfg.Key, ID)
|
||||||
})
|
})
|
||||||
//add conn
|
//add conn
|
||||||
// s.cfg.Mgr.cm.Add(s.cfg.Mgr.serverID, ID, &inConn)
|
|
||||||
log.Printf("%s conn %s created", *s.cfg.Key, ID)
|
log.Printf("%s conn %s created", *s.cfg.Key, ID)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("proxy on tunnel server mode %s", (*s.sc.Listener).Addr())
|
log.Printf("proxy on mux server mode %s", (*s.sc.Listener).Addr())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *MuxServer) Clean() {
|
func (s *MuxServer) Clean() {
|
||||||
|
|
||||||
}
|
}
|
||||||
func (s *MuxServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) {
|
func (s *MuxServer) GetOutConn() (outConn net.Conn, ID string, err error) {
|
||||||
outConn, err = s.GetConn()
|
outConn, err = s.GetConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("connection err: %s", err)
|
log.Printf("connection err: %s", err)
|
||||||
@ -197,7 +194,7 @@ func (s *MuxServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err erro
|
|||||||
remoteAddr = "udp:" + *s.cfg.Remote
|
remoteAddr = "udp:" + *s.cfg.Remote
|
||||||
}
|
}
|
||||||
ID = utils.Uniqueid()
|
ID = utils.Uniqueid()
|
||||||
_, err = outConn.Write(utils.BuildPacket(typ, *s.cfg.Key, ID, remoteAddr, s.cfg.Mgr.serverID))
|
_, err = outConn.Write(utils.BuildPacketData(ID, remoteAddr, s.cfg.Mgr.serverID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("write connection data err: %s ,retrying...", err)
|
log.Printf("write connection data err: %s ,retrying...", err)
|
||||||
utils.CloseConn(&outConn)
|
utils.CloseConn(&outConn)
|
||||||
@ -206,11 +203,43 @@ func (s *MuxServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *MuxServer) GetConn() (conn net.Conn, err error) {
|
func (s *MuxServer) GetConn() (conn net.Conn, err error) {
|
||||||
|
select {
|
||||||
|
case s.lockChn <- true:
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("can not connect at same time")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
<-s.lockChn
|
||||||
|
}()
|
||||||
|
if s.session == nil {
|
||||||
var _conn tls.Conn
|
var _conn tls.Conn
|
||||||
_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
conn = net.Conn(&_conn)
|
s.session = nil
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
c := net.Conn(&_conn)
|
||||||
|
_, err = c.Write(utils.BuildPacket(CONN_SERVER, *s.cfg.Key))
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
s.session = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
s.session, err = smux.Client(c, nil)
|
||||||
|
if err != nil {
|
||||||
|
s.session = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn, err = s.session.OpenStream()
|
||||||
|
if err != nil {
|
||||||
|
s.session.Close()
|
||||||
|
s.session = nil
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *MuxServer) UDPConnDeamon() {
|
func (s *MuxServer) UDPConnDeamon() {
|
||||||
@ -221,18 +250,15 @@ func (s *MuxServer) UDPConnDeamon() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var outConn net.Conn
|
var outConn net.Conn
|
||||||
// var hb utils.HeartbeatReadWriter
|
|
||||||
var ID string
|
var ID string
|
||||||
// var cmdChn = make(chan bool, 1000)
|
|
||||||
var err error
|
var err error
|
||||||
for {
|
for {
|
||||||
item := <-s.udpChn
|
item := <-s.udpChn
|
||||||
RETRY:
|
RETRY:
|
||||||
if outConn == nil {
|
if outConn == nil {
|
||||||
for {
|
for {
|
||||||
outConn, ID, err = s.GetOutConn(CONN_SERVER)
|
outConn, ID, err = s.GetOutConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// cmdChn <- true
|
|
||||||
outConn = nil
|
outConn = nil
|
||||||
utils.CloseConn(&outConn)
|
utils.CloseConn(&outConn)
|
||||||
log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
|
log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
|
||||||
@ -241,18 +267,14 @@ func (s *MuxServer) UDPConnDeamon() {
|
|||||||
} else {
|
} else {
|
||||||
go func(outConn net.Conn, ID string) {
|
go func(outConn net.Conn, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
// <-cmdChn
|
|
||||||
// outConn.Close()
|
// outConn.Close()
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
|
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
|
||||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
|
||||||
log.Printf("UDP deamon connection %s exited", ID)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
|
log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
|
||||||
continue
|
log.Printf("UDP deamon connection %s exited", ID)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
|
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
|
||||||
_srcAddr := strings.Split(srcAddrFromConn, ":")
|
_srcAddr := strings.Split(srcAddrFromConn, ":")
|
||||||
|
|||||||
Reference in New Issue
Block a user