mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-21 05:06:56 +00:00
MINOR: tools: make str2sa_range() directly return the protocol
We'll need this so that it can return pointers to stacked protocol in the future (for QUIC). In addition this removes a lot of tests for protocol validity in the callers. Some of them were checked further apart, or after a call to str2listener() and they were simplified as well. There's still a trick, we can fail to return a protocol in case the caller accepts an fqdn for use later. This is what servers do and in this case it is valid to return no protocol. A typical example is: server foo localhost:1111
This commit is contained in:
parent
9b3178df23
commit
5fc9328aa2
@ -241,10 +241,9 @@ static inline int is_idchar(char c)
|
||||
* If <pfx> is non-null, it is used as a string prefix before any path-based
|
||||
* address (typically the path to a unix socket).
|
||||
*/
|
||||
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);
|
||||
struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int *high, int *fd,
|
||||
struct protocol **proto, char **err,
|
||||
const char *pfx, char **fqdn, unsigned int opts);
|
||||
|
||||
/* converts <str> to a struct in_addr containing a network mask. It can be
|
||||
* passed in dotted form (255.255.255.0) or in CIDR form (24). It returns 1
|
||||
|
@ -2600,7 +2600,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, &proto,
|
||||
&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);
|
||||
@ -2608,8 +2608,7 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -2859,7 +2858,7 @@ stats_error_parsing:
|
||||
curproxy->conn_src.iface_name = NULL;
|
||||
curproxy->conn_src.iface_len = 0;
|
||||
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL,
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, &proto,
|
||||
&errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
@ -2868,8 +2867,7 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -2938,7 +2936,7 @@ stats_error_parsing:
|
||||
} else {
|
||||
struct sockaddr_storage *sk;
|
||||
|
||||
sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, NULL,
|
||||
sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, NULL, &proto,
|
||||
&errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
@ -2947,8 +2945,7 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
|
||||
file, linenum, args[cur_arg], args[cur_arg+1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
|
@ -127,19 +127,13 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
||||
*next++ = 0;
|
||||
}
|
||||
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, err,
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, 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_STREAM | PA_O_XPRT);
|
||||
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, proto, err)) {
|
||||
memprintf(err, "%s for address '%s'.\n", *err, str);
|
||||
@ -183,19 +177,13 @@ int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
||||
*next++ = 0;
|
||||
}
|
||||
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, err,
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, 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;
|
||||
|
||||
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, proto, err)) {
|
||||
memprintf(err, "%s for address '%s'.\n", *err, str);
|
||||
@ -642,7 +630,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
}
|
||||
}
|
||||
newpeer->addr = l->rx.addr;
|
||||
newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
|
||||
newpeer->proto = l->rx.proto;
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
@ -1001,7 +989,6 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
|
||||
else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
|
||||
struct sockaddr_storage *sk;
|
||||
int port1, port2;
|
||||
struct protocol *proto;
|
||||
|
||||
if (!*args[2]) {
|
||||
ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
|
||||
@ -1040,21 +1027,14 @@ 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, NULL, &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, 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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
newnameserver->addr = *sk;
|
||||
}
|
||||
else if (strcmp(args[0], "parse-resolv-conf") == 0) {
|
||||
@ -1410,15 +1390,15 @@ 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, NULL, &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, &proto,
|
||||
&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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
|
||||
if (!proto->connect || proto->sock_prot != IPPROTO_TCP) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
|
@ -2638,15 +2638,14 @@ 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, NULL, errmsg, NULL, NULL,
|
||||
sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, &proto, 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;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
memprintf(errmsg, "'%s %s' : connect() not supported for this address family.",
|
||||
args[*cur_arg], args[*cur_arg+1]);
|
||||
goto error;
|
||||
|
@ -2475,15 +2475,14 @@ 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, NULL,
|
||||
if ((sk = str2sa_range(msg, &port, &port1, &port2, NULL, &proto,
|
||||
&errmsg, NULL, NULL, PA_O_STREAM)) == 0) {
|
||||
goto error;
|
||||
}
|
||||
free(msg);
|
||||
msg = NULL;
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -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, NULL, PA_O_PORT_OK | PA_O_STREAM);
|
||||
addr = str2sa_range(ip, NULL, &low, &high, NULL, 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));
|
||||
|
@ -1019,7 +1019,7 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err)
|
||||
goto done;
|
||||
}
|
||||
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, &fd,
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, &fd, NULL,
|
||||
err, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_RAW_FD | PA_O_DGRAM);
|
||||
if (!sk)
|
||||
goto error;
|
||||
|
20
src/server.c
20
src/server.c
@ -659,15 +659,14 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, &proto,
|
||||
&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;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("'%s %s' : connect() not supported for this address family.\n",
|
||||
args[*cur_arg], args[*cur_arg + 1]);
|
||||
goto err;
|
||||
@ -745,15 +744,14 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, NULL, &proto,
|
||||
&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;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("'%s %s' : connect() not supported for this address family.\n",
|
||||
args[*cur_arg], args[*cur_arg + 1]);
|
||||
goto err;
|
||||
@ -842,15 +840,14 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, &proto,
|
||||
&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;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
ha_alert("'%s %s' : connect() not supported for this address family.\n", args[*cur_arg], args[*cur_arg + 1]);
|
||||
goto err;
|
||||
}
|
||||
@ -2030,7 +2027,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[cur_arg], &port, &port1, &port2, NULL, &proto,
|
||||
&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);
|
||||
@ -2038,8 +2035,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
||||
goto out;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!fqdn && (!proto || !proto->connect)) {
|
||||
if (!fqdn && !proto->connect) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
|
@ -2224,15 +2224,14 @@ 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, NULL,
|
||||
sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, NULL, &proto,
|
||||
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;
|
||||
}
|
||||
|
||||
proto = protocol_by_family(sk->ss_family);
|
||||
if (!proto || !proto->connect) {
|
||||
if (!proto->connect) {
|
||||
memprintf(errmsg, "'%s' : connect() not supported for this address family.\n",
|
||||
args[cur_arg]);
|
||||
goto error;
|
||||
|
23
src/tools.c
23
src/tools.c
@ -47,6 +47,7 @@
|
||||
#include <haproxy/hlua.h>
|
||||
#include <haproxy/listener.h>
|
||||
#include <haproxy/namespace.h>
|
||||
#include <haproxy/protocol.h>
|
||||
#include <haproxy/ssl_sock.h>
|
||||
#include <haproxy/stream_interface.h>
|
||||
#include <haproxy/task.h>
|
||||
@ -864,13 +865,18 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
|
||||
* the address when cast to sockaddr_in and the address family is
|
||||
* AF_CUST_EXISTING_FD.
|
||||
*
|
||||
* The matching protocol will be set into <proto> if non-null.
|
||||
*
|
||||
* 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, int *fd, 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,
|
||||
struct protocol **proto, char **err,
|
||||
const char *pfx, char **fqdn, unsigned int opts)
|
||||
{
|
||||
static THREAD_LOCAL struct sockaddr_storage ss;
|
||||
struct sockaddr_storage *ret = NULL;
|
||||
struct protocol *new_proto = NULL;
|
||||
char *back, *str2;
|
||||
char *port1, *port2;
|
||||
int portl, porth, porta;
|
||||
@ -1170,6 +1176,19 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
||||
ss.ss_family = AF_CUST_UDP4;
|
||||
}
|
||||
|
||||
if (proto) {
|
||||
/* Note: if the caller asks for a proto, we must find one,
|
||||
* except if we return with an fqdn that will resolve later,
|
||||
* in which case the address is not known yet (this is only
|
||||
* for servers actually).
|
||||
*/
|
||||
new_proto = protocol_by_family(ss.ss_family);
|
||||
if (!new_proto && (!fqdn || !*fqdn)) {
|
||||
memprintf(err, "unsupported protocol family %d for address '%s'", ss.ss_family, str);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = &ss;
|
||||
out:
|
||||
if (port)
|
||||
@ -1180,6 +1199,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
||||
*high = porth;
|
||||
if (fd)
|
||||
*fd = new_fd;
|
||||
if (proto)
|
||||
*proto = new_proto;
|
||||
free(back);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user