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)); }
/// <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}]." ); }
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)); }
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)); }
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)); }
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); }
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)); }
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)); }
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); }
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); }
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> >(); }