From 8ab57ebcf775bf97fc99c0315a4b7b29435c34c2 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 20 Apr 2016 17:07:53 -0400 Subject: [PATCH] common: limit potentially expensive name lookups Right now we're doing name look ups when we don't have to. These name look ups can cause lengthy timeouts in misconfigured environments. This commit reduces the name looks used by GDM to make it more resiliant to failure. Ported from RHEL 6 to RHEL 7 by Ashish Shah --- common/gdm-address.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/gdm-address.c b/common/gdm-address.c index 3448038..a8b73e2 100644 --- a/common/gdm-address.c +++ b/common/gdm-address.c @@ -193,159 +193,160 @@ gdm_address_equal (GdmAddress *a, return FALSE; } /* for debugging */ static const char * address_family_str (GdmAddress *address) { const char *str; switch (address->ss->ss_family) { case AF_INET: str = "inet"; break; case AF_INET6: str = "inet6"; break; case AF_UNIX: str = "unix"; break; case AF_UNSPEC: str = "unspecified"; break; default: str = "unknown"; break; } return str; } static void _gdm_address_debug (GdmAddress *address, - const char *hostname, const char *host, const char *port) { - g_debug ("Address family:%d (%s) hostname:%s host:%s port:%s local:%d loopback:%d", + g_debug ("Address family:%d (%s) host:%s port:%s local:%d loopback:%d", + address->ss->ss_family, address_family_str (address) ? address_family_str (address) : "(null)", - hostname ? hostname : "(null)", host ? host : "(null)", port ? port : "(null)", gdm_address_is_local (address), gdm_address_is_loopback (address)); } void gdm_address_debug (GdmAddress *address) { - char *hostname; - char *host; - char *port; + char *hostname = NULL; + char *host = NULL; + char *port = NULL; - gdm_address_get_hostname (address, &hostname); gdm_address_get_numeric_info (address, &host, &port); + _gdm_address_debug (address, host, port); + g_free (hostname); g_free (host); g_free (port); } gboolean gdm_address_get_hostname (GdmAddress *address, char **hostnamep) { char host [NI_MAXHOST]; int res; gboolean ret; g_return_val_if_fail (address != NULL, FALSE); g_return_val_if_fail (address->ss != NULL, FALSE); ret = FALSE; host [0] = '\0'; res = getnameinfo ((const struct sockaddr *)address->ss, (int) gdm_sockaddr_len (address->ss), host, sizeof (host), NULL, 0, 0); if (res == 0) { ret = TRUE; goto done; } else { const char *err_msg; err_msg = gai_strerror (res); g_warning ("Unable to lookup hostname: %s", err_msg ? err_msg : "(null)"); - _gdm_address_debug (address, NULL, NULL, NULL); + _gdm_address_debug (address, NULL, NULL); + } /* try numeric? */ done: if (hostnamep != NULL) { *hostnamep = g_strdup (host); } return ret; } gboolean gdm_address_get_numeric_info (GdmAddress *address, char **hostp, char **servp) { char host [NI_MAXHOST]; char serv [NI_MAXSERV]; int res; gboolean ret; g_return_val_if_fail (address != NULL, FALSE); g_return_val_if_fail (address->ss != NULL, FALSE); ret = FALSE; host [0] = '\0'; serv [0] = '\0'; res = getnameinfo ((const struct sockaddr *)address->ss, (int) gdm_sockaddr_len (address->ss), host, sizeof (host), serv, sizeof (serv), NI_NUMERICHOST | NI_NUMERICSERV); if (res != 0) { const char *err_msg; err_msg = gai_strerror (res); g_warning ("Unable to lookup numeric info: %s", err_msg ? err_msg : "(null)"); - _gdm_address_debug (address, NULL, NULL, NULL); + _gdm_address_debug (address, NULL, NULL); } else { ret = TRUE; } if (servp != NULL) { if (g_str_has_prefix (serv, "::ffff:")) { *servp = g_strdup (serv + 7); } else { *servp = g_strdup (serv); } } if (hostp != NULL) { if (g_str_has_prefix (host, "::ffff:")) { *hostp = g_strdup (host + 7); } else { *hostp = g_strdup (host); } } return ret; } gboolean gdm_address_is_loopback (GdmAddress *address) { g_return_val_if_fail (address != NULL, FALSE); g_return_val_if_fail (address->ss != NULL, FALSE); switch (address->ss->ss_family){ #ifdef AF_INET6 @@ -377,94 +378,93 @@ add_local_siocgifconf (GList **list) perror ("socket"); return; } ifc.ifc_len = sizeof (buf); ifc.ifc_buf = buf; if (ioctl (sock, SIOCGIFCONF, (char *) &ifc) < 0) { perror ("SIOCGIFCONF"); close (sock); return; } /* Get IP address of each active IP network interface. */ the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < the_end; ifr++) { if (ifr->ifr_addr.sa_family == AF_INET) { /* IP net interface */ ifreq = *ifr; if (ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) { perror("SIOCGIFFLAGS"); } else if (ifreq.ifr_flags & IFF_UP) { /* active interface */ if (ioctl (sock, SIOCGIFADDR, (char *) &ifreq) < 0) { perror("SIOCGIFADDR"); } else { GdmAddress *address; address = gdm_address_new_from_sockaddr ((struct sockaddr *)&ifreq.ifr_addr, sizeof (struct sockaddr)); - gdm_address_debug (address); - *list = g_list_append (*list, address); } } } /* Support for variable-length addresses. */ #ifdef HAS_SA_LEN ifr = (struct ifreq *) ((caddr_t) ifr + ifr->ifr_addr.sa_len - sizeof(struct sockaddr)); #endif } close (sock); } static void add_local_addrinfo (GList **list) { char hostbuf[BUFSIZ]; struct addrinfo *result; struct addrinfo *res; struct addrinfo hints; hostbuf[BUFSIZ-1] = '\0'; if (gethostname (hostbuf, BUFSIZ-1) != 0) { g_debug ("%s: Could not get server hostname, using localhost", "gdm_peek_local_address_list"); snprintf (hostbuf, BUFSIZ-1, "localhost"); } memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; - hints.ai_flags = AI_CANONNAME; + hints.ai_flags = AI_CANONNAME | AI_NUMERICHOST; + g_debug ("GdmAddress: looking up hostname: %s", hostbuf); result = NULL; if (getaddrinfo (hostbuf, NULL, &hints, &result) != 0) { g_debug ("%s: Could not get address from hostname!", "gdm_peek_local_address_list"); return; } for (res = result; res != NULL; res = res->ai_next) { GdmAddress *address; g_debug ("family=%d sock_type=%d protocol=%d flags=0x%x canonname=%s\n", res->ai_family, res->ai_socktype, res->ai_protocol, res->ai_flags, res->ai_canonname ? res->ai_canonname : "(null)"); address = gdm_address_new_from_sockaddr (res->ai_addr, res->ai_addrlen); *list = g_list_append (*list, address); } if (result != NULL) { freeaddrinfo (result); result = NULL; } } const GList * gdm_address_peek_local_list (void) -- 2.8.1