dnl
dnl Networking stuff for CUPS.
dnl
-dnl Copyright © 2021 by OpenPrinting.
+dnl Copyright © 2021-2023 by OpenPrinting.
dnl Copyright © 2007-2016 by Apple Inc.
dnl Copyright © 1997-2005 by Easy Software Products, all rights reserved.
dnl
])
])
-AC_SEARCH_LIBS([getaddrinfo], [nsl], [
- AC_DEFINE([HAVE_GETADDRINFO], [1], [Have the getaddrinfo function?])
-])
-AC_SEARCH_LIBS([getnameinfo], [nsl], [
- AC_DEFINE([HAVE_GETNAMEINFO], [1], [Have the getnameinfo function?])
-])
-
AC_CHECK_MEMBER([struct sockaddr.sa_len],,, [#include <sys/socket.h>])
AC_CHECK_HEADER([sys/sockio.h], [
AC_DEFINE([HAVE_SYS_SOCKIO_H], [1], [Have <sys/sockio.h> header?])
#undef HAVE_RRESVPORT_AF
-/*
- * Do we have getaddrinfo()?
- */
-
-#undef HAVE_GETADDRINFO
-
-
-/*
- * Do we have getnameinfo()?
- */
-
-#undef HAVE_GETNAMEINFO
-
-
/*
* Do we have getifaddrs()?
*/
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5
-printf %s "checking for library containing getaddrinfo... " >&6; }
-if test ${ac_cv_search_getaddrinfo+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char getaddrinfo ();
-int
-main (void)
-{
-return getaddrinfo ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' nsl
-do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_search_getaddrinfo=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext
- if test ${ac_cv_search_getaddrinfo+y}
-then :
- break
-fi
-done
-if test ${ac_cv_search_getaddrinfo+y}
-then :
-
-else $as_nop
- ac_cv_search_getaddrinfo=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getaddrinfo" >&5
-printf "%s\n" "$ac_cv_search_getaddrinfo" >&6; }
-ac_res=$ac_cv_search_getaddrinfo
-if test "$ac_res" != no
-then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-
-printf "%s\n" "#define HAVE_GETADDRINFO 1" >>confdefs.h
-
-
-fi
-
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing getnameinfo" >&5
-printf %s "checking for library containing getnameinfo... " >&6; }
-if test ${ac_cv_search_getnameinfo+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char getnameinfo ();
-int
-main (void)
-{
-return getnameinfo ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' nsl
-do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_search_getnameinfo=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext
- if test ${ac_cv_search_getnameinfo+y}
-then :
- break
-fi
-done
-if test ${ac_cv_search_getnameinfo+y}
-then :
-
-else $as_nop
- ac_cv_search_getnameinfo=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getnameinfo" >&5
-printf "%s\n" "$ac_cv_search_getnameinfo" >&6; }
-ac_res=$ac_cv_search_getnameinfo
-if test "$ac_res" != no
-then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-
-printf "%s\n" "#define HAVE_GETNAMEINFO 1" >>confdefs.h
-
-
-fi
-
-
ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include <sys/socket.h>
"
if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes
unsigned ip_addr; // Packed IPv4 address
char *ip_ptrs[2]; // Pointer to packed address
struct hostent hostent; // Host entry for IP address
-# ifdef HAVE_GETADDRINFO
char hostname[1024]; // Hostname
-# endif // HAVE_GETADDRINFO
int need_res_init; // Need to reinitialize resolver?
// ipp.c
char *name, // I - Host name buffer
int namelen) // I - Size of name buffer
{
+ int error; // Any error from getnameinfo
_cups_globals_t *cg = _cupsGlobals();
// Global data
}
#endif // HAVE_RES_INIT
-#ifdef HAVE_GETNAMEINFO
+ // STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
+ //
+ // FWIW, I think this is really a bug in the implementation of
+ // getnameinfo(), but falling back on httpAddrString() is easy to do...
+ if ((error = getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), name, (socklen_t)namelen, NULL, 0, 0)) != 0)
{
- // STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
- //
- // FWIW, I think this is really a bug in the implementation of
- // getnameinfo(), but falling back on httpAddrString() is easy to do...
- int error = getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), name, (socklen_t)namelen, NULL, 0, 0);
-
- if (error)
- {
- if (error == EAI_FAIL)
- cg->need_res_init = 1;
+ if (error == EAI_FAIL)
+ cg->need_res_init = 1;
- return (httpAddrGetString(addr, name, (size_t)namelen));
- }
+ return (httpAddrGetString(addr, name, (size_t)namelen));
}
-#else
- {
- struct hostent *host; // Host from name service
-
-# ifdef AF_INET6
- if (addr->addr.sa_family == AF_INET6)
- host = gethostbyaddr((char *)&(addr->ipv6.sin6_addr), sizeof(struct in_addr), AF_INET6);
- else
-# endif // AF_INET6
- host = gethostbyaddr((char *)&(addr->ipv4.sin_addr), sizeof(struct in_addr), AF_INET);
-
- if (host == NULL)
- {
- // No hostname, so return the raw address...
- if (h_errno == NO_RECOVERY)
- cg->need_res_init = 1;
-
- return (httpAddrGetString(addr, name, (size_t)namelen));
- }
-
- cupsCopyString(name, host->h_name, (size_t)namelen);
- }
-#endif // HAVE_GETNAMEINFO
DEBUG_printf("1httpAddrLookup: returning \"%s\"...", name);
char *sptr, // Pointer into string
temps[64]; // Temporary string for address
-# ifdef HAVE_GETNAMEINFO
if (getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), temps, sizeof(temps), NULL, 0, NI_NUMERICHOST))
{
// If we get an error back, then the address type is not supported
*sptr = '+';
}
-# else
- int i; // Looping var
- unsigned temp; // Current value
- const char *prefix; // Prefix for address
-
- prefix = "";
- for (sptr = temps, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
- {
- temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
-
- snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
- prefix = ":";
- sptr += strlen(sptr);
-
- temp &= 0xffff;
-
- if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
- {
- snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp);
- sptr += strlen(sptr);
- }
- }
-
- if (i < 4)
- {
- while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
- i ++;
-
- if (i < 4)
- {
- snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s:", prefix);
- prefix = ":";
- sptr += strlen(sptr);
-
- for (; i < 4; i ++)
- {
- temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
-
- if ((temp & 0xffff0000) || (i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1]))
- {
- snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
- sptr += strlen(sptr);
- }
-
- snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp & 0xffff);
- sptr += strlen(sptr);
- }
- }
- else if (sptr == s)
- {
- // Empty address...
- cupsCopyString(temps, "::", sizeof(temps));
- }
- else
- {
- // Empty at end...
- cupsCopyString(sptr, "::", sizeof(temps) - (size_t)(sptr - temps));
- }
- }
-# endif // HAVE_GETNAMEINFO
-
// Add "[v1." and "]" around IPv6 address to convert to URI form.
snprintf(s, slen, "[v1.%s]", temps);
}
#endif /* AF_LOCAL */
if (!hostname || _cups_strcasecmp(hostname, "localhost"))
{
-#ifdef HAVE_GETADDRINFO
struct addrinfo hints, /* Address lookup hints */
*results, /* Address lookup results */
*current; /* Current result */
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0);
# endif /* _WIN32 */
}
-
-#else
- if (hostname)
- {
- int i; /* Looping vars */
- unsigned ip[4]; /* IPv4 address components */
- const char *ptr; /* Pointer into hostname */
- struct hostent *host; /* Result of lookup */
- struct servent *port; /* Port number for service */
- int portnum; /* Port number */
-
-
- /*
- * Lookup the service...
- */
-
- if (!service)
- portnum = 0;
- else if (isdigit(*service & 255))
- portnum = atoi(service);
- else if ((port = getservbyname(service, NULL)) != NULL)
- portnum = ntohs(port->s_port);
- else if (!strcmp(service, "http"))
- portnum = 80;
- else if (!strcmp(service, "https"))
- portnum = 443;
- else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
- portnum = 631;
- else if (!strcmp(service, "lpd"))
- portnum = 515;
- else if (!strcmp(service, "socket"))
- portnum = 9100;
- else
- return (NULL);
-
- /*
- * This code is needed because some operating systems have a
- * buggy implementation of gethostbyname() that does not support
- * IPv4 addresses. If the hostname string is an IPv4 address, then
- * sscanf() is used to extract the IPv4 components. We then pack
- * the components into an IPv4 address manually, since the
- * inet_aton() function is deprecated. We use the htonl() macro
- * to get the right byte order for the address.
- */
-
- for (ptr = hostname; isdigit(*ptr & 255) || *ptr == '.'; ptr ++);
-
- if (!*ptr)
- {
- /*
- * We have an IPv4 address; break it up and create an IPv4 address...
- */
-
- if (sscanf(hostname, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) == 4 &&
- ip[0] <= 255 && ip[1] <= 255 && ip[2] <= 255 && ip[3] <= 255)
- {
- first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
- if (!first)
- return (NULL);
-
- first->addr.ipv4.sin_family = AF_INET;
- first->addr.ipv4.sin_addr.s_addr = htonl((ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3]);
- first->addr.ipv4.sin_port = htons(portnum);
- }
- }
- else if ((host = gethostbyname(hostname)) != NULL &&
-# ifdef AF_INET6
- (host->h_addrtype == AF_INET || host->h_addrtype == AF_INET6))
-# else
- host->h_addrtype == AF_INET)
-# endif /* AF_INET6 */
- {
- for (i = 0; host->h_addr_list[i]; i ++)
- {
- /*
- * Copy the address over...
- */
-
- temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
- if (!temp)
- {
- httpAddrFreeList(first);
- return (NULL);
- }
-
-# ifdef AF_INET6
- if (host->h_addrtype == AF_INET6)
- {
- temp->addr.ipv6.sin6_family = AF_INET6;
- memcpy(&(temp->addr.ipv6.sin6_addr), host->h_addr_list[i],
- sizeof(temp->addr.ipv6));
- temp->addr.ipv6.sin6_port = htons(portnum);
- }
- else
-# endif /* AF_INET6 */
- {
- temp->addr.ipv4.sin_family = AF_INET;
- memcpy(&(temp->addr.ipv4.sin_addr), host->h_addr_list[i],
- sizeof(temp->addr.ipv4));
- temp->addr.ipv4.sin_port = htons(portnum);
- }
-
- /*
- * Append the address to the list...
- */
-
- if (!first)
- first = temp;
-
- if (addr)
- addr->next = temp;
-
- addr = temp;
- }
- }
- else
- {
- if (h_errno == NO_RECOVERY)
- cg->need_res_init = 1;
-
- _cupsSetError(IPP_STATUS_ERROR_INTERNAL, hstrerror(h_errno), 0);
- }
- }
-#endif /* HAVE_GETADDRINFO */
}
/*
/* #undef HAVE_RRESVPORT_AF */
-/*
- * Do we have getaddrinfo()?
- */
-
-#define HAVE_GETADDRINFO 1
-
-
-/*
- * Do we have getnameinfo()?
- */
-
-#define HAVE_GETNAMEINFO 1
-
-
/*
* Do we have getifaddrs()?
*/
#define HAVE_RRESVPORT_AF 1
-/*
- * Do we have getaddrinfo()?
- */
-
-#define HAVE_GETADDRINFO 1
-
-
-/*
- * Do we have getnameinfo()?
- */
-
-#define HAVE_GETNAMEINFO 1
-
-
/*
* Do we have getifaddrs()?
*/