From: Willy Tarreau Date: Wed, 16 Sep 2020 09:35:47 +0000 (+0200) Subject: MINOR: tools: start to distinguish stream and dgram in str2sa_range() X-Git-Tag: v2.3-dev5~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e835bd8f9105c8ea03c0a1596bd42de999a1d426;p=thirdparty%2Fhaproxy.git MINOR: tools: start to distinguish stream and dgram in str2sa_range() The parser now supports a socket type for the control layer and a possible other one for the transport layer. Usually they are the same except for protocols like QUIC which will provide a stream transport layer based on a datagram control layer. The default types are preset based on the caller's expectations, and may be refined using "stream+" and "dgram+" prefixes. For now they were not added to the docuemntation because other changes will probably happen around UDP as well. It is conceivable that "tcpv4@" or "udpv6@" will appear later as aliases for "stream+ipv4" or "dgram+ipv6". --- diff --git a/src/tools.c b/src/tools.c index e543fd6cd3..0c4366408b 100644 --- a/src/tools.c +++ b/src/tools.c @@ -877,6 +877,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int int abstract = 0; int is_udp = 0; int new_fd = -1; + int sock_type, ctrl_type; portl = porth = porta = 0; if (fqdn) @@ -895,6 +896,21 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int memset(&ss, 0, sizeof(ss)); + /* prepare the default socket types */ + if ((opts & (PA_O_STREAM|PA_O_DGRAM)) == PA_O_DGRAM) + sock_type = ctrl_type = SOCK_DGRAM; + else + sock_type = ctrl_type = SOCK_STREAM; + + if (strncmp(str2, "stream+", 7) == 0) { + str2 += 7; + sock_type = ctrl_type = SOCK_STREAM; + } + else if (strncmp(str2, "dgram+", 6) == 0) { + str2 += 6; + sock_type = ctrl_type = SOCK_DGRAM; + } + if (strncmp(str2, "unix@", 5) == 0) { str2 += 5; abstract = 0; @@ -916,16 +932,19 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int else if (strncmp(str2, "udp4@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET; + sock_type = ctrl_type = SOCK_DGRAM; is_udp = 1; } else if (strncmp(str2, "udp6@", 5) == 0) { str2 += 5; ss.ss_family = AF_INET6; + sock_type = ctrl_type = SOCK_DGRAM; is_udp = 1; } else if (strncmp(str2, "udp@", 4) == 0) { str2 += 4; ss.ss_family = AF_UNSPEC; + sock_type = ctrl_type = SOCK_DGRAM; is_udp = 1; } else if (strncmp(str2, "fd@", 3) == 0) { @@ -984,7 +1003,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int addr_len = sizeof(type); if (getsockopt(new_fd, SOL_SOCKET, SO_TYPE, &type, &addr_len) != 0 || - (type == SOCK_STREAM) != !!(opts & PA_O_STREAM)) { + (type == SOCK_STREAM) != (sock_type == SOCK_STREAM)) { memprintf(err, "socket on file descriptor '%d' is of the wrong type.\n", new_fd); goto out; } @@ -1141,6 +1160,15 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int } + if (ctrl_type == SOCK_STREAM && !(opts & PA_O_STREAM)) { + memprintf(err, "stream-type socket not acceptable in '%s'\n", str); + goto out; + } + else if (ctrl_type == SOCK_DGRAM && !(opts & PA_O_DGRAM)) { + memprintf(err, "dgram-type socket not acceptable in '%s'\n", str); + goto out; + } + ret = &ss; out: if (port)