tls: add Client Certificate message
[siplcs.git] / src / purple / purple-dnsquery.c
blob45b99ecf3cdda4df1e912b42e2273c92f3ae5ea1
1 /**
2 * @file purple-dnsquery.c
4 * pidgin-sipe
6 * Copyright (C) 2010 SIPE Project <http://sipe.sourceforge.net/>
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.
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.
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
23 #ifdef _WIN32
24 #include "win32/win32dep.h" /* for inet_ntop() */
25 #include <ws2tcpip.h>
26 #else
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 #endif
31 #include <glib.h>
33 #include "dnsquery.h"
34 #include "dnssrv.h"
36 #include "sipe-backend.h"
38 struct sipe_dns_query {
39 enum {
41 SRV
42 } type;
43 sipe_dns_resolved_cb callback;
44 gpointer extradata;
45 gpointer purple_query_data;
48 static void dns_a_response(GSList *hosts,
49 struct sipe_dns_query *query,
50 const char *error_message)
52 char ipstr[INET6_ADDRSTRLEN];
53 struct sockaddr *addr;
54 const void *addrdata;
55 int port;
57 if (error_message || !g_slist_next(hosts)) {
58 query->callback(query->extradata, NULL, 0);
59 g_slist_free(hosts);
60 return;
63 addr = g_slist_next(hosts)->data;
64 if (addr->sa_family == AF_INET6) {
65 /* OS provides addr so it must be properly aligned */
66 struct sockaddr_in6 *sin6 = (void *) addr;
67 addrdata = &sin6->sin6_addr;
68 port = sin6->sin6_port;
69 } else {
70 /* OS provides addr so it must be properly aligned */
71 struct sockaddr_in *sin = (void *) addr;
72 addrdata = &sin->sin_addr;
73 port = sin->sin_port;
76 inet_ntop(addr->sa_family, addrdata, ipstr, sizeof (ipstr));
78 query->callback(query->extradata, ipstr, port);
80 for (; hosts; hosts = g_slist_delete_link(hosts, hosts)) {
81 // Free the addrlen, no data in this link
82 hosts = g_slist_delete_link(hosts, hosts);
83 // Free the address
84 g_free(hosts->data);
87 g_free(query);
90 struct sipe_dns_query *sipe_backend_dns_query_a(const gchar *hostname,
91 int port,
92 sipe_dns_resolved_cb callback,
93 gpointer data)
95 struct sipe_dns_query *query = g_new(struct sipe_dns_query, 1);
96 query->type = A;
97 query->callback = callback;
98 query->extradata = data;
99 query->purple_query_data = purple_dnsquery_a(hostname,
100 port,
101 (PurpleDnsQueryConnectFunction) dns_a_response,
102 query);
104 return query;
108 static void dns_srv_response(PurpleSrvResponse *resp,
109 int results,
110 struct sipe_dns_query *query)
112 if (results)
113 query->callback(query->extradata, resp->hostname, resp->port);
114 else
115 query->callback(query->extradata, NULL, 0);
117 g_free(query);
118 g_free(resp);
121 struct sipe_dns_query *sipe_backend_dns_query_srv(const gchar *protocol,
122 const gchar *transport,
123 const gchar *domain,
124 sipe_dns_resolved_cb callback,
125 gpointer data)
127 struct sipe_dns_query *query = g_new(struct sipe_dns_query, 1);
128 query->type = SRV;
129 query->callback = callback;
130 query->extradata = data;
131 query->purple_query_data = purple_srv_resolve(protocol,
132 transport,
133 domain,
134 (PurpleSrvCallback) dns_srv_response,
135 query);
137 return query;
140 void sipe_backend_dns_query_cancel(struct sipe_dns_query *query)
142 switch (query->type) {
143 case A:
144 purple_dnsquery_destroy(query->purple_query_data);
145 break;
146 case SRV:
147 purple_srv_cancel(query->purple_query_data);
148 break;
151 g_free(query);
155 Local Variables:
156 mode: c
157 c-file-style: "bsd"
158 indent-tabs-mode: t
159 tab-width: 8
160 End: