MINOR: config: allow IPv6 bracketed literals

This commit is contained in:
mildis 2015-10-26 18:50:08 +01:00 committed by Willy Tarreau
parent a124693ba0
commit ff5d510294
1 changed files with 54 additions and 8 deletions

View File

@ -620,6 +620,33 @@ const char *invalid_domainchar(const char *name) {
struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, int resolve) struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, int resolve)
{ {
struct hostent *he; struct hostent *he;
/* max IPv6 length, including brackets and terminating NULL */
char tmpip[48];
/* check IPv6 with square brackets */
if (str[0] == '[') {
size_t iplength = strlen(str);
if (iplength < 4) {
/* minimal size is 4 when using brackets "[::]" */
goto fail;
}
else if (iplength >= sizeof(tmpip)) {
/* IPv6 literal can not be larger than tmpip */
goto fail;
}
else {
if (str[iplength - 1] != ']') {
/* if address started with bracket, it should end with bracket */
goto fail;
}
else {
memcpy(tmpip, str + 1, iplength - 2);
tmpip[iplength - 2] = '\0';
str = tmpip;
}
}
}
/* Any IPv6 address */ /* Any IPv6 address */
if (str[0] == ':' && str[1] == ':' && !str[2]) { if (str[0] == ':' && str[1] == ':' && !str[2]) {
@ -747,10 +774,12 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i
* the first byte of the address. * the first byte of the address.
* - "fd@" => an integer must follow, and is a file descriptor number. * - "fd@" => an integer must follow, and is a file descriptor number.
* *
* Also note that in order to avoid any ambiguity with IPv6 addresses, the ':' * IPv6 addresses can be declared with or without square brackets. When using
* is mandatory after the IP address even when no port is specified. NULL is * square brackets for IPv6 addresses, the port separator (colon) is optional.
* returned if the address cannot be parsed. The <low> and <high> ports are * If not using square brackets, and in order to avoid any ambiguity with
* always initialized if non-null, even for non-IP families. * IPv6 addresses, the last colon ':' is mandatory even when no port is specified.
* NULL is returned if the address cannot be parsed. The <low> and <high> ports
* are always initialized if non-null, even for non-IP families.
* *
* If <pfx> is non-null, it is used as a string prefix before any path-based * If <pfx> is non-null, it is used as a string prefix before any path-based
* address (typically the path to a unix socket). * address (typically the path to a unix socket).
@ -855,12 +884,29 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char
} }
else { /* IPv4 and IPv6 */ else { /* IPv4 and IPv6 */
int use_fqdn = 0; int use_fqdn = 0;
char *end = str2 + strlen(str2);
char *chr;
port1 = strrchr(str2, ':'); /* search for : or ] whatever comes first */
if (port1) for (chr = end-1; chr > str2; chr--) {
*port1++ = '\0'; if (*chr == ']' || *chr == ':')
else break;
}
if (*chr == ':') {
/* Found a colon before a closing-bracket, must be a port separator.
* This guarantee backward compatibility.
*/
*chr++ = '\0';
port1 = chr;
}
else {
/* Either no colon and no closing-bracket
* or directly ending with a closing-bracket.
* However, no port.
*/
port1 = ""; port1 = "";
}
if (str2ip2(str2, &ss, 0) == NULL) { if (str2ip2(str2, &ss, 0) == NULL) {
use_fqdn = 1; use_fqdn = 1;