Mercurial > pidgin
comparison src/dnssrv.c @ 11395:f0e03a3ca3b5
[gaim-migrate @ 13626]
Now this actually works! Also some whitespace cleanup.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Wed, 31 Aug 2005 21:02:39 +0000 |
parents | bdeace860555 |
children | d678a37c16d9 |
comparison
equal
deleted
inserted
replaced
11394:54934c165625 | 11395:f0e03a3ca3b5 |
---|---|
46 #ifndef _WIN32 | 46 #ifndef _WIN32 |
47 typedef union { | 47 typedef union { |
48 HEADER hdr; | 48 HEADER hdr; |
49 u_char buf[1024]; | 49 u_char buf[1024]; |
50 } queryans; | 50 } queryans; |
51 #else | |
52 static DNS_STATUS (*MyDnsQuery_UTF8) ( | |
53 PCSTR lpstrName, WORD wType, DWORD fOptions, | |
54 PIP4_ARRAY aipServers, PDNS_RECORD* ppQueryResultsSet, | |
55 PVOID* pReserved) = NULL; | |
56 static void (*MyDnsRecordListFree) (PDNS_RECORD pRecordList, | |
57 DNS_FREE_TYPE FreeType) = NULL; | |
51 #endif | 58 #endif |
52 | 59 |
53 struct resdata { | 60 struct resdata { |
54 SRVCallback cb; | 61 SRVCallback cb; |
55 gpointer extradata; | 62 gpointer extradata; |
56 #ifndef _WIN32 | 63 #ifndef _WIN32 |
57 guint handle; | 64 guint handle; |
58 #else | 65 #else |
59 DNS_STATUS (*DnsQuery) (PCSTR lpstrName, WORD wType, DWORD fOptions, | |
60 PIP4_ARRAY aipServers, PDNS_RECORD* ppQueryResultsSet, PVOID* pReserved); | |
61 void (*DnsRecordListFree) (PDNS_RECORD pRecordList, DNS_FREE_TYPE FreeType); | |
62 char *query; | 66 char *query; |
63 char *errmsg; | 67 char *errmsg; |
64 GSList *results; | 68 GSList *results; |
65 #endif | 69 #endif |
66 }; | 70 }; |
100 size = res_query( query, C_IN, T_SRV, (u_char*)&answer, sizeof( answer)); | 104 size = res_query( query, C_IN, T_SRV, (u_char*)&answer, sizeof( answer)); |
101 | 105 |
102 qdcount = ntohs(answer.hdr.qdcount); | 106 qdcount = ntohs(answer.hdr.qdcount); |
103 ancount = ntohs(answer.hdr.ancount); | 107 ancount = ntohs(answer.hdr.ancount); |
104 | 108 |
105 | 109 |
106 cp = (guchar*)&answer + sizeof(HEADER); | 110 cp = (guchar*)&answer + sizeof(HEADER); |
107 end = (guchar*)&answer + size; | 111 end = (guchar*)&answer + size; |
108 | 112 |
109 /* skip over unwanted stuff */ | 113 /* skip over unwanted stuff */ |
110 while (qdcount-- > 0 && cp < end) { | 114 while (qdcount-- > 0 && cp < end) { |
117 size = dn_expand((unsigned char*)&answer, end, cp, name, 256); | 121 size = dn_expand((unsigned char*)&answer, end, cp, name, 256); |
118 if(size < 0) | 122 if(size < 0) |
119 goto end; | 123 goto end; |
120 | 124 |
121 cp += size; | 125 cp += size; |
122 | 126 |
123 NS_GET16(type,cp); | 127 NS_GET16(type,cp); |
124 cp += 6; /* skip ttl and class since we already know it */ | 128 cp += 6; /* skip ttl and class since we already know it */ |
125 | 129 |
126 NS_GET16(dlen,cp); | 130 NS_GET16(dlen,cp); |
127 | 131 |
141 srvres = g_new0(struct srv_response,1); | 145 srvres = g_new0(struct srv_response,1); |
142 strcpy(srvres->hostname, name); | 146 strcpy(srvres->hostname, name); |
143 srvres->pref = pref; | 147 srvres->pref = pref; |
144 srvres->port = port; | 148 srvres->port = port; |
145 srvres->weight = weight; | 149 srvres->weight = weight; |
146 | 150 |
147 ret = g_list_insert_sorted(ret, srvres, responsecompare); | 151 ret = g_list_insert_sorted(ret, srvres, responsecompare); |
148 } else { | 152 } else { |
149 cp += dlen; | 153 cp += dlen; |
150 } | 154 } |
151 } | 155 } |
158 } | 162 } |
159 | 163 |
160 /* Should the resolver be reused? | 164 /* Should the resolver be reused? |
161 * There is most likely only 1 SRV queries per prpl... | 165 * There is most likely only 1 SRV queries per prpl... |
162 */ | 166 */ |
163 _exit(0); | 167 _exit(0); |
164 } | 168 } |
165 | 169 |
166 static void resolved(gpointer data, gint source, GaimInputCondition cond) { | 170 static void resolved(gpointer data, gint source, GaimInputCondition cond) { |
167 int size; | 171 int size; |
168 struct resdata *rdata = (struct resdata*)data; | 172 struct resdata *rdata = (struct resdata*)data; |
198 struct srv_response *srvres_tmp; | 202 struct srv_response *srvres_tmp; |
199 GSList *lst = rdata->results; | 203 GSList *lst = rdata->results; |
200 | 204 |
201 size = g_slist_length(rdata->results); | 205 size = g_slist_length(rdata->results); |
202 | 206 |
203 gaim_debug_info("srv","found %d SRV entries\n", size); | |
204 | |
205 srvres_tmp = srvres = g_malloc0(sizeof(struct srv_response) * size); | 207 srvres_tmp = srvres = g_malloc0(sizeof(struct srv_response) * size); |
206 while (lst) { | 208 while (lst) { |
207 memcpy(srvres_tmp++, lst->data, sizeof(struct srv_response)); | 209 memcpy(srvres_tmp++, lst->data, sizeof(struct srv_response)); |
208 g_free(lst->data); | 210 g_free(lst->data); |
209 lst = g_slist_remove(lst, lst->data); | 211 lst = g_slist_remove(lst, lst->data); |
210 } | 212 } |
211 | 213 |
212 rdata->results = lst; | 214 rdata->results = lst; |
213 } | 215 } |
214 | 216 |
217 gaim_debug_info("srv", "found %d SRV entries\n", size); | |
218 | |
215 rdata->cb(srvres, size, rdata->extradata); | 219 rdata->cb(srvres, size, rdata->extradata); |
216 | 220 |
217 g_free(rdata->query); | 221 g_free(rdata->query); |
218 g_free(rdata); | 222 g_free(rdata); |
219 | 223 |
220 return FALSE; | 224 return FALSE; |
221 } | 225 } |
222 | 226 |
223 static gpointer res_thread(gpointer data) { | 227 static gpointer res_thread(gpointer data) { |
224 DNS_RECORD *dr = NULL, *dr_tmp; | 228 DNS_RECORD *dr = NULL; |
225 GSList *lst = NULL; | 229 GSList *lst = NULL; |
226 struct srv_response *srvres; | 230 struct srv_response *srvres; |
227 DNS_SRV_DATA *srv_data; | 231 DNS_SRV_DATA *srv_data; |
228 int type = DNS_TYPE_SRV; | 232 int type = DNS_TYPE_SRV; |
229 DNS_STATUS ds; | 233 DNS_STATUS ds; |
230 struct resdata *rdata = data; | 234 struct resdata *rdata = data; |
231 | 235 |
232 ds = rdata->DnsQuery(rdata->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL); | 236 ds = MyDnsQuery_UTF8(rdata->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL); |
233 if (ds != ERROR_SUCCESS) { | 237 if (ds != ERROR_SUCCESS) { |
234 rdata->errmsg = g_strdup_printf("Couldn't look up SRV record. Error = %d\n", (int) ds); | 238 rdata->errmsg = g_strdup_printf("Couldn't look up SRV record. Error = %d\n", (int) ds); |
235 } else { | 239 } else { |
236 dr_tmp = dr; | 240 DNS_RECORD *dr_tmp = dr; |
237 while (dr_tmp != NULL) { | 241 while (dr_tmp != NULL) { |
238 | |
239 /* Discard any incorrect entries. I'm not sure if this is necessary */ | 242 /* Discard any incorrect entries. I'm not sure if this is necessary */ |
240 if (dr_tmp->wType != type || strcmp(dr_tmp->pName, rdata->query) != 0) { | 243 if (dr_tmp->wType != type || strcmp(dr_tmp->pName, rdata->query) != 0) { |
244 dr_tmp = dr_tmp->pNext; | |
241 continue; | 245 continue; |
242 } | 246 } |
243 | 247 |
244 srv_data = &dr_tmp->Data.SRV; | 248 srv_data = &dr_tmp->Data.SRV; |
245 srvres = g_new0(struct srv_response, 1); | 249 srvres = g_new0(struct srv_response, 1); |
249 srvres->port = srv_data->wPort; | 253 srvres->port = srv_data->wPort; |
250 srvres->weight = srv_data->wWeight; | 254 srvres->weight = srv_data->wWeight; |
251 | 255 |
252 lst = g_slist_insert_sorted(lst, srvres, responsecompare); | 256 lst = g_slist_insert_sorted(lst, srvres, responsecompare); |
253 | 257 |
254 dr_tmp = dr->pNext; | 258 dr_tmp = dr_tmp->pNext; |
255 } | 259 } |
256 | 260 |
257 rdata->DnsRecordListFree(dr, DnsFreeRecordList); | 261 MyDnsRecordListFree(dr, DnsFreeRecordList); |
258 rdata->results = lst; | 262 rdata->results = lst; |
259 } | 263 } |
260 | 264 |
261 /* back to main thread */ | 265 /* back to main thread */ |
262 g_idle_add(res_main_thread_cb, rdata); | 266 g_idle_add(res_main_thread_cb, rdata); |
295 resolve(in[0], out[1]); | 299 resolve(in[0], out[1]); |
296 } | 300 } |
297 | 301 |
298 close(out[1]); | 302 close(out[1]); |
299 close(in[0]); | 303 close(in[0]); |
300 | 304 |
301 if(write(in[1], query, strlen(query)+1)<0) { | 305 if(write(in[1], query, strlen(query)+1)<0) { |
302 gaim_debug_error("srv", "Could not write to SRV resolver\n"); | 306 gaim_debug_error("srv", "Could not write to SRV resolver\n"); |
303 } | 307 } |
304 rdata = g_new0(struct resdata,1); | 308 rdata = g_new0(struct resdata,1); |
305 rdata->cb = cb; | 309 rdata->cb = cb; |
310 #else | 314 #else |
311 GError* err = NULL; | 315 GError* err = NULL; |
312 | 316 |
313 static gboolean initialized = FALSE; | 317 static gboolean initialized = FALSE; |
314 | 318 |
315 static DNS_STATUS (*MyDnsQuery_UTF) ( | |
316 PCSTR lpstrName, WORD wType, DWORD fOptions, PIP4_ARRAY aipServers, | |
317 PDNS_RECORD* ppQueryResultsSet, PVOID* pReserved) = NULL; | |
318 static void (*MyDnsRecordListFree) (PDNS_RECORD pRecordList, DNS_FREE_TYPE FreeType) = NULL; | |
319 | |
320 gaim_debug_info("srv","querying SRV record for %s\n", query); | 319 gaim_debug_info("srv","querying SRV record for %s\n", query); |
321 | 320 |
322 if (!initialized) { | 321 if (!initialized) { |
323 MyDnsQuery_UTF = (void*) wgaim_find_and_loadproc("dnsapi.dll", "DnsQuery_UTF"); | 322 MyDnsQuery_UTF8 = (void*) wgaim_find_and_loadproc("dnsapi.dll", "DnsQuery_UTF8"); |
324 MyDnsRecordListFree = (void*) wgaim_find_and_loadproc( | 323 MyDnsRecordListFree = (void*) wgaim_find_and_loadproc( |
325 "dnsapi.dll", "DnsRecordListFree"); | 324 "dnsapi.dll", "DnsRecordListFree"); |
326 initialized = TRUE; | 325 initialized = TRUE; |
327 } | 326 } |
328 | 327 |
329 | 328 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) { |
330 if (!MyDnsQuery_UTF || !MyDnsRecordListFree) { | |
331 gaim_debug_error("srv", "System missing DNS API (Requires W2K+)\n"); | 329 gaim_debug_error("srv", "System missing DNS API (Requires W2K+)\n"); |
332 g_free(query); | 330 g_free(query); |
333 cb(NULL, 0, extradata); | 331 cb(NULL, 0, extradata); |
334 return; | 332 return; |
335 } | 333 } |
336 | 334 |
337 rdata = g_new0(struct resdata, 1); | 335 rdata = g_new0(struct resdata, 1); |
338 rdata->DnsQuery = MyDnsQuery_UTF; | |
339 rdata->DnsRecordListFree = MyDnsRecordListFree; | |
340 rdata->cb = cb; | 336 rdata->cb = cb; |
341 rdata->query = query; | 337 rdata->query = query; |
338 rdata->extradata = extradata; | |
342 | 339 |
343 if (!g_thread_create(res_thread, rdata, FALSE, &err)) { | 340 if (!g_thread_create(res_thread, rdata, FALSE, &err)) { |
344 rdata->errmsg = g_strdup_printf("SRV thread create failure: %s\n", err ? err->message : ""); | 341 rdata->errmsg = g_strdup_printf("SRV thread create failure: %s\n", err ? err->message : ""); |
345 g_error_free(err); | 342 g_error_free(err); |
346 res_main_thread_cb(rdata); | 343 res_main_thread_cb(rdata); |