2 This file is part of GNUnet.
3 Copyright (C) 2012, 2017 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file gnunet-gns-helper-service-w32.c
22 * @brief an intermediary service to access distributed GNS
23 * @author Christian Grothoff
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>
33 #include "gnunet_w32nsp_lib.h"
34 #include "w32resolver.h"
38 #define DEFINE_DNS_GUID(a,x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
39 DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
40 DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
41 DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
42 DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
43 DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
44 DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
45 DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
46 DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
47 DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
48 DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
49 DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
55 * We keep these in a doubly-linked list (for cleanup).
60 * We keep these in a doubly-linked list (for cleanup).
65 * Client that issued the request
67 struct GNUNET_SERVICE_Client *client;
77 struct GNUNET_GNS_LookupRequest *lookup_request;
82 * Head of the doubly-linked list (for cleanup).
84 static struct request *rq_head;
87 * Tail of the doubly-linked list (for cleanup).
89 static struct request *rq_tail;
92 * Handle to GNS service.
94 static struct GNUNET_GNS_Handle *gns;
97 * Active operation on identity service.
99 static struct GNUNET_IDENTITY_Operation *id_op;
102 * Handle for identity service.
104 static struct GNUNET_IDENTITY_Handle *identity;
107 * Public key of the gns-master ego
109 static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey;
112 * Set to 1 once egos are obtained.
118 * Task run on shutdown. Cleans up everything.
123 do_shutdown (void *cls)
129 GNUNET_IDENTITY_cancel (id_op);
132 if (NULL != identity)
134 GNUNET_IDENTITY_disconnect (identity);
137 while (NULL != (rq = rq_head))
139 if (NULL != rq->lookup_request)
140 GNUNET_GNS_lookup_cancel (rq->lookup_request);
141 GNUNET_CONTAINER_DLL_remove (rq_head,
144 GNUNET_free_non_null (rq->name);
151 GNUNET_GNS_disconnect (gns);
158 * Function called to notify a client about the socket
159 * being ready to queue more data. "buf" will be
160 * NULL and "size" zero if the socket was closed for
161 * writing in the meantime.
164 * @param size number of bytes available in buf
165 * @param buf where the callee should write the message
166 * @return number of bytes written to buf
169 transmit_callback (void *cls, size_t size, void *buf)
171 struct TransmitCallbackContext *tcc = cls;
175 GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc);
176 msize = ntohs (tcc->msg->size);
179 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
180 _("Transmission to client failed!\n"));
181 GNUNET_free (tcc->msg);
185 GNUNET_assert (size >= msize);
186 GNUNET_memcpy (buf, tcc->msg, msize);
187 GNUNET_free (tcc->msg);
189 for (tcc = tcc_head; tcc; tcc = tcc->next)
193 tcc->th = GNUNET_SERVER_notify_transmit_ready (tcc->client,
194 ntohs (tcc->msg->size),
195 GNUNET_TIME_UNIT_FOREVER_REL,
196 &transmit_callback, tcc);
205 * Transmit the given message to the client.
207 * @param client target of the message
208 * @param msg message to transmit, will be freed!
211 transmit (struct GNUNET_SERVICE_Client *client,
212 struct GNUNET_MessageHeader *msg)
214 struct GNUNET_MQ_Handle *mq = GNUNET_SERVICE_client_get_mq (client);
215 struct GNUNET_MQ_Envelope *env;
217 /* NOTE: small hack here, should have constructed and
218 passed an 'env' in the first place... */
219 env = GNUNET_MQ_msg_copy (msg);
225 #define MarshallPtr(ptr, base, type) \
227 ptr = (type *) ((char *) ptr - (char *) base)
231 MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc)
233 MarshallPtr (qs->lpszServiceInstanceName, qs, wchar_t);
234 MarshallPtr (qs->lpServiceClassId, qs, GUID);
235 MarshallPtr (qs->lpVersion, qs, WSAVERSION);
236 MarshallPtr (qs->lpNSProviderId, qs, GUID);
237 MarshallPtr (qs->lpszContext, qs, wchar_t);
238 MarshallPtr (qs->lpafpProtocols, qs, AFPROTOCOLS);
239 MarshallPtr (qs->lpszQueryString, qs, wchar_t);
240 for (int i = 0; i < qs->dwNumberOfCsAddrs; i++)
242 MarshallPtr (qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR);
243 MarshallPtr (qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR);
245 MarshallPtr (qs->lpcsaBuffer, qs, CSADDR_INFO);
246 if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL)
250 he = (struct hostent *) qs->lpBlob->pBlobData;
251 for (int i = 0; he->h_aliases[i] != NULL; i++)
252 MarshallPtr (he->h_aliases[i], he, char);
253 MarshallPtr (he->h_aliases, he, char *);
254 MarshallPtr (he->h_name, he, char);
255 for (int i = 0; he->h_addr_list[i] != NULL; i++)
256 MarshallPtr (he->h_addr_list[i], he, void);
257 MarshallPtr (he->h_addr_list, he, char *);
258 MarshallPtr (qs->lpBlob->pBlobData, qs, void);
260 MarshallPtr (qs->lpBlob, qs, BLOB);
265 process_lookup_result (void *cls,
267 const struct GNUNET_GNSRECORD_Data *rd)
269 struct request *rq = cls;
271 struct GNUNET_W32RESOLVER_GetMessage *msg;
272 struct GNUNET_MessageHeader *msgend;
278 size_t blobaddrcount = 0;
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 "Got lookup result with count %u for rq %p with client %p\n",
285 rq->lookup_request = NULL;
289 msg = GNUNET_new (struct GNUNET_MessageHeader);
290 msg->header.size = htons (sizeof (struct GNUNET_MessageHeader));
291 msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
292 transmit (rq->client,
294 GNUNET_CONTAINER_DLL_remove (rq_head,
297 GNUNET_free_non_null (rq->name);
304 size = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW);
305 size += (wcslen (rq->name) + 1) * sizeof (wchar_t);
306 size += sizeof (GUID);
307 /* lpszComment ? a TXT record? */
308 size += sizeof (GUID);
309 /* lpszContext ? Not sure what it is */
311 for (i = 0; i < rd_count; i++)
313 switch (rd[i].record_type)
315 case GNUNET_DNSPARSER_TYPE_A:
316 if (rd[i].data_size != sizeof (struct in_addr))
318 size += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in) * 2;
321 case GNUNET_DNSPARSER_TYPE_AAAA:
322 if (rd[i].data_size != sizeof (struct in6_addr))
324 size += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in6) * 2;
329 if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
331 size += sizeof (BLOB);
332 blobsize += sizeof (struct hostent);
333 blobsize += strlen (rq->u8name) + 1;
334 blobsize += sizeof (void *); /* For aliases */
335 blobsize += sizeof (void *); /* For addresses */
336 for (i = 0; i < rd_count; i++)
338 if ((rq->af == AF_INET || rq->af == AF_UNSPEC) && rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
340 blobsize += sizeof (void *);
341 blobsize += sizeof (struct in_addr);
344 else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA)
346 blobsize += sizeof (void *);
347 blobsize += sizeof (struct in6_addr);
353 size_recalc = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW);
354 msg = GNUNET_malloc (size);
355 msg->header.size = htons (size - sizeof (struct GNUNET_MessageHeader));
356 msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
357 msg->af = htonl (rq->af);
358 msg->sc_data1 = htonl (rq->sc.Data1);
359 msg->sc_data2 = htons (rq->sc.Data2);
360 msg->sc_data3 = htons (rq->sc.Data3);
361 for (i = 0; i < 8; i++)
362 msg->sc_data4[i] = rq->sc.Data4[i];
363 qs = (WSAQUERYSETW *) &msg[1];
364 ptr = (char *) &qs[1];
365 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
366 qs->dwSize = sizeof (WSAQUERYSETW);
367 qs->lpszServiceInstanceName = (wchar_t *) ptr;
368 ptr += (wcslen (rq->name) + 1) * sizeof (wchar_t);
369 size_recalc += (wcslen (rq->name) + 1) * sizeof (wchar_t);
370 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
371 wcscpy (qs->lpszServiceInstanceName, rq->name);
372 qs->lpServiceClassId = (GUID *) ptr;
373 ptr += sizeof (GUID);
374 size_recalc += sizeof (GUID);
375 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
376 GNUNET_memcpy (qs->lpServiceClassId, &rq->sc, sizeof (GUID));
377 qs->lpVersion = NULL;
378 qs->dwNameSpace = NS_DNS;
379 qs->lpNSProviderId = (GUID *) ptr;
380 ptr += sizeof (GUID);
381 size_recalc += sizeof (GUID);
382 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
383 GNUNET_memcpy (qs->lpNSProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS, sizeof (GUID));
384 qs->lpszContext = NULL;
385 qs->dwNumberOfProtocols = 0;
386 qs->lpafpProtocols = NULL;
387 /* Don't bother with this... */
388 qs->lpszQueryString = NULL;
389 qs->dwNumberOfCsAddrs = rd_count;
390 qs->lpcsaBuffer = (CSADDR_INFO *) ptr;
391 ptr += sizeof (CSADDR_INFO) * csanum;
393 for (i = 0; i < rd_count; i++)
395 switch (rd[i].record_type)
397 case GNUNET_DNSPARSER_TYPE_A:
398 if (rd[i].data_size != sizeof (struct in_addr))
400 qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
401 qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
403 qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof (struct sockaddr_in);
404 qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *) ptr;
405 ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
406 memset (qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
407 ((struct sockaddr_in *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin_family = AF_INET;
409 qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof (struct sockaddr_in);
410 qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *) ptr;
411 ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
412 memset (qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
413 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_family = AF_INET;
414 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_port = htonl (53); /* Don't ask why it's 53 */
415 ((struct sockaddr_in *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_addr = *(struct in_addr *) rd[i].data;
416 size_recalc += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in) * 2;
419 case GNUNET_DNSPARSER_TYPE_AAAA:
420 if (rd[i].data_size != sizeof (struct in6_addr))
422 qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
423 qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
425 qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof (struct sockaddr_in6);
426 qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *) ptr;
427 ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
428 memset (qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
429 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin6_family = AF_INET6;
431 qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof (struct sockaddr_in6);
432 qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *) ptr;
433 ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
434 memset (qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
435 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_family = AF_INET6;
436 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_port = htonl (53); /* Don't ask why it's 53 */
437 ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_addr = *(struct in6_addr *) rd[i].data;
438 size_recalc += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in6) * 2;
445 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
446 qs->dwOutputFlags = 0;
447 if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
450 qs->lpBlob = (BLOB *) ptr;
451 ptr += sizeof (BLOB);
453 size_recalc += sizeof (BLOB);
454 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
456 qs->lpBlob->cbSize = blobsize;
457 qs->lpBlob->pBlobData = (BYTE *) ptr;
458 ptr += sizeof (struct hostent);
460 size_recalc += sizeof (struct hostent);
461 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
463 he = (struct hostent *) qs->lpBlob->pBlobData;
464 he->h_name = (char *) ptr;
465 ptr += strlen (rq->u8name) + 1;
467 size_recalc += strlen (rq->u8name) + 1;
468 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
470 strcpy (he->h_name, rq->u8name);
471 he->h_aliases = (char **) ptr;
472 ptr += sizeof (void *);
474 size_recalc += sizeof (void *); /* For aliases */
475 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
477 he->h_aliases[0] = NULL;
478 he->h_addrtype = rq->af;
479 he->h_length = rq->af == AF_INET || rq->af == AF_UNSPEC ? sizeof (struct in_addr) : sizeof (struct in6_addr);
480 he->h_addr_list = (char **) ptr;
481 ptr += sizeof (void *) * (blobaddrcount + 1);
483 size_recalc += sizeof (void *) * (blobaddrcount + 1); /* For addresses */
484 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
487 for (i = 0; i < rd_count; i++)
489 if ((rq->af == AF_INET || rq->af == AF_UNSPEC) &&
490 rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
492 he->h_addr_list[j] = (char *) ptr;
493 ptr += sizeof (struct in_addr);
495 size_recalc += sizeof (struct in_addr);
496 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
498 GNUNET_memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in_addr));
501 else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA)
503 he->h_addr_list[j] = (char *) ptr;
504 ptr += sizeof (struct in6_addr);
506 size_recalc += sizeof (struct in6_addr);
507 GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
509 GNUNET_memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in6_addr));
513 he->h_addr_list[j] = NULL;
515 msgend = GNUNET_new (struct GNUNET_MessageHeader);
517 msgend->type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
518 msgend->size = htons (sizeof (struct GNUNET_MessageHeader));
520 if ((char *) ptr - (char *) msg != size || size_recalc != size || size_recalc != ((char *) ptr - (char *) msg))
522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
523 "Error in WSAQUERYSETW size calc: expected %lu, got %lu (recalc %lu)\n",
525 (unsigned long) ((char *) ptr - (char *) msg),
528 MarshallWSAQUERYSETW (qs, &rq->sc);
529 transmit (rq->client,
531 transmit (rq->client,
533 GNUNET_CONTAINER_DLL_remove (rq_head,
536 GNUNET_free_non_null (rq->name);
544 get_ip_from_hostname (struct GNUNET_SERVICE_Client *client,
555 if (IsEqualGUID (&SVCID_DNS_TYPE_A, &sc))
556 rtype = GNUNET_DNSPARSER_TYPE_A;
557 else if (IsEqualGUID (&SVCID_DNS_TYPE_NS, &sc))
558 rtype = GNUNET_DNSPARSER_TYPE_NS;
559 else if (IsEqualGUID (&SVCID_DNS_TYPE_CNAME, &sc))
560 rtype = GNUNET_DNSPARSER_TYPE_CNAME;
561 else if (IsEqualGUID (&SVCID_DNS_TYPE_SOA, &sc))
562 rtype = GNUNET_DNSPARSER_TYPE_SOA;
563 else if (IsEqualGUID (&SVCID_DNS_TYPE_PTR, &sc))
564 rtype = GNUNET_DNSPARSER_TYPE_PTR;
565 else if (IsEqualGUID (&SVCID_DNS_TYPE_MX, &sc))
566 rtype = GNUNET_DNSPARSER_TYPE_MX;
567 else if (IsEqualGUID (&SVCID_DNS_TYPE_TEXT, &sc))
568 rtype = GNUNET_DNSPARSER_TYPE_TXT;
569 else if (IsEqualGUID (&SVCID_DNS_TYPE_AAAA, &sc))
570 rtype = GNUNET_DNSPARSER_TYPE_AAAA;
571 else if (IsEqualGUID (&SVCID_DNS_TYPE_SRV, &sc))
572 rtype = GNUNET_DNSPARSER_TYPE_SRV;
573 else if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &sc))
574 rtype = GNUNET_DNSPARSER_TYPE_A;
577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
578 "Unknown GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
590 GNUNET_SERVICE_client_drop (client);
595 namelen = wcslen (name);
599 hostname = (char *) u16_to_u8 (name, namelen + 1, NULL, &strl);
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
604 "W32 DNS resolver asked to look up %s for `%s'.\n",
605 af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything",
608 rq = GNUNET_new (struct request);
612 if (rq->af != AF_INET && rq->af != AF_INET6)
616 rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t));
617 GNUNET_memcpy (rq->name,
619 (namelen + 1) * sizeof (wchar_t));
620 rq->u8name = hostname;
623 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
624 "Launching a lookup for client %p with rq %p\n",
627 rq->lookup_request = GNUNET_GNS_lookup (gns,
631 GNUNET_NO /* Use DHT */,
632 &process_lookup_result,
634 if (NULL != rq->lookup_request)
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
637 "Lookup launched, waiting for a reply\n");
638 GNUNET_SERVICE_client_continue (client);
639 GNUNET_CONTAINER_DLL_insert (rq_head,
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
646 "Lookup was not launched, disconnecting the client\n");
647 GNUNET_free_non_null (rq->name);
651 GNUNET_SERVICE_client_drop (client);
659 * @param cls identification of the client
660 * @param msg the actual message
661 * @return #GNUNET_OK if @a msg is well-formed
664 check_get (void *cls,
665 const struct GNUNET_W32RESOLVER_GetMessage *msg)
668 const wchar_t *hostname;
672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673 _("Not ready to process requests, lacking ego data\n"));
674 return GNUNET_SYSERR;
676 size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
677 hostname = (const wchar_t *) &msg[1];
678 if (hostname[size / 2 - 1] != L'\0')
681 return GNUNET_SYSERR;
688 * Handle GET-message.
690 * @param cls identification of the client
691 * @param msg the actual message
694 handle_get (void *cls,
695 const struct GNUNET_W32RESOLVER_GetMessage *msg)
697 struct GNUNET_SERVICE_Client *client = cls;
700 const wchar_t *hostname;
703 size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
704 af = ntohl (msg->af);
705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
706 "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
718 sc.Data1 = ntohl (msg->sc_data1);
719 sc.Data2 = ntohs (msg->sc_data2);
720 sc.Data3 = ntohs (msg->sc_data3);
721 for (int i = 0; i < 8; i++)
722 sc.Data4[i] = msg->sc_data4[i];
723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
724 "Got GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
736 hostname = (const wchar_t *) &msg[1];
737 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
738 "Name of %u bytes (last word is 0x%0X): %*S\n",
740 hostname[size / 2 - 2],
743 get_ip_from_hostname (client,
751 * Method called to with the ego we are to use for the lookup,
752 * when the ego is the one for the default master zone.
754 * @param cls closure (NULL, unused)
755 * @param ego ego handle, NULL if not found
756 * @param ctx context for application to store data for this ego
757 * (during the lifetime of this process, initially NULL)
758 * @param name name assigned by the user for this ego,
759 * NULL if the user just deleted the ego and it
760 * must thus no longer be used
763 identity_master_cb (void *cls,
764 struct GNUNET_IDENTITY_Ego *ego,
771 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
772 _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
773 GNUNET_SCHEDULER_shutdown ();
776 GNUNET_IDENTITY_ego_get_public_key (ego,
783 * Start up gns-helper-w32 service.
786 * @param cfg configuration to use
787 * @param service the initialized service
791 const struct GNUNET_CONFIGURATION_Handle *cfg,
792 struct GNUNET_SERVICE_Handle *service)
794 gns = GNUNET_GNS_connect (cfg);
798 _("Failed to connect to GNS\n"));
799 GNUNET_SCHEDULER_shutdown ();
802 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
804 identity = GNUNET_IDENTITY_connect (cfg,
807 if (NULL == identity)
810 _("Failed to connect to identity service\n"));
811 GNUNET_SCHEDULER_shutdown ();
814 id_op = GNUNET_IDENTITY_get (identity,
818 GNUNET_assert (NULL != id_op);
823 * Handle client connecting to the service.
826 * @param client the new client
827 * @param mq the message queue of @a client
831 client_connect_cb (void *cls,
832 struct GNUNET_SERVICE_Client *client,
833 struct GNUNET_MQ_Handle *mq)
840 * Callback called when a client disconnected from the service
842 * @param cls closure for the service
843 * @param c the client that disconnected
844 * @param internal_cls should be equal to @a c
847 client_disconnect_cb (void *cls,
848 struct GNUNET_SERVICE_Client *client,
851 GNUNET_assert (internal_cls == client);
856 * Define "main" method using service macro.
859 ("gns-helper-service-w32",
860 GNUNET_SERVICE_OPTION_NONE,
863 &client_disconnect_cb,
865 GNUNET_MQ_hd_var_size (get,
866 GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST,
867 struct GNUNET_W32RESOLVER_GetMessage,
869 GNUNET_MQ_handler_end());
872 /* end of gnunet-gns-helper-service-w32.c */