1.修复了多个服务同时开启日志,只会输出到最后一个日志文件的bug.

2.增加了获取sdk版本的Version()方法.

Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
arraykeys@gmail.com
2018-05-03 17:59:06 +08:00
parent edb2fb3458
commit b3feff7843
21 changed files with 447 additions and 386 deletions

View File

@ -4,14 +4,15 @@ import (
"bufio" "bufio"
"crypto/sha1" "crypto/sha1"
"fmt" "fmt"
"github.com/snail007/goproxy/services" logger "log"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
"log"
"os" "os"
"os/exec" "os/exec"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
kcp "github.com/xtaci/kcp-go" kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2" kingpin "gopkg.in/alecthomas/kingpin.v2"
@ -297,11 +298,13 @@ func initConfig() (err error) {
muxServerArgs.KCP = kcpArgs muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs muxClientArgs.KCP = kcpArgs
flags := log.Ldate log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
flags := logger.Ldate
if *debug { if *debug {
flags |= log.Lshortfile | log.Lmicroseconds flags |= logger.Lshortfile | logger.Lmicroseconds
} else { } else {
flags |= log.Ltime flags |= logger.Ltime
} }
log.SetFlags(flags) log.SetFlags(flags)
@ -383,18 +386,18 @@ func initConfig() (err error) {
poster() poster()
} }
//regist services and run service //regist services and run service
services.Regist("http", services.NewHTTP(), httpArgs) services.Regist("http", services.NewHTTP(), httpArgs, log)
services.Regist("tcp", services.NewTCP(), tcpArgs) services.Regist("tcp", services.NewTCP(), tcpArgs, log)
services.Regist("udp", services.NewUDP(), udpArgs) services.Regist("udp", services.NewUDP(), udpArgs, log)
services.Regist("tserver", services.NewTunnelServerManager(), tunnelServerArgs) services.Regist("tserver", services.NewTunnelServerManager(), tunnelServerArgs, log)
services.Regist("tclient", services.NewTunnelClient(), tunnelClientArgs) services.Regist("tclient", services.NewTunnelClient(), tunnelClientArgs, log)
services.Regist("tbridge", services.NewTunnelBridge(), tunnelBridgeArgs) services.Regist("tbridge", services.NewTunnelBridge(), tunnelBridgeArgs, log)
services.Regist("server", services.NewMuxServerManager(), muxServerArgs) services.Regist("server", services.NewMuxServerManager(), muxServerArgs, log)
services.Regist("client", services.NewMuxClient(), muxClientArgs) services.Regist("client", services.NewMuxClient(), muxClientArgs, log)
services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs) services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs, log)
services.Regist("socks", services.NewSocks(), socksArgs) services.Regist("socks", services.NewSocks(), socksArgs, log)
services.Regist("sps", services.NewSPS(), spsArgs) services.Regist("sps", services.NewSPS(), spsArgs, log)
service, err = services.Run(serviceName) service, err = services.Run(serviceName, nil)
if err != nil { if err != nil {
log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err) log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err)
} }

3
sdk/CHANGELOG Normal file
View File

@ -0,0 +1,3 @@
v4.8
1.修复了多个服务同时开启日志,只会输出到最后一个日志文件的bug.
2.增加了获取sdk版本的Version()方法.

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.7" VER="v4.8"
rm -rf sdk-android-*.tar.gz rm -rf sdk-android-*.tar.gz
rm -rf android rm -rf android
mkdir android mkdir android

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.7" VER="v4.8"
rm -rf sdk-ios-*.tar.gz rm -rf sdk-ios-*.tar.gz
rm -rf ios rm -rf ios
mkdir ios mkdir ios

View File

@ -3,17 +3,20 @@ package proxy
import ( import (
"crypto/sha1" "crypto/sha1"
"fmt" "fmt"
"github.com/snail007/goproxy/services" logger "log"
"github.com/snail007/goproxy/services/kcpcfg"
"log"
"os" "os"
"strings" "strings"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
kcp "github.com/xtaci/kcp-go" kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2" kingpin "gopkg.in/alecthomas/kingpin.v2"
) )
const SDK_VERSION = "4.8"
var ( var (
app *kingpin.Application app *kingpin.Application
) )
@ -43,7 +46,7 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
kcpArgs := kcpcfg.KCPConfigArgs{} kcpArgs := kcpcfg.KCPConfigArgs{}
//build srvice args //build srvice args
app = kingpin.New("proxy", "happy with proxy") app = kingpin.New("proxy", "happy with proxy")
app.Author("snail").Version("4.7") app.Author("snail").Version(SDK_VERSION)
debug := app.Flag("debug", "debug log output").Default("false").Bool() debug := app.Flag("debug", "debug log output").Default("false").Bool()
logfile := app.Flag("log", "log file path").Default("").String() logfile := app.Flag("log", "log file path").Default("").String()
kcpArgs.Key = app.Flag("kcp-key", "pre-shared secret between client and server").Default("secrect").String() kcpArgs.Key = app.Flag("kcp-key", "pre-shared secret between client and server").Default("secrect").String()
@ -298,11 +301,12 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
muxServerArgs.KCP = kcpArgs muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs muxClientArgs.KCP = kcpArgs
flags := log.Ldate log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
flags := logger.Ldate
if *debug { if *debug {
flags |= log.Lshortfile | log.Lmicroseconds flags |= logger.Lshortfile | logger.Lmicroseconds
} else { } else {
flags |= log.Ltime flags |= logger.Ltime
} }
log.SetFlags(flags) log.SetFlags(flags)
@ -317,29 +321,29 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
//regist services and run service //regist services and run service
switch serviceName { switch serviceName {
case "http": case "http":
services.Regist(serviceID, services.NewHTTP(), httpArgs) services.Regist(serviceID, services.NewHTTP(), httpArgs, log)
case "tcp": case "tcp":
services.Regist(serviceID, services.NewTCP(), tcpArgs) services.Regist(serviceID, services.NewTCP(), tcpArgs, log)
case "udp": case "udp":
services.Regist(serviceID, services.NewUDP(), udpArgs) services.Regist(serviceID, services.NewUDP(), udpArgs, log)
case "tserver": case "tserver":
services.Regist(serviceID, services.NewTunnelServerManager(), tunnelServerArgs) services.Regist(serviceID, services.NewTunnelServerManager(), tunnelServerArgs, log)
case "tclient": case "tclient":
services.Regist(serviceID, services.NewTunnelClient(), tunnelClientArgs) services.Regist(serviceID, services.NewTunnelClient(), tunnelClientArgs, log)
case "tbridge": case "tbridge":
services.Regist(serviceID, services.NewTunnelBridge(), tunnelBridgeArgs) services.Regist(serviceID, services.NewTunnelBridge(), tunnelBridgeArgs, log)
case "server": case "server":
services.Regist(serviceID, services.NewMuxServerManager(), muxServerArgs) services.Regist(serviceID, services.NewMuxServerManager(), muxServerArgs, log)
case "client": case "client":
services.Regist(serviceID, services.NewMuxClient(), muxClientArgs) services.Regist(serviceID, services.NewMuxClient(), muxClientArgs, log)
case "bridge": case "bridge":
services.Regist(serviceID, services.NewMuxBridge(), muxBridgeArgs) services.Regist(serviceID, services.NewMuxBridge(), muxBridgeArgs, log)
case "socks": case "socks":
services.Regist(serviceID, services.NewSocks(), socksArgs) services.Regist(serviceID, services.NewSocks(), socksArgs, log)
case "sps": case "sps":
services.Regist(serviceID, services.NewSPS(), spsArgs) services.Regist(serviceID, services.NewSPS(), spsArgs, log)
} }
_, err = services.Run(serviceID) _, err = services.Run(serviceID, nil)
if err != nil { if err != nil {
return fmt.Sprintf("run service [%s:%s] fail, ERR:%s", serviceID, serviceName, err) return fmt.Sprintf("run service [%s:%s] fail, ERR:%s", serviceID, serviceName, err)
} }
@ -349,3 +353,7 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
func Stop(serviceID string) { func Stop(serviceID string) {
services.Stop(serviceID) services.Stop(serviceID)
} }
func Version() string {
return SDK_VERSION
}

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.7" VER="v4.8"
rm -rf sdk-linux-*.tar.gz rm -rf sdk-linux-*.tar.gz
rm -rf README.md libproxy-sdk.so libproxy-sdk.h libproxy-sdk.a rm -rf README.md libproxy-sdk.so libproxy-sdk.h libproxy-sdk.a

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.7" VER="v4.8"
rm -rf *.tar.gz rm -rf *.tar.gz
rm -rf README.md libproxy-sdk.dylib libproxy-sdk.h rm -rf README.md libproxy-sdk.dylib libproxy-sdk.h

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.7" VER="v4.8"
sudo rm /usr/local/go sudo rm /usr/local/go
sudo ln -s /usr/local/go1.10.1 /usr/local/go sudo ln -s /usr/local/go1.10.1 /usr/local/go

View File

@ -2,6 +2,7 @@ package main
import ( import (
"C" "C"
sdk "github.com/snail007/goproxy/sdk/android-ios" sdk "github.com/snail007/goproxy/sdk/android-ios"
) )
@ -15,5 +16,10 @@ func Stop(serviceID *C.char) {
sdk.Stop(C.GoString(serviceID)) sdk.Stop(C.GoString(serviceID))
} }
//export Version
func Version() (ver *C.char) {
return C.CString(sdk.Version())
}
func main() { func main() {
} }

View File

