コード例 #1
0
ファイル: Node.cs プロジェクト: RupeshDada/NBitcoin
        public void VersionHandshake(CancellationToken cancellationToken = default(CancellationToken))
        {
            using (var listener = CreateListener()
                                  .Where(p => p.Message.Payload is VersionPayload ||
                                         p.Message.Payload is RejectPayload ||
                                         p.Message.Payload is VerAckPayload))
            {
                using (TraceCorrelation.Open())
                {
                    SendMessage(MyVersion);

                    var payload = listener.ReceivePayload <Payload>(cancellationToken);
                    if (payload is RejectPayload)
                    {
                        throw new InvalidOperationException("Handshake rejected : " + ((RejectPayload)payload).Reason);
                    }
                    var version = (VersionPayload)payload;
                    _PeerVersion = version;
                    Version      = version.Version;
                    if (!version.AddressReciever.Address.Equals(MyVersion.AddressFrom.Address))
                    {
                        NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReciever.Address + " instead of " + MyVersion.AddressFrom.Address);
                    }
                    if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION)
                    {
                        NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting");
                        Disconnect();
                        return;
                    }
                    SendMessage(new VerAckPayload());
                    listener.ReceivePayload <VerAckPayload>(cancellationToken);
                    State = NodeState.HandShaked;
                }
            }
        }
コード例 #2
0
ファイル: Node.cs プロジェクト: RupeshDada/NBitcoin
        public static Node Connect(Network network,
                                   IPEndPoint endpoint,
                                   ProtocolVersion myVersion = ProtocolVersion.PROTOCOL_VERSION,
                                   bool isRelay = true,
                                   CancellationToken cancellation = default(CancellationToken))
        {
            var peer = new Peer(PeerOrigin.Manual, new NetworkAddress()
            {
                Time     = DateTimeOffset.UtcNow,
                Endpoint = endpoint
            });
            VersionPayload version = new VersionPayload()
            {
                Nonce           = 12345,
                UserAgent       = VersionPayload.GetNBitcoinUserAgent(),
                Version         = myVersion,
                StartHeight     = 0,
                Timestamp       = DateTimeOffset.UtcNow,
                AddressReciever = peer.NetworkAddress.Endpoint,
                AddressFrom     = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6(), network.DefaultPort),
                Relay           = isRelay
            };

            return(new Node(peer, network, version, cancellation));
        }
コード例 #3
0
 public NodeConnectionParameters()
 {
     ReuseBuffer = true;
     TemplateBehaviors.Add(new PingPongBehavior());
     Version             = ProtocolVersion.PROTOCOL_VERSION;
     IsRelay             = true;
     Services            = NodeServices.Nothing;
     ConnectCancellation = default(CancellationToken);
     ReceiveBufferSize   = 1000 * 5000;
     SendBufferSize      = 1000 * 1000;
     UserAgent           = VersionPayload.GetNBitcoinUserAgent();
 }
コード例 #4
0
 public NodeConnectionParameters()
 {
     this.ReuseBuffer = true;
     this.TemplateBehaviors.Add(new PingPongBehavior());
     this.Version                     = ProtocolVersion.PROTOCOL_VERSION;
     this.IsRelay                     = true;
     this.Services                    = NodeServices.Nothing;
     this.ConnectCancellation         = default(CancellationToken);
     this.ReceiveBufferSize           = 1000 * 5000;
     this.SendBufferSize              = 1000 * 1000;
     this.UserAgent                   = VersionPayload.GetNBitcoinUserAgent();
     this.PreferredTransactionOptions = TransactionOptions.All;
 }
コード例 #5
0
 public NodeConnectionParameters()
 {
     TemplateBehaviors.Add(new PingPongBehavior());
     Version             = null;
     IsRelay             = true;
     Services            = NodeServices.Nothing;
     ConnectCancellation = default(CancellationToken);
     // Use max supported by MAC OSX Yosemite/Mavericks/Sierra (https://fasterdata.es.net/host-tuning/osx/)
     this.SocketSettings.ReceiveBufferSize = 1048576;
     this.SocketSettings.SendBufferSize    = 1048576;
     ////////////////////////
     UserAgent = VersionPayload.GetNBitcoinUserAgent();
     PreferredTransactionOptions = TransactionOptions.All;
 }
コード例 #6
0
 internal Node(Peer peer, NodeServer nodeServer, Socket socket, VersionPayload version)
 {
     _Peer        = peer;
     _NodeServer  = nodeServer;
     _Connection  = new NodeConnection(this, socket);
     _FullVersion = version;
     Version      = version.Version;
     LastSeen     = peer.NetworkAddress.Time;
     TraceCorrelation.LogInside(() =>
     {
         NodeServerTrace.Information("Connected to advertised node " + _Peer.NetworkAddress.Endpoint);
         State = NodeState.Connected;
     });
     _Connection.BeginListen();
 }
