]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: make str2sa_range() optionally return the fd
authorWilly Tarreau <w@1wt.eu>
Tue, 15 Sep 2020 12:01:16 +0000 (14:01 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Sep 2020 20:08:08 +0000 (22:08 +0200)
If a file descriptor was passed, we can optionally return it. This will
be useful for listening sockets which are both a pre-bound FD and a ready
socket.

include/haproxy/tools.h
src/cfgparse-listen.c
src/cfgparse.c
src/check.c
src/cli.c
src/hlua.c
src/log.c
src/server.c
src/tcpcheck.c
src/tools.c

index 095485f4d4a9bb1d10a8baa5efe20d3eae0ba0f8..25a66f8fd04f9c4f48cbfaa9fb179a31fcc4bf19 100644 (file)
@@ -242,7 +242,7 @@ static inline int is_idchar(char c)
  * address (typically the path to a unix socket).
  */
 struct sockaddr_storage *str2sa_range(const char *str,
-                                      int *port, int *low, int *high,
+                                      int *port, int *low, int *high, int *fd,
                                       char **err, const char *pfx,
                                       char **fqdn, unsigned int opts);
 
index 2819ad9e3cd46388e2b330c386e5e1860699750f..d29505a3ebf085cd51e7f2ba0959e5a234a8ba6f 100644 (file)
@@ -2600,7 +2600,8 @@ stats_error_parsing:
                else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
                        err_code |= ERR_WARN;
 
-               sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT);
+               sk = str2sa_range(args[1], NULL, &port1, &port2, NULL,
+                                 &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
@@ -2858,7 +2859,8 @@ stats_error_parsing:
                curproxy->conn_src.iface_name = NULL;
                curproxy->conn_src.iface_len = 0;
 
-               sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
+               sk = str2sa_range(args[1], NULL, &port1, &port2, NULL,
+                                 &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
                                 file, linenum, args[0], args[1], errmsg);
@@ -2936,7 +2938,8 @@ stats_error_parsing:
                                } else {
                                        struct sockaddr_storage *sk;
 
-                                       sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
+                                       sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, NULL,
+                                                         &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
                                        if (!sk) {
                                                ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
                                                         file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
index 1ff555c3599a7fff2b2d217a421d54b5c3ef25a0..59827f45812d72c42f7f0da6a7ae6b13d54462dc 100644 (file)
@@ -126,7 +126,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
                        *next++ = 0;
                }
 
-               ss2 = str2sa_range(str, NULL, &port, &end, err,
+               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_STREAM | PA_O_XPRT);
@@ -1009,7 +1009,7 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                newnameserver->conf.line = linenum;
                newnameserver->id = strdup(args[1]);
 
-               sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM);
+               sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
@@ -1385,7 +1385,7 @@ int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
 
                newmailer->id = strdup(args[1]);
 
-               sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT);
+               sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
index 21978da50979f6b6714dfd14231609f285448f4d..40788ae98e2f74548295f27a24f68c999713c36c 100644 (file)
@@ -2638,7 +2638,7 @@ static int srv_parse_addr(char **args, int *cur_arg, struct proxy *curpx, struct
                goto error;
        }
 
-       sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL,
+       sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, errmsg, NULL, NULL,
                          PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
        if (!sk) {
                memprintf(errmsg, "'%s' : %s", args[*cur_arg], *errmsg);
index 55d2a034afa58181bbb1f1c9b469d4767a7a8411..2892d882f4daea22c0c1c1d51018d5eab9e306b8 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2475,7 +2475,8 @@ int mworker_cli_proxy_create()
                newsrv->conf.line = 0;
 
                memprintf(&msg, "sockpair@%d", child->ipc_fd[0]);
-               if ((sk = str2sa_range(msg, &port, &port1, &port2, &errmsg, NULL, NULL, PA_O_STREAM)) == 0) {
+               if ((sk = str2sa_range(msg, &port, &port1, &port2, NULL,
+                                      &errmsg, NULL, NULL, PA_O_STREAM)) == 0) {
                        goto error;
                }
                free(msg);
index b3b93e8d0a62615fe2ab807dc5233777b31204ae..5589482b024c34ee9e6266631ffebc1c83eef56a 100644 (file)
@@ -2534,7 +2534,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L)
        }
 
        /* Parse ip address. */
-       addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, PA_O_PORT_OK | PA_O_STREAM);
+       addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, NULL, PA_O_PORT_OK | PA_O_STREAM);
        if (!addr) {
                xref_unlock(&socket->xref, peer);
                WILL_LJMP(luaL_error(L, "connect: cannot parse destination address '%s'", ip));
index e31d85b700ef08f41dad9698ab08c8d23631171b..fcb16f6be2d9787d589b686dcb243c2fb6d0a1dc 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1021,7 +1021,8 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err)
        if (strncmp(args[1], "fd@", 3) == 0)
                logsrv->type = LOG_TARGET_FD;
 
-       sk = str2sa_range(args[1], NULL, &port1, &port2, err, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_RAW_FD | PA_O_DGRAM);
+       sk = str2sa_range(args[1], NULL, &port1, &port2, NULL,
+                         err, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_RAW_FD | PA_O_DGRAM);
        if (!sk)
                goto error;
        logsrv->addr = *sk;
