github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/transport/fakeip/packet.go (about) 1 package fakeip 2 3 import ( 4 "github.com/sagernet/sing/common/buf" 5 M "github.com/sagernet/sing/common/metadata" 6 N "github.com/sagernet/sing/common/network" 7 ) 8 9 var _ N.PacketConn = (*NATPacketConn)(nil) 10 11 type NATPacketConn struct { 12 N.PacketConn 13 origin M.Socksaddr 14 destination M.Socksaddr 15 } 16 17 func NewNATPacketConn(conn N.PacketConn, origin M.Socksaddr, destination M.Socksaddr) *NATPacketConn { 18 return &NATPacketConn{ 19 PacketConn: conn, 20 origin: socksaddrWithoutPort(origin), 21 destination: socksaddrWithoutPort(destination), 22 } 23 } 24 25 func (c *NATPacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) { 26 destination, err = c.PacketConn.ReadPacket(buffer) 27 if socksaddrWithoutPort(destination) == c.origin { 28 destination = M.Socksaddr{ 29 Addr: c.destination.Addr, 30 Fqdn: c.destination.Fqdn, 31 Port: destination.Port, 32 } 33 } 34 return 35 } 36 37 func (c *NATPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { 38 if socksaddrWithoutPort(destination) == c.destination { 39 destination = M.Socksaddr{ 40 Addr: c.origin.Addr, 41 Fqdn: c.origin.Fqdn, 42 Port: destination.Port, 43 } 44 } 45 return c.PacketConn.WritePacket(buffer, destination) 46 } 47 48 func (c *NATPacketConn) Upstream() any { 49 return c.PacketConn 50 } 51 52 func socksaddrWithoutPort(destination M.Socksaddr) M.Socksaddr { 53 destination.Port = 0 54 return destination 55 }