]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: listeners: new function create_listeners
authorWilly Tarreau <w@1wt.eu>
Fri, 15 Sep 2017 06:10:44 +0000 (08:10 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Sep 2017 09:49:52 +0000 (11:49 +0200)
This function is used to create a series of listeners for a specific
address and a port range. It automatically calls the matching protocol
handlers to add them to the relevant lists. This way cfgparse doesn't
need to manipulate listeners anymore. As an added bonus, the memory
allocation is checked.

include/proto/listener.h
src/cfgparse.c
src/listener.c

index 0ad0beb8cbd46a360107dcbfbd6e762775094737..7fdb1cfad825ab03defe759eb523ba4a83fa6137 100644 (file)
@@ -78,6 +78,17 @@ int unbind_listener_no_close(struct listener *listener);
  */
 int unbind_all_listeners(struct protocol *proto);
 
+
+/* creates one or multiple listeners for bind_conf <bc> on sockaddr <ss> on port
+ * range <portl> to <porth>, and possibly attached to fd <fd> (or -1 for auto
+ * allocation). The address family is taken from ss->ss_family. The number of
+ * jobs and listeners is automatically increased by the number of listeners
+ * created. It returns non-zero on success, zero on error with the error message
+ * set in <err>.
+ */
+int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
+                     int portl, int porth, int fd, char **err);
+
 /* Delete a listener from its protocol's list of listeners. The listener's
  * state is automatically updated from LI_ASSIGNED to LI_INIT. The protocol's
  * number of listeners is updated. Note that the listener must have previously
index 759d407598df86654e90651e60f533fa7ab1885f..9b91b9048ae2f0ab9b9382d3799e8c3565b4e747 100644 (file)
@@ -220,14 +220,13 @@ static struct cfg_kw_list cfg_keywords = {
  */
 int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err)
 {
-       struct listener *l;
        char *next, *dupstr;
        int port, end;
 
        next = dupstr = strdup(str);
 
        while (next && *next) {
-               struct sockaddr_storage ss, *ss2;
+               struct sockaddr_storage *ss2;
                int fd = -1;
 
                str = next;
@@ -283,31 +282,10 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
                }
 
                /* OK the address looks correct */
-               memcpy(&ss, ss2, sizeof(ss));
-
-               for (; port <= end; port++) {
-                       struct protocol *proto = protocol_by_family(ss.ss_family);
-
-                       if (!proto) {
-                               memprintf(err, "unsupported protocol family %d for address '%s'.\n", ss.ss_family, str);
-                               goto fail;
-                       }
-
-                       l = calloc(1, sizeof(*l));
-                       l->obj_type = OBJ_TYPE_LISTENER;
-                       LIST_ADDQ(&curproxy->conf.listeners, &l->by_fe);
-                       LIST_ADDQ(&bind_conf->listeners, &l->by_bind);
-                       l->bind_conf = bind_conf;
-
-                       l->fd = fd;
-                       memcpy(&l->addr, &ss, sizeof(ss));
-                       l->state = LI_INIT;
-
-                       proto->add(l, port);
-
-                       jobs++;
-                       listeners++;
-               } /* end for(port) */
+               if (!create_listeners(bind_conf, ss2, port, end, fd, err)) {
+                       memprintf(err, "%s for address '%s'.\n", *err, str);
+                       goto fail;
+               }
        } /* end while(next) */
        free(dupstr);
        return 1;
index abedd2fef666172cb8081f3e97bd34ff353277a8..47bed179ef46348030c897dc30deb64fd143c8da 100644 (file)
@@ -33,6 +33,7 @@
 #include <proto/freq_ctr.h>
 #include <proto/log.h>
 #include <proto/listener.h>
+#include <proto/protocol.h>
 #include <proto/sample.h>
 #include <proto/stream.h>
 #include <proto/task.h>
@@ -298,6 +299,48 @@ int unbind_all_listeners(struct protocol *proto)
        return ERR_NONE;
 }
 
+/* creates one or multiple listeners for bind_conf <bc> on sockaddr <ss> on port
+ * range <portl> to <porth>, and possibly attached to fd <fd> (or -1 for auto
+ * allocation). The address family is taken from ss->ss_family. The number of
+ * jobs and listeners is automatically increased by the number of listeners
+ * created. It returns non-zero on success, zero on error with the error message
+ * set in <err>.
+ */
+int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
+                     int portl, int porth, int fd, char **err)
+{
+       struct protocol *proto = protocol_by_family(ss->ss_family);
+       struct listener *l;
+       int port;
+
+       if (!proto) {
+               memprintf(err, "unsupported protocol family %d", ss->ss_family);
+               return 0;
+       }
+
+       for (port = portl; port <= porth; port++) {
+               l = calloc(1, sizeof(*l));
+               if (!l) {
+                       memprintf(err, "out of memory");
+                       return 0;
+               }
+               l->obj_type = OBJ_TYPE_LISTENER;
+               LIST_ADDQ(&bc->frontend->conf.listeners, &l->by_fe);
+               LIST_ADDQ(&bc->listeners, &l->by_bind);
+               l->bind_conf = bc;
+
+               l->fd = fd;
+               memcpy(&l->addr, ss, sizeof(*ss));
+               l->state = LI_INIT;
+
+               proto->add(l, port);
+
+               jobs++;
+               listeners++;
+       }
+       return 1;
+}
+
 /* Delete a listener from its protocol's list of listeners. The listener's
  * state is automatically updated from LI_ASSIGNED to LI_INIT. The protocol's
  * number of listeners is updated. Note that the listener must have previously