public void AddPeer(ISyncPeer syncPeer) { var peers = AllPeers as List <PeerInfo>; peers.Add(new PeerInfo(syncPeer)); PeerAdded?.Invoke(this, EventArgs.Empty); }
protected virtual void OnPeerAdded(Peer peer) { PeerAdded?.Invoke(this, new PeerEventArgs() { IPAddress = peer.GetRemoteAddress().ToString(), Port = peer.GetRemotePort().ToString() }); }
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); } }
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); }
protected virtual void RaisePeerAdded(IFileTransferPeer peer) { PeerAdded?.Invoke(this, new FileTransferPeerEventArgs(peer)); }
internal void OnContactAdded(object sender, PeerEventArgs args) { PeerAdded.Raise(sender, args); }