*/
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
*/
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;
}
/* 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;
#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>
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