From: Aurelien DARRAGON Date: Tue, 7 Feb 2023 11:17:20 +0000 (+0100) Subject: BUG/MEDIUM: resume from LI_ASSIGNED in default_resume_listener() X-Git-Tag: v2.8-dev5~109 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=046a75e13198b601943fcddf22bd950714d34fd3;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: resume from LI_ASSIGNED in default_resume_listener() Since fc974887c ("MEDIUM: protocol: explicitly start the receiver before the listener"), resume from LI_ASSIGNED state does not work anymore. This is because the binding part has been divided into 2 distinct steps since: first bind(), then listen(). This new logic was properly implemented in startup sequence through protocol_bind_all() but wasn't properly reported in default_resume_listener() function. Fixing default_resume_listener() to comply with the new logic. This should help ABNS sockets to properly rebind in resume_listener() after they have been stopped by pause_listener(): See Redmine:4475 for more context. This commit depends on: - "MINOR: listener: workaround for closing a tiny race between resume_listener() and stopping" - "MINOR: listener: make sure we don't pause/resume bypassed listeners" This could be backported up to 2.4 after a reasonable observation period to make sure that this change doesn't cause unwanted side-effects. --- diff --git a/src/listener.c b/src/listener.c index 82c8631791..dfd1fd9cff 100644 --- a/src/listener.c +++ b/src/listener.c @@ -427,8 +427,28 @@ int default_resume_listener(struct listener *l) if (l->state == LI_ASSIGNED) { char msg[100]; + char *errmsg; int err; + /* first, try to bind the receiver */ + err = l->rx.proto->fam->bind(&l->rx, &errmsg); + if (err != ERR_NONE) { + if (err & ERR_WARN) + ha_warning("Resuming listener: %s\n", errmsg); + else if (err & ERR_ALERT) + ha_alert("Resuming listener: %s\n", errmsg); + ha_free(&errmsg); + if (err & (ERR_FATAL | ERR_ABORT)) { + ret = 0; + goto end; + } + } + + /* then, try to listen: + * for now there's still always a listening function + * (same check performed in protocol_bind_all() + */ + BUG_ON(!l->rx.proto->listen); err = l->rx.proto->listen(l, msg, sizeof(msg)); if (err & ERR_ALERT) ha_alert("Resuming listener: %s\n", msg);