/// <summary> /// Creates a remote TCP connection through a proxy server to the destination host on the destination port. /// </summary> /// <param name="destinationHost">Destination host name or IP address of the destination server.</param> /// <param name="destinationPort">Port number to connect to on the destination host.</param> /// <returns> /// Returns an open TcpClient object that can be used normally to communicate /// with the destination server /// </returns> /// <remarks> /// This method creates a connection to the proxy server and instructs the proxy server /// to make a pass through connection to the specified destination host on the specified /// port. /// </remarks> public override Socket Create(TimeSpan timeout) { try { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // determine which authentication method the client would like to use DetermineClientAuthMethod(); // negotiate which authentication methods are supported / accepted by the server NegotiateServerAuthMethod(); Socks5ProxyClient.CheckTimeout(stopwatch.Elapsed, timeout); // send a connect command to the proxy server for destination host and port SendCommand(SOCKS5_CMD_CONNECT, _destinationHost, _destinationPort); // return the open proxied tcp client object to the caller for normal use return(_tcpClient.Client); } catch (Exception ex) { throw new ProxyClientException(String.Format(CultureInfo.InvariantCulture, "Connection to proxy host {0} on port {1} failed.", ((System.Net.IPEndPoint)_tcpClient.Client.RemoteEndPoint).Address.ToString(), ((System.Net.IPEndPoint)_tcpClient.Client.RemoteEndPoint).Port.ToString()), ex); } }
public Connection CreateConnection(string uri, BandwidthLimit bandwidthLimit) { List<IDisposable> garbages = new List<IDisposable>(); try { Connection connection = null; if (connection == null) { // Overlay network var cap = this.OnCreateCapEvent(uri); if (cap == null) goto End; garbages.Add(cap); connection = new BaseConnection(cap, bandwidthLimit, _maxReceiveCount, _bufferManager); garbages.Add(connection); End: ; } if (connection == null) { ConnectionFilter connectionFilter = null; lock (this.ThisLock) { foreach (var filter in this.Filters) { if (filter.UriCondition.IsMatch(uri)) { if (filter.ConnectionType != ConnectionType.None) { connectionFilter = filter.Clone(); } break; } } } if (connectionFilter == null) return null; string scheme = null; string host = null; int port = -1; { var match = _regex.Match(uri); if (match.Success) { scheme = match.Groups[1].Value; host = match.Groups[2].Value; port = int.Parse(match.Groups[3].Value); } else { var match2 = _regex2.Match(uri); if (match2.Success) { scheme = match2.Groups[1].Value; host = match2.Groups[2].Value; port = 4050; } } } if (host == null) return null; IList<KeyValuePair<string, string>> options = null; if (!string.IsNullOrWhiteSpace(connectionFilter.Option)) { options = ClientManager.Decode(connectionFilter.Option).OfType<KeyValuePair<string, string>>().ToList(); } if (connectionFilter.ConnectionType == ConnectionType.Tcp) { var ipAddress = ClientManager.GetIpAddress(host); if (ipAddress == null) return null; host = ipAddress.ToString(); uri = string.Format("{0}:{1}:{2}", scheme, host, port); if (!this.OnCheckUriEvent(uri)) { return null; } #if !DEBUG // Check { Uri url = new Uri(string.Format("{0}://{1}:{2}", scheme, host, port)); if (url.HostNameType == UriHostNameType.IPv4) { if (IPAddress.Any.ToString() == ipAddress.ToString() || IPAddress.Loopback.ToString() == ipAddress.ToString() || IPAddress.Broadcast.ToString() == ipAddress.ToString()) { return null; } if (CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("10.0.0.0").GetAddressBytes()) >= 0 && CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("10.255.255.255").GetAddressBytes()) <= 0) { return null; } if (CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("172.16.0.0").GetAddressBytes()) >= 0 && CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("172.31.255.255").GetAddressBytes()) <= 0) { return null; } if (CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("127.0.0.0").GetAddressBytes()) >= 0 && CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("127.255.255.255").GetAddressBytes()) <= 0) { return null; } if (CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("192.168.0.0").GetAddressBytes()) >= 0 && CollectionUtilities.Compare(ipAddress.GetAddressBytes(), IPAddress.Parse("192.168.255.255").GetAddressBytes()) <= 0) { return null; } } else if (url.HostNameType == UriHostNameType.IPv6) { if (IPAddress.IPv6Any.ToString() == ipAddress.ToString() || IPAddress.IPv6Loopback.ToString() == ipAddress.ToString() || IPAddress.IPv6None.ToString() == ipAddress.ToString()) { return null; } if (ipAddress.ToString().ToLower().StartsWith("fe80:")) { return null; } } } #endif var socket = ClientManager.Connect(new IPEndPoint(ipAddress, port), new TimeSpan(0, 0, 10)); garbages.Add(socket); var cap = new SocketCap(socket); garbages.Add(cap); connection = new BaseConnection(cap, bandwidthLimit, _maxReceiveCount, _bufferManager); garbages.Add(connection); } else { if (!this.OnCheckUriEvent(uri)) { return null; } string proxyScheme = null; string proxyHost = null; int proxyPort = -1; { var match = _regex.Match(connectionFilter.ProxyUri); if (match.Success) { proxyScheme = match.Groups[1].Value; proxyHost = match.Groups[2].Value; proxyPort = int.Parse(match.Groups[3].Value); } else { var match2 = _regex2.Match(connectionFilter.ProxyUri); if (match2.Success) { proxyScheme = match2.Groups[1].Value; proxyHost = match2.Groups[2].Value; if (connectionFilter.ConnectionType == ConnectionType.Socks4Proxy || connectionFilter.ConnectionType == ConnectionType.Socks4aProxy || connectionFilter.ConnectionType == ConnectionType.Socks5Proxy) { proxyPort = 1080; } else if (connectionFilter.ConnectionType == ConnectionType.HttpProxy) { proxyPort = 80; } } } } if (proxyHost == null) return null; if (connectionFilter.ConnectionType == ConnectionType.Socks4Proxy || connectionFilter.ConnectionType == ConnectionType.Socks4aProxy || connectionFilter.ConnectionType == ConnectionType.Socks5Proxy || connectionFilter.ConnectionType == ConnectionType.HttpProxy) { var socket = ClientManager.Connect(new IPEndPoint(ClientManager.GetIpAddress(proxyHost), proxyPort), new TimeSpan(0, 0, 10)); garbages.Add(socket); ProxyClientBase proxy = null; if (connectionFilter.ConnectionType == ConnectionType.Socks4Proxy) { var user = (options != null) ? options.Where(n => n.Key.ToLower().StartsWith("user")).Select(n => n.Value).FirstOrDefault() : null; proxy = new Socks4ProxyClient(socket, user, host, port); } else if (connectionFilter.ConnectionType == ConnectionType.Socks4aProxy) { var user = (options != null) ? options.Where(n => n.Key.ToLower().StartsWith("user")).Select(n => n.Value).FirstOrDefault() : null; proxy = new Socks4aProxyClient(socket, user, host, port); } else if (connectionFilter.ConnectionType == ConnectionType.Socks5Proxy) { var user = (options != null) ? options.Where(n => n.Key.ToLower().StartsWith("user")).Select(n => n.Value).FirstOrDefault() : null; var pass = (options != null) ? options.Where(n => n.Key.ToLower().StartsWith("pass")).Select(n => n.Value).FirstOrDefault() : null; proxy = new Socks5ProxyClient(socket, user, pass, host, port); } else if (connectionFilter.ConnectionType == ConnectionType.HttpProxy) { proxy = new HttpProxyClient(socket, host, port); } var cap = new SocketCap(proxy.Create(new TimeSpan(0, 0, 30))); garbages.Add(cap); connection = new BaseConnection(cap, bandwidthLimit, _maxReceiveCount, _bufferManager); garbages.Add(connection); } } } if (connection == null) return null; var secureConnection = new SecureConnection(SecureConnectionVersion.Version3, SecureConnectionType.Connect, connection, null, _bufferManager); garbages.Add(secureConnection); secureConnection.Connect(new TimeSpan(0, 0, 30)); var compressConnection = new CompressConnection(secureConnection, _maxReceiveCount, _bufferManager); garbages.Add(compressConnection); compressConnection.Connect(new TimeSpan(0, 0, 10)); return compressConnection; } catch (Exception) { foreach (var item in garbages) { item.Dispose(); } } return null; }