github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/testing/scenarios/socks_test.go (about) 1 package scenarios 2 3 import ( 4 "testing" 5 "time" 6 7 xproxy "golang.org/x/net/proxy" 8 "google.golang.org/protobuf/types/known/anypb" 9 socks4 "h12.io/socks" 10 11 core "github.com/v2fly/v2ray-core/v5" 12 "github.com/v2fly/v2ray-core/v5/app/proxyman" 13 "github.com/v2fly/v2ray-core/v5/app/router" 14 "github.com/v2fly/v2ray-core/v5/common" 15 "github.com/v2fly/v2ray-core/v5/common/net" 16 "github.com/v2fly/v2ray-core/v5/common/protocol" 17 "github.com/v2fly/v2ray-core/v5/common/serial" 18 "github.com/v2fly/v2ray-core/v5/proxy/blackhole" 19 "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" 20 "github.com/v2fly/v2ray-core/v5/proxy/freedom" 21 "github.com/v2fly/v2ray-core/v5/proxy/socks" 22 "github.com/v2fly/v2ray-core/v5/testing/servers/tcp" 23 "github.com/v2fly/v2ray-core/v5/testing/servers/udp" 24 ) 25 26 func TestSocksBridgeTCP(t *testing.T) { 27 tcpServer := tcp.Server{ 28 MsgProcessor: xor, 29 } 30 dest, err := tcpServer.Start() 31 common.Must(err) 32 defer tcpServer.Close() 33 34 serverPort := tcp.PickPort() 35 serverConfig := &core.Config{ 36 Inbound: []*core.InboundHandlerConfig{ 37 { 38 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 39 PortRange: net.SinglePortRange(serverPort), 40 Listen: net.NewIPOrDomain(net.LocalHostIP), 41 }), 42 ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{ 43 AuthType: socks.AuthType_PASSWORD, 44 Accounts: map[string]string{ 45 "Test Account": "Test Password", 46 }, 47 Address: net.NewIPOrDomain(net.LocalHostIP), 48 UdpEnabled: false, 49 }), 50 }, 51 }, 52 Outbound: []*core.OutboundHandlerConfig{ 53 { 54 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 55 }, 56 }, 57 } 58 59 clientPort := tcp.PickPort() 60 clientConfig := &core.Config{ 61 Inbound: []*core.InboundHandlerConfig{ 62 { 63 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 64 PortRange: net.SinglePortRange(clientPort), 65 Listen: net.NewIPOrDomain(net.LocalHostIP), 66 }), 67 ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ 68 Address: net.NewIPOrDomain(dest.Address), 69 Port: uint32(dest.Port), 70 NetworkList: &net.NetworkList{ 71 Network: []net.Network{net.Network_TCP}, 72 }, 73 }), 74 }, 75 }, 76 Outbound: []*core.OutboundHandlerConfig{ 77 { 78 ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{ 79 Server: []*protocol.ServerEndpoint{ 80 { 81 Address: net.NewIPOrDomain(net.LocalHostIP), 82 Port: uint32(serverPort), 83 User: []*protocol.User{ 84 { 85 Account: serial.ToTypedMessage(&socks.Account{ 86 Username: "Test Account", 87 Password: "Test Password", 88 }), 89 }, 90 }, 91 }, 92 }, 93 }), 94 }, 95 }, 96 } 97 98 servers, err := InitializeServerConfigs(serverConfig, clientConfig) 99 common.Must(err) 100 defer CloseAllServers(servers) 101 102 if err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil { 103 t.Error(err) 104 } 105 } 106 107 func TestSocksBridageUDP(t *testing.T) { 108 udpServer := udp.Server{ 109 MsgProcessor: xor, 110 } 111 dest, err := udpServer.Start() 112 common.Must(err) 113 defer udpServer.Close() 114 115 serverPort := tcp.PickPort() 116 serverConfig := &core.Config{ 117 Inbound: []*core.InboundHandlerConfig{ 118 { 119 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 120 PortRange: net.SinglePortRange(serverPort), 121 Listen: net.NewIPOrDomain(net.LocalHostIP), 122 }), 123 ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{ 124 AuthType: socks.AuthType_PASSWORD, 125 Accounts: map[string]string{ 126 "Test Account": "Test Password", 127 }, 128 Address: net.NewIPOrDomain(net.LocalHostIP), 129 UdpEnabled: true, 130 }), 131 }, 132 }, 133 Outbound: []*core.OutboundHandlerConfig{ 134 { 135 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 136 }, 137 }, 138 } 139 140 clientPort := tcp.PickPort() 141 clientConfig := &core.Config{ 142 Inbound: []*core.InboundHandlerConfig{ 143 { 144 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 145 PortRange: net.SinglePortRange(clientPort), 146 Listen: net.NewIPOrDomain(net.LocalHostIP), 147 }), 148 ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ 149 Address: net.NewIPOrDomain(dest.Address), 150 Port: uint32(dest.Port), 151 NetworkList: &net.NetworkList{ 152 Network: []net.Network{net.Network_TCP, net.Network_UDP}, 153 }, 154 }), 155 }, 156 }, 157 Outbound: []*core.OutboundHandlerConfig{ 158 { 159 ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{ 160 Server: []*protocol.ServerEndpoint{ 161 { 162 Address: net.NewIPOrDomain(net.LocalHostIP), 163 Port: uint32(serverPort), 164 User: []*protocol.User{ 165 { 166 Account: serial.ToTypedMessage(&socks.Account{ 167 Username: "Test Account", 168 Password: "Test Password", 169 }), 170 }, 171 }, 172 }, 173 }, 174 }), 175 }, 176 }, 177 } 178 179 servers, err := InitializeServerConfigs(serverConfig, clientConfig) 180 common.Must(err) 181 defer CloseAllServers(servers) 182 183 if err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil { 184 t.Error(err) 185 } 186 } 187 188 func TestSocksBridageUDPWithRouting(t *testing.T) { 189 udpServer := udp.Server{ 190 MsgProcessor: xor, 191 } 192 dest, err := udpServer.Start() 193 common.Must(err) 194 defer udpServer.Close() 195 196 serverPort := tcp.PickPort() 197 serverConfig := &core.Config{ 198 App: []*anypb.Any{ 199 serial.ToTypedMessage(&router.Config{ 200 Rule: []*router.RoutingRule{ 201 { 202 TargetTag: &router.RoutingRule_Tag{ 203 Tag: "out", 204 }, 205 InboundTag: []string{"socks"}, 206 }, 207 }, 208 }), 209 }, 210 Inbound: []*core.InboundHandlerConfig{ 211 { 212 Tag: "socks", 213 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 214 PortRange: net.SinglePortRange(serverPort), 215 Listen: net.NewIPOrDomain(net.LocalHostIP), 216 }), 217 ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{ 218 AuthType: socks.AuthType_NO_AUTH, 219 Address: net.NewIPOrDomain(net.LocalHostIP), 220 UdpEnabled: true, 221 }), 222 }, 223 }, 224 Outbound: []*core.OutboundHandlerConfig{ 225 { 226 ProxySettings: serial.ToTypedMessage(&blackhole.Config{}), 227 }, 228 { 229 Tag: "out", 230 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 231 }, 232 }, 233 } 234 235 clientPort := tcp.PickPort() 236 clientConfig := &core.Config{ 237 Inbound: []*core.InboundHandlerConfig{ 238 { 239 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 240 PortRange: net.SinglePortRange(clientPort), 241 Listen: net.NewIPOrDomain(net.LocalHostIP), 242 }), 243 ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ 244 Address: net.NewIPOrDomain(dest.Address), 245 Port: uint32(dest.Port), 246 NetworkList: &net.NetworkList{ 247 Network: []net.Network{net.Network_TCP, net.Network_UDP}, 248 }, 249 }), 250 }, 251 }, 252 Outbound: []*core.OutboundHandlerConfig{ 253 { 254 ProxySettings: serial.ToTypedMessage(&socks.ClientConfig{ 255 Server: []*protocol.ServerEndpoint{ 256 { 257 Address: net.NewIPOrDomain(net.LocalHostIP), 258 Port: uint32(serverPort), 259 }, 260 }, 261 }), 262 }, 263 }, 264 } 265 266 servers, err := InitializeServerConfigs(serverConfig, clientConfig) 267 common.Must(err) 268 defer CloseAllServers(servers) 269 270 if err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil { 271 t.Error(err) 272 } 273 } 274 275 func TestSocksConformanceMod(t *testing.T) { 276 tcpServer := tcp.Server{ 277 MsgProcessor: xor, 278 } 279 dest, err := tcpServer.Start() 280 common.Must(err) 281 defer tcpServer.Close() 282 283 authPort := tcp.PickPort() 284 noAuthPort := tcp.PickPort() 285 serverConfig := &core.Config{ 286 Inbound: []*core.InboundHandlerConfig{ 287 { 288 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 289 PortRange: net.SinglePortRange(authPort), 290 Listen: net.NewIPOrDomain(net.LocalHostIP), 291 }), 292 ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{ 293 AuthType: socks.AuthType_PASSWORD, 294 Accounts: map[string]string{ 295 "Test Account": "Test Password", 296 }, 297 Address: net.NewIPOrDomain(net.LocalHostIP), 298 UdpEnabled: false, 299 }), 300 }, 301 { 302 ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ 303 PortRange: net.SinglePortRange(noAuthPort), 304 Listen: net.NewIPOrDomain(net.LocalHostIP), 305 }), 306 ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{ 307 AuthType: socks.AuthType_NO_AUTH, 308 Accounts: map[string]string{ 309 "Test Account": "Test Password", 310 }, 311 Address: net.NewIPOrDomain(net.LocalHostIP), 312 UdpEnabled: false, 313 }), 314 }, 315 }, 316 Outbound: []*core.OutboundHandlerConfig{ 317 { 318 ProxySettings: serial.ToTypedMessage(&freedom.Config{}), 319 }, 320 }, 321 } 322 323 servers, err := InitializeServerConfigs(serverConfig) 324 common.Must(err) 325 defer CloseAllServers(servers) 326 327 { 328 noAuthDialer, err := xproxy.SOCKS5("tcp", net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr(), nil, xproxy.Direct) 329 common.Must(err) 330 conn, err := noAuthDialer.Dial("tcp", dest.NetAddr()) 331 common.Must(err) 332 defer conn.Close() 333 334 if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil { 335 t.Error(err) 336 } 337 } 338 339 { 340 authDialer, err := xproxy.SOCKS5("tcp", net.TCPDestination(net.LocalHostIP, authPort).NetAddr(), &xproxy.Auth{User: "Test Account", Password: "Test Password"}, xproxy.Direct) 341 common.Must(err) 342 conn, err := authDialer.Dial("tcp", dest.NetAddr()) 343 common.Must(err) 344 defer conn.Close() 345 346 if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil { 347 t.Error(err) 348 } 349 } 350 351 { 352 dialer := socks4.Dial("socks4://" + net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr()) 353 conn, err := dialer("tcp", dest.NetAddr()) 354 common.Must(err) 355 defer conn.Close() 356 357 if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil { 358 t.Error(err) 359 } 360 } 361 362 { 363 dialer := socks4.Dial("socks4://" + net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr()) 364 conn, err := dialer("tcp", net.TCPDestination(net.LocalHostIP, tcpServer.Port).NetAddr()) 365 common.Must(err) 366 defer conn.Close() 367 368 if err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil { 369 t.Error(err) 370 } 371 } 372 }