public async Task ReadWriteMessageWithInvalidMagicCookieAsync() { byte[] invalidCookie = { 0x01, 0x02 }; Assert.False(TcpTransport.MagicCookie.SequenceEqual(invalidCookie)); var listener = new TcpListener(IPAddress.Any, 0); listener.Start(); var client = new TcpClient(); await client.ConnectAsync("127.0.0.1", ((IPEndPoint)listener.LocalEndpoint).Port); TcpClient listenerSocket = await listener.AcceptTcpClientAsync(); AppProtocolVersion version = AppProtocolVersion.Sign(new PrivateKey(), 1); TcpTransport transport = CreateTcpTransport(appProtocolVersion: version); try { var message = new Ping { Identity = Guid.NewGuid().ToByteArray(), }; var codec = new TcpMessageCodec(); byte[] serialized = codec.Encode( message, new PrivateKey(), transport.AsPeer, DateTimeOffset.UtcNow, version); int length = serialized.Length; var buffer = new byte[invalidCookie.Length + sizeof(int) + length]; invalidCookie.CopyTo(buffer, 0); BitConverter.GetBytes(length).CopyTo(buffer, invalidCookie.Length); serialized.CopyTo(buffer, invalidCookie.Length + sizeof(int)); NetworkStream stream = client.GetStream(); await stream.WriteAsync(buffer, 0, buffer.Length, default); await Assert.ThrowsAsync <InvalidMagicCookieException>( async() => await transport.ReadMessageAsync(listenerSocket, default)); byte[] shortBuffer = { 0x00 }; await stream.WriteAsync(shortBuffer, 0, shortBuffer.Length, default); await Assert.ThrowsAsync <InvalidMagicCookieException>( async() => await transport.ReadMessageAsync(listenerSocket, default)); } finally { listenerSocket.Dispose(); client.Dispose(); } }
public static async Task <AppProtocolVersion> QueryAppProtocolVersionTcp( this BoundPeer peer, TimeSpan?timeout = null, CancellationToken cancellationToken = default ) { using var client = new TcpClient(); try { await client.ConnectAsync(peer.EndPoint.Host, peer.EndPoint.Port); } catch (SocketException) { throw new TimeoutException("Cannot find peer."); } client.ReceiveTimeout = timeout?.Milliseconds ?? 0; using var stream = client.GetStream(); var key = new PrivateKey(); var ping = new Ping { Identity = Guid.NewGuid().ToByteArray(), }; var messageCodec = new TcpMessageCodec(); byte[] serialized = messageCodec.Encode( ping, key, peer, DateTimeOffset.UtcNow); int length = serialized.Length; var buffer = new byte[TcpTransport.MagicCookie.Length + sizeof(int) + length]; TcpTransport.MagicCookie.CopyTo(buffer, 0); BitConverter.GetBytes(length).CopyTo(buffer, TcpTransport.MagicCookie.Length); serialized.CopyTo(buffer, TcpTransport.MagicCookie.Length + sizeof(int)); await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken); buffer = new byte[1000000]; int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); var magicCookieBuffer = new byte[TcpTransport.MagicCookie.Length]; Array.Copy(buffer, 0, magicCookieBuffer, 0, TcpTransport.MagicCookie.Length); var sizeBuffer = new byte[sizeof(int)]; Array.Copy(buffer, TcpTransport.MagicCookie.Length, sizeBuffer, 0, sizeof(int)); length = BitConverter.ToInt32(sizeBuffer, 0); var contentBuffer = new byte[length]; Array.Copy( buffer, TcpTransport.MagicCookie.Length + sizeof(int), contentBuffer, 0, length); // length of identity Array.Copy(contentBuffer, 4, sizeBuffer, 0, 4); length = BitConverter.ToInt32(sizeBuffer, 0); // length of apv token Array.Copy(contentBuffer, 4 + 4 + length, sizeBuffer, 0, 4); int apvLength = BitConverter.ToInt32(sizeBuffer, 0); var apvBytes = new byte[apvLength]; Array.Copy(contentBuffer, 4 + 4 + length + 4, apvBytes, 0, apvLength); var frame = new NetMQFrame(apvBytes); string token = frame.ConvertToString(); AppProtocolVersion version = AppProtocolVersion.FromToken(token); return(version); }