From 6603c1f334ced41c4993fb2dbec201a4e2910d24 Mon Sep 17 00:00:00 2001 From: xjasonlyu Date: Sat, 5 Feb 2022 16:51:17 +0800 Subject: [PATCH] Refactor: improve metadata structure --- metadata/metadata.go | 55 ++++++++++++++++++-------------------------- metadata/network.go | 27 ++++++++++++++++++++++ proxy/direct.go | 4 ++-- proxy/shadowsocks.go | 4 ++-- proxy/socks5.go | 4 ++-- tunnel/tcp.go | 2 +- tunnel/udp.go | 7 +++--- 7 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 metadata/network.go diff --git a/metadata/metadata.go b/metadata/metadata.go index d30231b..16125ca 100644 --- a/metadata/metadata.go +++ b/metadata/metadata.go @@ -3,38 +3,15 @@ package metadata import ( "bytes" "encoding/binary" - "fmt" "net" "strconv" "github.com/xjasonlyu/tun2socks/v2/transport/socks5" ) -const ( - TCP Network = iota - UDP -) - -type Network uint8 - -func (n Network) String() string { - switch n { - case TCP: - return "tcp" - case UDP: - return "udp" - default: - return fmt.Sprintf("network(%d)", n) - } -} - -func (n Network) MarshalText() ([]byte, error) { - return []byte(n.String()), nil -} - -// Metadata implements the net.Addr interface. +// Metadata contains metadata of transport protocol sessions. type Metadata struct { - Net Network `json:"network"` + Network Network `json:"network"` SrcIP net.IP `json:"sourceIP"` MidIP net.IP `json:"dialerIP"` DstIP net.IP `json:"destinationIP"` @@ -51,8 +28,15 @@ func (m *Metadata) SourceAddress() string { return net.JoinHostPort(m.SrcIP.String(), strconv.FormatUint(uint64(m.SrcPort), 10)) } +func (m *Metadata) Addr() net.Addr { + if udpAddr := m.UDPAddr(); udpAddr != nil { + return udpAddr + } + return &Addr{metadata: m} +} + func (m *Metadata) UDPAddr() *net.UDPAddr { - if m.Net != UDP || m.DstIP == nil { + if m.Network != UDP || m.DstIP == nil { return nil } return &net.UDPAddr{ @@ -78,12 +62,19 @@ func (m *Metadata) SerializeSocksAddr() socks5.Addr { return bytes.Join(buf, nil) } -func (m *Metadata) Network() string { - return m.Net.String() +// Addr implements the net.Addr interface. +type Addr struct { + metadata *Metadata +} + +func (a *Addr) Metadata() *Metadata { + return a.metadata +} + +func (a *Addr) Network() string { + return a.metadata.Network.String() } -// String returns destination address of this metadata. -// Also, it implements net.Addr interface. -func (m *Metadata) String() string { - return m.DestinationAddress() +func (a *Addr) String() string { + return a.metadata.DestinationAddress() } diff --git a/metadata/network.go b/metadata/network.go new file mode 100644 index 0000000..30410a6 --- /dev/null +++ b/metadata/network.go @@ -0,0 +1,27 @@ +package metadata + +import ( + "fmt" +) + +const ( + TCP Network = iota + UDP +) + +type Network uint8 + +func (n Network) String() string { + switch n { + case TCP: + return "tcp" + case UDP: + return "udp" + default: + return fmt.Sprintf("network(%d)", n) + } +} + +func (n Network) MarshalText() ([]byte, error) { + return []byte(n.String()), nil +} diff --git a/proxy/direct.go b/proxy/direct.go index b32c6a8..a24d16d 100644 --- a/proxy/direct.go +++ b/proxy/direct.go @@ -45,8 +45,8 @@ type directPacketConn struct { } func (pc *directPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { - if m, ok := addr.(*M.Metadata); ok && m.DstIP != nil { - return pc.PacketConn.WriteTo(b, m.UDPAddr()) + if ma, ok := addr.(*M.Addr); ok && ma.Metadata().DstIP != nil { + return pc.PacketConn.WriteTo(b, ma.Metadata().UDPAddr()) } udpAddr, err := net.ResolveUDPAddr("udp", addr.String()) diff --git a/proxy/shadowsocks.go b/proxy/shadowsocks.go index bdea185..964a08e 100644 --- a/proxy/shadowsocks.go +++ b/proxy/shadowsocks.go @@ -88,8 +88,8 @@ type ssPacketConn struct { func (pc *ssPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { var packet []byte - if m, ok := addr.(*M.Metadata); ok { - packet, err = socks5.EncodeUDPPacket(m.SerializeSocksAddr(), b) + if ma, ok := addr.(*M.Addr); ok { + packet, err = socks5.EncodeUDPPacket(ma.Metadata().SerializeSocksAddr(), b) } else { packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) } diff --git a/proxy/socks5.go b/proxy/socks5.go index d1bed8b..3d89955 100644 --- a/proxy/socks5.go +++ b/proxy/socks5.go @@ -141,8 +141,8 @@ type socksPacketConn struct { func (pc *socksPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { var packet []byte - if m, ok := addr.(*M.Metadata); ok { - packet, err = socks5.EncodeUDPPacket(m.SerializeSocksAddr(), b) + if ma, ok := addr.(*M.Addr); ok { + packet, err = socks5.EncodeUDPPacket(ma.Metadata().SerializeSocksAddr(), b) } else { packet, err = socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) } diff --git a/tunnel/tcp.go b/tunnel/tcp.go index 1c3c38e..792c738 100644 --- a/tunnel/tcp.go +++ b/tunnel/tcp.go @@ -30,7 +30,7 @@ func handleTCPConn(localConn core.TCPConn) { dstIP, dstPort = parseAddr(localConn.LocalAddr()) ) metadata := &M.Metadata{ - Net: M.TCP, + Network: M.TCP, SrcIP: srcIP, SrcPort: srcPort, DstIP: dstIP, diff --git a/tunnel/udp.go b/tunnel/udp.go index 9017e46..3d44cf4 100644 --- a/tunnel/udp.go +++ b/tunnel/udp.go @@ -33,7 +33,7 @@ func handleUDPConn(uc core.UDPConn) { dstIP, dstPort = parseAddr(uc.LocalAddr()) ) metadata := &M.Metadata{ - Net: M.UDP, + Network: M.UDP, SrcIP: srcIP, SrcPort: srcPort, DstIP: dstIP, @@ -50,8 +50,9 @@ func handleUDPConn(uc core.UDPConn) { pc = newUDPTracker(pc, metadata) defer pc.Close() - go handleUDPToRemote(uc, pc, metadata) - handleUDPToLocal(uc, pc, metadata) + remote := metadata.Addr() + go handleUDPToRemote(uc, pc, remote) + handleUDPToLocal(uc, pc, remote) } func handleUDPToRemote(uc core.UDPConn, pc net.PacketConn, remote net.Addr) {