/// <summary>
        /// Called by servers to authenticate the server and optionally the client in
        ///     a client-server connection using the specified certificate.
        /// </summary>
        /// <param name="cert">The certificate used to authenticate the server.</param>
        private void AuthenticateAsServer(object cert)
        {
            if (cert is X509Certificate)
            {
                dtlsServerContext = new DtlsServerSecurityContext(
                    SecurityPackageType.Schannel,
                    new CertificateCredential((X509Certificate)cert),
                    null,
                    ServerSecurityContextAttribute.ReplayDetect | ServerSecurityContextAttribute.SequenceDetect |
                     ServerSecurityContextAttribute.Confidentiality | ServerSecurityContextAttribute.ExtendedError |
                     ServerSecurityContextAttribute.AllocMemory | ServerSecurityContextAttribute.Datagram,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                try
                {
                    // First accept.
                    byte[] clientToken = this.GetReceivedData(this.timeout);
                    dtlsServerContext.Accept(clientToken);
                    this.SendData(dtlsServerContext.Token);

                    while (dtlsServerContext.NeedContinueProcessing)
                    {
                        if (dtlsServerContext.HasMoreFragments)
                        {
                            dtlsServerContext.Accept(null);
                        }
                        else
                        {
                            clientToken = this.GetReceivedData(this.timeout);
                            dtlsServerContext.Accept(clientToken);
                        }
                        if (dtlsServerContext.Token != null)
                        {
                            this.SendData(dtlsServerContext.Token);
                        }
                    }

                    isAuthenticated = true;

                    dtlsStreamSizes = dtlsServerContext.StreamSizes;
                }
                catch
                {
                    // Don't throw exception in ThreadPool thread
                }
            }
        }
        /// <summary>
        /// Called by clients to authenticate the server and optionally the client in
        /// a client-server connection.
        /// </summary>
        /// <param name="targetHost">The name of the server that share this connection.</param>
        public void AuthenticateAsClient(object targetHost)
        {
            if (targetHost is string)
            {
                dtlsClientContext = new DtlsClientSecurityContext(
                    SecurityPackageType.Schannel,
                    null,
                    (string)targetHost,
                    ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect |
                     ClientSecurityContextAttribute.Confidentiality | ClientSecurityContextAttribute.ExtendedError |
                     ClientSecurityContextAttribute.AllocMemory | ClientSecurityContextAttribute.Datagram |
                     ClientSecurityContextAttribute.UseSuppliedCreds,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                try
                {
                    // First Initialize.
                    byte[] serverToken = null;
                    dtlsClientContext.Initialize(serverToken);
                    this.SendData(dtlsClientContext.Token);

                    while (dtlsClientContext.NeedContinueProcessing)
                    {
                        if (dtlsClientContext.HasMoreFragments)
                        {
                            dtlsClientContext.Initialize(null);
                        }
                        else
                        {
                            serverToken = this.GetReceivedData(this.timeout);
                            dtlsClientContext.Initialize(serverToken);
                        }
                        if (dtlsClientContext.Token != null)
                        {
                            this.SendData(dtlsClientContext.Token);
                        }
                    }

                    isAuthenticated = true;

                    dtlsStreamSizes = dtlsClientContext.StreamSizes;
                }
                catch
                {
                    // Don't throw exception in ThreadPool thread
                }

            }
        }