mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: tools: make str2sa_range() directly return type hints
str2sa_range() already allows the caller to provide <proto> in order to
get a pointer on the protocol matching with the string input thanks to
5fc9328a
("MINOR: tools: make str2sa_range() directly return the protocol")
However, as stated into the commit message, there is 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"
In this case, we're unable to return protocol because the protocol lookup
depends on both the [proto type + xprt type] and the [family type] to be
known.
While family type might not be directly resolved when fqdn is involved
(because family type might be discovered using DNS queries), proto type
and xprt type are already known. As such, the caller might be interested
in knowing those address related hints even if the address family type is
not yet resolved and thus the matching protocol cannot be looked up.
Thus in this patch we add the optional net_addr_type (custom type)
argument to str2sa_range to enable the caller to check the protocol type
and transport type when the function succeeds.
This commit is contained in:
parent
ebf90ca550
commit
12582eb8e5
@ -157,4 +157,10 @@ struct net_addr {
|
||||
} addr;
|
||||
};
|
||||
|
||||
/* holds socket and xprt types for a given address */
|
||||
struct net_addr_type {
|
||||
int proto_type; // socket layer
|
||||
int xprt_type; // transport layer
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_TOOLS_T_H */
|
||||
|
@ -284,8 +284,8 @@ 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 *fd,
|
||||
struct protocol **proto, char **err,
|
||||
const char *pfx, char **fqdn, unsigned int opts);
|
||||
struct protocol **proto, struct net_addr_type *sa_type,
|
||||
char **err, const char *pfx, char **fqdn, unsigned int opts);
|
||||
|
||||
|
||||
/* converts <addr> and <port> into a string representation of the address and port. This is sort
|
||||
|
@ -2518,7 +2518,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
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, NULL,
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
@ -2852,7 +2852,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
ha_free(&curproxy->conn_src.iface_name);
|
||||
curproxy->conn_src.iface_len = 0;
|
||||
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, NULL,
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
@ -2926,7 +2926,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
} else {
|
||||
struct sockaddr_storage *sk;
|
||||
|
||||
sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, NULL, NULL,
|
||||
sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
|
||||
|
@ -155,7 +155,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
||||
*next++ = 0;
|
||||
}
|
||||
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, err,
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, NULL, err,
|
||||
(curproxy == global.cli_fe || curproxy == mworker_proxy) ? 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);
|
||||
@ -241,7 +241,7 @@ int str2receiver(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
||||
*next++ = 0;
|
||||
}
|
||||
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, err,
|
||||
ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, NULL, err,
|
||||
curproxy == global.cli_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);
|
||||
@ -1178,7 +1178,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, NULL, &proto,
|
||||
sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
|
@ -2033,7 +2033,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, NULL, NULL, errmsg, NULL, NULL,
|
||||
sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, NULL, NULL, errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
memprintf(errmsg, "'%s' : %s", args[*cur_arg], *errmsg);
|
||||
|
@ -3052,7 +3052,7 @@ 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, &proto,
|
||||
if ((sk = str2sa_range(msg, &port, &port1, &port2, NULL, &proto, NULL,
|
||||
&errmsg, NULL, NULL, PA_O_STREAM)) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -3228,7 +3228,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L)
|
||||
csk_ctx->srv = socket_tcp;
|
||||
|
||||
/* Parse ip address. */
|
||||
addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, NULL, NULL, PA_O_PORT_OK | PA_O_STREAM);
|
||||
addr = str2sa_range(ip, NULL, &low, &high, NULL, 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));
|
||||
|
@ -455,7 +455,7 @@ int httpclient_set_dst(struct httpclient *hc, const char *dst)
|
||||
|
||||
sockaddr_free(&hc->dst);
|
||||
/* 'sk' is statically allocated (no need to be freed). */
|
||||
sk = str2sa_range(dst, NULL, NULL, NULL, NULL, NULL,
|
||||
sk = str2sa_range(dst, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_PORT_OK | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
|
@ -1123,7 +1123,7 @@ static int parse_log_target(char *raw, struct log_target *target, char **err)
|
||||
target->type = LOG_TARGET_DGRAM; // default type
|
||||
|
||||
/* parse the target address */
|
||||
sk = str2sa_range(raw, NULL, &port1, &port2, &fd, &proto,
|
||||
sk = str2sa_range(raw, NULL, &port1, &port2, &fd, &proto, NULL,
|
||||
err, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_RAW_FD | PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
|
||||
if (!sk)
|
||||
|
@ -3521,7 +3521,7 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
|
||||
}
|
||||
}
|
||||
|
||||
sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto,
|
||||
sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto, NULL,
|
||||
&errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
|
@ -1432,7 +1432,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_RANGE | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
@ -1520,7 +1520,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
@ -1610,7 +1610,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, NULL, NULL,
|
||||
&errmsg, NULL, NULL,
|
||||
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
@ -3006,7 +3006,7 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
|
||||
if (!(parse_flags & SRV_PARSE_PARSE_ADDR))
|
||||
goto skip_addr;
|
||||
|
||||
sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, &newsrv->addr_proto,
|
||||
sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, &newsrv->addr_proto, NULL,
|
||||
&errmsg, NULL, &fqdn,
|
||||
(parse_flags & SRV_PARSE_INITIAL_RESOLVE ? PA_O_RESOLVE : 0) | PA_O_PORT_OK |
|
||||
(parse_flags & SRV_PARSE_IN_PEER_SECTION ? PA_O_PORT_MAND : PA_O_PORT_OFS) |
|
||||
|
@ -2413,7 +2413,7 @@ 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, NULL,
|
||||
sk = str2sa_range(args[cur_arg+1], NULL, &port1, &port2, NULL, NULL, NULL,
|
||||
errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
|
||||
if (!sk) {
|
||||
memprintf(errmsg, "'%s' : %s.", args[cur_arg], *errmsg);
|
||||
|
16
src/tools.c
16
src/tools.c
@ -947,13 +947,15 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
|
||||
* AF_CUST_EXISTING_FD.
|
||||
*
|
||||
* The matching protocol will be set into <proto> if non-null.
|
||||
* The address protocol and transport types hints which are directly resolved
|
||||
* will be set into <sa_type> if not 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,
|
||||
struct protocol **proto, char **err,
|
||||
const char *pfx, char **fqdn, unsigned int opts)
|
||||
struct protocol **proto, struct net_addr_type *sa_type,
|
||||
char **err, const char *pfx, char **fqdn, unsigned int opts)
|
||||
{
|
||||
static THREAD_LOCAL struct sockaddr_storage ss;
|
||||
struct sockaddr_storage *ret = NULL;
|
||||
@ -963,8 +965,8 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
||||
int portl, porth, porta;
|
||||
int abstract = 0;
|
||||
int new_fd = -1;
|
||||
enum proto_type proto_type;
|
||||
int ctrl_type;
|
||||
enum proto_type proto_type = 0; // to shut gcc warning
|
||||
int ctrl_type = 0; // to shut gcc warning
|
||||
|
||||
portl = porth = porta = 0;
|
||||
if (fqdn)
|
||||
@ -1383,6 +1385,10 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
|
||||
*fd = new_fd;
|
||||
if (proto)
|
||||
*proto = new_proto;
|
||||
if (sa_type) {
|
||||
sa_type->proto_type = proto_type;
|
||||
sa_type->xprt_type = (ctrl_type == SOCK_DGRAM) ? PROTO_TYPE_DGRAM : PROTO_TYPE_STREAM;
|
||||
}
|
||||
free(back);
|
||||
return ret;
|
||||
}
|
||||
@ -6018,7 +6024,7 @@ const char *hash_ipanon(uint32_t scramble, char *ipstring, int hasport)
|
||||
sa = &ss;
|
||||
}
|
||||
else {
|
||||
sa = str2sa_range(ipstring, NULL, NULL, NULL, NULL, NULL, &errmsg, NULL, NULL,
|
||||
sa = str2sa_range(ipstring, NULL, NULL, NULL, NULL, NULL, NULL, &errmsg, NULL, NULL,
|
||||
PA_O_PORT_OK | PA_O_STREAM | PA_O_DGRAM | PA_O_XPRT | PA_O_CONNECT |
|
||||
PA_O_PORT_RANGE | PA_O_PORT_OFS | PA_O_RESOLVE);
|
||||
if (sa == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user