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