GNUnet  0.11.x
dnsstub.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2018 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  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 
31 #define DNS_RETRANSMIT_DELAY \
32  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
33 
34 
38 struct DnsServer;
39 
40 
45 {
50 
55 
60 
64  void *rc_cls;
65 
70 
75 
79  struct DnsServer *ds_pos;
80 
85 
89  void *request;
90 
94  size_t request_len;
95 };
96 
97 
101 struct DnsServer
102 {
106  struct DnsServer *next;
107 
111  struct DnsServer *prev;
112 
116  struct sockaddr_storage ss;
117 };
118 
119 
124 {
129 
134 
139 
143  struct GNUNET_TIME_Relative retry_freq;
144 
148  unsigned int num_sockets;
149 };
150 
151 
157 static void
159 {
160  if (NULL != rs->dnsout4)
161  {
163  rs->dnsout4 = NULL;
164  }
165  if (NULL != rs->dnsout6)
166  {
168  rs->dnsout6 = NULL;
169  }
170  if (NULL != rs->read_task)
171  {
173  rs->read_task = NULL;
174  }
175  if (NULL != rs->retry_task)
176  {
178  rs->retry_task = NULL;
179  }
180  if (NULL != rs->request)
181  {
182  GNUNET_free (rs->request);
183  rs->request = NULL;
184  }
185 }
186 
187 
194 static struct GNUNET_NETWORK_Handle *
196 {
197  struct sockaddr_in a4;
198  struct sockaddr_in6 a6;
199  struct sockaddr *sa;
200  socklen_t alen;
201  struct GNUNET_NETWORK_Handle *ret;
202 
203  ret = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, 0);
204  if (NULL == ret)
205  return NULL;
206  switch (af)
207  {
208  case AF_INET:
209  memset (&a4, 0, alen = sizeof(struct sockaddr_in));
210  sa = (struct sockaddr *) &a4;
211  break;
212 
213  case AF_INET6:
214  memset (&a6, 0, alen = sizeof(struct sockaddr_in6));
215  sa = (struct sockaddr *) &a6;
216  break;
217 
218  default:
219  GNUNET_break (0);
221  return NULL;
222  }
223  sa->sa_family = af;
224  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret, sa, alen))
225  {
227  _ ("Could not bind to any port: %s\n"),
228  strerror (errno));
230  return NULL;
231  }
232  return ret;
233 }
234 
235 
243 static struct GNUNET_DNSSTUB_RequestSocket *
245 {
246  struct GNUNET_DNSSTUB_RequestSocket *rs;
247 
248  for (unsigned int i = 0; i < 256; i++)
249  {
251  ctx->num_sockets)];
252  if (NULL == rs->rc)
253  break;
254  }
255  if (NULL != rs->rc)
256  {
257  /* signal "failure" */
258  rs->rc (rs->rc_cls, NULL, 0);
259  rs->rc = NULL;
260  }
261  if (NULL != rs->read_task)
262  {
264  rs->read_task = NULL;
265  }
266  if (NULL != rs->retry_task)
267  {
269  rs->retry_task = NULL;
270  }
271  if (NULL != rs->request)
272  {
273  GNUNET_free (rs->request);
274  rs->request = NULL;
275  }
276  rs->ctx = ctx;
277  return rs;
278 }
279 
280 
289 static int
291  struct GNUNET_NETWORK_Handle *dnsout)
292 {
293  struct GNUNET_DNSSTUB_Context *ctx = rs->ctx;
294  ssize_t r;
295  int len;
296 
297  if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len))
298  {
299  /* conservative choice: */
300  len = UINT16_MAX;
301  }
302 
303  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving %d byte DNS reply\n", len);
304  {
305  unsigned char buf[len] GNUNET_ALIGN;
306  int found;
307  struct sockaddr_storage addr;
308  socklen_t addrlen;
309  struct GNUNET_TUN_DnsHeader *dns;
310 
311  addrlen = sizeof(addr);
312  memset (&addr, 0, sizeof(addr));
313  r = GNUNET_NETWORK_socket_recvfrom (dnsout,
314  buf,
315  sizeof(buf),
316  (struct sockaddr *) &addr,
317  &addrlen);
318  if (-1 == r)
319  {
322  return GNUNET_SYSERR;
323  }
324  found = GNUNET_NO;
325  for (struct DnsServer *ds = ctx->dns_head; NULL != ds; ds = ds->next)
326  {
327  if (0 == memcmp (&addr,
328  &ds->ss,
329  GNUNET_MIN (sizeof(struct sockaddr_storage), addrlen)))
330  {
331  found = GNUNET_YES;
332  break;
333  }
334  }
335  if (GNUNET_NO == found)
336  {
338  "Received DNS response from server we never asked (ignored)");
339  return GNUNET_NO;
340  }
341  if (sizeof(struct GNUNET_TUN_DnsHeader) > (size_t) r)
342  {
344  _ ("Received DNS response that is too small (%u bytes)"),
345  (unsigned int) r);
346  return GNUNET_NO;
347  }
348  dns = (struct GNUNET_TUN_DnsHeader *) buf;
349  if (NULL == rs->rc)
350  {
352  "Request timeout or cancelled; ignoring reply\n");
353  return GNUNET_NO;
354  }
355  rs->rc (rs->rc_cls, dns, r);
356  }
357  return GNUNET_OK;
358 }
359 
360 
366 static void
367 read_response (void *cls);
368 
369 
375 static void
377 {
378  struct GNUNET_NETWORK_FDSet *rset;
379 
380  if (NULL != rs->read_task)
382  rset = GNUNET_NETWORK_fdset_create ();
383  if (NULL != rs->dnsout4)
384  GNUNET_NETWORK_fdset_set (rset, rs->dnsout4);
385  if (NULL != rs->dnsout6)
386  GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
387  rs->read_task =
390  rset,
391  NULL,
392  &read_response,
393  rs);
395 }
396 
397 
403 static void
404 read_response (void *cls)
405 {
406  struct GNUNET_DNSSTUB_RequestSocket *rs = cls;
407  const struct GNUNET_SCHEDULER_TaskContext *tc;
408 
409  rs->read_task = NULL;
411  /* read and process ready sockets */
412  if ((NULL != rs->dnsout4) &&
414  (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout4)))
415  rs->dnsout4 = NULL;
416  if ((NULL != rs->dnsout6) &&
418  (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout6)))
419  rs->dnsout6 = NULL;
420  /* re-schedule read task */
421  schedule_read (rs);
422 }
423 
424 
431 static void
432 transmit_query (void *cls)
433 {
434  struct GNUNET_DNSSTUB_RequestSocket *rs = cls;
435  struct GNUNET_DNSSTUB_Context *ctx = rs->ctx;
436  const struct sockaddr *sa;
437  socklen_t salen;
438  struct DnsServer *ds;
439  struct GNUNET_NETWORK_Handle *dnsout;
440 
441  rs->retry_task =
443  ds = rs->ds_pos;
444  rs->ds_pos = ds->next;
445  if (NULL == rs->ds_pos)
446  rs->ds_pos = ctx->dns_head;
447  GNUNET_assert (NULL != ds);
448  dnsout = NULL;
449  switch (ds->ss.ss_family)
450  {
451  case AF_INET:
452  if (NULL == rs->dnsout4)
453  rs->dnsout4 = open_socket (AF_INET);
454  dnsout = rs->dnsout4;
455  sa = (const struct sockaddr *) &ds->ss;
456  salen = sizeof(struct sockaddr_in);
457  break;
458 
459  case AF_INET6:
460  if (NULL == rs->dnsout6)
461  rs->dnsout6 = open_socket (AF_INET6);
462  dnsout = rs->dnsout6;
463  sa = (const struct sockaddr *) &ds->ss;
464  salen = sizeof(struct sockaddr_in6);
465  break;
466 
467  default:
468  return;
469  }
470  if (NULL == dnsout)
471  {
473  "Unable to use configure DNS server, skipping\n");
474  return;
475  }
477  rs->request,
478  rs->request_len,
479  sa,
480  salen))
482  _ ("Failed to send DNS request to %s: %s\n"),
483  GNUNET_a2s (sa, salen),
484  strerror (errno));
485  else
487  _ ("Sent DNS request to %s\n"),
488  GNUNET_a2s (sa, salen));
489  schedule_read (rs);
490 }
491 
492 
505  const void *request,
506  size_t request_len,
508  void *rc_cls)
509 {
510  struct GNUNET_DNSSTUB_RequestSocket *rs;
511 
512  if (NULL == ctx->dns_head)
513  {
515  "No DNS server configured for resolution\n");
516  return NULL;
517  }
518  if (NULL == (rs = get_request_socket (ctx)))
519  {
521  "No request socket available for DNS resolution\n");
522  return NULL;
523  }
524  rs->ds_pos = ctx->dns_head;
525  rs->rc = rc;
526  rs->rc_cls = rc_cls;
527  rs->request = GNUNET_memdup (request, request_len);
528  rs->request_len = request_len;
530  return rs;
531 }
532 
533 
539 void
541 {
542  rs->rc = NULL;
543  if (NULL != rs->retry_task)
544  {
546  rs->retry_task = NULL;
547  }
548  if (NULL != rs->read_task)
549  {
551  rs->read_task = NULL;
552  }
553 }
554 
555 
563 struct GNUNET_DNSSTUB_Context *
565 {
566  struct GNUNET_DNSSTUB_Context *ctx;
567 
568  if (0 == num_sockets)
569  {
570  GNUNET_break (0);
571  return NULL;
572  }
573  ctx = GNUNET_new (struct GNUNET_DNSSTUB_Context);
574  ctx->num_sockets = num_sockets;
575  ctx->sockets =
576  GNUNET_new_array (num_sockets, struct GNUNET_DNSSTUB_RequestSocket);
578  return ctx;
579 }
580 
581 
590 int
592  const char *dns_ip)
593 {
594  struct DnsServer *ds;
595  struct in_addr i4;
596  struct in6_addr i6;
597 
598  ds = GNUNET_new (struct DnsServer);
599  if (1 == inet_pton (AF_INET, dns_ip, &i4))
600  {
601  struct sockaddr_in *s4 = (struct sockaddr_in *) &ds->ss;
602 
603  s4->sin_family = AF_INET;
604  s4->sin_port = htons (53);
605  s4->sin_addr = i4;
606 #if HAVE_SOCKADDR_IN_SIN_LEN
607  s4->sin_len = (u_char) sizeof(struct sockaddr_in);
608 #endif
609  }
610  else if (1 == inet_pton (AF_INET6, dns_ip, &i6))
611  {
612  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &ds->ss;
613 
614  s6->sin6_family = AF_INET6;
615  s6->sin6_port = htons (53);
616  s6->sin6_addr = i6;
617 #if HAVE_SOCKADDR_IN_SIN_LEN
618  s6->sin6_len = (u_char) sizeof(struct sockaddr_in6);
619 #endif
620  }
621  else
622  {
624  "Malformed IP address `%s' for DNS server\n",
625  dns_ip);
626  GNUNET_free (ds);
627  return GNUNET_SYSERR;
628  }
630  return GNUNET_OK;
631 }
632 
633 
642 int
644  const struct sockaddr *sa)
645 {
646  struct DnsServer *ds;
647 
648  ds = GNUNET_new (struct DnsServer);
649  switch (sa->sa_family)
650  {
651  case AF_INET:
652  GNUNET_memcpy (&ds->ss, sa, sizeof(struct sockaddr_in));
653  break;
654 
655  case AF_INET6:
656  GNUNET_memcpy (&ds->ss, sa, sizeof(struct sockaddr_in6));
657  break;
658 
659  default:
660  GNUNET_break (0);
661  GNUNET_free (ds);
662  return GNUNET_SYSERR;
663  }
665  return GNUNET_OK;
666 }
667 
668 
676 void
678  struct GNUNET_TIME_Relative retry_freq)
679 {
680  ctx->retry_freq = retry_freq;
681 }
682 
683 
689 void
691 {
692  struct DnsServer *ds;
693 
694  while (NULL != (ds = ctx->dns_head))
695  {
697  GNUNET_free (ds);
698  }
699  for (unsigned int i = 0; i < ctx->num_sockets; i++)
700  cleanup_rs (&ctx->sockets[i]);
701  GNUNET_free (ctx->sockets);
702  GNUNET_free (ctx);
703 }
704 
705 
706 /* end of dnsstub.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:747
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1080
struct GNUNET_SCHEDULER_Task * read_task
Task for reading from dnsout4 and dnsout6.
Definition: dnsstub.c:69
struct DnsServer * prev
Kept in a DLL.
Definition: dnsstub.c:111
void GNUNET_DNSSTUB_set_retry(struct GNUNET_DNSSTUB_Context *ctx, struct GNUNET_TIME_Relative retry_freq)
How long should we try requests before timing out? Only effective for requests issued after this call...
Definition: dnsstub.c:677
struct GNUNET_NETWORK_Handle * dnsout6
UDP socket we use for this request for IPv6.
Definition: dnsstub.c:54
void(* GNUNET_DNSSTUB_ResultCallback)(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t dns_len)
Function called with the result of a DNS resolution.
struct DnsServer * dns_head
DLL of DNS resolvers we use.
Definition: dnsstub.c:133
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static void transmit_query(void *cls)
Task to (re)transmit the DNS query, possibly repeatedly until we succeed.
Definition: dnsstub.c:432
Context information passed to each scheduler task.
static char * dns_ip
IP of DNS server.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:690
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:418
GNUNET_DNSSTUB_ResultCallback rc
Function to call with result.
Definition: dnsstub.c:59
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:591
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:485
#define DNS_RETRANSMIT_DELAY
Timeout for retrying DNS queries.
Definition: dnsstub.c:31
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
void * request
Query we sent to addr.
Definition: dnsstub.c:89
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
size_t request_len
Number of bytes in request.
Definition: dnsstub.c:94
struct sockaddr_storage ss
IP address of the DNS resolver.
Definition: dnsstub.c:116
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_DNSSTUB_Context * ctx
Context this request executes in.
Definition: dnsstub.c:84
struct DnsServer * next
Kept in a DLL.
Definition: dnsstub.c:106
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1266
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static void read_response(void *cls)
Read a DNS response from the (unhindered) UDP-Socket.
Definition: dnsstub.c:404
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1250
unsigned int num_sockets
Length of sockets array.
Definition: dnsstub.c:148
struct DnsServer * ds_pos
Next address we sent the DNS request to.
Definition: dnsstub.c:79
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:564
static struct GNUNET_NETWORK_Handle * open_socket(int af)
Open source port for sending DNS requests.
Definition: dnsstub.c:195
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
DNS Server used for resolution.
Definition: dnsstub.c:101
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
struct DnsServer * dns_tail
DLL of DNS resolvers we use.
Definition: dnsstub.c:138
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:850
Randomness for IVs etc.
collection of IO descriptors
static char buf[2048]
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1810
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
struct GNUNET_DNSSTUB_RequestSocket * sockets
Array of all open sockets for DNS requests.
Definition: dnsstub.c:128
static struct GNUNET_DNSSTUB_RequestSocket * get_request_socket(struct GNUNET_DNSSTUB_Context *ctx)
Get a socket of the specified address family to send out a UDP DNS request to the Internet...
Definition: dnsstub.c:244
static int do_dns_read(struct GNUNET_DNSSTUB_RequestSocket *rs, struct GNUNET_NETWORK_Handle *dnsout)
Actually do the reading of a DNS packet from our UDP socket and see if we have a valid, matching, pending request.
Definition: dnsstub.c:290
Handle to the stub resolver.
Definition: dnsstub.c:123
void * rc_cls
Closure for rc.
Definition: dnsstub.c:64
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition: dnsstub.c:504
static void schedule_read(struct GNUNET_DNSSTUB_RequestSocket *rs)
Schedule read_response() task for rs.
Definition: dnsstub.c:376
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Add a socket to the FD set.
Definition: network.c:1011
struct GNUNET_NETWORK_Handle * dnsout4
UDP socket we use for this request for IPv4.
Definition: dnsstub.c:49
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:540
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_SCHEDULER_Task * retry_task
Task for retrying transmission of the query.
Definition: dnsstub.c:74
handle to a socket
Definition: network.c:52
int af
Address family / domain.
Definition: network.c:59
struct GNUNET_TIME_Relative retry_freq
How frequently do we retry requests?
Definition: dnsstub.c:143
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_FS_DirScanner * ds
Handle to the directory scanner (for recursive insertions).
static void cleanup_rs(struct GNUNET_DNSSTUB_RequestSocket *rs)
We&#39;re done with a struct GNUNET_DNSSTUB_RequestSocket, close it for now.
Definition: dnsstub.c:158
Run with the default priority (normal P2P operations).
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:44
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:1029
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:754
int GNUNET_DNSSTUB_add_dns_sa(struct GNUNET_DNSSTUB_Context *ctx, const struct sockaddr *sa)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:643
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966