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 {
56  struct request *next;
57 
61  struct request *prev;
62 
67 
68  GUID sc;
69 
70  int af;
71 
72  wchar_t *name;
73 
74  char *u8name;
75 
77 };
78 
79 
83 static struct request *rq_head;
84 
88 static struct request *rq_tail;
89 
93 static struct GNUNET_GNS_Handle *gns;
94 
99 
104 
109 
113 static int got_egos;
114 
115 
121 static void
122 do_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)
141  rq_tail,
142  rq);
144  if (rq->u8name)
145  free(rq->u8name);
146  GNUNET_free(rq);
147  }
148  if (NULL != gns)
149  {
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 
161 void
162 MarshallWSAQUERYSETW(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 
195 static void
197  uint32_t rd_count,
198  const struct GNUNET_GNSRECORD_Data *rd)
199 {
200  struct request *rq = cls;
201  int i, j, csanum;
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 
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  {
224  msgend_env);
226  rq_tail,
227  rq);
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  {
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 
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;
351 
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  }
450 
451  if ((char *)ptr - (char *)msg != size || size_recalc != size || size_recalc != ((char *)ptr - (char *)msg))
452  {
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);
461  msg_env);
463  msgend_env);
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 
474 static void
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))
492  else if (IsEqualGUID(&SVCID_DNS_TYPE_SOA, &sc))
494  else if (IsEqualGUID(&SVCID_DNS_TYPE_PTR, &sc))
496  else if (IsEqualGUID(&SVCID_DNS_TYPE_MX, &sc))
497  rtype = GNUNET_DNSPARSER_TYPE_MX;
498  else if (IsEqualGUID(&SVCID_DNS_TYPE_TEXT, &sc))
500  else if (IsEqualGUID(&SVCID_DNS_TYPE_AAAA, &sc))
502  else if (IsEqualGUID(&SVCID_DNS_TYPE_SRV, &sc))
504  else if (IsEqualGUID(&SVCID_INET_HOSTADDRBYNAME, &sc))
505  rtype = GNUNET_DNSPARSER_TYPE_A;
506  else
507  {
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]);
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 
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 
555  "Launching a lookup for client %p with rq %p\n",
556  client,
557  rq);
559  hostname,
561  rtype,
562  GNUNET_NO /* Use DHT */,
564  rq);
565  if (NULL != rq->lookup_request)
566  {
568  "Lookup launched, waiting for a reply\n");
571  rq_tail,
572  rq);
573  }
574  else
575  {
577  "Lookup was not launched, disconnecting the client\n");
579  if (rq->u8name)
580  free(rq->u8name);
581  GNUNET_free(rq);
583  }
584 }
585 
586 
594 static int
595 check_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  {
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 
624 static void
625 handle_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);
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];
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];
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 
693 static void
695  struct GNUNET_IDENTITY_Ego *ego,
696  void **ctx,
697  const char *name)
698 {
699  id_op = NULL;
700  if (NULL == ego)
701  {
703  _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
705  return;
706  }
709  got_egos = 1;
710 }
711 
712 
720 static void
721 run(void *cls,
722  const struct GNUNET_CONFIGURATION_Handle *cfg,
724 {
725  gns = GNUNET_GNS_connect(cfg);
726  if (NULL == gns)
727  {
728  fprintf(stderr,
729  _("Failed to connect to GNS\n"));
731  return;
732  }
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"));
743  return;
744  }
745  id_op = GNUNET_IDENTITY_get(identity,
746  "gns-master",
748  NULL);
749  GNUNET_assert(NULL != id_op);
750 }
751 
752 
761 static void *
764  struct GNUNET_MQ_Handle *mq)
765 {
766  return client;
767 }
768 
769 
777 static void
780  void *internal_cls)
781 {
782  GNUNET_assert(internal_cls == client);
783 }
784 
785 
790  ("gns-helper-service-w32",
792  &run,
795  NULL,
799  NULL),
801 
802 
803 /* 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:525
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:816
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:114
#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:2526
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:1288
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:584
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:519
#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:181
#define GNUNET_DNSPARSER_TYPE_PTR
Handle to a client that is connected to a service.
Definition: service.c:246
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:237
#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:94
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:282
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:835
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:260
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2417
#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:66
#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:566
static struct GNUNET_IDENTITY_Handle * identity
Handle for identity service.
Handle to a message queue.
Definition: mq.c:84
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:83
#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:306
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:57
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:351
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:334
#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:2336
#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.