/// <summary>
        ///     Establishes a TCP connection with the endpoint at the specified address/port pair.
        /// </summary>
        /// <param name="address">The address of the endpoint to connect to.</param>
        /// <param name="service">The service name of the endpoint to connect to.</param>
        /// <param name="secure">True to enable TLS on the socket.</param>
        /// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
        public Task ConnectAsync(string address, string service, bool secure = false,
                                 CancellationToken cancellationToken         = default(CancellationToken))
        {
            var port = ServiceNames.PortForTcpServiceName(service);

            return(ConnectAsync(address, port, secure, cancellationToken));
        }
        public async Task ConnectAsync(
            string address,
            string service,
            bool secure = false,
            CancellationToken cancellationToken   = default(CancellationToken),
            bool ignoreServerCertificateErrors    = false,
            TlsProtocolVersion tlsProtocolVersion = TlsProtocolVersion.Tls12)
        {
            var port = ServiceNames.PortForTcpServiceName(service);

            await ConnectAsync(
                address,
                port,
                secure,
                cancellationToken,
                ignoreServerCertificateErrors).ConfigureAwait(false);
        }
Example #3
0
        public async Task ConnectAsync(
            string address,
            string service,
            bool secure = false,
            CancellationToken cancellationToken   = new CancellationToken(),
            bool ignoreServerCertificateErrors    = false,
            TlsProtocolVersion tlsProtocolVersion = TlsProtocolVersion.Tls12)
        {
            _ignoreCertificateErrors = ignoreServerCertificateErrors;

            var port = ServiceNames.PortForTcpServiceName(service);

            var connectTask = _tcpClient.ConnectAsync(address, port);

            var ret       = new TaskCompletionSource <bool>();
            var canceller = cancellationToken.Register(() => ret.SetCanceled());

            var okOrCancelled = await Task.WhenAny(connectTask, ret.Task);

            if (okOrCancelled == ret.Task)
            {
#pragma warning disable CS4014
                // ensure we observe the connectTask's exception in case downstream consumers throw on unobserved tasks
                connectTask.ContinueWith(t => $"{t.Exception}", TaskContinuationOptions.OnlyOnFaulted);
#pragma warning restore CS4014

                // reset the backing field.
                // depending on the state of the socket this may throw ODE which it is appropriate to ignore
                try
                {
                    Disconnect();
                }
                catch (ObjectDisposedException)
                {
                }
                return;
            }

            canceller.Dispose();

            if (secure)
            {
                SslProtocols tlsProtocol;

                switch (tlsProtocolVersion)
                {
                case TlsProtocolVersion.Tls10:
                    tlsProtocol = SslProtocols.Tls;
                    break;

                case TlsProtocolVersion.Tls11:
                    tlsProtocol = SslProtocols.Tls11;
                    break;

                case TlsProtocolVersion.Tls12:
                    tlsProtocol = SslProtocols.Tls12;
                    break;

                case TlsProtocolVersion.None:
                    throw new InvalidOperationException("Tls Protocol Version cannot be 'None' when establishing a secure connection. Use unencrypted WebSocket (i.e. ws://) with 'None' or set TLS Protocolversion to Tls10, Tls11 or Tls12. Default when using encrypted WebSocket is Tls12");

                default:
                    throw new ArgumentOutOfRangeException(nameof(tlsProtocolVersion), tlsProtocolVersion, null);
                }

                var secureStream = new SslStream(_tcpClient.GetStream(), true, ValidateServerCertificate);

                try
                {
                    await secureStream.AuthenticateAsClientAsync(address, null, tlsProtocol, false);

                    _secureStream = secureStream;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            IsConnected = true;
        }