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 }