@ -2,17 +2,18 @@ package services
import ( import (
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"io" "io"
"io/ioutil" "io/ioutil"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
@ -27,6 +28,7 @@ type HTTP struct {
isStop bool isStop bool
serverChannels []*utils.ServerChannel serverChannels []*utils.ServerChannel
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
func NewHTTP() Service { func NewHTTP() Service {
@ -125,7 +127,7 @@ func (s *HTTP) InitService() (err error) {
s.sshClient.Conn.Close() s.sshClient.Conn.Close()
} }
} }
log.Printf("ssh offline, retrying...") s.log.Printf("ssh offline, retrying...")
s.ConnectSSH() s.ConnectSSH()
} else { } else {
conn.Close() conn.Close()
@ -140,9 +142,9 @@ func (s *HTTP) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop http(s) service crashed,%s", e) s.log.Printf("stop http(s) service crashed,%s", e)
} else { } else {
log.Printf("service http(s) stoped") s.log.Printf("service http(s) stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -159,13 +161,14 @@ func (s *HTTP) StopService() {
} }
} }
} }
func (s *HTTP) Start(args interface{}) (err error) { func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(HTTPArgs) s.cfg = args.(HTTPArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
} }
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
s.InitOutConnPool() s.InitOutConnPool()
} }
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
@ -186,7 +189,7 @@ func (s *HTTP) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("%s http(s) proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) s.log.Printf("%s http(s) proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
s.serverChannels = append(s.serverChannels, &sc) s.serverChannels = append(s.serverChannels, &sc)
} }
} }
@ -199,7 +202,7 @@ func (s *HTTP) Clean() {
func (s *HTTP) callback(inConn net.Conn) { func (s *HTTP) callback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("http(s) conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("http(s) conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
if *s.cfg.LocalCompress { if *s.cfg.LocalCompress {
@ -215,7 +218,7 @@ func (s *HTTP) callback(inConn net.Conn) {
req, err = utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth) req, err = utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth)
if err != nil { if err != nil {
if err != io.EOF { if err != io.EOF {
log.Printf("decoder error , from %s, ERR:%s", inConn.RemoteAddr(), err) s.log.Printf("decoder error , from %s, ERR:%s", inConn.RemoteAddr(), err)
} }
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
return return
@ -234,18 +237,18 @@ func (s *HTTP) callback(inConn net.Conn) {
s.checker.Add(k) s.checker.Add(k)
//var n, m uint //var n, m uint
useProxy, _, _ = s.checker.IsBlocked(k) useProxy, _, _ = s.checker.IsBlocked(k)
//log.Printf("blocked ? : %v, %s , fail:%d ,success:%d", useProxy, address, n, m) //s.log.Printf("blocked ? : %v, %s , fail:%d ,success:%d", useProxy, address, n, m)
} }
} }
log.Printf("use proxy : %v, %s", useProxy, address) s.log.Printf("use proxy : %v, %s", useProxy, address)
err = s.OutToTCP(useProxy, address, &inConn, &req) err = s.OutToTCP(useProxy, address, &inConn, &req)
if err != nil { if err != nil {
if *s.cfg.Parent == "" { if *s.cfg.Parent == "" {
log.Printf("connect to %s fail, ERR:%s", address, err) s.log.Printf("connect to %s fail, ERR:%s", address, err)
} else { } else {
log.Printf("connect to %s parent %s fail", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("connect to %s parent %s fail", *s.cfg.ParentType, *s.cfg.Parent)
} }
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
} }
@ -270,7 +273,7 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
if *s.cfg.ParentType == "ssh" { if *s.cfg.ParentType == "ssh" {
outConn, err = s.getSSHConn(address) outConn, err = s.getSSHConn(address)
} else { } else {
// log.Printf("%v", s.outPool) // s.log.Printf("%v", s.outPool)
outConn, err = s.outPool.Get() outConn, err = s.outPool.Get()
} }
} else { } else {
@ -280,12 +283,12 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
if err == nil || tryCount > maxTryCount { if err == nil || tryCount > maxTryCount {
break break
} else { } else {
log.Printf("connect to %s , err:%s,retrying...", *s.cfg.Parent, err) s.log.Printf("connect to %s , err:%s,retrying...", *s.cfg.Parent, err)
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
} }
} }
if err != nil { if err != nil {
log.Printf("connect to %s , err:%s", *s.cfg.Parent, err) s.log.Printf("connect to %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
@ -309,17 +312,17 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
_, err = outConn.Write(req.HeadBuf) _, err = outConn.Write(req.HeadBuf)
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("write to %s , err:%s", *s.cfg.Parent, err) s.log.Printf("write to %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
} }
utils.IoBind((*inConn), outConn, func(err interface{}) { utils.IoBind((*inConn), outConn, func(err interface{}) {
log.Printf("conn %s - %s released [%s]", inAddr, outAddr, req.Host) s.log.Printf("conn %s - %s released [%s]", inAddr, outAddr, req.Host)
s.userConns.Remove(inAddr) s.userConns.Remove(inAddr)
}) })
log.Printf("conn %s - %s connected [%s]", inAddr, outAddr, req.Host) s.log.Printf("conn %s - %s connected [%s]", inAddr, outAddr, req.Host)
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
@ -350,7 +353,7 @@ RETRY:
err = fmt.Errorf("ssh dial %s timeout", host) err = fmt.Errorf("ssh dial %s timeout", host)
} }
if err != nil { if err != nil {
log.Printf("connect ssh fail, ERR: %s, retrying...", err) s.log.Printf("connect ssh fail, ERR: %s, retrying...", err)
e := s.ConnectSSH() e := s.ConnectSSH()
if e == nil { if e == nil {
tryCount++ tryCount++
@ -406,7 +409,7 @@ func (s *HTTP) InitBasicAuth() (err error) {
} }
if *s.cfg.AuthURL != "" { if *s.cfg.AuthURL != "" {
s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry) s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
log.Printf("auth from %s", *s.cfg.AuthURL) s.log.Printf("auth from %s", *s.cfg.AuthURL)
} }
if *s.cfg.AuthFile != "" { if *s.cfg.AuthFile != "" {
var n = 0 var n = 0
@ -415,11 +418,11 @@ func (s *HTTP) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err) err = fmt.Errorf("auth-file ERR:%s", err)
return return
} }
log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total())
} }
if len(*s.cfg.Auth) > 0 { if len(*s.cfg.Auth) > 0 {
n := s.basicAuth.Add(*s.cfg.Auth) n := s.basicAuth.Add(*s.cfg.Auth)
log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total())
} }
return return
} }
@ -471,7 +474,7 @@ func (s *HTTP) Resolve(address string) string {
} }
ip, err := s.domainResolver.Resolve(address) ip, err := s.domainResolver.Resolve(address)
if err != nil { if err != nil {
log.Printf("dns error %s , ERR:%s", address, err) s.log.Printf("dns error %s , ERR:%s", address, err)
} }
return ip return ip
} }

View File

@ -3,9 +3,8 @@ package services
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"math/rand" "math/rand"
"net" "net"
"strconv" "strconv"
@ -13,6 +12,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -24,6 +25,7 @@ type MuxBridge struct {
l *sync.Mutex l *sync.Mutex
isStop bool isStop bool
sc *utils.ServerChannel sc *utils.ServerChannel
log *logger.Logger
} }
func NewMuxBridge() Service { func NewMuxBridge() Service {
@ -58,9 +60,9 @@ func (s *MuxBridge) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop bridge service crashed,%s", e) s.log.Printf("stop bridge service crashed,%s", e)
} else { } else {
log.Printf("service bridge stoped") s.log.Printf("service bridge stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -76,7 +78,8 @@ func (s *MuxBridge) StopService() {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
} }
func (s *MuxBridge) Start(args interface{}) (err error) { func (s *MuxBridge) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(MuxBridgeArgs) s.cfg = args.(MuxBridgeArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -99,7 +102,7 @@ func (s *MuxBridge) Start(args interface{}) (err error) {
return return
} }
s.sc = &sc s.sc = &sc
log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
return return
} }
func (s *MuxBridge) Clean() { func (s *MuxBridge) Clean() {
@ -115,7 +118,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
err = utils.ReadPacket(reader, &connType, &key) err = utils.ReadPacket(reader, &connType, &key)
inConn.SetDeadline(time.Time{}) inConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.log.Printf("read error,ERR:%s", err)
return return
} }
switch connType { switch connType {
@ -126,10 +129,10 @@ func (s *MuxBridge) handler(inConn net.Conn) {
err = utils.ReadPacketData(reader, &serverID) err = utils.ReadPacketData(reader, &serverID)
inConn.SetDeadline(time.Time{}) inConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.log.Printf("read error,ERR:%s", err)
return return
} }
log.Printf("server connection %s %s connected", serverID, key) s.log.Printf("server connection %s %s connected", serverID, key)
if c, ok := s.serverConns.Get(inAddr); ok { if c, ok := s.serverConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
@ -137,7 +140,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
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 session error,ERR:%s", err) s.log.Printf("server session error,ERR:%s", err)
return return
} }
for { for {
@ -149,30 +152,30 @@ func (s *MuxBridge) handler(inConn net.Conn) {
session.Close() session.Close()
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
s.serverConns.Remove(inAddr) s.serverConns.Remove(inAddr)
log.Printf("server connection %s %s released", serverID, key) s.log.Printf("server connection %s %s released", serverID, key)
return return
} }
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
log.Printf("bridge callback crashed,err: %s", e) s.log.Printf("bridge callback crashed,err: %s", e)
} }
}() }()
s.callback(stream, serverID, key) s.callback(stream, serverID, key)
}() }()
} }
case CONN_CLIENT: case CONN_CLIENT:
log.Printf("client connection %s connected", key) s.log.Printf("client connection %s connected", key)
session, err := smux.Client(inConn, nil) session, err := smux.Client(inConn, nil)
if err != nil { if err != nil {
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("client session error,ERR:%s", err) s.log.Printf("client session error,ERR:%s", err)
return return
} }
keyInfo := strings.Split(key, "-") keyInfo := strings.Split(key, "-")
if len(keyInfo) != 2 { if len(keyInfo) != 2 {
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("client key format error,key:%s", key) s.log.Printf("client key format error,key:%s", key)
return return
} }
groupKey := keyInfo[0] groupKey := keyInfo[0]
@ -200,7 +203,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
defer s.l.Unlock() defer s.l.Unlock()
if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() { if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() {
group.Remove(index) group.Remove(index)
log.Printf("client connection %s released", key) s.log.Printf("client connection %s released", key)
} }
if group.IsEmpty() { if group.IsEmpty() {
s.clientControlConns.Remove(groupKey) s.clientControlConns.Remove(groupKey)
@ -210,7 +213,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
} }
}() }()
//log.Printf("set client session,key: %s", key) //s.log.Printf("set client session,key: %s", key)
} }
} }
@ -229,7 +232,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
} }
_group, ok := s.clientControlConns.Get(key) _group, ok := s.clientControlConns.Get(key)
if !ok { if !ok {
log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID) s.log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} }
@ -240,22 +243,22 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
if keysLen > 0 { if keysLen > 0 {
i = rand.Intn(keysLen) i = rand.Intn(keysLen)
} else { } else {
log.Printf("client %s session empty for server stream %s, retrying...", key, serverID) s.log.Printf("client %s session empty for server stream %s, retrying...", key, serverID)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} }
index := keys[i] index := keys[i]
log.Printf("select client : %s-%s", key, index) s.log.Printf("select client : %s-%s", key, index)
session, _ := group.Get(index) session, _ := group.Get(index)
session.(*smux.Session).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) session.(*smux.Session).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
stream, err := session.(*smux.Session).OpenStream() stream, err := session.(*smux.Session).OpenStream()
session.(*smux.Session).SetDeadline(time.Time{}) session.(*smux.Session).SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("%s client session open stream %s fail, err: %s, retrying...", key, serverID, err) s.log.Printf("%s client session open stream %s fail, err: %s, retrying...", key, serverID, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
log.Printf("stream %s -> %s created", serverID, key) s.log.Printf("stream %s -> %s created", serverID, key)
die1 := make(chan bool, 1) die1 := make(chan bool, 1)
die2 := make(chan bool, 1) die2 := make(chan bool, 1)
go func() { go func() {
@ -272,7 +275,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
} }
stream.Close() stream.Close()
inConn.Close() inConn.Close()
log.Printf("%s server %s stream released", key, serverID) s.log.Printf("%s server %s stream released", key, serverID)
break break
} }
} }

View File

