Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to connect with Unix Socket #1989

Closed
BastienCUENOT opened this issue May 6, 2024 · 4 comments · Fixed by #1995
Closed

Unable to connect with Unix Socket #1989

BastienCUENOT opened this issue May 6, 2024 · 4 comments · Fixed by #1995
Labels
bug Something isn't working

Comments

@BastienCUENOT
Copy link

BastienCUENOT commented May 6, 2024

Describe the bug

MqttClient is not able to connect to a mosquitto broker using unix sockets.

Which component is your bug related to?

  • Client

To Reproduce

Steps to reproduce the behavior:

  • MQTTnet version is 4.3.4.1047
  • I use .NET 8 version
  • My code where I create Mqttclient and I call 'connectAsync' method:
mqttClient = this.mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptions
{
  ChannelOptions = new MqttClientTcpOptions
  {
    RemoteEndpoint = new UnixDomainSocketEndPoint("/tmp/mosquitto.sock"),
    AddressFamily = AddressFamily.Unix,
    
  },
};
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
if (response.ResultCode == MqttClientConnectResultCode.Success)
{
    Console.Write("CONNECTED TO MQTT BROKER !");
}

This error is returned:

May 06 08:05:27 PWE HmiAPI[165]: Unhandled exception. MQTTnet.Exceptions.MqttCommunicationException: Protocol not supported
May 06 08:05:27 PWE HmiAPI[165]:  ---> System.Net.Sockets.SocketException (93): Protocol not supported
May 06 08:05:27 PWE HmiAPI[165]:    at System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Implementations.CrossPlatformSocket..ctor(AddressFamily addressFamily)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Adapter.MqttChannelAdapter.<>c__DisplayClass30_0.<<ConnectAsync>b__1>d.MoveNext()
May 06 08:05:27 PWE HmiAPI[165]: --- End of stack trace from previous location ---
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    --- End of inner exception stack trace ---
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Client.MqttClient.ConnectInternal(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
May 06 08:05:27 PWE HmiAPI[165]:    at HmiAPI.MqttClient.Connect() in /root/Product_CbwEv/Build_Kernel/build/hvsd_hmi_api-1.0.0/Models/Services/MqttClient.cs:line 27
May 06 08:05:27 PWE HmiAPI[165]:    at HmiAPI.Controllers.HmiAPIController.Connect() in /root/Product_CbwEv/Build_Kernel/build/hvsd_hmi_api-1.0.0/Controllers/HmiAPIController.cs:line 26
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callback, TState& state)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.QueueUserWorkItemCallback.Execute()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.Thread.StartCallback()
May 06 08:05:27 PWE HmiAPI[165]: Fatal error. Internal CLR error. (0x80131506)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.Tasks.Task+<>c.<ThrowAsync>b__128_1(System.Object)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.QueueUserWorkItemCallback+<>c.<.cctor>b__6_0(System.Threading.QueueUserWorkItemCallback)
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Threading.ExecutionContex
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.QueueUserWorkItemCallback.Execute()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.ThreadPoolWorkQueue.Dispatch()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
May 06 08:05:27 PWE HmiAPI[165]:    at System.Threading.Thread.StartCallback()

Expected behavior

A previous issue was be implemented but not tested: #1908
I think, there is an error when the library tries to initiate socket object.
In the file: "CrossPlaformSocket.cs", the constructor create Socket with the protocolType = TCP:

 public CrossPlatformSocket(AddressFamily addressFamily)
        {
            _socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);

#if !NET5_0_OR_GREATER
            _socketDisposeAction = _socket.Dispose;
#endif
        }

Maybe, ProtocolType shall not be equal to TCP in case of Unix socket ?
Can I specify the protocol type by another way ?

@BastienCUENOT BastienCUENOT added the bug Something isn't working label May 6, 2024
@chkr1011
Copy link
Collaborator

I cannot this test on my own because I have no Unix socket server.

I searched for some examples and in those examples, they set the protocol type to IP instead of TCP.
So, I exposed the protocol type in the MQTTnet client options.

