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 */