X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgresolver.c;h=e73ef0e9f8ef0b0b9d448cbb73bb01e5e2eb91ef;hb=356a3987cee7ceddcb3fe623edf0bd2881895add;hp=3708ee2c35111d2ca2e7d5c8a2771c64c7fead54;hpb=9e90575502e663e5adde201f214c811df08bdf29;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/gresolver.c b/gio/gresolver.c
index 3708ee2..e73ef0e 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -15,9 +15,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see .
*/
#include "config.h"
@@ -76,7 +74,9 @@ struct _GResolverPrivate {
* The object that handles DNS resolution. Use g_resolver_get_default()
* to get the default resolver.
*/
-G_DEFINE_TYPE (GResolver, g_resolver, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT,
+ G_ADD_PRIVATE (GResolver)
+ g_networking_init ();)
static GList *
srv_records_to_targets (GList *records)
@@ -151,11 +151,6 @@ g_resolver_class_init (GResolverClass *resolver_class)
resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish;
- g_type_class_add_private (resolver_class, sizeof (GResolverPrivate));
-
- /* Make sure _g_networking_init() has been called */
- g_type_ensure (G_TYPE_INET_ADDRESS);
-
/**
* GResolver::reload:
* @resolver: a #GResolver
@@ -180,7 +175,7 @@ g_resolver_init (GResolver *resolver)
struct stat st;
#endif
- resolver->priv = G_TYPE_INSTANCE_GET_PRIVATE (resolver, G_TYPE_RESOLVER, GResolverPrivate);
+ resolver->priv = g_resolver_get_instance_private (resolver);
#ifdef G_OS_UNIX
if (stat (_PATH_RESCONF, &st) == 0)
@@ -197,7 +192,7 @@ static GResolver *default_resolver;
* with it. #GResolver may use its reference count as a hint about how
* many threads it should allocate for concurrent DNS resolutions.
*
- * Return value: (transfer full): the default #GResolver.
+ * Returns: (transfer full): the default #GResolver.
*
* Since: 2.22
*/
@@ -234,6 +229,10 @@ g_resolver_set_default (GResolver *resolver)
default_resolver = g_object_ref (resolver);
}
+/* Bionic has res_init() but it's not in any header */
+#ifdef __BIONIC__
+int res_init (void);
+#endif
static void
g_resolver_maybe_reload (GResolver *resolver)
@@ -246,7 +245,9 @@ g_resolver_maybe_reload (GResolver *resolver)
if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
{
resolver->priv->resolv_conf_timestamp = st.st_mtime;
+#ifdef HAVE_RES_INIT
res_init ();
+#endif
g_signal_emit (resolver, signals[RELOAD], 0);
}
}
@@ -282,6 +283,48 @@ remove_duplicates (GList *addrs)
}
}
+/* Note that this does not follow the "FALSE means @error is set"
+ * convention. The return value tells the caller whether it should
+ * return @addrs and @error to the caller right away, or if it should
+ * continue and trying to resolve the name as a hostname.
+ */
+static gboolean
+handle_ip_address (const char *hostname,
+ GList **addrs,
+ GError **error)
+{
+ GInetAddress *addr;
+#ifndef G_OS_WIN32
+ struct in_addr ip4addr;
+#endif
+
+ addr = g_inet_address_new_from_string (hostname);
+ if (addr)
+ {
+ *addrs = g_list_append (NULL, addr);
+ return TRUE;
+ }
+
+ *addrs = NULL;
+
+ /* Reject non-standard IPv4 numbers-and-dots addresses.
+ * g_inet_address_new_from_string() will have accepted any "real" IP
+ * address, so if inet_aton() succeeds, then it's an address we want
+ * to reject. This check is not necessary for Windows, as getaddrinfo()
+ * already rejects such IPv4 addresses on Windows.
+ */
+#ifndef G_OS_WIN32
+ if (inet_aton (hostname, &ip4addr))
+ {
+ g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
+ _("Error resolving '%s': %s"),
+ hostname, gai_strerror (EAI_NONAME));
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
/**
* g_resolver_lookup_by_name:
@@ -295,7 +338,7 @@ remove_duplicates (GList *addrs)
* the textual form of an IP address (in which case this just becomes
* a wrapper around g_inet_address_new_from_string()).
*
- * On success, g_resolver_lookup_by_name() will return a #GList of
+ * On success, g_resolver_lookup_by_name() will return a non-empty #GList of
* #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
@@ -304,7 +347,7 @@ remove_duplicates (GList *addrs)
* 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.
+ * value from #GResolverError and %NULL will be returned.
*
* If @cancellable is non-%NULL, it can be used to cancel the
* operation, in which case @error (if non-%NULL) will be set to
@@ -314,7 +357,7 @@ remove_duplicates (GList *addrs)
* address, it may be easier to create a #GNetworkAddress and use its
* #GSocketConnectable interface.
*
- * Return value: (element-type GInetAddress) (transfer full): a #GList
+ * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList
* of #GInetAddress, or %NULL on error. You
* must unref each of the addresses and free the list when you are
* done with it. (You can use g_resolver_free_addresses() to do this.)
@@ -327,7 +370,6 @@ g_resolver_lookup_by_name (GResolver *resolver,
GCancellable *cancellable,
GError **error)
{
- GInetAddress *addr;
GList *addrs;
gchar *ascii_hostname = NULL;
@@ -335,9 +377,8 @@ g_resolver_lookup_by_name (GResolver *resolver,
g_return_val_if_fail (hostname != NULL, NULL);
/* Check if @hostname is just an IP address */
- addr = g_inet_address_new_from_string (hostname);
- if (addr)
- return g_list_append (NULL, addr);
+ if (handle_ip_address (hostname, &addrs, error))
+ return addrs;
if (g_hostname_is_non_ascii (hostname))
hostname = ascii_hostname = g_hostname_to_ascii (hostname);
@@ -374,22 +415,24 @@ g_resolver_lookup_by_name_async (GResolver *resolver,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GInetAddress *addr;
gchar *ascii_hostname = NULL;
+ GList *addrs;
+ GError *error = NULL;
g_return_if_fail (G_IS_RESOLVER (resolver));
g_return_if_fail (hostname != NULL);
/* Check if @hostname is just an IP address */
- addr = g_inet_address_new_from_string (hostname);
- if (addr)
+ if (handle_ip_address (hostname, &addrs, &error))
{
GTask *task;
task = g_task_new (resolver, cancellable, callback, user_data);
g_task_set_source_tag (task, g_resolver_lookup_by_name_async);
- g_task_return_pointer (task, g_list_append (NULL, addr),
- (GDestroyNotify) g_resolver_free_addresses);
+ if (addrs)
+ g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
+ else
+ g_task_return_error (task, error);
g_object_unref (task);
return;
}
@@ -417,7 +460,7 @@ g_resolver_lookup_by_name_async (GResolver *resolver,
* a value from #GResolverError. If the operation was cancelled,
* @error will be set to %G_IO_ERROR_CANCELLED.
*
- * Return value: (element-type GInetAddress) (transfer full): a #GList
+ * Returns: (element-type GInetAddress) (transfer full): a #GList
* of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name()
* for more details.
*
@@ -486,7 +529,7 @@ g_resolver_free_addresses (GList *addresses)
* operation, in which case @error (if non-%NULL) will be set to
* %G_IO_ERROR_CANCELLED.
*
- * Return value: a hostname (either ASCII-only, or in ASCII-encoded
+ * Returns: a hostname (either ASCII-only, or in ASCII-encoded
* form), or %NULL on error.
*
* Since: 2.22
@@ -547,7 +590,7 @@ g_resolver_lookup_by_address_async (GResolver *resolver,
* a value from #GResolverError. If the operation was cancelled,
* @error will be set to %G_IO_ERROR_CANCELLED.
*
- * Return value: a hostname (either ASCII-only, or in ASCII-encoded
+ * Returns: a hostname (either ASCII-only, or in ASCII-encoded
* form), or %NULL on error.
*
* Since: 2.22
@@ -594,17 +637,16 @@ g_resolver_get_service_rrname (const char *service,
* Synchronously performs a DNS SRV lookup for the given @service and
* @protocol in the given @domain and returns an array of #GSrvTarget.
* @domain may be an ASCII-only or UTF-8 hostname. Note also that the
- * @service and @protocol arguments do not
- * include the leading underscore that appears in the actual DNS
- * entry.
+ * @service and @protocol arguments do not include the leading underscore
+ * that appears in the actual DNS entry.
*
- * On success, g_resolver_lookup_service() will return a #GList of
+ * On success, g_resolver_lookup_service() will return a non-empty #GList of
* #GSrvTarget, sorted in order of preference. (That is, you should
* attempt to connect to the first target first, then the second if
* the first fails, etc.)
*
* If the DNS resolution fails, @error (if non-%NULL) will be set to
- * a value from #GResolverError.
+ * a value from #GResolverError and %NULL will be returned.
*
* If @cancellable is non-%NULL, it can be used to cancel the
* operation, in which case @error (if non-%NULL) will be set to
@@ -614,9 +656,10 @@ g_resolver_get_service_rrname (const char *service,
* to create a #GNetworkService and use its #GSocketConnectable
* interface.
*
- * Return value: (element-type GSrvTarget) (transfer full): a #GList of #GSrvTarget,
- * or %NULL on error. You must free each of the targets and the list when you are
- * done with it. (You can use g_resolver_free_targets() to do this.)
+ * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
+ * #GSrvTarget, or %NULL on error. You must free each of the targets and the
+ * list when you are done with it. (You can use g_resolver_free_targets() to do
+ * this.)
*
* Since: 2.22
*/
@@ -702,8 +745,9 @@ g_resolver_lookup_service_async (GResolver *resolver,
* a value from #GResolverError. If the operation was cancelled,
* @error will be set to %G_IO_ERROR_CANCELLED.
*
- * Return value: (element-type GSrvTarget) (transfer full): a #GList of #GSrvTarget,
- * or %NULL on error. See g_resolver_lookup_service() for more details.
+ * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of
+ * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more
+ * details.
*
* Since: 2.22
*/
@@ -755,15 +799,16 @@ g_resolver_free_targets (GList *targets)
* information on what the records contain for each @record_type.
*
* If the DNS resolution fails, @error (if non-%NULL) will be set to
- * a value from #GResolverError.
+ * a value from #GResolverError and %NULL will be returned.
*
* If @cancellable is non-%NULL, it can be used to cancel the
* operation, in which case @error (if non-%NULL) will be set to
* %G_IO_ERROR_CANCELLED.
*
- * Return value: (element-type GVariant) (transfer full): a #GList of #GVariant,
- * or %NULL on error. You must free each of the records and the list when you are
- * done with it. (You can use g_list_free_full() with g_variant_unref() to do this.)
+ * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
+ * #GVariant, or %NULL on error. You must free each of the records and the list
+ * when you are done with it. (You can use g_list_free_full() with
+ * g_variant_unref() to do this.)
*
* Since: 2.34
*/
@@ -825,16 +870,18 @@ g_resolver_lookup_records_async (GResolver *resolver,
* @error: return location for a #GError, or %NULL
*
* Retrieves the result of a previous call to
- * g_resolver_lookup_records_async(). Returns a list of records as #GVariant
- * tuples. See #GResolverRecordType for information on what the records contain.
+ * g_resolver_lookup_records_async(). Returns a non-empty list of records as
+ * #GVariant tuples. See #GResolverRecordType for information on what the
+ * records contain.
*
* If the DNS resolution failed, @error (if non-%NULL) will be set to
* a value from #GResolverError. If the operation was cancelled,
* @error will be set to %G_IO_ERROR_CANCELLED.
*
- * Return value: (element-type GVariant) (transfer full): a #GList of #GVariant,
- * or %NULL on error. You must free each of the records and the list when you are
- * done with it. (You can use g_list_free_full() with g_variant_unref() to do this.)
+ * Returns: (element-type GVariant) (transfer full): a non-empty #GList of
+ * #GVariant, or %NULL on error. You must free each of the records and the list
+ * when you are done with it. (You can use g_list_free_full() with
+ * g_variant_unref() to do this.)
*
* Since: 2.34
*/
@@ -848,12 +895,26 @@ g_resolver_lookup_records_finish (GResolver *resolver,
lookup_records_finish (resolver, result, error);
}
+guint64
+g_resolver_get_serial (GResolver *resolver)
+{
+ g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
+
+ g_resolver_maybe_reload (resolver);
+
+#ifdef G_OS_UNIX
+ return (guint64) resolver->priv->resolv_conf_timestamp;
+#else
+ return 1;
+#endif
+}
+
/**
* g_resolver_error_quark:
*
* Gets the #GResolver Error Quark.
*
- * Return value: a #GQuark.
+ * Returns: a #GQuark.
*
* Since: 2.22
*/