diff options
Diffstat (limited to 'gl/getaddrinfo.c')
| -rw-r--r-- | gl/getaddrinfo.c | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/gl/getaddrinfo.c b/gl/getaddrinfo.c index bf5d61f3..a8c45c21 100644 --- a/gl/getaddrinfo.c +++ b/gl/getaddrinfo.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Get address information (partial implementation). | 1 | /* Get address information (partial implementation). |
| 2 | Copyright (C) 1997, 2001-2002, 2004-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1997, 2001-2002, 2004-2025 Free Software Foundation, Inc. |
| 3 | Contributed by Simon Josefsson <simon@josefsson.org>. | 3 | Contributed by Simon Josefsson <simon@josefsson.org>. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -40,8 +40,8 @@ | |||
| 40 | #include <stdio.h> | 40 | #include <stdio.h> |
| 41 | 41 | ||
| 42 | #include "gettext.h" | 42 | #include "gettext.h" |
| 43 | #define _(String) gettext (String) | 43 | #define _(msgid) dgettext ("gnulib", msgid) |
| 44 | #define N_(String) String | 44 | #define N_(msgid) msgid |
| 45 | 45 | ||
| 46 | /* BeOS has AF_INET, but not PF_INET. */ | 46 | /* BeOS has AF_INET, but not PF_INET. */ |
| 47 | #ifndef PF_INET | 47 | #ifndef PF_INET |
| @@ -54,7 +54,7 @@ | |||
| 54 | 54 | ||
| 55 | #if HAVE_GETADDRINFO | 55 | #if HAVE_GETADDRINFO |
| 56 | 56 | ||
| 57 | /* Override with cdecl calling convention. */ | 57 | /* Override with cdecl calling convention and mingw fix. */ |
| 58 | 58 | ||
| 59 | int | 59 | int |
| 60 | getaddrinfo (const char *restrict nodename, | 60 | getaddrinfo (const char *restrict nodename, |
| @@ -63,6 +63,10 @@ getaddrinfo (const char *restrict nodename, | |||
| 63 | struct addrinfo **restrict res) | 63 | struct addrinfo **restrict res) |
| 64 | # undef getaddrinfo | 64 | # undef getaddrinfo |
| 65 | { | 65 | { |
| 66 | if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0 | ||
| 67 | && servname && !(*servname >= '0' && *servname <= '9')) | ||
| 68 | return EAI_NONAME; | ||
| 69 | |||
| 66 | return getaddrinfo (nodename, servname, hints, res); | 70 | return getaddrinfo (nodename, servname, hints, res); |
| 67 | } | 71 | } |
| 68 | 72 | ||
| @@ -169,16 +173,43 @@ validate_family (int family) | |||
| 169 | { | 173 | { |
| 170 | /* FIXME: Support more families. */ | 174 | /* FIXME: Support more families. */ |
| 171 | # if HAVE_IPV4 | 175 | # if HAVE_IPV4 |
| 172 | if (family == PF_INET) | 176 | if (family == PF_INET) |
| 173 | return true; | 177 | return true; |
| 174 | # endif | 178 | # endif |
| 175 | # if HAVE_IPV6 | 179 | # if HAVE_IPV6 |
| 176 | if (family == PF_INET6) | 180 | if (family == PF_INET6) |
| 177 | return true; | 181 | return true; |
| 178 | # endif | 182 | # endif |
| 179 | if (family == PF_UNSPEC) | 183 | if (family == PF_UNSPEC) |
| 180 | return true; | 184 | return true; |
| 181 | return false; | 185 | return false; |
| 186 | } | ||
| 187 | |||
| 188 | static bool | ||
| 189 | is_numeric_host (const char *host, int family) | ||
| 190 | { | ||
| 191 | # if HAVE_IPV4 | ||
| 192 | if (family == PF_INET || family == PF_UNSPEC) | ||
| 193 | { | ||
| 194 | /* glibc supports IPv4 addresses in numbers-and-dots notation, that is, | ||
| 195 | also hexadecimal and octal number formats and formats that don't | ||
| 196 | require all four bytes to be explicitly written, via inet_aton(). | ||
| 197 | But POSIX doesn't require support for these legacy formats. Therefore | ||
| 198 | we are free to use inet_pton() instead of inet_aton(). */ | ||
| 199 | struct in_addr addr; | ||
| 200 | if (inet_pton (AF_INET, host, &addr)) | ||
| 201 | return true; | ||
| 202 | } | ||
| 203 | # endif | ||
| 204 | # if HAVE_IPV6 | ||
| 205 | if (family == PF_INET6 || family == PF_UNSPEC) | ||
| 206 | { | ||
| 207 | struct in6_addr addr; | ||
| 208 | if (inet_pton (AF_INET6, host, &addr)) | ||
| 209 | return true; | ||
| 210 | } | ||
| 211 | # endif | ||
| 212 | return false; | ||
| 182 | } | 213 | } |
| 183 | 214 | ||
| 184 | /* Translate name of a service location and/or a service name to set of | 215 | /* Translate name of a service location and/or a service name to set of |
| @@ -210,10 +241,17 @@ getaddrinfo (const char *restrict nodename, | |||
| 210 | 241 | ||
| 211 | # ifdef WINDOWS_NATIVE | 242 | # ifdef WINDOWS_NATIVE |
| 212 | if (use_win32_p ()) | 243 | if (use_win32_p ()) |
| 213 | return getaddrinfo_ptr (nodename, servname, hints, res); | 244 | { |
| 245 | if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0 | ||
| 246 | && servname && !(*servname >= '0' && *servname <= '9')) | ||
| 247 | return EAI_NONAME; | ||
| 248 | return getaddrinfo_ptr (nodename, servname, hints, res); | ||
| 249 | } | ||
| 214 | # endif | 250 | # endif |
| 215 | 251 | ||
| 216 | if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) | 252 | if (hints |
| 253 | && (hints->ai_flags | ||
| 254 | & ~(AI_CANONNAME | AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV))) | ||
| 217 | /* FIXME: Support more flags. */ | 255 | /* FIXME: Support more flags. */ |
| 218 | return EAI_BADFLAGS; | 256 | return EAI_BADFLAGS; |
| 219 | 257 | ||
| @@ -225,12 +263,18 @@ getaddrinfo (const char *restrict nodename, | |||
| 225 | /* FIXME: Support other socktype. */ | 263 | /* FIXME: Support other socktype. */ |
| 226 | return EAI_SOCKTYPE; /* FIXME: Better return code? */ | 264 | return EAI_SOCKTYPE; /* FIXME: Better return code? */ |
| 227 | 265 | ||
| 228 | if (!nodename) | 266 | if (nodename != NULL) |
| 267 | { | ||
| 268 | if (hints && (hints->ai_flags & AI_NUMERICHOST) != 0 | ||
| 269 | && !is_numeric_host (nodename, hints->ai_family)) | ||
| 270 | return EAI_NONAME; | ||
| 271 | } | ||
| 272 | else | ||
| 229 | { | 273 | { |
| 230 | if (!(hints->ai_flags & AI_PASSIVE)) | 274 | if (!(hints->ai_flags & AI_PASSIVE)) |
| 231 | return EAI_NONAME; | 275 | return EAI_NONAME; |
| 232 | 276 | ||
| 233 | # ifdef HAVE_IPV6 | 277 | # if HAVE_IPV6 |
| 234 | nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; | 278 | nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; |
| 235 | # else | 279 | # else |
| 236 | nodename = "0.0.0.0"; | 280 | nodename = "0.0.0.0"; |