@ -3,12 +3,13 @@ package services
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"net" "net"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -17,6 +18,7 @@ type MuxClient struct {
cfg MuxClientArgs cfg MuxClientArgs
isStop bool isStop bool
sessions utils.ConcurrentMap sessions utils.ConcurrentMap
log *logger.Logger
} }
func NewMuxClient() Service { func NewMuxClient() Service {
@ -33,7 +35,7 @@ func (s *MuxClient) InitService() (err error) {
func (s *MuxClient) CheckArgs() (err error) { func (s *MuxClient) CheckArgs() (err error) {
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent) s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else { } else {
err = fmt.Errorf("parent required") err = fmt.Errorf("parent required")
return return
@ -54,9 +56,9 @@ func (s *MuxClient) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop client service crashed,%s", e) s.log.Printf("stop client service crashed,%s", e)
} else { } else {
log.Printf("service client stoped") s.log.Printf("service client stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -64,7 +66,8 @@ func (s *MuxClient) StopService() {
sess.(*smux.Session).Close() sess.(*smux.Session).Close()
} }
} }
func (s *MuxClient) Start(args interface{}) (err error) { func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(MuxClientArgs) s.cfg = args.(MuxClientArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -72,19 +75,19 @@ func (s *MuxClient) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
return return
} }
log.Printf("client started") s.log.Printf("client started")
count := 1 count := 1
if *s.cfg.SessionCount > 0 { if *s.cfg.SessionCount > 0 {
count = *s.cfg.SessionCount count = *s.cfg.SessionCount
} }
for i := 1; i <= count; i++ { for i := 1; i <= count; i++ {
key := fmt.Sprintf("worker[%d]", i) key := fmt.Sprintf("worker[%d]", i)
log.Printf("session %s started", key) s.log.Printf("session %s started", key)
go func(i int) { go func(i int) {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("session worker crashed: %s", e) s.log.Printf("session worker crashed: %s", e)
} }
}() }()
for { for {
@ -93,7 +96,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
} }
conn, err := s.getParentConn() conn, err := s.getParentConn()
if err != nil { if err != nil {
log.Printf("connection err: %s, retrying...", err) s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} }
@ -102,13 +105,13 @@ func (s *MuxClient) Start(args interface{}) (err error) {
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
conn.Close() conn.Close()
log.Printf("connection err: %s, retrying...", err) s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} }
session, err := smux.Server(conn, nil) session, err := smux.Server(conn, nil)
if err != nil { if err != nil {
log.Printf("session err: %s, retrying...", err) s.log.Printf("session err: %s, retrying...", err)
conn.Close() conn.Close()
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
@ -123,7 +126,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
} }
stream, err := session.AcceptStream() stream, err := session.AcceptStream()
if err != nil { if err != nil {
log.Printf("accept stream err: %s, retrying...", err) s.log.Printf("accept stream err: %s, retrying...", err)
session.Close() session.Close()
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
break break
@ -132,7 +135,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stream handler crashed: %s", e) s.log.Printf("stream handler crashed: %s", e)
} }
}() }()
var ID, clientLocalAddr, serverID string var ID, clientLocalAddr, serverID string
@ -140,11 +143,11 @@ func (s *MuxClient) Start(args interface{}) (err error) {
err = utils.ReadPacketData(stream, &ID, &clientLocalAddr, &serverID) err = utils.ReadPacketData(stream, &ID, &clientLocalAddr, &serverID)
stream.SetDeadline(time.Time{}) stream.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read stream signal err: %s", err) s.log.Printf("read stream signal err: %s", err)
stream.Close() stream.Close()
return return
} }
log.Printf("worker[%d] signal revecived,server %s stream %s %s", i, serverID, ID, clientLocalAddr) s.log.Printf("worker[%d] signal revecived,server %s stream %s %s", i, serverID, ID, clientLocalAddr)
protocol := clientLocalAddr[:3] protocol := clientLocalAddr[:3]
localAddr := clientLocalAddr[4:] localAddr := clientLocalAddr[4:]
if protocol == "udp" { if protocol == "udp" {
@ -186,16 +189,16 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
srcAddr, body, err := utils.ReadUDPPacket(inConn) srcAddr, body, err := utils.ReadUDPPacket(inConn)
inConn.SetDeadline(time.Time{}) inConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("udp packet revecived fail, err: %s", err) s.log.Printf("udp packet revecived fail, err: %s", err)
log.Printf("connection %s released", ID) s.log.Printf("connection %s released", ID)
inConn.Close() inConn.Close()
break break
} else { } else {
//log.Printf("udp packet revecived:%s,%v", srcAddr, body) //s.log.Printf("udp packet revecived:%s,%v", srcAddr, body)
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
log.Printf("client processUDPPacket crashed,err: %s", e) s.log.Printf("client processUDPPacket crashed,err: %s", e)
} }
}() }()
s.processUDPPacket(inConn, srcAddr, localAddr, body) s.processUDPPacket(inConn, srcAddr, localAddr, body)
@ -209,44 +212,44 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
func (s *MuxClient) processUDPPacket(inConn *smux.Stream, 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) s.log.Printf("can't resolve address: %s", err)
inConn.Close() inConn.Close()
return return
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(body) _, err = conn.Write(body)
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
//log.Printf("send udp packet to %s success", dstAddr.String()) //s.log.Printf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 1024) buf := make([]byte, 1024)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf) length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
return return
} }
respBody := buf[0:length] respBody := buf[0:length]
//log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody) //s.log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
bs := utils.UDPPacket(srcAddr, respBody) bs := utils.UDPPacket(srcAddr, respBody)
(*inConn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) (*inConn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = (*inConn).Write(bs) _, err = (*inConn).Write(bs)
(*inConn).SetDeadline(time.Time{}) (*inConn).SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("send udp response fail ,ERR:%s", err) s.log.Printf("send udp response fail ,ERR:%s", err)
inConn.Close() inConn.Close()
return return
} }
//log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs) //s.log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs)
} }
func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) { func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
var err error var err error
@ -262,7 +265,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
break break
} else { } else {
if i == 3 { if i == 3 {
log.Printf("connect to %s err: %s, retrying...", localAddr, err) s.log.Printf("connect to %s err: %s, retrying...", localAddr, err)
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
continue continue
} }
@ -271,11 +274,11 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
if err != nil { if err != nil {
inConn.Close() inConn.Close()
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
log.Printf("build connection error, err: %s", err) s.log.Printf("build connection error, err: %s", err)
return return
} }
log.Printf("stream %s created", ID) s.log.Printf("stream %s created", ID)
if *s.cfg.IsCompress { if *s.cfg.IsCompress {
die1 := make(chan bool, 1) die1 := make(chan bool, 1)
die2 := make(chan bool, 1) die2 := make(chan bool, 1)
@ -293,10 +296,10 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
} }
outConn.Close() outConn.Close()
inConn.Close() inConn.Close()
log.Printf("%s stream %s released", *s.cfg.Key, ID) s.log.Printf("%s stream %s released", *s.cfg.Key, ID)
} else { } else {
utils.IoBind(inConn, outConn, func(err interface{}) { utils.IoBind(inConn, outConn, func(err interface{}) {
log.Printf("stream %s released", ID) s.log.Printf("stream %s released", ID)
}) })
} }
} }

View File

@ -3,9 +3,8 @@ package services
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"math/rand" "math/rand"
"net" "net"
"runtime/debug" "runtime/debug"
@ -13,6 +12,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -25,6 +26,7 @@ type MuxServer struct {
lockChn chan bool lockChn chan bool
isStop bool isStop bool
udpConn *net.Conn udpConn *net.Conn
log *logger.Logger
} }
type MuxServerManager struct { type MuxServerManager struct {
@ -32,6 +34,7 @@ type MuxServerManager struct {
udpChn chan MuxUDPItem udpChn chan MuxUDPItem
serverID string serverID string
servers []*Service servers []*Service
log *logger.Logger
} }
func NewMuxServerManager() Service { func NewMuxServerManager() Service {
@ -43,13 +46,14 @@ func NewMuxServerManager() Service {
} }
} }
func (s *MuxServerManager) Start(args interface{}) (err error) { func (s *MuxServerManager) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(MuxServerArgs) s.cfg = args.(MuxServerArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
} }
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
} else { } else {
err = fmt.Errorf("parent required") err = fmt.Errorf("parent required")
return return
@ -59,8 +63,8 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
return return
} }
log.Printf("server id: %s", s.serverID) s.log.Printf("server id: %s", s.serverID)
//log.Printf("route:%v", *s.cfg.Route) //s.log.Printf("route:%v", *s.cfg.Route)
for _, _info := range *s.cfg.Route { for _, _info := range *s.cfg.Route {
if _info == "" { if _info == "" {
continue continue
@ -73,6 +77,7 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
info = strings.TrimPrefix(info, "tcp://") info = strings.TrimPrefix(info, "tcp://")
_routeInfo := strings.Split(info, "@") _routeInfo := strings.Split(info, "@")
server := NewMuxServer() server := NewMuxServer()
local := _routeInfo[0] local := _routeInfo[0]
remote := _routeInfo[1] remote := _routeInfo[1]
KEY := *s.cfg.Key KEY := *s.cfg.Key
@ -99,7 +104,7 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
SessionCount: s.cfg.SessionCount, SessionCount: s.cfg.SessionCount,
KCP: s.cfg.KCP, KCP: s.cfg.KCP,
ParentType: s.cfg.ParentType, ParentType: s.cfg.ParentType,
}) }, log)
if err != nil { if err != nil {
return return
@ -153,9 +158,9 @@ func (s *MuxServer) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop server service crashed,%s", e) s.log.Printf("stop server service crashed,%s", e)
} else { } else {
log.Printf("service server stoped") s.log.Printf("service server stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -184,7 +189,8 @@ func (s *MuxServer) CheckArgs() (err error) {
return return
} }
func (s *MuxServer) Start(args interface{}) (err error) { func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(MuxServerArgs) s.cfg = args.(MuxServerArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -206,12 +212,12 @@ func (s *MuxServer) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("server on %s", (*s.sc.UDPListener).LocalAddr()) s.log.Printf("server on %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("connection handler crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("connection handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
var outConn net.Conn var outConn net.Conn
@ -223,14 +229,14 @@ func (s *MuxServer) Start(args interface{}) (err error) {
outConn, ID, err = s.GetOutConn() 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) s.log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
break break
} }
} }
log.Printf("%s stream %s created", *s.cfg.Key, ID) s.log.Printf("%s stream %s created", *s.cfg.Key, ID)
if *s.cfg.IsCompress { if *s.cfg.IsCompress {
die1 := make(chan bool, 1) die1 := make(chan bool, 1)
die2 := make(chan bool, 1) die2 := make(chan bool, 1)
@ -248,17 +254,17 @@ func (s *MuxServer) Start(args interface{}) (err error) {
} }
outConn.Close() outConn.Close()
inConn.Close() inConn.Close()
log.Printf("%s stream %s released", *s.cfg.Key, ID) s.log.Printf("%s stream %s released", *s.cfg.Key, ID)
} else { } else {
utils.IoBind(inConn, outConn, func(err interface{}) { utils.IoBind(inConn, outConn, func(err interface{}) {
log.Printf("%s stream %s released", *s.cfg.Key, ID) s.log.Printf("%s stream %s released", *s.cfg.Key, ID)
}) })
} }
}) })
if err != nil { if err != nil {
return return
} }
log.Printf("server on %s", (*s.sc.Listener).Addr()) s.log.Printf("server on %s", (*s.sc.Listener).Addr())
} }
return return
} }
@ -272,7 +278,7 @@ func (s *MuxServer) GetOutConn() (outConn net.Conn, ID string, err error) {
} }
outConn, err = s.GetConn(fmt.Sprintf("%d", i)) outConn, err = s.GetConn(fmt.Sprintf("%d", i))
if err != nil { if err != nil {
log.Printf("connection err: %s", err) s.log.Printf("connection err: %s", err)
return return
} }
remoteAddr := "tcp:" + *s.cfg.Remote remoteAddr := "tcp:" + *s.cfg.Remote
@ -284,7 +290,7 @@ func (s *MuxServer) GetOutConn() (outConn net.Conn, ID string, err error) {
_, err = outConn.Write(utils.BuildPacketData(ID, remoteAddr, s.cfg.Mgr.serverID)) _, err = outConn.Write(utils.BuildPacketData(ID, remoteAddr, s.cfg.Mgr.serverID))
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("write stream data err: %s ,retrying...", err) s.log.Printf("write stream data err: %s ,retrying...", err)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
return return
} }
@ -325,7 +331,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
_sess.(*smux.Session).Close() _sess.(*smux.Session).Close()
} }
s.sessions.Set(index, session) s.sessions.Set(index, session)
log.Printf("session[%s] created", index) s.log.Printf("session[%s] created", index)
go func() { go func() {
for { for {
if s.isStop { if s.isStop {
@ -366,7 +372,7 @@ func (s *MuxServer) UDPConnDeamon() {
go func() { go func() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("udp conn deamon crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("udp conn deamon crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
var outConn net.Conn var outConn net.Conn
@ -390,7 +396,7 @@ func (s *MuxServer) UDPConnDeamon() {
if err != nil { if err != nil {
outConn = nil outConn = nil
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err) s.log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -407,14 +413,14 @@ func (s *MuxServer) UDPConnDeamon() {
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn) srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body) s.log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
log.Printf("UDP deamon connection %s exited", ID) s.log.Printf("UDP deamon connection %s exited", ID)
break break
} }
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn) //s.log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
_srcAddr := strings.Split(srcAddrFromConn, ":") _srcAddr := strings.Split(srcAddrFromConn, ":")
if len(_srcAddr) != 2 { if len(_srcAddr) != 2 {
log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn) s.log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn)
continue continue
} }
port, _ := strconv.Atoi(_srcAddr[1]) port, _ := strconv.Atoi(_srcAddr[1])
@ -423,10 +429,10 @@ func (s *MuxServer) UDPConnDeamon() {
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr) _, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
s.sc.UDPListener.SetDeadline(time.Time{}) s.sc.UDPListener.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("udp response to local %s fail,ERR:%s", srcAddrFromConn, err) s.log.Printf("udp response to local %s fail,ERR:%s", srcAddrFromConn, err)
continue continue
} }
//log.Printf("udp response to local %s success , %v", srcAddrFromConn, body) //s.log.Printf("udp response to local %s success , %v", srcAddrFromConn, body)
} }
}(outConn, ID) }(outConn, ID)
break break
@ -439,10 +445,10 @@ func (s *MuxServer) UDPConnDeamon() {
if err != nil { if err != nil {
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
outConn = nil outConn = nil
log.Printf("write udp packet to %s fail ,flush err:%s ,retrying...", *s.cfg.Parent, err) s.log.Printf("write udp packet to %s fail ,flush err:%s ,retrying...", *s.cfg.Parent, err)
goto RETRY goto RETRY
} }
//log.Printf("write packet %v", *item.packet) //s.log.Printf("write packet %v", *item.packet)
} }
}() }()
} }

