mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-20 15:48:54 +02:00
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
This commit is contained in:
@@ -361,6 +361,25 @@ g_network_service_set_scheme (GNetworkService *srv,
|
|||||||
g_object_notify (G_OBJECT (srv), "scheme");
|
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_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))
|
#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)
|
if (!srv_enum->srv->priv->targets)
|
||||||
{
|
{
|
||||||
GList *targets;
|
GList *targets;
|
||||||
|
GError *my_error = NULL;
|
||||||
|
|
||||||
targets = g_resolver_lookup_service (srv_enum->resolver,
|
targets = g_resolver_lookup_service (srv_enum->resolver,
|
||||||
srv_enum->srv->priv->service,
|
srv_enum->srv->priv->service,
|
||||||
srv_enum->srv->priv->protocol,
|
srv_enum->srv->priv->protocol,
|
||||||
srv_enum->srv->priv->domain,
|
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)
|
if (!targets)
|
||||||
return NULL;
|
{
|
||||||
|
g_propagate_error (error, my_error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
srv_enum->srv->priv->targets = targets;
|
srv_enum->srv->priv->targets = targets;
|
||||||
srv_enum->t = srv_enum->srv->priv->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;
|
GNetworkServiceAddressEnumerator *srv_enum = user_data;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
GList *targets;
|
||||||
|
|
||||||
srv_enum->srv->priv->targets =
|
targets = g_resolver_lookup_service_finish (srv_enum->resolver,
|
||||||
g_resolver_lookup_service_finish (srv_enum->resolver, result, &error);
|
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)
|
if (error)
|
||||||
{
|
{
|
||||||
@@ -562,7 +602,7 @@ next_async_resolved_targets (GObject *source_object,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srv_enum->t = srv_enum->srv->priv->targets;
|
srv_enum->t = srv_enum->srv->priv->targets = targets;
|
||||||
next_async_have_targets (srv_enum);
|
next_async_have_targets (srv_enum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user