1 /**
2 * @file telepathy-dnsquery.c
3 *
4 * pidgin-sipe
5 *
6 * Copyright (C) 2012-2017 SIPE Project <http://sipe.sourceforge.net/>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <glib.h>
24 #include <gio/gio.h>
25
26 #include "sipe-backend.h"
27 #include "sipe-common.h"
28
29 struct sipe_dns_query {
30 sipe_dns_resolved_cb callback;
31 gpointer extradata;
32 guint port;
33 GCancellable *cancel;
34 };
35
dns_srv_response(GObject * resolver,GAsyncResult * result,gpointer data)36 static void dns_srv_response(GObject *resolver,
37 GAsyncResult *result,
38 gpointer data)
39 {
40 GError *error = NULL;
41 GList *targets = g_resolver_lookup_service_finish(G_RESOLVER(resolver),
42 result,
43 &error);
44 struct sipe_dns_query *query = data;
45
46 if (targets) {
47 GSrvTarget *target = targets->data;
48 query->callback(query->extradata,
49 g_srv_target_get_hostname(target),
50 g_srv_target_get_port(target));
51 g_resolver_free_targets(targets);
52 } else {
53 SIPE_DEBUG_INFO("dns_srv_response: failed: %s",
54 error ? error->message : "UNKNOWN");
55 if (error)
56 g_error_free(error);
57 if (query->callback)
58 query->callback(query->extradata, NULL, 0);
59 }
60 g_object_unref(query->cancel);
61 g_free(query);
62 }
63
sipe_backend_dns_query_srv(SIPE_UNUSED_PARAMETER struct sipe_core_public * sipe_public,const gchar * protocol,const gchar * transport,const gchar * domain,sipe_dns_resolved_cb callback,gpointer data)64 struct sipe_dns_query *sipe_backend_dns_query_srv(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
65 const gchar *protocol,
66 const gchar *transport,
67 const gchar *domain,
68 sipe_dns_resolved_cb callback,
69 gpointer data)
70 {
71 struct sipe_dns_query *query = g_new0(struct sipe_dns_query, 1);
72 GResolver *resolver = g_resolver_get_default();
73
74 SIPE_DEBUG_INFO("sipe_backend_dns_query_srv: %s/%s/%s",
75 protocol, transport, domain);
76
77 query->callback = callback;
78 query->extradata = data;
79 query->cancel = g_cancellable_new();
80 g_resolver_lookup_service_async(resolver,
81 protocol, transport, domain,
82 query->cancel,
83 dns_srv_response,
84 query);
85
86 g_object_unref(resolver);
87 return(query);
88 }
89
dns_a_response(GObject * resolver,GAsyncResult * result,gpointer data)90 static void dns_a_response(GObject *resolver,
91 GAsyncResult *result,
92 gpointer data)
93 {
94 GError *error = NULL;
95 GList *addresses = g_resolver_lookup_by_name_finish(G_RESOLVER(resolver),
96 result,
97 &error);
98 struct sipe_dns_query *query = data;
99
100 if (addresses) {
101 GInetAddress *address = addresses->data;
102 gchar *ipstr = g_inet_address_to_string(address);
103 query->callback(query->extradata, ipstr, query->port);
104 g_free(ipstr);
105 g_resolver_free_addresses(addresses);
106 } else {
107 SIPE_DEBUG_INFO("dns_a_response: failed: %s",
108 error ? error->message : "UNKNOWN");
109 if (error)
110 g_error_free(error);
111 if (query->callback)
112 query->callback(query->extradata, NULL, 0);
113 }
114 g_object_unref(query->cancel);
115 g_free(query);
116 }
117
sipe_backend_dns_query_a(SIPE_UNUSED_PARAMETER struct sipe_core_public * sipe_public,const gchar * hostname,guint port,sipe_dns_resolved_cb callback,gpointer data)118 struct sipe_dns_query *sipe_backend_dns_query_a(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public,
119 const gchar *hostname,
120 guint port,
121 sipe_dns_resolved_cb callback,
122 gpointer data)
123 {
124 struct sipe_dns_query *query = g_new0(struct sipe_dns_query, 1);
125 GResolver *resolver = g_resolver_get_default();
126
127 SIPE_DEBUG_INFO("sipe_backend_dns_query_a: %s", hostname);
128
129 query->callback = callback;
130 query->extradata = data;
131 query->port = port;
132 query->cancel = g_cancellable_new();
133 g_resolver_lookup_by_name_async(resolver,
134 hostname,
135 query->cancel,
136 dns_a_response,
137 query);
138
139 g_object_unref(resolver);
140 return(query);
141 }
142
sipe_backend_dns_query_cancel(struct sipe_dns_query * query)143 void sipe_backend_dns_query_cancel(struct sipe_dns_query *query)
144 {
145 /* callback is invalid now, do no longer call! */
146 query->callback = NULL;
147 g_cancellable_cancel(query->cancel);
148 }
149
150 /*
151 Local Variables:
152 mode: c
153 c-file-style: "bsd"
154 indent-tabs-mode: t
155 tab-width: 8
156 End:
157 */
158