コード例 #7
0
        public VersionPayload CreateVersion(IPEndPoint peer, Network network)
        {
            VersionPayload version = new VersionPayload()
            {
                Nonce = Nonce == null?RandomUtils.GetUInt64() : Nonce.Value,
                            UserAgent       = UserAgent,
                            Version         = Version,
                            Timestamp       = DateTimeOffset.UtcNow,
                            AddressReceiver = peer,
                            AddressFrom     = AddressFrom ?? new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), network.DefaultPort),
                            Relay           = IsRelay,
                            Services        = Services
            };

            return(version);
        }
コード例 #8
0
ファイル: Node.cs プロジェクト: zenprotocol/zen-wallet
        public void VersionHandshake(NodeRequirement requirements, CancellationToken cancellationToken = default(CancellationToken))
        {
            requirements = requirements ?? new NodeRequirement();
            using (var listener = CreateListener()
                                  .Where(p => p.IsPayloadTypeOf(typeof(VersionPayload), typeof(RejectPayload), typeof(VerAckPayload))))
            {
                SendMessageAsync(MyVersion);
                var payload = listener.ReceivePayload <Object>(cancellationToken);
                if (payload is RejectPayload)
                {
                    throw new ProtocolException("Handshake rejected : " + ((RejectPayload)payload).Reason);
                }
                var version = (VersionPayload)payload;
                _PeerVersion = version;
                if (!version.AddressReceiver.Address.Equals(MyVersion.AddressFrom.Address))
                {
                    NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReceiver.Address + " instead of " + MyVersion.AddressFrom.Address);
                }
                if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION)
                {
                    NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting");
                    Disconnect("Outdated version");
                    return;
                }

                if (!requirements.Check(version))
                {
                    Disconnect("The peer does not support the required services requirement");
                    return;
                }

                SendMessageAsync(new VerAckPayload());
                listener.ReceivePayload <VerAckPayload>(cancellationToken);
                State = NodeState.HandShaked;
                if (Advertize && MyVersion.AddressFrom.Address.IsRoutable(true))
                {
                    SendMessageAsync(new AddrPayload(new NetworkAddress[] {
                        new NetworkAddress(MyVersion.AddressFrom)
                        {
                            Time = DateTimeOffset.UtcNow
                        }
                    }));
                }
            }
        }
コード例 #9
0
ファイル: Node.cs プロジェクト: jannickj/NBitcoin
        internal Node(Peer peer, Network network, VersionPayload myVersion, CancellationToken cancellation)
        {
            _MyVersion = myVersion;
            Version    = _MyVersion.Version;
            Network    = network;
            _Peer      = peer;
            LastSeen   = peer.NetworkAddress.Time;

            var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);

#if !NOIPDUALMODE
            socket.DualMode = true;
#endif
            _Connection = new NodeConnection(this, socket);
            using (TraceCorrelation.Open())
            {
                try
                {
                    var ar = socket.BeginConnect(Peer.NetworkAddress.Endpoint, null, null);
                    WaitHandle.WaitAny(new WaitHandle[] { ar.AsyncWaitHandle, cancellation.WaitHandle });
                    cancellation.ThrowIfCancellationRequested();
                    socket.EndConnect(ar);
                    State = NodeState.Connected;
                    NodeServerTrace.Information("Outbound connection successfull");
                }
                catch (OperationCanceledException)
                {
                    Utils.SafeCloseSocket(socket);
                    NodeServerTrace.Information("Connection to node cancelled");
                    State = NodeState.Offline;
                    return;
                }
                catch (Exception ex)
                {
                    Utils.SafeCloseSocket(socket);
                    NodeServerTrace.Error("Error connecting to the remote endpoint ", ex);
                    State = NodeState.Failed;
                    throw;
                }
                _Connection.BeginListen();
            }
        }
