diff --git a/include/haproxy/tools-t.h b/include/haproxy/tools-t.h index 805ade6a3..32d8193fe 100644 --- a/include/haproxy/tools-t.h +++ b/include/haproxy/tools-t.h @@ -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 */ diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index 2fc92bb90..e3b847905 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.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 and into a string representation of the address and port. This is sort diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 0b6f7fa07..6c7cc6382 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -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", diff --git a/src/cfgparse.c b/src/cfgparse.c index 11d262455..312b1d709 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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) { diff --git a/src/check.c b/src/check.c index 91fdbcb8c..51c028189 100644 --- a/src/check.c +++ b/src/check.c @@ -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); diff --git a/src/cli.c b/src/cli.c index 0a78ed780..b176d5232 100644 --- a/src/cli.c +++ b/src/cli.c @@ -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; } diff --git a/src/hlua.c b/src/hlua.c index 7e0580d35..c5a1c615b 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -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)); diff --git a/src/http_client.c b/src/http_client.c index e8fdf42a1..fca13a297 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -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) { diff --git a/src/log.c b/src/log.c index 3458f93f9..5efc08b3a 100644 --- a/src/log.c +++ b/src/log.c @@ -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) diff --git a/src/resolvers.c b/src/resolvers.c index c820d9cfb..4ef55b913 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -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); diff --git a/src/server.c b/src/server.c index ca48f2875..80e26ab94 100644 --- a/src/server.c +++ b/src/server.c @@ -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) | diff --git a/src/tcpcheck.c b/src/tcpcheck.c index c00c47fed..d30ecb57e 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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); diff --git a/src/tools.c b/src/tools.c index 45f519ab8..d67356f8e 100644 --- a/src/tools.c +++ b/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 if non-null. + * The address protocol and transport types hints which are directly resolved + * will be set into if not NULL. * * Any known file descriptor is also assigned to 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) {