[glib] GNetworkService: fall back when there is no valid SRV record
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GNetworkService: fall back when there is no valid SRV record
- Date: Fri, 22 Oct 2010 19:04:19 +0000 (UTC)
commit e410131021036532e6e9622e8b977222389b44e9
Author: Dan Winship <danw gnome org>
Date: Wed Sep 15 10:05:03 2010 -0400
GNetworkService: fall back when there is no valid SRV record
RFC 2782 says that if there is no SRV record for
_SERVICE._PROTOCOL.DOMAIN, you should fall back to trying just DOMAIN,
with the default port for SERVICE. Do that.
https://bugzilla.gnome.org/show_bug.cgi?id=629274
gio/gnetworkservice.c | 50 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 45 insertions(+), 5 deletions(-)
---
diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c
index 78e1ab5..58671a4 100644
--- a/gio/gnetworkservice.c
+++ b/gio/gnetworkservice.c
@@ -361,6 +361,25 @@ g_network_service_set_scheme (GNetworkService *srv,
g_object_notify (G_OBJECT (srv), "scheme");
}
+static GList *
+g_network_service_fallback_targets (GNetworkService *srv)
+{
+ GSrvTarget *target;
+ struct servent *entry;
+ guint16 port;
+
+ entry = getservbyname (srv->priv->service, "tcp");
+ port = entry ? g_ntohs (entry->s_port) : 0;
+#ifdef HAVE_ENDSERVENT
+ endservent ();
+#endif
+
+ if (entry == NULL)
+ return NULL;
+
+ target = g_srv_target_new (srv->priv->domain, port, 0, 0);
+ return g_list_append (NULL, target);
+}
#define G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR (_g_network_service_address_enumerator_get_type ())
#define G_NETWORK_SERVICE_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, GNetworkServiceAddressEnumerator))
@@ -401,14 +420,26 @@ g_network_service_address_enumerator_next (GSocketAddressEnumerator *enumerator
if (!srv_enum->srv->priv->targets)
{
GList *targets;
+ GError *my_error = NULL;
targets = g_resolver_lookup_service (srv_enum->resolver,
srv_enum->srv->priv->service,
srv_enum->srv->priv->protocol,
srv_enum->srv->priv->domain,
- cancellable, error);
+ cancellable, &my_error);
+ if (!targets && g_error_matches (my_error, G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND))
+ {
+ targets = g_network_service_fallback_targets (srv_enum->srv);
+ if (targets)
+ g_clear_error (&my_error);
+ }
+
if (!targets)
- return NULL;
+ {
+ g_propagate_error (error, my_error);
+ return NULL;
+ }
srv_enum->srv->priv->targets = targets;
srv_enum->t = srv_enum->srv->priv->targets;
@@ -546,9 +577,18 @@ next_async_resolved_targets (GObject *source_object,
{
GNetworkServiceAddressEnumerator *srv_enum = user_data;
GError *error = NULL;
+ GList *targets;
- srv_enum->srv->priv->targets =
- g_resolver_lookup_service_finish (srv_enum->resolver, result, &error);
+ targets = g_resolver_lookup_service_finish (srv_enum->resolver,
+ result, &error);
+
+ if (!targets && g_error_matches (error, G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND))
+ {
+ targets = g_network_service_fallback_targets (srv_enum->srv);
+ if (targets)
+ g_clear_error (&error);
+ }
if (error)
{
@@ -562,7 +602,7 @@ next_async_resolved_targets (GObject *source_object,
}
else
{
- srv_enum->t = srv_enum->srv->priv->targets;
+ srv_enum->t = srv_enum->srv->priv->targets = targets;
next_async_have_targets (srv_enum);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]