View File

@ -2,27 +2,30 @@ package services
import ( import (
"fmt" "fmt"
logger "log"
"runtime/debug" "runtime/debug"
) )
type Service interface { type Service interface {
Start(args interface{}) (err error) Start(args interface{}, log *logger.Logger) (err error)
Clean() Clean()
} }
type ServiceItem struct { type ServiceItem struct {
S Service S Service
Args interface{} Args interface{}
Name string Name string
Log *logger.Logger
} }
var servicesMap = map[string]*ServiceItem{} var servicesMap = map[string]*ServiceItem{}
func Regist(name string, s Service, args interface{}) { func Regist(name string, s Service, args interface{}, log *logger.Logger) {
Stop(name) Stop(name)
servicesMap[name] = &ServiceItem{ servicesMap[name] = &ServiceItem{
S: s, S: s,
Args: args, Args: args,
Name: name, Name: name,
Log: log,
} }
} }
func GetService(name string) *ServiceItem { func GetService(name string) *ServiceItem {
@ -37,7 +40,7 @@ func Stop(name string) {
s.S.Clean() s.S.Clean()
} }
} }
func Run(name string, args ...interface{}) (service *ServiceItem, err error) { func Run(name string, args interface{}) (service *ServiceItem, err error) {
service, ok := servicesMap[name] service, ok := servicesMap[name]
if ok { if ok {
defer func() { defer func() {
@ -46,10 +49,10 @@ func Run(name string, args ...interface{}) (service *ServiceItem, err error) {
err = fmt.Errorf("%s servcie crashed, ERR: %s\ntrace:%s", name, e, string(debug.Stack())) err = fmt.Errorf("%s servcie crashed, ERR: %s\ntrace:%s", name, e, string(debug.Stack()))
} }
}() }()
if len(args) == 1 { if args != nil {
err = service.S.Start(args[0]) err = service.S.Start(args, service.Log)
} else { } else {
err = service.S.Start(service.Args) err = service.S.Start(service.Args, service.Log)
} }
if err != nil { if err != nil {
err = fmt.Errorf("%s servcie fail, ERR: %s", name, err) err = fmt.Errorf("%s servcie fail, ERR: %s", name, err)

View File

@ -3,17 +3,18 @@ package services
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/aes"
"github.com/snail007/goproxy/utils/socks"
"github.com/snail007/goproxy/utils/conncrypt"
"io/ioutil" "io/ioutil"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/aes"
"github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/socks"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
@ -28,6 +29,7 @@ type Socks struct {
domainResolver utils.DomainResolver domainResolver utils.DomainResolver
isStop bool isStop bool
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
func NewSocks() Service { func NewSocks() Service {
@ -133,7 +135,7 @@ func (s *Socks) InitService() (err error) {
if s.sshClient != nil { if s.sshClient != nil {
s.sshClient.Close() s.sshClient.Close()
} }
log.Printf("ssh offline, retrying...") s.log.Printf("ssh offline, retrying...")
s.ConnectSSH() s.ConnectSSH()
} else { } else {
conn.Close() conn.Close()
@ -143,7 +145,7 @@ func (s *Socks) InitService() (err error) {
}() }()
} }
if *s.cfg.ParentType == "ssh" { if *s.cfg.ParentType == "ssh" {
log.Println("warn: socks udp not suppored for ssh") s.log.Printf("warn: socks udp not suppored for ssh")
} else { } else {
s.udpSC = utils.NewServerChannelHost(*s.cfg.UDPLocal) s.udpSC = utils.NewServerChannelHost(*s.cfg.UDPLocal)
e := s.udpSC.ListenUDP(s.udpCallback) e := s.udpSC.ListenUDP(s.udpCallback)
@ -151,7 +153,7 @@ func (s *Socks) InitService() (err error) {
err = fmt.Errorf("init udp service fail, ERR: %s", e) err = fmt.Errorf("init udp service fail, ERR: %s", e)
return return
} }
log.Printf("udp socks proxy on %s", s.udpSC.UDPListener.LocalAddr()) s.log.Printf("udp socks proxy on %s", s.udpSC.UDPListener.LocalAddr())
} }
return return
} }
@ -159,9 +161,9 @@ func (s *Socks) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop socks service crashed,%s", e) s.log.Printf("stop socks service crashed,%s", e)
} else { } else {
log.Printf("service socks stoped") s.log.Printf("service socks stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -179,7 +181,8 @@ func (s *Socks) StopService() {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
} }
func (s *Socks) Start(args interface{}) (err error) { func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
//start() //start()
s.cfg = args.(SocksArgs) s.cfg = args.(SocksArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
@ -189,10 +192,10 @@ func (s *Socks) Start(args interface{}) (err error) {
s.InitService() s.InitService()
} }
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
} }
if *s.cfg.UDPParent != "" { if *s.cfg.UDPParent != "" {
log.Printf("use socks udp parent %s", *s.cfg.UDPParent) s.log.Printf("use socks udp parent %s", *s.cfg.UDPParent)
} }
sc := utils.NewServerChannelHost(*s.cfg.Local) sc := utils.NewServerChannelHost(*s.cfg.Local)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == TYPE_TCP {
@ -206,7 +209,7 @@ func (s *Socks) Start(args interface{}) (err error) {
return return
} }
s.sc = &sc s.sc = &sc
log.Printf("%s socks proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) s.log.Printf("%s socks proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
return return
} }
func (s *Socks) Clean() { func (s *Socks) Clean() {
@ -222,29 +225,29 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
//decode b //decode b
rawB, err = goaes.Decrypt(s.UDPKey(), b) rawB, err = goaes.Decrypt(s.UDPKey(), b)
if err != nil { if err != nil {
log.Printf("decrypt udp packet fail from %s", srcAddr.String()) s.log.Printf("decrypt udp packet fail from %s", srcAddr.String())
return return
} }
} }
p, err := socks.ParseUDPPacket(rawB) p, err := socks.ParseUDPPacket(rawB)
log.Printf("udp revecived:%v", len(p.Data())) s.log.Printf("udp revecived:%v", len(p.Data()))
if err != nil { if err != nil {
log.Printf("parse udp packet fail, ERR:%s", err) s.log.Printf("parse udp packet fail, ERR:%s", err)
return return
} }
//防止死循环 //防止死循环
if s.IsDeadLoop((*localAddr).String(), p.Host()) { if s.IsDeadLoop((*localAddr).String(), p.Host()) {
log.Printf("dead loop detected , %s", p.Host()) s.log.Printf("dead loop detected , %s", p.Host())
return return
} }
//log.Printf("##########udp to -> %s:%s###########", p.Host(), p.Port()) //s.log.Printf("##########udp to -> %s:%s###########", p.Host(), p.Port())
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
//有上级代理,转发给上级 //有上级代理,转发给上级
if *s.cfg.ParentType == "tls" { if *s.cfg.ParentType == "tls" {
//encode b //encode b
rawB, err = goaes.Encrypt(s.UDPKey(), rawB) rawB, err = goaes.Encrypt(s.UDPKey(), rawB)
if err != nil { if err != nil {
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent) s.log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
return return
} }
} }
@ -254,43 +257,43 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
} }
dstAddr, err := net.ResolveUDPAddr("udp", s.Resolve(parent)) dstAddr, err := net.ResolveUDPAddr("udp", s.Resolve(parent))
if err != nil { if err != nil {
log.Printf("can't resolve address: %s", err) s.log.Printf("can't resolve address: %s", err)
return return
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*5))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*5)))
_, err = conn.Write(rawB) _, err = conn.Write(rawB)
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
log.Printf("udp request:%v", len(rawB)) s.log.Printf("udp request:%v", len(rawB))
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
conn.Close() conn.Close()
return return
} }
//log.Printf("send udp packet to %s success", dstAddr.String()) //s.log.Printf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 10*1024) buf := make([]byte, 10*1024)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf) length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
conn.Close() conn.Close()
return return
} }
respBody := buf[0:length] respBody := buf[0:length]
log.Printf("udp response:%v", len(respBody)) s.log.Printf("udp response:%v", len(respBody))
//log.Printf("revecived udp packet from %s", dstAddr.String()) //s.log.Printf("revecived udp packet from %s", dstAddr.String())
if *s.cfg.ParentType == "tls" { if *s.cfg.ParentType == "tls" {
//decode b //decode b
respBody, err = goaes.Decrypt(s.UDPKey(), respBody) respBody, err = goaes.Decrypt(s.UDPKey(), respBody)
if err != nil { if err != nil {
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent) s.log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
conn.Close() conn.Close()
return return
} }
@ -298,62 +301,62 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
if *s.cfg.LocalType == "tls" { if *s.cfg.LocalType == "tls" {
d, err := goaes.Encrypt(s.UDPKey(), respBody) d, err := goaes.Encrypt(s.UDPKey(), respBody)
if err != nil { if err != nil {
log.Printf("encrypt udp data fail from %s", dstAddr.String()) s.log.Printf("encrypt udp data fail from %s", dstAddr.String())
conn.Close() conn.Close()
return return
} }
s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
s.udpSC.UDPListener.WriteToUDP(d, srcAddr) s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
s.udpSC.UDPListener.SetDeadline(time.Time{}) s.udpSC.UDPListener.SetDeadline(time.Time{})
log.Printf("udp reply:%v", len(d)) s.log.Printf("udp reply:%v", len(d))
} else { } else {
s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
s.udpSC.UDPListener.WriteToUDP(respBody, srcAddr) s.udpSC.UDPListener.WriteToUDP(respBody, srcAddr)
s.udpSC.UDPListener.SetDeadline(time.Time{}) s.udpSC.UDPListener.SetDeadline(time.Time{})
log.Printf("udp reply:%v", len(respBody)) s.log.Printf("udp reply:%v", len(respBody))
} }
} else { } else {
//本地代理 //本地代理
dstAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(s.Resolve(p.Host()), p.Port())) dstAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(s.Resolve(p.Host()), p.Port()))
if err != nil { if err != nil {
log.Printf("can't resolve address: %s", err) s.log.Printf("can't resolve address: %s", err)
return return
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*3))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*3)))
_, err = conn.Write(p.Data()) _, err = conn.Write(p.Data())
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
log.Printf("udp send:%v", len(p.Data())) s.log.Printf("udp send:%v", len(p.Data()))
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
conn.Close() conn.Close()
return return
} }
//log.Printf("send udp packet to %s success", dstAddr.String()) //s.log.Printf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 10*1024) buf := make([]byte, 10*1024)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf) length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
conn.Close() conn.Close()
return return
} }
respBody := buf[0:length] respBody := buf[0:length]
//封装来自真实服务器的数据,返回给访问者 //封装来自真实服务器的数据,返回给访问者
respPacket := p.NewReply(respBody) respPacket := p.NewReply(respBody)
//log.Printf("revecived udp packet from %s", dstAddr.String()) //s.log.Printf("revecived udp packet from %s", dstAddr.String())
if *s.cfg.LocalType == "tls" { if *s.cfg.LocalType == "tls" {
d, err := goaes.Encrypt(s.UDPKey(), respPacket) d, err := goaes.Encrypt(s.UDPKey(), respPacket)
if err != nil { if err != nil {
log.Printf("encrypt udp data fail from %s", dstAddr.String()) s.log.Printf("encrypt udp data fail from %s", dstAddr.String())
conn.Close() conn.Close()
return return
} }
@ -365,14 +368,14 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
s.udpSC.UDPListener.WriteToUDP(respPacket, srcAddr) s.udpSC.UDPListener.WriteToUDP(respPacket, srcAddr)
s.udpSC.UDPListener.SetDeadline(time.Time{}) s.udpSC.UDPListener.SetDeadline(time.Time{})
} }
log.Printf("udp reply:%v", len(respPacket)) s.log.Printf("udp reply:%v", len(respPacket))
} }
} }
func (s *Socks) socksConnCallback(inConn net.Conn) { func (s *Socks) socksConnCallback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("socks conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("socks conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
inConn.Close() inConn.Close()
} }
}() }()
@ -393,7 +396,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
if err != nil { if err != nil {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE) methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("new methods request fail,ERR: %s", err) s.log.Printf("new methods request fail,ERR: %s", err)
return return
} }
@ -401,29 +404,29 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
if !methodReq.Select(socks.Method_NO_AUTH) { if !methodReq.Select(socks.Method_NO_AUTH) {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE) methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("none method found : Method_NO_AUTH") s.log.Printf("none method found : Method_NO_AUTH")
return return
} }
//method select reply //method select reply
err = methodReq.Reply(socks.Method_NO_AUTH) err = methodReq.Reply(socks.Method_NO_AUTH)
if err != nil { if err != nil {
log.Printf("reply answer data fail,ERR: %s", err) s.log.Printf("reply answer data fail,ERR: %s", err)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
return return
} }
// log.Printf("% x", methodReq.Bytes()) // s.log.Printf("% x", methodReq.Bytes())
} else { } else {
//auth //auth
if !methodReq.Select(socks.Method_USER_PASS) { if !methodReq.Select(socks.Method_USER_PASS) {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE) methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("none method found : Method_USER_PASS") s.log.Printf("none method found : Method_USER_PASS")
return return
} }
//method reply need auth //method reply need auth
err = methodReq.Reply(socks.Method_USER_PASS) err = methodReq.Reply(socks.Method_USER_PASS)
if err != nil { if err != nil {
log.Printf("reply answer data fail,ERR: %s", err) s.log.Printf("reply answer data fail,ERR: %s", err)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
return return
} }
@ -439,7 +442,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
r := buf[:n] r := buf[:n]
user := string(r[2 : r[1]+2]) user := string(r[2 : r[1]+2])
pass := string(r[2+r[1]+1:]) pass := string(r[2+r[1]+1:])
//log.Printf("user:%s,pass:%s", user, pass) //s.log.Printf("user:%s,pass:%s", user, pass)
//auth //auth
_addr := strings.Split(inConn.RemoteAddr().String(), ":") _addr := strings.Split(inConn.RemoteAddr().String(), ":")
if s.basicAuth.CheckUserPass(user, pass, _addr[0], "") { if s.basicAuth.CheckUserPass(user, pass, _addr[0], "") {
@ -460,7 +463,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
//request detail //request detail
request, err := socks.NewRequest(inConn) request, err := socks.NewRequest(inConn)
if err != nil { if err != nil {
log.Printf("read request data fail,ERR: %s", err) s.log.Printf("read request data fail,ERR: %s", err)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
return return
} }
@ -488,7 +491,7 @@ func (s *Socks) proxyUDP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
} }
host, _, _ := net.SplitHostPort((*inConn).LocalAddr().String()) host, _, _ := net.SplitHostPort((*inConn).LocalAddr().String())
_, port, _ := net.SplitHostPort(s.udpSC.UDPListener.LocalAddr().String()) _, port, _ := net.SplitHostPort(s.udpSC.UDPListener.LocalAddr().String())
log.Printf("proxy udp on %s", net.JoinHostPort(host, port)) s.log.Printf("proxy udp on %s", net.JoinHostPort(host, port))
request.UDPReply(socks.REP_SUCCESS, net.JoinHostPort(host, port)) request.UDPReply(socks.REP_SUCCESS, net.JoinHostPort(host, port))
} }
func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) { func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) {
@ -500,7 +503,7 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
//防止死循环 //防止死循环
if s.IsDeadLoop((*inConn).LocalAddr().String(), request.Host()) { if s.IsDeadLoop((*inConn).LocalAddr().String(), request.Host()) {
utils.CloseConn(inConn) utils.CloseConn(inConn)
log.Printf("dead loop detected , %s", request.Host()) s.log.Printf("dead loop detected , %s", request.Host())
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
@ -535,25 +538,25 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
if err == nil || tryCount > maxTryCount || *s.cfg.Parent == "" { if err == nil || tryCount > maxTryCount || *s.cfg.Parent == "" {
break break
} else { } else {
log.Printf("get out conn fail,%s,retrying...", err) s.log.Printf("get out conn fail,%s,retrying...", err)
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
} }
} }
if err != nil { if err != nil {
log.Printf("get out conn fail,%s", err) s.log.Printf("get out conn fail,%s", err)
request.TCPReply(socks.REP_NETWOR_UNREACHABLE) request.TCPReply(socks.REP_NETWOR_UNREACHABLE)
return return
} }
log.Printf("use proxy %v : %s", useProxy, request.Addr()) s.log.Printf("use proxy %v : %s", useProxy, request.Addr())
request.TCPReply(socks.REP_SUCCESS) request.TCPReply(socks.REP_SUCCESS)
inAddr := (*inConn).RemoteAddr().String() inAddr := (*inConn).RemoteAddr().String()
//inLocalAddr := (*inConn).LocalAddr().String() //inLocalAddr := (*inConn).LocalAddr().String()
log.Printf("conn %s - %s connected", inAddr, request.Addr()) s.log.Printf("conn %s - %s connected", inAddr, request.Addr())
utils.IoBind(*inConn, outConn, func(err interface{}) { utils.IoBind(*inConn, outConn, func(err interface{}) {
log.Printf("conn %s - %s released", inAddr, request.Addr()) s.log.Printf("conn %s - %s released", inAddr, request.Addr())
}) })
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
@ -606,7 +609,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
return return
} }
//resp := buf[:n] //resp := buf[:n]
//log.Printf("resp:%v", resp) //s.log.Printf("resp:%v", resp)
outConn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) outConn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = outConn.Write(reqBytes) _, err = outConn.Write(reqBytes)
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
@ -622,7 +625,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
return return
} }
//result := buf[:n] //result := buf[:n]
//log.Printf("result:%v", result) //s.log.Printf("result:%v", result)
case "ssh": case "ssh":
maxTryCount := 1 maxTryCount := 1
@ -648,7 +651,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
s.sshClient.Close() s.sshClient.Close()
} }
if err != nil { if err != nil {
log.Printf("connect ssh fail, ERR: %s, retrying...", err) s.log.Printf("connect ssh fail, ERR: %s, retrying...", err)
e := s.ConnectSSH() e := s.ConnectSSH()
if e == nil { if e == nil {
tryCount++ tryCount++
@ -692,7 +695,7 @@ func (s *Socks) InitBasicAuth() (err error) {
} }
if *s.cfg.AuthURL != "" { if *s.cfg.AuthURL != "" {
s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry) s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
log.Printf("auth from %s", *s.cfg.AuthURL) s.log.Printf("auth from %s", *s.cfg.AuthURL)
} }
if *s.cfg.AuthFile != "" { if *s.cfg.AuthFile != "" {
var n = 0 var n = 0
@ -701,11 +704,11 @@ func (s *Socks) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err) err = fmt.Errorf("auth-file ERR:%s", err)
return return
} }
log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total())
} }
if len(*s.cfg.Auth) > 0 { if len(*s.cfg.Auth) > 0 {
n := s.basicAuth.Add(*s.cfg.Auth) n := s.basicAuth.Add(*s.cfg.Auth)
log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total())
} }
return return
} }
@ -757,7 +760,7 @@ func (s *Socks) Resolve(address string) string {
} }
ip, err := s.domainResolver.Resolve(address) ip, err := s.domainResolver.Resolve(address)
if err != nil { if err != nil {
log.Printf("dns error %s , ERR:%s", address, err) s.log.Printf("dns error %s , ERR:%s", address, err)
} }
return ip return ip
} }

