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"
"crypto/sha1"
"fmt"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
"log"
logger "log"
"os"
"os/exec"
"time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2"
@ -297,11 +298,13 @@ func initConfig() (err error) {
muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs
flags := log.Ldate
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
flags := logger.Ldate
if *debug {
flags |= log.Lshortfile | log.Lmicroseconds
flags |= logger.Lshortfile | logger.Lmicroseconds
} else {
flags |= log.Ltime
flags |= logger.Ltime
}
log.SetFlags(flags)
@ -383,18 +386,18 @@ func initConfig() (err error) {
poster()
}
//regist services and run service
services.Regist("http", services.NewHTTP(), httpArgs)
services.Regist("tcp", services.NewTCP(), tcpArgs)
services.Regist("udp", services.NewUDP(), udpArgs)
services.Regist("tserver", services.NewTunnelServerManager(), tunnelServerArgs)
services.Regist("tclient", services.NewTunnelClient(), tunnelClientArgs)
services.Regist("tbridge", services.NewTunnelBridge(), tunnelBridgeArgs)
services.Regist("server", services.NewMuxServerManager(), muxServerArgs)
services.Regist("client", services.NewMuxClient(), muxClientArgs)
services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs)
services.Regist("socks", services.NewSocks(), socksArgs)
services.Regist("sps", services.NewSPS(), spsArgs)
service, err = services.Run(serviceName)
services.Regist("http", services.NewHTTP(), httpArgs, log)
services.Regist("tcp", services.NewTCP(), tcpArgs, log)
services.Regist("udp", services.NewUDP(), udpArgs, log)
services.Regist("tserver", services.NewTunnelServerManager(), tunnelServerArgs, log)
services.Regist("tclient", services.NewTunnelClient(), tunnelClientArgs, log)
services.Regist("tbridge", services.NewTunnelBridge(), tunnelBridgeArgs, log)
services.Regist("server", services.NewMuxServerManager(), muxServerArgs, log)
services.Regist("client", services.NewMuxClient(), muxClientArgs, log)
services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs, log)
services.Regist("socks", services.NewSocks(), socksArgs, log)
services.Regist("sps", services.NewSPS(), spsArgs, log)
service, err = services.Run(serviceName, nil)
if err != nil {
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
VER="v4.7"
VER="v4.8"
rm -rf sdk-android-*.tar.gz
rm -rf android
mkdir android

View File

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

View File

@ -3,17 +3,20 @@ package proxy
import (
"crypto/sha1"
"fmt"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"log"
logger "log"
"os"
"strings"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
const SDK_VERSION = "4.8"
var (
app *kingpin.Application
)
@ -43,7 +46,7 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
kcpArgs := kcpcfg.KCPConfigArgs{}
//build srvice args
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()
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()
@ -298,11 +301,12 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs
flags := log.Ldate
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
flags := logger.Ldate
if *debug {
flags |= log.Lshortfile | log.Lmicroseconds
flags |= logger.Lshortfile | logger.Lmicroseconds
} else {
flags |= log.Ltime
flags |= logger.Ltime
}
log.SetFlags(flags)
@ -317,29 +321,29 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
//regist services and run service
switch serviceName {
case "http":
services.Regist(serviceID, services.NewHTTP(), httpArgs)
services.Regist(serviceID, services.NewHTTP(), httpArgs, log)
case "tcp":
services.Regist(serviceID, services.NewTCP(), tcpArgs)
services.Regist(serviceID, services.NewTCP(), tcpArgs, log)
case "udp":
services.Regist(serviceID, services.NewUDP(), udpArgs)
services.Regist(serviceID, services.NewUDP(), udpArgs, log)
case "tserver":
services.Regist(serviceID, services.NewTunnelServerManager(), tunnelServerArgs)
services.Regist(serviceID, services.NewTunnelServerManager(), tunnelServerArgs, log)
case "tclient":
services.Regist(serviceID, services.NewTunnelClient(), tunnelClientArgs)
services.Regist(serviceID, services.NewTunnelClient(), tunnelClientArgs, log)
case "tbridge":
services.Regist(serviceID, services.NewTunnelBridge(), tunnelBridgeArgs)
services.Regist(serviceID, services.NewTunnelBridge(), tunnelBridgeArgs, log)
case "server":
services.Regist(serviceID, services.NewMuxServerManager(), muxServerArgs)
services.Regist(serviceID, services.NewMuxServerManager(), muxServerArgs, log)
case "client":
services.Regist(serviceID, services.NewMuxClient(), muxClientArgs)
services.Regist(serviceID, services.NewMuxClient(), muxClientArgs, log)
case "bridge":
services.Regist(serviceID, services.NewMuxBridge(), muxBridgeArgs)
services.Regist(serviceID, services.NewMuxBridge(), muxBridgeArgs, log)
case "socks":
services.Regist(serviceID, services.NewSocks(), socksArgs)
services.Regist(serviceID, services.NewSocks(), socksArgs, log)
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 {
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) {
services.Stop(serviceID)
}
func Version() string {
return SDK_VERSION
}

View File

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

View File

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

View File

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

View File

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

View File

@ -2,17 +2,18 @@ package services
import (
"fmt"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"io"
"io/ioutil"
"log"
logger "log"
"net"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"golang.org/x/crypto/ssh"
)
@ -27,6 +28,7 @@ type HTTP struct {
isStop bool
serverChannels []*utils.ServerChannel
userConns utils.ConcurrentMap
log *logger.Logger
}
func NewHTTP() Service {
@ -125,7 +127,7 @@ func (s *HTTP) InitService() (err error) {
s.sshClient.Conn.Close()
}
}
log.Printf("ssh offline, retrying...")
s.log.Printf("ssh offline, retrying...")
s.ConnectSSH()
} else {
conn.Close()
@ -140,9 +142,9 @@ func (s *HTTP) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop http(s) service crashed,%s", e)
s.log.Printf("stop http(s) service crashed,%s", e)
} else {
log.Printf("service http(s) stoped")
s.log.Printf("service http(s) stoped")
}
}()
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)
if err = s.CheckArgs(); err != nil {
return
}
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()
}
if err = s.InitService(); err != nil {
@ -186,7 +189,7 @@ func (s *HTTP) Start(args interface{}) (err error) {
if err != nil {
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)
}
}
@ -199,7 +202,7 @@ func (s *HTTP) Clean() {
func (s *HTTP) callback(inConn net.Conn) {
defer func() {
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 {
@ -215,7 +218,7 @@ func (s *HTTP) callback(inConn net.Conn) {
req, err = utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth)
if err != nil {
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)
return
@ -234,18 +237,18 @@ func (s *HTTP) callback(inConn net.Conn) {
s.checker.Add(k)
//var n, m uint
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)
if err != nil {
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 {
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)
}
@ -270,7 +273,7 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
if *s.cfg.ParentType == "ssh" {
outConn, err = s.getSSHConn(address)
} else {
// log.Printf("%v", s.outPool)
// s.log.Printf("%v", s.outPool)
outConn, err = s.outPool.Get()
}
} else {
@ -280,12 +283,12 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
if err == nil || tryCount > maxTryCount {
break
} 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)
}
}
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)
return
}
@ -309,17 +312,17 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
_, err = outConn.Write(req.HeadBuf)
outConn.SetDeadline(time.Time{})
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)
return
}
}
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)
})
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 {
(*c.(*net.Conn)).Close()
}
@ -350,7 +353,7 @@ RETRY:
err = fmt.Errorf("ssh dial %s timeout", host)
}
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()
if e == nil {
tryCount++
@ -406,7 +409,7 @@ func (s *HTTP) InitBasicAuth() (err error) {
}
if *s.cfg.AuthURL != "" {
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 != "" {
var n = 0
@ -415,11 +418,11 @@ func (s *HTTP) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err)
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 {
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
}
@ -471,7 +474,7 @@ func (s *HTTP) Resolve(address string) string {
}
ip, err := s.domainResolver.Resolve(address)
if err != nil {
log.Printf("dns error %s , ERR:%s", address, err)
s.log.Printf("dns error %s , ERR:%s", address, err)
}
return ip
}

View File

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

View File

@ -3,12 +3,13 @@ package services
import (
"crypto/tls"
"fmt"
"github.com/snail007/goproxy/utils"
"io"
"log"
logger "log"
"net"
"time"
"github.com/snail007/goproxy/utils"
"github.com/golang/snappy"
"github.com/xtaci/smux"
)
@ -17,6 +18,7 @@ type MuxClient struct {
cfg MuxClientArgs
isStop bool
sessions utils.ConcurrentMap
log *logger.Logger
}
func NewMuxClient() Service {
@ -33,7 +35,7 @@ func (s *MuxClient) InitService() (err error) {
func (s *MuxClient) CheckArgs() (err error) {
if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent)
s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else {
err = fmt.Errorf("parent required")
return
@ -54,9 +56,9 @@ func (s *MuxClient) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop client service crashed,%s", e)
s.log.Printf("stop client service crashed,%s", e)
} else {
log.Printf("service client stoped")
s.log.Printf("service client stoped")
}
}()
s.isStop = true
@ -64,7 +66,8 @@ func (s *MuxClient) StopService() {
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)
if err = s.CheckArgs(); err != nil {
return
@ -72,19 +75,19 @@ func (s *MuxClient) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil {
return
}
log.Printf("client started")
s.log.Printf("client started")
count := 1
if *s.cfg.SessionCount > 0 {
count = *s.cfg.SessionCount
}
for i := 1; i <= count; i++ {
key := fmt.Sprintf("worker[%d]", i)
log.Printf("session %s started", key)
s.log.Printf("session %s started", key)
go func(i int) {
defer func() {
e := recover()
if e != nil {
log.Printf("session worker crashed: %s", e)
s.log.Printf("session worker crashed: %s", e)
}
}()
for {
@ -93,7 +96,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
}
conn, err := s.getParentConn()
if err != nil {
log.Printf("connection err: %s, retrying...", err)
s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3)
continue
}
@ -102,13 +105,13 @@ func (s *MuxClient) Start(args interface{}) (err error) {
conn.SetDeadline(time.Time{})
if err != nil {
conn.Close()
log.Printf("connection err: %s, retrying...", err)
s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3)
continue
}
session, err := smux.Server(conn, nil)
if err != nil {
log.Printf("session err: %s, retrying...", err)
s.log.Printf("session err: %s, retrying...", err)
conn.Close()
time.Sleep(time.Second * 3)
continue
@ -123,7 +126,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
}
stream, err := session.AcceptStream()
if err != nil {
log.Printf("accept stream err: %s, retrying...", err)
s.log.Printf("accept stream err: %s, retrying...", err)
session.Close()
time.Sleep(time.Second * 3)
break
@ -132,7 +135,7 @@ func (s *MuxClient) Start(args interface{}) (err error) {
defer func() {
e := recover()
if e != nil {
log.Printf("stream handler crashed: %s", e)
s.log.Printf("stream handler crashed: %s", e)
}
}()
var ID, clientLocalAddr, serverID string
@ -140,11 +143,11 @@ func (s *MuxClient) Start(args interface{}) (err error) {
err = utils.ReadPacketData(stream, &ID, &clientLocalAddr, &serverID)
stream.SetDeadline(time.Time{})
if err != nil {
log.Printf("read stream signal err: %s", err)
s.log.Printf("read stream signal err: %s", err)
stream.Close()
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]
localAddr := clientLocalAddr[4:]
if protocol == "udp" {
@ -186,16 +189,16 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
srcAddr, body, err := utils.ReadUDPPacket(inConn)
inConn.SetDeadline(time.Time{})
if err != nil {
log.Printf("udp packet revecived fail, err: %s", err)
log.Printf("connection %s released", ID)
s.log.Printf("udp packet revecived fail, err: %s", err)
s.log.Printf("connection %s released", ID)
inConn.Close()
break
} else {
//log.Printf("udp packet revecived:%s,%v", srcAddr, body)
//s.log.Printf("udp packet revecived:%s,%v", srcAddr, body)
go func() {
defer func() {
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)
@ -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) {
dstAddr, err := net.ResolveUDPAddr("udp", localAddr)
if err != nil {
log.Printf("can't resolve address: %s", err)
s.log.Printf("can't resolve address: %s", err)
inConn.Close()
return
}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
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
}
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(body)
conn.SetDeadline(time.Time{})
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
}
//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)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{})
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
}
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)
(*inConn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = (*inConn).Write(bs)
(*inConn).SetDeadline(time.Time{})
if err != nil {
log.Printf("send udp response fail ,ERR:%s", err)
s.log.Printf("send udp response fail ,ERR:%s", err)
inConn.Close()
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) {
var err error
@ -262,7 +265,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
break
} else {
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)
continue
}
@ -271,11 +274,11 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
if err != nil {
inConn.Close()
utils.CloseConn(&outConn)
log.Printf("build connection error, err: %s", err)
s.log.Printf("build connection error, err: %s", err)
return
}
log.Printf("stream %s created", ID)
s.log.Printf("stream %s created", ID)
if *s.cfg.IsCompress {
die1 := 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()
inConn.Close()
log.Printf("%s stream %s released", *s.cfg.Key, ID)
s.log.Printf("%s stream %s released", *s.cfg.Key, ID)
} else {
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 (
"crypto/tls"
"fmt"
"github.com/snail007/goproxy/utils"
"io"
"log"
logger "log"
"math/rand"
"net"
"runtime/debug"
@ -13,6 +12,8 @@ import (
"strings"
"time"
"github.com/snail007/goproxy/utils"
"github.com/golang/snappy"
"github.com/xtaci/smux"
)
@ -25,6 +26,7 @@ type MuxServer struct {
lockChn chan bool
isStop bool
udpConn *net.Conn
log *logger.Logger
}
type MuxServerManager struct {
@ -32,6 +34,7 @@ type MuxServerManager struct {
udpChn chan MuxUDPItem
serverID string
servers []*Service
log *logger.Logger
}
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)
if err = s.CheckArgs(); err != nil {
return
}
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 {
err = fmt.Errorf("parent required")
return
@ -59,8 +63,8 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
return
}
log.Printf("server id: %s", s.serverID)
//log.Printf("route:%v", *s.cfg.Route)
s.log.Printf("server id: %s", s.serverID)
//s.log.Printf("route:%v", *s.cfg.Route)
for _, _info := range *s.cfg.Route {
if _info == "" {
continue
@ -73,6 +77,7 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
info = strings.TrimPrefix(info, "tcp://")
_routeInfo := strings.Split(info, "@")
server := NewMuxServer()
local := _routeInfo[0]
remote := _routeInfo[1]
KEY := *s.cfg.Key
@ -99,7 +104,7 @@ func (s *MuxServerManager) Start(args interface{}) (err error) {
SessionCount: s.cfg.SessionCount,
KCP: s.cfg.KCP,
ParentType: s.cfg.ParentType,
})
}, log)
if err != nil {
return
@ -153,9 +158,9 @@ func (s *MuxServer) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop server service crashed,%s", e)
s.log.Printf("stop server service crashed,%s", e)
} else {
log.Printf("service server stoped")
s.log.Printf("service server stoped")
}
}()
s.isStop = true
@ -184,7 +189,8 @@ func (s *MuxServer) CheckArgs() (err error) {
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)
if err = s.CheckArgs(); err != nil {
return
@ -206,12 +212,12 @@ func (s *MuxServer) Start(args interface{}) (err error) {
if err != nil {
return
}
log.Printf("server on %s", (*s.sc.UDPListener).LocalAddr())
s.log.Printf("server on %s", (*s.sc.UDPListener).LocalAddr())
} else {
err = s.sc.ListenTCP(func(inConn net.Conn) {
defer func() {
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
@ -223,14 +229,14 @@ func (s *MuxServer) Start(args interface{}) (err error) {
outConn, ID, err = s.GetOutConn()
if err != nil {
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)
continue
} else {
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 {
die1 := make(chan bool, 1)
die2 := make(chan bool, 1)
@ -248,17 +254,17 @@ func (s *MuxServer) Start(args interface{}) (err error) {
}
outConn.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 {
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 {
return
}
log.Printf("server on %s", (*s.sc.Listener).Addr())
s.log.Printf("server on %s", (*s.sc.Listener).Addr())
}
return
}
@ -272,7 +278,7 @@ func (s *MuxServer) GetOutConn() (outConn net.Conn, ID string, err error) {
}
outConn, err = s.GetConn(fmt.Sprintf("%d", i))
if err != nil {
log.Printf("connection err: %s", err)
s.log.Printf("connection err: %s", err)
return
}
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))
outConn.SetDeadline(time.Time{})
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)
return
}
@ -325,7 +331,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
_sess.(*smux.Session).Close()
}
s.sessions.Set(index, session)
log.Printf("session[%s] created", index)
s.log.Printf("session[%s] created", index)
go func() {
for {
if s.isStop {
@ -366,7 +372,7 @@ func (s *MuxServer) UDPConnDeamon() {
go func() {
defer func() {
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
@ -390,7 +396,7 @@ func (s *MuxServer) UDPConnDeamon() {
if err != nil {
outConn = nil
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)
continue
} else {
@ -407,14 +413,14 @@ func (s *MuxServer) UDPConnDeamon() {
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
outConn.SetDeadline(time.Time{})
if err != nil {
log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
log.Printf("UDP deamon connection %s exited", ID)
s.log.Printf("parse revecived udp packet fail, err: %s ,%v", err, body)
s.log.Printf("UDP deamon connection %s exited", ID)
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, ":")
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
}
port, _ := strconv.Atoi(_srcAddr[1])
@ -423,10 +429,10 @@ func (s *MuxServer) UDPConnDeamon() {
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
s.sc.UDPListener.SetDeadline(time.Time{})
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
}
//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)
break
@ -439,10 +445,10 @@ func (s *MuxServer) UDPConnDeamon() {
if err != nil {
utils.CloseConn(&outConn)
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
}
//log.Printf("write packet %v", *item.packet)
//s.log.Printf("write packet %v", *item.packet)
}
}()
}

View File

@ -2,27 +2,30 @@ package services
import (
"fmt"
logger "log"
"runtime/debug"
)
type Service interface {
Start(args interface{}) (err error)
Start(args interface{}, log *logger.Logger) (err error)
Clean()
}
type ServiceItem struct {
S Service
Args interface{}
Name string
Log *logger.Logger
}
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)
servicesMap[name] = &ServiceItem{
S: s,
Args: args,
Name: name,
Log: log,
}
}
func GetService(name string) *ServiceItem {
@ -37,7 +40,7 @@ func Stop(name string) {
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]
if ok {
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()))
}
}()
if len(args) == 1 {
err = service.S.Start(args[0])
if args != nil {
err = service.S.Start(args, service.Log)
} else {
err = service.S.Start(service.Args)
err = service.S.Start(service.Args, service.Log)
}
if err != nil {
err = fmt.Errorf("%s servcie fail, ERR: %s", name, err)

View File

@ -3,17 +3,18 @@ package services
import (
"crypto/tls"
"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"
"log"
logger "log"
"net"
"runtime/debug"
"strings"
"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"
)
@ -28,6 +29,7 @@ type Socks struct {
domainResolver utils.DomainResolver
isStop bool
userConns utils.ConcurrentMap
log *logger.Logger
}
func NewSocks() Service {
@ -133,7 +135,7 @@ func (s *Socks) InitService() (err error) {
if s.sshClient != nil {
s.sshClient.Close()
}
log.Printf("ssh offline, retrying...")
s.log.Printf("ssh offline, retrying...")
s.ConnectSSH()
} else {
conn.Close()
@ -143,7 +145,7 @@ func (s *Socks) InitService() (err error) {
}()
}
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 {
s.udpSC = utils.NewServerChannelHost(*s.cfg.UDPLocal)
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)
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
}
@ -159,9 +161,9 @@ func (s *Socks) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop socks service crashed,%s", e)
s.log.Printf("stop socks service crashed,%s", e)
} else {
log.Printf("service socks stoped")
s.log.Printf("service socks stoped")
}
}()
s.isStop = true
@ -179,7 +181,8 @@ func (s *Socks) StopService() {
(*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()
s.cfg = args.(SocksArgs)
if err = s.CheckArgs(); err != nil {
@ -189,10 +192,10 @@ func (s *Socks) Start(args interface{}) (err error) {
s.InitService()
}
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 != "" {
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)
if *s.cfg.LocalType == TYPE_TCP {
@ -206,7 +209,7 @@ func (s *Socks) Start(args interface{}) (err error) {
return
}
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
}
func (s *Socks) Clean() {
@ -222,29 +225,29 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
//decode b
rawB, err = goaes.Decrypt(s.UDPKey(), b)
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
}
}
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 {
log.Printf("parse udp packet fail, ERR:%s", err)
s.log.Printf("parse udp packet fail, ERR:%s", err)
return
}
//防止死循环
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
}
//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.ParentType == "tls" {
//encode b
rawB, err = goaes.Encrypt(s.UDPKey(), rawB)
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
}
}
@ -254,43 +257,43 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
}
dstAddr, err := net.ResolveUDPAddr("udp", s.Resolve(parent))
if err != nil {
log.Printf("can't resolve address: %s", err)
s.log.Printf("can't resolve address: %s", err)
return
}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
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
}
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*5)))
_, err = conn.Write(rawB)
conn.SetDeadline(time.Time{})
log.Printf("udp request:%v", len(rawB))
s.log.Printf("udp request:%v", len(rawB))
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()
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)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{})
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()
return
}
respBody := buf[0:length]
log.Printf("udp response:%v", len(respBody))
//log.Printf("revecived udp packet from %s", dstAddr.String())
s.log.Printf("udp response:%v", len(respBody))
//s.log.Printf("revecived udp packet from %s", dstAddr.String())
if *s.cfg.ParentType == "tls" {
//decode b
respBody, err = goaes.Decrypt(s.UDPKey(), respBody)
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()
return
}
@ -298,62 +301,62 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
if *s.cfg.LocalType == "tls" {
d, err := goaes.Encrypt(s.UDPKey(), respBody)
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()
return
}
s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
s.udpSC.UDPListener.SetDeadline(time.Time{})
log.Printf("udp reply:%v", len(d))
s.log.Printf("udp reply:%v", len(d))
} else {
s.udpSC.UDPListener.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
s.udpSC.UDPListener.WriteToUDP(respBody, srcAddr)
s.udpSC.UDPListener.SetDeadline(time.Time{})
log.Printf("udp reply:%v", len(respBody))
s.log.Printf("udp reply:%v", len(respBody))
}
} else {
//本地代理
dstAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(s.Resolve(p.Host()), p.Port()))
if err != nil {
log.Printf("can't resolve address: %s", err)
s.log.Printf("can't resolve address: %s", err)
return
}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
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
}
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*3)))
_, err = conn.Write(p.Data())
conn.SetDeadline(time.Time{})
log.Printf("udp send:%v", len(p.Data()))
s.log.Printf("udp send:%v", len(p.Data()))
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()
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)
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
length, _, err := conn.ReadFromUDP(buf)
conn.SetDeadline(time.Time{})
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()
return
}
respBody := buf[0:length]
//封装来自真实服务器的数据,返回给访问者
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" {
d, err := goaes.Encrypt(s.UDPKey(), respPacket)
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()
return
}
@ -365,14 +368,14 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
s.udpSC.UDPListener.WriteToUDP(respPacket, srcAddr)
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) {
defer func() {
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()
}
}()
@ -393,7 +396,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
if err != nil {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn)
log.Printf("new methods request fail,ERR: %s", err)
s.log.Printf("new methods request fail,ERR: %s", err)
return
}
@ -401,29 +404,29 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
if !methodReq.Select(socks.Method_NO_AUTH) {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn)
log.Printf("none method found : Method_NO_AUTH")
s.log.Printf("none method found : Method_NO_AUTH")
return
}
//method select reply
err = methodReq.Reply(socks.Method_NO_AUTH)
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)
return
}
// log.Printf("% x", methodReq.Bytes())
// s.log.Printf("% x", methodReq.Bytes())
} else {
//auth
if !methodReq.Select(socks.Method_USER_PASS) {
methodReq.Reply(socks.Method_NONE_ACCEPTABLE)
utils.CloseConn(&inConn)
log.Printf("none method found : Method_USER_PASS")
s.log.Printf("none method found : Method_USER_PASS")
return
}
//method reply need auth
err = methodReq.Reply(socks.Method_USER_PASS)
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)
return
}
@ -439,7 +442,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
r := buf[:n]
user := string(r[2 : r[1]+2])
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
_addr := strings.Split(inConn.RemoteAddr().String(), ":")
if s.basicAuth.CheckUserPass(user, pass, _addr[0], "") {
@ -460,7 +463,7 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
//request detail
request, err := socks.NewRequest(inConn)
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)
return
}
@ -488,7 +491,7 @@ func (s *Socks) proxyUDP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
}
host, _, _ := net.SplitHostPort((*inConn).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))
}
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()) {
utils.CloseConn(inConn)
log.Printf("dead loop detected , %s", request.Host())
s.log.Printf("dead loop detected , %s", request.Host())
utils.CloseConn(inConn)
return
}
@ -535,25 +538,25 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
if err == nil || tryCount > maxTryCount || *s.cfg.Parent == "" {
break
} 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)
}
}
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)
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)
inAddr := (*inConn).RemoteAddr().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{}) {
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 {
(*c.(*net.Conn)).Close()
@ -606,7 +609,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
return
}
//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)))
_, err = outConn.Write(reqBytes)
outConn.SetDeadline(time.Time{})
@ -622,7 +625,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
return
}
//result := buf[:n]
//log.Printf("result:%v", result)
//s.log.Printf("result:%v", result)
case "ssh":
maxTryCount := 1
@ -648,7 +651,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
s.sshClient.Close()
}
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()
if e == nil {
tryCount++
@ -692,7 +695,7 @@ func (s *Socks) InitBasicAuth() (err error) {
}
if *s.cfg.AuthURL != "" {
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 != "" {
var n = 0
@ -701,11 +704,11 @@ func (s *Socks) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err)
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 {
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
}
@ -757,7 +760,7 @@ func (s *Socks) Resolve(address string) string {
}
ip, err := s.domainResolver.Resolve(address)
if err != nil {
log.Printf("dns error %s , ERR:%s", address, err)
s.log.Printf("dns error %s , ERR:%s", address, err)
}
return ip
}

View File

@ -5,16 +5,17 @@ import (
"encoding/base64"
"errors"
"fmt"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/socks"
"github.com/snail007/goproxy/utils/conncrypt"
"io/ioutil"
"log"
logger "log"
"net"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/socks"
)
type SPS struct {
@ -24,6 +25,7 @@ type SPS struct {
basicAuth utils.BasicAuth
serverChannels []*utils.ServerChannel
userConns utils.ConcurrentMap
log *logger.Logger
}
func NewSPS() Service {
@ -86,9 +88,9 @@ func (s *SPS) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop sps service crashed,%s", e)
s.log.Printf("stop sps service crashed,%s", e)
} else {
log.Printf("service sps stoped")
s.log.Printf("service sps stoped")
}
}()
for _, sc := range s.serverChannels {
@ -103,7 +105,8 @@ func (s *SPS) StopService() {
(*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)
if err = s.CheckArgs(); err != nil {
return
@ -111,7 +114,7 @@ func (s *SPS) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil {
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, ",") {
if addr != "" {
host, port, _ := net.SplitHostPort(*s.cfg.Local)
@ -127,7 +130,7 @@ func (s *SPS) Start(args interface{}) (err error) {
if err != nil {
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)
}
}
@ -140,7 +143,7 @@ func (s *SPS) Clean() {
func (s *SPS) callback(inConn net.Conn) {
defer func() {
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 {
@ -163,7 +166,7 @@ func (s *SPS) callback(inConn net.Conn) {
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
}
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)
}
}
@ -172,7 +175,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
n, err := (*inConn).Read(buf)
header := buf[:n]
if err != nil {
log.Printf("ERR:%s", err)
s.log.Printf("ERR:%s", err)
utils.CloseConn(inConn)
return
}
@ -204,14 +207,14 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
}
(*inConn).SetDeadline(time.Time{})
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)
return
}
if len(header) >= 7 && strings.ToLower(string(header[:7])) == "connect" {
//https
request.HTTPSReply()
//log.Printf("https reply: %s", request.Host)
//s.log.Printf("https reply: %s", request.Host)
} else {
forwardBytes = request.HeadBuf
}
@ -228,7 +231,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
}
}
} 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)
err = errors.New("unknown request")
return
@ -237,7 +240,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
var outConn net.Conn
outConn, err = s.outPool.Get()
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)
return
}
@ -276,7 +279,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
_, err = outConn.Write(pb.Bytes())
outConn.SetDeadline(time.Time{})
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(&outConn)
return
@ -286,14 +289,14 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
_, err = outConn.Read(reply)
outConn.SetDeadline(time.Time{})
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(&outConn)
return
}
//log.Printf("reply: %s", string(reply[:n]))
//s.log.Printf("reply: %s", string(reply[:n]))
} else {
log.Printf("connect %s", address)
s.log.Printf("connect %s", address)
//socks client
var clientConn *socks.ClientConn
if *s.cfg.ParentAuth != "" {
@ -322,10 +325,10 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
inAddr := (*inConn).RemoteAddr().String()
outAddr := outConn.RemoteAddr().String()
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)
})
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 {
(*c.(*net.Conn)).Close()
}
@ -340,7 +343,7 @@ func (s *SPS) InitBasicAuth() (err error) {
}
if *s.cfg.AuthURL != "" {
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 != "" {
var n = 0
@ -349,11 +352,11 @@ func (s *SPS) InitBasicAuth() (err error) {
err = fmt.Errorf("auth-file ERR:%s", err)
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 {
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
}
@ -404,7 +407,7 @@ func (s *SPS) Resolve(address string) string {
}
ip, err := s.domainResolver.Resolve(address)
if err != nil {
log.Printf("dns error %s , ERR:%s", address, err)
s.log.Printf("dns error %s , ERR:%s", address, err)
}
return ip
}

View File

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

View File

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

View File

@ -3,12 +3,13 @@ package services
import (
"crypto/tls"
"fmt"
"github.com/snail007/goproxy/utils"
"io"
"log"
logger "log"
"net"
"time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux"
)
@ -17,6 +18,7 @@ type TunnelClient struct {
ctrlConn net.Conn
isStop bool
userConns utils.ConcurrentMap
log *logger.Logger
}
func NewTunnelClient() Service {
@ -33,7 +35,7 @@ func (s *TunnelClient) InitService() (err error) {
func (s *TunnelClient) CheckArgs() (err error) {
if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent)
s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else {
err = fmt.Errorf("parent required")
return
@ -49,9 +51,9 @@ func (s *TunnelClient) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop tclient service crashed,%s", e)
s.log.Printf("stop tclient service crashed,%s", e)
} else {
log.Printf("service tclient stoped")
s.log.Printf("service tclient stoped")
}
}()
s.isStop = true
@ -62,7 +64,8 @@ func (s *TunnelClient) StopService() {
(*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)
if err = s.CheckArgs(); err != nil {
return
@ -70,7 +73,7 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
if err = s.InitService(); err != nil {
return
}
log.Printf("proxy on tunnel client mode")
s.log.Printf("proxy on tunnel client mode")
for {
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)
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)
if s.ctrlConn != nil {
s.ctrlConn.Close()
@ -99,10 +102,10 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
if s.ctrlConn != nil {
s.ctrlConn.Close()
}
log.Printf("read connection signal err: %s, retrying...", err)
s.log.Printf("read connection signal err: %s, retrying...", err)
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]
localAddr := clientLocalAddr[4:]
if protocol == "udp" {
@ -142,13 +145,13 @@ func (s *TunnelClient) GetConn() (conn net.Conn, err error) {
MaxReceiveBuffer: 4194304,
})
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
return
}
conn, e = c.OpenStream()
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
return
}
@ -170,7 +173,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
if err != nil {
utils.CloseConn(&inConn)
log.Printf("connection err: %s, retrying...", err)
s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3)
continue
} else {
@ -178,7 +181,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
}
}
// s.cm.Add(*s.cfg.Key, ID, &inConn)
log.Printf("conn %s created", ID)
s.log.Printf("conn %s created", ID)
for {
if s.isStop {
@ -186,13 +189,13 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
}
srcAddr, body, err := utils.ReadUDPPacket(inConn)
if err == io.EOF || err == io.ErrUnexpectedEOF {
log.Printf("connection %s released", ID)
s.log.Printf("connection %s released", ID)
utils.CloseConn(&inConn)
break
} else if err != nil {
log.Printf("udp packet revecived fail, err: %s", err)
s.log.Printf("udp packet revecived fail, err: %s", err)
} 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)
}
@ -202,39 +205,39 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
func (s *TunnelClient) processUDPPacket(inConn *net.Conn, srcAddr, localAddr string, body []byte) {
dstAddr, err := net.ResolveUDPAddr("udp", localAddr)
if err != nil {
log.Printf("can't resolve address: %s", err)
s.log.Printf("can't resolve address: %s", err)
utils.CloseConn(inConn)
return
}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
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
}
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(body)
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
}
//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)
length, _, err := conn.ReadFromUDP(buf)
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
}
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)
_, err = (*inConn).Write(bs)
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)
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) {
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)
if err != nil {
utils.CloseConn(&inConn)
log.Printf("connection err: %s, retrying...", err)
s.log.Printf("connection err: %s, retrying...", err)
time.Sleep(time.Second * 3)
continue
} else {
@ -265,7 +268,7 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
break
} else {
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)
continue
}
@ -274,17 +277,17 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
if err != nil {
utils.CloseConn(&inConn)
utils.CloseConn(&outConn)
log.Printf("build connection error, err: %s", err)
s.log.Printf("build connection error, err: %s", err)
return
}
inAddr := inConn.RemoteAddr().String()
utils.IoBind(inConn, outConn, func(err interface{}) {
log.Printf("conn %s released", ID)
s.log.Printf("conn %s released", ID)
s.userConns.Remove(inAddr)
})
if c, ok := s.userConns.Get(inAddr); ok {
(*c.(*net.Conn)).Close()
}
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 (
"crypto/tls"
"fmt"
"github.com/snail007/goproxy/utils"
"io"
"log"
logger "log"
"net"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/snail007/goproxy/utils"
"github.com/xtaci/smux"
)
@ -22,6 +23,7 @@ type TunnelServer struct {
isStop bool
udpConn *net.Conn
userConns utils.ConcurrentMap
log *logger.Logger
}
type TunnelServerManager struct {
@ -29,6 +31,7 @@ type TunnelServerManager struct {
udpChn chan UDPItem
serverID string
servers []*Service
log *logger.Logger
}
func NewTunnelServerManager() Service {
@ -39,13 +42,14 @@ func NewTunnelServerManager() 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)
if err = s.CheckArgs(); err != nil {
return
}
if *s.cfg.Parent != "" {
log.Printf("use tls parent %s", *s.cfg.Parent)
s.log.Printf("use tls parent %s", *s.cfg.Parent)
} else {
err = fmt.Errorf("parent required")
return
@ -55,8 +59,8 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
return
}
log.Printf("server id: %s", s.serverID)
//log.Printf("route:%v", *s.cfg.Route)
s.log.Printf("server id: %s", s.serverID)
//s.log.Printf("route:%v", *s.cfg.Route)
for _, _info := range *s.cfg.Route {
IsUDP := *s.cfg.IsUDP
if strings.HasPrefix(_info, "udp://") {
@ -88,7 +92,7 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
Key: &KEY,
Timeout: s.cfg.Timeout,
Mgr: s,
})
}, log)
if err != nil {
return
@ -120,13 +124,13 @@ func (s *TunnelServerManager) InitService() (err error) {
func (s *TunnelServerManager) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) {
outConn, err = s.GetConn()
if err != nil {
log.Printf("connection err: %s", err)
s.log.Printf("connection err: %s", err)
return
}
ID = s.serverID
_, err = outConn.Write(utils.BuildPacket(typ, s.serverID))
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)
return
}
@ -159,9 +163,9 @@ func (s *TunnelServer) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop server service crashed,%s", e)
s.log.Printf("stop server service crashed,%s", e)
} else {
log.Printf("service server stoped")
s.log.Printf("service server stoped")
}
}()
s.isStop = true
@ -191,7 +195,8 @@ func (s *TunnelServer) CheckArgs() (err error) {
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)
if err = s.CheckArgs(); err != nil {
return
@ -213,12 +218,12 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
if err != nil {
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 {
err = s.sc.ListenTCP(func(inConn net.Conn) {
defer func() {
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
@ -230,7 +235,7 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
outConn, ID, err = s.GetOutConn(CONN_SERVER)
if err != nil {
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)
continue
} else {
@ -240,18 +245,18 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
inAddr := inConn.RemoteAddr().String()
utils.IoBind(inConn, outConn, func(err interface{}) {
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 {
(*c.(*net.Conn)).Close()
}
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 {
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
}
@ -261,7 +266,7 @@ func (s *TunnelServer) Clean() {
func (s *TunnelServer) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) {
outConn, err = s.GetConn()
if err != nil {
log.Printf("connection err: %s", err)
s.log.Printf("connection err: %s", err)
return
}
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()
_, err = outConn.Write(utils.BuildPacket(typ, *s.cfg.Key, ID, remoteAddr, s.cfg.Mgr.serverID))
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)
return
}
@ -289,13 +294,13 @@ func (s *TunnelServer) GetConn() (conn net.Conn, err error) {
MaxReceiveBuffer: 4194304,
})
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
return
}
conn, e = c.OpenStream()
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
return
}
@ -306,7 +311,7 @@ func (s *TunnelServer) UDPConnDeamon() {
go func() {
defer func() {
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
@ -333,7 +338,7 @@ func (s *TunnelServer) UDPConnDeamon() {
// cmdChn <- true
outConn = nil
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)
continue
} else {
@ -348,27 +353,27 @@ func (s *TunnelServer) UDPConnDeamon() {
}
srcAddrFromConn, body, err := utils.ReadUDPPacket(outConn)
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
}
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
}
//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, ":")
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
}
port, _ := strconv.Atoi(_srcAddr[1])
dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port}
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
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
}
//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)
break
@ -381,10 +386,10 @@ func (s *TunnelServer) UDPConnDeamon() {
if err != nil {
utils.CloseConn(&outConn)
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
}
//log.Printf("write packet %v", *item.packet)
//s.log.Printf("write packet %v", *item.packet)
}
}()
}

