/// <inheritdoc/> public void PeerConnected(IPEndPoint endpoint, DateTimeOffset peerConnectedAt) { PeerAddress peer = this.FindPeer(endpoint); peer?.SetConnected(peerConnectedAt); }
/// <inheritdoc/> public void PeerDiscoveredFrom(IPEndPoint endpoint, DateTime peerDiscoveredFrom) { PeerAddress peer = this.FindPeer(endpoint); peer?.SetDiscoveredFrom(peerDiscoveredFrom); }
public override async Task OnConnectAsync() { this.logger.LogTrace("()"); int peerSelectionFailed = 0; PeerAddress peer = null; while (!this.nodeLifetime.ApplicationStopping.IsCancellationRequested) { if (peerSelectionFailed > MaximumPeerSelectionAttempts) { peerSelectionFailed = 0; peer = null; this.logger.LogTrace("Peer selection failed, maximum amount of selection attempts reached."); break; } peer = this.peerAddressManager.PeerSelector.SelectPeer(); if (peer == null) { peerSelectionFailed++; continue; } if (!peer.Endpoint.Address.IsValid()) { this.logger.LogTrace("Peer selection failed, peer endpoint is not valid '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } // If the peer is already connected just continue. if (this.IsPeerConnected(peer.Endpoint)) { this.logger.LogTrace("Peer selection failed, peer is already connected '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } // If the peer exists in the -addnode collection don't // try and connect to it. var peerExistsInAddNode = this.ConnectionSettings.AddNode.Any(p => p.MapToIpv6().Match(peer.Endpoint)); if (peerExistsInAddNode) { this.logger.LogTrace("Peer selection failed, peer exists in -addnode args '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } // If the peer exists in the -connect collection don't // try and connect to it. var peerExistsInConnectNode = this.ConnectionSettings.Connect.Any(p => p.MapToIpv6().Match(peer.Endpoint)); if (peerExistsInConnectNode) { this.logger.LogTrace("Peer selection failed, peer exists in -connect args '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } break; } //If the peer selector returns nothing, we wait 2 seconds to //effectively override the connector's burst mode. if (peer == null) { this.logger.LogTrace("Peer selection failed, executing selection delay..."); await Task.Delay(2000, this.nodeLifetime.ApplicationStopping).ConfigureAwait(false); } else { await this.ConnectAsync(peer).ConfigureAwait(false); } this.logger.LogTrace("(-)"); }
/// <summary>Attempts to connect to a random peer.</summary> internal async Task ConnectAsync(PeerAddress peerAddress) { this.logger.LogTrace("({0}:'{1}')", nameof(peerAddress), peerAddress.Endpoint); if (this.selfEndpointTracker.IsSelf(peerAddress.Endpoint)) { this.logger.LogTrace("{0} is self. Therefore not connecting.", peerAddress.Endpoint); this.logger.LogTrace("(-)"); return; } // Connect if local, ip range filtering disabled or ip range filtering enabled and peer in a different group. if (peerAddress.Endpoint.Address.IsRoutable(false) && this.ConnectionSettings.IpRangeFiltering && this.PeerIsPartOfExistingGroup(peerAddress)) { this.logger.LogTrace("(-)[RANGE_FILTERED]"); return; } INetworkPeer peer = null; try { using (CancellationTokenSource timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this.nodeLifetime.ApplicationStopping)) { this.peerAddressManager.PeerAttempted(peerAddress.Endpoint, this.dateTimeProvider.GetUtcNow()); NetworkPeerConnectionParameters clonedConnectParamaters = this.CurrentParameters.Clone(); timeoutTokenSource.CancelAfter(5000); clonedConnectParamaters.ConnectCancellation = timeoutTokenSource.Token; peer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(peerAddress.Endpoint, clonedConnectParamaters, this.networkPeerDisposer).ConfigureAwait(false); await peer.VersionHandshakeAsync(this.Requirements, timeoutTokenSource.Token).ConfigureAwait(false); this.AddPeer(peer); } } catch (OperationCanceledException) { if (this.nodeLifetime.ApplicationStopping.IsCancellationRequested) { this.logger.LogDebug("Peer {0} connection canceled because application is stopping.", peerAddress.Endpoint); peer?.Disconnect("Application stopping"); } else { this.logger.LogDebug("Peer {0} connection timeout.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Connection timeout"); } } catch (NBitcoin.Protocol.ProtocolException) { this.logger.LogDebug("Handshake rejected by peer '{0}'.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while handshaking"); } catch (Exception exception) { this.logger.LogTrace("Exception occurred while connecting: {0}", exception.ToString()); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while connecting", exception); } this.logger.LogTrace("(-)"); }
/// <inheritdoc/> public override async Task OnConnectAsync() { int peerSelectionFailed = 0; PeerAddress peer = null; while (!this.NodeLifetime.ApplicationStopping.IsCancellationRequested) { if (peerSelectionFailed > MaximumPeerSelectionAttempts) { peerSelectionFailed = 0; peer = null; this.logger.LogTrace("Selection failed, maximum amount of selection attempts reached."); break; } peer = this.PeerAddressManager.PeerSelector.SelectPeer(); if (peer == null) { this.logger.LogTrace("Selection failed, selector returned nothing."); peerSelectionFailed++; continue; } if (!peer.Endpoint.Address.IsValid()) { this.logger.LogTrace("Selection failed, peer endpoint is not valid '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } // If the peer exists in the -addnode collection don't // try and connect to it. bool peerExistsInAddNode = this.ConnectionSettings.AddNode.Any(p => p.MapToIpv6().Match(peer.Endpoint)); if (peerExistsInAddNode) { this.logger.LogTrace("Selection failed, peer exists in -addnode args '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } // If the peer exists in the -connect collection don't // try and connect to it. bool peerExistsInConnectNode = this.ConnectionSettings.Connect.Any(p => p.MapToIpv6().Match(peer.Endpoint)); if (peerExistsInConnectNode) { this.logger.LogTrace("Selection failed, peer exists in -connect args '{0}'.", peer.Endpoint); peerSelectionFailed++; continue; } break; } // If the peer selector returns nothing, we wait 2 seconds to // effectively override the connector's initial connection interval. if (peer == null) { this.logger.LogTrace("Selection failed, executing selection delay."); await Task.Delay(2000, this.NodeLifetime.ApplicationStopping).ConfigureAwait(false); } else { // Connect if local, ip range filtering disabled or ip range filtering enabled and peer in a different group. if (peer.Endpoint.Address.IsRoutable(false) && this.ConnectionSettings.IpRangeFiltering && this.PeerIsPartOfExistingGroup(peer)) { this.logger.LogTrace("(-)[RANGE_FILTERED]"); return; } this.logger.LogDebug("Attempting connection to {0}.", peer.Endpoint); await this.ConnectAsync(peer).ConfigureAwait(false); } }
/// <inheritdoc/> public void PeerSeen(IPEndPoint endpoint, DateTime peerSeenAt) { PeerAddress peer = this.FindPeer(endpoint); peer?.SetLastSeen(peerSeenAt); }
/// <inheritdoc/> public void PeerHandshaked(IPEndPoint endpoint, DateTimeOffset peerHandshakedAt) { PeerAddress peer = this.FindPeer(endpoint); peer?.SetHandshaked(peerHandshakedAt); }
private bool IsBanned(PeerAddress peerAddress) { return(peerAddress.BanUntil > this.dateTimeProvider.GetUtcNow()); }
/// <summary>Attempts to connect to a random peer.</summary> public async Task ConnectAsync(PeerAddress peerAddress) { if (this.selfEndpointTracker.IsSelf(peerAddress.Endpoint)) { this.logger.LogDebug("Connect aborted: {0} is self.", peerAddress.Endpoint); return; } if (this.IsPeerConnected(peerAddress.Endpoint)) { this.logger.LogDebug("Connect aborted: {0} is already connected.", peerAddress.Endpoint); return; } if (peerAddress.IsBanned(this.dateTimeProvider.GetUtcNow())) { this.logger.LogDebug("Connect aborted: {0} is banned until {1}.", peerAddress.Endpoint, peerAddress.BanUntil); return; } INetworkPeer peer = null; try { using (CancellationTokenSource timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this.NodeLifetime.ApplicationStopping)) { this.PeerAddressManager.PeerAttempted(peerAddress.Endpoint, this.dateTimeProvider.GetUtcNow()); NetworkPeerConnectionParameters clonedConnectParamaters = this.CurrentParameters.Clone(); timeoutTokenSource.CancelAfter(5000); clonedConnectParamaters.ConnectCancellation = timeoutTokenSource.Token; peer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(peerAddress.Endpoint, clonedConnectParamaters, this.networkPeerDisposer).ConfigureAwait(false); await peer.VersionHandshakeAsync(this.Requirements, timeoutTokenSource.Token).ConfigureAwait(false); this.AddPeer(peer); } } catch (OperationCanceledException) { if (this.NodeLifetime.ApplicationStopping.IsCancellationRequested) { this.logger.LogDebug("Peer {0} connection canceled because application is stopping.", peerAddress.Endpoint); peer?.Disconnect("Application stopping"); } else { this.logger.LogDebug("Peer {0} connection timeout.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Connection timeout"); } } catch (NBitcoin.Protocol.ProtocolException) { this.logger.LogDebug("Handshake rejected by peer '{0}'.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while handshaking"); } catch (Exception exception) { this.logger.LogDebug("Exception occurred while connecting: {0}", exception is SocketException ? exception.Message : exception.ToString()); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while connecting", exception); } }