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.
This commit is contained in:
Willy Tarreau 2017-09-15 08:10:44 +02:00
parent 31794892af
commit 0de59fd53a
3 changed files with 59 additions and 27 deletions

View 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

View 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;

View 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