Skip to content

Commit

Permalink
Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
Browse files Browse the repository at this point in the history
  • Loading branch information
snail007 committed Dec 1, 2017
1 parent 0247c47 commit 4b35219
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 269 deletions.
12 changes: 6 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,25 +103,25 @@ func initConfig() (err error) {
udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()

//########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.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.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.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#########
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.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.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()

//########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.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()
Expand All @@ -135,7 +135,7 @@ func initConfig() (err error) {
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.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#########
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
Expand Down Expand Up @@ -259,7 +259,7 @@ func initConfig() (err error) {
log.Printf("ERR:%s,restarting...", err)
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)
}
}()
Expand Down
134 changes: 53 additions & 81 deletions services/mux_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package services

import (
"bufio"
"io"
"log"
"net"
"proxy/utils"
Expand All @@ -11,20 +12,14 @@ import (
"github.com/xtaci/smux"
)

type MuxServerConn struct {
//ClientLocalAddr string //tcp:2.2.22:333@ID
Conn *net.Conn
}
type MuxBridge struct {
cfg MuxBridgeArgs
serverConns utils.ConcurrentMap
clientControlConns utils.ConcurrentMap
}

func NewMuxBridge() Service {
return &MuxBridge{
cfg: MuxBridgeArgs{},
serverConns: utils.NewConcurrentMap(),
clientControlConns: utils.NewConcurrentMap(),
}
}
Expand All @@ -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) {
reader := bufio.NewReader(inConn)

var err error
var connType uint8
err = utils.ReadPacket(reader, &connType)
var key string
err = utils.ReadPacket(reader, &connType, &key)
if err != nil {
log.Printf("read error,ERR:%s", err)
return
}
switch connType {
case CONN_SERVER:
log.Printf("server connection %s", key)
session, err := smux.Server(inConn, nil)
if err != nil {
utils.CloseConn(&inConn)
log.Printf("server underlayer connection error,ERR:%s", err)
log.Printf("server session error,ERR:%s", err)
return
}
conn, err := session.AcceptStream()
for {
stream, err := session.AcceptStream()
if err != nil {
session.Close()
utils.CloseConn(&inConn)
return
}
go s.callback(stream, key)
}
case CONN_CLIENT:

log.Printf("client connection %s", key)
session, err := smux.Client(inConn, nil)
if err != nil {
session.Close()
utils.CloseConn(&inConn)
log.Printf("client session error,ERR:%s", err)
return
}
log.Printf("server connection %s", conn.RemoteAddr())
//s.callback(conn)
s.clientControlConns.Set(key, session)
//log.Printf("set client session,key: %s", key)
}
s.callback(inConn)

})
if err != nil {
return
Expand All @@ -86,86 +96,48 @@ func (s *MuxBridge) Start(args interface{}) (err error) {
func (s *MuxBridge) Clean() {
s.StopService()
}
func (s *MuxBridge) callback(inConn net.Conn) {
func (s *MuxBridge) callback(inConn net.Conn, key string) {
reader := bufio.NewReader(inConn)
var err error
var connType uint8
err = utils.ReadPacket(reader, &connType)
var ID, clientLocalAddr, serverID string
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 {
log.Printf("read error,ERR:%s", err)
return
packet := utils.BuildPacketData(ID, clientLocalAddr, serverID)
try := 20
for {
try--
if try == 0 {
break
}
packet := utils.BuildPacketData(ID, clientLocalAddr, serverID)
log.Printf("server connection, key: %s , id: %s %s %s", key, ID, clientLocalAddr, serverID)

//addr := clientLocalAddr + "@" + ID
s.serverConns.Set(ID, MuxServerConn{
Conn: &inConn,
})
for {
item, ok := s.clientControlConns.Get(key)
if !ok {
log.Printf("client %s control conn not exists", key)
time.Sleep(time.Second * 3)
continue
}
(*item.(*net.Conn)).SetWriteDeadline(time.Now().Add(time.Second * 3))
_, err := (*item.(*net.Conn)).Write(packet)
(*item.(*net.Conn)).SetWriteDeadline(time.Time{})
session, ok := s.clientControlConns.Get(key)
if !ok {
log.Printf("client %s session not exists", key)
time.Sleep(time.Second * 3)
continue
}
stream, err := session.(*smux.Session).OpenStream()
if err != nil {
log.Printf("%s client session open stream fail, err: %s, retrying...", key, err)
time.Sleep(time.Second * 3)
continue
} else {
_, err := stream.Write(packet)
if err != nil {
log.Printf("%s client control conn write signal fail, err: %s, retrying...", key, err)
log.Printf("server %s stream write fail, err: %s, retrying...", key, err)
time.Sleep(time.Second * 3)
continue
} else {
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 {
log.Printf("server stream %s created", ID)
go io.Copy(stream, inConn)
io.Copy(inConn, stream)
stream.Close()
inConn.Close()
log.Printf("server conn %s exists", ID)
return
log.Printf("server stream %s released", ID)
break
}
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)
}

}
Loading

0 comments on commit 4b35219

Please sign in to comment.