예제 #1
0
        // Called by the Session class for peers connecting through the server and in StartPeerConnectionThread() method for peers
        // connected to directly
        private void AddPeerPrivate(Sockets.Socket socket, Sockets.NetworkStream netStream, PeerInformation peerInformation)
        {
            try
            {
                if (Config.ActiveConfig.MaxPeersConnected < this.mPeers.Count)
                {
                    socket.Close();
                    return;
                }

                bool connect = true;

                if (Config.ActiveConfig.OnlyOneConnectionFromEachIP)
                {
                    foreach (Peer connectedPeer in this.mPeers)
                    {
                        if (connectedPeer.Information.IP.Equals(peerInformation.IP))
                        {
                            connect = false;
                            break;
                        }
                    }
                }

                if (!connect)
                {
                    socket.Close();
                    return;
                }

                if (!this.downloadFile.Bitfield.AllFalse)
                {
                    PeerProtocol.SendBitfieldMessage(netStream, this.downloadFile);
                }

                Peer peer = new Peer(this.infofile, this.downloadFile, socket, netStream, peerInformation);
                peer.Disconnected += new PeerDisconnectedCallback(peer_Disconnected);

                Config.LogDebugMessage("Connection accepted from: " + peer.ToString());

                // add to download and upload manager
                this.mDownloadStrategy.HookPeerEvents(peer);
                this.uploadManager.AddPeer(peer);
                this.peerManager.AddPeer(peer);

                if (this.PeerConnected != null)
                {
                    this.PeerConnected(this, peer, true);
                }

                this.mPeers.Add(peer);
            }
            catch (System.Exception e)
            {
                Config.LogException(e);
            }
        }
예제 #2
0
        /// <summary>
        /// Helper thread method to start the connection to peers
        /// </summary>
        /// <param name="state"></param>
        private void StartPeerConnectionThread(System.IAsyncResult result)
        {
            object[]        objs = (object[])result.AsyncState;
            Sockets.Socket  socket = (Sockets.Socket)objs[0];
            PeerInformation peerinfo = (PeerInformation)objs[1];
            ByteField20     infoDigest = new ByteField20(), peerId = new ByteField20();

            Sockets.NetworkStream netStream;

            try
            {
                socket.EndConnect(result);

                netStream = new Sockets.NetworkStream(socket, true);

                // send handshake info
                PeerProtocol.SendHandshake(netStream, this.infofile.InfoDigest);
                PeerProtocol.ReceiveHandshake(netStream, ref infoDigest);
                PeerProtocol.SendPeerId(netStream, this.mSession.LocalPeerID);

                if (!PeerProtocol.ReceivePeerId(netStream, ref peerId))
                {                 // NAT check
                    socket.Close();
                    return;
                }

                // check info digest matches and we are not attempting to connect to ourself
                if (infoDigest.Equals(this.infofile.InfoDigest) && !peerId.Equals(this.mSession.LocalPeerID))
                {
                    peerinfo.ID = peerId;
                    this.AddPeer(socket, netStream, peerinfo);
                }
                else                 // info digest doesn't match, close the connection
                {
                    socket.Close();
                }
            }
            catch (System.Exception e)
            {
                Config.LogException(e);
                // die if the connection failed
                if (socket != null)
                {
                    socket.Close();
                }
                return;
            }
        }
예제 #3
0
        private void OnAccept(System.IAsyncResult result)
        {
            Sockets.Socket socket;

            try
            {
                // Accept connections from other peers, find the appropriate torrent and add the peer to it
                socket = this.mListener.EndAccept(result);
            }
            catch (System.Exception)
            {
                if (this.mListener != null)
                {
                    this.mListener.Close();
                }
                this.mListener = null;
                return;
            }

            try
            {
                ByteField20           infoDigest = new ByteField20(), peerId = new ByteField20();
                Sockets.NetworkStream netStream = new Sockets.NetworkStream(socket, true);

                PeerProtocol.ReceiveHandshake(netStream, ref infoDigest);

                Torrent torrent = this.FindTorrent(infoDigest);

                if (torrent != null)
                {
                    // found it, finish handshaking and add the peer to the list
                    PeerProtocol.SendHandshake(netStream, torrent.Metainfo.InfoDigest);
                    PeerProtocol.SendPeerId(netStream, mLocalPeerId);

                    if (!PeerProtocol.ReceivePeerId(netStream, ref peerId))
                    {                     // NAT check, discard
                        socket.Close();
                    }
                    else
                    {
                        if (!peerId.Equals(mLocalPeerId))                             // make sure we aren't connecting to ourselves
                        {
                            Net.IPEndPoint  endPoint        = (Net.IPEndPoint)socket.RemoteEndPoint;
                            PeerInformation peerInformation = new PeerInformation(endPoint.Address.ToString(), endPoint.Port, peerId);

                            // add the peer to the torrent
                            torrent.AddPeer(socket, netStream, peerInformation);
                        }
                        else
                        {
                            socket.Close();
                        }
                    }
                }
                else
                {
                    socket.Close();
                }
            }
            catch (System.Exception e)
            {
                Config.LogException(e);
                socket.Close();
            }

            this.mListener.BeginAccept(new System.AsyncCallback(OnAccept), null);
        }