protected override UdpConnection CreateConnection(IPEndPoint endPoint, ILogger logger, IPMode ipMode = IPMode.IPv4)
        {
            DtlsUnityConnection connection = new DtlsUnityConnection(logger, endPoint, ipMode);

            connection.SetValidServerCertificates(GetCertificateForClient());
            return(connection);
        }
        public void TestMalformedApplicationData()
        {
            IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 27510);

            IPEndPoint connectionEndPoint = ep;

            DtlsConnectionListener.ConnectionId connectionId = new ThreadLimitedUdpConnectionListener.ConnectionId();

            Semaphore signal = new Semaphore(0, int.MaxValue);

            using (MalformedDTLSListener listener = new MalformedDTLSListener(2, new IPEndPoint(IPAddress.Any, ep.Port), new TestLogger()))
                using (DtlsUnityConnection connection = new DtlsUnityConnection(new TestLogger(), ep))
                {
                    listener.SetCertificate(GetCertificateForServer());
                    connection.SetValidServerCertificates(GetCertificateForClient());

                    listener.NewConnection += (evt) =>
                    {
                        connectionEndPoint = evt.Connection.EndPoint;
                        connectionId       = ((ThreadLimitedUdpServerConnection)evt.Connection).ConnectionId;

                        signal.Release();
                        evt.Connection.Disconnected += (o, et) => {
                        };
                    };
                    connection.Disconnected += (o, evt) => {
                        signal.Release();
                    };

                    listener.Start();
                    connection.Connect();

                    // wait for the client to connect
                    signal.WaitOne(10);

                    ByteSpan data = new byte[5] {
                        0x01, 0x02, 0x03, 0x04, 0x05
                    };

                    Record record = new Record();
                    record.ContentType    = ContentType.ApplicationData;
                    record.Epoch          = 1;
                    record.SequenceNumber = 10;
                    record.Length         = (ushort)data.Length;

                    ByteSpan encoded = new byte[Record.Size + data.Length];
                    record.Encode(encoded);
                    data.CopyTo(encoded.Slice(Record.Size));

                    listener.InjectPacket(encoded, connectionEndPoint, connectionId);

                    // wait for the client to disconnect
                    listener.Dispose();
                    signal.WaitOne(100);
                }
        }
        public void TestClientConnects()
        {
            IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 27510);

            bool serverConnected    = false;
            bool serverDisconnected = false;
            bool clientDisconnected = false;

            Semaphore signal = new Semaphore(0, int.MaxValue);

            using (DtlsConnectionListener listener = new DtlsConnectionListener(2, new IPEndPoint(IPAddress.Any, ep.Port), new TestLogger()))
                using (DtlsUnityConnection connection = new DtlsUnityConnection(new TestLogger(), ep))
                {
                    listener.SetCertificate(GetCertificateForServer());
                    connection.SetValidServerCertificates(GetCertificateForClient());

                    listener.NewConnection += (evt) =>
                    {
                        serverConnected = true;
                        signal.Release();
                        evt.Connection.Disconnected += (o, et) => {
                            serverDisconnected = true;
                        };
                    };
                    connection.Disconnected += (o, evt) => {
                        clientDisconnected = true;
                        signal.Release();
                    };

                    listener.Start();
                    connection.Connect();

                    // wait for the client to connect
                    signal.WaitOne(10);

                    listener.Dispose();

                    // wait for the client to disconnect
                    signal.WaitOne(100);

                    Assert.IsTrue(serverConnected);
                    Assert.IsTrue(clientDisconnected);
                    Assert.IsFalse(serverDisconnected);
                }
        }
        public void TestResentHandshakeConnects()
        {
            IPEndPoint captureEndPoint  = new IPEndPoint(IPAddress.Loopback, 27511);
            IPEndPoint listenerEndPoint = new IPEndPoint(IPAddress.Loopback, 27510);

            bool serverConnected    = false;
            bool serverDisconnected = false;
            bool clientDisconnected = false;

            Semaphore signal = new Semaphore(0, int.MaxValue);

            using (SocketCapture capture = new SocketCapture(captureEndPoint, listenerEndPoint))
                using (DtlsConnectionListener listener = new DtlsConnectionListener(2, new IPEndPoint(IPAddress.Any, listenerEndPoint.Port), new TestLogger()))
                    using (DtlsUnityConnection connection = new DtlsUnityConnection(new TestLogger(), captureEndPoint))
                    {
                        Semaphore listenerToConnectionThrottle = new Semaphore(0, int.MaxValue);
                        capture.SendToLocalSemaphore = listenerToConnectionThrottle;
                        Thread throttleThread = new Thread(() => {
                            // HelloVerifyRequest
                            listenerToConnectionThrottle.Release(1);
                            // ServerHello, Server Certificate
                            listenerToConnectionThrottle.Release(1);

                            // Trigger a resend of ServerHello, ServerCertificate
                            Thread.Sleep(1000);
                            listenerToConnectionThrottle.Release(1);


                            // ServerKeyExchange, ServerHelloDone
                            listenerToConnectionThrottle.Release(1);

                            // Trigger a resend of ServerKeyExchange, ServerHelloDone
                            Thread.Sleep(1000);
                            listenerToConnectionThrottle.Release(1);

                            capture.SendToLocalSemaphore = null;
                        });
                        throttleThread.Start();

                        listener.SetCertificate(GetCertificateForServer());
                        connection.SetValidServerCertificates(GetCertificateForClient());

                        listener.NewConnection += (evt) =>
                        {
                            serverConnected = true;
                            signal.Release();
                            evt.Connection.Disconnected += (o, et) => {
                                serverDisconnected = true;
                            };
                        };
                        connection.Disconnected += (o, evt) => {
                            clientDisconnected = true;
                            signal.Release();
                        };

                        listener.Start();
                        connection.Connect();

                        // wait for the client to connect
                        signal.WaitOne(10);

                        listener.Dispose();

                        // wait for the client to disconnect
                        signal.WaitOne(100);

                        Assert.IsTrue(serverConnected);
                        Assert.IsTrue(clientDisconnected);
                        Assert.IsFalse(serverDisconnected);
                    }
        }