From fc974887ceefd6716b6de5b089e97f312ab90a87 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 2 Sep 2020 18:22:11 +0200 Subject: [PATCH] MEDIUM: protocol: explicitly start the receiver before the listener Now protocol_bind_all() starts the receivers before their respective listeners so that ultimately we won't need the listeners for non- connected protocols. We still have to resort to an ugly trick to set the I/O handler in case of syslog over UDP because for now it's still not set in the receiver, so we hard-code it. --- src/protocol.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/protocol.c b/src/protocol.c index 6ea60337a2..a4e93e2de1 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -60,14 +60,30 @@ int protocol_bind_all(int verbose) { struct protocol *proto; struct listener *listener; + struct receiver *receiver; char msg[100]; + char *errmsg; + void *handler; int err, lerr; err = 0; HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); list_for_each_entry(proto, &protocols, list) { - list_for_each_entry(listener, &proto->listeners, rx.proto_list) { - lerr = proto->listen(listener, msg, sizeof(msg)); + list_for_each_entry(receiver, &proto->listeners, proto_list) { + listener = LIST_ELEM(receiver, struct listener *, rx); + + /* FIXME: horrible hack, we don't have a way to register + * a handler when creating the receiver yet, so we still + * have to take care of special cases here. + */ + handler = listener->rx.proto->accept; + if (!handler && listener->bind_conf->frontend->mode == PR_MODE_SYSLOG) { + extern void syslog_fd_handler(int); + handler = syslog_fd_handler; + } + + lerr = proto->bind(receiver, handler, &errmsg); + err |= lerr; /* errors are reported if is set or if they are fatal */ if (verbose || (lerr & (ERR_FATAL | ERR_ABORT))) { @@ -75,13 +91,33 @@ int protocol_bind_all(int verbose) if (lerr & ERR_ALERT) ha_alert("Starting %s %s: %s\n", - proxy_type_str(px), px->id, msg); + proxy_type_str(px), px->id, errmsg); else if (lerr & ERR_WARN) ha_warning("Starting %s %s: %s\n", - proxy_type_str(px), px->id, msg); + proxy_type_str(px), px->id, errmsg); + free(errmsg); errmsg = NULL; } + if (lerr & ERR_ABORT) + break; + + if (lerr & ~ERR_WARN) + continue; + /* for now there's still always a listening function */ + BUG_ON(!proto->listen); + lerr = proto->listen(listener, msg, sizeof(msg)); err |= lerr; + + if (verbose || (lerr & (ERR_FATAL | ERR_ABORT))) { + struct proxy *px = listener->bind_conf->frontend; + + if (lerr & ERR_ALERT) + ha_alert("Starting %s %s: %s\n", + proxy_type_str(px), px->id, msg); + else if (lerr & ERR_WARN) + ha_warning("Starting %s %s: %s\n", + proxy_type_str(px), px->id, msg); + } if (lerr & ERR_ABORT) break; } -- 2.39.5