View File

@ -5,16 +5,17 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/socks"
"github.com/snail007/goproxy/utils/conncrypt"
"io/ioutil" "io/ioutil"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/socks"
) )
type SPS struct { type SPS struct {
@ -24,6 +25,7 @@ type SPS struct {
basicAuth utils.BasicAuth basicAuth utils.BasicAuth
serverChannels []*utils.ServerChannel serverChannels []*utils.ServerChannel
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
func NewSPS() Service { func NewSPS() Service {
@ -86,9 +88,9 @@ func (s *SPS) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop sps service crashed,%s", e) s.log.Printf("stop sps service crashed,%s", e)
} else { } else {
log.Printf("service sps stoped") s.log.Printf("service sps stoped")
} }
}() }()
for _, sc := range s.serverChannels { for _, sc := range s.serverChannels {
@ -103,7 +105,8 @@ func (s *SPS) StopService() {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
} }
func (s *SPS) Start(args interface{}) (err error) { func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(SPSArgs) s.cfg = args.(SPSArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -111,7 +114,7 @@ func (s *SPS) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
return return
} }
log.Printf("use %s %s parent %s", *s.cfg.ParentType, *s.cfg.ParentServiceType, *s.cfg.Parent) s.log.Printf("use %s %s parent %s", *s.cfg.ParentType, *s.cfg.ParentServiceType, *s.cfg.Parent)
for _, addr := range strings.Split(*s.cfg.Local, ",") { for _, addr := range strings.Split(*s.cfg.Local, ",") {
if addr != "" { if addr != "" {
host, port, _ := net.SplitHostPort(*s.cfg.Local) host, port, _ := net.SplitHostPort(*s.cfg.Local)
@ -127,7 +130,7 @@ func (s *SPS) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("%s http(s)+socks proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr()) s.log.Printf("%s http(s)+socks proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr())
s.serverChannels = append(s.serverChannels, &sc) s.serverChannels = append(s.serverChannels, &sc)
} }
} }
@ -140,7 +143,7 @@ func (s *SPS) Clean() {
func (s *SPS) callback(inConn net.Conn) { func (s *SPS) callback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack())) s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack()))
} }
}() }()
if *s.cfg.LocalCompress { if *s.cfg.LocalCompress {
@ -163,7 +166,7 @@ func (s *SPS) callback(inConn net.Conn) {
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
} }
if err != nil { if err != nil {
log.Printf("connect to %s parent %s fail, ERR:%s from %s", *s.cfg.ParentType, *s.cfg.Parent, err, inConn.RemoteAddr()) s.log.Printf("connect to %s parent %s fail, ERR:%s from %s", *s.cfg.ParentType, *s.cfg.Parent, err, inConn.RemoteAddr())
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
} }
} }
@ -172,7 +175,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
n, err := (*inConn).Read(buf) n, err := (*inConn).Read(buf)
header := buf[:n] header := buf[:n]
if err != nil { if err != nil {
log.Printf("ERR:%s", err) s.log.Printf("ERR:%s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
@ -204,14 +207,14 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
} }
(*inConn).SetDeadline(time.Time{}) (*inConn).SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("new http request fail,ERR: %s", err) s.log.Printf("new http request fail,ERR: %s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
if len(header) >= 7 && strings.ToLower(string(header[:7])) == "connect" { if len(header) >= 7 && strings.ToLower(string(header[:7])) == "connect" {
//https //https
request.HTTPSReply() request.HTTPSReply()
//log.Printf("https reply: %s", request.Host) //s.log.Printf("https reply: %s", request.Host)
} else { } else {
forwardBytes = request.HeadBuf forwardBytes = request.HeadBuf
} }
@ -228,7 +231,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
} }
} }
} else { } else {
log.Printf("unknown request from: %s,%s", (*inConn).RemoteAddr(), string(header)) s.log.Printf("unknown request from: %s,%s", (*inConn).RemoteAddr(), string(header))
utils.CloseConn(inConn) utils.CloseConn(inConn)
err = errors.New("unknown request") err = errors.New("unknown request")
return return
@ -237,7 +240,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
var outConn net.Conn var outConn net.Conn
outConn, err = s.outPool.Get() outConn, err = s.outPool.Get()
if err != nil { if err != nil {
log.Printf("connect to %s , err:%s", *s.cfg.Parent, err) s.log.Printf("connect to %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
@ -276,7 +279,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
_, err = outConn.Write(pb.Bytes()) _, err = outConn.Write(pb.Bytes())
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("write CONNECT to %s , err:%s", *s.cfg.Parent, err) s.log.Printf("write CONNECT to %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
return return
@ -286,14 +289,14 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
_, err = outConn.Read(reply) _, err = outConn.Read(reply)
outConn.SetDeadline(time.Time{}) outConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
log.Printf("read reply from %s , err:%s", *s.cfg.Parent, err) s.log.Printf("read reply from %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
return return
} }
//log.Printf("reply: %s", string(reply[:n])) //s.log.Printf("reply: %s", string(reply[:n]))
} else { } else {
log.Printf("connect %s", address) s.log.Printf("connect %s", address)
//socks client //socks client
var clientConn *socks.ClientConn var clientConn *socks.ClientConn
if *s.cfg.ParentAuth != "" { if *s.cfg.ParentAuth != "" {
@ -322,10 +325,10 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
inAddr := (*inConn).RemoteAddr().String() inAddr := (*inConn).RemoteAddr().String()
outAddr := outConn.RemoteAddr().String() outAddr := outConn.RemoteAddr().String()
utils.IoBind((*inConn), outConn, func(err interface{}) { utils.IoBind((*inConn), outConn, func(err interface{}) {
log.Printf("conn %s - %s released", inAddr, outAddr) s.log.Printf("conn %s - %s released", inAddr, outAddr)
s.userConns.Remove(inAddr) s.userConns.Remove(inAddr)
}) })
log.Printf("conn %s - %s connected", inAddr, outAddr) s.log.Printf("conn %s - %s connected", inAddr, outAddr)
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
@ -340,7 +343,7 @@ func (s *SPS) InitBasicAuth() (err error) {
} }
if *s.cfg.AuthURL != "" { if *s.cfg.AuthURL != "" {
s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry) s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
log.Printf("auth from %s", *s.cfg.AuthURL) s.log.Printf("auth from %s", *s.cfg.AuthURL)
} }
if *s.cfg.AuthFile != "" { if *s.cfg.AuthFile != "" {
var n = 0 var n = 0
@ -349,11 +352,11 @@ func (s *SPS) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err) err = fmt.Errorf("auth-file ERR:%s", err)
return return
} }
log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total())
} }
if len(*s.cfg.Auth) > 0 { if len(*s.cfg.Auth) > 0 {
n := s.basicAuth.Add(*s.cfg.Auth) n := s.basicAuth.Add(*s.cfg.Auth)
log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total()) s.log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total())
} }
return return
} }
@ -404,7 +407,7 @@ func (s *SPS) Resolve(address string) string {
} }
ip, err := s.domainResolver.Resolve(address) ip, err := s.domainResolver.Resolve(address)
if err != nil { if err != nil {
log.Printf("dns error %s , ERR:%s", address, err) s.log.Printf("dns error %s , ERR:%s", address, err)
} }
return ip return ip
} }

