Implemented proxy_enumerate() for all Connectables
[platform/upstream/glib.git] / gio / gnetworkservice.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* GIO - GLib Input, Output and Streaming Library
4  *
5  * Copyright (C) 2008 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "config.h"
24 #include <glib.h>
25 #include "glibintl.h"
26
27 #include "gnetworkservice.h"
28
29 #include "gcancellable.h"
30 #include "ginetaddress.h"
31 #include "ginetsocketaddress.h"
32 #include "gioerror.h"
33 #include "gnetworkaddress.h"
34 #include "gresolver.h"
35 #include "gsimpleasyncresult.h"
36 #include "gsocketaddressenumerator.h"
37 #include "gsocketconnectable.h"
38 #include "gsrvtarget.h"
39
40 #include <stdlib.h>
41 #include <string.h>
42
43
44 /**
45  * SECTION:gnetworkservice
46  * @short_description: A GSocketConnectable for resolving SRV records
47  * @include: gio/gio.h
48  *
49  * Like #GNetworkAddress does with hostnames, #GNetworkService
50  * provides an easy way to resolve a SRV record, and then attempt to
51  * connect to one of the hosts that implements that service, handling
52  * service priority/weighting, multiple IP addresses, and multiple
53  * address families.
54  *
55  * See #GSrvTarget for more information about SRV records, and see
56  * #GSocketConnectable for and example of using the connectable
57  * interface.
58  */
59
60 /**
61  * GNetworkService:
62  *
63  * A #GSocketConnectable for resolving a SRV record and connecting to
64  * that service.
65  */
66
67 struct _GNetworkServicePrivate
68 {
69   gchar *service, *protocol, *domain, *scheme;
70   GList *targets;
71 };
72
73 enum {
74   PROP_0,
75   PROP_SERVICE,
76   PROP_PROTOCOL,
77   PROP_DOMAIN,
78   PROP_SCHEME
79 };
80
81 static void g_network_service_set_property (GObject      *object,
82                                             guint         prop_id,
83                                             const GValue *value,
84                                             GParamSpec   *pspec);
85 static void g_network_service_get_property (GObject      *object,
86                                             guint         prop_id,
87                                             GValue       *value,
88                                             GParamSpec   *pspec);
89
90 static void                      g_network_service_connectable_iface_init       (GSocketConnectableIface *iface);
91 static GSocketAddressEnumerator *g_network_service_connectable_enumerate        (GSocketConnectable      *connectable);
92 static GSocketAddressEnumerator *g_network_service_connectable_proxy_enumerate  (GSocketConnectable      *connectable);
93
94 G_DEFINE_TYPE_WITH_CODE (GNetworkService, g_network_service, G_TYPE_OBJECT,
95                          G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE,
96                                                 g_network_service_connectable_iface_init))
97
98 static void
99 g_network_service_finalize (GObject *object)
100 {
101   GNetworkService *srv = G_NETWORK_SERVICE (object);
102
103   g_free (srv->priv->service);
104   g_free (srv->priv->protocol);
105   g_free (srv->priv->domain);
106   g_free (srv->priv->scheme);
107
108   if (srv->priv->targets)
109     g_resolver_free_targets (srv->priv->targets);
110
111   G_OBJECT_CLASS (g_network_service_parent_class)->finalize (object);
112 }
113
114 static void
115 g_network_service_class_init (GNetworkServiceClass *klass)
116 {
117   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
118
119   g_type_class_add_private (klass, sizeof (GNetworkServicePrivate));
120
121   gobject_class->set_property = g_network_service_set_property;
122   gobject_class->get_property = g_network_service_get_property;
123   gobject_class->finalize = g_network_service_finalize;
124
125   g_object_class_install_property (gobject_class, PROP_SERVICE,
126                                    g_param_spec_string ("service",
127                                                         P_("Service"),
128                                                         P_("Service name, eg \"ldap\""),
129                                                         NULL,
130                                                         G_PARAM_READWRITE |
131                                                         G_PARAM_CONSTRUCT_ONLY |
132                                                         G_PARAM_STATIC_STRINGS));
133   g_object_class_install_property (gobject_class, PROP_PROTOCOL,
134                                    g_param_spec_string ("protocol",
135                                                         P_("Protocol"),
136                                                         P_("Network protocol, eg \"tcp\""),
137                                                         NULL,
138                                                         G_PARAM_READWRITE |
139                                                         G_PARAM_CONSTRUCT_ONLY |
140                                                         G_PARAM_STATIC_STRINGS));
141   g_object_class_install_property (gobject_class, PROP_DOMAIN,
142                                    g_param_spec_string ("domain",
143                                                         P_("Domain"),
144                                                         P_("Network domain, eg, \"example.com\""),
145                                                         NULL,
146                                                         G_PARAM_READWRITE |
147                                                         G_PARAM_CONSTRUCT_ONLY |
148                                                         G_PARAM_STATIC_STRINGS));
149   g_object_class_install_property (gobject_class, PROP_DOMAIN,
150                                    g_param_spec_string ("scheme",
151                                                         P_("Scheme"),
152                                                         P_("Network scheme (default is to use service)"),
153                                                         NULL,
154                                                         G_PARAM_READWRITE |
155                                                         G_PARAM_STATIC_STRINGS));
156
157 }
158
159 static void
160 g_network_service_connectable_iface_init (GSocketConnectableIface *connectable_iface)
161 {
162   connectable_iface->enumerate = g_network_service_connectable_enumerate;
163   connectable_iface->proxy_enumerate = g_network_service_connectable_proxy_enumerate;
164 }
165
166 static void
167 g_network_service_init (GNetworkService *srv)
168 {
169   srv->priv = G_TYPE_INSTANCE_GET_PRIVATE (srv, G_TYPE_NETWORK_SERVICE,
170                                            GNetworkServicePrivate);
171 }
172
173 static void
174 g_network_service_set_property (GObject      *object,
175                                 guint         prop_id,
176                                 const GValue *value,
177                                 GParamSpec   *pspec)
178 {
179   GNetworkService *srv = G_NETWORK_SERVICE (object);
180
181   switch (prop_id)
182     {
183     case PROP_SERVICE:
184       srv->priv->service = g_value_dup_string (value);
185       break;
186
187     case PROP_PROTOCOL:
188       srv->priv->protocol = g_value_dup_string (value);
189       break;
190
191     case PROP_DOMAIN:
192       srv->priv->domain = g_value_dup_string (value);
193       break;
194
195     case PROP_SCHEME:
196       g_network_service_set_scheme (srv, g_value_get_string (value));
197       break;
198
199     default:
200       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
201       break;
202     }
203 }
204
205 static void
206 g_network_service_get_property (GObject    *object,
207                                 guint       prop_id,
208                                 GValue     *value,
209                                 GParamSpec *pspec)
210 {
211   GNetworkService *srv = G_NETWORK_SERVICE (object);
212
213   switch (prop_id)
214     {
215     case PROP_SERVICE:
216       g_value_set_string (value, g_network_service_get_service (srv));
217       break;
218
219     case PROP_PROTOCOL:
220       g_value_set_string (value, g_network_service_get_protocol (srv));
221       break;
222
223     case PROP_DOMAIN:
224       g_value_set_string (value, g_network_service_get_domain (srv));
225       break;
226
227     case PROP_SCHEME:
228       g_value_set_string (value, g_network_service_get_scheme (srv));
229       break;
230
231     default:
232       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
233       break;
234     }
235 }
236
237 /**
238  * g_network_service_new:
239  * @service: the service type to look up (eg, "ldap")
240  * @protocol: the networking protocol to use for @service (eg, "tcp")
241  * @domain: the DNS domain to look up the service in
242  *
243  * Creates a new #GNetworkService representing the given @service,
244  * @protocol, and @domain. This will initially be unresolved; use the
245  * #GSocketConnectable interface to resolve it.
246  *
247  * Return value: a new #GNetworkService
248  *
249  * Since: 2.22
250  */
251 GSocketConnectable *
252 g_network_service_new (const gchar *service,
253                        const gchar *protocol,
254                        const gchar *domain)
255 {
256   return g_object_new (G_TYPE_NETWORK_SERVICE,
257                        "service", service,
258                        "protocol", protocol,
259                        "domain", domain,
260                        NULL);
261 }
262
263 /**
264  * g_network_service_get_service:
265  * @srv: a #GNetworkService
266  *
267  * Gets @srv's service name (eg, "ldap").
268  *
269  * Return value: @srv's service name
270  *
271  * Since: 2.22
272  */
273 const gchar *
274 g_network_service_get_service (GNetworkService *srv)
275 {
276   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL);
277
278   return srv->priv->service;
279 }
280
281 /**
282  * g_network_service_get_protocol:
283  * @srv: a #GNetworkService
284  *
285  * Gets @srv's protocol name (eg, "tcp").
286  *
287  * Return value: @srv's protocol name
288  *
289  * Since: 2.22
290  */
291 const gchar *
292 g_network_service_get_protocol (GNetworkService *srv)
293 {
294   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL);
295
296   return srv->priv->protocol;
297 }
298
299 /**
300  * g_network_service_get_domain:
301  * @srv: a #GNetworkService
302  *
303  * Gets the domain that @srv serves. This might be either UTF-8 or
304  * ASCII-encoded, depending on what @srv was created with.
305  *
306  * Return value: @srv's domain name
307  *
308  * Since: 2.22
309  */
310 const gchar *
311 g_network_service_get_domain (GNetworkService *srv)
312 {
313   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL);
314
315   return srv->priv->domain;
316 }
317
318 /**
319  * g_network_service_get_scheme:
320  * @srv: a #GNetworkService
321  *
322  * Get's the URI scheme used to resolve proxies. By default, the service name
323  * is used as scheme.
324  *
325  * Return value: @srv's scheme name
326  *
327  * Since: 2.26
328  */
329 const gchar *
330 g_network_service_get_scheme (GNetworkService *srv)
331 {
332   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL);
333
334   if (srv->priv->scheme)
335     return srv->priv->scheme;
336   else
337     return srv->priv->service;
338 }
339
340 /**
341  * g_network_service_set_scheme:
342  * @srv: a #GNetworkService
343  *
344  * Set's the URI scheme used to resolve proxies. By default, the service name
345  * is used as scheme.
346  *
347  * Since: 2.26
348  */
349 void
350 g_network_service_set_scheme (GNetworkService *srv, const gchar *scheme)
351 {
352   g_return_if_fail (G_IS_NETWORK_SERVICE (srv));
353
354   if (srv->priv->scheme)
355     g_free (srv->priv->scheme);
356   srv->priv->scheme = g_strdup (scheme);
357
358   g_object_notify (G_OBJECT (srv), "scheme");
359 }
360
361
362 #define G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR (_g_network_service_address_enumerator_get_type ())
363 #define G_NETWORK_SERVICE_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, GNetworkServiceAddressEnumerator))
364
365 typedef struct {
366   GSocketAddressEnumerator parent_instance;
367
368   GResolver *resolver;
369   GNetworkService *srv;
370   GSocketAddressEnumerator *addr_enum;
371   GList *t;
372   gboolean use_proxy;
373
374   GError *error;
375
376   /* For async operation */
377   GCancellable *cancellable;
378   GSimpleAsyncResult *result;
379 } GNetworkServiceAddressEnumerator;
380
381 typedef struct {
382   GSocketAddressEnumeratorClass parent_class;
383
384 } GNetworkServiceAddressEnumeratorClass;
385
386 G_DEFINE_TYPE (GNetworkServiceAddressEnumerator, _g_network_service_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR)
387
388 static GSocketAddress *
389 g_network_service_address_enumerator_next (GSocketAddressEnumerator  *enumerator,
390                                            GCancellable              *cancellable,
391                                            GError                   **error)
392 {
393   GNetworkServiceAddressEnumerator *srv_enum =
394     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator);
395   GSocketAddress *ret = NULL;
396
397   /* If we haven't yet resolved srv, do that */
398   if (!srv_enum->srv->priv->targets)
399     {
400       GList *targets;
401
402       targets = g_resolver_lookup_service (srv_enum->resolver,
403                                            srv_enum->srv->priv->service,
404                                            srv_enum->srv->priv->protocol,
405                                            srv_enum->srv->priv->domain,
406                                            cancellable, error);
407       if (!targets)
408         return NULL;
409
410       srv_enum->srv->priv->targets = targets;
411       srv_enum->t = srv_enum->srv->priv->targets;
412     }
413
414   /* Delegate to GNetworkAddress */
415   do
416     {
417       if (srv_enum->addr_enum == NULL && srv_enum->t)
418         {
419           GError *error = NULL;
420           gchar *uri;
421           gchar *hostname;
422           GSocketConnectable *addr;
423           GSrvTarget *target = srv_enum->t->data;
424
425           srv_enum->t = g_list_next (srv_enum->t);
426
427           hostname = g_hostname_to_ascii (g_srv_target_get_hostname (target));
428
429           if (hostname == NULL)
430             {
431               if (srv_enum->error == NULL)
432                 srv_enum->error =
433                   g_error_new (G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
434                                "Received invalid hostname '%s' from GSrvTarget",
435                                g_srv_target_get_hostname (target));
436               continue;
437             }
438
439           uri = g_strdup_printf ("%s://%s:%u",
440                                  g_network_service_get_scheme (srv_enum->srv),
441                                  hostname,
442                                  g_srv_target_get_port (target));
443           g_free (hostname);
444
445           addr = g_network_address_parse_uri (uri,
446                                               g_srv_target_get_port (target),
447                                               &error);
448           g_free (uri);
449
450           if (addr == NULL)
451             {
452               if (srv_enum->error == NULL)
453                 srv_enum->error = error;
454               continue;
455             }
456
457           if (srv_enum->use_proxy)
458             srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr);
459           else
460             srv_enum->addr_enum = g_socket_connectable_enumerate (addr);
461           g_object_unref (addr);
462         }
463
464       if (srv_enum->addr_enum)
465         {
466           GError *error = NULL;
467
468           ret = g_socket_address_enumerator_next (srv_enum->addr_enum,
469                                                   cancellable,
470                                                   &error);
471
472           if (error)
473             {
474               if (srv_enum->error == NULL)
475                 srv_enum->error = error;
476               else
477                 g_error_free (error);
478
479               g_object_unref (srv_enum->addr_enum);
480               srv_enum->addr_enum = NULL;
481             }
482         }
483     }
484   while (srv_enum->addr_enum == NULL && srv_enum->t);
485
486   if (ret == NULL && srv_enum->error)
487     {
488       g_propagate_error (error, srv_enum->error);
489       srv_enum->error = NULL;
490     }
491
492   return ret;
493 }
494
495 static void next_async_resolved_targets   (GObject                          *source_object,
496                                            GAsyncResult                     *result,
497                                            gpointer                          user_data);
498 static void next_async_have_targets       (GNetworkServiceAddressEnumerator *srv_enum);
499 static void next_async_have_address       (GObject                          *source_object,
500                                            GAsyncResult                     *result,
501                                            gpointer                          user_data);
502
503 static void
504 g_network_service_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator,
505                                                  GCancellable              *cancellable,
506                                                  GAsyncReadyCallback        callback,
507                                                  gpointer                   user_data)
508 {
509   GNetworkServiceAddressEnumerator *srv_enum =
510     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator);
511
512   g_return_if_fail (srv_enum->result == NULL);
513
514   srv_enum->result = g_simple_async_result_new (G_OBJECT (enumerator),
515                                                 callback, user_data,
516                                                 g_network_service_address_enumerator_next_async);
517
518   if (cancellable)
519     srv_enum->cancellable = g_object_ref (cancellable);
520
521   /* If we haven't yet resolved srv, do that */
522   if (!srv_enum->srv->priv->targets)
523     {
524       g_resolver_lookup_service_async (srv_enum->resolver,
525                                        srv_enum->srv->priv->service,
526                                        srv_enum->srv->priv->protocol,
527                                        srv_enum->srv->priv->domain,
528                                        cancellable,
529                                        next_async_resolved_targets,
530                                        srv_enum);
531     }
532   else
533     next_async_have_targets (srv_enum);
534 }
535
536 static void
537 next_async_resolved_targets (GObject      *source_object,
538                              GAsyncResult *result,
539                              gpointer      user_data)
540 {
541   GNetworkServiceAddressEnumerator *srv_enum = user_data;
542   GError *error = NULL;
543
544   srv_enum->srv->priv->targets =
545     g_resolver_lookup_service_finish (srv_enum->resolver, result, &error);
546
547   if (error)
548     {
549       GSimpleAsyncResult *simple = srv_enum->result;
550
551       srv_enum->result = NULL;
552       g_simple_async_result_set_from_error (simple, error);
553       g_error_free (error);
554       g_simple_async_result_complete (simple);
555       g_object_unref (simple);
556     }
557   else
558     {
559       srv_enum->t = srv_enum->srv->priv->targets;
560       next_async_have_targets (srv_enum);
561     }
562 }
563
564 static void
565 next_async_have_targets (GNetworkServiceAddressEnumerator *srv_enum)
566 {
567   /* Delegate to GNetworkAddress */
568   if (srv_enum->addr_enum == NULL && srv_enum->t)
569     {
570       GSocketConnectable *addr;
571       GSrvTarget *target = srv_enum->t->data;
572
573       srv_enum->t = g_list_next (srv_enum->t);
574       addr = g_network_address_new (g_srv_target_get_hostname (target),
575                                     (guint16) g_srv_target_get_port (target));
576
577       if (srv_enum->use_proxy)
578         srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr);
579       else
580         srv_enum->addr_enum = g_socket_connectable_enumerate (addr);
581
582       g_object_unref (addr);
583     }
584
585   if (srv_enum->addr_enum)
586     {
587       g_socket_address_enumerator_next_async (srv_enum->addr_enum,
588                                               srv_enum->cancellable,
589                                               next_async_have_address,
590                                               srv_enum);
591     }
592   else
593     {
594       GSimpleAsyncResult *simple = srv_enum->result;
595       srv_enum->result = NULL;
596
597       if (srv_enum->error)
598         {
599           g_simple_async_result_set_from_error (simple, srv_enum->error);
600           g_error_free (srv_enum->error);
601           srv_enum->error = NULL;
602         }
603
604       g_simple_async_result_complete (simple);
605       g_object_unref (simple);
606     }
607 }
608
609 static void
610 next_async_have_address (GObject      *source_object,
611                          GAsyncResult *result,
612                          gpointer      user_data)
613 {
614   GNetworkServiceAddressEnumerator *srv_enum = user_data;
615   GSocketAddress *address;
616   GError *error = NULL;
617   
618   address = g_socket_address_enumerator_next_finish (srv_enum->addr_enum,
619                                                      result,
620                                                      &error);
621
622   if (error)
623     {
624       if (srv_enum->error == NULL)
625         srv_enum->error = error;
626       else
627         g_error_free (error);
628
629       g_object_unref (srv_enum->addr_enum);
630       srv_enum->addr_enum = NULL;
631
632       next_async_have_targets (srv_enum);
633     }
634   else
635     {
636       GSimpleAsyncResult *simple = srv_enum->result;
637
638       srv_enum->result = NULL;
639
640       if (address)
641         g_simple_async_result_set_op_res_gpointer (simple,
642                                                    address, g_object_unref);
643
644       g_simple_async_result_complete (simple);
645       g_object_unref (simple);
646     }
647 }
648
649 static GSocketAddress *
650 g_network_service_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator,
651                                                   GAsyncResult              *result,
652                                                   GError                   **error)
653 {
654   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
655   GSocketAddress *sockaddr;
656
657   if (g_simple_async_result_propagate_error (simple, error))
658     return NULL;
659
660   sockaddr = g_simple_async_result_get_op_res_gpointer (simple);
661   return sockaddr ? g_object_ref (sockaddr) : NULL;
662 }
663
664 static void
665 _g_network_service_address_enumerator_init (GNetworkServiceAddressEnumerator *enumerator)
666 {
667 }
668
669 static void
670 g_network_service_address_enumerator_finalize (GObject *object)
671 {
672   GNetworkServiceAddressEnumerator *srv_enum =
673     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (object);
674
675   if (srv_enum->srv)
676     g_object_unref (srv_enum->srv);
677
678   if (srv_enum->addr_enum)
679     g_object_unref (srv_enum->addr_enum);
680
681   if (srv_enum->resolver)
682     g_object_unref (srv_enum->resolver);
683
684   if (srv_enum->result)
685     g_object_unref (srv_enum->result);
686
687   if (srv_enum->cancellable)
688     g_object_unref (srv_enum->cancellable);
689
690   if (srv_enum->error)
691     g_error_free (srv_enum->error);
692
693   G_OBJECT_CLASS (_g_network_service_address_enumerator_parent_class)->finalize (object);
694 }
695
696 static void
697 _g_network_service_address_enumerator_class_init (GNetworkServiceAddressEnumeratorClass *srvenum_class)
698 {
699   GObjectClass *object_class = G_OBJECT_CLASS (srvenum_class);
700   GSocketAddressEnumeratorClass *enumerator_class =
701     G_SOCKET_ADDRESS_ENUMERATOR_CLASS (srvenum_class);
702
703   enumerator_class->next        = g_network_service_address_enumerator_next;
704   enumerator_class->next_async  = g_network_service_address_enumerator_next_async;
705   enumerator_class->next_finish = g_network_service_address_enumerator_next_finish;
706
707   object_class->finalize = g_network_service_address_enumerator_finalize;
708 }
709
710 static GSocketAddressEnumerator *
711 g_network_service_connectable_enumerate (GSocketConnectable *connectable)
712 {
713   GNetworkServiceAddressEnumerator *srv_enum;
714
715   srv_enum = g_object_new (G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, NULL);
716   srv_enum->srv = g_object_ref (connectable);
717   srv_enum->resolver = g_resolver_get_default ();
718   srv_enum->use_proxy = FALSE;
719
720   return G_SOCKET_ADDRESS_ENUMERATOR (srv_enum);
721 }
722
723 static GSocketAddressEnumerator *
724 g_network_service_connectable_proxy_enumerate (GSocketConnectable *connectable)
725 {
726   GSocketAddressEnumerator *addr_enum;
727   GNetworkServiceAddressEnumerator *srv_enum;
728
729   addr_enum = g_network_service_connectable_enumerate (connectable);
730   srv_enum = G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (addr_enum);
731   srv_enum->use_proxy = TRUE;
732
733   return addr_enum;
734 }