summaryrefslogtreecommitdiffstats
path: root/src/listener.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
commitcff6d757e3ba609c08ef2aaa00f07e53551e5bf6 (patch)
tree08c4fc3255483ad397d712edb4214ded49149fd9 /src/listener.c
parentAdding upstream version 2.9.7. (diff)
downloadhaproxy-upstream.tar.xz
haproxy-upstream.zip
Adding upstream version 3.0.0.upstream/3.0.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/listener.c')
-rw-r--r--src/listener.c107
1 files changed, 92 insertions, 15 deletions
diff --git a/src/listener.c b/src/listener.c
index 75e164a..a348558 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -27,6 +27,7 @@
#include <haproxy/freq_ctr.h>
#include <haproxy/frontend.h>
#include <haproxy/global.h>
+#include <haproxy/guid.h>
#include <haproxy/list.h>
#include <haproxy/listener.h>
#include <haproxy/log.h>
@@ -443,9 +444,9 @@ int default_resume_listener(struct listener *l)
err = l->rx.proto->fam->bind(&l->rx, &errmsg);
if (err != ERR_NONE) {
if (err & ERR_WARN)
- ha_warning("Resuming listener: %s\n", errmsg);
+ ha_warning("Resuming listener: protocol %s: %s.\n", l->rx.proto->name, errmsg);
else if (err & ERR_ALERT)
- ha_alert("Resuming listener: %s\n", errmsg);
+ ha_alert("Resuming listener: protocol %s: %s.\n", l->rx.proto->name, errmsg);
ha_free(&errmsg);
if (err & (ERR_FATAL | ERR_ABORT)) {
ret = 0;
@@ -460,9 +461,9 @@ int default_resume_listener(struct listener *l)
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);
+ ha_alert("Resuming listener: protocol %s: %s.\n", l->rx.proto->name, msg);
else if (err & ERR_WARN)
- ha_warning("Resuming listener: %s\n", msg);
+ ha_warning("Resuming listener: protocol %s: %s.\n", l->rx.proto->name, msg);
if (err & (ERR_FATAL | ERR_ABORT)) {
ret = 0;
@@ -816,6 +817,8 @@ int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
if (fd != -1)
l->rx.flags |= RX_F_INHERITED;
+ guid_init(&l->guid);
+
l->extra_counters = NULL;
HA_RWLOCK_INIT(&l->lock);
@@ -913,6 +916,7 @@ struct listener *clone_listener(struct listener *src)
goto oom1;
memcpy(l, src, sizeof(*l));
+ l->luid = 0; // don't dup the listener's ID!
if (l->name) {
l->name = strdup(l->name);
if (!l->name)
@@ -1066,11 +1070,11 @@ void listener_accept(struct listener *l)
}
#endif
if (p && p->fe_sps_lim) {
- int max = freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0);
+ int max = freq_ctr_remain(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0);
if (unlikely(!max)) {
/* frontend accept rate limit was reached */
- expire = tick_add(now_ms, next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 0));
+ expire = tick_add(now_ms, next_event_delay(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0));
goto limit_proxy;
}
@@ -1541,7 +1545,7 @@ void listener_accept(struct listener *l)
dequeue_all_listeners();
if (p && !MT_LIST_ISEMPTY(&p->listener_queue) &&
- (!p->fe_sps_lim || freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0) > 0))
+ (!p->fe_sps_lim || freq_ctr_remain(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0) > 0))
dequeue_proxy_listeners(p);
}
return;
@@ -1600,14 +1604,14 @@ void listener_release(struct listener *l)
dequeue_all_listeners();
if (fe && !MT_LIST_ISEMPTY(&fe->listener_queue) &&
- (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_sess_per_sec, fe->fe_sps_lim, 0) > 0))
+ (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_counters.sess_per_sec, fe->fe_sps_lim, 0) > 0))
dequeue_proxy_listeners(fe);
else {
unsigned int wait;
int expire = TICK_ETERNITY;
if (fe->task && fe->fe_sps_lim &&
- (wait = next_event_delay(&fe->fe_sess_per_sec,fe->fe_sps_lim, 0))) {
+ (wait = next_event_delay(&fe->fe_counters.sess_per_sec,fe->fe_sps_lim, 0))) {
/* we're blocking because a limit was reached on the number of
* requests/s on the frontend. We want to re-check ASAP, which
* means in 1 ms before estimated expiration date, because the
@@ -1713,8 +1717,8 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
else {
if (fe != global.cli_fe)
ha_diag_warning("[%s:%d]: Disabling per-thread sharding for listener in"
- " %s '%s' because SO_REUSEPORT is disabled\n",
- bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id);
+ " %s '%s' because SO_REUSEPORT is disabled for %s protocol.\n",
+ bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id, li->rx.proto->name);
shards = 1;
}
}
@@ -1727,8 +1731,8 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
/* We also need to check if an explicit shards count was set and cannot be honored */
if (shards > 1 && !protocol_supports_flag(li->rx.proto, PROTO_F_REUSEPORT_SUPPORTED)) {
- ha_warning("[%s:%d]: Disabling sharding for listener in %s '%s' because SO_REUSEPORT is disabled\n",
- bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id);
+ ha_warning("[%s:%d]: Disabling sharding for listener in %s '%s' because SO_REUSEPORT is disabled for %s protocol.\n",
+ bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id, li->rx.proto->name);
shards = 1;
}
@@ -1807,6 +1811,12 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
*err_code |= ERR_FATAL | ERR_ALERT;
return cfgerr;
}
+ /* assign the ID to the first one only */
+ new_li->luid = new_li->conf.id.key = tmp_li->luid;
+ tmp_li->luid = 0;
+ eb32_delete(&tmp_li->conf.id);
+ if (tmp_li->luid)
+ eb32_insert(&fe->conf.used_listener_id, &new_li->conf.id);
new_li = tmp_li;
}
}
@@ -1825,6 +1835,12 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
*err_code |= ERR_FATAL | ERR_ALERT;
return cfgerr;
}
+ /* assign the ID to the first one only */
+ new_li->luid = new_li->conf.id.key = li->luid;
+ li->luid = 0;
+ eb32_delete(&li->conf.id);
+ if (li->luid)
+ eb32_insert(&fe->conf.used_listener_id, &new_li->conf.id);
}
}
@@ -1832,6 +1848,43 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
return cfgerr;
}
+/* Generate and insert unique GUID for each listeners of <bind_conf> instance
+ * if GUID prefix is defined.
+ *
+ * Returns 0 on success else non-zero.
+ */
+int bind_generate_guid(struct bind_conf *bind_conf)
+{
+ struct listener *l;
+ char *guid_err = NULL;
+
+ if (!bind_conf->guid_prefix)
+ return 0;
+
+ list_for_each_entry(l, &bind_conf->listeners, by_bind) {
+ if (bind_conf->guid_idx == (size_t)-1) {
+ ha_alert("[%s:%d] : error on GUID generation : Too many listeners.\n",
+ bind_conf->file, bind_conf->line);
+ return 1;
+ }
+
+ chunk_printf(&trash, "%s-%lld", bind_conf->guid_prefix,
+ (ullong)bind_conf->guid_idx);
+
+ if (guid_insert(&l->obj_type, b_head(&trash), &guid_err)) {
+ ha_alert("[%s:%d] : error on GUID generation : %s. "
+ "You may fix it by adjusting guid-prefix.\n",
+ bind_conf->file, bind_conf->line, guid_err);
+ ha_free(&guid_err);
+ return 1;
+ }
+
+ ++bind_conf->guid_idx;
+ }
+
+ return 0;
+}
+
/*
* Registers the bind keyword list <kwl> as a list of valid keywords for next
* parsing sessions.
@@ -1975,6 +2028,9 @@ struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file,
#endif
LIST_INIT(&bind_conf->listeners);
+ bind_conf->guid_prefix = NULL;
+ bind_conf->guid_idx = 0;
+
bind_conf->rhttp_srvname = NULL;
return bind_conf;
@@ -2082,6 +2138,26 @@ static int bind_parse_backlog(char **args, int cur_arg, struct proxy *px, struct
return 0;
}
+/* parse the "guid-prefix" bind keyword */
+static int bind_parse_guid_prefix(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ char *prefix = NULL;
+
+ if (!*args[cur_arg + 1]) {
+ memprintf(err, "'%s' : expects an argument", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ prefix = strdup(args[cur_arg + 1]);
+ if (!prefix) {
+ memprintf(err, "'%s' : out of memory", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ conf->guid_prefix = prefix;
+ return 0;
+}
+
/* parse the "id" bind keyword */
static int bind_parse_id(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
@@ -2225,8 +2301,8 @@ int bind_parse_args_list(struct bind_conf *bind_conf, char **args, int cur_arg,
#if (!defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR)) || !defined(IPV6_RECVPKTINFO)
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
if (++listener_count > 1 || !is_inet_addr(&l->rx.addr)) {
- ha_diag_warning("parsing [%s:%d] : '%s %s' in section '%s' : UDP binding on multiple addresses without IP_PKTINFO or equivalent support may be unreliable.\n",
- file, linenum, args[0], args[1], section);
+ ha_warning("parsing [%s:%d] : '%s %s' in section '%s' : UDP binding on multiple addresses without IP_PKTINFO or equivalent support may be unreliable.\n",
+ file, linenum, args[0], args[1], section);
break;
}
}
@@ -2486,6 +2562,7 @@ static struct bind_kw_list bind_kws = { "ALL", { }, {
{ "accept-netscaler-cip", bind_parse_accept_netscaler_cip, 1, 0 }, /* enable NetScaler Client IP insertion protocol */
{ "accept-proxy", bind_parse_accept_proxy, 0, 0 }, /* enable PROXY protocol */
{ "backlog", bind_parse_backlog, 1, 0 }, /* set backlog of listening socket */
+ { "guid-prefix", bind_parse_guid_prefix, 1, 1 }, /* set guid of listening socket */
{ "id", bind_parse_id, 1, 1 }, /* set id of listening socket */
{ "maxconn", bind_parse_maxconn, 1, 0 }, /* set maxconn of listening socket */
{ "name", bind_parse_name, 1, 1 }, /* set name of listening socket */