diff --git a/include/haproxy/cfgparse.h b/include/haproxy/cfgparse.h index 15a46ec8a..85bd164f6 100644 --- a/include/haproxy/cfgparse.h +++ b/include/haproxy/cfgparse.h @@ -96,6 +96,7 @@ void cfg_unregister_keywords(struct cfg_kw_list *kwl); void init_default_instance(); int check_config_validity(); int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err); +int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err); int cfg_register_section(char *section_name, int (*section_parser)(const char *, int, char **, int), int (*post_section_parser)()); diff --git a/src/cfgparse.c b/src/cfgparse.c index fa546d3d3..5451359c4 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -146,6 +146,55 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, return 0; } +/* + * converts to a list of datagram-oriented listeners which are dynamically + * allocated. + * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where : + * - can be empty or "*" to indicate INADDR_ANY ; + * - is a numerical port from 1 to 65535 ; + * - indicates to use the range from to instead (inclusive). + * This can be repeated as many times as necessary, separated by a coma. + * Function returns 1 for success or 0 if error. In case of errors, if is + * not NULL, it must be a valid pointer to either NULL or a freeable area that + * will be replaced with an error message. + */ +int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err) +{ + char *next, *dupstr; + int port, end; + + next = dupstr = strdup(str); + + while (next && *next) { + struct sockaddr_storage *ss2; + int fd = -1; + + str = next; + /* 1) look for the end of the first address */ + if ((next = strchr(str, ',')) != NULL) { + *next++ = 0; + } + + ss2 = str2sa_range(str, NULL, &port, &end, &fd, err, + curproxy == global.stats_fe ? NULL : global.unix_bind.prefix, + NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_PORT_RANGE | + PA_O_SOCKET_FD | PA_O_DGRAM | PA_O_XPRT); + if (!ss2) + goto fail; + + /* OK the address looks correct */ + 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; + fail: + free(dupstr); + return 0; +} + /* * Report an error in when there are too many arguments. This version is * intended to be used by keyword parsers so that the message will be included