1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-address.c: Internet address handing
5 * Copyright (C) 2010 Red Hat, Inc.
17 #include <sys/types.h>
21 #include "soup-address.h"
22 #include "soup-enum-types.h"
23 #include "soup-marshal.h"
24 #include "soup-misc.h"
27 * SECTION:soup-address
28 * @short_description: DNS support
30 * #SoupAddress represents the address of a TCP connection endpoint:
31 * both the IP address and the port. (It is somewhat like an
32 * object-oriented version of struct sockaddr.)
49 struct sockaddr_storage *sockaddr;
52 char *name, *physical;
57 GSList *async_lookups;
59 #define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS, SoupAddressPrivate))
61 /* sockaddr generic macros */
62 #define SOUP_SIN(priv) ((struct sockaddr_in *)priv->sockaddr)
63 #define SOUP_SIN6(priv) ((struct sockaddr_in6 *)priv->sockaddr)
65 /* sockaddr family macros */
66 #define SOUP_ADDRESS_GET_FAMILY(priv) (priv->sockaddr->ss_family)
67 #define SOUP_ADDRESS_SET_FAMILY(priv, family) \
68 (priv->sockaddr->ss_family = family)
69 #define SOUP_ADDRESS_FAMILY_IS_VALID(family) \
70 (family == AF_INET || family == AF_INET6)
71 #define SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE(family) \
72 (family == AF_INET ? sizeof (struct sockaddr_in) : \
73 sizeof (struct sockaddr_in6))
74 #define SOUP_ADDRESS_FAMILY_DATA_SIZE(family) \
75 (family == AF_INET ? sizeof (struct in_addr) : \
76 sizeof (struct in6_addr))
78 /* sockaddr port macros */
79 #define SOUP_ADDRESS_PORT_IS_VALID(port) (port >= 0 && port <= 65535)
80 #define SOUP_ADDRESS_GET_PORT(priv) \
81 (priv->sockaddr->ss_family == AF_INET ? \
82 SOUP_SIN(priv)->sin_port : \
83 SOUP_SIN6(priv)->sin6_port)
84 #define SOUP_ADDRESS_SET_PORT(priv, port) \
86 if (priv->sockaddr->ss_family == AF_INET) \
87 SOUP_SIN(priv)->sin_port = port; \
89 SOUP_SIN6(priv)->sin6_port = port; \
92 /* sockaddr data macros */
93 #define SOUP_ADDRESS_GET_DATA(priv) \
94 (priv->sockaddr->ss_family == AF_INET ? \
95 (gpointer)&SOUP_SIN(priv)->sin_addr : \
96 (gpointer)&SOUP_SIN6(priv)->sin6_addr)
97 #define SOUP_ADDRESS_SET_DATA(priv, data, length) \
98 memcpy (SOUP_ADDRESS_GET_DATA (priv), data, length)
101 static GObject *constructor (GType type,
102 guint n_construct_properties,
103 GObjectConstructParam *construct_properties);
104 static void set_property (GObject *object, guint prop_id,
105 const GValue *value, GParamSpec *pspec);
106 static void get_property (GObject *object, guint prop_id,
107 GValue *value, GParamSpec *pspec);
109 static void soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface);
110 static GSocketAddressEnumerator *soup_address_connectable_enumerate (GSocketConnectable *connectable);
111 static GSocketAddressEnumerator *soup_address_connectable_proxy_enumerate (GSocketConnectable *connectable);
113 G_DEFINE_TYPE_WITH_CODE (SoupAddress, soup_address, G_TYPE_OBJECT,
114 G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE,
115 soup_address_connectable_iface_init))
118 soup_address_init (SoupAddress *addr)
120 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
122 g_mutex_init (&priv->lock);
126 finalize (GObject *object)
128 SoupAddress *addr = SOUP_ADDRESS (object);
129 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
132 g_free (priv->sockaddr);
136 g_free (priv->physical);
138 g_mutex_clear (&priv->lock);
140 G_OBJECT_CLASS (soup_address_parent_class)->finalize (object);
144 soup_address_class_init (SoupAddressClass *address_class)
146 GObjectClass *object_class = G_OBJECT_CLASS (address_class);
148 g_type_class_add_private (address_class, sizeof (SoupAddressPrivate));
150 /* virtual method override */
151 object_class->constructor = constructor;
152 object_class->finalize = finalize;
153 object_class->set_property = set_property;
154 object_class->get_property = get_property;
160 * Alias for the #SoupAddress:name property. (The hostname for
163 g_object_class_install_property (
164 object_class, PROP_NAME,
165 g_param_spec_string (SOUP_ADDRESS_NAME,
167 "Hostname for this address",
169 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
171 * SOUP_ADDRESS_FAMILY:
173 * Alias for the #SoupAddress:family property. (The
174 * #SoupAddressFamily for this address.)
176 g_object_class_install_property (
177 object_class, PROP_FAMILY,
178 g_param_spec_enum (SOUP_ADDRESS_FAMILY,
180 "Address family for this address",
181 SOUP_TYPE_ADDRESS_FAMILY,
182 SOUP_ADDRESS_FAMILY_INVALID,
183 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
187 * An alias for the #SoupAddress:port property. (The port for
190 g_object_class_install_property (
191 object_class, PROP_PORT,
192 g_param_spec_int (SOUP_ADDRESS_PORT,
194 "Port for this address",
196 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
198 * SOUP_ADDRESS_PROTOCOL:
200 * Alias for the #SoupAddress:protocol property. (The URI scheme
201 * used with this address.)
203 g_object_class_install_property (
204 object_class, PROP_PROTOCOL,
205 g_param_spec_string (SOUP_ADDRESS_PROTOCOL,
207 "URI scheme for this address",
209 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
211 * SOUP_ADDRESS_PHYSICAL:
213 * An alias for the #SoupAddress:physical property. (The
214 * stringified IP address for this address.)
216 g_object_class_install_property (
217 object_class, PROP_PHYSICAL,
218 g_param_spec_string (SOUP_ADDRESS_PHYSICAL,
220 "IP address for this address",
224 * SOUP_ADDRESS_SOCKADDR:
226 * An alias for the #SoupAddress:sockaddr property. (A pointer
227 * to the struct sockaddr for this address.)
229 g_object_class_install_property (
230 object_class, PROP_SOCKADDR,
231 g_param_spec_pointer (SOUP_ADDRESS_SOCKADDR,
233 "struct sockaddr for this address",
234 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
238 soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface)
240 connectable_iface->enumerate = soup_address_connectable_enumerate;
241 connectable_iface->proxy_enumerate = soup_address_connectable_proxy_enumerate;
245 constructor (GType type,
246 guint n_construct_properties,
247 GObjectConstructParam *construct_properties)
250 SoupAddressPrivate *priv;
252 addr = G_OBJECT_CLASS (soup_address_parent_class)->constructor (
253 type, n_construct_properties, construct_properties);
256 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
258 if (!priv->name && !priv->sockaddr) {
259 g_object_unref (addr);
267 set_property (GObject *object, guint prop_id,
268 const GValue *value, GParamSpec *pspec)
270 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
271 SoupAddressFamily family;
275 /* This is a mess because the properties are mostly orthogonal,
276 * but g_object_constructor wants to set a default value for each
282 priv->name = g_value_dup_string (value);
286 family = g_value_get_enum (value);
287 if (family == SOUP_ADDRESS_FAMILY_INVALID)
289 g_return_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (family));
290 g_return_if_fail (priv->sockaddr == NULL);
292 priv->sockaddr = g_malloc0 (SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (family));
293 SOUP_ADDRESS_SET_FAMILY (priv, family);
294 SOUP_ADDRESS_SET_PORT (priv, htons (priv->port));
299 port = g_value_get_int (value);
302 g_return_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port));
306 SOUP_ADDRESS_SET_PORT (priv, htons (port));
310 priv->protocol = g_intern_string (g_value_get_string (value));
314 sa = g_value_get_pointer (value);
317 g_return_if_fail (priv->sockaddr == NULL);
319 len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (sa->sa_family);
320 priv->sockaddr = g_memdup (sa, len);
322 priv->port = ntohs (SOUP_ADDRESS_GET_PORT (priv));
325 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
331 get_property (GObject *object, guint prop_id,
332 GValue *value, GParamSpec *pspec)
334 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
338 g_value_set_string (value, priv->name);
342 g_value_set_enum (value, SOUP_ADDRESS_GET_FAMILY (priv));
344 g_value_set_enum (value, 0);
347 g_value_set_int (value, priv->port);
350 g_value_set_string (value, soup_address_get_physical (SOUP_ADDRESS (object)));
353 g_value_set_string (value, priv->protocol);
356 g_value_set_pointer (value, priv->sockaddr);
359 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
366 * @name: a hostname or physical address
367 * @port: a port number
369 * Creates a #SoupAddress from @name and @port. The #SoupAddress's IP
370 * address may not be available right away; the caller can call
371 * soup_address_resolve_async() or soup_address_resolve_sync() to
372 * force a DNS resolution.
374 * Return value: a #SoupAddress
377 soup_address_new (const char *name, guint port)
379 g_return_val_if_fail (name != NULL, NULL);
380 g_return_val_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port), NULL);
382 return g_object_new (SOUP_TYPE_ADDRESS,
383 SOUP_ADDRESS_NAME, name,
384 SOUP_ADDRESS_PORT, port,
389 * soup_address_new_from_sockaddr:
390 * @sa: a pointer to a sockaddr
393 * Returns a #SoupAddress equivalent to @sa (or %NULL if @sa's
394 * address family isn't supported)
396 * Return value: (allow-none): the new #SoupAddress
399 soup_address_new_from_sockaddr (struct sockaddr *sa, int len)
401 g_return_val_if_fail (sa != NULL, NULL);
402 g_return_val_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (sa->sa_family), NULL);
403 g_return_val_if_fail (len == SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (sa->sa_family), NULL);
405 return g_object_new (SOUP_TYPE_ADDRESS,
406 SOUP_ADDRESS_SOCKADDR, sa,
412 * @SOUP_ADDRESS_FAMILY_INVALID: an invalid %SoupAddress
413 * @SOUP_ADDRESS_FAMILY_IPV4: an IPv4 address
414 * @SOUP_ADDRESS_FAMILY_IPV6: an IPv6 address
416 * The supported address families.
420 * SOUP_ADDRESS_ANY_PORT:
422 * This can be passed to any #SoupAddress method that expects a port,
423 * to indicate that you don't care what port is used.
427 * soup_address_new_any:
428 * @family: the address family
429 * @port: the port number (usually %SOUP_ADDRESS_ANY_PORT)
431 * Returns a #SoupAddress corresponding to the "any" address
432 * for @family (or %NULL if @family isn't supported), suitable for
433 * using as a listening #SoupSocket.
435 * Return value: (allow-none): the new #SoupAddress
438 soup_address_new_any (SoupAddressFamily family, guint port)
440 g_return_val_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (family), NULL);
441 g_return_val_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port), NULL);
443 return g_object_new (SOUP_TYPE_ADDRESS,
444 SOUP_ADDRESS_FAMILY, family,
445 SOUP_ADDRESS_PORT, port,
450 * soup_address_get_name:
451 * @addr: a #SoupAddress
453 * Returns the hostname associated with @addr.
455 * This method is not thread-safe; if you call it while @addr is being
456 * resolved in another thread, it may return garbage. You can use
457 * soup_address_is_resolved() to safely test whether or not an address
458 * is resolved before fetching its name or address.
460 * Return value: (allow-none): the hostname, or %NULL if it is not known.
463 soup_address_get_name (SoupAddress *addr)
465 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
467 return SOUP_ADDRESS_GET_PRIVATE (addr)->name;
471 * soup_address_get_sockaddr:
472 * @addr: a #SoupAddress
473 * @len: return location for sockaddr length
475 * Returns the sockaddr associated with @addr, with its length in
476 * *@len. If the sockaddr is not yet known, returns %NULL.
478 * This method is not thread-safe; if you call it while @addr is being
479 * resolved in another thread, it may return garbage. You can use
480 * soup_address_is_resolved() to safely test whether or not an address
481 * is resolved before fetching its name or address.
483 * Return value: (allow-none) (transfer none): the sockaddr, or %NULL
486 soup_address_get_sockaddr (SoupAddress *addr, int *len)
488 SoupAddressPrivate *priv;
490 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
491 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
493 if (priv->sockaddr && len)
494 *len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv));
495 return (struct sockaddr *)priv->sockaddr;
499 * soup_address_get_gsockaddr:
500 * @addr: a #SoupAddress
502 * Creates a new #GSocketAddress corresponding to @addr (which is assumed
503 * to only have one socket address associated with it).
505 * Return value: (transfer full): a new #GSocketAddress
510 soup_address_get_gsockaddr (SoupAddress *addr)
512 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
514 return g_socket_address_new_from_native (priv->sockaddr,
515 SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
518 static GInetAddress *
519 soup_address_make_inet_address (SoupAddress *addr)
521 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
525 gsa = g_socket_address_new_from_native (priv->sockaddr,
526 SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
527 gia = g_inet_socket_address_get_address ((GInetSocketAddress *)gsa);
529 g_object_unref (gsa);
534 * soup_address_get_physical:
535 * @addr: a #SoupAddress
537 * Returns the physical address associated with @addr as a string.
538 * (Eg, "127.0.0.1"). If the address is not yet known, returns %NULL.
540 * This method is not thread-safe; if you call it while @addr is being
541 * resolved in another thread, it may return garbage. You can use
542 * soup_address_is_resolved() to safely test whether or not an address
543 * is resolved before fetching its name or address.
545 * Return value: (allow-none): the physical address, or %NULL
548 soup_address_get_physical (SoupAddress *addr)
550 SoupAddressPrivate *priv;
552 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
553 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
558 if (!priv->physical) {
561 gia = soup_address_make_inet_address (addr);
562 priv->physical = g_inet_address_to_string (gia);
563 g_object_unref (gia);
566 return priv->physical;
570 * soup_address_get_port:
571 * @addr: a #SoupAddress
573 * Returns the port associated with @addr.
575 * Return value: the port
578 soup_address_get_port (SoupAddress *addr)
580 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), 0);
582 return SOUP_ADDRESS_GET_PRIVATE (addr)->port;
587 update_addrs (SoupAddress *addr, GList *addrs, GError *error)
589 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
595 if (error->domain == G_IO_ERROR &&
596 error->code == G_IO_ERROR_CANCELLED)
597 return SOUP_STATUS_CANCELLED;
599 return SOUP_STATUS_CANT_RESOLVE;
601 return SOUP_STATUS_CANT_RESOLVE;
602 else if (priv->sockaddr)
603 return SOUP_STATUS_OK;
605 priv->n_addrs = g_list_length (addrs);
606 priv->sockaddr = g_new (struct sockaddr_storage, priv->n_addrs);
607 for (i = 0; addrs; addrs = addrs->next, i++) {
609 gsa = g_inet_socket_address_new (gia, priv->port);
611 if (!g_socket_address_to_native (gsa, &priv->sockaddr[i],
612 sizeof (struct sockaddr_storage),
614 /* can't happen: We know the address format is supported
615 * and the buffer is large enough
617 g_warn_if_reached ();
619 g_object_unref (gsa);
622 return SOUP_STATUS_OK;
626 update_name (SoupAddress *addr, const char *name, GError *error)
628 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
631 if (error->domain == G_IO_ERROR &&
632 error->code == G_IO_ERROR_CANCELLED)
633 return SOUP_STATUS_CANCELLED;
635 return SOUP_STATUS_CANT_RESOLVE;
637 return SOUP_STATUS_CANT_RESOLVE;
639 return SOUP_STATUS_OK;
641 priv->name = g_strdup (name);
642 return SOUP_STATUS_OK;
646 SoupAddressCallback callback;
647 gpointer callback_data;
648 } SoupAddressResolveAsyncData;
651 complete_resolve_async (SoupAddress *addr, guint status)
653 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
654 SoupAddressResolveAsyncData *res_data;
656 GSource *current_source;
657 GMainContext *current_context;
659 lookups = priv->async_lookups;
660 priv->async_lookups = NULL;
662 /* Awful hack; to make soup_socket_connect_async() with an
663 * non-default async_context work correctly, we need to ensure
664 * that the non-default context (which we're now running in)
665 * is the thread-default when the callbacks are run...
667 current_source = g_main_current_source ();
668 if (current_source && !g_source_is_destroyed (current_source))
669 current_context = g_source_get_context (current_source);
671 current_context = NULL;
672 g_main_context_push_thread_default (current_context);
674 for (l = lookups; l; l = l->next) {
677 if (res_data->callback) {
678 res_data->callback (addr, status,
679 res_data->callback_data);
681 g_slice_free (SoupAddressResolveAsyncData, res_data);
683 g_slist_free (lookups);
685 g_main_context_pop_thread_default (current_context);
687 g_object_unref (addr);
691 lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
693 GResolver *resolver = G_RESOLVER (source);
694 SoupAddress *addr = user_data;
695 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
696 GError *error = NULL;
699 if (!priv->sockaddr) {
702 addrs = g_resolver_lookup_by_name_finish (resolver, result,
704 status = update_addrs (addr, addrs, error);
705 g_resolver_free_addresses (addrs);
706 } else if (!priv->name) {
709 name = g_resolver_lookup_by_address_finish (resolver, result,
711 status = update_name (addr, name, error);
714 status = SOUP_STATUS_OK;
716 /* For the enumerator impl, below */
718 g_object_set_data (G_OBJECT (addr), "async-resolved-error", error);
720 complete_resolve_async (addr, status);
722 g_object_set_data (G_OBJECT (addr), "async-resolved-error", NULL);
723 g_object_unref (addr);
725 g_error_free (error);
729 idle_complete_resolve (gpointer addr)
731 complete_resolve_async (addr, SOUP_STATUS_OK);
736 * SoupAddressCallback:
737 * @addr: the #SoupAddress that was resolved
738 * @status: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or
739 * %SOUP_STATUS_CANCELLED
740 * @user_data: the user data that was passed to
741 * soup_address_resolve_async()
743 * The callback function passed to soup_address_resolve_async().
747 * soup_address_resolve_async:
748 * @addr: a #SoupAddress
749 * @async_context: (allow-none): the #GMainContext to call @callback from
750 * @cancellable: a #GCancellable object, or %NULL
751 * @callback: (scope async): callback to call with the result
752 * @user_data: data for @callback
754 * Asynchronously resolves the missing half of @addr (its IP address
755 * if it was created with soup_address_new(), or its hostname if it
756 * was created with soup_address_new_from_sockaddr() or
757 * soup_address_new_any().)
759 * If @cancellable is non-%NULL, it can be used to cancel the
760 * resolution. @callback will still be invoked in this case, with a
761 * status of %SOUP_STATUS_CANCELLED.
763 * It is safe to call this more than once on a given address, from the
764 * same thread, with the same @async_context (and doing so will not
765 * result in redundant DNS queries being made). But it is not safe to
766 * call from multiple threads, or with different @async_contexts, or
767 * mixed with calls to soup_address_resolve_sync().
770 soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
771 GCancellable *cancellable,
772 SoupAddressCallback callback, gpointer user_data)
774 SoupAddressPrivate *priv;
775 SoupAddressResolveAsyncData *res_data;
777 gboolean already_started;
779 g_return_if_fail (SOUP_IS_ADDRESS (addr));
780 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
781 g_return_if_fail (priv->name || priv->sockaddr);
783 /* We don't need to do locking here because the async case is
784 * not intended to be thread-safe.
787 if (priv->name && priv->sockaddr && !callback)
790 res_data = g_slice_new0 (SoupAddressResolveAsyncData);
791 res_data->callback = callback;
792 res_data->callback_data = user_data;
794 already_started = priv->async_lookups != NULL;
795 priv->async_lookups = g_slist_prepend (priv->async_lookups, res_data);
802 if (priv->name && priv->sockaddr) {
803 soup_add_completion (async_context, idle_complete_resolve, addr);
807 resolver = g_resolver_get_default ();
809 g_main_context_push_thread_default (async_context);
812 g_resolver_lookup_by_name_async (resolver, priv->name,
814 lookup_resolved, addr);
818 gia = soup_address_make_inet_address (addr);
819 g_resolver_lookup_by_address_async (resolver, gia,
821 lookup_resolved, addr);
822 g_object_unref (gia);
826 g_main_context_pop_thread_default (async_context);
827 g_object_unref (resolver);
831 resolve_sync_internal (SoupAddress *addr, GCancellable *cancellable, GError **error)
833 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
836 GError *my_err = NULL;
838 resolver = g_resolver_get_default ();
840 /* We could optimize this to avoid multiple lookups the same
841 * way _resolve_async does, but we don't currently. So, first
842 * lock the mutex to ensure we have a consistent view of
843 * priv->sockaddr and priv->name, unlock it around the
844 * blocking op, and then re-lock it to modify @addr.
846 g_mutex_lock (&priv->lock);
847 if (!priv->sockaddr) {
850 g_mutex_unlock (&priv->lock);
851 addrs = g_resolver_lookup_by_name (resolver, priv->name,
852 cancellable, &my_err);
853 g_mutex_lock (&priv->lock);
855 status = update_addrs (addr, addrs, my_err);
856 g_resolver_free_addresses (addrs);
857 } else if (!priv->name) {
861 g_mutex_unlock (&priv->lock);
862 gia = soup_address_make_inet_address (addr);
863 name = g_resolver_lookup_by_address (resolver, gia,
864 cancellable, &my_err);
865 g_object_unref (gia);
866 g_mutex_lock (&priv->lock);
868 status = update_name (addr, name, my_err);
871 status = SOUP_STATUS_OK;
872 g_mutex_unlock (&priv->lock);
875 g_propagate_error (error, my_err);
876 g_object_unref (resolver);
882 * soup_address_resolve_sync:
883 * @addr: a #SoupAddress
884 * @cancellable: a #GCancellable object, or %NULL
886 * Synchronously resolves the missing half of @addr, as with
887 * soup_address_resolve_async().
889 * If @cancellable is non-%NULL, it can be used to cancel the
890 * resolution. soup_address_resolve_sync() will then return a status
891 * of %SOUP_STATUS_CANCELLED.
893 * It is safe to call this more than once, even from different
894 * threads, but it is not safe to mix calls to
895 * soup_address_resolve_sync() with calls to
896 * soup_address_resolve_async() on the same address.
898 * Return value: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or
899 * %SOUP_STATUS_CANCELLED.
902 soup_address_resolve_sync (SoupAddress *addr, GCancellable *cancellable)
904 SoupAddressPrivate *priv;
906 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), SOUP_STATUS_MALFORMED);
907 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
908 g_return_val_if_fail (priv->name || priv->sockaddr, SOUP_STATUS_MALFORMED);
910 return resolve_sync_internal (addr, cancellable, NULL);
914 * soup_address_is_resolved:
915 * @addr: a #SoupAddress
917 * Tests if @addr has already been resolved. Unlike the other
918 * #SoupAddress "get" methods, this is safe to call when @addr might
919 * be being resolved in another thread.
921 * Return value: %TRUE if @addr has been resolved.
924 soup_address_is_resolved (SoupAddress *addr)
926 SoupAddressPrivate *priv;
929 g_return_val_if_fail (SOUP_IS_ADDRESS (addr), FALSE);
930 priv = SOUP_ADDRESS_GET_PRIVATE (addr);
932 g_mutex_lock (&priv->lock);
933 resolved = priv->sockaddr && priv->name;
934 g_mutex_unlock (&priv->lock);
940 * soup_address_hash_by_name:
941 * @addr: (type Soup.Address): a #SoupAddress
943 * A hash function (for #GHashTable) that corresponds to
944 * soup_address_equal_by_name(), qv
946 * Return value: the named-based hash value for @addr.
951 soup_address_hash_by_name (gconstpointer addr)
953 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
955 g_return_val_if_fail (priv->name != NULL, 0);
956 return g_str_hash (priv->name);
960 * soup_address_equal_by_name:
961 * @addr1: (type Soup.Address): a #SoupAddress with a resolved name
962 * @addr2: (type Soup.Address): another #SoupAddress with a resolved
965 * Tests if @addr1 and @addr2 have the same "name". This method can be
966 * used with soup_address_hash_by_name() to create a #GHashTable that
967 * hashes on address "names".
969 * Comparing by name normally means comparing the addresses by their
970 * hostnames. But if the address was originally created using an IP
971 * address literal, then it will be compared by that instead.
973 * In particular, if "www.example.com" has the IP address 10.0.0.1,
974 * and @addr1 was created with the name "www.example.com" and @addr2
975 * was created with the name "10.0.0.1", then they will compare as
976 * unequal for purposes of soup_address_equal_by_name().
978 * This would be used to distinguish hosts in situations where
979 * different virtual hosts on the same IP address should be considered
980 * different. Eg, for purposes of HTTP authentication or cookies, two
981 * hosts with the same IP address but different names are considered
982 * to be different hosts.
984 * See also soup_address_equal_by_ip(), which compares by IP address
985 * rather than by name.
987 * Return value: whether or not @addr1 and @addr2 have the same name
992 soup_address_equal_by_name (gconstpointer addr1, gconstpointer addr2)
994 SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
995 SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
997 g_return_val_if_fail (priv1->name != NULL, FALSE);
998 g_return_val_if_fail (priv2->name != NULL, FALSE);
999 return !g_ascii_strcasecmp (priv1->name, priv2->name);
1003 * soup_address_hash_by_ip:
1004 * @addr: (type Soup.Address): a #SoupAddress
1006 * A hash function (for #GHashTable) that corresponds to
1007 * soup_address_equal_by_ip(), qv
1009 * Return value: the IP-based hash value for @addr.
1014 soup_address_hash_by_ip (gconstpointer addr)
1016 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
1019 g_return_val_if_fail (priv->sockaddr != NULL, 0);
1021 memcpy (&hash, SOUP_ADDRESS_GET_DATA (priv),
1022 MIN (sizeof (hash), SOUP_ADDRESS_FAMILY_DATA_SIZE (priv->sockaddr->ss_family)));
1027 * soup_address_equal_by_ip:
1028 * @addr1: (type Soup.Address): a #SoupAddress with a resolved IP
1030 * @addr2: (type Soup.Address): another #SoupAddress with a resolved
1033 * Tests if @addr1 and @addr2 have the same IP address. This method
1034 * can be used with soup_address_hash_by_ip() to create a
1035 * #GHashTable that hashes on IP address.
1037 * This would be used to distinguish hosts in situations where
1038 * different virtual hosts on the same IP address should be considered
1039 * the same. Eg, if "www.example.com" and "www.example.net" have the
1040 * same IP address, then a single connection can be used to talk
1041 * to either of them.
1043 * See also soup_address_equal_by_name(), which compares by name
1044 * rather than by IP address.
1046 * Return value: whether or not @addr1 and @addr2 have the same IP
1052 soup_address_equal_by_ip (gconstpointer addr1, gconstpointer addr2)
1054 SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
1055 SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
1058 g_return_val_if_fail (priv1->sockaddr != NULL, FALSE);
1059 g_return_val_if_fail (priv2->sockaddr != NULL, FALSE);
1061 size = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (priv1->sockaddr->ss_family);
1062 return (priv1->sockaddr->ss_family ==
1063 priv2->sockaddr->ss_family &&
1064 !memcmp (priv1->sockaddr, priv2->sockaddr, size));
1068 #define SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR (_soup_address_address_enumerator_get_type ())
1069 #define SOUP_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR, SoupAddressAddressEnumerator))
1072 GSocketAddressEnumerator parent_instance;
1077 } SoupAddressAddressEnumerator;
1080 GSocketAddressEnumeratorClass parent_class;
1082 } SoupAddressAddressEnumeratorClass;
1084 GType _soup_address_address_enumerator_get_type (void);
1085 G_DEFINE_TYPE (SoupAddressAddressEnumerator, _soup_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR)
1088 soup_address_address_enumerator_finalize (GObject *object)
1090 SoupAddressAddressEnumerator *addr_enum =
1091 SOUP_ADDRESS_ADDRESS_ENUMERATOR (object);
1093 g_object_unref (addr_enum->addr);
1095 G_OBJECT_CLASS (_soup_address_address_enumerator_parent_class)->finalize (object);
1098 static GSocketAddress *
1099 next_address (SoupAddressAddressEnumerator *addr_enum)
1101 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1102 struct sockaddr_storage *ss;
1105 /* If there are two addresses but the first one is unusable
1106 * (eg, it's IPv6 and we can only do IPv4), then we don't want to
1107 * try the bad one every time. So we use priv->offset to remember
1108 * the offset of the first usable address (ie, the first address
1109 * that we weren't called again after returning).
1111 next_addr = (addr_enum->orig_offset + addr_enum->n) % priv->n_addrs;
1112 priv->offset = next_addr;
1114 if (addr_enum->n >= priv->n_addrs)
1118 ss = &priv->sockaddr[next_addr];
1119 return g_socket_address_new_from_native (ss, SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (ss->ss_family));
1122 static GSocketAddress *
1123 soup_address_address_enumerator_next (GSocketAddressEnumerator *enumerator,
1124 GCancellable *cancellable,
1127 SoupAddressAddressEnumerator *addr_enum =
1128 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1129 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1131 if (!priv->sockaddr) {
1132 if (resolve_sync_internal (addr_enum->addr, cancellable, error) != SOUP_STATUS_OK)
1136 return next_address (addr_enum);
1140 got_addresses (SoupAddress *addr, guint status, gpointer user_data)
1142 GSimpleAsyncResult *simple = user_data;
1145 error = g_object_get_data (G_OBJECT (addr), "async-resolved-error");
1147 g_simple_async_result_set_from_error (simple, error);
1149 g_simple_async_result_complete (simple);
1150 g_object_unref (simple);
1154 soup_address_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
1155 GCancellable *cancellable,
1156 GAsyncReadyCallback callback,
1159 SoupAddressAddressEnumerator *addr_enum =
1160 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1161 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1162 GSimpleAsyncResult *simple;
1164 simple = g_simple_async_result_new (G_OBJECT (enumerator),
1165 callback, user_data,
1166 soup_address_address_enumerator_next_async);
1168 if (!priv->sockaddr) {
1169 soup_address_resolve_async (addr_enum->addr, NULL, cancellable,
1170 got_addresses, simple);
1172 g_simple_async_result_complete_in_idle (simple);
1173 g_object_unref (simple);
1177 static GSocketAddress *
1178 soup_address_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator,
1179 GAsyncResult *result,
1182 SoupAddressAddressEnumerator *addr_enum =
1183 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1184 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1186 if (g_simple_async_result_propagate_error (simple, error))
1189 return next_address (addr_enum);
1193 _soup_address_address_enumerator_init (SoupAddressAddressEnumerator *enumerator)
1198 _soup_address_address_enumerator_class_init (SoupAddressAddressEnumeratorClass *addrenum_class)
1200 GObjectClass *object_class = G_OBJECT_CLASS (addrenum_class);
1201 GSocketAddressEnumeratorClass *enumerator_class =
1202 G_SOCKET_ADDRESS_ENUMERATOR_CLASS (addrenum_class);
1204 enumerator_class->next = soup_address_address_enumerator_next;
1205 enumerator_class->next_async = soup_address_address_enumerator_next_async;
1206 enumerator_class->next_finish = soup_address_address_enumerator_next_finish;
1207 object_class->finalize = soup_address_address_enumerator_finalize;
1210 static GSocketAddressEnumerator *
1211 soup_address_connectable_enumerate (GSocketConnectable *connectable)
1213 SoupAddressAddressEnumerator *addr_enum;
1214 SoupAddressPrivate *priv;
1216 addr_enum = g_object_new (SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR, NULL);
1217 addr_enum->addr = g_object_ref (connectable);
1219 priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1220 addr_enum->orig_offset = priv->offset;
1222 return (GSocketAddressEnumerator *)addr_enum;
1225 static GSocketAddressEnumerator *
1226 soup_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
1228 SoupAddress *addr = SOUP_ADDRESS (connectable);
1229 SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
1230 GSocketAddressEnumerator *proxy_enum;
1233 /* We cheerily assume "http" here because you shouldn't be
1234 * using SoupAddress any more if you're not doing HTTP anyway.
1236 uri = g_strdup_printf ("%s://%s:%u",
1237 priv->protocol ? priv->protocol : "http",
1238 priv->name ? priv->name : soup_address_get_physical (addr),
1240 proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1241 "connectable", connectable,