Inheritance: Connection, IThisLock
Esempio n. 1
0
        public override void Send(Stream stream, TimeSpan timeout, Information options)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (!_connect)
            {
                throw new ConnectionException();
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (stream.Length == 0)
            {
                throw new ArgumentOutOfRangeException("stream");
            }

            lock (_sendLock)
            {
                using (RangeStream targetStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true))
                {
                    try
                    {
                        _sendStopwatch.Restart();

                        Stream headerStream = new BufferStream(_bufferManager);
                        headerStream.Write(NetworkConverter.GetBytes((int)targetStream.Length), 0, 4);

                        byte[] sendBuffer = null;

                        try
                        {
                            sendBuffer = _bufferManager.TakeBuffer(1024 * 4);

                            using (Stream dataStream = new UniteStream(headerStream, new WrapperStream(targetStream, true)))
                            {
                                for (; ;)
                                {
                                    int sendLength = (int)Math.Min(dataStream.Length - dataStream.Position, sendBuffer.Length);
                                    if (sendLength == 0)
                                    {
                                        break;
                                    }

                                    if (_bandwidthLimit != null)
                                    {
                                        sendLength = _bandwidthLimit.GetOutBandwidth(this, sendLength);
                                        if (sendLength < 0)
                                        {
                                            throw new ConnectionException();
                                        }
                                    }

                                    dataStream.Read(sendBuffer, 0, sendLength);

                                    var time = BaseConnection.CheckTimeout(_sendStopwatch.Elapsed, timeout);
                                    time = (time < _sendTimeSpan) ? time : _sendTimeSpan;

                                    _cap.Send(sendBuffer, 0, sendLength, time);

                                    _aliveStopwatch.Restart();
                                    _sentByteCount.Add(sendLength);
                                }
                            }
                        }
                        finally
                        {
                            _bufferManager.ReturnBuffer(sendBuffer);
                        }

                        _aliveTimer.Change(1000 * 30);
                    }
                    catch (ConnectionException e)
                    {
                        throw e;
                    }
                    catch (Exception e)
                    {
                        throw new ConnectionException(e.Message, e);
                    }
                }
            }
        }
Esempio n. 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;
        }
Esempio n. 3
0
        public override Stream Receive(TimeSpan timeout, Information options)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (!_connect)
            {
                throw new ConnectionException();
            }

            lock (_receiveLock)
            {
                try
                {
                    _receiveStopwatch.Restart();

                    Restart :;

                    int length = 0;

                    {
                        byte[] lengthbuffer = new byte[4];

                        var time = BaseConnection.CheckTimeout(_receiveStopwatch.Elapsed, timeout);
                        time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan;

                        _cap.Receive(lengthbuffer, time);

                        _receivedByteCount.Add(4);

                        length = NetworkConverter.ToInt32(lengthbuffer);
                    }

                    if (length == 0)
                    {
                        Thread.Sleep(100);
                        goto Restart;
                    }
                    else if (length > _maxReceiveCount)
                    {
                        throw new ConnectionException();
                    }

                    BufferStream bufferStream = null;

                    try
                    {
                        bufferStream = new BufferStream(_bufferManager);
                        byte[] receiveBuffer = null;

                        try
                        {
                            receiveBuffer = _bufferManager.TakeBuffer(1024 * 4);

                            do
                            {
                                int receiveLength = Math.Min(receiveBuffer.Length, length);

                                if (_bandwidthLimit != null)
                                {
                                    receiveLength = _bandwidthLimit.GetInBandwidth(this, receiveLength);
                                    if (receiveLength < 0)
                                    {
                                        throw new ConnectionException();
                                    }
                                }

                                var time = BaseConnection.CheckTimeout(_receiveStopwatch.Elapsed, timeout);
                                time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan;

                                _cap.Receive(receiveBuffer, 0, receiveLength, time);

                                _receivedByteCount.Add(receiveLength);
                                bufferStream.Write(receiveBuffer, 0, receiveLength);

                                length -= receiveLength;
                            } while (length > 0);
                        }
                        finally
                        {
                            _bufferManager.ReturnBuffer(receiveBuffer);
                        }
                    }
                    catch (Exception e)
                    {
                        if (bufferStream != null)
                        {
                            bufferStream.Dispose();
                        }

                        throw e;
                    }

                    bufferStream.Seek(0, SeekOrigin.Begin);
                    return(bufferStream);
                }
                catch (ConnectionException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    throw new ConnectionException(e.Message, e);
                }
            }
        }
        public void Test_ConnectionManager()
        {
            for (int i = 0; i < 4; 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();

                var tcpClient = new BaseConnection(new SocketCap(client.Client), null, Test_Library_Net_Amoeba.MaxReceiveCount, _bufferManager);
                var tcpServer = new BaseConnection(new SocketCap(server), null, Test_Library_Net_Amoeba.MaxReceiveCount, _bufferManager);

                List<ConnectionManager> connectionManagers = new List<ConnectionManager>();

                {
                    ConnectionManager serverConnectionManager;
                    ConnectionManager clientConnectionManager;

                    Node serverNode = null;
                    Node clientNode = null;

                    byte[] serverSessionId = null;
                    byte[] clientSessionId = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        serverNode = new Node(id, uris);
                    }

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        clientNode = new Node(id, uris);
                    }

                    {
                        serverSessionId = new byte[32];
                        _random.NextBytes(serverSessionId);
                    }

                    {
                        clientSessionId = new byte[32];
                        _random.NextBytes(clientSessionId);
                    }

                    serverConnectionManager = new ConnectionManager(tcpServer, serverSessionId, serverNode, ConnectDirection.In, _bufferManager);
                    clientConnectionManager = new ConnectionManager(tcpClient, clientSessionId, clientNode, ConnectDirection.Out, _bufferManager);

                    Thread serverThread = new Thread(new ThreadStart(() =>
                    {
                        serverConnectionManager.Connect();
                    }));

                    Thread clientThread = new Thread(new ThreadStart(() =>
                    {
                        clientConnectionManager.Connect();
                    }));

                    serverThread.Start();
                    clientThread.Start();

                    serverThread.Join();
                    clientThread.Join();

                    Assert.IsTrue(CollectionUtilities.Equals(serverConnectionManager.SesstionId, clientSessionId), "ConnectionManager SessionId #1");
                    Assert.IsTrue(CollectionUtilities.Equals(clientConnectionManager.SesstionId, serverSessionId), "ConnectionManager SessionId #2");

                    Assert.AreEqual(serverConnectionManager.Node, clientNode, "ConnectionManager Node #1");
                    Assert.AreEqual(clientConnectionManager.Node, serverNode, "ConnectionManager Node #2");

                    connectionManagers.Add(serverConnectionManager);
                    connectionManagers.Add(clientConnectionManager);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullNodesEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullNodesEvent += (object sender, PullNodesEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    List<Node> nodes = new List<Node>();

                    for (int j = 0; j < 32; j++)
                    {
                        Node node = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);
                            var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                            node = new Node(id, uris);
                        }

                        nodes.Add(node);
                    }

                    senderConnection.PushNodes(nodes);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(nodes, item.Nodes), "ConnectionManager #1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksLinkEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksLinkEvent += (object sender, PullBlocksLinkEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(id, HashAlgorithm.Sha256);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksLink(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(keys, item.Keys), "ConnectionManager #2");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksRequestEvent += (object sender, PullBlocksRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(id, HashAlgorithm.Sha256);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksRequest(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(keys, item.Keys), "ConnectionManager #3");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlockEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlockEvent += (object sender, PullBlockEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var buffer = _bufferManager.TakeBuffer(1024 * 1024 * 8);
                    var key = new Key(Sha256.ComputeHash(buffer), HashAlgorithm.Sha256);

                    senderConnection.PushBlock(key, new ArraySegment<byte>(buffer, 0, 1024 * 1024 * 4));

                    var item = queue.Dequeue();
                    Assert.AreEqual(key, item.Key, "ConnectionManager #4.1");
                    Assert.IsTrue(CollectionUtilities.Equals(buffer, 0, item.Value.Array, item.Value.Offset, 1024 * 1024 * 4), "ConnectionManager #4.2");

                    _bufferManager.ReturnBuffer(buffer);
                    _bufferManager.ReturnBuffer(item.Value.Array);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullSeedsRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullSeedsRequestEvent += (object sender, PullSeedsRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var signatures = new SignatureCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        signatures.Add(digitalSignature.ToString());
                    }

                    senderConnection.PushSeedsRequest(signatures);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(signatures, item.Signatures), "ConnectionManager #5");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullSeedsEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullSeedsEvent += (object sender, PullSeedsEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    List<Seed> seeds = new List<Seed>();

                    for (int j = 0; j < 32; j++)
                    {
                        var seed = new Seed();
                        seed.Name = "aaaa.zip";
                        seed.Keywords.AddRange(new KeywordCollection
                        {
                            "bbbb",
                            "cccc",
                            "dddd",
                        });
                        seed.CreationTime = DateTime.Now;
                        seed.Length = 10000;
                        seed.Comment = "eeee";
                        seed.Rank = 1;
                        seed.Key = new Key(new byte[32], HashAlgorithm.Sha256);
                        seed.CompressionAlgorithm = CompressionAlgorithm.Xz;
                        seed.CryptoAlgorithm = CryptoAlgorithm.Aes256;
                        seed.CryptoKey = new byte[32 + 32];

                        seeds.Add(seed);
                    }

                    senderConnection.PushSeeds(seeds);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(seeds, item.Seeds), "ConnectionManager #6");
                }

                foreach (var connectionManager in connectionManagers)
                {
                    connectionManager.Dispose();
                }

                client.Close();
                server.Close();
            }
        }
        public void Test_ConnectionManager()
        {
            for (int i = 0; i < 4; 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();

                var tcpClient = new BaseConnection(new SocketCap(client.Client), null, Test_Library_Net_Amoeba.MaxReceiveCount, _bufferManager);
                var tcpServer = new BaseConnection(new SocketCap(server), null, Test_Library_Net_Amoeba.MaxReceiveCount, _bufferManager);

                List<ConnectionManager> connectionManagers = new List<ConnectionManager>();

                {
                    ConnectionManager serverConnectionManager;
                    ConnectionManager clientConnectionManager;

                    Node serverNode = null;
                    Node clientNode = null;

                    byte[] serverSessionId = null;
                    byte[] clientSessionId = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "tcp:localhost:9000", "tcp:localhost:9001", "tcp:localhost:9002" };

                        serverNode = new Node(id, uris);
                    }

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "tcp:localhost:9000", "tcp:localhost:9001", "tcp:localhost:9002" };

                        clientNode = new Node(id, uris);
                    }

                    {
                        serverSessionId = new byte[32];
                        _random.NextBytes(serverSessionId);
                    }

                    {
                        clientSessionId = new byte[32];
                        _random.NextBytes(clientSessionId);
                    }

                    serverConnectionManager = new ConnectionManager(tcpServer, serverSessionId, serverNode, ConnectDirection.In, _bufferManager);
                    clientConnectionManager = new ConnectionManager(tcpClient, clientSessionId, clientNode, ConnectDirection.Out, _bufferManager);

                    var serverTask = Task.Run(() => serverConnectionManager.Connect());
                    var clientTask = Task.Run(() => clientConnectionManager.Connect());

                    Task.WaitAll(serverTask, clientTask);

                    Assert.IsTrue(CollectionUtils.Equals(serverConnectionManager.SesstionId, clientSessionId), "ConnectionManager SessionId #1");
                    Assert.IsTrue(CollectionUtils.Equals(clientConnectionManager.SesstionId, serverSessionId), "ConnectionManager SessionId #2");

                    Assert.AreEqual(serverConnectionManager.Node, clientNode, "ConnectionManager Node #1");
                    Assert.AreEqual(clientConnectionManager.Node, serverNode, "ConnectionManager Node #2");

                    connectionManagers.Add(serverConnectionManager);
                    connectionManagers.Add(clientConnectionManager);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullNodesEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullNodesEvent += (object sender, PullNodesEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    List<Node> nodes = new List<Node>();

                    for (int j = 0; j < 32; j++)
                    {
                        Node node = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);
                            var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                            node = new Node(id, uris);
                        }

                        nodes.Add(node);
                    }

                    senderConnection.PushNodes(nodes);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(nodes, item.Nodes), "ConnectionManager #1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksLinkEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksLinkEvent += (object sender, PullBlocksLinkEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(HashAlgorithm.Sha256, id);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksLink(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(keys, item.Keys), "ConnectionManager #2");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksRequestEvent += (object sender, PullBlocksRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(HashAlgorithm.Sha256, id);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksRequest(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(keys, item.Keys), "ConnectionManager #3");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlockEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlockEvent += (object sender, PullBlockEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var buffer = _bufferManager.TakeBuffer(1024 * 1024 * 8);
                    var key = new Key(HashAlgorithm.Sha256, Sha256.ComputeHash(buffer));

                    senderConnection.PushBlock(key, new ArraySegment<byte>(buffer, 0, 1024 * 1024 * 4));

                    var item = queue.Dequeue();
                    Assert.AreEqual(key, item.Key, "ConnectionManager #4.1");
                    Assert.IsTrue(CollectionUtils.Equals(buffer, 0, item.Value.Array, item.Value.Offset, 1024 * 1024 * 4), "ConnectionManager #4.2");

                    _bufferManager.ReturnBuffer(buffer);
                    _bufferManager.ReturnBuffer(item.Value.Array);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBroadcastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBroadcastMetadatasRequestEvent += (object sender, PullBroadcastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.Rsa2048_Sha256);

                    var signatures = new SignatureCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        signatures.Add(digitalSignature.ToString());
                    }

                    senderConnection.PushBroadcastMetadatasRequest(signatures);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(signatures, item.Signatures), "ConnectionManager #5.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBroadcastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBroadcastMetadatasEvent += (object sender, PullBroadcastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.Rsa2048_Sha256);

                    var metadatas1 = new List<BroadcastMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var key = new Key(HashAlgorithm.Sha256, new byte[32]);
                        var metadata = new Metadata(1, key, CompressionAlgorithm.Xz, CryptoAlgorithm.Aes256, new byte[32 + 32]);
                        var broadcastMetadata = new BroadcastMetadata("Type", DateTime.UtcNow, metadata, digitalSignature);

                        metadatas1.Add(broadcastMetadata);
                    }

                    senderConnection.PushBroadcastMetadatas(metadatas1);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(metadatas1, item.BroadcastMetadatas), "ConnectionManager #6.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullUnicastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullUnicastMetadatasRequestEvent += (object sender, PullUnicastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.Rsa2048_Sha256);

                    var signatures = new SignatureCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        signatures.Add(digitalSignature.ToString());
                    }

                    senderConnection.PushUnicastMetadatasRequest(signatures);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(signatures, item.Signatures), "ConnectionManager #7.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullUnicastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullUnicastMetadatasEvent += (object sender, PullUnicastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.Rsa2048_Sha256);

                    var metadatas1 = new List<UnicastMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var key = new Key(HashAlgorithm.Sha256, new byte[32]);
                        var metadata = new Metadata(1, key, CompressionAlgorithm.Xz, CryptoAlgorithm.Aes256, new byte[32 + 32]);
                        var unicastMetadata = new UnicastMetadata("Type", digitalSignature.ToString(), DateTime.UtcNow, metadata, digitalSignature);

                        metadatas1.Add(unicastMetadata);
                    }

                    senderConnection.PushUnicastMetadatas(metadatas1);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(metadatas1, item.UnicastMetadatas), "ConnectionManager #8.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullMulticastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullMulticastMetadatasRequestEvent += (object sender, PullMulticastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var tags = new TagCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);

                        tags.Add(new Tag(RandomString.GetValue(256), id));
                    }

                    senderConnection.PushMulticastMetadatasRequest(tags);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(tags, item.Tags), "ConnectionManager #9.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullMulticastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullMulticastMetadatasEvent += (object sender, PullMulticastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.Rsa2048_Sha256);

                    var metadatas1 = new List<MulticastMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var key = new Key(HashAlgorithm.Sha256, new byte[32]);
                        var metadata = new Metadata(1, key, CompressionAlgorithm.Xz, CryptoAlgorithm.Aes256, new byte[32 + 32]);
                        var tag = new Tag("oooo", new byte[32]);
                        var miner = new Miner(CashAlgorithm.Version1, -1, TimeSpan.Zero);
                        var multicastMetadata = new MulticastMetadata("Type", tag, DateTime.UtcNow, metadata, miner, digitalSignature);

                        metadatas1.Add(multicastMetadata);
                    }

                    senderConnection.PushMulticastMetadatas(metadatas1);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtils.Equals(metadatas1, item.MulticastMetadatas), "ConnectionManager #10.1");
                }

                foreach (var connectionManager in connectionManagers)
                {
                    connectionManager.Dispose();
                }

                client.Close();
                server.Close();
            }
        }
        public void Test_ConnectionManager()
        {
            for (int i = 0; i < 4; 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();

                var tcpClient = new BaseConnection(new SocketCap(client.Client), null, Test_Library_Net_Outopos.MaxReceiveCount, _bufferManager);
                var tcpServer = new BaseConnection(new SocketCap(server), null, Test_Library_Net_Outopos.MaxReceiveCount, _bufferManager);

                List<ConnectionManager> connectionManagers = new List<ConnectionManager>();

                {
                    ConnectionManager serverConnectionManager;
                    ConnectionManager clientConnectionManager;

                    Node serverNode = null;
                    Node clientNode = null;

                    byte[] serverSessionId = null;
                    byte[] clientSessionId = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        serverNode = new Node(id, uris);
                    }

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        clientNode = new Node(id, uris);
                    }

                    {
                        serverSessionId = new byte[32];
                        _random.NextBytes(serverSessionId);
                    }

                    {
                        clientSessionId = new byte[32];
                        _random.NextBytes(clientSessionId);
                    }

                    serverConnectionManager = new ConnectionManager(tcpServer, serverSessionId, serverNode, ConnectDirection.In, _bufferManager);
                    clientConnectionManager = new ConnectionManager(tcpClient, clientSessionId, clientNode, ConnectDirection.Out, _bufferManager);

                    Thread serverThread = new Thread(new ThreadStart(() =>
                    {
                        serverConnectionManager.Connect();
                    }));

                    Thread clientThread = new Thread(new ThreadStart(() =>
                    {
                        clientConnectionManager.Connect();
                    }));

                    serverThread.Start();
                    clientThread.Start();

                    serverThread.Join();
                    clientThread.Join();

                    Assert.IsTrue(CollectionUtilities.Equals(serverConnectionManager.SesstionId, clientSessionId), "ConnectionManager SessionId #1");
                    Assert.IsTrue(CollectionUtilities.Equals(clientConnectionManager.SesstionId, serverSessionId), "ConnectionManager SessionId #2");

                    Assert.AreEqual(serverConnectionManager.Node, clientNode, "ConnectionManager Node #1");
                    Assert.AreEqual(clientConnectionManager.Node, serverNode, "ConnectionManager Node #2");

                    connectionManagers.Add(serverConnectionManager);
                    connectionManagers.Add(clientConnectionManager);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullNodesEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullNodesEvent += (object sender, PullNodesEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    List<Node> nodes = new List<Node>();

                    for (int j = 0; j < 32; j++)
                    {
                        Node node = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);
                            var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                            node = new Node(id, uris);
                        }

                        nodes.Add(node);
                    }

                    senderConnection.PushNodes(nodes);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(nodes, item.Nodes), "ConnectionManager #1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksLinkEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksLinkEvent += (object sender, PullBlocksLinkEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(id, HashAlgorithm.Sha256);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksLink(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(keys, item.Keys), "ConnectionManager #2");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlocksRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlocksRequestEvent += (object sender, PullBlocksRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var keys = new List<Key>();

                    for (int j = 0; j < 32; j++)
                    {
                        Key key = null;

                        {
                            var id = new byte[32];
                            _random.NextBytes(id);

                            key = new Key(id, HashAlgorithm.Sha256);
                        }

                        keys.Add(key);
                    }

                    senderConnection.PushBlocksRequest(keys);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(keys, item.Keys), "ConnectionManager #3");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBlockEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBlockEvent += (object sender, PullBlockEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var buffer = _bufferManager.TakeBuffer(1024 * 1024 * 8);
                    var key = new Key(Sha256.ComputeHash(buffer), HashAlgorithm.Sha256);

                    senderConnection.PushBlock(key, new ArraySegment<byte>(buffer, 0, 1024 * 1024 * 4));

                    var item = queue.Dequeue();
                    Assert.AreEqual(key, item.Key, "ConnectionManager #4.1");
                    Assert.IsTrue(CollectionUtilities.Equals(buffer, 0, item.Value.Array, item.Value.Offset, 1024 * 1024 * 4), "ConnectionManager #4.2");

                    _bufferManager.ReturnBuffer(buffer);
                    _bufferManager.ReturnBuffer(item.Value.Array);
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBroadcastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBroadcastMetadatasRequestEvent += (object sender, PullBroadcastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var signatures = new SignatureCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        signatures.Add(digitalSignature.ToString());
                    }

                    senderConnection.PushBroadcastMetadatasRequest(signatures);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(signatures, item.Signatures), "ConnectionManager #5.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullBroadcastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullBroadcastMetadatasEvent += (object sender, PullBroadcastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var metadatas1 = new List<ProfileMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);
                        var metadata = new ProfileMetadata(DateTime.UtcNow, key, digitalSignature);

                        metadatas1.Add(metadata);
                    }

                    senderConnection.PushBroadcastMetadatas(metadatas1);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(metadatas1, item.ProfileMetadatas), "ConnectionManager #6.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullUnicastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullUnicastMetadatasRequestEvent += (object sender, PullUnicastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var signatures = new SignatureCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        signatures.Add(digitalSignature.ToString());
                    }

                    senderConnection.PushUnicastMetadatasRequest(signatures);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(signatures, item.Signatures), "ConnectionManager #7.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullUnicastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullUnicastMetadatasEvent += (object sender, PullUnicastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var metadatas1 = new List<SignatureMessageMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);
                        var miner = new Miner(CashAlgorithm.Version1, -1, TimeSpan.Zero);
                        var metadata = new SignatureMessageMetadata(digitalSignature.ToString(), DateTime.UtcNow, key, miner, digitalSignature);

                        metadatas1.Add(metadata);
                    }

                    senderConnection.PushUnicastMetadatas(metadatas1);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(metadatas1, item.SignatureMessageMetadatas), "ConnectionManager #8.1");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullMulticastMetadatasRequestEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullMulticastMetadatasRequestEvent += (object sender, PullMulticastMetadatasRequestEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var wikis = new WikiCollection();
                    var chats = new ChatCollection();

                    for (int j = 0; j < 32; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);

                        wikis.Add(new Wiki(RandomString.GetValue(256), id));
                    }

                    for (int j = 0; j < 32; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);

                        chats.Add(new Chat(RandomString.GetValue(256), id));
                    }

                    senderConnection.PushMulticastMetadatasRequest(wikis, chats);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(wikis, item.Wikis), "ConnectionManager #9.1");
                    Assert.IsTrue(CollectionUtilities.Equals(chats, item.Chats), "ConnectionManager #9.2");
                }

                connectionManagers.Randomize();

                {
                    var queue = new WaitQueue<PullMulticastMetadatasEventArgs>();

                    var receiverConnection = connectionManagers[0];
                    var senderConnection = connectionManagers[1];

                    receiverConnection.PullMulticastMetadatasEvent += (object sender, PullMulticastMetadatasEventArgs e) =>
                    {
                        queue.Enqueue(e);
                    };

                    var digitalSignature = new DigitalSignature("123", DigitalSignatureAlgorithm.EcDsaP521_Sha256);

                    var metadatas1 = new List<WikiDocumentMetadata>();
                    var metadatas2 = new List<ChatTopicMetadata>();
                    var metadatas3 = new List<ChatMessageMetadata>();

                    for (int j = 0; j < 4; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);
                        var tag = new Wiki("oooo", new byte[32]);
                        var miner = new Miner(CashAlgorithm.Version1, -1, TimeSpan.Zero);
                        var metadata = new WikiDocumentMetadata(tag, DateTime.UtcNow, key, miner, digitalSignature);

                        metadatas1.Add(metadata);
                    }

                    for (int j = 0; j < 4; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);
                        var tag = new Chat("oooo", new byte[32]);
                        var miner = new Miner(CashAlgorithm.Version1, -1, TimeSpan.Zero);
                        var metadata = new ChatTopicMetadata(tag, DateTime.UtcNow, key, miner, digitalSignature);

                        metadatas2.Add(metadata);
                    }

                    for (int j = 0; j < 4; j++)
                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var key = new Key(id, HashAlgorithm.Sha256);
                        var tag = new Chat("oooo", new byte[32]);
                        var miner = new Miner(CashAlgorithm.Version1, -1, TimeSpan.Zero);
                        var metadata = new ChatMessageMetadata(tag, DateTime.UtcNow, key, miner, digitalSignature);

                        metadatas3.Add(metadata);
                    }

                    senderConnection.PushMulticastMetadatas(metadatas1, metadatas2, metadatas3);

                    var item = queue.Dequeue();
                    Assert.IsTrue(CollectionUtilities.Equals(metadatas1, item.WikiDocumentMetadatas), "ConnectionManager #10.1");
                    Assert.IsTrue(CollectionUtilities.Equals(metadatas2, item.ChatTopicMetadatas), "ConnectionManager #10.2");
                    Assert.IsTrue(CollectionUtilities.Equals(metadatas3, item.ChatMessageMetadatas), "ConnectionManager #10.3");
                }

                foreach (var connectionManager in connectionManagers)
                {
                    connectionManager.Dispose();
                }

                client.Close();
                server.Close();
            }
        }
        public void Test_BaseConnection()
        {
            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();

            using (var baseClient = new BaseConnection(new SocketCap(client.Client), null, Test_Library_Net_Connection.MaxReceiveCount, _bufferManager))
            using (var baseServer = new BaseConnection(new SocketCap(server), null, Test_Library_Net_Connection.MaxReceiveCount, _bufferManager))
            {
                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 = baseClient.SendAsync(stream, new TimeSpan(0, 0, 20));
                    var serverReceiveTask = baseServer.ReceiveAsync(new TimeSpan(0, 0, 20));

                    Task.WaitAll(clientSendTask, 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), "BaseConnection #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 = baseServer.SendAsync(stream, new TimeSpan(0, 0, 20));
                    var clientReceiveTask = baseClient.ReceiveAsync(new TimeSpan(0, 0, 20));

                    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), "BaseConnection #2");
                    }
                }
            }

            client.Close();
            server.Close();
        }
Esempio n. 8
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;
        }