Exemplo n.º 1
0
        public void DifferentAppProtocolVersionStructure()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var apv1       = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var apv2 = new AppProtocolVersion(
                2,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var          message      = new Ping();
            var          codec1       = new NetMQMessageCodec(appProtocolVersion: apv1);
            var          codec2       = new NetMQMessageCodec(appProtocolVersion: apv2);
            NetMQMessage netMQMessage = codec1.Encode(
                message,
                privateKey,
                peer,
                DateTimeOffset.UtcNow);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 codec2.Decode(netMQMessage, true));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Queries <see cref="AppProtocolVersion"/> of given <see cref="BoundPeer"/>.
        /// </summary>
        /// <param name="peer">The <see cref="BoundPeer"/> to query
        /// <see cref="AppProtocolVersion"/>.</param>
        /// <param name="timeout">Timeout value for request.</param>
        /// <returns><see cref="AppProtocolVersion"/> of given peer. </returns>
        public static AppProtocolVersion QueryAppProtocolVersion(
            this BoundPeer peer,
            TimeSpan?timeout = null
            )
        {
            using var dealerSocket = new DealerSocket(ToNetMQAddress(peer));
            var          key  = new PrivateKey();
            var          ping = new Ping();
            var          netMQMessageCodec = new NetMQMessageCodec();
            NetMQMessage request           = netMQMessageCodec.Encode(
                ping,
                key,
                new Peer(key.PublicKey),
                DateTimeOffset.UtcNow,
                default
                );

            TimeSpan timeoutNotNull = timeout ?? TimeSpan.FromSeconds(5);

            if (dealerSocket.TrySendMultipartMessage(timeoutNotNull, request))
            {
                var response = new NetMQMessage();
                if (dealerSocket.TryReceiveMultipartMessage(timeoutNotNull, ref response))
                {
                    return(AppProtocolVersion.FromToken(response.First.ConvertToString()));
                }
            }

            throw new TimeoutException(
                      $"Peer[{peer}] didn't respond within the specified time[{timeout}]."
                      );
        }
Exemplo n.º 3
0
        public void InvalidMessageTimestamp()
        {
            var privateKey   = new PrivateKey();
            var peer         = new Peer(privateKey.PublicKey);
            var futureOffset = DateTimeOffset.MaxValue;
            var pastOffset   = DateTimeOffset.MinValue;
            var apv          = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var buffer  = TimeSpan.FromSeconds(1);
            var message = new Ping();
            var codec   = new NetMQMessageCodec(
                appProtocolVersion: apv,
                messageTimestampBuffer: buffer);
            NetMQMessage futureRaw =
                codec.Encode(message, privateKey, peer, futureOffset);

            // Messages from the future throws InvalidMessageTimestampException.
            Assert.Throws <InvalidMessageTimestampException>(() =>
                                                             codec.Decode(futureRaw, true));
            NetMQMessage pastRaw =
                codec.Encode(message, privateKey, peer, pastOffset);

            // Messages from the far past throws InvalidMessageTimestampException.
            Assert.Throws <InvalidMessageTimestampException>(() =>
                                                             codec.Decode(pastRaw, true));
        }
Exemplo n.º 4
0
        public void UseInvalidSignature()
        {
            // Victim
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey, new IPAddress(1024L));
            var timestamp  = DateTimeOffset.UtcNow;
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var ping         = new Ping();
            var codec        = new NetMQMessageCodec(appProtocolVersion: apv);
            var netMqMessage = codec.Encode(ping, privateKey, peer, timestamp).ToArray();

            // Attacker
            var fakePeer    = new Peer(privateKey.PublicKey, new IPAddress(2048L));
            var fakeMessage = codec.Encode(ping, privateKey, fakePeer, timestamp).ToArray();

            var frames = new NetMQMessage();

            frames.Push(netMqMessage[4]);
            frames.Push(netMqMessage[3]);
            frames.Push(fakeMessage[2]);
            frames.Push(netMqMessage[1]);
            frames.Push(netMqMessage[0]);

            Assert.Throws <InvalidMessageSignatureException>(() =>
                                                             codec.Decode(frames, true));
        }
Exemplo n.º 5
0
        public void DifferentAppProtocolVersionStructure()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var          message      = new Ping();
            var          codec        = new NetMQMessageCodec();
            NetMQMessage netMQMessage = codec.Encode(
                message,
                privateKey,
                peer,
                DateTimeOffset.UtcNow,
                apv);

            Assert.Throws <DifferentAppProtocolVersionException>(() =>
                                                                 codec.Decode(
                                                                     netMQMessage,
                                                                     true,
                                                                     (i, p, v) => throw new DifferentAppProtocolVersionException(
                                                                         string.Empty,
                                                                         i,
                                                                         v,
                                                                         v),
                                                                     null));
        }
Exemplo n.º 6
0
        public void Decode()
        {
            BlockHash[] blockHashes = GenerateRandomBlockHashes(100L).ToArray();
            var         msg         = new BlockHashes(123, blockHashes);

            Assert.Equal(123, msg.StartIndex);
            Assert.Equal(blockHashes, msg.Hashes);
            var privKey               = new PrivateKey();
            AppProtocolVersion ver    = AppProtocolVersion.Sign(privKey, 3);
            Peer         peer         = new BoundPeer(privKey.PublicKey, new DnsEndPoint("0.0.0.0", 1234));
            var          messageCodec = new NetMQMessageCodec();
            NetMQMessage encoded      = messageCodec.Encode(
                msg,
                privKey,
                peer,
                DateTimeOffset.UtcNow,
                ver);
            BlockHashes restored = (BlockHashes)messageCodec.Decode(
                encoded,
                true,
                (b, p, a) => { },
                null);

            Assert.Equal(msg.StartIndex, restored.StartIndex);
            Assert.Equal(msg.Hashes, restored.Hashes);
        }
