/// <summary> /// Create a pass through connection to the specified destination host. /// </summary> /// <see cref="ISocks"></see> /// <param name="socket">The socket connected to the Socks Server</param> /// <param name="destination">The destination host and port where the Socks Server have to Connect</param> /// <param name="userId">User identification information</param> public void CreateTunnel(Socket socket, Models.Sockets.SocketAddress destination, string userId = "") { if (socket == null) { throw new ArgumentNullException(nameof(socket), $"{nameof(socket)} has to be not null"); } if (destination == null) { throw new ArgumentNullException(nameof(destination), $"{nameof(destination)} has to be not null"); } var msg = BuildRequestMessage(destination.Host, destination.Port, userId); socket.Send(msg); var response = new byte[8]; socket.Receive(response); if (response == null) { throw new ArgumentNullException(nameof(response), $"{nameof(response)} error"); } ValidateRequestMessageResponse(response); }
/// <summary> /// Create a pass through connection to the specified destination host. /// </summary> /// <see cref="ISocks"></see> /// <param name="socket">The socket connected to the Socks Server</param> /// <param name="destinationAddress">The destination host and port where the Socks Server have to Connect</param> /// <param name="proxyCredentials">The proxy credentials of the Socks Server</param> public void CreateTunnel(Socket socket, Models.Sockets.SocketAddress destination, Credential proxyCredentials) { if (socket == null) { throw new ArgumentNullException(nameof(socket), $"{nameof(socket)} has to be not null"); } if (destination == null) { throw new ArgumentNullException(nameof(destination), $"{nameof(destination)} has to be not null"); } var auth = proxyCredentials != null; var ngAuthMsg = BuildNeogtiateAuthenticationMessage(auth); socket.Send(ngAuthMsg); var ngAuthMsgByte = new byte[2]; if (socket.Receive(ngAuthMsgByte) != 2) { throw new Socks5Exception("Invalid response size. Negotiation message response for authentication must be 2 byte."); } VaidateNeogtiateAuthenticationMessageRespone(ngAuthMsgByte, auth); if (auth) { var authMsg = BuildAuthenticationMessage(proxyCredentials.Username, proxyCredentials.Password); socket.Send(authMsg); var authMsgByte = new byte[2]; if (socket.Receive(authMsgByte) != 2) { throw new Socks5Exception("Invalid response size. Authentication message response must be 2 byte."); } VaidateAuthenticationMessageRespone(authMsgByte); } var addressType = GetAddressType(destination.Host); var resolvedIp = destination.Host; if (addressType == SOCKS5_ADDRTYPE_DOMAIN_NAME && Resolver != null) { if (Resolver.TryResolve(destination.Host, out var ipAddress)) { resolvedIp = ipAddress.ToString(); } else { throw new Socks5Exception("Destination address unreachable."); } } var connectCmdMsg = BuildRequestMessage(SOCKS5_CMD_CONNECT, addressType, resolvedIp, destination.Port); socket.Send(connectCmdMsg); var connectCmdMsgByte = new byte[255]; var connectCmdMsgRecByte = socket.Receive(connectCmdMsgByte); ValidateRequestMessageResponse(connectCmdMsgRecByte, connectCmdMsgByte); }