Ejemplo n.º 1
0
        public void TestSingleClientConnection()
        {
            var connectionEstablished = new ManualResetEventSlim();
            var connectionLost        = new ManualResetEventSlim();

            SecureTransport serverTransport = null;
            SecureTransport clientTransport = null;

            try
            {
                serverTransport = CreateTransport();
                serverTransport.StartServer(this.serverListenPort);

                clientTransport = CreateTransport();
                clientTransport.OnNewConnection  = _ => connectionEstablished.Set();
                clientTransport.OnConnectionLost = () => connectionLost.Set();

                clientTransport.StartClient(this.clientEndPoints);
                connectionEstablished.Wait();
            }
            finally
            {
                try
                {
                    serverTransport.Dispose();
                    Assert.IsTrue(connectionLost.Wait(5000));
                }
                finally
                {
                    clientTransport?.Dispose();
                }
            }
        }
Ejemplo n.º 2
0
        public void TestMaxConnectionIdleTime()
        {
            var connection1Established = new ManualResetEventSlim();
            var connection1Lost        = new ManualResetEventSlim();

            var configuration = new SecureTransport.Configuration
            {
                MaxConnectionIdleTime        = TimeSpan.FromSeconds(5),
                CommunicationProtocolVersion = 1,
            };

            using (var cancellationTokenSource = new CancellationTokenSource())
                using (var serverTransport = new SecureTransport(configuration, null, cancellationTokenSource.Token))
                {
                    serverTransport.StartServer(this.serverListenPort);

                    using (var clientTransport1 = CreateTransport())
                    {
                        serverTransport.OnNewConnection   = _ => connection1Established.Set();
                        clientTransport1.OnConnectionLost = () => connection1Lost.Set();
                        clientTransport1.StartClient(this.clientEndPoints);
                        connection1Established.Wait();

                        // The connections should be terminated after 5 seconds
                        Trace.TraceInformation("Waiting for connection to be lost");
                        connection1Lost.Wait();
                    }
                }
        }
Ejemplo n.º 3
0
        private void Run(int port)
        {
            var protocol = new RingMasterCommunicationProtocol();

            this.CreateBackend();

            using (var cancel = new CancellationTokenSource())
            {
                this.ringMasterServer = new RingMasterServer(protocol, null, cancel.Token);

                var transportConfig = new SecureTransport.Configuration
                {
                    UseSecureConnection          = false,
                    IsClientCertificateRequired  = false,
                    CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion,
                };

                using (var serverTransport = new SecureTransport(transportConfig))
                {
                    this.ringMasterServer.RegisterTransport(serverTransport);
                    this.ringMasterServer.OnInitSession = initRequest =>
                    {
                        return(new CoreRequestHandler(this.backend, initRequest));
                    };

                    serverTransport.StartServer(port);

                    Console.WriteLine("Press ENTER to exit...");
                    Console.ReadLine();
                    cancel.Cancel();
                }
            }
        }
Ejemplo n.º 4
0
        public void TestClientConnectionRetrySameServer()
        {
            var connectionEstablished = new ManualResetEventSlim();
            var connectionLost        = new ManualResetEventSlim();

            SecureTransport serverTransport = null;
            SecureTransport clientTransport = null;

            try
            {
                serverTransport = CreateTransport();
                serverTransport.StartServer(this.serverListenPort);

                clientTransport = CreateTransport();
                clientTransport.OnNewConnection  = _ => connectionEstablished.Set();
                clientTransport.OnConnectionLost = () => connectionLost.Set();

                clientTransport.StartClient(this.clientEndPoints);
                connectionEstablished.Wait();

                // Now stop the server to break the established connection
                serverTransport.Stop();
                connectionLost.Wait();

                connectionEstablished.Reset();
                connectionLost.Reset();

                // Restart the server and verify that the client automatically connects to it
                serverTransport.StartServer(this.serverListenPort);
                connectionEstablished.Wait();
            }
            finally
            {
                try
                {
                    serverTransport.Dispose();
                    Assert.IsTrue(connectionLost.Wait(5000));
                }
                finally
                {
                    clientTransport?.Dispose();
                }
            }
        }