View File

@ -3,13 +3,14 @@ package services
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"time" "time"
"github.com/snail007/goproxy/utils"
"strconv" "strconv"
) )
@ -19,6 +20,7 @@ type TCP struct {
sc *utils.ServerChannel sc *utils.ServerChannel
isStop bool isStop bool
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
func NewTCP() Service { func NewTCP() Service {
@ -54,9 +56,9 @@ func (s *TCP) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop tcp service crashed,%s", e) s.log.Printf("stop tcp service crashed,%s", e)
} else { } else {
log.Printf("service tcp stoped") s.log.Printf("service tcp stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -70,7 +72,8 @@ func (s *TCP) StopService() {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
} }
func (s *TCP) Start(args interface{}) (err error) { func (s *TCP) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(TCPArgs) s.cfg = args.(TCPArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -78,7 +81,7 @@ func (s *TCP) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
return return
} }
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
host, port, _ := net.SplitHostPort(*s.cfg.Local) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p) sc := utils.NewServerChannel(host, p)
@ -93,7 +96,7 @@ func (s *TCP) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("%s proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr()) s.log.Printf("%s proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr())
s.sc = &sc s.sc = &sc
return return
} }
@ -104,7 +107,7 @@ func (s *TCP) Clean() {
func (s *TCP) callback(inConn net.Conn) { func (s *TCP) callback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack())) s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack()))
} }
}() }()
var err error var err error
@ -121,7 +124,7 @@ func (s *TCP) callback(inConn net.Conn) {
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
} }
if err != nil { if err != nil {
log.Printf("connect to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err) s.log.Printf("connect to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
} }
} }
@ -129,7 +132,7 @@ func (s *TCP) OutToTCP(inConn *net.Conn) (err error) {
var outConn net.Conn var outConn net.Conn
outConn, err = s.outPool.Get() outConn, err = s.outPool.Get()
if err != nil { if err != nil {
log.Printf("connect to %s , err:%s", *s.cfg.Parent, err) s.log.Printf("connect to %s , err:%s", *s.cfg.Parent, err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
@ -138,10 +141,10 @@ func (s *TCP) OutToTCP(inConn *net.Conn) (err error) {
outAddr := outConn.RemoteAddr().String() outAddr := outConn.RemoteAddr().String()
//outLocalAddr := outConn.LocalAddr().String() //outLocalAddr := outConn.LocalAddr().String()
utils.IoBind((*inConn), outConn, func(err interface{}) { utils.IoBind((*inConn), outConn, func(err interface{}) {
log.Printf("conn %s - %s released", inAddr, outAddr) s.log.Printf("conn %s - %s released", inAddr, outAddr)
s.userConns.Remove(inAddr) s.userConns.Remove(inAddr)
}) })
log.Printf("conn %s - %s connected", inAddr, outAddr) s.log.Printf("conn %s - %s connected", inAddr, outAddr)
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
@ -149,7 +152,7 @@ func (s *TCP) OutToTCP(inConn *net.Conn) (err error) {
return return
} }
func (s *TCP) OutToUDP(inConn *net.Conn) (err error) { func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
log.Printf("conn created , remote : %s ", (*inConn).RemoteAddr()) s.log.Printf("conn created , remote : %s ", (*inConn).RemoteAddr())
for { for {
if s.isStop { if s.isStop {
(*inConn).Close() (*inConn).Close()
@ -157,45 +160,45 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
} }
srcAddr, body, err := utils.ReadUDPPacket(bufio.NewReader(*inConn)) srcAddr, body, err := utils.ReadUDPPacket(bufio.NewReader(*inConn))
if err == io.EOF || err == io.ErrUnexpectedEOF { if err == io.EOF || err == io.ErrUnexpectedEOF {
//log.Printf("connection %s released", srcAddr) //s.log.Printf("connection %s released", srcAddr)
utils.CloseConn(inConn) utils.CloseConn(inConn)
break break
} }
//log.Debugf("udp packet revecived:%s,%v", srcAddr, body) //log.Debugf("udp packet revecived:%s,%v", srcAddr, body)
dstAddr, err := net.ResolveUDPAddr("udp", *s.cfg.Parent) dstAddr, err := net.ResolveUDPAddr("udp", *s.cfg.Parent)
if err != nil { if err != nil {
log.Printf("can't resolve address: %s", err) s.log.Printf("can't resolve address: %s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
break break
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
continue continue
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(body) _, err = conn.Write(body)
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
continue continue
} }
//log.Debugf("send udp packet to %s success", dstAddr.String()) //log.Debugf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 512) buf := make([]byte, 512)
len, _, err := conn.ReadFromUDP(buf) len, _, err := conn.ReadFromUDP(buf)
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
continue continue
} }
respBody := buf[0:len] respBody := buf[0:len]
//log.Debugf("revecived udp packet from %s , %v", dstAddr.String(), respBody) //log.Debugf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
_, err = (*inConn).Write(utils.UDPPacket(srcAddr, respBody)) _, err = (*inConn).Write(utils.UDPPacket(srcAddr, respBody))
if err != nil { if err != nil {
log.Printf("send udp response fail ,ERR:%s", err) s.log.Printf("send udp response fail ,ERR:%s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
break break
} }
//log.Printf("send udp response success ,from:%s", dstAddr.String()) //s.log.Printf("send udp response success ,from:%s", dstAddr.String())
} }
return return

View File

@ -3,12 +3,13 @@ package services
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/snail007/goproxy/utils" logger "log"
"log"
"net" "net"
"strconv" "strconv"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -21,6 +22,7 @@ type TunnelBridge struct {
serverConns utils.ConcurrentMap serverConns utils.ConcurrentMap
clientControlConns utils.ConcurrentMap clientControlConns utils.ConcurrentMap
isStop bool isStop bool
log *logger.Logger
} }
func NewTunnelBridge() Service { func NewTunnelBridge() Service {
@ -47,9 +49,9 @@ func (s *TunnelBridge) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop tbridge service crashed,%s", e) s.log.Printf("stop tbridge service crashed,%s", e)
} else { } else {
log.Printf("service tbridge stoped") s.log.Printf("service tbridge stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -60,7 +62,8 @@ func (s *TunnelBridge) StopService() {
(*sess.(ServerConn).Conn).Close() (*sess.(ServerConn).Conn).Close()
} }
} }
func (s *TunnelBridge) Start(args interface{}) (err error) { func (s *TunnelBridge) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(TunnelBridgeArgs) s.cfg = args.(TunnelBridgeArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -76,7 +79,7 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("proxy on tunnel bridge mode %s", (*sc.Listener).Addr()) s.log.Printf("proxy on tunnel bridge mode %s", (*sc.Listener).Addr())
return return
} }
func (s *TunnelBridge) Clean() { func (s *TunnelBridge) Clean() {
@ -84,7 +87,7 @@ func (s *TunnelBridge) Clean() {
} }
func (s *TunnelBridge) callback(inConn net.Conn) { func (s *TunnelBridge) callback(inConn net.Conn) {
var err error var err error
//log.Printf("connection from %s ", inConn.RemoteAddr()) //s.log.Printf("connection from %s ", inConn.RemoteAddr())
sess, err := smux.Server(inConn, &smux.Config{ sess, err := smux.Server(inConn, &smux.Config{
KeepAliveInterval: 10 * time.Second, KeepAliveInterval: 10 * time.Second,
KeepAliveTimeout: time.Duration(*s.cfg.Timeout) * time.Second, KeepAliveTimeout: time.Duration(*s.cfg.Timeout) * time.Second,
@ -92,12 +95,12 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
MaxReceiveBuffer: 4194304, MaxReceiveBuffer: 4194304,
}) })
if err != nil { if err != nil {
log.Printf("new mux server conn error,ERR:%s", err) s.log.Printf("new mux server conn error,ERR:%s", err)
return return
} }
inConn, err = sess.AcceptStream() inConn, err = sess.AcceptStream()
if err != nil { if err != nil {
log.Printf("mux server conn accept error,ERR:%s", err) s.log.Printf("mux server conn accept error,ERR:%s", err)
return return
} }
@ -109,7 +112,7 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
var connType uint8 var connType uint8
err = utils.ReadPacket(reader, &connType) err = utils.ReadPacket(reader, &connType)
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.log.Printf("read error,ERR:%s", err)
return return
} }
switch connType { switch connType {
@ -117,11 +120,11 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
var key, ID, clientLocalAddr, serverID string var key, ID, clientLocalAddr, serverID string
err = utils.ReadPacketData(reader, &key, &ID, &clientLocalAddr, &serverID) err = utils.ReadPacketData(reader, &key, &ID, &clientLocalAddr, &serverID)
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.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) s.log.Printf("server connection, key: %s , id: %s %s %s", key, ID, clientLocalAddr, serverID)
//addr := clientLocalAddr + "@" + ID //addr := clientLocalAddr + "@" + ID
s.serverConns.Set(ID, ServerConn{ s.serverConns.Set(ID, ServerConn{
@ -133,7 +136,7 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
} }
item, ok := s.clientControlConns.Get(key) item, ok := s.clientControlConns.Get(key)
if !ok { if !ok {
log.Printf("client %s control conn not exists", key) s.log.Printf("client %s control conn not exists", key)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} }
@ -141,7 +144,7 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
_, err := (*item.(*net.Conn)).Write(packet) _, err := (*item.(*net.Conn)).Write(packet)
(*item.(*net.Conn)).SetWriteDeadline(time.Time{}) (*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) s.log.Printf("%s client control conn write signal fail, err: %s, retrying...", key, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -153,15 +156,15 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
var key, ID, serverID string var key, ID, serverID string
err = utils.ReadPacketData(reader, &key, &ID, &serverID) err = utils.ReadPacketData(reader, &key, &ID, &serverID)
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.log.Printf("read error,ERR:%s", err)
return return
} }
log.Printf("client connection , key: %s , id: %s, server id:%s", key, ID, serverID) s.log.Printf("client connection , key: %s , id: %s, server id:%s", key, ID, serverID)
serverConnItem, ok := s.serverConns.Get(ID) serverConnItem, ok := s.serverConns.Get(ID)
if !ok { if !ok {
inConn.Close() inConn.Close()
log.Printf("server conn %s exists", ID) s.log.Printf("server conn %s exists", ID)
return return
} }
serverConn := serverConnItem.(ServerConn).Conn serverConn := serverConnItem.(ServerConn).Conn
@ -169,24 +172,24 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
s.serverConns.Remove(ID) s.serverConns.Remove(ID)
// s.cmClient.RemoveOne(key, ID) // s.cmClient.RemoveOne(key, ID)
// s.cmServer.RemoveOne(serverID, ID) // s.cmServer.RemoveOne(serverID, ID)
log.Printf("conn %s released", ID) s.log.Printf("conn %s released", ID)
}) })
// s.cmClient.Add(key, ID, &inConn) // s.cmClient.Add(key, ID, &inConn)
log.Printf("conn %s created", ID) s.log.Printf("conn %s created", ID)
case CONN_CLIENT_CONTROL: case CONN_CLIENT_CONTROL:
var key string var key string
err = utils.ReadPacketData(reader, &key) err = utils.ReadPacketData(reader, &key)
if err != nil { if err != nil {
log.Printf("read error,ERR:%s", err) s.log.Printf("read error,ERR:%s", err)
return return
} }
log.Printf("client control connection, key: %s", key) s.log.Printf("client control connection, key: %s", key)
if s.clientControlConns.Has(key) { if s.clientControlConns.Has(key) {
item, _ := s.clientControlConns.Get(key) item, _ := s.clientControlConns.Get(key)
(*item.(*net.Conn)).Close() (*item.(*net.Conn)).Close()
} }
s.clientControlConns.Set(key, &inConn) s.clientControlConns.Set(key, &inConn)
log.Printf("set client %s control conn", key) s.log.Printf("set client %s control conn", key)
} }
} }

