lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [mqtt] Disconnection caused by a keep-alive timeout


From: Giuseppe Modugno
Subject: [lwip-devel] [mqtt] Disconnection caused by a keep-alive timeout
Date: Fri, 27 Nov 2020 18:26:29 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.5.0

MQTT client manages the situation when the reply of a keep-alive (PINGRESP) doesn't arrive in time (mqtt_cyclick_timer):

      /* If reception from server has been idle for 1.5*keep_alive time, server is considered unresponsive */
      if ((client->server_watchdog * MQTT_CYCLIC_TIMER_INTERVAL) > (client->keep_alive + client->keep_alive / 2)) {
        LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_cyclic_timer: Server incoming keep-alive timeout\n"));
        mqtt_close(client, MQTT_CONNECT_TIMEOUT);
        restart_timer = 0;
      }

Here mqtt_close() is called and my user callback is called too to signal the event. 
After this event, I see that a couple of allocated blocks aren't freed. I strongly suspect the first is
the TCP packet containing the last unacked keep-alive and the second block is the TCP packet that is sent to 
the server to stop the connection (FYN flag?). I think they are allocated by tcp_output module.

Because I want to stay connected to the server, in my callback I call mqtt_client_connect() again after some seconds.
Now suppose the connection to the server is established again, but maybe after some time again a keep-alive doesn't
receive an answer (think of a client connected to Internet through a bad connection). I will have other two 
allocated and lost blocks in the heap. This is obviously very bad for the heap.

I suspect mqtt_close() doesn't free immediately all the packets that are waiting for an ACK. That function does its 
best to close the connection cleanly, so sending FYN packet (the second block) and waiting for an answer from the server.
However I think there should be a timeout, because unacked packets can stay in the heap forever. What is this timeout?
What could be the reason why in my case those packets are never freed?

I tried to avoid re-calling mqtt_client_connect() when my callback is called at the disconnection, but the two blocks 
above stay unfreed, even after many seconds.

One solution is to call altcp_abort() instead of altcp_close(), indeed in this case I see the heap completely empty 
when the event occurs and my callback is called.
Thinking about this, maybe it's better to call abort() instead of close(). If the server han't answered to a keep-alive,
most probably the connection is not stable and is useless trying the clean closing procedure.

I don't know if it's important, I'm using mbedtls for MQTT connection.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]