soup-auth-manager: add soup_auth_manager_use_auth()
[platform/upstream/libsoup.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 <string.h>
13
14 #include "soup-address.h"
15 #include "soup.h"
16 #include "soup-marshal.h"
17
18 /**
19  * SECTION:soup-address
20  * @short_description: DNS support
21  *
22  * #SoupAddress represents the address of a TCP connection endpoint:
23  * both the IP address and the port. (It is somewhat like an
24  * object-oriented version of struct sockaddr.)
25  *
26  * Although #SoupAddress is still used in some libsoup API's, it
27  * should not be used in new code; use GLib's #GNetworkAddress or
28  * #GSocketAddress instead.
29  **/
30
31 enum {
32         PROP_0,
33
34         PROP_NAME,
35         PROP_FAMILY,
36         PROP_PORT,
37         PROP_PROTOCOL,
38         PROP_PHYSICAL,
39         PROP_SOCKADDR,
40
41         LAST_PROP
42 };
43
44 typedef struct {
45         struct sockaddr_storage *sockaddr;
46         int n_addrs, offset;
47
48         char *name, *physical;
49         guint port;
50         const char *protocol;
51
52         GMutex lock;
53         GSList *async_lookups;
54 } SoupAddressPrivate;
55 #define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS, SoupAddressPrivate))
56
57 /* sockaddr generic macros */
58 #define SOUP_SIN(priv) ((struct sockaddr_in *)priv->sockaddr)
59 #define SOUP_SIN6(priv) ((struct sockaddr_in6 *)priv->sockaddr)
60
61 /* sockaddr family macros */
62 #define SOUP_ADDRESS_GET_FAMILY(priv) (priv->sockaddr->ss_family)
63 #define SOUP_ADDRESS_SET_FAMILY(priv, family) \
64         (priv->sockaddr->ss_family = family)
65 #define SOUP_ADDRESS_FAMILY_IS_VALID(family) \
66         (family == AF_INET || family == AF_INET6)
67 #define SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE(family) \
68         (family == AF_INET ? sizeof (struct sockaddr_in) : \
69                              sizeof (struct sockaddr_in6))
70 #define SOUP_ADDRESS_FAMILY_DATA_SIZE(family) \
71         (family == AF_INET ? sizeof (struct in_addr) : \
72                              sizeof (struct in6_addr))
73
74 /* sockaddr port macros */
75 #define SOUP_ADDRESS_PORT_IS_VALID(port) (port >= 0 && port <= 65535)
76 #define SOUP_ADDRESS_GET_PORT(priv) \
77         (priv->sockaddr->ss_family == AF_INET ? \
78                 SOUP_SIN(priv)->sin_port : \
79                 SOUP_SIN6(priv)->sin6_port)
80 #define SOUP_ADDRESS_SET_PORT(priv, port) \
81         G_STMT_START {                                  \
82         if (priv->sockaddr->ss_family == AF_INET)       \
83                 SOUP_SIN(priv)->sin_port = port;        \
84         else                                            \
85                 SOUP_SIN6(priv)->sin6_port = port;      \
86         } G_STMT_END
87
88 /* sockaddr data macros */
89 #define SOUP_ADDRESS_GET_DATA(priv) \
90         (priv->sockaddr->ss_family == AF_INET ? \
91                 (gpointer)&SOUP_SIN(priv)->sin_addr : \
92                 (gpointer)&SOUP_SIN6(priv)->sin6_addr)
93 #define SOUP_ADDRESS_SET_DATA(priv, data, length) \
94         memcpy (SOUP_ADDRESS_GET_DATA (priv), data, length)
95
96
97 static void soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface);
98
99 G_DEFINE_TYPE_WITH_CODE (SoupAddress, soup_address, G_TYPE_OBJECT,
100                          G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE,
101                                                 soup_address_connectable_iface_init))
102
103 static void
104 soup_address_init (SoupAddress *addr)
105 {
106         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
107
108         g_mutex_init (&priv->lock);
109 }
110
111 static void
112 soup_address_finalize (GObject *object)
113 {
114         SoupAddress *addr = SOUP_ADDRESS (object);
115         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
116
117         g_free (priv->sockaddr);
118         g_free (priv->name);
119         g_free (priv->physical);
120
121         g_mutex_clear (&priv->lock);
122
123         G_OBJECT_CLASS (soup_address_parent_class)->finalize (object);
124 }
125
126 static GObject *
127 soup_address_constructor (GType                  type,
128                           guint                  n_construct_properties,
129                           GObjectConstructParam *construct_properties)
130 {
131         GObject *addr;
132         SoupAddressPrivate *priv;
133
134         addr = G_OBJECT_CLASS (soup_address_parent_class)->constructor (
135                 type, n_construct_properties, construct_properties);
136         if (!addr)
137                 return NULL;
138         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
139
140         if (!priv->name && !priv->sockaddr) {
141                 g_object_unref (addr);
142                 return NULL;
143         }
144
145         return addr;
146 }
147
148 static void
149 soup_address_set_property (GObject *object, guint prop_id,
150                            const GValue *value, GParamSpec *pspec)
151 {
152         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
153         SoupAddressFamily family;
154         struct sockaddr *sa;
155         int len, port;
156
157         /* This is a mess because the properties are mostly orthogonal,
158          * but g_object_constructor wants to set a default value for each
159          * of them.
160          */
161
162         switch (prop_id) {
163         case PROP_NAME:
164                 priv->name = g_value_dup_string (value);
165                 break;
166
167         case PROP_FAMILY:
168                 family = g_value_get_enum (value);
169                 if (family == SOUP_ADDRESS_FAMILY_INVALID)
170                         return;
171                 g_return_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (family));
172                 g_return_if_fail (priv->sockaddr == NULL);
173
174                 priv->sockaddr = g_malloc0 (SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (family));
175                 SOUP_ADDRESS_SET_FAMILY (priv, family);
176                 SOUP_ADDRESS_SET_PORT (priv, htons (priv->port));
177                 priv->n_addrs = 1;
178                 break;
179
180         case PROP_PORT:
181                 port = g_value_get_int (value);
182                 if (port == -1)
183                         return;
184                 g_return_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port));
185
186                 priv->port = port;
187                 if (priv->sockaddr)
188                         SOUP_ADDRESS_SET_PORT (priv, htons (port));
189                 break;
190
191         case PROP_PROTOCOL:
192                 priv->protocol = g_intern_string (g_value_get_string (value));
193                 break;
194
195         case PROP_SOCKADDR:
196                 sa = g_value_get_pointer (value);
197                 if (!sa)
198                         return;
199                 g_return_if_fail (priv->sockaddr == NULL);
200
201                 len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (sa->sa_family);
202                 priv->sockaddr = g_memdup (sa, len);
203                 priv->n_addrs = 1;
204                 priv->port = ntohs (SOUP_ADDRESS_GET_PORT (priv));
205                 break;
206         default:
207                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
208                 break;
209         }
210 }
211
212 static void
213 soup_address_get_property (GObject *object, guint prop_id,
214                            GValue *value, GParamSpec *pspec)
215 {
216         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (object);
217
218         switch (prop_id) {
219         case PROP_NAME:
220                 g_value_set_string (value, priv->name);
221                 break;
222         case PROP_FAMILY:
223                 if (priv->sockaddr)
224                         g_value_set_enum (value, SOUP_ADDRESS_GET_FAMILY (priv));
225                 else
226                         g_value_set_enum (value, 0);
227                 break;
228         case PROP_PORT:
229                 g_value_set_int (value, priv->port);
230                 break;
231         case PROP_PHYSICAL:
232                 g_value_set_string (value, soup_address_get_physical (SOUP_ADDRESS (object)));
233                 break;
234         case PROP_PROTOCOL:
235                 g_value_set_string (value, priv->protocol);
236                 break;
237         case PROP_SOCKADDR:
238                 g_value_set_pointer (value, priv->sockaddr);
239                 break;
240         default:
241                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
242                 break;
243         }
244 }
245
246 static void
247 soup_address_class_init (SoupAddressClass *address_class)
248 {
249         GObjectClass *object_class = G_OBJECT_CLASS (address_class);
250
251         g_type_class_add_private (address_class, sizeof (SoupAddressPrivate));
252
253         /* virtual method override */
254         object_class->constructor  = soup_address_constructor;
255         object_class->finalize     = soup_address_finalize;
256         object_class->set_property = soup_address_set_property;
257         object_class->get_property = soup_address_get_property;
258
259         /* properties */
260         /**
261          * SOUP_ADDRESS_NAME:
262          *
263          * Alias for the #SoupAddress:name property. (The hostname for
264          * this address.)
265          **/
266         g_object_class_install_property (
267                 object_class, PROP_NAME,
268                 g_param_spec_string (SOUP_ADDRESS_NAME,
269                                      "Name",
270                                      "Hostname for this address",
271                                      NULL,
272                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
273         /**
274          * SOUP_ADDRESS_FAMILY:
275          *
276          * Alias for the #SoupAddress:family property. (The
277          * #SoupAddressFamily for this address.)
278          **/
279         g_object_class_install_property (
280                 object_class, PROP_FAMILY,
281                 g_param_spec_enum (SOUP_ADDRESS_FAMILY,
282                                    "Family",
283                                    "Address family for this address",
284                                    SOUP_TYPE_ADDRESS_FAMILY,
285                                    SOUP_ADDRESS_FAMILY_INVALID,
286                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
287         /**
288          * SOUP_ADDRESS_PORT:
289          *
290          * An alias for the #SoupAddress:port property. (The port for
291          * this address.)
292          **/
293         g_object_class_install_property (
294                 object_class, PROP_PORT,
295                 g_param_spec_int (SOUP_ADDRESS_PORT,
296                                   "Port",
297                                   "Port for this address",
298                                   -1, 65535, -1,
299                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
300         /**
301          * SOUP_ADDRESS_PROTOCOL:
302          *
303          * Alias for the #SoupAddress:protocol property. (The URI scheme
304          * used with this address.)
305          **/
306         g_object_class_install_property (
307                 object_class, PROP_PROTOCOL,
308                 g_param_spec_string (SOUP_ADDRESS_PROTOCOL,
309                                      "Protocol",
310                                      "URI scheme for this address",
311                                      NULL,
312                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
313         /**
314          * SOUP_ADDRESS_PHYSICAL:
315          *
316          * An alias for the #SoupAddress:physical property. (The
317          * stringified IP address for this address.)
318          **/
319         g_object_class_install_property (
320                 object_class, PROP_PHYSICAL,
321                 g_param_spec_string (SOUP_ADDRESS_PHYSICAL,
322                                      "Physical address",
323                                      "IP address for this address",
324                                      NULL,
325                                      G_PARAM_READABLE));
326         /**
327          * SOUP_ADDRESS_SOCKADDR:
328          *
329          * An alias for the #SoupAddress:sockaddr property. (A pointer
330          * to the struct sockaddr for this address.)
331          **/
332         g_object_class_install_property (
333                 object_class, PROP_SOCKADDR,
334                 g_param_spec_pointer (SOUP_ADDRESS_SOCKADDR,
335                                       "sockaddr",
336                                       "struct sockaddr for this address",
337                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
338 }
339
340 /**
341  * soup_address_new:
342  * @name: a hostname or physical address
343  * @port: a port number
344  *
345  * Creates a #SoupAddress from @name and @port. The #SoupAddress's IP
346  * address may not be available right away; the caller can call
347  * soup_address_resolve_async() or soup_address_resolve_sync() to
348  * force a DNS resolution.
349  *
350  * Return value: a #SoupAddress
351  **/
352 SoupAddress *
353 soup_address_new (const char *name, guint port)
354 {
355         g_return_val_if_fail (name != NULL, NULL);
356         g_return_val_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port), NULL);
357
358         return g_object_new (SOUP_TYPE_ADDRESS,
359                              SOUP_ADDRESS_NAME, name,
360                              SOUP_ADDRESS_PORT, port,
361                              NULL);
362 }
363
364 /**
365  * soup_address_new_from_sockaddr:
366  * @sa: a pointer to a sockaddr
367  * @len: size of @sa
368  *
369  * Returns a #SoupAddress equivalent to @sa (or %NULL if @sa's
370  * address family isn't supported)
371  *
372  * Return value: (allow-none): the new #SoupAddress
373  **/
374 SoupAddress *
375 soup_address_new_from_sockaddr (struct sockaddr *sa, int len)
376 {
377         g_return_val_if_fail (sa != NULL, NULL);
378         g_return_val_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (sa->sa_family), NULL);
379         g_return_val_if_fail (len == SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (sa->sa_family), NULL);
380
381         return g_object_new (SOUP_TYPE_ADDRESS,
382                              SOUP_ADDRESS_SOCKADDR, sa,
383                              NULL);
384 }
385
386 /**
387  * SoupAddressFamily:
388  * @SOUP_ADDRESS_FAMILY_INVALID: an invalid %SoupAddress
389  * @SOUP_ADDRESS_FAMILY_IPV4: an IPv4 address
390  * @SOUP_ADDRESS_FAMILY_IPV6: an IPv6 address
391  *
392  * The supported address families.
393  **/
394
395 /**
396  * SOUP_ADDRESS_ANY_PORT:
397  *
398  * This can be passed to any #SoupAddress method that expects a port,
399  * to indicate that you don't care what port is used.
400  **/
401
402 /**
403  * soup_address_new_any:
404  * @family: the address family
405  * @port: the port number (usually %SOUP_ADDRESS_ANY_PORT)
406  *
407  * Returns a #SoupAddress corresponding to the "any" address
408  * for @family (or %NULL if @family isn't supported), suitable for
409  * using as a listening #SoupSocket.
410  *
411  * Return value: (allow-none): the new #SoupAddress
412  **/
413 SoupAddress *
414 soup_address_new_any (SoupAddressFamily family, guint port)
415 {
416         g_return_val_if_fail (SOUP_ADDRESS_FAMILY_IS_VALID (family), NULL);
417         g_return_val_if_fail (SOUP_ADDRESS_PORT_IS_VALID (port), NULL);
418
419         return g_object_new (SOUP_TYPE_ADDRESS,
420                              SOUP_ADDRESS_FAMILY, family,
421                              SOUP_ADDRESS_PORT, port,
422                              NULL);
423 }
424
425 /**
426  * soup_address_get_name:
427  * @addr: a #SoupAddress
428  *
429  * Returns the hostname associated with @addr.
430  *
431  * This method is not thread-safe; if you call it while @addr is being
432  * resolved in another thread, it may return garbage. You can use
433  * soup_address_is_resolved() to safely test whether or not an address
434  * is resolved before fetching its name or address.
435  *
436  * Return value: (allow-none): the hostname, or %NULL if it is not known.
437  **/
438 const char *
439 soup_address_get_name (SoupAddress *addr)
440 {
441         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
442
443         return SOUP_ADDRESS_GET_PRIVATE (addr)->name;
444 }
445
446 /**
447  * soup_address_get_sockaddr:
448  * @addr: a #SoupAddress
449  * @len: return location for sockaddr length
450  *
451  * Returns the sockaddr associated with @addr, with its length in
452  * *@len. If the sockaddr is not yet known, returns %NULL.
453  *
454  * This method is not thread-safe; if you call it while @addr is being
455  * resolved in another thread, it may return garbage. You can use
456  * soup_address_is_resolved() to safely test whether or not an address
457  * is resolved before fetching its name or address.
458  *
459  * Return value: (allow-none) (transfer none): the sockaddr, or %NULL
460  **/
461 struct sockaddr *
462 soup_address_get_sockaddr (SoupAddress *addr, int *len)
463 {
464         SoupAddressPrivate *priv;
465
466         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
467         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
468
469         if (priv->sockaddr && len)
470                 *len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv));
471         return (struct sockaddr *)priv->sockaddr;
472 }
473
474 /**
475  * soup_address_get_gsockaddr:
476  * @addr: a #SoupAddress
477  *
478  * Creates a new #GSocketAddress corresponding to @addr (which is assumed
479  * to only have one socket address associated with it).
480  *
481  * Return value: (transfer full): a new #GSocketAddress
482  *
483  * Since: 2.32
484  */
485 GSocketAddress *
486 soup_address_get_gsockaddr (SoupAddress *addr)
487 {
488         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
489
490         return g_socket_address_new_from_native (priv->sockaddr,
491                                                  SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
492 }
493
494 static GInetAddress *
495 soup_address_make_inet_address (SoupAddress *addr)
496 {
497         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
498         GSocketAddress *gsa;
499         GInetAddress *gia;
500
501         gsa = g_socket_address_new_from_native (priv->sockaddr,
502                                                 SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
503         gia = g_inet_socket_address_get_address ((GInetSocketAddress *)gsa);
504         g_object_ref (gia);
505         g_object_unref (gsa);
506         return gia;
507 }
508
509 /**
510  * soup_address_get_physical:
511  * @addr: a #SoupAddress
512  *
513  * Returns the physical address associated with @addr as a string.
514  * (Eg, "127.0.0.1"). If the address is not yet known, returns %NULL.
515  *
516  * This method is not thread-safe; if you call it while @addr is being
517  * resolved in another thread, it may return garbage. You can use
518  * soup_address_is_resolved() to safely test whether or not an address
519  * is resolved before fetching its name or address.
520  *
521  * Return value: (allow-none): the physical address, or %NULL
522  **/
523 const char *
524 soup_address_get_physical (SoupAddress *addr)
525 {
526         SoupAddressPrivate *priv;
527
528         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), NULL);
529         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
530
531         if (!priv->sockaddr)
532                 return NULL;
533
534         if (!priv->physical) {
535                 GInetAddress *gia;
536
537                 gia = soup_address_make_inet_address (addr);
538                 priv->physical = g_inet_address_to_string (gia);
539                 g_object_unref (gia);
540         }
541
542         return priv->physical;
543 }
544
545 /**
546  * soup_address_get_port:
547  * @addr: a #SoupAddress
548  *
549  * Returns the port associated with @addr.
550  *
551  * Return value: the port
552  **/
553 guint
554 soup_address_get_port (SoupAddress *addr)
555 {
556         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), 0);
557
558         return SOUP_ADDRESS_GET_PRIVATE (addr)->port;
559 }
560
561
562 static guint
563 update_addrs (SoupAddress *addr, GList *addrs, GError *error)
564 {
565         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
566         GInetAddress *gia;
567         GSocketAddress *gsa;
568         int i;
569
570         if (error) {
571                 if (error->domain == G_IO_ERROR &&
572                     error->code == G_IO_ERROR_CANCELLED)
573                         return SOUP_STATUS_CANCELLED;
574                 else
575                         return SOUP_STATUS_CANT_RESOLVE;
576         } else if (!addrs)
577                 return SOUP_STATUS_CANT_RESOLVE;
578         else if (priv->sockaddr)
579                 return SOUP_STATUS_OK;
580
581         priv->n_addrs = g_list_length (addrs);
582         priv->sockaddr = g_new (struct sockaddr_storage, priv->n_addrs);
583         for (i = 0; addrs; addrs = addrs->next, i++) {
584                 gia = addrs->data;
585                 gsa = g_inet_socket_address_new (gia, priv->port);
586
587                 if (!g_socket_address_to_native (gsa, &priv->sockaddr[i],
588                                                  sizeof (struct sockaddr_storage),
589                                                  NULL)) {
590                         /* can't happen: We know the address format is supported
591                          * and the buffer is large enough
592                          */
593                         g_warn_if_reached ();
594                 }
595                 g_object_unref (gsa);
596         }
597
598         return SOUP_STATUS_OK;
599 }
600
601 static guint
602 update_name (SoupAddress *addr, const char *name, GError *error)
603 {
604         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
605
606         if (error) {
607                 if (error->domain == G_IO_ERROR &&
608                     error->code == G_IO_ERROR_CANCELLED)
609                         return SOUP_STATUS_CANCELLED;
610                 else
611                         return SOUP_STATUS_CANT_RESOLVE;
612         } else if (!name)
613                 return SOUP_STATUS_CANT_RESOLVE;
614         else if (priv->name)
615                 return SOUP_STATUS_OK;
616
617         priv->name = g_strdup (name);
618         return SOUP_STATUS_OK;
619 }
620
621 typedef struct {
622         SoupAddressCallback  callback;
623         gpointer             callback_data;
624 } SoupAddressResolveAsyncData;
625
626 static void
627 complete_resolve_async (SoupAddress *addr, guint status)
628 {
629         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
630         SoupAddressResolveAsyncData *res_data;
631         GSList *lookups, *l;
632         GSource *current_source;
633         GMainContext *current_context;
634
635         lookups = priv->async_lookups;
636         priv->async_lookups = NULL;
637
638         /* Awful hack; to make soup_socket_connect_async() with an
639          * non-default async_context work correctly, we need to ensure
640          * that the non-default context (which we're now running in)
641          * is the thread-default when the callbacks are run...
642          */
643         current_source = g_main_current_source ();
644         if (current_source && !g_source_is_destroyed (current_source))
645                 current_context = g_source_get_context (current_source);
646         else
647                 current_context = NULL;
648         g_main_context_push_thread_default (current_context);
649
650         for (l = lookups; l; l = l->next) {
651                 res_data = l->data;
652
653                 if (res_data->callback) {
654                         res_data->callback (addr, status,
655                                             res_data->callback_data);
656                 }
657                 g_slice_free (SoupAddressResolveAsyncData, res_data);
658         }
659         g_slist_free (lookups);
660
661         g_main_context_pop_thread_default (current_context);
662
663         g_object_unref (addr);
664 }
665
666 static void
667 lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
668 {
669         GResolver *resolver = G_RESOLVER (source);
670         SoupAddress *addr = user_data;
671         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
672         GError *error = NULL;
673         guint status;
674
675         if (!priv->sockaddr) {
676                 GList *addrs;
677
678                 addrs = g_resolver_lookup_by_name_finish (resolver, result,
679                                                           &error);
680                 status = update_addrs (addr, addrs, error);
681                 g_resolver_free_addresses (addrs);
682         } else if (!priv->name) {
683                 char *name;
684
685                 name = g_resolver_lookup_by_address_finish (resolver, result,
686                                                             &error);
687                 status = update_name (addr, name, error);
688                 g_free (name);
689         } else
690                 status = SOUP_STATUS_OK;
691
692         /* For the enumerator impl, below */
693         g_object_ref (addr);
694         g_object_set_data (G_OBJECT (addr), "async-resolved-error", error);
695
696         complete_resolve_async (addr, status);
697
698         g_object_set_data (G_OBJECT (addr), "async-resolved-error", NULL);
699         g_object_unref (addr);
700         if (error)
701                 g_error_free (error);
702 }
703
704 static gboolean
705 idle_complete_resolve (gpointer addr)
706 {
707         complete_resolve_async (addr, SOUP_STATUS_OK);
708         return FALSE;
709 }
710
711 /**
712  * SoupAddressCallback:
713  * @addr: the #SoupAddress that was resolved
714  * @status: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or
715  * %SOUP_STATUS_CANCELLED
716  * @user_data: the user data that was passed to
717  * soup_address_resolve_async()
718  *
719  * The callback function passed to soup_address_resolve_async().
720  **/
721
722 /**
723  * soup_address_resolve_async:
724  * @addr: a #SoupAddress
725  * @async_context: (allow-none): the #GMainContext to call @callback from
726  * @cancellable: a #GCancellable object, or %NULL
727  * @callback: (scope async): callback to call with the result
728  * @user_data: data for @callback
729  *
730  * Asynchronously resolves the missing half of @addr (its IP address
731  * if it was created with soup_address_new(), or its hostname if it
732  * was created with soup_address_new_from_sockaddr() or
733  * soup_address_new_any().)
734  *
735  * If @cancellable is non-%NULL, it can be used to cancel the
736  * resolution. @callback will still be invoked in this case, with a
737  * status of %SOUP_STATUS_CANCELLED.
738  *
739  * It is safe to call this more than once on a given address, from the
740  * same thread, with the same @async_context (and doing so will not
741  * result in redundant DNS queries being made). But it is not safe to
742  * call from multiple threads, or with different @async_contexts, or
743  * mixed with calls to soup_address_resolve_sync().
744  **/
745 void
746 soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
747                             GCancellable *cancellable,
748                             SoupAddressCallback callback, gpointer user_data)
749 {
750         SoupAddressPrivate *priv;
751         SoupAddressResolveAsyncData *res_data;
752         GResolver *resolver;
753         gboolean already_started;
754
755         g_return_if_fail (SOUP_IS_ADDRESS (addr));
756         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
757         g_return_if_fail (priv->name || priv->sockaddr);
758
759         /* We don't need to do locking here because the async case is
760          * not intended to be thread-safe.
761          */
762
763         if (priv->name && priv->sockaddr && !callback)
764                 return;
765
766         res_data = g_slice_new0 (SoupAddressResolveAsyncData);
767         res_data->callback = callback;
768         res_data->callback_data = user_data;
769
770         already_started = priv->async_lookups != NULL;
771         priv->async_lookups = g_slist_prepend (priv->async_lookups, res_data);
772
773         if (already_started)
774                 return;
775
776         g_object_ref (addr);
777
778         if (priv->name && priv->sockaddr) {
779                 soup_add_completion (async_context, idle_complete_resolve, addr);
780                 return;
781         }
782
783         resolver = g_resolver_get_default ();
784         if (async_context)
785                 g_main_context_push_thread_default (async_context);
786
787         if (priv->name) {
788                 g_resolver_lookup_by_name_async (resolver, priv->name,
789                                                  cancellable,
790                                                  lookup_resolved, addr);
791         } else {
792                 GInetAddress *gia;
793
794                 gia = soup_address_make_inet_address (addr);
795                 g_resolver_lookup_by_address_async (resolver, gia,
796                                                     cancellable,
797                                                     lookup_resolved, addr);
798                 g_object_unref (gia);
799         }
800
801         if (async_context)
802                 g_main_context_pop_thread_default (async_context);
803         g_object_unref (resolver);
804 }
805
806 static guint
807 resolve_sync_internal (SoupAddress *addr, GCancellable *cancellable, GError **error)
808 {
809         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
810         GResolver *resolver;
811         guint status;
812         GError *my_err = NULL;
813
814         resolver = g_resolver_get_default ();
815
816         /* We could optimize this to avoid multiple lookups the same
817          * way _resolve_async does, but we don't currently. So, first
818          * lock the mutex to ensure we have a consistent view of
819          * priv->sockaddr and priv->name, unlock it around the
820          * blocking op, and then re-lock it to modify @addr.
821          */
822         g_mutex_lock (&priv->lock);
823         if (!priv->sockaddr) {
824                 GList *addrs;
825
826                 g_mutex_unlock (&priv->lock);
827                 addrs = g_resolver_lookup_by_name (resolver, priv->name,
828                                                    cancellable, &my_err);
829                 g_mutex_lock (&priv->lock);
830
831                 status = update_addrs (addr, addrs, my_err);
832                 g_resolver_free_addresses (addrs);
833         } else if (!priv->name) {
834                 GInetAddress *gia;
835                 char *name;
836
837                 g_mutex_unlock (&priv->lock);
838                 gia = soup_address_make_inet_address (addr);
839                 name = g_resolver_lookup_by_address (resolver, gia,
840                                                      cancellable, &my_err);
841                 g_object_unref (gia);
842                 g_mutex_lock (&priv->lock);
843
844                 status = update_name (addr, name, my_err);
845                 g_free (name);
846         } else
847                 status = SOUP_STATUS_OK;
848         g_mutex_unlock (&priv->lock);
849
850         if (my_err)
851                 g_propagate_error (error, my_err);
852         g_object_unref (resolver);
853
854         return status;
855 }
856
857 /**
858  * soup_address_resolve_sync:
859  * @addr: a #SoupAddress
860  * @cancellable: a #GCancellable object, or %NULL
861  *
862  * Synchronously resolves the missing half of @addr, as with
863  * soup_address_resolve_async().
864  *
865  * If @cancellable is non-%NULL, it can be used to cancel the
866  * resolution. soup_address_resolve_sync() will then return a status
867  * of %SOUP_STATUS_CANCELLED.
868  *
869  * It is safe to call this more than once, even from different
870  * threads, but it is not safe to mix calls to
871  * soup_address_resolve_sync() with calls to
872  * soup_address_resolve_async() on the same address.
873  *
874  * Return value: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or
875  * %SOUP_STATUS_CANCELLED.
876  **/
877 guint
878 soup_address_resolve_sync (SoupAddress *addr, GCancellable *cancellable)
879 {
880         SoupAddressPrivate *priv;
881
882         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), SOUP_STATUS_MALFORMED);
883         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
884         g_return_val_if_fail (priv->name || priv->sockaddr, SOUP_STATUS_MALFORMED);
885
886         return resolve_sync_internal (addr, cancellable, NULL);
887 }
888
889 /**
890  * soup_address_is_resolved:
891  * @addr: a #SoupAddress
892  *
893  * Tests if @addr has already been resolved. Unlike the other
894  * #SoupAddress "get" methods, this is safe to call when @addr might
895  * be being resolved in another thread.
896  *
897  * Return value: %TRUE if @addr has been resolved.
898  **/
899 gboolean
900 soup_address_is_resolved (SoupAddress *addr)
901 {
902         SoupAddressPrivate *priv;
903         gboolean resolved;
904
905         g_return_val_if_fail (SOUP_IS_ADDRESS (addr), FALSE);
906         priv = SOUP_ADDRESS_GET_PRIVATE (addr);
907
908         g_mutex_lock (&priv->lock);
909         resolved = priv->sockaddr && priv->name;
910         g_mutex_unlock (&priv->lock);
911
912         return resolved;
913 }
914
915 /**
916  * soup_address_hash_by_name:
917  * @addr: (type Soup.Address): a #SoupAddress
918  *
919  * A hash function (for #GHashTable) that corresponds to
920  * soup_address_equal_by_name(), qv
921  *
922  * Return value: the named-based hash value for @addr.
923  *
924  * Since: 2.26
925  **/
926 guint
927 soup_address_hash_by_name (gconstpointer addr)
928 {
929         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
930
931         g_return_val_if_fail (priv->name != NULL, 0);
932         return g_str_hash (priv->name);
933 }
934
935 /**
936  * soup_address_equal_by_name:
937  * @addr1: (type Soup.Address): a #SoupAddress with a resolved name
938  * @addr2: (type Soup.Address): another #SoupAddress with a resolved
939  *   name
940  *
941  * Tests if @addr1 and @addr2 have the same "name". This method can be
942  * used with soup_address_hash_by_name() to create a #GHashTable that
943  * hashes on address "names".
944  *
945  * Comparing by name normally means comparing the addresses by their
946  * hostnames. But if the address was originally created using an IP
947  * address literal, then it will be compared by that instead.
948  *
949  * In particular, if "www.example.com" has the IP address 10.0.0.1,
950  * and @addr1 was created with the name "www.example.com" and @addr2
951  * was created with the name "10.0.0.1", then they will compare as
952  * unequal for purposes of soup_address_equal_by_name().
953  *
954  * This would be used to distinguish hosts in situations where
955  * different virtual hosts on the same IP address should be considered
956  * different. Eg, for purposes of HTTP authentication or cookies, two
957  * hosts with the same IP address but different names are considered
958  * to be different hosts.
959  *
960  * See also soup_address_equal_by_ip(), which compares by IP address
961  * rather than by name.
962  *
963  * Return value: whether or not @addr1 and @addr2 have the same name
964  *
965  * Since: 2.26
966  **/
967 gboolean
968 soup_address_equal_by_name (gconstpointer addr1, gconstpointer addr2)
969 {
970         SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
971         SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
972
973         g_return_val_if_fail (priv1->name != NULL, FALSE);
974         g_return_val_if_fail (priv2->name != NULL, FALSE);
975         return !g_ascii_strcasecmp (priv1->name, priv2->name);
976 }
977
978 /**
979  * soup_address_hash_by_ip:
980  * @addr: (type Soup.Address): a #SoupAddress
981  *
982  * A hash function (for #GHashTable) that corresponds to
983  * soup_address_equal_by_ip(), qv
984  *
985  * Return value: the IP-based hash value for @addr.
986  *
987  * Since: 2.26
988  **/
989 guint
990 soup_address_hash_by_ip (gconstpointer addr)
991 {
992         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
993         guint hash;
994
995         g_return_val_if_fail (priv->sockaddr != NULL, 0);
996
997         memcpy (&hash, SOUP_ADDRESS_GET_DATA (priv),
998                 MIN (sizeof (hash), SOUP_ADDRESS_FAMILY_DATA_SIZE (priv->sockaddr->ss_family)));
999         return hash;
1000 }
1001
1002 /**
1003  * soup_address_equal_by_ip:
1004  * @addr1: (type Soup.Address): a #SoupAddress with a resolved IP
1005  *   address
1006  * @addr2: (type Soup.Address): another #SoupAddress with a resolved
1007  *   IP address
1008  *
1009  * Tests if @addr1 and @addr2 have the same IP address. This method
1010  * can be used with soup_address_hash_by_ip() to create a
1011  * #GHashTable that hashes on IP address.
1012  *
1013  * This would be used to distinguish hosts in situations where
1014  * different virtual hosts on the same IP address should be considered
1015  * the same. Eg, if "www.example.com" and "www.example.net" have the
1016  * same IP address, then a single connection can be used to talk
1017  * to either of them.
1018  *
1019  * See also soup_address_equal_by_name(), which compares by name
1020  * rather than by IP address.
1021  *
1022  * Return value: whether or not @addr1 and @addr2 have the same IP
1023  * address.
1024  *
1025  * Since: 2.26
1026  **/
1027 gboolean
1028 soup_address_equal_by_ip (gconstpointer addr1, gconstpointer addr2)
1029 {
1030         SoupAddressPrivate *priv1 = SOUP_ADDRESS_GET_PRIVATE (addr1);
1031         SoupAddressPrivate *priv2 = SOUP_ADDRESS_GET_PRIVATE (addr2);
1032         int size;
1033
1034         g_return_val_if_fail (priv1->sockaddr != NULL, FALSE);
1035         g_return_val_if_fail (priv2->sockaddr != NULL, FALSE);
1036
1037         size = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (priv1->sockaddr->ss_family);
1038         return (priv1->sockaddr->ss_family ==
1039                 priv2->sockaddr->ss_family &&
1040                 !memcmp (priv1->sockaddr, priv2->sockaddr, size));
1041 }
1042
1043
1044 #define SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR (_soup_address_address_enumerator_get_type ())
1045 #define SOUP_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR, SoupAddressAddressEnumerator))
1046
1047 typedef struct {
1048         GSocketAddressEnumerator parent_instance;
1049
1050         SoupAddress *addr;
1051         int orig_offset;
1052         int n;
1053 } SoupAddressAddressEnumerator;
1054
1055 typedef struct {
1056         GSocketAddressEnumeratorClass parent_class;
1057
1058 } SoupAddressAddressEnumeratorClass;
1059
1060 GType _soup_address_address_enumerator_get_type (void);
1061 G_DEFINE_TYPE (SoupAddressAddressEnumerator, _soup_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR)
1062
1063 static void
1064 soup_address_address_enumerator_finalize (GObject *object)
1065 {
1066         SoupAddressAddressEnumerator *addr_enum =
1067                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (object);
1068
1069         g_object_unref (addr_enum->addr);
1070
1071         G_OBJECT_CLASS (_soup_address_address_enumerator_parent_class)->finalize (object);
1072 }
1073
1074 static GSocketAddress *
1075 next_address (SoupAddressAddressEnumerator *addr_enum)
1076 {
1077         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1078         struct sockaddr_storage *ss;
1079         int next_addr;
1080
1081         /* If there are two addresses but the first one is unusable
1082          * (eg, it's IPv6 and we can only do IPv4), then we don't want to
1083          * try the bad one every time. So we use priv->offset to remember
1084          * the offset of the first usable address (ie, the first address
1085          * that we weren't called again after returning).
1086          */
1087         next_addr = (addr_enum->orig_offset + addr_enum->n) % priv->n_addrs;
1088         priv->offset = next_addr;
1089
1090         if (addr_enum->n >= priv->n_addrs)
1091                 return NULL;
1092         addr_enum->n++;
1093
1094         ss = &priv->sockaddr[next_addr];
1095         return g_socket_address_new_from_native (ss, SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (ss->ss_family));
1096 }
1097
1098 static GSocketAddress *
1099 soup_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
1100                                       GCancellable              *cancellable,
1101                                       GError                   **error)
1102 {
1103         SoupAddressAddressEnumerator *addr_enum =
1104                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1105         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1106
1107         if (!priv->sockaddr) {
1108                 if (resolve_sync_internal (addr_enum->addr, cancellable, error) != SOUP_STATUS_OK)
1109                         return NULL;
1110         }
1111
1112         return next_address (addr_enum);
1113 }
1114
1115 static void
1116 got_addresses (SoupAddress *addr, guint status, gpointer user_data)
1117 {
1118         GTask *task = user_data;
1119         GError *error;
1120
1121         error = g_object_get_data (G_OBJECT (addr), "async-resolved-error");
1122         if (error)
1123                 g_task_return_error (task, g_error_copy (error));
1124         else {
1125                 GSocketAddress *addr;
1126
1127                 addr = next_address (g_task_get_source_object (task));
1128                 g_task_return_pointer (task, addr, g_object_unref);
1129         }
1130         g_object_unref (task);
1131 }
1132
1133 static void
1134 soup_address_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator,
1135                                             GCancellable              *cancellable,
1136                                             GAsyncReadyCallback        callback,
1137                                             gpointer                   user_data)
1138 {
1139         SoupAddressAddressEnumerator *addr_enum =
1140                 SOUP_ADDRESS_ADDRESS_ENUMERATOR (enumerator);
1141         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1142         GTask *task;
1143
1144         task = g_task_new (enumerator, cancellable, callback, user_data);
1145         if (!priv->sockaddr) {
1146                 soup_address_resolve_async (addr_enum->addr, NULL, cancellable,
1147                                             got_addresses, task);
1148         } else {
1149                 g_task_return_pointer (task, next_address (addr_enum), g_object_unref);
1150                 g_object_unref (task);
1151         }
1152 }
1153
1154 static GSocketAddress *
1155 soup_address_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator,
1156                                              GAsyncResult              *result,
1157                                              GError                   **error)
1158 {
1159         return g_task_propagate_pointer (G_TASK (result), error);
1160 }
1161
1162 static void
1163 _soup_address_address_enumerator_init (SoupAddressAddressEnumerator *enumerator)
1164 {
1165 }
1166
1167 static void
1168 _soup_address_address_enumerator_class_init (SoupAddressAddressEnumeratorClass *addrenum_class)
1169 {
1170         GObjectClass *object_class = G_OBJECT_CLASS (addrenum_class);
1171         GSocketAddressEnumeratorClass *enumerator_class =
1172                 G_SOCKET_ADDRESS_ENUMERATOR_CLASS (addrenum_class);
1173
1174         enumerator_class->next = soup_address_address_enumerator_next;
1175         enumerator_class->next_async = soup_address_address_enumerator_next_async;
1176         enumerator_class->next_finish = soup_address_address_enumerator_next_finish;
1177         object_class->finalize = soup_address_address_enumerator_finalize;
1178 }
1179
1180 static GSocketAddressEnumerator *
1181 soup_address_connectable_enumerate (GSocketConnectable *connectable)
1182 {
1183         SoupAddressAddressEnumerator *addr_enum;
1184         SoupAddressPrivate *priv;
1185
1186         addr_enum = g_object_new (SOUP_TYPE_ADDRESS_ADDRESS_ENUMERATOR, NULL);
1187         addr_enum->addr = g_object_ref (connectable);
1188
1189         priv = SOUP_ADDRESS_GET_PRIVATE (addr_enum->addr);
1190         addr_enum->orig_offset = priv->offset;
1191
1192         return (GSocketAddressEnumerator *)addr_enum;
1193 }
1194
1195 static GSocketAddressEnumerator *
1196 soup_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
1197 {
1198         SoupAddress *addr = SOUP_ADDRESS (connectable);
1199         SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
1200         GSocketAddressEnumerator *proxy_enum;
1201         SoupURI *uri;
1202         char *uri_string;
1203
1204         /* We cheerily assume "http" here because you shouldn't be
1205          * using SoupAddress any more if you're not doing HTTP anyway.
1206          */
1207         uri = soup_uri_new (NULL);
1208         soup_uri_set_scheme (uri, priv->protocol ? priv->protocol : "http");
1209         soup_uri_set_host (uri, priv->name ? priv->name : soup_address_get_physical (addr));
1210         soup_uri_set_port (uri, priv->port);
1211         soup_uri_set_path (uri, "");
1212         uri_string = soup_uri_to_string (uri, FALSE);
1213
1214         proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1215                                    "connectable", connectable,
1216                                    "uri", uri_string,
1217                                    NULL);
1218         g_free (uri_string);
1219         soup_uri_free (uri);
1220
1221         return proxy_enum;
1222 }
1223
1224 static void
1225 soup_address_connectable_iface_init (GSocketConnectableIface *connectable_iface)
1226 {
1227   connectable_iface->enumerate       = soup_address_connectable_enumerate;
1228   connectable_iface->proxy_enumerate = soup_address_connectable_proxy_enumerate;
1229 }