knxd/knxd

knxd does not disconnect correctly

dorfil opened this issue · 0 comments

Hi,

I'm running knxd tag 0.14.51, using ipt driver.
If I restart knxd daemon, then the connection fails, and I have to wait some minutes until I can connect again.

This is what I found debugging:

  • When shutting down knxd, the EIBNetIPTunnel::stop function is executed. This function executes EIBNetIPTunnel::restart and EIBNetIPTunnel::is_stopped.

  • EIBNetIPTunnel::restart creates the disconnect-request packet and adds it to the send queue.

  • EIBNetIPTunnel::is_stopped deletes the EIBNetIPSocket, so EIBNetIPSocket::io_send_cb is not executed, and the disconnect-request packet is not sent.

Also the EIBNetIPTunnel::is_stopped is executed again in EIBNetIPTunnel's destructor.

I tried moving the deletion of the EIBNetIPSocket from is_stopped function to the EIBNetIPTunnel destructor, and with this change the disconnect packet is sent and I can reconnect successfully. But I guess I'm just delaying the deletion of the socket, maybe I should ensure somehow that io_send_cb has been executed. Or maybe EIBNetIPTunnel::is_stopped should not be executed in EIBNetIPTunnel::stop function?

Any thoughts?

 src/backend/eibnettunnel.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/eibnettunnel.cpp b/src/backend/eibnettunnel.cpp
index 35bdeb6..018ecc7 100644
--- a/src/backend/eibnettunnel.cpp
+++ b/src/backend/eibnettunnel.cpp
@@ -34,6 +34,11 @@ EIBNetIPTunnel::~EIBNetIPTunnel ()
 {
   TRACEPRINTF (t, 2, "Close A");
   // restart();
+  if (sock)
+    {
+      delete sock;
+      sock = nullptr;
+    }
   is_stopped();
 }

@@ -42,8 +47,6 @@ void EIBNetIPTunnel::is_stopped()
   timeout.stop();
   conntimeout.stop();
   trigger.stop();
-  delete sock;
-  sock = nullptr;
 }

 void EIBNetIPTunnel::stop(bool err)
@@ -509,6 +512,11 @@ void EIBNetIPTunnel::conntimeout_cb(ev::timer &, int)
   else
     {
       TRACEPRINTF (t, 1, "Connect timed out");
+      if (sock)
+        {
+          delete sock;
+          sock = nullptr;
+        }
       is_stopped();
       stop(true);
       // EIBnet_ConnectRequest creq = get_creq();
--

Thanks,
Hector