github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/direct/tcp.go (about)

     1  package direct
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/database64128/shadowsocks-go/conn"
     7  	"github.com/database64128/shadowsocks-go/socks5"
     8  	"github.com/database64128/shadowsocks-go/zerocopy"
     9  )
    10  
    11  // TCPClient implements the zerocopy TCPClient interface.
    12  type TCPClient struct {
    13  	name    string
    14  	network string
    15  	dialer  conn.Dialer
    16  }
    17  
    18  func NewTCPClient(name, network string, dialer conn.Dialer) *TCPClient {
    19  	return &TCPClient{
    20  		name:    name,
    21  		network: network,
    22  		dialer:  dialer,
    23  	}
    24  }
    25  
    26  // Info implements the zerocopy.TCPClient Info method.
    27  func (c *TCPClient) Info() zerocopy.TCPClientInfo {
    28  	return zerocopy.TCPClientInfo{
    29  		Name:                 c.name,
    30  		NativeInitialPayload: !c.dialer.DisableTFO,
    31  	}
    32  }
    33  
    34  // Dial implements the zerocopy.TCPClient Dial method.
    35  func (c *TCPClient) Dial(ctx context.Context, targetAddr conn.Addr, payload []byte) (rawRW zerocopy.DirectReadWriteCloser, rw zerocopy.ReadWriter, err error) {
    36  	rawRW, err = c.dialer.DialTCP(ctx, c.network, targetAddr.String(), payload)
    37  	if err != nil {
    38  		return
    39  	}
    40  	rw = &DirectStreamReadWriter{rw: rawRW}
    41  	return
    42  }
    43  
    44  // TCPServer is the client-side tunnel server.
    45  //
    46  // TCPServer implements the zerocopy TCPServer interface.
    47  type TCPServer struct {
    48  	targetAddr conn.Addr
    49  }
    50  
    51  func NewTCPServer(targetAddr conn.Addr) *TCPServer {
    52  	return &TCPServer{
    53  		targetAddr: targetAddr,
    54  	}
    55  }
    56  
    57  // Info implements the zerocopy.TCPServer Info method.
    58  func (s *TCPServer) Info() zerocopy.TCPServerInfo {
    59  	return zerocopy.TCPServerInfo{
    60  		NativeInitialPayload: false,
    61  		DefaultTCPConnCloser: zerocopy.JustClose,
    62  	}
    63  }
    64  
    65  // Accept implements the zerocopy.TCPServer Accept method.
    66  func (s *TCPServer) Accept(rawRW zerocopy.DirectReadWriteCloser) (rw zerocopy.ReadWriter, targetAddr conn.Addr, payload []byte, username string, err error) {
    67  	return &DirectStreamReadWriter{rw: rawRW}, s.targetAddr, nil, "", nil
    68  }
    69  
    70  // ShadowsocksNoneTCPClient implements the zerocopy TCPClient interface.
    71  type ShadowsocksNoneTCPClient struct {
    72  	name string
    73  	tco  *zerocopy.TCPConnOpener
    74  }
    75  
    76  func NewShadowsocksNoneTCPClient(name, network, address string, dialer conn.Dialer) *ShadowsocksNoneTCPClient {
    77  	return &ShadowsocksNoneTCPClient{
    78  		name: name,
    79  		tco:  zerocopy.NewTCPConnOpener(dialer, network, address),
    80  	}
    81  }
    82  
    83  // Info implements the zerocopy.TCPClient Info method.
    84  func (c *ShadowsocksNoneTCPClient) Info() zerocopy.TCPClientInfo {
    85  	return zerocopy.TCPClientInfo{
    86  		Name:                 c.name,
    87  		NativeInitialPayload: true,
    88  	}
    89  }
    90  
    91  // Dial implements the zerocopy.TCPClient Dial method.
    92  func (c *ShadowsocksNoneTCPClient) Dial(ctx context.Context, targetAddr conn.Addr, payload []byte) (rawRW zerocopy.DirectReadWriteCloser, rw zerocopy.ReadWriter, err error) {
    93  	rw, rawRW, err = NewShadowsocksNoneStreamClientReadWriter(ctx, c.tco, targetAddr, payload)
    94  	return
    95  }
    96  
    97  // ShadowsocksNoneTCPServer implements the zerocopy TCPServer interface.
    98  type ShadowsocksNoneTCPServer struct{}
    99  
   100  func NewShadowsocksNoneTCPServer() ShadowsocksNoneTCPServer {
   101  	return ShadowsocksNoneTCPServer{}
   102  }
   103  
   104  // Info implements the zerocopy.TCPServer Info method.
   105  func (ShadowsocksNoneTCPServer) Info() zerocopy.TCPServerInfo {
   106  	return zerocopy.TCPServerInfo{
   107  		NativeInitialPayload: false,
   108  		DefaultTCPConnCloser: zerocopy.JustClose,
   109  	}
   110  }
   111  
   112  // Accept implements the zerocopy.TCPServer Accept method.
   113  func (ShadowsocksNoneTCPServer) Accept(rawRW zerocopy.DirectReadWriteCloser) (rw zerocopy.ReadWriter, targetAddr conn.Addr, payload []byte, username string, err error) {
   114  	rw, targetAddr, err = NewShadowsocksNoneStreamServerReadWriter(rawRW)
   115  	return
   116  }
   117  
   118  // Socks5TCPClient implements the zerocopy TCPClient interface.
   119  type Socks5TCPClient struct {
   120  	name    string
   121  	network string
   122  	address string
   123  	dialer  conn.Dialer
   124  }
   125  
   126  func NewSocks5TCPClient(name, network, address string, dialer conn.Dialer) *Socks5TCPClient {
   127  	return &Socks5TCPClient{
   128  		name:    name,
   129  		network: network,
   130  		address: address,
   131  		dialer:  dialer,
   132  	}
   133  }
   134  
   135  // Info implements the zerocopy.TCPClient Info method.
   136  func (c *Socks5TCPClient) Info() zerocopy.TCPClientInfo {
   137  	return zerocopy.TCPClientInfo{
   138  		Name:                 c.name,
   139  		NativeInitialPayload: false,
   140  	}
   141  }
   142  
   143  // Dial implements the zerocopy.TCPClient Dial method.
   144  func (c *Socks5TCPClient) Dial(ctx context.Context, targetAddr conn.Addr, payload []byte) (rawRW zerocopy.DirectReadWriteCloser, rw zerocopy.ReadWriter, err error) {
   145  	rawRW, err = c.dialer.DialTCP(ctx, c.network, c.address, nil)
   146  	if err != nil {
   147  		return
   148  	}
   149  
   150  	rw, err = NewSocks5StreamClientReadWriter(rawRW, targetAddr)
   151  	if err != nil {
   152  		rawRW.Close()
   153  		return
   154  	}
   155  
   156  	if len(payload) > 0 {
   157  		if _, err = rw.WriteZeroCopy(payload, 0, len(payload)); err != nil {
   158  			rawRW.Close()
   159  		}
   160  	}
   161  	return
   162  }
   163  
   164  // Socks5TCPServer implements the zerocopy TCPServer interface.
   165  type Socks5TCPServer struct {
   166  	enableTCP bool
   167  	enableUDP bool
   168  }
   169  
   170  func NewSocks5TCPServer(enableTCP, enableUDP bool) *Socks5TCPServer {
   171  	return &Socks5TCPServer{
   172  		enableTCP: enableTCP,
   173  		enableUDP: enableUDP,
   174  	}
   175  }
   176  
   177  // Info implements the zerocopy.TCPServer Info method.
   178  func (s *Socks5TCPServer) Info() zerocopy.TCPServerInfo {
   179  	return zerocopy.TCPServerInfo{
   180  		NativeInitialPayload: false,
   181  		DefaultTCPConnCloser: zerocopy.JustClose,
   182  	}
   183  }
   184  
   185  // Accept implements the zerocopy.TCPServer Accept method.
   186  func (s *Socks5TCPServer) Accept(rawRW zerocopy.DirectReadWriteCloser) (rw zerocopy.ReadWriter, targetAddr conn.Addr, payload []byte, username string, err error) {
   187  	rw, targetAddr, err = NewSocks5StreamServerReadWriter(rawRW, s.enableTCP, s.enableUDP)
   188  	if err == socks5.ErrUDPAssociateDone {
   189  		err = zerocopy.ErrAcceptDoneNoRelay
   190  	}
   191  	return
   192  }