View File

@ -3,16 +3,17 @@ package services
import (
"bufio"
"fmt"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
"hash/crc32"
"io"
"log"
logger "log"
"net"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
)
type UDP struct {
@ -21,6 +22,7 @@ type UDP struct {
cfg UDPArgs
sc *utils.ServerChannel
isStop bool
log *logger.Logger
}
func NewUDP() Service {
@ -57,9 +59,9 @@ func (s *UDP) StopService() {
defer func() {
e := recover()
if e != nil {
log.Printf("stop udp service crashed,%s", e)
s.log.Printf("stop udp service crashed,%s", e)
} else {
log.Printf("service udp stoped")
s.log.Printf("service udp stoped")
}
}()
s.isStop = true
@ -70,12 +72,13 @@ func (s *UDP) StopService() {
(*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)
if err = s.CheckArgs(); err != nil {
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 {
return
}
@ -87,7 +90,7 @@ func (s *UDP) Start(args interface{}) (err error) {
if err != nil {
return
}
log.Printf("udp proxy on %s", (*sc.UDPListener).LocalAddr())
s.log.Printf("udp proxy on %s", (*sc.UDPListener).LocalAddr())
return
}
@ -97,7 +100,7 @@ func (s *UDP) Clean() {
func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) {
defer func() {
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
@ -112,7 +115,7 @@ func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) {
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
}
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) {
@ -140,17 +143,17 @@ func (s *UDP) OutToTCP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err erro
connKey := uint64((numLocal/10)*10 + numSrc%mod)
conn, isNew, err := s.GetConn(fmt.Sprintf("%d", connKey))
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
}
if isNew {
go func() {
defer func() {
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 {
if s.isStop {
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))
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))
break
}
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
}
//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, ":")
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
}
port, _ := strconv.Atoi(_srcAddr[1])
dstAddr := &net.UDPAddr{IP: net.ParseIP(_srcAddr[0]), Port: port}
_, err = s.sc.UDPListener.WriteToUDP(body, dstAddr)
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
}
//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)
//fmt.Println(conn, writer)
writer.Write(utils.UDPPacket(srcAddr.String(), packet))
err = writer.Flush()
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
}
//log.Printf("write packet %v", packet)
//s.log.Printf("write packet %v", packet)
return
}
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)
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
}
clientSrcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
conn, err := net.DialUDP("udp", clientSrcAddr, dstAddr)
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
}
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
_, err = conn.Write(packet)
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
}
//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)
len, _, err := conn.ReadFromUDP(buf)
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
}
//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)
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
}
//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
}
func (s *UDP) InitOutConnPool() {