Exemplo n.º 7
0
        public void InvalidArguments()
        {
            var codec      = new NetMQMessageCodec();
            var message    = new Ping();
            var privateKey = new PrivateKey();
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));

            Assert.Throws <ArgumentException>(
                () => codec.Decode(new NetMQMessage(), true));
        }
Exemplo n.º 8
0
        public void InvalidArguments()
        {
            var codec      = new NetMQMessageCodec();
            var message    = new Ping();
            var privateKey = new PrivateKey();
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));

            Assert.Throws <ArgumentNullException>(
                () => codec.Encode(message, privateKey, null, DateTimeOffset.UtcNow, apv));
            Assert.Throws <ArgumentException>(
                () => codec.Decode(
                    new NetMQMessage(),
                    true,
                    (i, p, v) => { },
                    null));
        }
Exemplo n.º 9
0
        public void BlockHeaderMessage()
        {
            var privateKey = new PrivateKey();
            var peer       = new Peer(privateKey.PublicKey);
            var apv        = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var dateTimeOffset         = DateTimeOffset.UtcNow;
            Block <DumbAction> genesis = MineGenesisBlock <DumbAction>(
                _ => HashAlgorithmType.Of <SHA256>(),
                GenesisMiner
                );
            var          message = new BlockHeaderMessage(genesis.Hash, genesis.Header);
            var          codec   = new NetMQMessageCodec(appProtocolVersion: apv);
            NetMQMessage raw     =
                codec.Encode(message, privateKey, peer, dateTimeOffset);
            var parsed = codec.Decode(raw, true);

            Assert.Equal(peer, parsed.Remote);
        }
Exemplo n.º 10
0
        public void CheckMessages(Message.MessageType type)
        {
            var privateKey     = new PrivateKey();
            var peer           = new Peer(privateKey.PublicKey);
            var dateTimeOffset = DateTimeOffset.UtcNow;
            var apv            = new AppProtocolVersion(
                1,
                new Bencodex.Types.Integer(0),
                ImmutableArray <byte> .Empty,
                default(Address));
            var          message = CreateMessage(type);
            var          codec   = new NetMQMessageCodec(appProtocolVersion: apv);
            NetMQMessage raw     =
                codec.Encode(message, privateKey, peer, dateTimeOffset);
            var parsed = codec.Decode(raw, true);

            Assert.Equal(apv, parsed.Version);
            Assert.Equal(peer, parsed.Remote);
            Assert.Equal(dateTimeOffset, parsed.Timestamp);
            Assert.IsType(message.GetType(), parsed);
            Assert.Equal(message.DataFrames, parsed.DataFrames);
        }
Exemplo n.º 11
0
        public NetMQTransport(
            PrivateKey privateKey,
            AppProtocolVersion appProtocolVersion,
            IImmutableSet <PublicKey> trustedAppProtocolVersionSigners,
            int workers,
            string host,
            int?listenPort,
            IEnumerable <IceServer> iceServers,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered,
            TimeSpan?messageTimestampBuffer = null)
        {
            _logger = Log
                      .ForContext <NetMQTransport>()
                      .ForContext("Source", nameof(NetMQTransport));

            if (host is null && (iceServers is null || !iceServers.Any()))
            {
                throw new ArgumentException(
                          $"Swarm requires either {nameof(host)} or {nameof(iceServers)}.");
            }

            Running = false;

            _socketCount  = 0;
            _privateKey   = privateKey;
            _host         = host;
            _iceServers   = iceServers?.ToList();
            _listenPort   = listenPort ?? 0;
            _messageCodec = new NetMQMessageCodec(
                appProtocolVersion,
                trustedAppProtocolVersionSigners,
                differentAppProtocolVersionEncountered,
                messageTimestampBuffer);

            _requests = Channel.CreateUnbounded <MessageRequest>();
            _runtimeProcessorCancellationTokenSource = new CancellationTokenSource();
            _runtimeCancellationTokenSource          = new CancellationTokenSource();
            _turnCancellationTokenSource             = new CancellationTokenSource();
            _requestCount     = 0;
            _runtimeProcessor = Task.Factory.StartNew(
                () =>
            {
                // Ignore NetMQ related exceptions during NetMQRuntime.Dispose() to stabilize
                // tests
                try
                {
                    using var runtime  = new NetMQRuntime();
                    Task[] workerTasks = Enumerable
                                         .Range(0, workers)
                                         .Select(_ =>
                                                 ProcessRuntime(_runtimeProcessorCancellationTokenSource.Token))
                                         .ToArray();
                    runtime.Run(workerTasks);
                }
                catch (Exception e)
                    when(e is NetMQException nme || e is ObjectDisposedException ode)
                    {
                        _logger.Error(
                            e,
                            "An exception has occurred while running {TaskName}.",
                            nameof(_runtimeProcessor));
                    }
            },
                CancellationToken.None,
                TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning,
                TaskScheduler.Default
                );

            ProcessMessageHandler   = new AsyncDelegate <Message>();
            _replyCompletionSources =
                new ConcurrentDictionary <string, TaskCompletionSource <object> >();
        }