Ejemplo n.º 5
0
        public void TestClientConnectionRetryDifferentServer()
        {
            var connectionEstablished = new ManualResetEventSlim();
            var connectionLost        = new ManualResetEventSlim();

            int server1ListenPort = GetAvailablePort(9997);
            int server2ListenPort = GetAvailablePort(server1ListenPort + 1);

            IPEndPoint[] clientEndPoints = SecureTransport.ParseConnectionString(string.Format("127.0.0.1:{0},127.0.0.1:{1}", server1ListenPort, server2ListenPort));

            SecureTransport serverTransport1 = null;
            SecureTransport clientTransport  = null;

            try
            {
                serverTransport1 = CreateTransport();
                serverTransport1.StartServer(server1ListenPort);

                clientTransport = CreateTransport();
                clientTransport.OnNewConnection  = _ => connectionEstablished.Set();
                clientTransport.OnConnectionLost = () => connectionLost.Set();

                clientTransport.StartClient(clientEndPoints);
                connectionEstablished.Wait();

                // Now stop the server to break the established connection
                serverTransport1.Stop();
                connectionLost.Wait();

                connectionEstablished.Reset();
                connectionLost.Reset();

                using (var serverTransport2 = CreateTransport())
                {
                    // Start a new server at a different port and verify that the client automatically connects to it
                    serverTransport2.StartServer(server2ListenPort);
                    connectionEstablished.Wait();
                }
            }
            finally
            {
                try
                {
                    serverTransport1.Dispose();
                    Assert.IsTrue(connectionLost.Wait(5000));
                }
                finally
                {
                    clientTransport?.Dispose();
                }
            }
        }
Ejemplo n.º 6
0
        public void TestMultipleServerConnections()
        {
            var connection1Established = new ManualResetEventSlim();
            var connection1Lost        = new ManualResetEventSlim();
            var connection2Established = new ManualResetEventSlim();
            var connection2Lost        = new ManualResetEventSlim();

            var port           = GetAvailablePort(10000);
            var clientEndpoint = SecureTransport.ParseConnectionString($"127.0.0.1:{port}");

            SecureTransport serverTransport  = null;
            SecureTransport clientTransport1 = null;
            SecureTransport clientTransport2 = null;

            try
            {
                serverTransport = CreateTransport();
                serverTransport.StartServer(port);

                clientTransport1 = CreateTransport();

                serverTransport.OnNewConnection   = _ => connection1Established.Set();
                clientTransport1.OnConnectionLost = () => connection1Lost.Set();
                clientTransport1.StartClient(clientEndpoint);
                connection1Established.Wait();

                clientTransport2 = CreateTransport();

                serverTransport.OnNewConnection   = _ => connection2Established.Set();
                clientTransport2.OnConnectionLost = () => connection2Lost.Set();
                clientTransport2.StartClient(clientEndpoint);
                connection2Established.Wait();
            }
            finally
            {
                try
                {
                    serverTransport.Dispose();
                    Assert.IsTrue(connection1Lost.Wait(5000));
                    Assert.IsTrue(connection2Lost.Wait(5000));
                }
                finally
                {
                    clientTransport1?.Dispose();
                    clientTransport2?.Dispose();
                }
            }
        }
Ejemplo n.º 7
0
        public static void Setup(TestContext context)
        {
            var            path        = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var            builder     = new ConfigurationBuilder().SetBasePath(Path.GetDirectoryName(path)).AddJsonFile("appSettings.json");
            IConfiguration appSettings = builder.Build();

            Helpers.SetupTraceLog(Path.Combine(appSettings["LogFolder"], "VegaInMemoryPerf.LogPath"));
            log = s => Trace.TraceInformation(s);

            // If a parameter is specified as follows:
            //      te.exe VegaInMemoryPerf.dll /p:ServerAddress=127.0.0.1:99
            if (!context.Properties.ContainsKey("ServerAddress"))
            {
                backendCore   = CreateBackend();
                backendServer = new RingMasterServer(protocol, null, CancellationToken.None);

                var transportConfig = new SecureTransport.Configuration
                {
                    UseSecureConnection          = false,
                    IsClientCertificateRequired  = false,
                    CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion,
                };

                serverTransport = new SecureTransport(transportConfig);

                backendServer.RegisterTransport(serverTransport);
                backendServer.OnInitSession = initRequest =>
                {
                    return(new CoreRequestHandler(backendCore, initRequest));
                };

                serverTransport.StartServer(10009);
                serverAddress = "127.0.0.1:10009";
            }
            else
            {
                serverAddress = context.Properties["ServerAddress"] as string;
            }

            // Read the app settings
            minPayloadSize = int.Parse(appSettings["MinPayloadSize"]);
            maxPayloadSize = int.Parse(appSettings["MaxPayloadSize"]);
            threadCount    = int.Parse(appSettings["ThreadCount"]);
        }
