github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/tun/tun2socket/nat/tcp.go (about)

     1  package nat
     2  
     3  import (
     4  	"net"
     5  	"time"
     6  
     7  	"github.com/Asutorufa/yuhaiin/pkg/net/dialer"
     8  	"gvisor.dev/gvisor/pkg/tcpip"
     9  )
    10  
    11  var (
    12  	loopback   = tcpip.AddrFrom4([4]byte{127, 0, 0, 1})
    13  	loopbackv6 = tcpip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
    14  )
    15  
    16  type TCP struct {
    17  	listener  *net.TCPListener
    18  	address   tcpip.Address
    19  	addressV6 tcpip.Address
    20  	portal    net.IP
    21  	portalv6  net.IP
    22  	table     *tableSplit
    23  }
    24  
    25  type Conn struct {
    26  	*net.TCPConn
    27  	tuple Tuple
    28  }
    29  
    30  func (t *TCP) Accept() (net.Conn, error) {
    31  	c, err := t.listener.AcceptTCP()
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	_ = c.SetWriteBuffer(dialer.SocketBufferSize)
    37  	_ = c.SetReadBuffer(dialer.SocketBufferSize)
    38  
    39  	addr := c.RemoteAddr().(*net.TCPAddr)
    40  
    41  	v6 := addr.IP.To4() == nil
    42  
    43  	var portal net.IP
    44  	if v6 {
    45  		portal = t.portalv6
    46  	} else {
    47  		portal = t.portal
    48  	}
    49  
    50  	tup := t.table.tupleOf(uint16(addr.Port), v6)
    51  
    52  	if !portal.Equal(addr.IP) || tup == zeroTuple {
    53  		_ = c.Close()
    54  
    55  		return nil, net.InvalidAddrError("unknown remote addr")
    56  	}
    57  
    58  	if tup.DestinationAddr.Len() == 4 && tup.DestinationAddr.Equal(t.address) {
    59  		tup.DestinationAddr = loopback
    60  	} else if tup.DestinationAddr.Equal(t.addressV6) {
    61  		tup.DestinationAddr = loopbackv6
    62  	}
    63  	/*
    64  			sys, err := c.SyscallConn()
    65  			if err == nil {
    66  				_ = sys.Control(func(fd uintptr) {
    67  					setSocketOptions(fd)
    68  				})
    69  			}
    70  
    71  			https://www.kernel.org/doc/Documentation/networking/udplite.txt
    72  		  	3) Disabling the Checksum Computation
    73  		  	On both sender and receiver, checksumming will always be performed
    74  		  	and cannot be disabled using SO_NO_CHECK. Thus
    75  		        setsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK,  ... );
    76  		  	will always will be ignored, while the value of
    77  		        getsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, &value, ...);
    78  		  	is meaningless (as in TCP). Packets with a zero checksum field are
    79  		  	illegal (cf. RFC 3828, sec. 3.1) and will be silently discarded.
    80  	*/
    81  
    82  	return &Conn{
    83  		TCPConn: c,
    84  		tuple:   tup,
    85  	}, nil
    86  }
    87  
    88  func (t *TCP) Close() error {
    89  	return t.listener.Close()
    90  }
    91  
    92  func (t *TCP) Addr() net.Addr {
    93  	return t.listener.Addr()
    94  }
    95  
    96  func (t *TCP) SetDeadline(time time.Time) error {
    97  	return t.listener.SetDeadline(time)
    98  }
    99  
   100  func (c *Conn) Close() error {
   101  	return c.TCPConn.Close()
   102  }
   103  
   104  func (c *Conn) LocalAddr() net.Addr {
   105  	return &net.TCPAddr{
   106  		IP:   net.IP(c.tuple.SourceAddr.AsSlice()),
   107  		Port: int(c.tuple.SourcePort),
   108  	}
   109  }
   110  
   111  func (c *Conn) RemoteAddr() net.Addr {
   112  	return &net.TCPAddr{
   113  		IP:   net.IP(c.tuple.DestinationAddr.AsSlice()),
   114  		Port: int(c.tuple.DestinationPort),
   115  	}
   116  }
   117  
   118  func (c *Conn) RawConn() (net.Conn, bool) { return c.TCPConn, true }