diff --git a/constant/constant.go b/constant/constant.go deleted file mode 100644 index 66ab104..0000000 --- a/constant/constant.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package constant provides global constants/variables of this project. -package constant diff --git a/common/adapter/metadata.go b/constant/metadata.go similarity index 99% rename from common/adapter/metadata.go rename to constant/metadata.go index cca8d8b..c0fe485 100755 --- a/common/adapter/metadata.go +++ b/constant/metadata.go @@ -1,4 +1,4 @@ -package adapter +package constant import ( "bytes" diff --git a/common/adapter/adapter.go b/core/adapter.go old mode 100755 new mode 100644 similarity index 79% rename from common/adapter/adapter.go rename to core/adapter.go index 4880cc5..98803bc --- a/common/adapter/adapter.go +++ b/core/adapter.go @@ -1,12 +1,14 @@ -package adapter +package core import ( "net" + + "gvisor.dev/gvisor/pkg/tcpip/stack" ) type TCPConn interface { net.Conn - Metadata() *Metadata + ID() *stack.TransportEndpointID } type UDPPacket interface { @@ -16,12 +18,12 @@ type UDPPacket interface { // Drop call after packet is used, could release resources in this function. Drop() + // ID returns the transport endpoint id of packet. + ID() *stack.TransportEndpointID + // LocalAddr returns the source IP/Port of packet. LocalAddr() net.Addr - // Metadata returns the metadata of packet. - Metadata() *Metadata - // RemoteAddr returns the destination IP/Port of packet. RemoteAddr() net.Addr diff --git a/core/handler.go b/core/handler.go new file mode 100755 index 0000000..8606df1 --- /dev/null +++ b/core/handler.go @@ -0,0 +1,6 @@ +package core + +type Handler interface { + Add(TCPConn) + AddPacket(UDPPacket) +} diff --git a/core/stack/handler.go b/core/stack/handler.go deleted file mode 100755 index f4219c2..0000000 --- a/core/stack/handler.go +++ /dev/null @@ -1,10 +0,0 @@ -package stack - -import ( - "github.com/xjasonlyu/tun2socks/common/adapter" -) - -type Handler interface { - Add(adapter.TCPConn) - AddPacket(adapter.UDPPacket) -} diff --git a/core/stack/stack.go b/core/stack/stack.go index 629c774..bafbf2f 100755 --- a/core/stack/stack.go +++ b/core/stack/stack.go @@ -2,6 +2,8 @@ package stack import ( + "github.com/xjasonlyu/tun2socks/core" + "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" @@ -14,12 +16,12 @@ import ( type Stack struct { *stack.Stack - handler Handler + handler core.Handler nicID tcpip.NICID } // New allocates a new *Stack with given options. -func New(ep stack.LinkEndpoint, handler Handler, opts ...Option) (*Stack, error) { +func New(ep stack.LinkEndpoint, handler core.Handler, opts ...Option) (*Stack, error) { s := &Stack{ Stack: stack.New(stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{ diff --git a/core/stack/tcp.go b/core/stack/tcp.go index d13b4c0..309ad01 100755 --- a/core/stack/tcp.go +++ b/core/stack/tcp.go @@ -5,10 +5,9 @@ import ( "net" "time" - "github.com/xjasonlyu/tun2socks/common/adapter" - "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" + "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" "gvisor.dev/gvisor/pkg/waiter" ) @@ -50,15 +49,8 @@ func withTCPHandler() Option { conn := &tcpConn{ Conn: gonet.NewTCPConn(&wq, ep), - metadata: &adapter.Metadata{ - Net: adapter.TCP, - SrcIP: net.IP(id.RemoteAddress), - SrcPort: id.RemotePort, - DstIP: net.IP(id.LocalAddress), - DstPort: id.LocalPort, - }, + id: &id, } - s.handler.Add(conn) }) s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket) @@ -83,9 +75,9 @@ func setKeepalive(ep tcpip.Endpoint) error { type tcpConn struct { net.Conn - metadata *adapter.Metadata + id *stack.TransportEndpointID } -func (c *tcpConn) Metadata() *adapter.Metadata { - return c.metadata +func (c *tcpConn) ID() *stack.TransportEndpointID { + return c.id } diff --git a/core/stack/udp.go b/core/stack/udp.go index 0324be6..fcdde60 100755 --- a/core/stack/udp.go +++ b/core/stack/udp.go @@ -4,8 +4,6 @@ import ( "fmt" "net" - "github.com/xjasonlyu/tun2socks/common/adapter" - "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/header" @@ -39,18 +37,11 @@ func withUDPHandler() Option { packet := &udpPacket{ s: s, - id: id, + id: &id, nicID: pkt.NICID, netHdr: pkt.Network(), netProto: pkt.NetworkProtocolNumber, payload: pkt.Data.ToView(), - metadata: &adapter.Metadata{ - Net: adapter.UDP, - SrcIP: net.IP(id.RemoteAddress), - SrcPort: id.RemotePort, - DstIP: net.IP(id.LocalAddress), - DstPort: id.LocalPort, - }, } s.handler.AddPacket(packet) @@ -63,12 +54,11 @@ func withUDPHandler() Option { type udpPacket struct { s *Stack - id stack.TransportEndpointID + id *stack.TransportEndpointID nicID tcpip.NICID netHdr header.Network netProto tcpip.NetworkProtocolNumber payload []byte - metadata *adapter.Metadata } func (p *udpPacket) Data() []byte { @@ -79,12 +69,12 @@ func (p *udpPacket) Drop() { /* Release */ } -func (p *udpPacket) LocalAddr() net.Addr { - return &net.UDPAddr{IP: net.IP(p.id.LocalAddress), Port: int(p.id.LocalPort)} +func (p *udpPacket) ID() *stack.TransportEndpointID { + return p.id } -func (p *udpPacket) Metadata() *adapter.Metadata { - return p.metadata +func (p *udpPacket) LocalAddr() net.Addr { + return &net.UDPAddr{IP: net.IP(p.id.LocalAddress), Port: int(p.id.LocalPort)} } func (p *udpPacket) RemoteAddr() net.Addr { diff --git a/engine/tunnel.go b/engine/tunnel.go index 5c4f21c..b0e223f 100644 --- a/engine/tunnel.go +++ b/engine/tunnel.go @@ -1,19 +1,18 @@ package engine import ( - "github.com/xjasonlyu/tun2socks/common/adapter" - "github.com/xjasonlyu/tun2socks/core/stack" + "github.com/xjasonlyu/tun2socks/core" "github.com/xjasonlyu/tun2socks/tunnel" ) -var _ stack.Handler = (*fakeTunnel)(nil) +var _ core.Handler = (*fakeTunnel)(nil) type fakeTunnel struct{} -func (*fakeTunnel) Add(conn adapter.TCPConn) { +func (*fakeTunnel) Add(conn core.TCPConn) { tunnel.Add(conn) } -func (*fakeTunnel) AddPacket(packet adapter.UDPPacket) { +func (*fakeTunnel) AddPacket(packet core.UDPPacket) { tunnel.AddPacket(packet) } diff --git a/proxy/base.go b/proxy/base.go index 2185404..4453acd 100755 --- a/proxy/base.go +++ b/proxy/base.go @@ -5,7 +5,7 @@ import ( "errors" "net" - "github.com/xjasonlyu/tun2socks/common/adapter" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/xjasonlyu/tun2socks/proxy/proto" ) @@ -28,10 +28,10 @@ func (b *Base) Proto() proto.Proto { return b.proto } -func (b *Base) DialContext(context.Context, *adapter.Metadata) (net.Conn, error) { +func (b *Base) DialContext(context.Context, *M.Metadata) (net.Conn, error) { return nil, errors.New("not supported") } -func (b *Base) DialUDP(*adapter.Metadata) (net.PacketConn, error) { +func (b *Base) DialUDP(*M.Metadata) (net.PacketConn, error) { return nil, errors.New("not supported") } diff --git a/proxy/direct.go b/proxy/direct.go index 6880c1f..7899f9b 100755 --- a/proxy/direct.go +++ b/proxy/direct.go @@ -4,8 +4,8 @@ import ( "context" "net" - "github.com/xjasonlyu/tun2socks/common/adapter" "github.com/xjasonlyu/tun2socks/component/dialer" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/xjasonlyu/tun2socks/proxy/proto" ) @@ -23,7 +23,7 @@ func NewDirect() *Direct { } } -func (d *Direct) DialContext(ctx context.Context, metadata *adapter.Metadata) (net.Conn, error) { +func (d *Direct) DialContext(ctx context.Context, metadata *M.Metadata) (net.Conn, error) { c, err := dialer.DialContext(ctx, "tcp", metadata.DestinationAddress()) if err != nil { return nil, err @@ -32,7 +32,7 @@ func (d *Direct) DialContext(ctx context.Context, metadata *adapter.Metadata) (n return c, nil } -func (d *Direct) DialUDP(_ *adapter.Metadata) (net.PacketConn, error) { +func (d *Direct) DialUDP(*M.Metadata) (net.PacketConn, error) { pc, err := dialer.ListenPacket("udp", "") if err != nil { return nil, err @@ -45,7 +45,7 @@ type directPacketConn struct { } func (pc *directPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { - if m, ok := addr.(*adapter.Metadata); ok && m.DstIP != nil { + if m, ok := addr.(*M.Metadata); ok && m.DstIP != nil { return pc.PacketConn.WriteTo(b, m.UDPAddr()) } diff --git a/proxy/proxy.go b/proxy/proxy.go index df36883..3b0cdbd 100755 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -6,7 +6,7 @@ import ( "net" "time" - "github.com/xjasonlyu/tun2socks/common/adapter" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/xjasonlyu/tun2socks/proxy/proto" ) @@ -19,8 +19,8 @@ var ( ) type Dialer interface { - DialContext(context.Context, *adapter.Metadata) (net.Conn, error) - DialUDP(*adapter.Metadata) (net.PacketConn, error) + DialContext(context.Context, *M.Metadata) (net.Conn, error) + DialUDP(*M.Metadata) (net.PacketConn, error) } type Proxy interface { @@ -35,18 +35,18 @@ func SetDialer(d Dialer) { } // Dial uses default Dialer to dial TCP. -func Dial(metadata *adapter.Metadata) (net.Conn, error) { +func Dial(metadata *M.Metadata) (net.Conn, error) { ctx, cancel := context.WithTimeout(context.Background(), tcpConnectTimeout) defer cancel() return _defaultDialer.DialContext(ctx, metadata) } // DialContext uses default Dialer to dial TCP with context. -func DialContext(ctx context.Context, metadata *adapter.Metadata) (net.Conn, error) { +func DialContext(ctx context.Context, metadata *M.Metadata) (net.Conn, error) { return _defaultDialer.DialContext(ctx, metadata) } // DialUDP uses default Dialer to dial UDP. -func DialUDP(metadata *adapter.Metadata) (net.PacketConn, error) { +func DialUDP(metadata *M.Metadata) (net.PacketConn, error) { return _defaultDialer.DialUDP(metadata) } diff --git a/proxy/shadowsocks.go b/proxy/shadowsocks.go index d8de273..67987fb 100755 --- a/proxy/shadowsocks.go +++ b/proxy/shadowsocks.go @@ -6,10 +6,10 @@ import ( "fmt" "net" - "github.com/xjasonlyu/tun2socks/common/adapter" "github.com/xjasonlyu/tun2socks/component/dialer" obfs "github.com/xjasonlyu/tun2socks/component/simple-obfs" "github.com/xjasonlyu/tun2socks/component/socks5" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/xjasonlyu/tun2socks/proxy/proto" "github.com/Dreamacro/go-shadowsocks2/core" @@ -43,7 +43,7 @@ func NewShadowsocks(addr, method, password, obfsMode, obfsHost string) (*Shadows }, nil } -func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *adapter.Metadata) (c net.Conn, err error) { +func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *M.Metadata) (c net.Conn, err error) { c, err = dialer.DialContext(ctx, "tcp", ss.Addr()) if err != nil { return nil, fmt.Errorf("connect to %s: %w", ss.Addr(), err) @@ -69,7 +69,7 @@ func (ss *Shadowsocks) DialContext(ctx context.Context, metadata *adapter.Metada return } -func (ss *Shadowsocks) DialUDP(_ *adapter.Metadata) (net.PacketConn, error) { +func (ss *Shadowsocks) DialUDP(*M.Metadata) (net.PacketConn, error) { pc, err := dialer.ListenPacket("udp", "") if err != nil { return nil, fmt.Errorf("listen packet: %w", err) @@ -92,7 +92,7 @@ type ssPacketConn struct { func (pc *ssPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { var packet []byte - if m, ok := addr.(*adapter.Metadata); ok { + if m, ok := addr.(*M.Metadata); ok { packet, err = socks5.EncodeUDPPacket(m.SerializesSocksAddr(), b) } else { packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) diff --git a/proxy/socks5.go b/proxy/socks5.go index 7ccbbe6..a4eb879 100755 --- a/proxy/socks5.go +++ b/proxy/socks5.go @@ -7,9 +7,9 @@ import ( "io/ioutil" "net" - "github.com/xjasonlyu/tun2socks/common/adapter" "github.com/xjasonlyu/tun2socks/component/dialer" "github.com/xjasonlyu/tun2socks/component/socks5" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/xjasonlyu/tun2socks/proxy/proto" ) @@ -33,7 +33,7 @@ func NewSocks5(addr, user, pass string) (*Socks5, error) { }, nil } -func (ss *Socks5) DialContext(ctx context.Context, metadata *adapter.Metadata) (c net.Conn, err error) { +func (ss *Socks5) DialContext(ctx context.Context, metadata *M.Metadata) (c net.Conn, err error) { c, err = dialer.DialContext(ctx, "tcp", ss.Addr()) if err != nil { return nil, fmt.Errorf("connect to %s: %w", ss.Addr(), err) @@ -58,7 +58,7 @@ func (ss *Socks5) DialContext(ctx context.Context, metadata *adapter.Metadata) ( return } -func (ss *Socks5) DialUDP(_ *adapter.Metadata) (_ net.PacketConn, err error) { +func (ss *Socks5) DialUDP(*M.Metadata) (_ net.PacketConn, err error) { ctx, cancel := context.WithTimeout(context.Background(), tcpConnectTimeout) defer cancel() @@ -132,7 +132,7 @@ type socksPacketConn struct { func (pc *socksPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { var packet []byte - if m, ok := addr.(*adapter.Metadata); ok { + if m, ok := addr.(*M.Metadata); ok { packet, err = socks5.EncodeUDPPacket(m.SerializesSocksAddr(), b) } else { packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) diff --git a/tunnel/statistic/tracker.go b/tunnel/statistic/tracker.go index 5315993..f5a4155 100755 --- a/tunnel/statistic/tracker.go +++ b/tunnel/statistic/tracker.go @@ -4,7 +4,7 @@ import ( "net" "time" - "github.com/xjasonlyu/tun2socks/common/adapter" + M "github.com/xjasonlyu/tun2socks/constant" "github.com/gofrs/uuid" "go.uber.org/atomic" @@ -16,11 +16,11 @@ type tracker interface { } type trackerInfo struct { - Start time.Time `json:"start"` - UUID uuid.UUID `json:"id"` - Metadata *adapter.Metadata `json:"metadata"` - UploadTotal *atomic.Int64 `json:"upload"` - DownloadTotal *atomic.Int64 `json:"download"` + Start time.Time `json:"start"` + UUID uuid.UUID `json:"id"` + Metadata *M.Metadata `json:"metadata"` + UploadTotal *atomic.Int64 `json:"upload"` + DownloadTotal *atomic.Int64 `json:"download"` } type tcpTracker struct { @@ -30,7 +30,7 @@ type tcpTracker struct { manager *Manager } -func NewTCPTracker(conn net.Conn, metadata *adapter.Metadata, manager *Manager) *tcpTracker { +func NewTCPTracker(conn net.Conn, metadata *M.Metadata, manager *Manager) *tcpTracker { id, _ := uuid.NewV4() tt := &tcpTracker{ @@ -81,7 +81,7 @@ type udpTracker struct { manager *Manager } -func NewUDPTracker(conn net.PacketConn, metadata *adapter.Metadata, manager *Manager) *udpTracker { +func NewUDPTracker(conn net.PacketConn, metadata *M.Metadata, manager *Manager) *udpTracker { id, _ := uuid.NewV4() ut := &udpTracker{ diff --git a/tunnel/tcp.go b/tunnel/tcp.go index 5d8f04b..80e9499 100755 --- a/tunnel/tcp.go +++ b/tunnel/tcp.go @@ -7,8 +7,9 @@ import ( "sync" "time" - "github.com/xjasonlyu/tun2socks/common/adapter" "github.com/xjasonlyu/tun2socks/common/pool" + M "github.com/xjasonlyu/tun2socks/constant" + "github.com/xjasonlyu/tun2socks/core" "github.com/xjasonlyu/tun2socks/log" "github.com/xjasonlyu/tun2socks/proxy" "github.com/xjasonlyu/tun2socks/tunnel/statistic" @@ -18,14 +19,21 @@ const ( tcpWaitTimeout = 5 * time.Second ) -func newTCPTracker(conn net.Conn, metadata *adapter.Metadata) net.Conn { +func newTCPTracker(conn net.Conn, metadata *M.Metadata) net.Conn { return statistic.NewTCPTracker(conn, metadata, statistic.DefaultManager) } -func handleTCP(localConn adapter.TCPConn) { +func handleTCP(localConn core.TCPConn) { defer localConn.Close() - metadata := localConn.Metadata() + id := localConn.ID() + metadata := &M.Metadata{ + Net: M.TCP, + SrcIP: net.IP(id.RemoteAddress), + SrcPort: id.RemotePort, + DstIP: net.IP(id.LocalAddress), + DstPort: id.LocalPort, + } if !metadata.Valid() { log.Warnf("[Metadata] not valid: %#v", metadata) return diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 0ec5acd..55d7d7b 100755 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -3,7 +3,7 @@ package tunnel import ( "runtime" - "github.com/xjasonlyu/tun2socks/common/adapter" + "github.com/xjasonlyu/tun2socks/core" "github.com/xjasonlyu/tun2socks/log" ) @@ -15,8 +15,8 @@ const ( ) var ( - tcpQueue = make(chan adapter.TCPConn) /* unbuffered */ - udpQueue = make(chan adapter.UDPPacket, maxUDPQueueSize) + tcpQueue = make(chan core.TCPConn) /* unbuffered */ + udpQueue = make(chan core.UDPPacket, maxUDPQueueSize) numUDPWorkers = max(runtime.NumCPU(), 4 /* at least 4 workers */) ) @@ -25,12 +25,12 @@ func init() { } // Add adds tcpConn to tcpQueue. -func Add(conn adapter.TCPConn) { +func Add(conn core.TCPConn) { tcpQueue <- conn } // AddPacket adds udpPacket to udpQueue. -func AddPacket(packet adapter.UDPPacket) { +func AddPacket(packet core.UDPPacket) { select { case udpQueue <- packet: default: diff --git a/tunnel/udp.go b/tunnel/udp.go index 01d99a0..f54458b 100755 --- a/tunnel/udp.go +++ b/tunnel/udp.go @@ -7,9 +7,10 @@ import ( "strconv" "time" - "github.com/xjasonlyu/tun2socks/common/adapter" "github.com/xjasonlyu/tun2socks/common/pool" "github.com/xjasonlyu/tun2socks/component/nat" + M "github.com/xjasonlyu/tun2socks/constant" + "github.com/xjasonlyu/tun2socks/core" "github.com/xjasonlyu/tun2socks/log" "github.com/xjasonlyu/tun2socks/proxy" "github.com/xjasonlyu/tun2socks/tunnel/statistic" @@ -25,18 +26,25 @@ var ( natTable = nat.NewTable() ) -func newUDPTracker(conn net.PacketConn, metadata *adapter.Metadata) net.PacketConn { +func newUDPTracker(conn net.PacketConn, metadata *M.Metadata) net.PacketConn { return statistic.NewUDPTracker(conn, metadata, statistic.DefaultManager) } -func handleUDP(packet adapter.UDPPacket) { - metadata := packet.Metadata() +func handleUDP(packet core.UDPPacket) { + id := packet.ID() + metadata := &M.Metadata{ + Net: M.UDP, + SrcIP: net.IP(id.RemoteAddress), + SrcPort: id.RemotePort, + DstIP: net.IP(id.LocalAddress), + DstPort: id.LocalPort, + } if !metadata.Valid() { log.Warnf("[Metadata] not valid: %#v", metadata) return } - generateNATKey := func(m *adapter.Metadata) string { + generateNATKey := func(m *M.Metadata) string { return m.SourceAddress() /* Full Cone NAT Key */ } key := generateNATKey(metadata) @@ -101,7 +109,7 @@ func handleUDP(packet adapter.UDPPacket) { }() } -func handleUDPToRemote(packet adapter.UDPPacket, pc net.PacketConn, remote net.Addr, drop bool) { +func handleUDPToRemote(packet core.UDPPacket, pc net.PacketConn, remote net.Addr, drop bool) { defer func() { if drop { packet.Drop() @@ -115,7 +123,7 @@ func handleUDPToRemote(packet adapter.UDPPacket, pc net.PacketConn, remote net.A log.Infof("[UDP] %s --> %s", packet.RemoteAddr(), remote) } -func handleUDPToLocal(packet adapter.UDPPacket, pc net.PacketConn, timeout time.Duration) { +func handleUDPToLocal(packet core.UDPPacket, pc net.PacketConn, timeout time.Duration) { buf := pool.Get(pool.MaxSegmentSize) defer pool.Put(buf)