优化错误捕获,防止意外crash
优化停止服务,释放内存
This commit is contained in:
@ -21,6 +21,7 @@ v6.0 enterprise version
|
|||||||
10.SOCKS5代理支持级联认证.
|
10.SOCKS5代理支持级联认证.
|
||||||
11.插件机制,定制功能可以使用插件方式开发了,热插拔,不需要修改goproxy二进制,可以插件so或者
|
11.插件机制,定制功能可以使用插件方式开发了,热插拔,不需要修改goproxy二进制,可以插件so或者
|
||||||
dylib注入.
|
dylib注入.
|
||||||
|
12.修复了tclient可能意外退出的bug.
|
||||||
|
|
||||||
v5.4
|
v5.4
|
||||||
1.优化了获取本地IP信息导致CPU过高的问题.
|
1.优化了获取本地IP信息导致CPU过高的问题.
|
||||||
|
|||||||
30
config.go
30
config.go
@ -10,6 +10,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime/debug"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ func initConfig() (err error) {
|
|||||||
//build srvice args
|
//build srvice args
|
||||||
app = kingpin.New("proxy", "happy with proxy")
|
app = kingpin.New("proxy", "happy with proxy")
|
||||||
app.Author("snail").Version("v" + APP_VERSION + " enterprise version")
|
app.Author("snail").Version("v" + APP_VERSION + " enterprise version")
|
||||||
debug := app.Flag("debug", "debug log output").Default("false").Bool()
|
isDebug := app.Flag("debug", "debug log output").Default("false").Bool()
|
||||||
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
||||||
forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool()
|
forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool()
|
||||||
logfile := app.Flag("log", "log file path").Default("").String()
|
logfile := app.Flag("log", "log file path").Default("").String()
|
||||||
@ -120,7 +121,7 @@ func initConfig() (err error) {
|
|||||||
httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||||
httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||||
httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
||||||
httpArgs.Debug = debug
|
httpArgs.Debug = isDebug
|
||||||
//########tcp#########
|
//########tcp#########
|
||||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||||
tcpArgs.Parent = tcp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("[]").Short('P').String()
|
tcpArgs.Parent = tcp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("[]").Short('P').String()
|
||||||
@ -243,7 +244,7 @@ func initConfig() (err error) {
|
|||||||
socksArgs.LoadBalanceOnlyHA = socks.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
socksArgs.LoadBalanceOnlyHA = socks.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||||
socksArgs.RateLimit = socks.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
socksArgs.RateLimit = socks.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||||
socksArgs.BindListen = socks.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
socksArgs.BindListen = socks.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
||||||
socksArgs.Debug = debug
|
socksArgs.Debug = isDebug
|
||||||
|
|
||||||
//########socks+http(s)#########
|
//########socks+http(s)#########
|
||||||
sps := app.Command("sps", "proxy on socks+http(s) mode")
|
sps := app.Command("sps", "proxy on socks+http(s) mode")
|
||||||
@ -283,7 +284,7 @@ func initConfig() (err error) {
|
|||||||
spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||||
spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||||
spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||||
spsArgs.Debug = debug
|
spsArgs.Debug = isDebug
|
||||||
|
|
||||||
//########dns#########
|
//########dns#########
|
||||||
dns := app.Command("dns", "proxy on dns server mode")
|
dns := app.Command("dns", "proxy on dns server mode")
|
||||||
@ -314,8 +315,6 @@ func initConfig() (err error) {
|
|||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
|
||||||
isDebug = *debug
|
|
||||||
|
|
||||||
//set kcp config
|
//set kcp config
|
||||||
|
|
||||||
switch *kcpArgs.Mode {
|
switch *kcpArgs.Mode {
|
||||||
@ -372,7 +371,7 @@ func initConfig() (err error) {
|
|||||||
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
|
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
|
||||||
|
|
||||||
flags := logger.Ldate
|
flags := logger.Ldate
|
||||||
if *debug {
|
if *isDebug {
|
||||||
flags |= logger.Lshortfile | logger.Lmicroseconds
|
flags |= logger.Lshortfile | logger.Lmicroseconds
|
||||||
cpuProfilingFile, _ = os.Create("cpu.prof")
|
cpuProfilingFile, _ = os.Create("cpu.prof")
|
||||||
memProfilingFile, _ = os.Create("memory.prof")
|
memProfilingFile, _ = os.Create("memory.prof")
|
||||||
@ -417,6 +416,11 @@ func initConfig() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
cmd.Process.Kill()
|
cmd.Process.Kill()
|
||||||
@ -436,11 +440,21 @@ func initConfig() (err error) {
|
|||||||
scanner := bufio.NewScanner(cmdReader)
|
scanner := bufio.NewScanner(cmdReader)
|
||||||
scannerStdErr := bufio.NewScanner(cmdReaderStderr)
|
scannerStdErr := bufio.NewScanner(cmdReaderStderr)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
fmt.Println(scanner.Text())
|
fmt.Println(scanner.Text())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for scannerStdErr.Scan() {
|
for scannerStdErr.Scan() {
|
||||||
fmt.Println(scannerStdErr.Text())
|
fmt.Println(scannerStdErr.Text())
|
||||||
}
|
}
|
||||||
@ -462,7 +476,7 @@ func initConfig() (err error) {
|
|||||||
}
|
}
|
||||||
if *logfile == "" {
|
if *logfile == "" {
|
||||||
poster()
|
poster()
|
||||||
if *debug {
|
if *isDebug {
|
||||||
log.Println("[profiling] cpu profiling save to file : cpu.prof")
|
log.Println("[profiling] cpu profiling save to file : cpu.prof")
|
||||||
log.Println("[profiling] memory profiling save to file : memory.prof")
|
log.Println("[profiling] memory profiling save to file : memory.prof")
|
||||||
log.Println("[profiling] block profiling save to file : block.prof")
|
log.Println("[profiling] block profiling save to file : block.prof")
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
@ -133,7 +134,14 @@ func newConn(m *Mux, dst net.Addr) *Conn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) start() {
|
func (c *Conn) start() {
|
||||||
go c.reader()
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c.reader()
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) reader() {
|
func (c *Conn) reader() {
|
||||||
|
|||||||
@ -6,6 +6,7 @@ package dst
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
@ -78,8 +79,14 @@ func NewMux(conn net.PacketConn, packetSize int) *Mux {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go m.readerLoop()
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
m.readerLoop()
|
||||||
|
}()
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ package dst
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -52,7 +53,14 @@ func newSendBuffer(m *Mux) *sendBuffer {
|
|||||||
scheduler: ratelimit.NewBucketWithRate(schedulerRate, schedulerCapacity),
|
scheduler: ratelimit.NewBucketWithRate(schedulerRate, schedulerCapacity),
|
||||||
}
|
}
|
||||||
b.cond = sync.NewCond(&b.mut)
|
b.cond = sync.NewCond(&b.mut)
|
||||||
go b.writerLoop()
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
b.writerLoop()
|
||||||
|
}()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package mapx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -150,7 +152,14 @@ type Tuple struct {
|
|||||||
func (m ConcurrentMap) Iter() <-chan Tuple {
|
func (m ConcurrentMap) Iter() <-chan Tuple {
|
||||||
chans := snapshot(m)
|
chans := snapshot(m)
|
||||||
ch := make(chan Tuple)
|
ch := make(chan Tuple)
|
||||||
go fanIn(chans, ch)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fanIn(chans, ch)
|
||||||
|
}()
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +171,14 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
|||||||
total += cap(c)
|
total += cap(c)
|
||||||
}
|
}
|
||||||
ch := make(chan Tuple, total)
|
ch := make(chan Tuple, total)
|
||||||
go fanIn(chans, ch)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fanIn(chans, ch)
|
||||||
|
}()
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +192,13 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
wg.Add(SHARD_COUNT)
|
wg.Add(SHARD_COUNT)
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
for index, shard := range m {
|
for index, shard := range m {
|
||||||
go func(index int, shard *ConcurrentMapShared) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(index int, shard *ConcurrentMapShared) {
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
shard.RLock()
|
shard.RLock()
|
||||||
chans[index] = make(chan Tuple, len(shard.items))
|
chans[index] = make(chan Tuple, len(shard.items))
|
||||||
@ -187,6 +209,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
shard.RUnlock()
|
shard.RUnlock()
|
||||||
close(chans[index])
|
close(chans[index])
|
||||||
}(index, shard)
|
}(index, shard)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return chans
|
return chans
|
||||||
@ -197,12 +220,19 @@ func fanIn(chans []chan Tuple, out chan Tuple) {
|
|||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(len(chans))
|
wg.Add(len(chans))
|
||||||
for _, ch := range chans {
|
for _, ch := range chans {
|
||||||
go func(ch chan Tuple) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(ch chan Tuple) {
|
||||||
for t := range ch {
|
for t := range ch {
|
||||||
out <- t
|
out <- t
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(ch)
|
}(ch)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(out)
|
close(out)
|
||||||
@ -244,11 +274,22 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
count := m.Count()
|
count := m.Count()
|
||||||
ch := make(chan string, count)
|
ch := make(chan string, count)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(SHARD_COUNT)
|
wg.Add(SHARD_COUNT)
|
||||||
for _, shard := range m {
|
for _, shard := range m {
|
||||||
go func(shard *ConcurrentMapShared) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(shard *ConcurrentMapShared) {
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
shard.RLock()
|
shard.RLock()
|
||||||
for key := range shard.items {
|
for key := range shard.items {
|
||||||
@ -257,6 +298,7 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
shard.RUnlock()
|
shard.RUnlock()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(shard)
|
}(shard)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(ch)
|
close(ch)
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package udputils
|
package udputils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
logger "log"
|
logger "log"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -58,6 +60,11 @@ func (s *IOBinder) Clean(fn CleanFn) *IOBinder {
|
|||||||
func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBinder {
|
func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBinder {
|
||||||
s.inTCPConn = inTCPConn
|
s.inTCPConn = inTCPConn
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
buf := make([]byte, 1)
|
buf := make([]byte, 1)
|
||||||
(*inTCPConn).SetReadDeadline(time.Time{})
|
(*inTCPConn).SetReadDeadline(time.Time{})
|
||||||
if _, err := (*inTCPConn).Read(buf); err != nil {
|
if _, err := (*inTCPConn).Read(buf); err != nil {
|
||||||
@ -66,6 +73,11 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
(*inTCPConn).SetWriteDeadline(time.Now().Add(time.Second * 5))
|
(*inTCPConn).SetWriteDeadline(time.Now().Add(time.Second * 5))
|
||||||
if _, err := (*inTCPConn).Write([]byte{0x00}); err != nil {
|
if _, err := (*inTCPConn).Write([]byte{0x00}); err != nil {
|
||||||
@ -82,6 +94,11 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
|
|||||||
func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IOBinder {
|
func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IOBinder {
|
||||||
s.outTCPConn = outTCPConn
|
s.outTCPConn = outTCPConn
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
buf := make([]byte, 1)
|
buf := make([]byte, 1)
|
||||||
(*outTCPConn).SetReadDeadline(time.Time{})
|
(*outTCPConn).SetReadDeadline(time.Time{})
|
||||||
if _, err := (*outTCPConn).Read(buf); err != nil {
|
if _, err := (*outTCPConn).Read(buf); err != nil {
|
||||||
@ -137,6 +154,11 @@ func (s *IOBinder) Run() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
defer func() {
|
defer func() {
|
||||||
s.clean(srcAddr.String())
|
s.clean(srcAddr.String())
|
||||||
}()
|
}()
|
||||||
|
|||||||
7
main.go
7
main.go
@ -1,9 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"runtime/debug"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
@ -32,6 +34,11 @@ func Clean(s *services.Service) {
|
|||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
syscall.SIGQUIT)
|
syscall.SIGQUIT)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for _ = range signalChan {
|
for _ = range signalChan {
|
||||||
log.Println("Received an interrupt, stopping services...")
|
log.Println("Received an interrupt, stopping services...")
|
||||||
if s != nil && *s != nil {
|
if s != nil && *s != nil {
|
||||||
|
|||||||
@ -11,10 +11,10 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
|
|
||||||
services "github.com/snail007/goproxy/services"
|
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
gocache "github.com/pmylund/go-cache"
|
gocache "github.com/pmylund/go-cache"
|
||||||
|
services "github.com/snail007/goproxy/services"
|
||||||
|
"github.com/snail007/goproxy/services/kcpcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DNSArgs struct {
|
type DNSArgs struct {
|
||||||
@ -58,6 +58,11 @@ func (s *DNS) InitService() (err error) {
|
|||||||
s.cache = gocache.New(time.Second*time.Duration(*s.cfg.DNSTTL), time.Second*60)
|
s.cache = gocache.New(time.Second*time.Duration(*s.cfg.DNSTTL), time.Second*60)
|
||||||
s.cache.LoadFile(*s.cfg.CacheFile)
|
s.cache.LoadFile(*s.cfg.CacheFile)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-s.exitSig:
|
case <-s.exitSig:
|
||||||
@ -135,6 +140,11 @@ func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
}
|
}
|
||||||
dns.HandleFunc(".", s.callback)
|
dns.HandleFunc(".", s.callback)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
log.Printf("dns server on udp %s", *s.cfg.Local)
|
log.Printf("dns server on udp %s", *s.cfg.Local)
|
||||||
err := dns.ListenAndServe(*s.cfg.Local, "udp", nil)
|
err := dns.ListenAndServe(*s.cfg.Local, "udp", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -181,6 +181,11 @@ func (s *HTTP) InitService() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
//循环检查ssh网络连通性
|
//循环检查ssh网络连通性
|
||||||
for {
|
for {
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -218,6 +223,17 @@ func (s *HTTP) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service http(s) stoped")
|
s.log.Printf("service http(s) stoped")
|
||||||
}
|
}
|
||||||
|
s.basicAuth = utils.BasicAuth{}
|
||||||
|
s.cfg = HTTPArgs{}
|
||||||
|
s.checker = utils.Checker{}
|
||||||
|
s.domainResolver = dnsx.DomainResolver{}
|
||||||
|
s.lb = nil
|
||||||
|
s.lockChn = nil
|
||||||
|
s.log = nil
|
||||||
|
s.serverChannels = nil
|
||||||
|
s.sshClient = nil
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if len(*s.cfg.Parent) > 0 {
|
if len(*s.cfg.Parent) > 0 {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
logger "log"
|
logger "log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -79,6 +80,14 @@ func (s *MuxBridge) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service bridge stoped")
|
s.log.Printf("service bridge stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = MuxBridgeArgs{}
|
||||||
|
s.clientControlConns = nil
|
||||||
|
s.l = nil
|
||||||
|
s.log = nil
|
||||||
|
s.router = utils.ClientKeyRouter{}
|
||||||
|
s.sc = nil
|
||||||
|
s.serverConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if s.sc != nil && (*s.sc).Listener != nil {
|
if s.sc != nil && (*s.sc).Listener != nil {
|
||||||
@ -209,6 +218,11 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
|||||||
group.Set(index, session)
|
group.Set(index, session)
|
||||||
// s.clientControlConns.Set(key, session)
|
// s.clientControlConns.Set(key, session)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
@ -277,10 +291,20 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
|||||||
die1 := make(chan bool, 1)
|
die1 := make(chan bool, 1)
|
||||||
die2 := make(chan bool, 1)
|
die2 := make(chan bool, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(stream, inConn)
|
io.Copy(stream, inConn)
|
||||||
die1 <- true
|
die1 <- true
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(inConn, stream)
|
io.Copy(inConn, stream)
|
||||||
die2 <- true
|
die2 <- true
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
logger "log"
|
logger "log"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -106,6 +107,12 @@ func (s *MuxClient) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service client stoped")
|
s.log.Printf("service client stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = MuxClientArgs{}
|
||||||
|
s.jumper = nil
|
||||||
|
s.log = nil
|
||||||
|
s.sessions = nil
|
||||||
|
s.udpConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
for _, sess := range s.sessions.Items() {
|
for _, sess := range s.sessions.Items() {
|
||||||
@ -297,6 +304,11 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
|
|||||||
}
|
}
|
||||||
func (s *MuxClient) UDPRevecive(key, ID string) {
|
func (s *MuxClient) UDPRevecive(key, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
v, ok := s.udpConns.Get(key)
|
v, ok := s.udpConns.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -322,6 +334,11 @@ func (s *MuxClient) UDPRevecive(key, ID string) {
|
|||||||
}
|
}
|
||||||
cui.touchtime = time.Now().Unix()
|
cui.touchtime = time.Now().Unix()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
_, err = cui.conn.Write(utils.UDPPacket(cui.srcAddr.String(), buf[:n]))
|
_, err = cui.conn.Write(utils.UDPPacket(cui.srcAddr.String(), buf[:n]))
|
||||||
cui.conn.SetWriteDeadline(time.Time{})
|
cui.conn.SetWriteDeadline(time.Time{})
|
||||||
@ -336,6 +353,11 @@ func (s *MuxClient) UDPRevecive(key, ID string) {
|
|||||||
func (s *MuxClient) UDPGCDeamon() {
|
func (s *MuxClient) UDPGCDeamon() {
|
||||||
gctime := int64(30)
|
gctime := int64(30)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -390,10 +412,20 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
|||||||
die1 := make(chan bool, 1)
|
die1 := make(chan bool, 1)
|
||||||
die2 := make(chan bool, 1)
|
die2 := make(chan bool, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(outConn, snappy.NewReader(inConn))
|
io.Copy(outConn, snappy.NewReader(inConn))
|
||||||
die1 <- true
|
die1 <- true
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(snappy.NewWriter(inConn), outConn)
|
io.Copy(snappy.NewWriter(inConn), outConn)
|
||||||
die2 <- true
|
die2 <- true
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -149,6 +149,11 @@ func (s *MuxServerManager) StopService() {
|
|||||||
for _, server := range s.servers {
|
for _, server := range s.servers {
|
||||||
(*server).Clean()
|
(*server).Clean()
|
||||||
}
|
}
|
||||||
|
s.cfg = MuxServerArgs{}
|
||||||
|
s.log = nil
|
||||||
|
s.serverID = ""
|
||||||
|
s.servers = nil
|
||||||
|
s = nil
|
||||||
}
|
}
|
||||||
func (s *MuxServerManager) CheckArgs() (err error) {
|
func (s *MuxServerManager) CheckArgs() (err error) {
|
||||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||||
@ -198,6 +203,14 @@ func (s *MuxServer) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service server stoped")
|
s.log.Printf("service server stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = MuxServerArgs{}
|
||||||
|
s.jumper = nil
|
||||||
|
s.lockChn = nil
|
||||||
|
s.log = nil
|
||||||
|
s.sc = utils.ServerChannel{}
|
||||||
|
s.sessions = nil
|
||||||
|
s.udpConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
for _, sess := range s.sessions.Items() {
|
for _, sess := range s.sessions.Items() {
|
||||||
@ -283,10 +296,20 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
die1 := make(chan bool, 1)
|
die1 := make(chan bool, 1)
|
||||||
die2 := make(chan bool, 1)
|
die2 := make(chan bool, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(inConn, snappy.NewReader(outConn))
|
io.Copy(inConn, snappy.NewReader(outConn))
|
||||||
die1 <- true
|
die1 <- true
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
io.Copy(snappy.NewWriter(outConn), inConn)
|
io.Copy(snappy.NewWriter(outConn), inConn)
|
||||||
die2 <- true
|
die2 <- true
|
||||||
}()
|
}()
|
||||||
@ -377,6 +400,11 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
|
|||||||
s.sessions.Set(index, session)
|
s.sessions.Set(index, session)
|
||||||
s.log.Printf("session[%s] created", index)
|
s.log.Printf("session[%s] created", index)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
@ -432,6 +460,11 @@ func (s *MuxServer) getParentConn() (conn net.Conn, err error) {
|
|||||||
func (s *MuxServer) UDPGCDeamon() {
|
func (s *MuxServer) UDPGCDeamon() {
|
||||||
gctime := int64(30)
|
gctime := int64(30)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -506,6 +539,11 @@ func (s *MuxServer) UDPSend(data []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
}
|
}
|
||||||
func (s *MuxServer) UDPRevecive(key, ID string) {
|
func (s *MuxServer) UDPRevecive(key, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
var uc *MuxUDPConnItem
|
var uc *MuxUDPConnItem
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -533,7 +571,14 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
uc.touchtime = time.Now().Unix()
|
uc.touchtime = time.Now().Unix()
|
||||||
go s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -189,6 +189,11 @@ func (s *Socks) InitService() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
//循环检查ssh网络连通性
|
//循环检查ssh网络连通性
|
||||||
for {
|
for {
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -226,6 +231,21 @@ func (s *Socks) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service socks stoped")
|
s.log.Printf("service socks stoped")
|
||||||
}
|
}
|
||||||
|
s.basicAuth = utils.BasicAuth{}
|
||||||
|
s.cfg = SocksArgs{}
|
||||||
|
s.checker = utils.Checker{}
|
||||||
|
s.domainResolver = dnsx.DomainResolver{}
|
||||||
|
s.lb = nil
|
||||||
|
s.lockChn = nil
|
||||||
|
s.log = nil
|
||||||
|
s.sc = nil
|
||||||
|
s.sshClient = nil
|
||||||
|
s.udpLocalKey = nil
|
||||||
|
s.udpParentKey = nil
|
||||||
|
s.udpRelatedPacketConns = nil
|
||||||
|
s.udpSC = utils.ServerChannel{}
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if len(*s.cfg.Parent) > 0 {
|
if len(*s.cfg.Parent) > 0 {
|
||||||
|
|||||||
@ -178,6 +178,19 @@ func (s *SPS) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service sps stoped")
|
s.log.Printf("service sps stoped")
|
||||||
}
|
}
|
||||||
|
s.basicAuth = utils.BasicAuth{}
|
||||||
|
s.cfg = SPSArgs{}
|
||||||
|
s.domainResolver = dnsx.DomainResolver{}
|
||||||
|
s.lb = nil
|
||||||
|
s.localCipher = nil
|
||||||
|
s.log = nil
|
||||||
|
s.parentCipher = nil
|
||||||
|
s.serverChannels = nil
|
||||||
|
s.udpLocalKey = nil
|
||||||
|
s.udpParentKey = nil
|
||||||
|
s.udpRelatedPacketConns = nil
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
for _, sc := range s.serverChannels {
|
for _, sc := range s.serverChannels {
|
||||||
if sc.Listener != nil && *sc.Listener != nil {
|
if sc.Listener != nil && *sc.Listener != nil {
|
||||||
|
|||||||
@ -92,6 +92,12 @@ func (s *TCP) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service tcp stoped")
|
s.log.Printf("service tcp stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = TCPArgs{}
|
||||||
|
s.jumper = nil
|
||||||
|
s.log = nil
|
||||||
|
s.sc = nil
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if s.sc.Listener != nil && *s.sc.Listener != nil {
|
if s.sc.Listener != nil && *s.sc.Listener != nil {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
@ -72,6 +73,11 @@ func (s *TunnelBridge) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service tbridge stoped")
|
s.log.Printf("service tbridge stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = TunnelBridgeArgs{}
|
||||||
|
s.clientControlConns = nil
|
||||||
|
s.log = nil
|
||||||
|
s.serverConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
for _, sess := range s.clientControlConns.Items() {
|
for _, sess := range s.clientControlConns.Items() {
|
||||||
@ -178,7 +184,7 @@ func (s *TunnelBridge) callback(inConn net.Conn) {
|
|||||||
(*item.(*net.Conn)).SetWriteDeadline(time.Now().Add(time.Second * 3))
|
(*item.(*net.Conn)).SetWriteDeadline(time.Now().Add(time.Second * 3))
|
||||||
_, 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 && strings.Contains(err.Error(), "stream closed") {
|
||||||
s.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
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
logger "log"
|
logger "log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ type ClientUDPConnItem struct {
|
|||||||
}
|
}
|
||||||
type TunnelClient struct {
|
type TunnelClient struct {
|
||||||
cfg TunnelClientArgs
|
cfg TunnelClientArgs
|
||||||
ctrlConn net.Conn
|
ctrlConn *net.Conn
|
||||||
isStop bool
|
isStop bool
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
@ -96,10 +97,17 @@ func (s *TunnelClient) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service tclient stoped")
|
s.log.Printf("service tclient stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = TunnelClientArgs{}
|
||||||
|
s.ctrlConn = nil
|
||||||
|
s.jumper = nil
|
||||||
|
s.log = nil
|
||||||
|
s.udpConns = nil
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if s.ctrlConn != nil {
|
if s.ctrlConn != nil {
|
||||||
s.ctrlConn.Close()
|
(*s.ctrlConn).Close()
|
||||||
}
|
}
|
||||||
for _, c := range s.userConns.Items() {
|
for _, c := range s.userConns.Items() {
|
||||||
(*c.(*net.Conn)).Close()
|
(*c.(*net.Conn)).Close()
|
||||||
@ -121,27 +129,25 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.ctrlConn != nil {
|
if s.ctrlConn != nil {
|
||||||
s.ctrlConn.Close()
|
(*s.ctrlConn).Close()
|
||||||
}
|
}
|
||||||
|
var c net.Conn
|
||||||
s.ctrlConn, err = s.GetInConn(CONN_CLIENT_CONTROL, *s.cfg.Key)
|
c, err = s.GetInConn(CONN_CLIENT_CONTROL, *s.cfg.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.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 {
|
|
||||||
s.ctrlConn.Close()
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
s.ctrlConn = &c
|
||||||
for {
|
for {
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var ID, clientLocalAddr, serverID string
|
var ID, clientLocalAddr, serverID string
|
||||||
err = utils.ReadPacketData(s.ctrlConn, &ID, &clientLocalAddr, &serverID)
|
err = utils.ReadPacketData(*s.ctrlConn, &ID, &clientLocalAddr, &serverID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if s.ctrlConn != nil {
|
if s.ctrlConn != nil {
|
||||||
s.ctrlConn.Close()
|
(*s.ctrlConn).Close()
|
||||||
}
|
}
|
||||||
s.log.Printf("read connection signal err: %s, retrying...", err)
|
s.log.Printf("read connection signal err: %s, retrying...", err)
|
||||||
break
|
break
|
||||||
@ -150,9 +156,23 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
protocol := clientLocalAddr[:3]
|
protocol := clientLocalAddr[:3]
|
||||||
localAddr := clientLocalAddr[4:]
|
localAddr := clientLocalAddr[4:]
|
||||||
if protocol == "udp" {
|
if protocol == "udp" {
|
||||||
go s.ServeUDP(localAddr, ID, serverID)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
s.ServeUDP(localAddr, ID, serverID)
|
||||||
|
}()
|
||||||
} else {
|
} else {
|
||||||
go s.ServeConn(localAddr, ID, serverID)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
s.ServeConn(localAddr, ID, serverID)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,11 +321,23 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
|||||||
item = v.(*ClientUDPConnItem)
|
item = v.(*ClientUDPConnItem)
|
||||||
}
|
}
|
||||||
(*item).touchtime = time.Now().Unix()
|
(*item).touchtime = time.Now().Unix()
|
||||||
go (*item).udpConn.Write(body)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
(*item).udpConn.Write(body)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *TunnelClient) UDPRevecive(key, ID string) {
|
func (s *TunnelClient) UDPRevecive(key, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
v, ok := s.udpConns.Get(key)
|
v, ok := s.udpConns.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -331,6 +363,11 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
|||||||
}
|
}
|
||||||
cui.touchtime = time.Now().Unix()
|
cui.touchtime = time.Now().Unix()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
_, err = (*cui.conn).Write(utils.UDPPacket(cui.srcAddr.String(), buf[:n]))
|
_, err = (*cui.conn).Write(utils.UDPPacket(cui.srcAddr.String(), buf[:n]))
|
||||||
(*cui.conn).SetWriteDeadline(time.Time{})
|
(*cui.conn).SetWriteDeadline(time.Time{})
|
||||||
@ -345,6 +382,11 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
|||||||
func (s *TunnelClient) UDPGCDeamon() {
|
func (s *TunnelClient) UDPGCDeamon() {
|
||||||
gctime := int64(30)
|
gctime := int64(30)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,6 +128,11 @@ func (s *TunnelServerManager) StopService() {
|
|||||||
for _, server := range s.servers {
|
for _, server := range s.servers {
|
||||||
(*server).Clean()
|
(*server).Clean()
|
||||||
}
|
}
|
||||||
|
s.cfg = TunnelServerArgs{}
|
||||||
|
s.log = nil
|
||||||
|
s.serverID = ""
|
||||||
|
s.servers = nil
|
||||||
|
s = nil
|
||||||
}
|
}
|
||||||
func (s *TunnelServerManager) CheckArgs() (err error) {
|
func (s *TunnelServerManager) CheckArgs() (err error) {
|
||||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||||
@ -172,6 +177,14 @@ func (s *TunnelServer) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service server stoped")
|
s.log.Printf("service server stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = TunnelServerArgs{}
|
||||||
|
s.jumper = nil
|
||||||
|
s.log = nil
|
||||||
|
s.sc = utils.ServerChannel{}
|
||||||
|
s.udpConn = nil
|
||||||
|
s.udpConns = nil
|
||||||
|
s.userConns = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
|
|
||||||
@ -353,6 +366,11 @@ func (s *TunnelServer) GetConn() (conn net.Conn, err error) {
|
|||||||
func (s *TunnelServer) UDPGCDeamon() {
|
func (s *TunnelServer) UDPGCDeamon() {
|
||||||
gctime := int64(30)
|
gctime := int64(30)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -419,6 +437,11 @@ func (s *TunnelServer) UDPSend(data []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
}
|
}
|
||||||
func (s *TunnelServer) UDPRevecive(key, ID string) {
|
func (s *TunnelServer) UDPRevecive(key, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
var uc *TunnelUDPConnItem
|
var uc *TunnelUDPConnItem
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -446,7 +469,14 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
uc.touchtime = time.Now().Unix()
|
uc.touchtime = time.Now().Unix()
|
||||||
go s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,11 @@ func (s *UDP) StopService() {
|
|||||||
} else {
|
} else {
|
||||||
s.log.Printf("service udp stoped")
|
s.log.Printf("service udp stoped")
|
||||||
}
|
}
|
||||||
|
s.cfg = UDPArgs{}
|
||||||
|
s.log = nil
|
||||||
|
s.p = nil
|
||||||
|
s.sc = nil
|
||||||
|
s = nil
|
||||||
}()
|
}()
|
||||||
s.isStop = true
|
s.isStop = true
|
||||||
if s.sc.Listener != nil && *s.sc.Listener != nil {
|
if s.sc.Listener != nil && *s.sc.Listener != nil {
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package lb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -112,6 +114,11 @@ func (b *Backend) StartHeartCheck() {
|
|||||||
}
|
}
|
||||||
func (b *Backend) startMuxHeartCheck() {
|
func (b *Backend) startMuxHeartCheck() {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if b.isStop {
|
if b.isStop {
|
||||||
return
|
return
|
||||||
@ -142,6 +149,11 @@ func (b *Backend) startMuxHeartCheck() {
|
|||||||
// Monitoring the backend
|
// Monitoring the backend
|
||||||
func (b *Backend) startTCPHeartCheck() {
|
func (b *Backend) startTCPHeartCheck() {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if b.isStop {
|
if b.isStop {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package mapx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -150,7 +152,14 @@ type Tuple struct {
|
|||||||
func (m ConcurrentMap) Iter() <-chan Tuple {
|
func (m ConcurrentMap) Iter() <-chan Tuple {
|
||||||
chans := snapshot(m)
|
chans := snapshot(m)
|
||||||
ch := make(chan Tuple)
|
ch := make(chan Tuple)
|
||||||
go fanIn(chans, ch)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fanIn(chans, ch)
|
||||||
|
}()
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +171,14 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
|||||||
total += cap(c)
|
total += cap(c)
|
||||||
}
|
}
|
||||||
ch := make(chan Tuple, total)
|
ch := make(chan Tuple, total)
|
||||||
go fanIn(chans, ch)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fanIn(chans, ch)
|
||||||
|
}()
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +192,13 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
wg.Add(SHARD_COUNT)
|
wg.Add(SHARD_COUNT)
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
for index, shard := range m {
|
for index, shard := range m {
|
||||||
go func(index int, shard *ConcurrentMapShared) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(index int, shard *ConcurrentMapShared) {
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
shard.RLock()
|
shard.RLock()
|
||||||
chans[index] = make(chan Tuple, len(shard.items))
|
chans[index] = make(chan Tuple, len(shard.items))
|
||||||
@ -187,6 +209,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
shard.RUnlock()
|
shard.RUnlock()
|
||||||
close(chans[index])
|
close(chans[index])
|
||||||
}(index, shard)
|
}(index, shard)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return chans
|
return chans
|
||||||
@ -197,12 +220,19 @@ func fanIn(chans []chan Tuple, out chan Tuple) {
|
|||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(len(chans))
|
wg.Add(len(chans))
|
||||||
for _, ch := range chans {
|
for _, ch := range chans {
|
||||||
go func(ch chan Tuple) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(ch chan Tuple) {
|
||||||
for t := range ch {
|
for t := range ch {
|
||||||
out <- t
|
out <- t
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(ch)
|
}(ch)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(out)
|
close(out)
|
||||||
@ -244,11 +274,22 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
count := m.Count()
|
count := m.Count()
|
||||||
ch := make(chan string, count)
|
ch := make(chan string, count)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(SHARD_COUNT)
|
wg.Add(SHARD_COUNT)
|
||||||
for _, shard := range m {
|
for _, shard := range m {
|
||||||
go func(shard *ConcurrentMapShared) {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
func(shard *ConcurrentMapShared) {
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
shard.RLock()
|
shard.RLock()
|
||||||
for key := range shard.items {
|
for key := range shard.items {
|
||||||
@ -257,6 +298,7 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
shard.RUnlock()
|
shard.RUnlock()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(shard)
|
}(shard)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(ch)
|
close(ch)
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
logger "log"
|
logger "log"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -87,11 +88,21 @@ func (c *Checker) Stop() {
|
|||||||
}
|
}
|
||||||
func (c *Checker) start() {
|
func (c *Checker) start() {
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
//log.Printf("checker started")
|
//log.Printf("checker started")
|
||||||
for {
|
for {
|
||||||
//log.Printf("checker did")
|
//log.Printf("checker did")
|
||||||
for _, v := range c.data.Items() {
|
for _, v := range c.data.Items() {
|
||||||
go func(item CheckerItem) {
|
go func(item CheckerItem) {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
if c.isNeedCheck(item) {
|
if c.isNeedCheck(item) {
|
||||||
//log.Printf("check %s", item.Host)
|
//log.Printf("check %s", item.Host)
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
|
|||||||
Reference in New Issue
Block a user