diff --git a/include/haproxy/listener.h b/include/haproxy/listener.h index fc37128a6..726931624 100644 --- a/include/haproxy/listener.h +++ b/include/haproxy/listener.h @@ -85,13 +85,13 @@ void unbind_listener_no_close(struct listener *listener); /* 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 . + * allocation). The address family is taken from ss->ss_family, and the protocol + * passed in must be usable on this 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); + int portl, int porth, int fd, struct protocol *proto, 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 diff --git a/src/cfgparse.c b/src/cfgparse.c index 23a369561..c4dd262ff 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -111,6 +111,7 @@ 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 protocol *proto; char *next, *dupstr; int port, end; @@ -133,8 +134,14 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, if (!ss2) goto fail; + proto = protocol_by_family(ss2->ss_family); + if (!proto) { + memprintf(err, "unsupported protocol family %d fr address '%s'", ss2->ss_family, str); + goto fail; + } + /* OK the address looks correct */ - if (!create_listeners(bind_conf, ss2, port, end, fd, err)) { + if (!create_listeners(bind_conf, ss2, port, end, fd, proto, err)) { memprintf(err, "%s for address '%s'.\n", *err, str); goto fail; } @@ -160,6 +167,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, */ int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err) { + struct protocol *proto; char *next, *dupstr; int port, end; @@ -182,8 +190,14 @@ int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, if (!ss2) goto fail; + proto = protocol_by_family(ss2->ss_family); + if (!proto) { + memprintf(err, "unsupported protocol family %d fr address '%s'", ss2->ss_family, str); + goto fail; + } + /* OK the address looks correct */ - if (!create_listeners(bind_conf, ss2, port, end, fd, err)) { + if (!create_listeners(bind_conf, ss2, port, end, fd, proto, err)) { memprintf(err, "%s for address '%s'.\n", *err, str); goto fail; } diff --git a/src/listener.c b/src/listener.c index 263508bc4..59aedb224 100644 --- a/src/listener.c +++ b/src/listener.c @@ -535,23 +535,17 @@ void unbind_listener_no_close(struct listener *listener) /* 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 . + * allocation). The address family is taken from ss->ss_family, and the protocol + * passed in must be usable on this 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) + int portl, int porth, int fd, struct protocol *proto, 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) {