From: Vincent Bernat Date: Wed, 29 Feb 2012 22:14:41 +0000 (+0100) Subject: lldpd: do not stay stuck in the receive loop X-Git-Tag: 0.5.7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8b66dd39ca5de2d796d2ffd9db7505e853e8a87;p=thirdparty%2Flldpd.git lldpd: do not stay stuck in the receive loop On some corner case conditions, we can stay stuck in the receive loop because we did not send packets for more than 30 seconds. In this case, we keep reset the timeout to 30 seconds and we cannot exit the loop (since the first condition to exit the loop is to have reached the timeout). Therefore, we invert the condition. If we have stay too long in the loop, just exit. We know for sure that we will hit lldpd_send_all() soon and get back to a sane state. Also, in receive only state, we are also stuck in the loop. This forbids us to update data about local chassis and interfaces. We also fix this. --- diff --git a/CHANGELOG b/CHANGELOG index cfcb2d0d..6b40e267 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ lldpd (0.5.7) * Fixes: + Configure issue with NetSNMP and some linkers + + Fix infinite loop for the receive part: on certain conditions, + lldpd will stop sending packets and stop updating local data. lldpd (0.5.6) * Features: diff --git a/configure.ac b/configure.ac index 59a5aa42..2822ebc6 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ # Configure autoconf AC_PREREQ([2.64]) -AC_INIT([lldpd], [0.5.6], [bernat@luffy.cx]) +AC_INIT([lldpd], [0.5.7], [bernat@luffy.cx]) AC_CONFIG_SRCDIR([src/lldpd.c]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_FILES([Makefile src/Makefile man/Makefile tests/Makefile]) diff --git a/src/lldpd.c b/src/lldpd.c index 6f592d61..bbfe2a72 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -776,7 +776,9 @@ lldpd_recv_all(struct lldpd *cfg) do { tv.tv_sec = cfg->g_delay - (time(NULL) - cfg->g_lastsent); if (tv.tv_sec < 0) - tv.tv_sec = LLDPD_TX_DELAY; + /* We did not send packets in a long time, + just give up receive for now. */ + break; if (tv.tv_sec >= cfg->g_delay) tv.tv_sec = cfg->g_delay; tv.tv_usec = 0; @@ -879,6 +881,7 @@ lldpd_send_all(struct lldpd *cfg) int i, sent; cfg->g_lastsent = time(NULL); + if (cfg->g_receiveonly) return; TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) { /* Ignore if interface is down */ if ((hardware->h_flags & IFF_RUNNING) == 0) @@ -1061,8 +1064,7 @@ lldpd_loop(struct lldpd *cfg) lldpd_update_localports(cfg); lldpd_cleanup(cfg); lldpd_update_localchassis(cfg); - if (!cfg->g_receiveonly) - lldpd_send_all(cfg); + lldpd_send_all(cfg); lldpd_recv_all(cfg); }