Ejemplo n.º 8
0
        public void TestServerCertificateSelectionCallback()
        {
            var certificates = GetLocalCertificates(2);

            X509Certificate[] clientCertificates = new X509Certificate[] { certificates[0] };
            X509Certificate[] serverCertificates = new X509Certificate[] { certificates[1] };

            int port = TestSecureTransport.GetAvailablePort(10000);
            var serverAcceptedClient = new ManualResetEventSlim();
            var clientConnected      = new ManualResetEventSlim();
            var serverCertificateSelectionCallbackCalled = new ManualResetEventSlim();

            var configuration = new SecureTransport.Configuration()
            {
                UseSecureConnection               = true,
                ClientCertificates                = certificates,
                ServerCertificates                = serverCertificates,
                CommunicationProtocolVersion      = 1,
                MustCheckCertificateTrustChain    = false,
                LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
                {
                    serverCertificateSelectionCallbackCalled.Set();
                    return(certificates[1]);
                }
            };

            using (var server = new SecureTransport(configuration, null, CancellationToken.None))
                using (var client = CreateTransport(clientCertificates, serverCertificates))
                {
                    server.OnNewConnection = _ => serverAcceptedClient.Set();
                    client.OnNewConnection = _ => clientConnected.Set();
                    server.StartServer(port);
                    client.StartClient(new IPEndPoint(IPAddress.Loopback, port));

                    // Server certificate selection callback must be called before
                    // the server accepts the connection.
                    serverCertificateSelectionCallbackCalled.Wait(3000).Should().BeTrue();
                    serverAcceptedClient.Wait(30000).Should().BeTrue();
                    clientConnected.Wait(30000).Should().BeTrue();
                }
        }
