github.com/database64128/shadowsocks-go@v1.7.0/direct/tcp.go (about)

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