aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-helper-service-w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns-helper-service-w32.c')
-rw-r--r--src/gns/gnunet-gns-helper-service-w32.c803
1 files changed, 0 insertions, 803 deletions
diff --git a/src/gns/gnunet-gns-helper-service-w32.c b/src/gns/gnunet-gns-helper-service-w32.c
deleted file mode 100644
index 4c4803556..000000000
--- a/src/gns/gnunet-gns-helper-service-w32.c
+++ /dev/null
@@ -1,803 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file gnunet-gns-helper-service-w32.c
22 * @brief an intermediary service to access distributed GNS
23 * @author Christian Grothoff
24 * @author LRN
25 */
26#include "platform.h"
27#include <gnunet_util_lib.h>
28#include <gnunet_identity_service.h>
29#include <gnunet_dnsparser_lib.h>
30#include <gnunet_namestore_service.h>
31#include <gnunet_gns_service.h>
32#include <initguid.h>
33#include "gnunet_w32nsp_lib.h"
34#include "w32resolver.h"
35#include <nspapi.h>
36#include <unistr.h>
37
38#define DEFINE_DNS_GUID(a, x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
39DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
40DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
41DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
42DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
43DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
44DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
45DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
46DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
47DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
48DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
49DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
50
51
52struct request {
53 /**
54 * We keep these in a doubly-linked list (for cleanup).
55 */
56 struct request *next;
57
58 /**
59 * We keep these in a doubly-linked list (for cleanup).
60 */
61 struct request *prev;
62
63 /**
64 * Client that issued the request
65 */
66 struct GNUNET_SERVICE_Client *client;
67
68 GUID sc;
69
70 int af;
71
72 wchar_t *name;
73
74 char *u8name;
75
76 struct GNUNET_GNS_LookupRequest *lookup_request;
77};
78
79
80/**
81 * Head of the doubly-linked list (for cleanup).
82 */
83static struct request *rq_head;
84
85/**
86 * Tail of the doubly-linked list (for cleanup).
87 */
88static struct request *rq_tail;
89
90/**
91 * Handle to GNS service.
92 */
93static struct GNUNET_GNS_Handle *gns;
94
95/**
96 * Active operation on identity service.
97 */
98static struct GNUNET_IDENTITY_Operation *id_op;
99
100/**
101 * Handle for identity service.
102 */
103static struct GNUNET_IDENTITY_Handle *identity;
104
105/**
106 * Public key of the gns-master ego
107 */
108static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey;
109
110/**
111 * Set to 1 once egos are obtained.
112 */
113static int got_egos;
114
115
116/**
117 * Task run on shutdown. Cleans up everything.
118 *
119 * @param cls unused
120 */
121static void
122do_shutdown(void *cls)
123{
124 struct request *rq;
125
126 if (NULL != id_op)
127 {
128 GNUNET_IDENTITY_cancel(id_op);
129 id_op = NULL;
130 }
131 if (NULL != identity)
132 {
133 GNUNET_IDENTITY_disconnect(identity);
134 identity = NULL;
135 }
136 while (NULL != (rq = rq_head))
137 {
138 if (NULL != rq->lookup_request)
139 GNUNET_GNS_lookup_cancel(rq->lookup_request);
140 GNUNET_CONTAINER_DLL_remove(rq_head,
141 rq_tail,
142 rq);
143 GNUNET_free_non_null(rq->name);
144 if (rq->u8name)
145 free(rq->u8name);
146 GNUNET_free(rq);
147 }
148 if (NULL != gns)
149 {
150 GNUNET_GNS_disconnect(gns);
151 gns = NULL;
152 }
153}
154
155
156#define MarshallPtr(ptr, base, type) \
157 if (ptr) \
158 ptr = (type *) ((char *)ptr - (char *)base)
159
160
161void
162MarshallWSAQUERYSETW(WSAQUERYSETW *qs, GUID *sc)
163{
164 MarshallPtr(qs->lpszServiceInstanceName, qs, wchar_t);
165 MarshallPtr(qs->lpServiceClassId, qs, GUID);
166 MarshallPtr(qs->lpVersion, qs, WSAVERSION);
167 MarshallPtr(qs->lpNSProviderId, qs, GUID);
168 MarshallPtr(qs->lpszContext, qs, wchar_t);
169 MarshallPtr(qs->lpafpProtocols, qs, AFPROTOCOLS);
170 MarshallPtr(qs->lpszQueryString, qs, wchar_t);
171 for (int i = 0; i < qs->dwNumberOfCsAddrs; i++)
172 {
173 MarshallPtr(qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR);
174 MarshallPtr(qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR);
175 }
176 MarshallPtr(qs->lpcsaBuffer, qs, CSADDR_INFO);
177 if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL)
178 {
179 struct hostent *he;
180
181 he = (struct hostent *)qs->lpBlob->pBlobData;
182 for (int i = 0; he->h_aliases[i] != NULL; i++)
183 MarshallPtr(he->h_aliases[i], he, char);
184 MarshallPtr(he->h_aliases, he, char *);
185 MarshallPtr(he->h_name, he, char);
186 for (int i = 0; he->h_addr_list[i] != NULL; i++)
187 MarshallPtr(he->h_addr_list[i], he, void);
188 MarshallPtr(he->h_addr_list, he, char *);
189 MarshallPtr(qs->lpBlob->pBlobData, qs, void);
190 }
191 MarshallPtr(qs->lpBlob, qs, BLOB);
192}
193
194
195static void
196process_lookup_result(void *cls,
197 uint32_t rd_count,
198 const struct GNUNET_GNSRECORD_Data *rd)
199{
200 struct request *rq = cls;
201 int i, j, csanum;
202 struct GNUNET_W32RESOLVER_GetMessage *msg;
203 struct GNUNET_MQ_Envelope *msg_env;
204 struct GNUNET_MessageHeader *msgend;
205 struct GNUNET_MQ_Envelope *msgend_env;
206 WSAQUERYSETW *qs;
207 size_t size;
208 size_t size_recalc;
209 char *ptr;
210 size_t blobsize = 0;
211 size_t blobaddrcount = 0;
212
213 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
214 "Got lookup result with count %u for rq %p with client %p\n",
215 rd_count,
216 rq,
217 rq->client);
218 rq->lookup_request = NULL;
219
220 if (0 == rd_count)
221 {
222 msgend_env = GNUNET_MQ_msg(msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
223 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client),
224 msgend_env);
225 GNUNET_CONTAINER_DLL_remove(rq_head,
226 rq_tail,
227 rq);
228 GNUNET_free_non_null(rq->name);
229 if (rq->u8name)
230 free(rq->u8name);
231 GNUNET_free(rq);
232 return;
233 }
234
235 size = sizeof(struct GNUNET_W32RESOLVER_GetMessage) + sizeof(WSAQUERYSETW);
236 size += (wcslen(rq->name) + 1) * sizeof(wchar_t);
237 size += sizeof(GUID);
238 /* lpszComment ? a TXT record? */
239 size += sizeof(GUID);
240 /* lpszContext ? Not sure what it is */
241 csanum = 0;
242 for (i = 0; i < rd_count; i++)
243 {
244 switch (rd[i].record_type)
245 {
246 case GNUNET_DNSPARSER_TYPE_A:
247 if (rd[i].data_size != sizeof(struct in_addr))
248 continue;
249 size += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in) * 2;
250 csanum++;
251 break;
252
253 case GNUNET_DNSPARSER_TYPE_AAAA:
254 if (rd[i].data_size != sizeof(struct in6_addr))
255 continue;
256 size += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in6) * 2;
257 csanum++;
258 break;
259 }
260 }
261 if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
262 {
263 size += sizeof(BLOB);
264 blobsize += sizeof(struct hostent);
265 blobsize += strlen(rq->u8name) + 1;
266 blobsize += sizeof(void *); /* For aliases */
267 blobsize += sizeof(void *); /* For addresses */
268 for (i = 0; i < rd_count; i++)
269 {
270 if ((rq->af == AF_INET || rq->af == AF_UNSPEC) && rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
271 {
272 blobsize += sizeof(void *);
273 blobsize += sizeof(struct in_addr);
274 blobaddrcount++;
275 }
276 else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA)
277 {
278 blobsize += sizeof(void *);
279 blobsize += sizeof(struct in6_addr);
280 blobaddrcount++;
281 }
282 }
283 size += blobsize;
284 }
285 size_recalc = sizeof(struct GNUNET_W32RESOLVER_GetMessage) + sizeof(WSAQUERYSETW);
286 msg_env = GNUNET_MQ_msg_extra(msg,
287 size - sizeof(struct GNUNET_MessageHeader),
288 GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
289 msg->af = htonl(rq->af);
290 msg->sc_data1 = htonl(rq->sc.Data1);
291 msg->sc_data2 = htons(rq->sc.Data2);
292 msg->sc_data3 = htons(rq->sc.Data3);
293 for (i = 0; i < 8; i++)
294 msg->sc_data4[i] = rq->sc.Data4[i];
295 qs = (WSAQUERYSETW *)&msg[1];
296 ptr = (char *)&qs[1];
297 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
298 qs->dwSize = sizeof(WSAQUERYSETW);
299 qs->lpszServiceInstanceName = (wchar_t *)ptr;
300 ptr += (wcslen(rq->name) + 1) * sizeof(wchar_t);
301 size_recalc += (wcslen(rq->name) + 1) * sizeof(wchar_t);
302 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
303 wcscpy(qs->lpszServiceInstanceName, rq->name);
304 qs->lpServiceClassId = (GUID *)ptr;
305 ptr += sizeof(GUID);
306 size_recalc += sizeof(GUID);
307 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
308 GNUNET_memcpy(qs->lpServiceClassId, &rq->sc, sizeof(GUID));
309 qs->lpVersion = NULL;
310 qs->dwNameSpace = NS_DNS;
311 qs->lpNSProviderId = (GUID *)ptr;
312 ptr += sizeof(GUID);
313 size_recalc += sizeof(GUID);
314 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
315 GNUNET_memcpy(qs->lpNSProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS, sizeof(GUID));
316 qs->lpszContext = NULL;
317 qs->dwNumberOfProtocols = 0;
318 qs->lpafpProtocols = NULL;
319 /* Don't bother with this... */
320 qs->lpszQueryString = NULL;
321 qs->dwNumberOfCsAddrs = rd_count;
322 qs->lpcsaBuffer = (CSADDR_INFO *)ptr;
323 ptr += sizeof(CSADDR_INFO) * csanum;
324 j = 0;
325 for (i = 0; i < rd_count; i++)
326 {
327 switch (rd[i].record_type)
328 {
329 case GNUNET_DNSPARSER_TYPE_A:
330 if (rd[i].data_size != sizeof(struct in_addr))
331 continue;
332 qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
333 qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
334
335 qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof(struct sockaddr_in);
336 qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *)ptr;
337 ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
338 memset(qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
339 ((struct sockaddr_in *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin_family = AF_INET;
340
341 qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof(struct sockaddr_in);
342 qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *)ptr;
343 ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
344 memset(qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
345 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_family = AF_INET;
346 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_port = htonl(53); /* Don't ask why it's 53 */
347 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_addr = *(struct in_addr *)rd[i].data;
348 size_recalc += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in) * 2;
349 j++;
350 break;
351
352 case GNUNET_DNSPARSER_TYPE_AAAA:
353 if (rd[i].data_size != sizeof(struct in6_addr))
354 continue;
355 qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
356 qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
357
358 qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof(struct sockaddr_in6);
359 qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *)ptr;
360 ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
361 memset(qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
362 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin6_family = AF_INET6;
363
364 qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof(struct sockaddr_in6);
365 qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *)ptr;
366 ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
367 memset(qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
368 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_family = AF_INET6;
369 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_port = htonl(53); /* Don't ask why it's 53 */
370 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_addr = *(struct in6_addr *)rd[i].data;
371 size_recalc += sizeof(CSADDR_INFO) + sizeof(struct sockaddr_in6) * 2;
372 j++;
373 break;
374
375 default:
376 break;
377 }
378 }
379 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
380 qs->dwOutputFlags = 0;
381 if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
382 {
383 struct hostent *he;
384 qs->lpBlob = (BLOB *)ptr;
385 ptr += sizeof(BLOB);
386
387 size_recalc += sizeof(BLOB);
388 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
389
390 qs->lpBlob->cbSize = blobsize;
391 qs->lpBlob->pBlobData = (BYTE *)ptr;
392 ptr += sizeof(struct hostent);
393
394 size_recalc += sizeof(struct hostent);
395 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
396
397 he = (struct hostent *)qs->lpBlob->pBlobData;
398 he->h_name = (char *)ptr;
399 ptr += strlen(rq->u8name) + 1;
400
401 size_recalc += strlen(rq->u8name) + 1;
402 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
403
404 strcpy(he->h_name, rq->u8name);
405 he->h_aliases = (char **)ptr;
406 ptr += sizeof(void *);
407
408 size_recalc += sizeof(void *); /* For aliases */
409 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
410
411 he->h_aliases[0] = NULL;
412 he->h_addrtype = rq->af;
413 he->h_length = rq->af == AF_INET || rq->af == AF_UNSPEC ? sizeof(struct in_addr) : sizeof(struct in6_addr);
414 he->h_addr_list = (char **)ptr;
415 ptr += sizeof(void *) * (blobaddrcount + 1);
416
417 size_recalc += sizeof(void *) * (blobaddrcount + 1); /* For addresses */
418 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
419
420 j = 0;
421 for (i = 0; i < rd_count; i++)
422 {
423 if ((rq->af == AF_INET || rq->af == AF_UNSPEC) &&
424 rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
425 {
426 he->h_addr_list[j] = (char *)ptr;
427 ptr += sizeof(struct in_addr);
428
429 size_recalc += sizeof(struct in_addr);
430 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
431
432 GNUNET_memcpy(he->h_addr_list[j], rd[i].data, sizeof(struct in_addr));
433 j++;
434 }
435 else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA)
436 {
437 he->h_addr_list[j] = (char *)ptr;
438 ptr += sizeof(struct in6_addr);
439
440 size_recalc += sizeof(struct in6_addr);
441 GNUNET_break(size_recalc == (size_t)((char *)ptr - (char *)msg));
442
443 GNUNET_memcpy(he->h_addr_list[j], rd[i].data, sizeof(struct in6_addr));
444 j++;
445 }
446 }
447 he->h_addr_list[j] = NULL;
448 }
449 msgend_env = GNUNET_MQ_msg(msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
450
451 if ((char *)ptr - (char *)msg != size || size_recalc != size || size_recalc != ((char *)ptr - (char *)msg))
452 {
453 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
454 "Error in WSAQUERYSETW size calc: expected %u, got %lu (recalc %u)\n",
455 size,
456 (unsigned long)((char *)ptr - (char *)msg),
457 size_recalc);
458 }
459 MarshallWSAQUERYSETW(qs, &rq->sc);
460 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client),
461 msg_env);
462 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(rq->client),
463 msgend_env);
464 GNUNET_CONTAINER_DLL_remove(rq_head,
465 rq_tail,
466 rq);
467 GNUNET_free_non_null(rq->name);
468 if (rq->u8name)
469 free(rq->u8name);
470 GNUNET_free(rq);
471}
472
473
474static void
475get_ip_from_hostname(struct GNUNET_SERVICE_Client *client,
476 const wchar_t *name,
477 int af,
478 GUID sc)
479{
480 struct request *rq;
481 char *hostname;
482 size_t strl;
483 size_t namelen;
484 uint32_t rtype;
485
486 if (IsEqualGUID(&SVCID_DNS_TYPE_A, &sc))
487 rtype = GNUNET_DNSPARSER_TYPE_A;
488 else if (IsEqualGUID(&SVCID_DNS_TYPE_NS, &sc))
489 rtype = GNUNET_DNSPARSER_TYPE_NS;
490 else if (IsEqualGUID(&SVCID_DNS_TYPE_CNAME, &sc))
491 rtype = GNUNET_DNSPARSER_TYPE_CNAME;
492 else if (IsEqualGUID(&SVCID_DNS_TYPE_SOA, &sc))
493 rtype = GNUNET_DNSPARSER_TYPE_SOA;
494 else if (IsEqualGUID(&SVCID_DNS_TYPE_PTR, &sc))
495 rtype = GNUNET_DNSPARSER_TYPE_PTR;
496 else if (IsEqualGUID(&SVCID_DNS_TYPE_MX, &sc))
497 rtype = GNUNET_DNSPARSER_TYPE_MX;
498 else if (IsEqualGUID(&SVCID_DNS_TYPE_TEXT, &sc))
499 rtype = GNUNET_DNSPARSER_TYPE_TXT;
500 else if (IsEqualGUID(&SVCID_DNS_TYPE_AAAA, &sc))
501 rtype = GNUNET_DNSPARSER_TYPE_AAAA;
502 else if (IsEqualGUID(&SVCID_DNS_TYPE_SRV, &sc))
503 rtype = GNUNET_DNSPARSER_TYPE_SRV;
504 else if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &sc))
505 rtype = GNUNET_DNSPARSER_TYPE_A;
506 else
507 {
508 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
509 "Unknown GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
510 sc.Data1,
511 sc.Data2,
512 sc.Data3,
513 sc.Data4[0],
514 sc.Data4[1],
515 sc.Data4[2],
516 sc.Data4[3],
517 sc.Data4[4],
518 sc.Data4[5],
519 sc.Data4[6],
520 sc.Data4[7]);
521 GNUNET_SERVICE_client_drop(client);
522 return;
523 }
524
525 if (name)
526 namelen = wcslen(name);
527 else
528 namelen = 0;
529 if (namelen > 0)
530 hostname = (char *)u16_to_u8(name, namelen + 1, NULL, &strl);
531 else
532 hostname = NULL;
533
534 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
535 "W32 DNS resolver asked to look up %s for `%s'.\n",
536 af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything",
537 hostname);
538
539 rq = GNUNET_new(struct request);
540 rq->sc = sc;
541 rq->client = client;
542 rq->af = af;
543 if (rq->af != AF_INET && rq->af != AF_INET6)
544 rq->af = AF_INET;
545 if (namelen)
546 {
547 rq->name = GNUNET_malloc((namelen + 1) * sizeof(wchar_t));
548 GNUNET_memcpy(rq->name,
549 name,
550 (namelen + 1) * sizeof(wchar_t));
551 rq->u8name = hostname;
552 }
553
554 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
555 "Launching a lookup for client %p with rq %p\n",
556 client,
557 rq);
558 rq->lookup_request = GNUNET_GNS_lookup(gns,
559 hostname,
560 &gns_master_pubkey,
561 rtype,
562 GNUNET_NO /* Use DHT */,
563 &process_lookup_result,
564 rq);
565 if (NULL != rq->lookup_request)
566 {
567 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
568 "Lookup launched, waiting for a reply\n");
569 GNUNET_SERVICE_client_continue(client);
570 GNUNET_CONTAINER_DLL_insert(rq_head,
571 rq_tail,
572 rq);
573 }
574 else
575 {
576 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
577 "Lookup was not launched, disconnecting the client\n");
578 GNUNET_free_non_null(rq->name);
579 if (rq->u8name)
580 free(rq->u8name);
581 GNUNET_free(rq);
582 GNUNET_SERVICE_client_drop(client);
583 }
584}
585
586
587/**
588 * Check GET-message.
589 *
590 * @param cls identification of the client
591 * @param msg the actual message
592 * @return #GNUNET_OK if @a msg is well-formed
593 */
594static int
595check_get(void *cls,
596 const struct GNUNET_W32RESOLVER_GetMessage *msg)
597{
598 uint16_t size;
599 const wchar_t *hostname;
600
601 if (!got_egos)
602 {
603 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
604 _("Not ready to process requests, lacking ego data\n"));
605 return GNUNET_SYSERR;
606 }
607 size = ntohs(msg->header.size) - sizeof(struct GNUNET_W32RESOLVER_GetMessage);
608 hostname = (const wchar_t *)&msg[1];
609 if (hostname[size / 2 - 1] != L'\0')
610 {
611 GNUNET_break(0);
612 return GNUNET_SYSERR;
613 }
614 return GNUNET_OK;
615}
616
617
618/**
619 * Handle GET-message.
620 *
621 * @param cls identification of the client
622 * @param msg the actual message
623 */
624static void
625handle_get(void *cls,
626 const struct GNUNET_W32RESOLVER_GetMessage *msg)
627{
628 struct GNUNET_SERVICE_Client *client = cls;
629 GUID sc;
630 uint16_t size;
631 const wchar_t *hostname;
632 int af;
633
634 size = ntohs(msg->header.size) - sizeof(struct GNUNET_W32RESOLVER_GetMessage);
635 af = ntohl(msg->af);
636 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
637 "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
638 msg->sc_data1,
639 msg->sc_data2,
640 msg->sc_data3,
641 msg->sc_data4[0],
642 msg->sc_data4[1],
643 msg->sc_data4[2],
644 msg->sc_data4[3],
645 msg->sc_data4[4],
646 msg->sc_data4[5],
647 msg->sc_data4[6],
648 msg->sc_data4[7]);
649 sc.Data1 = ntohl(msg->sc_data1);
650 sc.Data2 = ntohs(msg->sc_data2);
651 sc.Data3 = ntohs(msg->sc_data3);
652 for (int i = 0; i < 8; i++)
653 sc.Data4[i] = msg->sc_data4[i];
654 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
655 "Got GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
656 sc.Data1,
657 sc.Data2,
658 sc.Data3,
659 sc.Data4[0],
660 sc.Data4[1],
661 sc.Data4[2],
662 sc.Data4[3],
663 sc.Data4[4],
664 sc.Data4[5],
665 sc.Data4[6],
666 sc.Data4[7]);
667 hostname = (const wchar_t *)&msg[1];
668 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
669 "Name of %u bytes (last word is 0x%0X): %*S\n",
670 size,
671 hostname[size / 2 - 2],
672 size / 2,
673 hostname);
674 get_ip_from_hostname(client,
675 hostname,
676 af,
677 sc);
678}
679
680
681/**
682 * Method called to with the ego we are to use for the lookup,
683 * when the ego is the one for the default master zone.
684 *
685 * @param cls closure (NULL, unused)
686 * @param ego ego handle, NULL if not found
687 * @param ctx context for application to store data for this ego
688 * (during the lifetime of this process, initially NULL)
689 * @param name name assigned by the user for this ego,
690 * NULL if the user just deleted the ego and it
691 * must thus no longer be used
692 */
693static void
694identity_master_cb(void *cls,
695 struct GNUNET_IDENTITY_Ego *ego,
696 void **ctx,
697 const char *name)
698{
699 id_op = NULL;
700 if (NULL == ego)
701 {
702 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
703 _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
704 GNUNET_SCHEDULER_shutdown();
705 return;
706 }
707 GNUNET_IDENTITY_ego_get_public_key(ego,
708 &gns_master_pubkey);
709 got_egos = 1;
710}
711
712
713/**
714 * Start up gns-helper-w32 service.
715 *
716 * @param cls closure
717 * @param cfg configuration to use
718 * @param service the initialized service
719 */
720static void
721run(void *cls,
722 const struct GNUNET_CONFIGURATION_Handle *cfg,
723 struct GNUNET_SERVICE_Handle *service)
724{
725 gns = GNUNET_GNS_connect(cfg);
726 if (NULL == gns)
727 {
728 fprintf(stderr,
729 _("Failed to connect to GNS\n"));
730 GNUNET_SCHEDULER_shutdown();
731 return;
732 }
733 GNUNET_SCHEDULER_add_shutdown(&do_shutdown,
734 NULL);
735 identity = GNUNET_IDENTITY_connect(cfg,
736 NULL,
737 NULL);
738 if (NULL == identity)
739 {
740 fprintf(stderr,
741 _("Failed to connect to identity service\n"));
742 GNUNET_SCHEDULER_shutdown();
743 return;
744 }
745 id_op = GNUNET_IDENTITY_get(identity,
746 "gns-master",
747 &identity_master_cb,
748 NULL);
749 GNUNET_assert(NULL != id_op);
750}
751
752
753/**
754 * Handle client connecting to the service.
755 *
756 * @param cls NULL
757 * @param client the new client
758 * @param mq the message queue of @a client
759 * @return @a client
760 */
761static void *
762client_connect_cb(void *cls,
763 struct GNUNET_SERVICE_Client *client,
764 struct GNUNET_MQ_Handle *mq)
765{
766 return client;
767}
768
769
770/**
771 * Callback called when a client disconnected from the service
772 *
773 * @param cls closure for the service
774 * @param c the client that disconnected
775 * @param internal_cls should be equal to @a c
776 */
777static void
778client_disconnect_cb(void *cls,
779 struct GNUNET_SERVICE_Client *client,
780 void *internal_cls)
781{
782 GNUNET_assert(internal_cls == client);
783}
784
785
786/**
787 * Define "main" method using service macro.
788 */
789GNUNET_SERVICE_MAIN
790 ("gns-helper-service-w32",
791 GNUNET_SERVICE_OPTION_NONE,
792 &run,
793 &client_connect_cb,
794 &client_disconnect_cb,
795 NULL,
796 GNUNET_MQ_hd_var_size(get,
797 GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST,
798 struct GNUNET_W32RESOLVER_GetMessage,
799 NULL),
800 GNUNET_MQ_handler_end());
801
802
803/* end of gnunet-gns-helper-service-w32.c */