Пример #1
0
        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();
            }
        }
Пример #2
0
        public TcpTransport(
            PrivateKey privateKey,
            AppProtocolVersion appProtocolVersion,
            IImmutableSet <PublicKey>?trustedAppProtocolVersionSigners,
            string?host,
            int?listenPort,
            IEnumerable <IceServer> iceServers,
            DifferentAppProtocolVersionEncountered?differentAppProtocolVersionEncountered,
            TimeSpan?messageTimestampBuffer = null)
        {
            _logger = Log
                      .ForContext <TcpTransport>()
                      .ForContext("Source", nameof(TcpTransport));

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

            _runningEvent = null !;
            Running       = false;

            _privateKey   = privateKey;
            _host         = host;
            _iceServers   = iceServers.ToList();
            _messageCodec = new TcpMessageCodec(
                appProtocolVersion,
                trustedAppProtocolVersionSigners,
                differentAppProtocolVersionEncountered,
                messageTimestampBuffer);
            _streams = new ConcurrentDictionary <Guid, ReplyStream>();
            _runtimeCancellationTokenSource = new CancellationTokenSource();
            _turnCancellationTokenSource    = new CancellationTokenSource();
            _listenPort = listenPort ?? 0;
            _listener   = new TcpListener(new IPEndPoint(IPAddress.Any, _listenPort));

            ProcessMessageHandler = new AsyncDelegate <Message>();
        }
Пример #3
0
        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);
        }