Ejemplo n.º 9
0
        private static void SecureTransportInternal(Action <string> log, string testCaseName, int numberOfClients)
        {
            var packetCount = 0;

            log($"Starting {testCaseName} ...");

            SecureTransport server = null;

            SecureTransport[] clients = new SecureTransport[0];

            try
            {
                // Start the service
                server = new SecureTransport(new SecureTransport.Configuration
                {
                    UseSecureConnection          = false,
                    IsClientCertificateRequired  = false,
                    CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion,
                });

                var serverSendTask = Task.CompletedTask;

                server.OnNewConnection = connection =>
                {
                    connection.OnPacketReceived = packet =>
                    {
                        Interlocked.Increment(ref packetCount);
                        serverSendTask.GetAwaiter().GetResult();
                        serverSendTask = connection.SendAsync(packet);
                    };

                    Trace.TraceInformation("Server accepted a new connection: {0}", connection.RemoteIdentity);
                };

                server.StartServer(Port);

                // Start the client
                clients = Enumerable.Range(0, numberOfClients).Select(
                    _ => new SecureTransport(new SecureTransport.Configuration
                {
                    UseSecureConnection          = false,
                    IsClientCertificateRequired  = false,
                    CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion,
                }))
                          .ToArray();

                Parallel.ForEach(
                    clients,
                    client => client.OnNewConnection = connection =>
                {
                    var clientSendTask = Task.CompletedTask;

                    connection.OnPacketReceived = packet =>
                    {
                        clientSendTask.GetAwaiter().GetResult();
                        clientSendTask = connection.SendAsync(packet);
                    };

                    clientSendTask = connection.SendAsync(new byte[PacketLength]);
                });

                Parallel.ForEach(
                    clients,
                    client => client.StartClient(new IPEndPoint(IPAddress.Loopback, Port)));

                log($"    Warming up for {WarmupMilliSeconds / 1000} seconds");
                Thread.Sleep(WarmupMilliSeconds);

                log($"    Start measuring for {MeasureMilliSeconds} seconds");
                var sw = new Stopwatch();
                int gen0 = GC.CollectionCount(0), gen1 = GC.CollectionCount(1), gen2 = GC.CollectionCount(2);
                sw.Start();
                Interlocked.Exchange(ref packetCount, 0);

                for (int i = 0; i < MeasureMilliSeconds / PrintStatusInterval; i++)
                {
                    Thread.Sleep(PrintStatusInterval);
                    log($"    {DateTime.Now.ToString()} count={packetCount}");
                }

                sw.Stop();
                var totalCount = packetCount;
                var rate       = totalCount / sw.Elapsed.TotalSeconds;

                Parallel.ForEach(clients, client => client.Close());
                server.Close();
                log($"{testCaseName}: {totalCount} in {sw.Elapsed} with {numberOfClients} clients. QPS={rate}");
                log($"  Gen0={GC.CollectionCount(0) - gen0} Gen1={GC.CollectionCount(1) - gen1} Gen2={GC.CollectionCount(2) - gen2}\n");
                log(string.Empty);
            }
            finally
            {
                server?.Dispose();
                Parallel.ForEach(clients, client => client.Dispose());
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Defines the entry point of the application.
        /// </summary>
        /// <param name="args">Command line arguments</param>
        public static void Main(string[] args)
        {
            Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

            if (args == null || args.Length < 1)
            {
                Trace.TraceError("USAGE: SecureTransportServiceTool.exe <port>");
                return;
            }

            int port = int.Parse(args[0]);

            var configuration = new SecureTransport.Configuration();

            var            path        = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var            builder     = new ConfigurationBuilder().SetBasePath(Path.GetDirectoryName(path)).AddJsonFile("appSettings.json");
            IConfiguration appSettings = builder.Build();

            int maxConcurrentRequests = int.Parse(appSettings["MaxConcurrentRequests"]);

            configuration.UseSecureConnection = bool.Parse(appSettings["SSL.UseSSL"]);
            configuration.SendBufferSize      = int.Parse(appSettings["SendBufferSize"]);
            configuration.ReceiveBufferSize   = int.Parse(appSettings["ReceiveBufferSize"]);

            if (configuration.UseSecureConnection)
            {
                string[] clientThumbprints  = appSettings["SSL.ClientCerts"].Split(new char[] { ';', ',' });
                string[] serviceThumbprints = appSettings["SSL.ServerCerts"].Split(new char[] { ';', ',' });

                configuration.ClientCertificates = SecureTransport.GetCertificatesFromThumbPrintOrFileName(clientThumbprints);
                configuration.ServerCertificates = SecureTransport.GetCertificatesFromThumbPrintOrFileName(serviceThumbprints);
            }

            Trace.TraceInformation(
                "Listening on port {0}. Using SSL={1}, MaxConcurentRequests={2}, SendBufferSize={3}, ReceiveBufferSize={4}",
                port,
                configuration.UseSecureConnection,
                maxConcurrentRequests,
                configuration.SendBufferSize,
                configuration.ReceiveBufferSize);

            using (var transport = new SecureTransport(configuration))
            {
                var  timer             = Stopwatch.StartNew();
                long activeConnections = 0;
                long packetsReceived   = 0;
                Task serverTask        = transport.StartServer(port);

                Console.CancelKeyPress += (sender, eventArgs) =>
                {
                    Trace.TraceInformation("Attempting to close server transport");
                    transport.Close();
                };

                var semaphore = new SemaphoreSlim(maxConcurrentRequests, maxConcurrentRequests);
                transport.OnNewConnection = connection =>
                {
                    Trace.TraceInformation("Connection Established with {0}", connection.RemoteEndPoint);
                    Interlocked.Increment(ref activeConnections);

                    connection.OnPacketReceived = packet =>
                    {
                        semaphore.Wait();
                        Interlocked.Increment(ref packetsReceived);
                        connection.SendAsync(packet).ContinueWith(_ => semaphore.Release());
                    };

                    connection.OnConnectionLost = () =>
                    {
                        Trace.TraceInformation("Connection with {0} was lost", connection.RemoteEndPoint);
                        Interlocked.Decrement(ref activeConnections);
                    };
                };

                while (!serverTask.Wait(5000))
                {
                    timer.Stop();
                    long rate          = (long)(packetsReceived * 1000) / timer.ElapsedMilliseconds;
                    int  inflightCount = maxConcurrentRequests - semaphore.CurrentCount;
                    Trace.TraceInformation($"ActiveConnections={activeConnections}, RequestRate {rate} InFlight count={inflightCount}");
                    packetsReceived = 0;
                    timer.Restart();
                }
            }
        }