View File

@ -3,12 +3,13 @@ package services
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"net" "net"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -17,6 +18,7 @@ type TunnelClient struct {
ctrlConn net.Conn ctrlConn net.Conn
isStop bool isStop bool
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
func NewTunnelClient() Service { func NewTunnelClient() Service {
@ -33,7 +35,7 @@ func (s *TunnelClient) InitService() (err error) {
func (s *TunnelClient) CheckArgs() (err error) { func (s *TunnelClient) CheckArgs() (err error) {
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent) s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else { } else {
err = fmt.Errorf("parent required") err = fmt.Errorf("parent required")
return return
@ -49,9 +51,9 @@ func (s *TunnelClient) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop tclient service crashed,%s", e) s.log.Printf("stop tclient service crashed,%s", e)
} else { } else {
log.Printf("service tclient stoped") s.log.Printf("service tclient stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -62,7 +64,8 @@ func (s *TunnelClient) StopService() {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
} }
func (s *TunnelClient) Start(args interface{}) (err error) { func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(TunnelClientArgs) s.cfg = args.(TunnelClientArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -70,7 +73,7 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
return return
} }
log.Printf("proxy on tunnel client mode") s.log.Printf("proxy on tunnel client mode")
for { for {
if s.isStop { if s.isStop {
@ -82,7 +85,7 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
s.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) s.log.Printf("control connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
if s.ctrlConn != nil { if s.ctrlConn != nil {
s.ctrlConn.Close() s.ctrlConn.Close()
@ -99,10 +102,10 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
if s.ctrlConn != nil { if s.ctrlConn != nil {
s.ctrlConn.Close() s.ctrlConn.Close()
} }
log.Printf("read connection signal err: %s, retrying...", err) s.log.Printf("read connection signal err: %s, retrying...", err)
break break
} }
log.Printf("signal revecived:%s %s %s", serverID, ID, clientLocalAddr) s.log.Printf("signal revecived:%s %s %s", serverID, ID, clientLocalAddr)
protocol := clientLocalAddr[:3] protocol := clientLocalAddr[:3]
localAddr := clientLocalAddr[4:] localAddr := clientLocalAddr[4:]
if protocol == "udp" { if protocol == "udp" {
@ -142,13 +145,13 @@ func (s *TunnelClient) GetConn() (conn net.Conn, err error) {
MaxReceiveBuffer: 4194304, MaxReceiveBuffer: 4194304,
}) })
if e != nil { if e != nil {
log.Printf("new mux client conn error,ERR:%s", e) s.log.Printf("new mux client conn error,ERR:%s", e)
err = e err = e
return return
} }
conn, e = c.OpenStream() conn, e = c.OpenStream()
if e != nil { if e != nil {
log.Printf("mux client conn open stream error,ERR:%s", e) s.log.Printf("mux client conn open stream error,ERR:%s", e)
err = e err = e
return return
} }
@ -170,7 +173,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID) inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
if err != nil { if err != nil {
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("connection err: %s, retrying...", err) s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -178,7 +181,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
} }
} }
// s.cm.Add(*s.cfg.Key, ID, &inConn) // s.cm.Add(*s.cfg.Key, ID, &inConn)
log.Printf("conn %s created", ID) s.log.Printf("conn %s created", ID)
for { for {
if s.isStop { if s.isStop {
@ -186,13 +189,13 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
} }
srcAddr, body, err := utils.ReadUDPPacket(inConn) srcAddr, body, err := utils.ReadUDPPacket(inConn)
if err == io.EOF || err == io.ErrUnexpectedEOF { if err == io.EOF || err == io.ErrUnexpectedEOF {
log.Printf("connection %s released", ID) s.log.Printf("connection %s released", ID)
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
break break
} else if err != nil { } else if err != nil {
log.Printf("udp packet revecived fail, err: %s", err) s.log.Printf("udp packet revecived fail, err: %s", err)
} else { } else {
//log.Printf("udp packet revecived:%s,%v", srcAddr, body) //s.log.Printf("udp packet revecived:%s,%v", srcAddr, body)
go s.processUDPPacket(&inConn, srcAddr, localAddr, body) go s.processUDPPacket(&inConn, srcAddr, localAddr, body)
} }
@ -202,39 +205,39 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
func (s *TunnelClient) processUDPPacket(inConn *net.Conn, srcAddr, localAddr string, body []byte) { func (s *TunnelClient) processUDPPacket(inConn *net.Conn, 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) s.log.Printf("can't resolve address: %s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(body) _, err = conn.Write(body)
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
//log.Printf("send udp packet to %s success", dstAddr.String()) //s.log.Printf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 1024) buf := make([]byte, 1024)
length, _, err := conn.ReadFromUDP(buf) length, _, err := conn.ReadFromUDP(buf)
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
return return
} }
respBody := buf[0:length] respBody := buf[0:length]
//log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody) //s.log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
bs := utils.UDPPacket(srcAddr, respBody) bs := utils.UDPPacket(srcAddr, respBody)
_, err = (*inConn).Write(bs) _, err = (*inConn).Write(bs)
if err != nil { if err != nil {
log.Printf("send udp response fail ,ERR:%s", err) s.log.Printf("send udp response fail ,ERR:%s", err)
utils.CloseConn(inConn) utils.CloseConn(inConn)
return return
} }
//log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs) //s.log.Printf("send udp response success ,from:%s ,%d ,%v", dstAddr.String(), len(bs), bs)
} }
func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) { func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
var inConn, outConn net.Conn var inConn, outConn net.Conn
@ -246,7 +249,7 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID) inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
if err != nil { if err != nil {
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
log.Printf("connection err: %s, retrying...", err) s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -265,7 +268,7 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
break break
} else { } else {
if i == 3 { if i == 3 {
log.Printf("connect to %s err: %s, retrying...", localAddr, err) s.log.Printf("connect to %s err: %s, retrying...", localAddr, err)
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
continue continue
} }
@ -274,17 +277,17 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
if err != nil { if err != nil {
utils.CloseConn(&inConn) utils.CloseConn(&inConn)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
log.Printf("build connection error, err: %s", err) s.log.Printf("build connection error, err: %s", err)
return return
} }
inAddr := inConn.RemoteAddr().String() inAddr := inConn.RemoteAddr().String()
utils.IoBind(inConn, outConn, func(err interface{}) { utils.IoBind(inConn, outConn, func(err interface{}) {
log.Printf("conn %s released", ID) s.log.Printf("conn %s released", ID)
s.userConns.Remove(inAddr) s.userConns.Remove(inAddr)
}) })
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
s.userConns.Set(inAddr, &inConn) s.userConns.Set(inAddr, &inConn)
log.Printf("conn %s created", ID) s.log.Printf("conn %s created", ID)
} }

View File

@ -3,15 +3,16 @@ package services
import ( import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/snail007/goproxy/utils"
"io" "io"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux" "github.com/xtaci/smux"
) )
@ -22,6 +23,7 @@ type TunnelServer struct {
isStop bool isStop bool
udpConn *net.Conn udpConn *net.Conn
userConns utils.ConcurrentMap userConns utils.ConcurrentMap
log *logger.Logger
} }
type TunnelServerManager struct { type TunnelServerManager struct {
@ -29,6 +31,7 @@ type TunnelServerManager struct {
udpChn chan UDPItem udpChn chan UDPItem
serverID string serverID string
servers []*Service servers []*Service
log *logger.Logger
} }
func NewTunnelServerManager() Service { func NewTunnelServerManager() Service {
@ -39,13 +42,14 @@ func NewTunnelServerManager() Service {
servers: []*Service{}, servers: []*Service{},
} }
} }
func (s *TunnelServerManager) Start(args interface{}) (err error) { func (s *TunnelServerManager) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(TunnelServerArgs) s.cfg = args.(TunnelServerArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
} }
if *s.cfg.Parent != "" { if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent) s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else { } else {
err = fmt.Errorf("parent required") err = fmt.Errorf("parent required")
return return
@ -55,8 +59,8 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
return return
} }
log.Printf("server id: %s", s.serverID) s.log.Printf("server id: %s", s.serverID)
//log.Printf("route:%v", *s.cfg.Route) //s.log.Printf("route:%v", *s.cfg.Route)
for _, _info := range *s.cfg.Route { for _, _info := range *s.cfg.Route {
IsUDP := *s.cfg.IsUDP IsUDP := *s.cfg.IsUDP
if strings.HasPrefix(_info, "udp://") { if strings.HasPrefix(_info, "udp://") {
@ -88,7 +92,7 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
Key: &KEY, Key: &KEY,
Timeout: s.cfg.Timeout, Timeout: s.cfg.Timeout,
Mgr: s, Mgr: s,
}) }, log)
if err != nil { if err != nil {
return return
@ -120,13 +124,13 @@ func (s *TunnelServerManager) InitService() (err error) {
func (s *TunnelServerManager) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) { func (s *TunnelServerManager) GetOutConn(typ uint8) (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) s.log.Printf("connection err: %s", err)
return return
} }
ID = s.serverID ID = s.serverID
_, err = outConn.Write(utils.BuildPacket(typ, s.serverID)) _, err = outConn.Write(utils.BuildPacket(typ, s.serverID))
if err != nil { if err != nil {
log.Printf("write connection data err: %s ,retrying...", err) s.log.Printf("write connection data err: %s ,retrying...", err)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
return return
} }
@ -159,9 +163,9 @@ func (s *TunnelServer) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop server service crashed,%s", e) s.log.Printf("stop server service crashed,%s", e)
} else { } else {
log.Printf("service server stoped") s.log.Printf("service server stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -191,7 +195,8 @@ func (s *TunnelServer) CheckArgs() (err error) {
return return
} }
func (s *TunnelServer) Start(args interface{}) (err error) { func (s *TunnelServer) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(TunnelServerArgs) s.cfg = args.(TunnelServerArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
@ -213,12 +218,12 @@ func (s *TunnelServer) 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()) s.log.Printf("proxy on udp tunnel 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())) s.log.Printf("tserver conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
var outConn net.Conn var outConn net.Conn
@ -230,7 +235,7 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
outConn, ID, err = s.GetOutConn(CONN_SERVER) outConn, ID, err = s.GetOutConn(CONN_SERVER)
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) s.log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -240,18 +245,18 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
inAddr := inConn.RemoteAddr().String() inAddr := inConn.RemoteAddr().String()
utils.IoBind(inConn, outConn, func(err interface{}) { utils.IoBind(inConn, outConn, func(err interface{}) {
s.userConns.Remove(inAddr) s.userConns.Remove(inAddr)
log.Printf("%s conn %s released", *s.cfg.Key, ID) s.log.Printf("%s conn %s released", *s.cfg.Key, ID)
}) })
if c, ok := s.userConns.Get(inAddr); ok { if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close() (*c.(*net.Conn)).Close()
} }
s.userConns.Set(inAddr, &inConn) s.userConns.Set(inAddr, &inConn)
log.Printf("%s conn %s created", *s.cfg.Key, ID) s.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()) s.log.Printf("proxy on tunnel server mode %s", (*s.sc.Listener).Addr())
} }
return return
} }
@ -261,7 +266,7 @@ func (s *TunnelServer) Clean() {
func (s *TunnelServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) { func (s *TunnelServer) GetOutConn(typ uint8) (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) s.log.Printf("connection err: %s", err)
return return
} }
remoteAddr := "tcp:" + *s.cfg.Remote remoteAddr := "tcp:" + *s.cfg.Remote
@ -271,7 +276,7 @@ func (s *TunnelServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err e
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.BuildPacket(typ, *s.cfg.Key, ID, remoteAddr, s.cfg.Mgr.serverID))
if err != nil { if err != nil {
log.Printf("write connection data err: %s ,retrying...", err) s.log.Printf("write connection data err: %s ,retrying...", err)
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
return return
} }
@ -289,13 +294,13 @@ func (s *TunnelServer) GetConn() (conn net.Conn, err error) {
MaxReceiveBuffer: 4194304, MaxReceiveBuffer: 4194304,
}) })
if e != nil { if e != nil {
log.Printf("new mux client conn error,ERR:%s", e) s.log.Printf("new mux client conn error,ERR:%s", e)
err = e err = e
return return
} }
conn, e = c.OpenStream() conn, e = c.OpenStream()
if e != nil { if e != nil {
log.Printf("mux client conn open stream error,ERR:%s", e) s.log.Printf("mux client conn open stream error,ERR:%s", e)
err = e err = e
return return
} }
@ -306,7 +311,7 @@ func (s *TunnelServer) UDPConnDeamon() {
go func() { go func() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("udp conn deamon crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("udp conn deamon crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
var outConn net.Conn var outConn net.Conn
@ -333,7 +338,7 @@ func (s *TunnelServer) UDPConnDeamon() {
// cmdChn <- true // 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) s.log.Printf("connect to %s fail, err: %s, retrying...", *s.cfg.Parent, err)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
continue continue
} else { } else {
@ -348,27 +353,27 @@ func (s *TunnelServer) UDPConnDeamon() {
} }
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn) srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
if err == io.EOF || err == io.ErrUnexpectedEOF { if err == io.EOF || err == io.ErrUnexpectedEOF {
log.Printf("UDP deamon connection %s exited", ID) s.log.Printf("UDP deamon connection %s exited", ID)
break break
} }
if err != nil { if err != nil {
log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body) s.log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
continue continue
} }
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn) //s.log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
_srcAddr := strings.Split(srcAddrFromConn, ":") _srcAddr := strings.Split(srcAddrFromConn, ":")
if len(_srcAddr) != 2 { if len(_srcAddr) != 2 {
log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn) s.log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn)
continue continue
} }
port, _ := strconv.Atoi(_srcAddr[1]) port, _ := strconv.Atoi(_srcAddr[1])
dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port} dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port}
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr) _, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
if err != nil { if err != nil {
log.Printf("udp response to local %s fail,ERR:%s", srcAddrFromConn, err) s.log.Printf("udp response to local %s fail,ERR:%s", srcAddrFromConn, err)
continue continue
} }
//log.Printf("udp response to local %s success , %v", srcAddrFromConn, body) //s.log.Printf("udp response to local %s success , %v", srcAddrFromConn, body)
} }
}(outConn, ID) }(outConn, ID)
break break
@ -381,10 +386,10 @@ func (s *TunnelServer) UDPConnDeamon() {
if err != nil { if err != nil {
utils.CloseConn(&outConn) utils.CloseConn(&outConn)
outConn = nil outConn = nil
log.Printf("write udp packet to %s fail ,flush err:%s ,retrying...", *s.cfg.Parent, err) s.log.Printf("write udp packet to %s fail ,flush err:%s ,retrying...", *s.cfg.Parent, err)
goto RETRY goto RETRY
} }
//log.Printf("write packet %v", *item.packet) //s.log.Printf("write packet %v", *item.packet)
} }
}() }()
} }