コード例 #10
0
        public void VersionHandshake(CancellationToken cancellationToken = default(CancellationToken))
        {
            var listener = new PollMessageListener <IncomingMessage>();

            using (MessageProducer.AddMessageListener(listener))
            {
                using (TraceCorrelation.Open())
                {
                    var myVersion = CreateVersionPayload();
                    SendMessage(myVersion);

                    var version = listener.RecieveMessage(cancellationToken).AssertPayload <VersionPayload>();
                    _FullVersion = version;
                    Version      = version.Version;
                    if (version.Nonce == NodeServer.Nonce)
                    {
                        NodeServerTrace.ConnectionToSelfDetected();
                        Disconnect();
                        throw new InvalidOperationException("Impossible to connect to self");
                    }

                    if (!version.AddressReciever.Address.Equals(ExternalEndpoint.Address))
                    {
                        NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReciever.Address + " instead of " + ExternalEndpoint.Address);
                    }
                    NodeServer.ExternalAddressDetected(version.AddressReciever.Address);
                    if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION)
                    {
                        NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting");
                        Disconnect();
                        return;
                    }
                    SendMessage(new VerAckPayload());
                    listener.RecieveMessage(cancellationToken).AssertPayload <VerAckPayload>();
                    State = NodeState.HandShaked;
                    if (NodeServer.AdvertizeMyself)
                    {
                        AdvertiseMyself();
                    }
                }
            }
        }
コード例 #11
0
ファイル: Node.cs プロジェクト: zenprotocol/zen-wallet
 internal Node(NetworkAddress peer, NetworkInfo network, NodeConnectionParameters parameters, Socket socket, VersionPayload peerVersion)
 {
     _RemoteSocketAddress = ((IPEndPoint)socket.RemoteEndPoint).Address;
     _RemoteSocketPort    = ((IPEndPoint)socket.RemoteEndPoint).Port;
     Inbound      = true;
     _Behaviors   = new NodeBehaviorsCollection(this);
     _MyVersion   = parameters.CreateVersion(peer.Endpoint, network);
     Network      = network;
     _Peer        = peer;
     _Connection  = new NodeConnection(this, socket);
     _PeerVersion = peerVersion;
     LastSeen     = peer.Time;
     ConnectedAt  = DateTimeOffset.UtcNow;
     TraceCorrelation.LogInside(() =>
     {
         NodeServerTrace.Information("Connected to advertised node " + _Peer.Endpoint);
         State = NodeState.Connected;
     });
     InitDefaultBehaviors(parameters);
     _Connection.BeginListen();
 }
コード例 #12
0
		public VersionPayload CreateVersion(IPEndPoint peer, Network network)
		{
			VersionPayload version = new VersionPayload()
			{
				Nonce = Nonce == null ? RandomUtils.GetUInt64() : Nonce.Value,
				UserAgent = UserAgent,
				Version = Version,
				Timestamp = DateTimeOffset.UtcNow,
				AddressReceiver = peer,
				AddressFrom = AddressFrom ?? new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6(), network.DefaultPort),
				Relay = IsRelay,
				Services = Services
			};
			return version;
		}
コード例 #13
0
        private void ProcessMessageCore(IncomingMessage message)
        {
            if (message.Message.Payload is VersionPayload)
            {
                VersionPayload version         = message.AssertPayload <VersionPayload>();
                bool           connectedToSelf = version.Nonce == this.Nonce;
                if ((message.Node != null) && connectedToSelf)
                {
                    NodeServerTrace.ConnectionToSelfDetected();
                    message.Node.DisconnectAsync();
                    return;
                }

                if (message.Node == null)
                {
                    IPEndPoint remoteEndpoint = version.AddressFrom;
                    if (!remoteEndpoint.Address.IsRoutable(this.AllowLocalPeers))
                    {
                        // Send his own endpoint.
                        remoteEndpoint = new IPEndPoint(((IPEndPoint)message.Socket.RemoteEndPoint).Address, this.Network.DefaultPort);
                    }

                    var peer = new NetworkAddress()
                    {
                        Endpoint = remoteEndpoint,
                        Time     = DateTimeOffset.UtcNow
                    };

                    var node = new Node(peer, this.Network, CreateNodeConnectionParameters(), message.Socket, version);
                    if (connectedToSelf)
                    {
                        node.SendMessage(CreateNodeConnectionParameters().CreateVersion(node.Peer.Endpoint, this.Network));
                        NodeServerTrace.ConnectionToSelfDetected();
                        node.Disconnect();
                        return;
                    }

                    CancellationTokenSource cancel = new CancellationTokenSource();
                    cancel.CancelAfter(TimeSpan.FromSeconds(10.0));
                    try
                    {
                        this.ConnectedNodes.Add(node);
                        node.StateChanged += Node_StateChanged;
                        node.RespondToHandShake(cancel.Token);
                    }
                    catch (OperationCanceledException ex)
                    {
                        NodeServerTrace.Error("The remote node did not respond fast enough (10 seconds) to the handshake completion, dropping connection", ex);
                        node.DisconnectAsync();
                        throw;
                    }
                    catch (Exception)
                    {
                        node.DisconnectAsync();
                        throw;
                    }
                }
            }

            this.MessageReceived?.Invoke(this, message);
        }