Inheritance: Connection, IThisLock
        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();
            }
        }
Example #2
0
        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;
        }
Example #3
0
        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;
        }