View File

@ -3,16 +3,17 @@ package services
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
"hash/crc32" "hash/crc32"
"io" "io"
"log" logger "log"
"net" "net"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
) )
type UDP struct { type UDP struct {
@ -21,6 +22,7 @@ type UDP struct {
cfg UDPArgs cfg UDPArgs
sc *utils.ServerChannel sc *utils.ServerChannel
isStop bool isStop bool
log *logger.Logger
} }
func NewUDP() Service { func NewUDP() Service {
@ -57,9 +59,9 @@ func (s *UDP) StopService() {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { if e != nil {
log.Printf("stop udp service crashed,%s", e) s.log.Printf("stop udp service crashed,%s", e)
} else { } else {
log.Printf("service udp stoped") s.log.Printf("service udp stoped")
} }
}() }()
s.isStop = true s.isStop = true
@ -70,12 +72,13 @@ func (s *UDP) StopService() {
(*s.sc.UDPListener).Close() (*s.sc.UDPListener).Close()
} }
} }
func (s *UDP) Start(args interface{}) (err error) { func (s *UDP) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(UDPArgs) s.cfg = args.(UDPArgs)
if err = s.CheckArgs(); err != nil { if err = s.CheckArgs(); err != nil {
return return
} }
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent) s.log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
if err = s.InitService(); err != nil { if err = s.InitService(); err != nil {
return return
} }
@ -87,7 +90,7 @@ func (s *UDP) Start(args interface{}) (err error) {
if err != nil { if err != nil {
return return
} }
log.Printf("udp proxy on %s", (*sc.UDPListener).LocalAddr()) s.log.Printf("udp proxy on %s", (*sc.UDPListener).LocalAddr())
return return
} }
@ -97,7 +100,7 @@ func (s *UDP) Clean() {
func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) { func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("udp conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("udp conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
var err error var err error
@ -112,7 +115,7 @@ func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) {
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
} }
if err != nil { if err != nil {
log.Printf("connect to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err) s.log.Printf("connect to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err)
} }
} }
func (s *UDP) GetConn(connKey string) (conn net.Conn, isNew bool, err error) { func (s *UDP) GetConn(connKey string) (conn net.Conn, isNew bool, err error) {
@ -140,17 +143,17 @@ func (s *UDP) OutToTCP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err erro
connKey := uint64((numLocal/10)*10 + numSrc%mod) connKey := uint64((numLocal/10)*10 + numSrc%mod)
conn, isNew, err := s.GetConn(fmt.Sprintf("%d", connKey)) conn, isNew, err := s.GetConn(fmt.Sprintf("%d", connKey))
if err != nil { if err != nil {
log.Printf("upd get conn to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err) s.log.Printf("upd get conn to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err)
return return
} }
if isNew { if isNew {
go func() { go func() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("udp conn handler out to tcp crashed with err : %s \nstack: %s", err, string(debug.Stack())) s.log.Printf("udp conn handler out to tcp crashed with err : %s \nstack: %s", err, string(debug.Stack()))
} }
}() }()
log.Printf("conn %d created , local: %s", connKey, srcAddr.String()) s.log.Printf("conn %d created , local: %s", connKey, srcAddr.String())
for { for {
if s.isStop { if s.isStop {
conn.Close() conn.Close()
@ -158,76 +161,76 @@ func (s *UDP) OutToTCP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err erro
} }
srcAddrFromConn, body, err := utils.ReadUDPPacket(bufio.NewReader(conn)) srcAddrFromConn, body, err := utils.ReadUDPPacket(bufio.NewReader(conn))
if err == io.EOF || err == io.ErrUnexpectedEOF { if err == io.EOF || err == io.ErrUnexpectedEOF {
//log.Printf("connection %d released", connKey) //s.log.Printf("connection %d released", connKey)
s.p.Remove(fmt.Sprintf("%d", connKey)) s.p.Remove(fmt.Sprintf("%d", connKey))
break break
} }
if err != nil { if err != nil {
log.Printf("parse revecived udp packet fail, err: %s", err) s.log.Printf("parse revecived udp packet fail, err: %s", err)
continue continue
} }
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn) //s.log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
_srcAddr := strings.Split(srcAddrFromConn, ":") _srcAddr := strings.Split(srcAddrFromConn, ":")
if len(_srcAddr) != 2 { if len(_srcAddr) != 2 {
log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn) s.log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn)
continue continue
} }
port, _ := strconv.Atoi(_srcAddr[1]) port, _ := strconv.Atoi(_srcAddr[1])
dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port} dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port}
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr) _, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
if err != nil { if err != nil {
log.Printf("udp response to local %s fail,ERR:%s", srcAddr, err) s.log.Printf("udp response to local %s fail,ERR:%s", srcAddr, err)
continue continue
} }
//log.Printf("udp response to local %s success", srcAddr) //s.log.Printf("udp response to local %s success", srcAddr)
} }
}() }()
} }
//log.Printf("select conn %d , local: %s", connKey, srcAddr.String()) //s.log.Printf("select conn %d , local: %s", connKey, srcAddr.String())
writer := bufio.NewWriter(conn) writer := bufio.NewWriter(conn)
//fmt.Println(conn, writer) //fmt.Println(conn, writer)
writer.Write(utils.UDPPacket(srcAddr.String(), packet)) writer.Write(utils.UDPPacket(srcAddr.String(), packet))
err = writer.Flush() err = writer.Flush()
if err != nil { if err != nil {
log.Printf("write udp packet to %s fail ,flush err:%s", *s.cfg.Parent, err) s.log.Printf("write udp packet to %s fail ,flush err:%s", *s.cfg.Parent, err)
return return
} }
//log.Printf("write packet %v", packet) //s.log.Printf("write packet %v", packet)
return return
} }
func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err error) { func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err error) {
//log.Printf("udp packet revecived:%s,%v", srcAddr, packet) //s.log.Printf("udp packet revecived:%s,%v", srcAddr, packet)
dstAddr, err := net.ResolveUDPAddr("udp", *s.cfg.Parent) dstAddr, err := net.ResolveUDPAddr("udp", *s.cfg.Parent)
if err != nil { if err != nil {
log.Printf("resolve udp addr %s fail fail,ERR:%s", dstAddr.String(), err) s.log.Printf("resolve udp addr %s fail fail,ERR:%s", dstAddr.String(), err)
return return
} }
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0} clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr) conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
if err != nil { if err != nil {
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(packet) _, err = conn.Write(packet)
if err != nil { if err != nil {
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err) s.log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
return return
} }
//log.Printf("send udp packet to %s success", dstAddr.String()) //s.log.Printf("send udp packet to %s success", dstAddr.String())
buf := make([]byte, 512) buf := make([]byte, 512)
len, _, err := conn.ReadFromUDP(buf) len, _, err := conn.ReadFromUDP(buf)
if err != nil { if err != nil {
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err) s.log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
return return
} }
//log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody) //s.log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
_, err = s.sc.UDPListener.WriteToUDP(buf[0:len], srcAddr) _, err = s.sc.UDPListener.WriteToUDP(buf[0:len], srcAddr)
if err != nil { if err != nil {
log.Printf("send udp response to cluster fail ,ERR:%s", err) s.log.Printf("send udp response to cluster fail ,ERR:%s", err)
return return
} }
//log.Printf("send udp response to cluster success ,from:%s", dstAddr.String()) //s.log.Printf("send udp response to cluster success ,from:%s", dstAddr.String())
return return
} }
func (s *UDP) InitOutConnPool() { func (s *UDP) InitOutConnPool() {