index 5c457186f449fbccadbf2fee67904819a697ebd8..84b66f734ca458db5dd96fda43b8a99fd48952a3 100644 (file)
@@ -659,7 +659,8 @@ static int srv_parse_source(char **args, int *cur_arg,
        }
 
        /* 'sk' is statically allocated (no need to be freed). */
-       sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_RANGE | PA_O_STREAM);
+       sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL,
+                         &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_RANGE | PA_O_STREAM);
        if (!sk) {
                memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
                goto err;
@@ -744,7 +745,8 @@ static int srv_parse_source(char **args, int *cur_arg,
                                int port1, port2;
 
                                /* 'sk' is statically allocated (no need to be freed). */
-                               sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
+                               sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, NULL,
+                                                 &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
                                if (!sk) {
                                        ha_alert("'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
                                        goto err;
@@ -840,7 +842,8 @@ static int srv_parse_socks4(char **args, int *cur_arg,
        }
 
        /* 'sk' is statically allocated (no need to be freed). */
-       sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM);
+       sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL,
+                         &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM);
        if (!sk) {
                memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
                goto err;
@@ -2027,7 +2030,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
                        if (!parse_addr)
                                goto skip_addr;
 
-                       sk = str2sa_range(args[cur_arg], &port, &port1, &port2, &errmsg, NULL, &fqdn, (initial_resolve ? PA_O_RESOLVE : 0) | PA_O_PORT_OK | PA_O_PORT_OFS | PA_O_STREAM | PA_O_XPRT);
+                       sk = str2sa_range(args[cur_arg], &port, &port1, &port2, NULL,
+                                         &errmsg, NULL, &fqdn, (initial_resolve ? PA_O_RESOLVE : 0) | PA_O_PORT_OK | PA_O_PORT_OFS | PA_O_STREAM | PA_O_XPRT);
                        if (!sk) {
                                ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
                                err_code |= ERR_ALERT | ERR_FATAL;
index abd92cf15cb9a6115bab36a5d4c1e11ef37f697c..8da89559b832592442e6a3875a88f70692caf039 100644 (file)
@@ -2224,7 +2224,8 @@ struct tcpcheck_rule *parse_tcpcheck_connect(char **args, int cur_arg, struct pr
                                goto error;
                        }
 
-                       sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
+                       sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, NULL,
+                                         errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
                        if (!sk) {
                                memprintf(errmsg, "'%s' : %s.", args[cur_arg], *errmsg);
                                goto error;
index 4f61ae256298e5ad5b5cab49c02a1dd1f23246dc..9fffc702998521739f1755c2b36982a8cbbcbda4 100644 (file)
@@ -863,8 +863,11 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
  * When a file descriptor is passed, its value is put into the s_addr part of
  * the address when cast to sockaddr_in and the address family is
  * AF_CUST_EXISTING_FD.
+ *
+ * Any known file descriptor is also assigned to <fd> if non-null, otherwise it
+ * is forced to -1.
  */
-struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, char **err, const char *pfx, char **fqdn, unsigned int opts)
+struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, int *fd, char **err, const char *pfx, char **fqdn, unsigned int opts)
 {
        static THREAD_LOCAL struct sockaddr_storage ss;
        struct sockaddr_storage *ret = NULL;
@@ -873,6 +876,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
        int portl, porth, porta;
        int abstract = 0;
        int is_udp = 0;
+       int new_fd = -1;
 
        portl = porth = porta = 0;
        if (fqdn)
@@ -941,24 +945,26 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
        if (ss.ss_family == AF_CUST_SOCKPAIR) {
                char *endptr;
 
-               ((struct sockaddr_in *)&ss)->sin_addr.s_addr = strtol(str2, &endptr, 10);
-               ((struct sockaddr_in *)&ss)->sin_port = 0;
-
-               if (!*str2 || *endptr) {
+               new_fd = strtol(str2, &endptr, 10);
+               if (!*str2 || new_fd < 0 || *endptr) {
                        memprintf(err, "file descriptor '%s' is not a valid integer in '%s'\n", str2, str);
                        goto out;
                }
+
+               ((struct sockaddr_in *)&ss)->sin_addr.s_addr = new_fd;
+               ((struct sockaddr_in *)&ss)->sin_port = 0;
        }
        else if (ss.ss_family == AF_CUST_EXISTING_FD) {
                char *endptr;
 
-               ((struct sockaddr_in *)&ss)->sin_addr.s_addr = strtol(str2, &endptr, 10);
-               ((struct sockaddr_in *)&ss)->sin_port = 0;
-
-               if (!*str2 || *endptr) {
+               new_fd = strtol(str2, &endptr, 10);
+               if (!*str2 || new_fd < 0 || *endptr) {
                        memprintf(err, "file descriptor '%s' is not a valid integer in '%s'\n", str2, str);
                        goto out;
                }
+
+               ((struct sockaddr_in *)&ss)->sin_addr.s_addr = new_fd;
+               ((struct sockaddr_in *)&ss)->sin_port = 0;
        }
        else if (ss.ss_family == AF_UNIX) {
                struct sockaddr_un *un = (struct sockaddr_un *)&ss;
@@ -1111,6 +1117,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
                *low = portl;
        if (high)
                *high = porth;
+       if (fd)
+               *fd = new_fd;
        free(back);
        return ret;
 }