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  }