Exemplo n.º 1
0
        public void AddPeer(ISyncPeer syncPeer)
        {
            var peers = AllPeers as List <PeerInfo>;

            peers.Add(new PeerInfo(syncPeer));
            PeerAdded?.Invoke(this, EventArgs.Empty);
        }
Exemplo n.º 2
0
 protected virtual void OnPeerAdded(Peer peer)
 {
     PeerAdded?.Invoke(this, new PeerEventArgs()
     {
         IPAddress = peer.GetRemoteAddress().ToString(),
         Port      = peer.GetRemotePort().ToString()
     });
 }
Exemplo n.º 3
0
        void ProcessResponse(Socket socket, bool broadcastSocket)
        {
            if (mReadBuffer.Length < socket.Available)
            {
                mReadBuffer = new byte[(int)(1.2f * socket.Available)];
            }
            byte[] packet = mReadBuffer;

            EndPoint remoteEp = new IPEndPoint(0, 0);
            int      length   = 0;

            try
            {
                length = socket.ReceiveFrom(packet, ref remoteEp);
            }
            catch
            {
                // The remote computer can forcibly close the port, then we get the exception here
                return;
            }

            // Verify packet header is correct
            var ep = (IPEndPoint)remoteEp;

            if (ep.AddressFamily != AddressFamily.InterNetwork ||
                packet.Length < mHeader.Length ||
                length < mHeader.Length)
            {
                return;
            }
            for (int i = 0; i < mHeader.Length; i++)
            {
                if (mHeader[i] != packet[i])
                {
                    return;
                }
            }

            // Decode the beacon packet
            Info info;

            try
            {
                var ms = new MemoryStream(packet, mHeader.Length, length - mHeader.Length);
                info = (Info)mJsonSerializer.Deserialize(new StreamReader(ms), mInfo.GetType());
                if (info == null)
                {
                    throw new Exception("Invalid JSON received");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error decoding becon packet: " + ex.Message);
                return;
            }

            // Packet must contain a source ID to be valid
            if (info.SourceId == "")
            {
                return;
            }

            // Keep different entries for the same application even if the
            // packets come from different IP addresses, which is possible
            // when connected to multiple networks.
            // TBD: Maybe it would be better to have one entry per application
            //      with a list of IP addresses instead.
            string key = info.SourceId + ", " + ep.Address.ToString();
            Peer   peer;

            if (!mPeers.TryGetValue(key, out peer))
            {
                // Collect first contact info, even if NOP
                peer              = new Peer(key);
                mPeers[key]       = peer;
                peer.Info         = info;
                peer.EndPoint     = ep;
                peer.ThisBeacon   = info.SourceId == mSourceId;
                peer.TimeReceived = DateTime.Now;
                PeerAdded?.Invoke(peer);
            }

            // Save peer info (not as much if it's a NOP)
            peer.ThisBeacon   = info.SourceId == mSourceId;
            peer.TimeReceived = DateTime.Now;
            if (info.State == State.Nop)
            {
                return;
            }
            peer.Info     = info;
            peer.EndPoint = ep;

            // Send response to establish a connection
            if (info.State == State.Broadcast && !peer.ConnectionEstablished)
            {
                SendResponse(mSocketUnicast, ep, State.Ping);
            }

            // Do not allow P2P on the broadcast port
            if (broadcastSocket)
            {
                return;
            }

            // Continue conversation on unicast socket
            if (info.State == State.Ping)
            {
                SendResponse(mSocketUnicast, ep, State.Pong);
            }

            if (info.State == State.Pong)
            {
                SendResponse(mSocketUnicast, ep, State.Gong);
            }

            if ((info.State == State.Pong || info.State == State.Gong) && !peer.ConnectionEstablished)
            {
                peer.ConnectionEstablished = true;
                PeerConnectionEstablishedChanged?.Invoke(peer);
            }
            if (info.State == State.Exit && peer.ConnectionEstablished)
            {
                peer.ConnectionEstablished = false;
                PeerConnectionEstablishedChanged?.Invoke(peer);
            }
        }
Exemplo n.º 4
0
        private async Task ExecuteRefreshTask(RefreshTotalDiffTask refreshTotalDiffTask, CancellationToken token)
        {
            PeerInfo peerInfo = refreshTotalDiffTask.PeerInfo;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Requesting head block info from {peerInfo.SyncPeer.Node:s}");
            }

            ISyncPeer syncPeer                   = peerInfo.SyncPeer;
            var       getHeadHeaderTask          = peerInfo.SyncPeer.GetHeadBlockHeader(refreshTotalDiffTask.BlockHash ?? peerInfo.HeadHash, token);
            CancellationTokenSource delaySource  = new CancellationTokenSource();
            CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(delaySource.Token, token);
            Task delayTask       = Task.Delay(InitTimeout, linkedSource.Token);
            Task firstToComplete = await Task.WhenAny(getHeadHeaderTask, delayTask);

            await firstToComplete.ContinueWith(
                t =>
            {
                try
                {
                    if (firstToComplete.IsFaulted || firstToComplete == delayTask)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                        syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - timeout");
                    }
                    else if (firstToComplete.IsCanceled)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"InitPeerInfo canceled for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncCancelled : NodeStatsEventType.SyncInitCancelled);
                        token.ThrowIfCancellationRequested();
                    }
                    else
                    {
                        delaySource.Cancel();
                        BlockHeader header = getHeadHeaderTask.Result;
                        if (header == null)
                        {
                            if (_logger.IsDebug)
                            {
                                _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                            }

                            _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                            syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - null response");
                            return;
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Received head block info from {syncPeer.Node:c} with head block numer {header.Number}");
                        }
                        if (!peerInfo.IsInitialized)
                        {
                            _stats.ReportSyncEvent(syncPeer.Node, NodeStatsEventType.SyncInitCompleted);
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"REFRESH Updating header of {peerInfo} from {peerInfo.HeadNumber} to {header.Number}");
                        }

                        BlockHeader parent = _blockTree.FindHeader(header.ParentHash, BlockTreeLookupOptions.None);
                        if (parent != null)
                        {
                            UInt256 newTotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty;
                            if (newTotalDifficulty >= peerInfo.TotalDifficulty)
                            {
                                peerInfo.TotalDifficulty = newTotalDifficulty;
                                peerInfo.HeadNumber      = header.Number;
                                peerInfo.HeadHash        = header.Hash;
                            }
                        }
                        else if (header.Number > peerInfo.HeadNumber)
                        {
                            peerInfo.HeadNumber = header.Number;
                            peerInfo.HeadHash   = header.Hash;
                        }

                        peerInfo.IsInitialized = true;
                        foreach ((SyncPeerAllocation allocation, object _) in _replaceableAllocations)
                        {
                            if (allocation.Current == peerInfo)
                            {
                                allocation.Refresh();
                            }
                        }

                        _signals.Set();
                        PeerAdded?.Invoke(this, EventArgs.Empty);
                    }
                }
                finally
                {
                    linkedSource.Dispose();
                    delaySource.Dispose();
                }
            }, token);
        }
Exemplo n.º 5
0
 protected virtual void RaisePeerAdded(IFileTransferPeer peer)
 {
     PeerAdded?.Invoke(this, new FileTransferPeerEventArgs(peer));
 }
Exemplo n.º 6
0
 internal void OnContactAdded(object sender, PeerEventArgs args)
 {
     PeerAdded.Raise(sender, args);
 }