Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
xjasonlyu committed Aug 29, 2024
1 parent ba05656 commit 6a96a61
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 33 deletions.
2 changes: 1 addition & 1 deletion engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func netstack(k *Key) (err error) {
if _defaultProxy, err = parseProxy(k.Proxy); err != nil {
return
}
proxy.SetDialer(_defaultProxy)
tunnel.T().SetDialer(_defaultProxy)

if _defaultDevice, err = parseDevice(k.Device, uint32(k.MTU)); err != nil {
return
Expand Down
23 changes: 5 additions & 18 deletions tunnel/global.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package tunnel

import (
"context"
"net"
"sync"

M "github.com/xjasonlyu/tun2socks/v2/metadata"
"github.com/xjasonlyu/tun2socks/v2/proxy"
"github.com/xjasonlyu/tun2socks/v2/tunnel/statistic"
)
Expand All @@ -16,35 +13,25 @@ var (
)

func init() {
ReplaceGlobals(New(wrapper{}, statistic.DefaultManager))
ReplaceGlobal(New(&proxy.Base{}, statistic.DefaultManager))
go T().Process()
}

type wrapper struct{}

func (wrapper) DialContext(ctx context.Context, metadata *M.Metadata) (net.Conn, error) {
return proxy.DialContext(ctx, metadata)
}

func (wrapper) DialUDP(metadata *M.Metadata) (net.PacketConn, error) {
return proxy.DialUDP(metadata)
}

// T returns the global Tunnel, which can be reconfigured with
// ReplaceGlobals. It's safe for concurrent use.
// ReplaceGlobal. It's safe for concurrent use.
func T() *Tunnel {
_globalMu.RLock()
t := _globalT
_globalMu.RUnlock()
return t
}

// ReplaceGlobals replaces the global Tunnel, and returns a function
// ReplaceGlobal replaces the global Tunnel, and returns a function
// to restore the original values. It's safe for concurrent use.
func ReplaceGlobals(t *Tunnel) func() {
func ReplaceGlobal(t *Tunnel) func() {
_globalMu.Lock()
prev := _globalT
_globalT = t
_globalMu.Unlock()
return func() { ReplaceGlobals(prev) }
return func() { ReplaceGlobal(prev) }
}
2 changes: 1 addition & 1 deletion tunnel/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (t *Tunnel) handleTCPConn(originConn adapter.TCPConn) {
ctx, cancel := context.WithTimeout(context.Background(), tcpConnectTimeout)
defer cancel()

remoteConn, err := t.dialer.DialContext(ctx, metadata)
remoteConn, err := t.Dialer().DialContext(ctx, metadata)
if err != nil {
log.Warnf("[TCP] dial %s: %v", metadata.DestinationAddress(), err)
return
Expand Down
44 changes: 37 additions & 7 deletions tunnel/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ type Tunnel struct {
// UDP session timeout.
udpTimeout time.Duration

dialer proxy.Dialer
mu sync.RWMutex
dialer proxy.Dialer

// Internal statistic.Manager for Tunnel.
manager *statistic.Manager

once sync.Once
cancel context.CancelFunc
// Process controls.
procOnce sync.Once
procCancel context.CancelFunc
}

func New(dialer proxy.Dialer, manager *statistic.Manager) *Tunnel {
Expand All @@ -36,7 +40,7 @@ func New(dialer proxy.Dialer, manager *statistic.Manager) *Tunnel {
udpTimeout: udpSessionTimeout,
dialer: dialer,
manager: manager,
cancel: func() {},
procCancel: func() {},
}
}

Expand All @@ -58,6 +62,32 @@ func (t *Tunnel) HandleUDP(conn adapter.UDPConn) {
t.UDPIn() <- conn
}

func (t *Tunnel) Dialer() proxy.Dialer {
t.mu.RLock()
d := t.dialer
t.mu.RUnlock()
return d
}

func (t *Tunnel) SetDialer(dialer proxy.Dialer) {
t.mu.Lock()
t.dialer = dialer
t.mu.Unlock()
}

func (t *Tunnel) UDPTimeout() time.Duration {
t.mu.RLock()
timeout := t.udpTimeout
t.mu.RUnlock()
return timeout
}

func (t *Tunnel) SetUDPTimeout(timeout time.Duration) {
t.mu.Lock()
t.udpTimeout = timeout
t.mu.Unlock()
}

func (t *Tunnel) process(ctx context.Context) {
for {
select {
Expand All @@ -72,13 +102,13 @@ func (t *Tunnel) process(ctx context.Context) {
}

func (t *Tunnel) Process() {
t.once.Do(func() {
t.procOnce.Do(func() {
ctx, cancel := context.WithCancel(context.Background())
t.cancel = cancel
t.procCancel = cancel
t.process(ctx)
})
}

func (t *Tunnel) Close() {
t.cancel()
t.procCancel()
}
8 changes: 2 additions & 6 deletions tunnel/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import (
"github.com/xjasonlyu/tun2socks/v2/tunnel/statistic"
)

func (t *Tunnel) SetUDPTimeout(timeout time.Duration) {
t.udpTimeout = timeout
}

// TODO: Port Restricted NAT support.
func (t *Tunnel) handleUDPConn(uc adapter.UDPConn) {
defer uc.Close()
Expand All @@ -30,7 +26,7 @@ func (t *Tunnel) handleUDPConn(uc adapter.UDPConn) {
DstPort: id.LocalPort,
}

pc, err := t.dialer.DialUDP(metadata)
pc, err := t.Dialer().DialUDP(metadata)
if err != nil {
log.Warnf("[UDP] dial %s: %v", metadata.DestinationAddress(), err)
return
Expand All @@ -49,7 +45,7 @@ func (t *Tunnel) handleUDPConn(uc adapter.UDPConn) {
pc = newSymmetricNATPacketConn(pc, metadata)

log.Infof("[UDP] %s <-> %s", metadata.SourceAddress(), metadata.DestinationAddress())
pipePacket(uc, pc, remote, t.udpTimeout)
pipePacket(uc, pc, remote, t.UDPTimeout())
}

func pipePacket(origin, remote net.PacketConn, to net.Addr, timeout time.Duration) {
Expand Down

0 comments on commit 6a96a61

Please sign in to comment.