]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: resume from LI_ASSIGNED in default_resume_listener()
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 7 Feb 2023 11:17:20 +0000 (12:17 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 Feb 2023 14:05:05 +0000 (15:05 +0100)
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.

src/listener.c

index 82c8631791c024716d8e5d0e51da6b1634991633..dfd1fd9cff90f8ae5f9e7249eac6722a6109c3ed 100644 (file)
@@ -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);