From: Willy Tarreau Date: Fri, 15 Sep 2017 06:10:44 +0000 (+0200) Subject: MINOR: listeners: new function create_listeners X-Git-Tag: v1.8-dev3~95 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0de59fd53a117a2878141522acd03e3338320218;p=thirdparty%2Fhaproxy.git MINOR: listeners: new function create_listeners 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. --- diff --git a/include/proto/listener.h b/include/proto/listener.h index 0ad0beb8cb..7fdb1cfad8 100644 --- a/include/proto/listener.h +++ b/include/proto/listener.h @@ -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 on sockaddr on port + * range to , and possibly attached to 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 . + */ +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 diff --git a/src/cfgparse.c b/src/cfgparse.c index 759d407598..9b91b9048a 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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; diff --git a/src/listener.c b/src/listener.c index abedd2fef6..47bed179ef 100644 --- a/src/listener.c +++ b/src/listener.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,48 @@ int unbind_all_listeners(struct protocol *proto) return ERR_NONE; } +/* creates one or multiple listeners for bind_conf on sockaddr on port + * range to , and possibly attached to 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 . + */ +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