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

     1  package tun
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/Asutorufa/yuhaiin/pkg/log"
     7  	"github.com/Asutorufa/yuhaiin/pkg/net/netapi"
     8  	"github.com/Asutorufa/yuhaiin/pkg/protos/statistic"
     9  	"gvisor.dev/gvisor/pkg/tcpip"
    10  	"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
    11  	"gvisor.dev/gvisor/pkg/tcpip/header"
    12  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    13  	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
    14  	"gvisor.dev/gvisor/pkg/waiter"
    15  )
    16  
    17  func (t *tunServer) tcpForwarder() *tcp.Forwarder {
    18  	return tcp.NewForwarder(t.stack, defaultWndSize, maxConnAttempts, func(r *tcp.ForwarderRequest) {
    19  		wq := new(waiter.Queue)
    20  		id := r.ID()
    21  
    22  		ep, err := r.CreateEndpoint(wq)
    23  		if err != nil {
    24  			log.Error("create endpoint failed", "err", err)
    25  			r.Complete(true)
    26  			return
    27  		}
    28  		r.Complete(false)
    29  
    30  		if err = setSocketOptions(t.stack, ep); err != nil {
    31  			log.Error("set socket options failed", "err", err)
    32  		}
    33  
    34  		addr := netapi.ParseAddressPort(statistic.Type_tcp, id.LocalAddress.String(), netapi.ParsePort(id.LocalPort))
    35  		local := gonet.NewTCPConn(wq, ep)
    36  
    37  		_ = t.SendStream(&netapi.StreamMeta{
    38  			Source:      local.RemoteAddr(),
    39  			Destination: addr,
    40  			Src:         local,
    41  			Address:     addr,
    42  		})
    43  	})
    44  }
    45  
    46  const (
    47  	// defaultWndSize if set to zero, the default
    48  	// receive window buffer size is used instead.
    49  	defaultWndSize = 0
    50  
    51  	// maxConnAttempts specifies the maximum number
    52  	// of in-flight tcp connection attempts.
    53  	maxConnAttempts = 2 << 10
    54  
    55  	// tcpKeepaliveCount is the maximum number of
    56  	// TCP keep-alive probes to send before giving up
    57  	// and killing the connection if no response is
    58  	// obtained from the other end.
    59  	tcpKeepaliveCount = 9
    60  
    61  	// tcpKeepaliveIdle specifies the time a connection
    62  	// must remain idle before the first TCP keepalive
    63  	// packet is sent. Once this time is reached,
    64  	// tcpKeepaliveInterval option is used instead.
    65  	tcpKeepaliveIdle = 60 * time.Second
    66  
    67  	// tcpKeepaliveInterval specifies the interval
    68  	// time between sending TCP keepalive packets.
    69  	tcpKeepaliveInterval = 30 * time.Second
    70  )
    71  
    72  func setSocketOptions(s *stack.Stack, ep tcpip.Endpoint) tcpip.Error {
    73  	{ /* TCP keepalive options */
    74  		ep.SocketOptions().SetKeepAlive(true)
    75  
    76  		idle := tcpip.KeepaliveIdleOption(tcpKeepaliveIdle)
    77  		if err := ep.SetSockOpt(&idle); err != nil {
    78  			return err
    79  		}
    80  
    81  		interval := tcpip.KeepaliveIntervalOption(tcpKeepaliveInterval)
    82  		if err := ep.SetSockOpt(&interval); err != nil {
    83  			return err
    84  		}
    85  
    86  		if err := ep.SetSockOptInt(tcpip.KeepaliveCountOption, tcpKeepaliveCount); err != nil {
    87  			return err
    88  		}
    89  	}
    90  	{ /* TCP recv/send buffer size */
    91  		var ss tcpip.TCPSendBufferSizeRangeOption
    92  		if err := s.TransportProtocolOption(header.TCPProtocolNumber, &ss); err == nil {
    93  			ep.SocketOptions().SetReceiveBufferSize(int64(ss.Default), false)
    94  		}
    95  
    96  		var rs tcpip.TCPReceiveBufferSizeRangeOption
    97  		if err := s.TransportProtocolOption(header.TCPProtocolNumber, &rs); err == nil {
    98  			ep.SocketOptions().SetReceiveBufferSize(int64(rs.Default), false)
    99  		}
   100  	}
   101  	return nil
   102  }