Could you please try version 4.3.4.1071 from the MyGet feed (https://www.myget.org/feed/mqttnet/package/nuget/MQTTnet) and let me know if changing the protocol type (to IP) fixes the issue?

@BastienCUENOT
Copy link
Author

BastienCUENOT commented May 13, 2024

I try to set protocol type to "IP" with the build 4.3.4.1071.
My code:

mqttClient = this.mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptions
{
  ChannelOptions = new MqttClientTcpOptions
  {
    RemoteEndpoint = new UnixDomainSocketEndPoint("/tmp/mosquitto.sock"),
    AddressFamily = AddressFamily.Unix,
    ProtocolType = ProtocolType.IP
  },
};
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
if (response.ResultCode == MqttClientConnectResultCode.Success)
{
    Console.Write("CONNECTED TO MQTT BROKER !");
}

I don't have the same error but there is another one on the NoDelay property:

Unhandled exception. MQTTnet.Exceptions.MqttCommunicationException: Operation not supported
May 13 08:31:23 PWE HmiAPI[167]:  ---> System.Net.Sockets.SocketException (95): Operation not supported
May 13 08:31:23 PWE HmiAPI[167]:    at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
May 13 08:31:23 PWE HmiAPI[167]:    at System.Net.Sockets.Socket.UpdateStatusAfterSocketOptionErrorAndThrowException(SocketError error, String callerName)
May 13 08:31:23 PWE HmiAPI[167]:    at System.Net.Sockets.Socket.SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, Int32 optionValue, Boolean silent)
May 13 08:31:23 PWE HmiAPI[167]:    at System.Net.Sockets.Socket.SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, Int32 optionValue)
May 13 08:31:23 PWE HmiAPI[167]:    at MQTTnet.Implementations.CrossPlatformSocket.set_NoDelay(Boolean value)
May 13 08:31:23 PWE HmiAPI[167]:    at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken)
May 13 08:31:23 PWE HmiAPI[167]:    at MQTTnet.Adapter.MqttChannelAdapter.<>c__DisplayClass30_0.<<ConnectAsync>b__1>d.MoveNext()

I searched more information about SocketOptionLevel, and it seems that it is not possible to set SocketOptionLevel.TCP or IP to an unix socket: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socketoptionlevel?view=net-8.0
(I use socket with "Unix" addressFamily).


Update:

I rebuild the library on my own, and I commented 'set' method for NoDelay property in the file 'CrossPlatformSocket.cs':

public bool NoDelay
{
    // We cannot use the _NoDelay_ property from the socket because there is an issue in .NET 4.5.2, 4.6.
    // The decompiled code is: this.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, value ? 1 : 0);
    // Which is wrong because the "NoDelay" should be set and not "Debug".
    get => false /*(int?)_socket.GetSocketOption(SocketOptionLevel.IP, SocketOptionName.NoDelay) != 0*/;
    set { } /* _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.NoDelay, value ? 1 : 0);*/
}

I know it is not a final solution, but it is only for testing.

Then, I set 'protocolType' to 'Unspecified' like that:

mqttClient = this.mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptions
{
  ChannelOptions = new MqttClientTcpOptions
  {
    RemoteEndpoint = new UnixDomainSocketEndPoint("/tmp/mosquitto.sock"),
    AddressFamily = AddressFamily.Unix,
    ProtocolType = ProtocolType.Unspecified
  },
};
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
if (response.ResultCode == MqttClientConnectResultCode.Success)
{
    Console.Write("CONNECTED TO MQTT BROKER !");
} 

With this change, it works !

@chkr1011
Copy link
Collaborator

Thanks for testing and providing feedback.

Please try again with version x.x.x.1073 from the myget feed. The NoDelay is only set if the protocol type supports that algorithm at all.

It if works I can create a PR, merge and release a new version.

@BastienCUENOT
Copy link
Author

I tried with the build x.x.x.1073 and it works !
I think you can merge, and thank you for your support 😃

@chkr1011 chkr1011 linked a pull request May 14, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants