eclipse / mosquitto

Eclipse Mosquitto - An open source MQTT broker
https://mosquitto.org
Other
8.93k stars 2.37k forks source link

Handling of connection errors with SSL #2421

Open gollux opened 2 years ago

gollux commented 2 years ago

I am trying to write a simple program, which listens for MQTT messages and which can recover from server failures. I am using this:

        mosquitto_lib_init();

        mosq = mosquitto_new("test", 1, NULL);
        if (!mosq)
                die("Mosquitto: initialization failed");

        // Leaving out setup of callbacks. The problem occurs without them, too.

        if (mosquitto_tls_set(mosq, "ca.crt", NULL, "client.crt", "client.key", NULL) != MOSQ_ERR_SUCCESS)
                die("Mosquitto: unable to set TLS parameters");

        mosquitto_connect_async(mosq, "localhost", 8883, 60);
        mosquitto_loop_forever(mosq, 10000, 1);

Now, if the server is available, everything works correctly. But once I run this program with no server running, it gets stuck in an infinite loop:

connect(7, {sa_family=AF_INET6, sin6_port=htons(8883), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
...
write(7, "\26\3\1\1(\1\0\1$\3\3\264)JU\335f\276qF\347\242\276@\375\222\277\324\27}\201\351"..., 301) = -1 ECONNREFUSED (Connection refused)
write(6, "\0", 1)                       = 1
pselect6(8, [5 7], [], NULL, {tv_sec=10, tv_nsec=0}, {NULL, 8}) = 2 (in [5 7], left {tv_sec=9, tv_nsec=999998668})
write(7, "\26\3\1\1(\1\0\1$\3\3\264)JU\335f\276qF\347\242\276@\375\222\277\324\27}\201\351"..., 301) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=50249, si_uid=1000} ---
read(5, "\0", 1)                        = 1
write(7, "\26\3\1\1(\1\0\1$\3\3\264)JU\335f\276qF\347\242\276@\375\222\277\324\27}\201\351"..., 301) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=50249, si_uid=1000} ---
pselect6(8, [5 7], [], NULL, {tv_sec=10, tv_nsec=0}, {NULL, 8}) = 1 (in [7], left {tv_sec=9, tv_nsec=999999055})
write(7, "\26\3\1\1(\1\0\1$\3\3\264)JU\335f\276qF\347\242\276@\375\222\277\324\27}\201\351"..., 301) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=50249, si_uid=1000} ---
... and so on ...

If I turn off TLS, mosquitto_loop_forever() correctly detects that the connection is broken and reconnect after some delay.

I used mosquitto-1.5.7 from Debian Buster, but unmodified version 2.0.11 behaves the same. I am using openssl 1.1.1d as a SSL library.

gdt commented 2 years ago

There were fixes about bridge reconnection in 2.0.13, so I recommend updating to 2.0.14 and retesting. (I'm not a maintainer of mosquitto, but when acting of maintainer of other things, I basically decline to address bugs in other than the latest release.)

It sounds like firing up gdb would be useful.

gollux commented 2 years ago

Sorry, my typo. It was 2.0.14. Just to be sure, I re-tested it again today with freshly downloaded 2.0.14 and the bug still persists.

c-fis commented 2 years ago

I have the same issue using the function mosquitto_loop() with version 2.0.11 and openssl 1.1.1k. The function mosquitto_loop() returns with MOSQ_ERR_SUCCESS immediately after calling. So, according to mosquitto_loop() everything is OK, but errno is set to EPIPE.

The according strace output is:

[pid 11935] pselect6(14, [7 13], [], NULL, {tv_sec=1, tv_nsec=0}, {NULL, 8}) = 1 (in [13], left {tv_sec=0, tv_nsec=999986959})
[pid 11935] write(13, "\26\3\1\1(\1\0\1$\3\3q\244\340\6\216NYJ<|\212\232&\\\361\nV\1\217*/"..., 301) = -1 EPIPE (Broken pipe)
[pid 11935] --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=11931, si_uid=0} ---