private void PeerHandshakeReceived(bool succeeded, PeerMessage message, object state)
        {
            PeerId id = (PeerId)state;

            if (!succeeded)
            {
                CleanupSocket(id, "Handshaking failed");
                return;
            }

            try
            {
                message.Handle(id);

                // If there are any pending messages, send them otherwise set the queue
                // processing as finished.
                if (id.QueueLength > 0)
                {
                    id.ConnectionManager.ProcessQueue(id);
                }
                else
                {
                    id.ProcessingQueue = false;
                }

                PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id);
                // Alert the engine that there is a new usable connection
                id.TorrentManager.HandlePeerConnected(id, Direction.Outgoing);
            }
            catch (TorrentException ex)
            {
                CleanupSocket(id, ex.Message);
            }
        }
        private void MessageReceived(bool successful, PeerMessage message, object state)
        {
            PeerId id = (PeerId)state;

            if (!successful)
            {
                id.ConnectionManager.CleanupSocket(id, "Could not receive a message");
                return;
            }

            try
            {
                PeerMessageEventArgs e = new PeerMessageEventArgs(id.TorrentManager, (PeerMessage)message, Direction.Incoming, id);
                id.ConnectionManager.RaisePeerMessageTransferred(e);

                message.Handle(id);

                id.LastMessageReceived = DateTime.Now;
                PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id);
            }
            catch (TorrentException ex)
            {
                id.ConnectionManager.CleanupSocket(id, ex.Message);
            }
        }
示例#3
0
        void DownloadLogic(int counter)
        {
            // FIXME: Hardcoded 15kB/sec - is this ok?
            if ((DateTime.Now - manager.StartTime) > TimeSpan.FromSeconds(20))
            {
                foreach (string s in manager.Torrent.GetRightHttpSeeds)
                {
                    string peerId = "-WebSeed-";
                    peerId = peerId + (webseedCount++).ToString().PadLeft(20 - peerId.Length, '0');

                    Uri uri = new Uri(s);
                    // HACK: Don't want to add more than 10 same webseed (sometimes webseeds stuck)
                    if (manager.Peers.ConnectedPeers.FindAll(p => p.Uri.Host.Equals(uri.Host)).Count > 9)
                    {
                        continue;
                    }

                    // Dont' want to add more than 2 same webseed if current webseeds is active (speed more than 5Kbs.
                    if (manager.Peers.ConnectedPeers.FindAll(p => p.Uri.Host.Equals(uri.Host) &&
                                                             p.Monitor.DownloadSpeed > 5 * 1024
                                                             ).Count > 1
                        )
                    {
                        continue;
                    }

                    Peer           peer       = new Peer(peerId, uri);
                    PeerId         id         = new PeerId(peer, manager);
                    HttpConnection connection = new HttpConnection(new Uri(s));
                    connection.Manager = this.manager;
                    peer.IsSeeder      = true;
                    id.BitField.SetAll(true);
                    id.Encryptor    = new PlainTextEncryption();
                    id.Decryptor    = new PlainTextEncryption();
                    id.IsChoking    = false;
                    id.AmInterested = !manager.Complete;
                    id.Connection   = connection;
                    id.ClientApp    = new Software(id.PeerID);
                    manager.Peers.ConnectedPeers.Add(id);
                    manager.RaisePeerConnected(new PeerConnectionEventArgs(manager, id, Direction.Outgoing));
                    PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, Manager.DownloadLimiter, id.Monitor, id.TorrentManager, id.ConnectionManager.messageReceivedCallback, id);
                }
            }

            // Remove inactive peers we haven't heard from if we're downloading
            if (manager.State == TorrentState.Downloading && manager.lastCalledInactivePeerManager + TimeSpan.FromSeconds(5) < DateTime.Now)
            {
                manager.InactivePeerManager.TimePassed();
                manager.lastCalledInactivePeerManager = DateTime.Now;
            }

            // Now choke/unchoke peers; first instantiate the choke/unchoke manager if we haven't done so already
            if (manager.chokeUnchoker == null)
            {
                manager.chokeUnchoker = new ChokeUnchokeManager(manager, manager.Settings.MinimumTimeBetweenReviews, manager.Settings.PercentOfMaxRateToSkipReview);
            }
            manager.chokeUnchoker.UnchokeReview();
        }
示例#4
0
        void DownloadLogic(int counter)
        {
            // FIXME: Hardcoded 15kB/sec - is this ok?
            if ((DateTime.Now - manager.StartTime) > TimeSpan.FromMinutes(1) && manager.Monitor.DownloadSpeed < 15 * 1024)
            {
                foreach (string s in manager.Torrent.GetRightHttpSeeds)
                {
                    try
                    {
                        string peerId = "-WebSeed-";
                        peerId = peerId + (webseedCount++).ToString().PadLeft(20 - peerId.Length, '0');

                        Uri            uri        = new Uri(s);
                        Peer           peer       = new Peer(peerId, uri);
                        PeerId         id         = new PeerId(peer, manager);
                        HttpConnection connection = new HttpConnection(new Uri(s));
                        connection.Manager = this.manager;
                        peer.IsSeeder      = true;
                        id.BitField.SetAll(true);
                        id.Encryptor    = new PlainTextEncryption();
                        id.Decryptor    = new PlainTextEncryption();
                        id.IsChoking    = false;
                        id.AmInterested = !manager.Complete;
                        id.Connection   = connection;
                        id.ClientApp    = new Software(id.PeerID);
                        manager.Peers.ConnectedPeers.Add(id);
                        manager.RaisePeerConnected(new PeerConnectionEventArgs(manager, id, Direction.Outgoing));
                        PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, Manager.DownloadLimiter, id.Monitor, id.TorrentManager, id.ConnectionManager.messageReceivedCallback, id);
                    }
                    catch (UriFormatException)
                    {
                        logger.Info("Invalid web seed uri '{0}'", s);
                    }
                }

                // FIXME: In future, don't clear out this list. It may be useful to keep the list of HTTP seeds
                // Add a boolean or something so that we don't add them twice.
                manager.Torrent.GetRightHttpSeeds.Clear();
            }

            // Remove inactive peers we haven't heard from if we're downloading
            if (manager.State == TorrentState.Downloading && manager.lastCalledInactivePeerManager + TimeSpan.FromSeconds(5) < DateTime.Now)
            {
                manager.InactivePeerManager.TimePassed();
                manager.lastCalledInactivePeerManager = DateTime.Now;
            }

            // Now choke/unchoke peers; first instantiate the choke/unchoke manager if we haven't done so already
            if (manager.chokeUnchoker == null)
            {
                manager.chokeUnchoker = new ChokeUnchokeManager(manager, manager.Settings.MinimumTimeBetweenReviews, manager.Settings.PercentOfMaxRateToSkipReview);
            }
            manager.chokeUnchoker.UnchokeReview();
        }
        /// <summary>
        /// This method is called when the ClientEngine recieves a valid incoming connection
        /// </summary>
        /// <param name="result"></param>
        private void IncomingConnectionAccepted(bool succeeded, int count, object state)
        {
            PeerId id = (PeerId)state;

            try
            {
                if (!succeeded)
                {
                    var args = new PeerConnectionFailedEventArgs(id.TorrentManager, id.Peer, Direction.Incoming, "Incoming connection coult not be accepted");
                    id.TorrentManager.RaiseConnectionAttemptFailed(args);
                }

                bool maxAlreadyOpen = (OpenConnections >= this.MaxOpenConnections) || (id.TorrentManager.OpenConnections >= id.TorrentManager.Settings.MaxConnections);
                if (!succeeded || id.Peer.PeerId == engine.PeerId || maxAlreadyOpen)
                {
                    CleanupSocket(id, "Connection was not accepted");
                    return;
                }

                if (id.TorrentManager.Peers.ActivePeers.Contains(id.Peer))
                {
                    logger.Error("Already connected to peer {0}", id.Peer);
                    id.Connection.Dispose();
                    return;
                }

                logger.Info("Incoming connection fully accepted {0}, total {1}", id.Peer, OpenConnections);
                id.TorrentManager.Peers.AvailablePeers.Remove(id.Peer);
                id.TorrentManager.Peers.ActivePeers.Add(id.Peer);
                id.TorrentManager.Peers.ConnectedPeers.Add(id);
                id.WhenConnected = DateTime.Now;
                // Baseline the time the last block was received
                id.LastBlockReceived = DateTime.Now;

                id.TorrentManager.HandlePeerConnected(id, Direction.Incoming);

                // We've sent our handshake so begin our looping to receive incoming message
                PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id);
            }
            catch (Exception e)
            {
                CleanupSocket(id, e.Message);
            }
        }
示例#6
0
        public void InvalidMessage()
        {
            bool             success = true;
            ManualResetEvent handle  = new ManualResetEvent(false);

            Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(16)), 0, data, 0, 4);
            for (int i = 4; i < 16; i++)
            {
                data [i] = byte.MaxValue;
            }
            PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, (successful, count, state) => {
                success = successful;
                handle.Set();
            }, null);

            NetworkIO.EnqueueSend(Outgoing, data, 0, 20, null, null, null, delegate { }, null);
            Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(4)), "#Should have closed");;
            Assert.IsFalse(success, "#1");
        }
示例#7
0
        public void ReceiveTwoKeepAlives()
        {
            var message = new KeepAliveMessage();
            var buffer  = message.Encode();
            var handle  = new AutoResetEvent(false);

            NetworkIO.EnqueueSend(Outgoing, buffer, 0, buffer.Length, null, null, null, delegate { }, null);
            NetworkIO.EnqueueSend(Outgoing, buffer, 0, buffer.Length, null, null, null, delegate { }, null);

            AsyncMessageReceivedCallback callback = (s, m, state) => {
                if (s && m is KeepAliveMessage)
                {
                    handle.Set();
                }
            };

            PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, callback, null);
            Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(2)), "#Should receive first message");


            PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, callback, null);
            Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(2)), "#Should receive second message");
        }