MAJOR: listeners: use dual-linked lists to chain listeners with frontends
Navigating through listeners was very inconvenient and error-prone. Not to
mention that listeners were linked in reverse order and reverted afterwards.
In order to definitely get rid of these issues, we now do the following :
- frontends have a dual-linked list of bind_conf
- frontends have a dual-linked list of listeners
- bind_conf have a dual-linked list of listeners
- listeners have a pointer to their bind_conf
This way we can now navigate from anywhere to anywhere and always find the
proper bind_conf for a given listener, as well as find the list of listeners
for a current bind_conf.
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 5f56ad5..58fd06d 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -349,17 +349,11 @@
}
/* parse the "mode" bind keyword */
-static int bind_parse_mode(char **args, int cur_arg, struct proxy *px, struct listener *last, char **err)
+static int bind_parse_mode(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
int val;
- if (px->listen->addr.ss_family != AF_UNIX) {
- if (err)
- memprintf(err, "'%s' option is only supported on unix sockets", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
-
if (!*args[cur_arg + 1]) {
if (err)
memprintf(err, "'%s' : missing mode (octal integer expected)", args[cur_arg]);
@@ -368,24 +362,20 @@
val = strtol(args[cur_arg + 1], NULL, 8);
- for (l = px->listen; l != last; l = l->next)
- l->perm.ux.mode = val;
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_UNIX)
+ l->perm.ux.mode = val;
+ }
return 0;
}
/* parse the "gid" bind keyword */
-static int bind_parse_gid(char **args, int cur_arg, struct proxy *px, struct listener *last, char **err)
+static int bind_parse_gid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
int val;
- if (px->listen->addr.ss_family != AF_UNIX) {
- if (err)
- memprintf(err, "'%s' option is only supported on unix sockets", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
-
if (!*args[cur_arg + 1]) {
if (err)
memprintf(err, "'%s' : missing value", args[cur_arg]);
@@ -393,24 +383,20 @@
}
val = atol(args[cur_arg + 1]);
- for (l = px->listen; l != last; l = l->next)
- l->perm.ux.gid = val;
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_UNIX)
+ l->perm.ux.gid = val;
+ }
return 0;
}
/* parse the "group" bind keyword */
-static int bind_parse_group(char **args, int cur_arg, struct proxy *px, struct listener *last, char **err)
+static int bind_parse_group(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
struct group *group;
- if (px->listen->addr.ss_family != AF_UNIX) {
- if (err)
- memprintf(err, "'%s' option is only supported on unix sockets", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
-
if (!*args[cur_arg + 1]) {
if (err)
memprintf(err, "'%s' : missing group name", args[cur_arg]);
@@ -424,24 +410,20 @@
return ERR_ALERT | ERR_FATAL;
}
- for (l = px->listen; l != last; l = l->next)
- l->perm.ux.gid = group->gr_gid;
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_UNIX)
+ l->perm.ux.gid = group->gr_gid;
+ }
return 0;
}
/* parse the "uid" bind keyword */
-static int bind_parse_uid(char **args, int cur_arg, struct proxy *px, struct listener *last, char **err)
+static int bind_parse_uid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
int val;
- if (px->listen->addr.ss_family != AF_UNIX) {
- if (err)
- memprintf(err, "'%s' option is only supported on unix sockets", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
-
if (!*args[cur_arg + 1]) {
if (err)
memprintf(err, "'%s' : missing value", args[cur_arg]);
@@ -449,24 +431,20 @@
}
val = atol(args[cur_arg + 1]);
- for (l = px->listen; l != last; l = l->next)
- l->perm.ux.uid = val;
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_UNIX)
+ l->perm.ux.uid = val;
+ }
return 0;
}
/* parse the "user" bind keyword */
-static int bind_parse_user(char **args, int cur_arg, struct proxy *px, struct listener *last, char **err)
+static int bind_parse_user(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
struct passwd *user;
- if (px->listen->addr.ss_family != AF_UNIX) {
- if (err)
- memprintf(err, "'%s' option is only supported on unix sockets", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
-
if (!*args[cur_arg + 1]) {
if (err)
memprintf(err, "'%s' : missing user name", args[cur_arg]);
@@ -480,8 +458,10 @@
return ERR_ALERT | ERR_FATAL;
}
- for (l = px->listen; l != last; l = l->next)
- l->perm.ux.uid = user->pw_uid;
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_UNIX)
+ l->perm.ux.uid = user->pw_uid;
+ }
return 0;
}