MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

MQTTnet.Server's WithEncryptedEndpointBoundIPAddress() Fails Silently

Open JohnCoffinAtTripSpark opened this issue 4 years ago • 1 comments

Describe the bug

When we use MQTTnet.Server's method WithEncryptedEndpointBoundIPAddress(), the port does not get opened. No error is generated. It just fails silently.

All things kept equal, WithDefaultEndpointBoundIPAddress() works as expected. We're currently using WithEncryptedEndpoint() as a work-around.

Which project is your bug related to?

  • Server

To Reproduce

  1. Windows 10, C#, .NET Standard 2.0, MQTTnet v3.0.13 (also reproduced with latest stable v3.0.16)
  2. Configure UseEncryption to true and the BrokerAddress to a valid local IPv4 address (see code below).
  3. Note that there are no logged traces or errors
  4. Check for connection using netstat
  5. Note that the connection does not appear to have been created.

FYI: I noticed in the opensource code that the property TreatSocketOpeningErrorAsWarning was set to true in the MqttServerService constructor. I set this to false and rebuilt it (then updated the MQTTnet in my project). Still the same result.

Expected behavior

An error should be generated or the connection should be created.

Code example

For reference, here's the code that we were using:

        /// <summary>
        /// Initialize the broker to receive subscriptions and publications.
        /// </summary>
        public void Initialize()
        {
            // We configure the broker to accept all connections, all subscriptions, all publications, and to use the default endpoint. We set the port and IP address to their default values.
            MqttServerOptionsBuilder optionsBuilder = new MqttServerOptionsBuilder()
                .WithConnectionValidator(this)
                .WithDisconnectedInterceptor(this) // No longer available in 3.0.16
                .WithSubscriptionInterceptor(this)
                .WithUnsubscriptionInterceptor(this)
                .WithApplicationMessageInterceptor(this);

            // Configure endpoints for either encrypted or unencrypted communication.
            if (m_configuration.UseEncryption)
            {
                // Find the server certificate in the current user certificate store
                X509Certificate2 brokerCertificate = null;
                try
                {
                    X509Store userStore = new X509Store(StoreName.My);
                    userStore.Open(OpenFlags.OpenExistingOnly);
                    X509Certificate2Collection certificates = userStore.Certificates.Find(X509FindType.FindByThumbprint, m_configuration.CertificateThumbprint, m_configuration.ValidateCertificate);
                    if (certificates.Count > 0)
                    {
                        brokerCertificate = certificates[0];
                    }
                    userStore.Close();
                }
                catch (Exception exception)
                {
                    m_logger?.LogError(exception, "Cannot start broker (exception thrown while trying to retrieve the broker certificate from the certificate store)");
                }

                // Set options builder
                if (brokerCertificate != null)
                {
                    optionsBuilder.WithEncryptionCertificate(brokerCertificate.Export(X509ContentType.Pkcs12));
                    optionsBuilder.WithEncryptionSslProtocol(System.Security.Authentication.SslProtocols.Tls12);
                    optionsBuilder.WithEncryptedEndpointPort(m_configuration.BrokerPort);
					
                    try
                    {
                        IPAddress address = IPAddress.Parse(m_configuration.BrokerAddress);
                        optionsBuilder.WithEncryptedEndpointBoundIPAddress(address);
                    }
                    catch (Exception exception)
                    {
                        optionsBuilder.WithDefaultEndpoint();
                        m_logger?.LogWarning(exception, $"Could not use configured broker address {m_configuration.BrokerAddress}. Will fall back to default endpoint.");
                    }

                    // Start broker
                    _ = m_mqttServer.StartAsync(optionsBuilder.Build());
                }
                else
                {
                    m_logger?.LogError("Cannot start broker (could not find broker certificate in certificate store)");
                }
            }
            else
            {
                optionsBuilder.WithDefaultEndpointPort(m_configuration.BrokerPort);

                try
                {
                    IPAddress address = IPAddress.Parse(m_configuration.BrokerAddress);
                    optionsBuilder.WithDefaultEndpointBoundIPAddress(address);
                }
                catch (Exception exception)
                {
                    optionsBuilder.WithDefaultEndpoint();
                    m_logger?.LogWarning(exception, $"Could not use configured broker address {m_configuration.BrokerAddress}. Will fall back to default endpoint.");
                }

                // Start broker
                _ = m_mqttServer.StartAsync(optionsBuilder.Build());
            }
        }

JohnCoffinAtTripSpark avatar Oct 22 '21 20:10 JohnCoffinAtTripSpark

I think you need use the code like

var options = new MqttServerOptionsBuilder()
                .WithDefaultEndpoint() // Activate the default (unsecured) endpoint
                .WithDefaultEndpointPort(port)
                .WithDefaultEndpointBoundIPAddress(IPAddress.Parse(ipAddress))
                .WithEncryptedEndpoint()

tjy-cool avatar Dec 26 '24 05:12 tjy-cool