Reapplying patch to disable attempts to use gtk-doc
[profile/ivi/libsoup2.4.git] / libsoup / soup-address.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-address.c: Internet address handing
4  *
5  * Copyright (C) 2010 Red Hat, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <unistd.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/types.h>
18
19 #include <gio/gio.h>
20
21 #include "soup-address.h"
22 #include "soup-enum-types.h"
23 #include "soup-marshal.h"
24 #include "soup-misc.h"
25
26 /**
27  * SECTION:soup-address
28  * @short_description: DNS support
29  *
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.)
33  **/
34
35 enum {
36         PROP_0,
37
38         PROP_NAME,
39         PROP_FAMILY,
40         PROP_PORT,
41         PROP_PROTOCOL,
42         PROP_PHYSICAL,
43         PROP_SOCKADDR,
44
45         LAST_PROP
46 };
47
48 typedef struct {
49         struct sockaddr_storage *sockaddr;
50         int n_addrs, offset;
51
52         char *name, *physical;
53         guint port;
54         const char *protocol;
55
56         GMutex lock;
57         GSList *async_lookups;
58 } SoupAddressPrivate;
59 #define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS, SoupAddressPrivate))
60
61 /* sockaddr generic macros */
62 #define SOUP_SIN(priv) ((struct sockaddr_in *)priv->sockaddr)
63 #define SOUP_SIN6(priv) ((struct sockaddr_in6 *)priv->sockaddr)
64
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))
77
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) \
85         G_STMT_START {                                  \
86         if (priv->sockaddr->ss_family == AF_INET)       \
87                 SOUP_SIN(priv)->sin_port = port;        \
88         else                                            \
89                 SOUP_SIN6(priv)->sin6_port = port;      \
90         } G_STMT_END
91
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)
99
100
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);
108
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);
112
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))
116
117 static void
118 soup_address_init (SoupAddress *addr)
119 {
120         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
121
122         g_mutex_init (&priv->lock);
123 }
124
125 static void
126 finalize (GObject *object)
127 {
128         SoupAddress *addr = SOUP_ADDRESS (object);
129         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
130
131         if (priv->sockaddr)
132                 g_free (priv->sockaddr);
133         if (priv->name)
134                 g_free (priv->name);
135         if (priv->physical)
136                 g_free (priv->physical);
137
138         g_mutex_clear (&priv->lock);
139
140         G_OBJECT_CLASS (soup_address_parent_class)->finalize (object);
141 }
142
143 static void
144 soup_address_class_init (SoupAddressClass *address_class)
145 {
146         GObjectClass *object_class = G_OBJECT_CLASS (address_class);
147
148         g_type_class_add_private (address_class, sizeof (SoupAddressPrivate));
149
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;
155
156         /* properties */
157         /**
158          * SOUP_ADDRESS_NAME:
159          *
160          * Alias for the #SoupAddress:name property. (The hostname for
161          * this address.)
162          **/
163         g_object_class_install_property (
164                 object_class, PROP_NAME,
165                 g_param_spec_string (SOUP_ADDRESS_NAME,
166                                      "Name",
167                                      "Hostname for this address",
168                                      NULL,
169                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
170         /**
171          * SOUP_ADDRESS_FAMILY:
172          *
173          * Alias for the #SoupAddress:family property. (The
174          * #SoupAddressFamily for this address.)
175          **/
176         g_object_class_install_property (
177                 object_class, PROP_FAMILY,
178                 g_param_spec_enum (SOUP_ADDRESS_FAMILY,
179                                    "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));
184         /**
185          * SOUP_ADDRESS_PORT:
186          *
187          * An alias for the #SoupAddress:port property. (The port for
188          * this address.)
189          **/
190         g_object_class_install_property (
191                 object_class, PROP_PORT,
192                 g_param_spec_int (SOUP_ADDRESS_PORT,
193                                   "Port",
194                                   "Port for this address",
195                                   -1, 65535, -1,
196                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
197         /**
198          * SOUP_ADDRESS_PROTOCOL:
199          *
200          * Alias for the #SoupAddress:protocol property. (The URI scheme
201          * used with this address.)
202          **/
203         g_object_class_install_property (
204                 object_class, PROP_PROTOCOL,
205                 g_param_spec_string (SOUP_ADDRESS_PROTOCOL,
206                                      "Protocol",
207                                      "URI scheme for this address",
208                                      NULL,
209                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
210         /**
211          * SOUP_ADDRESS_PHYSICAL:
212          *
213          * An alias for the #SoupAddress:physical property. (The
214          * stringified IP address for this address.)
215          **/
216         g_object_class_install_property (
217                 object_class, PROP_PHYSICAL,
218                 g_param_spec_string (SOUP_ADDRESS_PHYSICAL,
219                                      "Physical address",
220                                      "IP address for this address",
221                                      NULL,
222                                      G_PARAM_READABLE));
223         /**
224          * SOUP_ADDRESS_SOCKADDR:
225          *
226          * An alias for the #SoupAddress:sockaddr property. (A pointer
227          * to the struct sockaddr for this address.)
228          **/
229         g_object_class_install_property (
230                 object_class, PROP_SOCKADDR,
231                 g_param_spec_pointer (SOUP_ADDRESS_SOCKADDR,
232                                       "sockaddr",
233                                       "struct sockaddr for this address",
234                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
235 }
236
237 static void
238 soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface)
239 {
240   connectable_iface->enumerate       = soup_address_connectable_enumerate;
241   connectable_iface->proxy_enumerate = soup_address_connectable_proxy_enumerate;
242 }
243
244 static GObject *
245 constructor (GType                  type,
246              guint                  n_construct_properties,
247              GObjectConstructParam *construct_properties)
248 {
249         GObject *addr;
250         SoupAddressPrivate *priv;
251
252         addr = G_OBJECT_CLASS (soup_address_parent_class)->constructor (
253                 type, n_construct_properties, construct_properties);
254         if (!addr)
255                 return NULL;
256         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
257
258         if (!priv->name && !priv->sockaddr) {
259                 g_object_unref (addr);
260                 return NULL;
261         }
262
263         return addr;
264 }
265
266 static void
267 set_property (GObject *object, guint prop_id,
268               const GValue *value, GParamSpec *pspec)
269 {
270         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
271         SoupAddressFamily family;
272         struct sockaddr *sa;
273         int len, port;
274
275         /* This is a mess because the properties are mostly orthogonal,
276          * but g_object_constructor wants to set a default value for each
277          * of them.
278          */
279
280         switch (prop_id) {
281         case PROP_NAME:
282                 priv->name = g_value_dup_string (value);
283                 break;
284
285         case PROP_FAMILY:
286                 family = g_value_get_enum (value);
287                 if (family == SOUP_ADDRESS_FAMILY_INVALID)
288                         return;
289                 g_return_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (family));
290                 g_return_if_fail (priv->sockaddr == NULL);
291
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));
295                 priv->n_addrs = 1;
296                 break;
297
298         case PROP_PORT:
299                 port = g_value_get_int (value);
300                 if (port == -1)
301                         return;
302                 g_return_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port));
303
304                 priv->port = port;
305                 if (priv->sockaddr)
306                         SOUP_ADDRESS_SET_PORT (priv, htons (port));
307                 break;
308
309         case PROP_PROTOCOL:
310                 priv->protocol = g_intern_string (g_value_get_string (value));
311                 break;
312
313         case PROP_SOCKADDR:
314                 sa = g_value_get_pointer (value);
315                 if (!sa)
316                         return;
317                 g_return_if_fail (priv->sockaddr == NULL);
318
319                 len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (sa->sa_family);
320                 priv->sockaddr = g_memdup (sa, len);
321                 priv->n_addrs = 1;
322                 priv->port = ntohs (SOUP_ADDRESS_GET_PORT (priv));
323                 break;
324         default:
325                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
326                 break;
327         }
328 }
329
330 static void
331 get_property (GObject *object, guint prop_id,
332               GValue *value, GParamSpec *pspec)
333 {
334         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
335
336         switch (prop_id) {
337         case PROP_NAME:
338                 g_value_set_string (value, priv->name);
339                 break;
340         case PROP_FAMILY:
341                 if (priv->sockaddr)
342                         g_value_set_enum (value, SOUP_ADDRESS_GET_FAMILY (priv));
343                 else
344                         g_value_set_enum (value, 0);
345                 break;
346         case PROP_PORT:
347                 g_value_set_int (value, priv->port);
348                 break;
349         case PROP_PHYSICAL:
350                 g_value_set_string (value, soup_address_get_physical (SOUP_ADDRESS (object)));
351                 break;
352         case PROP_PROTOCOL:
353                 g_value_set_string (value, priv->protocol);
354                 break;
355         case PROP_SOCKADDR:
356                 g_value_set_pointer (value, priv->sockaddr);
357                 break;
358         default:
359                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
360                 break;
361         }
362 }
363
364 /**
365  * soup_address_new:
366  * @name: a hostname or physical address
367  * @port: a port number
368  *
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.
373  *
374  * Return value: a #SoupAddress
375  **/
376 SoupAddress *
377 soup_address_new (const char *name, guint port)
378 {
379         g_return_val_if_fail (name != NULL, NULL);
380         g_return_val_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port), NULL);
381
382         return g_object_new (SOUP_TYPE_ADDRESS,
383                              SOUP_ADDRESS_NAME, name,
384                              SOUP_ADDRESS_PORT, port,
385                              NULL);
386 }
387
388 /**
389  * soup_address_new_from_sockaddr:
390  * @sa: a pointer to a sockaddr
391  * @len: size of @sa
392  *
393  * Returns a #SoupAddress equivalent to @sa (or %NULL if @sa's
394  * address family isn't supported)
395  *
396  * Return value: (allow-none): the new #SoupAddress
397  **/
398 SoupAddress *
399 soup_address_new_from_sockaddr (struct sockaddr *sa, int len)
400 {
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);
404
405         return g_object_new (SOUP_TYPE_ADDRESS,
406                              SOUP_ADDRESS_SOCKADDR, sa,
407                              NULL);
408 }
409
410 /**
411  * SoupAddressFamily:
412  * @SOUP_ADDRESS_FAMILY_INVALID: an invalid %SoupAddress
413  * @SOUP_ADDRESS_FAMILY_IPV4: an IPv4 address
414  * @SOUP_ADDRESS_FAMILY_IPV6: an IPv6 address
415  *
416  * The supported address families.
417  **/
418
419 /**
420  * SOUP_ADDRESS_ANY_PORT:
421  *
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.
424  **/
425
426 /**
427  * soup_address_new_any:
428  * @family: the address family
429  * @port: the port number (usually %SOUP_ADDRESS_ANY_PORT)
430  *
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.
434  *
435  * Return value: (allow-none): the new #SoupAddress
436  **/
437 SoupAddress *
438 soup_address_new_any (SoupAddressFamily family, guint port)
439 {
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);
442
443         return g_object_new (SOUP_TYPE_ADDRESS,
444                              SOUP_ADDRESS_FAMILY, family,
445                              SOUP_ADDRESS_PORT, port,
446                              NULL);
447 }
448
449 /**
450  * soup_address_get_name:
451  * @addr: a #SoupAddress
452  *
453  * Returns the hostname associated with @addr.
454  *
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.
459  *
460  * Return value: (allow-none): the hostname, or %NULL if it is not known.
461  **/
462 const char *
463 soup_address_get_name (SoupAddress *addr)
464 {
465         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
466
467         return SOUP_ADDRESS_GET_PRIVATE (addr)->name;
468 }
469
470 /**
471  * soup_address_get_sockaddr:
472  * @addr: a #SoupAddress
473  * @len: return location for sockaddr length
474  *
475  * Returns the sockaddr associated with @addr, with its length in
476  * *@len. If the sockaddr is not yet known, returns %NULL.
477  *
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.
482  *
483  * Return value: (allow-none) (transfer none): the sockaddr, or %NULL
484  **/
485 struct sockaddr *
486 soup_address_get_sockaddr (SoupAddress *addr, int *len)
487 {
488         SoupAddressPrivate *priv;
489
490         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
491         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
492
493         if (priv->sockaddr && len)
494                 *len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv));
495         return (struct sockaddr *)priv->sockaddr;
496 }
497
498 /**
499  * soup_address_get_gsockaddr:
500  * @addr: a #SoupAddress
501  *
502  * Creates a new #GSocketAddress corresponding to @addr (which is assumed
503  * to only have one socket address associated with it).
504  *
505  * Return value: (transfer full): a new #GSocketAddress
506  *
507  * Since: 2.32
508  */
509 GSocketAddress *
510 soup_address_get_gsockaddr (SoupAddress *addr)
511 {
512         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
513
514         return g_socket_address_new_from_native (priv->sockaddr,
515                                                  SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
516 }
517
518 static GInetAddress *
519 soup_address_make_inet_address (SoupAddress *addr)
520 {
521         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
522         GSocketAddress *gsa;
523         GInetAddress *gia;
524
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);
528         g_object_ref (gia);
529         g_object_unref (gsa);
530         return gia;
531 }
532
533 /**
534  * soup_address_get_physical:
535  * @addr: a #SoupAddress
536  *
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.
539  *
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.
544  *
545  * Return value: (allow-none): the physical address, or %NULL
546  **/
547 const char *
548 soup_address_get_physical (SoupAddress *addr)
549 {
550         SoupAddressPrivate *priv;
551
552         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
553         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
554
555         if (!priv->sockaddr)
556                 return NULL;
557
558         if (!priv->physical) {
559                 GInetAddress *gia;
560
561                 gia = soup_address_make_inet_address (addr);
562                 priv->physical = g_inet_address_to_string (gia);
563                 g_object_unref (gia);
564         }
565
566         return priv->physical;
567 }
568
569 /**
570  * soup_address_get_port:
571  * @addr: a #SoupAddress
572  *
573  * Returns the port associated with @addr.
574  *
575  * Return value: the port
576  **/
577 guint
578 soup_address_get_port (SoupAddress *addr)
579 {
580         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), 0);
581
582         return SOUP_ADDRESS_GET_PRIVATE (addr)->port;
583 }
584
585
586 static guint
587 update_addrs (SoupAddress *addr, GList *addrs, GError *error)
588 {
589         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
590         GInetAddress *gia;
591         GSocketAddress *gsa;
592         int i;
593
594         if (error) {
595                 if (error->domain == G_IO_ERROR &&
596                     error->code == G_IO_ERROR_CANCELLED)
597                         return SOUP_STATUS_CANCELLED;
598                 else
599                         return SOUP_STATUS_CANT_RESOLVE;
600         } else if (!addrs)
601                 return SOUP_STATUS_CANT_RESOLVE;
602         else if (priv->sockaddr)
603                 return SOUP_STATUS_OK;
604
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++) {
608                 gia = addrs->data;
609                 gsa = g_inet_socket_address_new (gia, priv->port);
610
611                 if (!g_socket_address_to_native (gsa, &priv->sockaddr[i],
612                                                  sizeof (struct sockaddr_storage),
613                                                  NULL)) {
614                         /* can't happen: We know the address format is supported
615                          * and the buffer is large enough
616                          */
617                         g_warn_if_reached ();
618                 }
619                 g_object_unref (gsa);
620         }
621
622         return SOUP_STATUS_OK;
623 }
624
625 static guint
626 update_name (SoupAddress *addr, const char *name, GError *error)
627 {
628         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
629
630         if (error) {
631                 if (error->domain == G_IO_ERROR &&
632                     error->code == G_IO_ERROR_CANCELLED)
633                         return SOUP_STATUS_CANCELLED;
634                 else
635                         return SOUP_STATUS_CANT_RESOLVE;
636         } else if (!name)
637                 return SOUP_STATUS_CANT_RESOLVE;
638         else if (priv->name)
639                 return SOUP_STATUS_OK;
640
641         priv->name = g_strdup (name);
642         return SOUP_STATUS_OK;
643 }
644
645 typedef struct {
646         SoupAddressCallback  callback;
647         gpointer             callback_data;
648 } SoupAddressResolveAsyncData;
649
650 static void
651 complete_resolve_async (SoupAddress *addr, guint status)
652 {
653         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
654         SoupAddressResolveAsyncData *res_data;
655         GSList *lookups, *l;
656         GSource *current_source;
657         GMainContext *current_context;
658
659         lookups = priv->async_lookups;
660         priv->async_lookups = NULL;
661
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...
666          */
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);
670         else
671                 current_context = NULL;
672         g_main_context_push_thread_default (current_context);
673
674         for (l = lookups; l; l = l->next) {
675                 res_data = l->data;
676
677                 if (res_data->callback) {
678                         res_data->callback (addr, status,
679                                             res_data->callback_data);
680                 }
681                 g_slice_free (SoupAddressResolveAsyncData, res_data);
682         }
683         g_slist_free (lookups);
684
685         g_main_context_pop_thread_default (current_context);
686
687         g_object_unref (addr);
688 }
689
690 static void
691 lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
692 {
693         GResolver *resolver = G_RESOLVER (source);
694         SoupAddress *addr = user_data;
695         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
696         GError *error = NULL;
697         guint status;
698
699         if (!priv->sockaddr) {
700                 GList *addrs;
701
702                 addrs = g_resolver_lookup_by_name_finish (resolver, result,
703                                                           &error);
704                 status = update_addrs (addr, addrs, error);
705                 g_resolver_free_addresses (addrs);
706         } else if (!priv->name) {
707                 char *name;
708
709                 name = g_resolver_lookup_by_address_finish (resolver, result,
710                                                             &error);
711                 status = update_name (addr, name, error);
712                 g_free (name);
713         } else
714                 status = SOUP_STATUS_OK;
715
716         /* For the enumerator impl, below */
717         g_object_ref (addr);
718         g_object_set_data (G_OBJECT (addr), "async-resolved-error", error);
719
720         complete_resolve_async (addr, status);
721
722         g_object_set_data (G_OBJECT (addr), "async-resolved-error", NULL);
723         g_object_unref (addr);
724         if (error)
725                 g_error_free (error);
726 }
727
728 static gboolean
729 idle_complete_resolve (gpointer addr)
730 {
731         complete_resolve_async (addr, SOUP_STATUS_OK);
732         return FALSE;
733 }
734
735 /**
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()
742  *
743  * The callback function passed to soup_address_resolve_async().
744  **/
745
746 /**
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
753  *
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().)
758  *
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.
762  *
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().
768  **/
769 void
770 soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
771                             GCancellable *cancellable,
772                             SoupAddressCallback callback, gpointer user_data)
773 {
774         SoupAddressPrivate *priv;
775         SoupAddressResolveAsyncData *res_data;
776         GResolver *resolver;
777         gboolean already_started;
778
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);
782
783         /* We don't need to do locking here because the async case is
784          * not intended to be thread-safe.
785          */
786
787         if (priv->name && priv->sockaddr && !callback)
788                 return;
789
790         res_data = g_slice_new0 (SoupAddressResolveAsyncData);
791         res_data->callback = callback;
792         res_data->callback_data = user_data;
793
794         already_started = priv->async_lookups != NULL;
795         priv->async_lookups = g_slist_prepend (priv->async_lookups, res_data);
796
797         if (already_started)
798                 return;
799
800         g_object_ref (addr);
801
802         if (priv->name && priv->sockaddr) {
803                 soup_add_completion (async_context, idle_complete_resolve, addr);
804                 return;
805         }
806
807         resolver = g_resolver_get_default ();
808         if (async_context)
809                 g_main_context_push_thread_default (async_context);
810
811         if (priv->name) {
812                 g_resolver_lookup_by_name_async (resolver, priv->name,
813                                                  cancellable,
814                                                  lookup_resolved, addr);
815         } else {
816                 GInetAddress *gia;
817
818                 gia = soup_address_make_inet_address (addr);
819                 g_resolver_lookup_by_address_async (resolver, gia,
820                                                     cancellable,
821                                                     lookup_resolved, addr);
822                 g_object_unref (gia);
823         }
824
825         if (async_context)
826                 g_main_context_pop_thread_default (async_context);
827         g_object_unref (resolver);
828 }
829
830 static guint
831 resolve_sync_internal (SoupAddress *addr, GCancellable *cancellable, GError **error)
832 {
833         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
834         GResolver *resolver;
835         guint status;
836         GError *my_err = NULL;
837
838         resolver = g_resolver_get_default ();
839
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.
845          */
846         g_mutex_lock (&priv->lock);
847         if (!priv->sockaddr) {
848                 GList *addrs;
849
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);
854
855                 status = update_addrs (addr, addrs, my_err);
856                 g_resolver_free_addresses (addrs);
857         } else if (!priv->name) {
858                 GInetAddress *gia;
859                 char *name;
860
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);
867
868                 status = update_name (addr, name, my_err);
869                 g_free (name);
870         } else
871                 status = SOUP_STATUS_OK;
872         g_mutex_unlock (&priv->lock);
873
874         if (my_err)
875                 g_propagate_error (error, my_err);
876         g_object_unref (resolver);
877
878         return status;
879 }
880
881 /**
882  * soup_address_resolve_sync:
883  * @addr: a #SoupAddress
884  * @cancellable: a #GCancellable object, or %NULL
885  *
886  * Synchronously resolves the missing half of @addr, as with
887  * soup_address_resolve_async().
888  *
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.
892  *
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.
897  *
898  * Return value: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or
899  * %SOUP_STATUS_CANCELLED.
900  **/
901 guint
902 soup_address_resolve_sync (SoupAddress *addr, GCancellable *cancellable)
903 {
904         SoupAddressPrivate *priv;
905
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);
909
910         return resolve_sync_internal (addr, cancellable, NULL);
911 }
912
913 /**
914  * soup_address_is_resolved:
915  * @addr: a #SoupAddress
916  *
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.
920  *
921  * Return value: %TRUE if @addr has been resolved.
922  **/
923 gboolean
924 soup_address_is_resolved (SoupAddress *addr)
925 {
926         SoupAddressPrivate *priv;
927         gboolean resolved;
928
929         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), FALSE);
930         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
931
932         g_mutex_lock (&priv->lock);
933         resolved = priv->sockaddr && priv->name;
934         g_mutex_unlock (&priv->lock);
935
936         return resolved;
937 }
938
939 /**
940  * soup_address_hash_by_name:
941  * @addr: (type Soup.Address): a #SoupAddress
942  *
943  * A hash function (for #GHashTable) that corresponds to
944  * soup_address_equal_by_name(), qv
945  *
946  * Return value: the named-based hash value for @addr.
947  *
948  * Since: 2.26
949  **/
950 guint
951 soup_address_hash_by_name (gconstpointer addr)
952 {
953         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
954
955         g_return_val_if_fail (priv->name != NULL, 0);
956         return g_str_hash (priv->name);
957 }
958
959 /**
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
963  *   name
964  *
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".
968  *
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.
972  *
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().
977  *
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.
983  *
984  * See also soup_address_equal_by_ip(), which compares by IP address
985  * rather than by name.
986  *
987  * Return value: whether or not @addr1 and @addr2 have the same name
988  *
989  * Since: 2.26
990  **/
991 gboolean
992 soup_address_equal_by_name (gconstpointer addr1, gconstpointer addr2)
993 {
994         SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
995         SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
996
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);
1000 }
1001
1002 /**
1003  * soup_address_hash_by_ip:
1004  * @addr: (type Soup.Address): a #SoupAddress
1005  *
1006  * A hash function (for #GHashTable) that corresponds to
1007  * soup_address_equal_by_ip(), qv
1008  *
1009  * Return value: the IP-based hash value for @addr.
1010  *
1011  * Since: 2.26
1012  **/
1013 guint
1014 soup_address_hash_by_ip (gconstpointer addr)
1015 {
1016         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
1017         guint hash;
1018
1019         g_return_val_if_fail (priv->sockaddr != NULL, 0);
1020
1021         memcpy (&hash, SOUP_ADDRESS_GET_DATA (priv),
1022                 MIN (sizeof (hash), SOUP_ADDRESS_FAMILY_DATA_SIZE (priv->sockaddr->ss_family)));
1023         return hash;
1024 }
1025
1026 /**
1027  * soup_address_equal_by_ip:
1028  * @addr1: (type Soup.Address): a #SoupAddress with a resolved IP
1029  *   address
1030  * @addr2: (type Soup.Address): another #SoupAddress with a resolved
1031  *   IP address
1032  *
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.
1036  *
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.
1042  *
1043  * See also soup_address_equal_by_name(), which compares by name
1044  * rather than by IP address.
1045  *
1046  * Return value: whether or not @addr1 and @addr2 have the same IP
1047  * address.
1048  *
1049  * Since: 2.26
1050  **/
1051 gboolean
1052 soup_address_equal_by_ip (gconstpointer addr1, gconstpointer addr2)
1053 {
1054         SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
1055         SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
1056         int size;
1057
1058         g_return_val_if_fail (priv1->sockaddr != NULL, FALSE);
1059         g_return_val_if_fail (priv2->sockaddr != NULL, FALSE);
1060
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));
1065 }
1066
1067
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))
1070
1071 typedef struct {
1072         GSocketAddressEnumerator parent_instance;
1073
1074         SoupAddress *addr;
1075         int orig_offset;
1076         int n;
1077 } SoupAddressAddressEnumerator;
1078
1079 typedef struct {
1080         GSocketAddressEnumeratorClass parent_class;
1081
1082 } SoupAddressAddressEnumeratorClass;
1083
1084 GType _soup_address_address_enumerator_get_type (void);
1085 G_DEFINE_TYPE (SoupAddressAddressEnumerator, _soup_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR)
1086
1087 static void
1088 soup_address_address_enumerator_finalize (GObject *object)
1089 {
1090         SoupAddressAddressEnumerator *addr_enum =
1091                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (object);
1092
1093         g_object_unref (addr_enum->addr);
1094
1095         G_OBJECT_CLASS (_soup_address_address_enumerator_parent_class)->finalize (object);
1096 }
1097
1098 static GSocketAddress *
1099 next_address (SoupAddressAddressEnumerator *addr_enum)
1100 {
1101         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1102         struct sockaddr_storage *ss;
1103         int next_addr;
1104
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).
1110          */
1111         next_addr = (addr_enum->orig_offset + addr_enum->n) % priv->n_addrs;
1112         priv->offset = next_addr;
1113
1114         if (addr_enum->n >= priv->n_addrs)
1115                 return NULL;
1116         addr_enum->n++;
1117
1118         ss = &priv->sockaddr[next_addr];
1119         return g_socket_address_new_from_native (ss, SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (ss->ss_family));
1120 }
1121
1122 static GSocketAddress *
1123 soup_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
1124                                       GCancellable              *cancellable,
1125                                       GError                   **error)
1126 {
1127         SoupAddressAddressEnumerator *addr_enum =
1128                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1129         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1130
1131         if (!priv->sockaddr) {
1132                 if (resolve_sync_internal (addr_enum->addr, cancellable, error) != SOUP_STATUS_OK)
1133                         return NULL;
1134         }
1135
1136         return next_address (addr_enum);
1137 }
1138
1139 static void
1140 got_addresses (SoupAddress *addr, guint status, gpointer user_data)
1141 {
1142         GSimpleAsyncResult *simple = user_data;
1143         GError *error;
1144
1145         error = g_object_get_data (G_OBJECT (addr), "async-resolved-error");
1146         if (error)
1147                 g_simple_async_result_set_from_error (simple, error);
1148
1149         g_simple_async_result_complete (simple);
1150         g_object_unref (simple);
1151 }
1152
1153 static void
1154 soup_address_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator,
1155                                             GCancellable              *cancellable,
1156                                             GAsyncReadyCallback        callback,
1157                                             gpointer                   user_data)
1158 {
1159         SoupAddressAddressEnumerator *addr_enum =
1160                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1161         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1162         GSimpleAsyncResult *simple;
1163
1164         simple = g_simple_async_result_new (G_OBJECT (enumerator),
1165                                             callback, user_data,
1166                                             soup_address_address_enumerator_next_async);
1167
1168         if (!priv->sockaddr) {
1169                 soup_address_resolve_async (addr_enum->addr, NULL, cancellable,
1170                                             got_addresses, simple);
1171         } else {
1172                 g_simple_async_result_complete_in_idle (simple);
1173                 g_object_unref (simple);
1174         }
1175 }
1176
1177 static GSocketAddress *
1178 soup_address_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator,
1179                                              GAsyncResult              *result,
1180                                              GError                   **error)
1181 {
1182         SoupAddressAddressEnumerator *addr_enum =
1183                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1184         GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1185
1186         if (g_simple_async_result_propagate_error (simple, error))
1187                 return NULL;
1188         else 
1189                 return next_address (addr_enum);
1190 }
1191
1192 static void
1193 _soup_address_address_enumerator_init (SoupAddressAddressEnumerator *enumerator)
1194 {
1195 }
1196
1197 static void
1198 _soup_address_address_enumerator_class_init (SoupAddressAddressEnumeratorClass *addrenum_class)
1199 {
1200         GObjectClass *object_class = G_OBJECT_CLASS (addrenum_class);
1201         GSocketAddressEnumeratorClass *enumerator_class =
1202                 G_SOCKET_ADDRESS_ENUMERATOR_CLASS (addrenum_class);
1203
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;
1208 }
1209
1210 static GSocketAddressEnumerator *
1211 soup_address_connectable_enumerate (GSocketConnectable *connectable)
1212 {
1213         SoupAddressAddressEnumerator *addr_enum;
1214         SoupAddressPrivate *priv;
1215
1216         addr_enum = g_object_new (SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR, NULL);
1217         addr_enum->addr = g_object_ref (connectable);
1218
1219         priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1220         addr_enum->orig_offset = priv->offset;
1221
1222         return (GSocketAddressEnumerator *)addr_enum;
1223 }
1224
1225 static GSocketAddressEnumerator *
1226 soup_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
1227 {
1228         SoupAddress *addr = SOUP_ADDRESS (connectable);
1229         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
1230         GSocketAddressEnumerator *proxy_enum;
1231         char *uri;
1232
1233         /* We cheerily assume "http" here because you shouldn't be
1234          * using SoupAddress any more if you're not doing HTTP anyway.
1235          */
1236         uri = g_strdup_printf ("%s://%s:%u",
1237                                priv->protocol ? priv->protocol : "http",
1238                                priv->name ? priv->name : soup_address_get_physical (addr),
1239                                priv->port);
1240         proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1241                                    "connectable", connectable,
1242                                    "uri", uri,
1243                                    NULL);
1244         g_free (uri);
1245
1246         return proxy_enum;
1247 }