GNUnet  0.10.x
gnunet-gns-helper-service-w32.c
Go to the documentation of this file.
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 */
26 #include "platform.h"
27 #include <gnunet_util_lib.h>
29 #include <gnunet_dnsparser_lib.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)
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);
50 
51 
52 struct request
53 {
57  struct request *next;
58 
62  struct request *prev;
63 
68 
69  GUID sc;
70 
71  int af;
72 
73  wchar_t *name;
74 
75  char *u8name;
76 
78 };
79 
80 
84 static struct request *rq_head;
85 
89 static struct request *rq_tail;
90 
94 static struct GNUNET_GNS_Handle *gns;
95 
100 
105 
110 
114 static int got_egos;
115 
116 
122 static void
123 do_shutdown (void *cls)
124 {
125  struct request *rq;
126 
127  if (NULL != id_op)
128  {
129  GNUNET_IDENTITY_cancel (id_op);
130  id_op = NULL;
131  }
132  if (NULL != identity)
133  {
134  GNUNET_IDENTITY_disconnect (identity);
135  identity = NULL;
136  }
137  while (NULL != (rq = rq_head))
138  {
139  if (NULL != rq->lookup_request)
142  rq_tail,
143  rq);
145  if (rq->u8name)
146  free (rq->u8name);
147  GNUNET_free (rq);
148  }
149  if (NULL != gns)
150  {
151  GNUNET_GNS_disconnect (gns);
152  gns = NULL;
153  }
154 }
155 
156 
157 #define MarshallPtr(ptr, base, type) \
158  if (ptr) \
159  ptr = (type *) ((char *) ptr - (char *) base)
160 
161 
162 void
163 MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc)
164 {
165  MarshallPtr (qs->lpszServiceInstanceName, qs, wchar_t);
166  MarshallPtr (qs->lpServiceClassId, qs, GUID);
167  MarshallPtr (qs->lpVersion, qs, WSAVERSION);
168  MarshallPtr (qs->lpNSProviderId, qs, GUID);
169  MarshallPtr (qs->lpszContext, qs, wchar_t);
170  MarshallPtr (qs->lpafpProtocols, qs, AFPROTOCOLS);
171  MarshallPtr (qs->lpszQueryString, qs, wchar_t);
172  for (int i = 0; i < qs->dwNumberOfCsAddrs; i++)
173  {
174  MarshallPtr (qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR);
175  MarshallPtr (qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR);
176  }
177  MarshallPtr (qs->lpcsaBuffer, qs, CSADDR_INFO);
178  if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL)
179  {
180  struct hostent *he;
181 
182  he = (struct hostent *) qs->lpBlob->pBlobData;
183  for (int i = 0; he->h_aliases[i] != NULL; i++)
184  MarshallPtr (he->h_aliases[i], he, char);
185  MarshallPtr (he->h_aliases, he, char *);
186  MarshallPtr (he->h_name, he, char);
187  for (int i = 0; he->h_addr_list[i] != NULL; i++)
188  MarshallPtr (he->h_addr_list[i], he, void);
189  MarshallPtr (he->h_addr_list, he, char *);
190  MarshallPtr (qs->lpBlob->pBlobData, qs, void);
191  }
192  MarshallPtr (qs->lpBlob, qs, BLOB);
193 }
194 
195 
196 static void
198  uint32_t rd_count,
199  const struct GNUNET_GNSRECORD_Data *rd)
200 {
201  struct request *rq = cls;
202  int i, j, csanum;
204  struct GNUNET_MQ_Envelope *msg_env;
205  struct GNUNET_MessageHeader *msgend;
206  struct GNUNET_MQ_Envelope *msgend_env;
207  WSAQUERYSETW *qs;
208  size_t size;
209  size_t size_recalc;
210  char *ptr;
211  size_t blobsize = 0;
212  size_t blobaddrcount = 0;
213 
215  "Got lookup result with count %u for rq %p with client %p\n",
216  rd_count,
217  rq,
218  rq->client);
219  rq->lookup_request = NULL;
220 
221  if (0 == rd_count)
222  {
225  msgend_env);
227  rq_tail,
228  rq);
230  if (rq->u8name)
231  free (rq->u8name);
232  GNUNET_free (rq);
233  return;
234  }
235 
236  size = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW);
237  size += (wcslen (rq->name) + 1) * sizeof (wchar_t);
238  size += sizeof (GUID);
239  /* lpszComment ? a TXT record? */
240  size += sizeof (GUID);
241  /* lpszContext ? Not sure what it is */
242  csanum = 0;
243  for (i = 0; i < rd_count; i++)
244  {
245  switch (rd[i].record_type)
246  {
248  if (rd[i].data_size != sizeof (struct in_addr))
249  continue;
250  size += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in) * 2;
251  csanum++;
252  break;
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),
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  {
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;
352  if (rd[i].data_size != sizeof (struct in6_addr))
353  continue;
354  qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
355  qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
356 
357  qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof (struct sockaddr_in6);
358  qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *) ptr;
359  ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
360  memset (qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
361  ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin6_family = AF_INET6;
362 
363  qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof (struct sockaddr_in6);
364  qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *) ptr;
365  ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
366  memset (qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
367  ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_family = AF_INET6;
368  ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_port = htonl (53); /* Don't ask why it's 53 */
369  ((struct sockaddr_in6 *)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_addr = *(struct in6_addr *) rd[i].data;
370  size_recalc += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in6) * 2;
371  j++;
372  break;
373  default:
374  break;
375  }
376  }
377  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
378  qs->dwOutputFlags = 0;
379  if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
380  {
381  struct hostent *he;
382  qs->lpBlob = (BLOB *) ptr;
383  ptr += sizeof (BLOB);
384 
385  size_recalc += sizeof (BLOB);
386  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
387 
388  qs->lpBlob->cbSize = blobsize;
389  qs->lpBlob->pBlobData = (BYTE *) ptr;
390  ptr += sizeof (struct hostent);
391 
392  size_recalc += sizeof (struct hostent);
393  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
394 
395  he = (struct hostent *) qs->lpBlob->pBlobData;
396  he->h_name = (char *) ptr;
397  ptr += strlen (rq->u8name) + 1;
398 
399  size_recalc += strlen (rq->u8name) + 1;
400  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
401 
402  strcpy (he->h_name, rq->u8name);
403  he->h_aliases = (char **) ptr;
404  ptr += sizeof (void *);
405 
406  size_recalc += sizeof (void *); /* For aliases */
407  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
408 
409  he->h_aliases[0] = NULL;
410  he->h_addrtype = rq->af;
411  he->h_length = rq->af == AF_INET || rq->af == AF_UNSPEC ? sizeof (struct in_addr) : sizeof (struct in6_addr);
412  he->h_addr_list = (char **) ptr;
413  ptr += sizeof (void *) * (blobaddrcount + 1);
414 
415  size_recalc += sizeof (void *) * (blobaddrcount + 1); /* For addresses */
416  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
417 
418  j = 0;
419  for (i = 0; i < rd_count; i++)
420  {
421  if ((rq->af == AF_INET || rq->af == AF_UNSPEC) &&
422  rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
423  {
424  he->h_addr_list[j] = (char *) ptr;
425  ptr += sizeof (struct in_addr);
426 
427  size_recalc += sizeof (struct in_addr);
428  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
429 
430  GNUNET_memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in_addr));
431  j++;
432  }
433  else if (rq->af == AF_INET6 && rd[i].record_type == GNUNET_DNSPARSER_TYPE_AAAA)
434  {
435  he->h_addr_list[j] = (char *) ptr;
436  ptr += sizeof (struct in6_addr);
437 
438  size_recalc += sizeof (struct in6_addr);
439  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
440 
441  GNUNET_memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in6_addr));
442  j++;
443  }
444  }
445  he->h_addr_list[j] = NULL;
446  }
448 
449  if ((char *) ptr - (char *) msg != size || size_recalc != size || size_recalc != ((char *) ptr - (char *) msg))
450  {
452  "Error in WSAQUERYSETW size calc: expected %u, got %lu (recalc %u)\n",
453  size,
454  (unsigned long) ((char *) ptr - (char *) msg),
455  size_recalc);
456  }
457  MarshallWSAQUERYSETW (qs, &rq->sc);
459  msg_env);
461  msgend_env);
463  rq_tail,
464  rq);
465  GNUNET_free_non_null (rq->name);
466  if (rq->u8name)
467  free (rq->u8name);
468  GNUNET_free (rq);
469 }
470 
471 
472 static void
474  const wchar_t *name,
475  int af,
476  GUID sc)
477 {
478  struct request *rq;
479  char *hostname;
480  size_t strl;
481  size_t namelen;
482  uint32_t rtype;
483 
484  if (IsEqualGUID (&SVCID_DNS_TYPE_A, &sc))
485  rtype = GNUNET_DNSPARSER_TYPE_A;
486  else if (IsEqualGUID (&SVCID_DNS_TYPE_NS, &sc))
487  rtype = GNUNET_DNSPARSER_TYPE_NS;
488  else if (IsEqualGUID (&SVCID_DNS_TYPE_CNAME, &sc))
490  else if (IsEqualGUID (&SVCID_DNS_TYPE_SOA, &sc))
492  else if (IsEqualGUID (&SVCID_DNS_TYPE_PTR, &sc))
494  else if (IsEqualGUID (&SVCID_DNS_TYPE_MX, &sc))
495  rtype = GNUNET_DNSPARSER_TYPE_MX;
496  else if (IsEqualGUID (&SVCID_DNS_TYPE_TEXT, &sc))
498  else if (IsEqualGUID (&SVCID_DNS_TYPE_AAAA, &sc))
500  else if (IsEqualGUID (&SVCID_DNS_TYPE_SRV, &sc))
502  else if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &sc))
503  rtype = GNUNET_DNSPARSER_TYPE_A;
504  else
505  {
507  "Unknown GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
508  sc.Data1,
509  sc.Data2,
510  sc.Data3,
511  sc.Data4[0],
512  sc.Data4[1],
513  sc.Data4[2],
514  sc.Data4[3],
515  sc.Data4[4],
516  sc.Data4[5],
517  sc.Data4[6],
518  sc.Data4[7]);
520  return;
521  }
522 
523  if (name)
524  namelen = wcslen (name);
525  else
526  namelen = 0;
527  if (namelen > 0)
528  hostname = (char *) u16_to_u8 (name, namelen + 1, NULL, &strl);
529  else
530  hostname = NULL;
531 
533  "W32 DNS resolver asked to look up %s for `%s'.\n",
534  af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything",
535  hostname);
536 
537  rq = GNUNET_new (struct request);
538  rq->sc = sc;
539  rq->client = client;
540  rq->af = af;
541  if (rq->af != AF_INET && rq->af != AF_INET6)
542  rq->af = AF_INET;
543  if (namelen)
544  {
545  rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t));
546  GNUNET_memcpy (rq->name,
547  name,
548  (namelen + 1) * sizeof (wchar_t));
549  rq->u8name = hostname;
550  }
551 
553  "Launching a lookup for client %p with rq %p\n",
554  client,
555  rq);
557  hostname,
559  rtype,
560  GNUNET_NO /* Use DHT */,
562  rq);
563  if (NULL != rq->lookup_request)
564  {
566  "Lookup launched, waiting for a reply\n");
569  rq_tail,
570  rq);
571  }
572  else
573  {
575  "Lookup was not launched, disconnecting the client\n");
577  if (rq->u8name)
578  free (rq->u8name);
579  GNUNET_free (rq);
581  }
582 }
583 
584 
592 static int
593 check_get (void *cls,
594  const struct GNUNET_W32RESOLVER_GetMessage *msg)
595 {
596  uint16_t size;
597  const wchar_t *hostname;
598 
599  if (! got_egos)
600  {
602  _("Not ready to process requests, lacking ego data\n"));
603  return GNUNET_SYSERR;
604  }
605  size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
606  hostname = (const wchar_t *) &msg[1];
607  if (hostname[size / 2 - 1] != L'\0')
608  {
609  GNUNET_break (0);
610  return GNUNET_SYSERR;
611  }
612  return GNUNET_OK;
613 }
614 
615 
622 static void
623 handle_get (void *cls,
624  const struct GNUNET_W32RESOLVER_GetMessage *msg)
625 {
626  struct GNUNET_SERVICE_Client *client = cls;
627  GUID sc;
628  uint16_t size;
629  const wchar_t *hostname;
630  int af;
631 
632  size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
633  af = ntohl (msg->af);
635  "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
636  msg->sc_data1,
637  msg->sc_data2,
638  msg->sc_data3,
639  msg->sc_data4[0],
640  msg->sc_data4[1],
641  msg->sc_data4[2],
642  msg->sc_data4[3],
643  msg->sc_data4[4],
644  msg->sc_data4[5],
645  msg->sc_data4[6],
646  msg->sc_data4[7]);
647  sc.Data1 = ntohl (msg->sc_data1);
648  sc.Data2 = ntohs (msg->sc_data2);
649  sc.Data3 = ntohs (msg->sc_data3);
650  for (int i = 0; i < 8; i++)
651  sc.Data4[i] = msg->sc_data4[i];
653  "Got GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
654  sc.Data1,
655  sc.Data2,
656  sc.Data3,
657  sc.Data4[0],
658  sc.Data4[1],
659  sc.Data4[2],
660  sc.Data4[3],
661  sc.Data4[4],
662  sc.Data4[5],
663  sc.Data4[6],
664  sc.Data4[7]);
665  hostname = (const wchar_t *) &msg[1];
667  "Name of %u bytes (last word is 0x%0X): %*S\n",
668  size,
669  hostname[size / 2 - 2],
670  size / 2,
671  hostname);
672  get_ip_from_hostname (client,
673  hostname,
674  af,
675  sc);
676 }
677 
678 
691 static void
693  struct GNUNET_IDENTITY_Ego *ego,
694  void **ctx,
695  const char *name)
696 {
697  id_op = NULL;
698  if (NULL == ego)
699  {
701  _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
703  return;
704  }
707  got_egos = 1;
708 }
709 
710 
718 static void
719 run (void *cls,
720  const struct GNUNET_CONFIGURATION_Handle *cfg,
722 {
723  gns = GNUNET_GNS_connect (cfg);
724  if (NULL == gns)
725  {
726  fprintf (stderr,
727  _("Failed to connect to GNS\n"));
729  return;
730  }
732  NULL);
733  identity = GNUNET_IDENTITY_connect (cfg,
734  NULL,
735  NULL);
736  if (NULL == identity)
737  {
738  fprintf (stderr,
739  _("Failed to connect to identity service\n"));
741  return;
742  }
743  id_op = GNUNET_IDENTITY_get (identity,
744  "gns-master",
746  NULL);
747  GNUNET_assert (NULL != id_op);
748 }
749 
750 
759 static void *
760 client_connect_cb (void *cls,
762  struct GNUNET_MQ_Handle *mq)
763 {
764  return client;
765 }
766 
767 
775 static void
778  void *internal_cls)
779 {
780  GNUNET_assert (internal_cls == client);
781 }
782 
783 
788 ("gns-helper-service-w32",
790  &run,
793  NULL,
797  NULL),
799 
800 
801 /* end of gnunet-gns-helper-service-w32.c */
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:528
static struct request * rq_tail
Tail of the doubly-linked list (for cleanup).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Connection to the GNS service.
Definition: gns_api.h:35
static void identity_master_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Method called to with the ego we are to use for the lookup, when the ego is the one for the default m...
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
Definition: identity_api.c:819
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Handle client connecting to the service.
Handle to a service.
Definition: service.c:116
#define GNUNET_DNSPARSER_TYPE_CNAME
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
DEFINE_GUID(SVCID_DNS_TYPE_A, 0x00090035, 0x0000, 0x0001, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Handle to a lookup request.
Definition: gns_api.c:42
static struct GNUNET_IDENTITY_Operation * id_op
Active operation on identity service.
static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey
Public key of the gns-master ego.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_get(struct GNUNET_IDENTITY_Handle *h, const char *service_name, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Obtain the identity that is currently preferred/default for a service.
Definition: identity_api.c:587
static void get_ip_from_hostname(struct GNUNET_SERVICE_Client *client, const wchar_t *name, int af, GUID sc)
static int got_egos
Set to 1 once egos are obtained.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void MarshallWSAQUERYSETW(WSAQUERYSETW *qs, GUID *sc)
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
#define GNUNET_DNSPARSER_TYPE_MX
static void process_lookup_result(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle for an operation with the identity service.
Definition: identity_api.c:39
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define GNUNET_DNSPARSER_TYPE_PTR
Handle to a client that is connected to a service.
Definition: service.c:249
struct request * next
We keep these in a doubly-linked list (for cleanup).
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
Callback called when a client disconnected from the service.
#define DEFINE_DNS_GUID(a, x)
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Handle for an ego.
Definition: identity.h:245
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_memcpy(dst, src, n)
const void * data
Binary value stored in the DNS record.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
Handle for the service.
Definition: identity_api.c:96
Request for the resolver.
Definition: w32resolver.h:53
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:285
static struct request * rq_head
Head of the doubly-linked list (for cleanup).
struct GNUNET_SERVICE_Client * client
Client that issued the request.
struct request * prev
We keep these in a doubly-linked list (for cleanup).
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:838
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:263
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST
Request DNS resolution.
Definition: w32resolver.h:35
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Start up gns-helper-w32 service.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
static void do_shutdown(void *cls)
Task run on shutdown.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define GNUNET_DNSPARSER_TYPE_TXT
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:569
static struct GNUNET_IDENTITY_Handle * identity
Handle for identity service.
Handle to a message queue.
Definition: mq.c:85
static int check_get(void *cls, const struct GNUNET_W32RESOLVER_GetMessage *msg)
Check GET-message.
#define MarshallPtr(ptr, base, type)
static char * hostname
Our hostname; we give this to all the peers we start.
uint32_t record_type
Type of the GNS/DNS record.
#define GNUNET_DNSPARSER_TYPE_AAAA
configuration data
Definition: configuration.c:85
#define GNUNET_DNSPARSER_TYPE_NS
GNUNET_SERVICE_MAIN("gns-helper-service-w32", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(get, 4, struct GNUNET_W32RESOLVER_GetMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:309
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:58
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct GNUNET_GNS_LookupRequest * lookup_request
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE
Response to a DNS resolution request.
Definition: w32resolver.h:40
static struct GNUNET_GNS_Handle * gns
Handle to GNS service.
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:337
#define GNUNET_DNSPARSER_TYPE_SRV
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
static uint32_t rtype
Desired record type.
Definition: gnunet-gns.c:60
#define GNUNET_DNSPARSER_TYPE_A
static void handle_get(void *cls, const struct GNUNET_W32RESOLVER_GetMessage *msg)
Handle GET-message.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.