GResolver: Don't return duplicate addresses

... this was causing a GDBus test-case to fail so now that it is
fixed, also reenable the test case.

https://bugzilla.gnome.org/show_bug.cgi?id=631379

Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
David Zeuthen 2011-04-14 11:27:57 -04:00
parent 33515d4eb4
commit 4da1824759
2 changed files with 45 additions and 10 deletions

View File

@ -212,6 +212,36 @@ g_resolver_maybe_reload (GResolver *resolver)
#endif
}
/* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */
static void
remove_duplicates (GList *addrs)
{
GList *l;
GList *ll;
GList *lll;
/* TODO: if this is too slow (it's O(n^2) but n is typically really
* small), we can do something more clever but note that we must not
* change the order of elements...
*/
for (l = addrs; l != NULL; l = l->next)
{
GInetAddress *address = G_INET_ADDRESS (l->data);
for (ll = l->next; ll != NULL; ll = lll)
{
GInetAddress *other_address = G_INET_ADDRESS (ll->data);
lll = ll->next;
if (g_inet_address_equal (address, other_address))
{
g_object_unref (other_address);
/* we never return the first element */
g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs);
}
}
}
}
/**
* g_resolver_lookup_by_name:
* @resolver: a #GResolver
@ -225,9 +255,12 @@ g_resolver_maybe_reload (GResolver *resolver)
* a wrapper around g_inet_address_new_from_string()).
*
* On success, g_resolver_lookup_by_name() will return a #GList of
* #GInetAddress, sorted in order of preference. (That is, you should
* attempt to connect to the first address first, then the second if
* the first fails, etc.)
* #GInetAddress, sorted in order of preference and guaranteed to not
* contain duplicates. That is, if using the result to connect to
* @hostname, you should attempt to connect to the first address
* first, then the second if the first fails, etc. If you are using
* the result to listen on a socket, it is appropriate to add each
* result using e.g. g_socket_listener_add_address().
*
* If the DNS resolution fails, @error (if non-%NULL) will be set to a
* value from #GResolverError.
@ -272,6 +305,8 @@ g_resolver_lookup_by_name (GResolver *resolver,
addrs = G_RESOLVER_GET_CLASS (resolver)->
lookup_by_name (resolver, hostname, cancellable, error);
remove_duplicates (addrs);
g_free (ascii_hostname);
return addrs;
}
@ -354,6 +389,8 @@ g_resolver_lookup_by_name_finish (GResolver *resolver,
GAsyncResult *result,
GError **error)
{
GList *addrs;
g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL);
if (G_IS_SIMPLE_ASYNC_RESULT (result))
@ -373,8 +410,12 @@ g_resolver_lookup_by_name_finish (GResolver *resolver,
}
}
return G_RESOLVER_GET_CLASS (resolver)->
addrs = G_RESOLVER_GET_CLASS (resolver)->
lookup_by_name_finish (resolver, result, error);
remove_duplicates (addrs);
return addrs;
}
/**

View File

@ -1083,7 +1083,6 @@ delayed_message_processing (void)
/* ---------------------------------------------------------------------------------------------------- */
#ifdef BUG_631379_FIXED
static gboolean
nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer,
GIOStream *stream,
@ -1285,7 +1284,6 @@ test_nonce_tcp (void)
g_main_loop_quit (service_loop);
g_thread_join (service_thread);
}
#endif
static void
test_credentials (void)
@ -1438,7 +1436,6 @@ test_overflow (void)
/* ---------------------------------------------------------------------------------------------------- */
#ifdef BUG_631379_FIXED
static gboolean
tcp_anonymous_on_new_connection (GDBusServer *server,
GDBusConnection *connection,
@ -1525,7 +1522,6 @@ test_tcp_anonymous (void)
g_thread_join (service_thread);
}
#endif
/* ---------------------------------------------------------------------------------------------------- */
@ -1551,10 +1547,8 @@ main (int argc,
g_test_add_func ("/gdbus/peer-to-peer", test_peer);
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
#ifdef BUG_631379_FIXED
g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
#endif
g_test_add_func ("/gdbus/credentials", test_credentials);
g_test_add_func ("/gdbus/overflow", test_overflow);