public void Test_SecureConnection() { for (int i = 0; i < 8; i++) { TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000)); listener.Start(); var listenerAcceptSocket = listener.BeginAcceptSocket(null, null); TcpClient client = new TcpClient(); client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000)); var server = listener.EndAcceptSocket(listenerAcceptSocket); listener.Stop(); DigitalSignature clientDigitalSignature = null; DigitalSignature serverDigitalSignature = null; if (_random.Next(0, 100) < 50) { clientDigitalSignature = new DigitalSignature("NickName1", DigitalSignatureAlgorithm.Rsa2048_Sha256); } if (_random.Next(0, 100) < 50) { serverDigitalSignature = new DigitalSignature("NickName2", DigitalSignatureAlgorithm.Rsa2048_Sha256); } SecureConnectionVersion clientVersion; SecureConnectionVersion serverVersion; { clientVersion = SecureConnectionVersion.Version3; serverVersion = SecureConnectionVersion.Version3; } { //SecureConnectionVersion clientVersion = 0; //SecureConnectionVersion serverVersion = 0; //for (; ; ) //{ // switch (_random.Next(0, 3)) // { // case 0: // clientVersion = SecureConnectionVersion.Version2; // break; // case 1: // clientVersion = SecureConnectionVersion.Version3; // break; // case 2: // clientVersion = SecureConnectionVersion.Version2 | SecureConnectionVersion.Version3; // break; // } // switch (_random.Next(0, 3)) // { // case 0: // serverVersion = SecureConnectionVersion.Version2; // break; // case 1: // serverVersion = SecureConnectionVersion.Version3; // break; // case 2: // serverVersion = SecureConnectionVersion.Version2 | SecureConnectionVersion.Version3; // break; // } // if ((clientVersion & serverVersion) != 0) break; //} } //var TcpClient = new BaseConnection(client.Client, Test_Library_Net_Connection.MaxReceiveCount, _bufferManager); using (var secureClient = new SecureConnection(clientVersion, SecureConnectionType.Connect, new BaseConnection(new SocketCap(client.Client), null, Test_Library_Net_Connection.MaxReceiveCount, _bufferManager), clientDigitalSignature, _bufferManager)) using (var secureServer = new SecureConnection(serverVersion, SecureConnectionType.Accept, new BaseConnection(new SocketCap(server), null, Test_Library_Net_Connection.MaxReceiveCount, _bufferManager), serverDigitalSignature, _bufferManager)) { try { var clientConnectTask = secureClient.ConnectAsync(new TimeSpan(0, 0, 30)); var serverConnectTask = secureServer.ConnectAsync(new TimeSpan(0, 0, 30)); Task.WaitAll(clientConnectTask, serverConnectTask); if (clientDigitalSignature != null) { if (secureServer.Certificate.ToString() != clientDigitalSignature.ToString()) throw new Exception(); } if (serverDigitalSignature != null) { if (secureClient.Certificate.ToString() != serverDigitalSignature.ToString()) throw new Exception(); } using (MemoryStream stream = new MemoryStream()) { var buffer = new byte[1024 * 8]; _random.NextBytes(buffer); stream.Write(buffer, 0, buffer.Length); stream.Seek(0, SeekOrigin.Begin); var clientSendTask = secureClient.SendAsync(stream, new TimeSpan(0, 0, 30)); var serverReceiveTask = secureServer.ReceiveAsync(new TimeSpan(0, 0, 30)); Task.WaitAll(clientConnectTask, serverReceiveTask); using (var returnStream = serverReceiveTask.Result) { var buff2 = new byte[(int)returnStream.Length]; returnStream.Read(buff2, 0, buff2.Length); Assert.IsTrue(CollectionUtils.Equals(buffer, buff2), "SecureConnection #1"); } } using (MemoryStream stream = new MemoryStream()) { var buffer = new byte[1024 * 8]; _random.NextBytes(buffer); stream.Write(buffer, 0, buffer.Length); stream.Seek(0, SeekOrigin.Begin); var serverSendTask = secureServer.SendAsync(stream, new TimeSpan(0, 0, 30)); var clientReceiveTask = secureClient.ReceiveAsync(new TimeSpan(0, 0, 30)); Task.WaitAll(serverSendTask, clientReceiveTask); using (var returnStream = clientReceiveTask.Result) { var buff2 = new byte[(int)returnStream.Length]; returnStream.Read(buff2, 0, buff2.Length); Assert.IsTrue(CollectionUtils.Equals(buffer, buff2), "SecureConnection #2"); } } } catch (AggregateException e) { Assert.IsTrue(e.InnerException.GetType() == typeof(ConnectionException) && (clientVersion & serverVersion) == 0, "SecureConnection #Version test"); } } client.Close(); server.Close(); } }
public Connection AcceptConnection(out string uri, BandwidthLimit bandwidthLimit) { uri = null; List<IDisposable> garbages = new List<IDisposable>(); try { Connection connection = null; foreach (var type in (new int[] { 0, 1 }).Randomize()) { if (this.State == ManagerState.Stop) return null; if (type == 0) { lock (this.ThisLock) { foreach (var item in _tcpListeners) { if (item.Value.Pending()) { var socket = item.Value.AcceptTcpClient().Client; garbages.Add(socket); { var remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint; uri = string.Format("tcp:{0}:{1}", remoteEndPoint.Address, remoteEndPoint.Port); } if (!this.OnCheckUriEvent(uri)) { _blockedCount.Increment(); continue; } var cap = new SocketCap(socket); garbages.Add(cap); connection = new BaseConnection(cap, bandwidthLimit, _maxReceiveCount, _bufferManager); garbages.Add(connection); } } } } else if (type == 1) { // Overlay network var cap = this.OnAcceptCapEvent(out uri); if (cap == null) continue; garbages.Add(cap); connection = new BaseConnection(cap, bandwidthLimit, _maxReceiveCount, _bufferManager); garbages.Add(connection); } if (connection != null) break; } if (connection == null) return null; var secureConnection = new SecureConnection(SecureConnectionVersion.Version3, SecureConnectionType.Accept, 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; }
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; }