GNUnet 0.21.1
dnsstub.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for dnsstub.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_DNSSTUB_RequestSocket
 UDP socket we are using for sending DNS requests to the Internet. More...
struct  DnsServer
 DNS Server used for resolution. More...
struct  GNUNET_DNSSTUB_Context
 Handle to the stub resolver. More...


 Timeout for retrying DNS queries. More...


static void cleanup_rs (struct GNUNET_DNSSTUB_RequestSocket *rs)
 We're done with a struct GNUNET_DNSSTUB_RequestSocket, close it for now. More...
static struct GNUNET_NETWORK_Handleopen_socket (int af)
 Open source port for sending DNS requests. More...
static struct GNUNET_DNSSTUB_RequestSocketget_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. More...
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. More...
static void read_response (void *cls)
 Read a DNS response from the (unhindered) UDP-Socket. More...
static void schedule_read (struct GNUNET_DNSSTUB_RequestSocket *rs)
 Schedule read_response() task for rs. More...
static void transmit_query (void *cls)
 Task to (re)transmit the DNS query, possibly repeatedly until we succeed. More...
struct GNUNET_DNSSTUB_RequestSocketGNUNET_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. More...
void GNUNET_DNSSTUB_resolve_cancel (struct GNUNET_DNSSTUB_RequestSocket *rs)
 Cancel DNS resolution. More...
struct GNUNET_DNSSTUB_ContextGNUNET_DNSSTUB_start (unsigned int num_sockets)
 Start a DNS stub resolver. More...
int GNUNET_DNSSTUB_add_dns_ip (struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
 Add nameserver for use by the DNSSTUB. More...
int GNUNET_DNSSTUB_add_dns_sa (struct GNUNET_DNSSTUB_Context *ctx, const struct sockaddr *sa)
 Add nameserver for use by the DNSSTUB. More...
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. More...
void GNUNET_DNSSTUB_stop (struct GNUNET_DNSSTUB_Context *ctx)
 Cleanup DNSSTUB resolver. More...

Macro Definition Documentation



Timeout for retrying DNS queries.

Definition at line 32 of file dnsstub.c.

Function Documentation

◆ cleanup_rs()

static void cleanup_rs ( struct GNUNET_DNSSTUB_RequestSocket rs)

We're done with a struct GNUNET_DNSSTUB_RequestSocket, close it for now.

rsrequest socket to clean up

Definition at line 159 of file dnsstub.c.

161 if (NULL != rs->dnsout4)
162 {
164 rs->dnsout4 = NULL;
165 }
166 if (NULL != rs->dnsout6)
167 {
169 rs->dnsout6 = NULL;
170 }
171 if (NULL != rs->read_task)
172 {
174 rs->read_task = NULL;
175 }
176 if (NULL != rs->retry_task)
177 {
179 rs->retry_task = NULL;
180 }
181 if (NULL != rs->request)
182 {
183 GNUNET_free (rs->request);
184 rs->request = NULL;
185 }
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
void * request
Query we sent to addr.
Definition: dnsstub.c:90
struct GNUNET_NETWORK_Handle * dnsout4
UDP socket we use for this request for IPv4.
Definition: dnsstub.c:50
struct GNUNET_SCHEDULER_Task * read_task
Task for reading from dnsout4 and dnsout6.
Definition: dnsstub.c:70
struct GNUNET_SCHEDULER_Task * retry_task
Task for retrying transmission of the query.
Definition: dnsstub.c:75
struct GNUNET_NETWORK_Handle * dnsout6
UDP socket we use for this request for IPv6.
Definition: dnsstub.c:55

References GNUNET_DNSSTUB_RequestSocket::dnsout4, GNUNET_DNSSTUB_RequestSocket::dnsout6, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), GNUNET_DNSSTUB_RequestSocket::read_task, GNUNET_DNSSTUB_RequestSocket::request, and GNUNET_DNSSTUB_RequestSocket::retry_task.

Referenced by GNUNET_DNSSTUB_stop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_socket()

static struct GNUNET_NETWORK_Handle * open_socket ( int  af)

Open source port for sending DNS requests.

GNUNET_OK on success

Definition at line 196 of file dnsstub.c.

198 struct sockaddr_in a4;
199 struct sockaddr_in6 a6;
200 struct sockaddr *sa;
201 socklen_t alen;
204 ret = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, 0);
205 if (NULL == ret)
206 return NULL;
207 switch (af)
208 {
209 case AF_INET:
210 memset (&a4, 0, alen = sizeof(struct sockaddr_in));
211 sa = (struct sockaddr *) &a4;
212 break;
214 case AF_INET6:
215 memset (&a6, 0, alen = sizeof(struct sockaddr_in6));
216 sa = (struct sockaddr *) &a6;
217 break;
219 default:
220 GNUNET_break (0);
222 return NULL;
223 }
224 sa->sa_family = af;
225 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret, sa, alen))
226 {
228 _ ("Could not bind to any port: %s\n"),
229 strerror (errno));
231 return NULL;
232 }
233 return ret;
static int ret
Final status code.
Definition: gnunet-arm.c:94
#define GNUNET_log(kind,...)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue 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:439
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
handle to a socket
Definition: network.c:53
int af
Address family / domain.
Definition: network.c:59

References _, GNUNET_NETWORK_Handle::af, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, and ret.

Referenced by transmit_query().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_request_socket()

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.

ctxthe DNSSTUB context
NULL on error

Definition at line 245 of file dnsstub.c.

249 for (unsigned int i = 0; i < 256; i++)
250 {
252 ctx->num_sockets)];
253 if (NULL == rs->rc)
254 break;
255 }
256 if (NULL != rs->rc)
257 {
258 /* signal "failure" */
259 rs->rc (rs->rc_cls, NULL, 0);
260 rs->rc = NULL;
261 }
262 if (NULL != rs->read_task)
263 {
265 rs->read_task = NULL;
266 }
267 if (NULL != rs->retry_task)
268 {
270 rs->retry_task = NULL;
271 }
272 if (NULL != rs->request)
273 {
274 GNUNET_free (rs->request);
275 rs->request = NULL;
276 }
277 rs->ctx = ctx;
278 return rs;
static struct GNUNET_FS_Handle * ctx
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
Randomness for IVs etc.
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:46
struct GNUNET_DNSSTUB_Context * ctx
Context this request executes in.
Definition: dnsstub.c:85
GNUNET_DNSSTUB_ResultCallback rc
Function to call with result.
Definition: dnsstub.c:60
void * rc_cls
Closure for rc.
Definition: dnsstub.c:65

References ctx, GNUNET_DNSSTUB_RequestSocket::ctx, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_free, GNUNET_SCHEDULER_cancel(), GNUNET_DNSSTUB_RequestSocket::rc, GNUNET_DNSSTUB_RequestSocket::rc_cls, GNUNET_DNSSTUB_RequestSocket::read_task, GNUNET_DNSSTUB_RequestSocket::request, and GNUNET_DNSSTUB_RequestSocket::retry_task.

Referenced by GNUNET_DNSSTUB_resolve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_dns_read()

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.

rsrequest socket with callback details
dnsoutsocket to read from
GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket)

Definition at line 291 of file dnsstub.c.

294 struct GNUNET_DNSSTUB_Context *ctx = rs->ctx;
295 ssize_t r;
296 int len;
298 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len))
299 {
300 /* conservative choice: */
301 len = UINT16_MAX;
302 }
304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving %d byte DNS reply\n", len);
305 {
306 unsigned char buf[len] GNUNET_ALIGN;
307 int found;
308 struct sockaddr_storage addr;
309 socklen_t addrlen;
310 struct GNUNET_TUN_DnsHeader *dns;
312 addrlen = sizeof(addr);
313 memset (&addr, 0, sizeof(addr));
315 buf,
316 sizeof(buf),
317 (struct sockaddr *) &addr,
318 &addrlen);
319 if (-1 == r)
320 {
323 return GNUNET_SYSERR;
324 }
325 found = GNUNET_NO;
326 for (struct DnsServer *ds = ctx->dns_head; NULL != ds; ds = ds->next)
327 {
328 if (ds->ss.ss_family != addr.ss_family)
329 continue;
330 if (addr.ss_family == AF_INET)
331 {
332 struct sockaddr_in *v4 = (struct sockaddr_in *) &addr;
333 struct sockaddr_in *ds_v4 = (struct sockaddr_in *) &ds->ss;
336 if ((0 == memcmp (&v4->sin_addr,
337 &ds_v4->sin_addr,
338 sizeof(struct sockaddr_in))) &&
339 (v4->sin_port == ds_v4->sin_port))
340 {
341 found = GNUNET_YES;
342 break;
343 }
344 }
345 else
346 {
347 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *) &addr;
348 struct sockaddr_in6 *ds_v6 = (struct sockaddr_in6 *) &ds->ss;
350 if (0 == memcmp (&v6->sin6_addr,
351 &ds_v6->sin6_addr,
352 sizeof (v6->sin6_addr)) &&
353 (v6->sin6_port == ds_v6->sin6_port))
354 {
355 found = GNUNET_YES;
356 break;
357 }
359 }
360 }
361 if (GNUNET_NO == found)
362 {
364 "Received DNS response from server we never asked (ignored)\n");
366 return GNUNET_NO;
367 }
368 if (sizeof(struct GNUNET_TUN_DnsHeader) > (size_t) r)
369 {
371 _ ("Received DNS response that is too small (%u bytes)\n"),
372 (unsigned int) r);
373 return GNUNET_NO;
374 }
375 dns = (struct GNUNET_TUN_DnsHeader *) buf;
376 if (NULL == rs->rc)
377 {
379 "Request timeout or cancelled; ignoring reply\n");
380 return GNUNET_NO;
381 }
382 rs->rc (rs->rc_cls, dns, r);
383 }
384 return GNUNET_OK;
static struct GNUNET_FS_DirScanner * ds
Handle to the directory scanner (for recursive insertions).
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
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:687
DNS Server used for resolution.
Definition: dnsstub.c:103
Handle to the stub resolver.
Definition: dnsstub.c:125


Referenced by read_response().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_response()

static void read_response ( void *  cls)

Read a DNS response from the (unhindered) UDP-Socket.

clsstruct GNUNET_DNSSTUB_RequestSocket to read from

Definition at line 426 of file dnsstub.c.

428 struct GNUNET_DNSSTUB_RequestSocket *rs = cls;
429 const struct GNUNET_SCHEDULER_TaskContext *tc;
431 rs->read_task = NULL;
433 /* read and process ready sockets */
434 if ((NULL != rs->dnsout4) &&
436 (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout4)))
437 rs->dnsout4 = NULL;
438 if ((NULL != rs->dnsout6) &&
440 (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout6)))
441 rs->dnsout6 = NULL;
442 /* re-schedule read task */
443 schedule_read (rs);
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,...
Definition: dnsstub.c:291
static void schedule_read(struct GNUNET_DNSSTUB_RequestSocket *rs)
Schedule read_response() task for rs.
Definition: dnsstub.c:403
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:949
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:758
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Context information passed to each scheduler task.
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 ...

References GNUNET_DNSSTUB_RequestSocket::dnsout4, GNUNET_DNSSTUB_RequestSocket::dnsout6, do_dns_read(), GNUNET_NETWORK_fdset_isset(), GNUNET_SCHEDULER_get_task_context(), GNUNET_SYSERR, GNUNET_SCHEDULER_TaskContext::read_ready, GNUNET_DNSSTUB_RequestSocket::read_task, schedule_read(), and tc.

Referenced by schedule_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_read()

static void schedule_read ( struct GNUNET_DNSSTUB_RequestSocket rs)

Schedule read_response() task for rs.

rsrequest to schedule read operation for

Definition at line 403 of file dnsstub.c.

405 struct GNUNET_NETWORK_FDSet *rset;
407 if (NULL != rs->read_task)
410 if (NULL != rs->dnsout4)
412 if (NULL != rs->dnsout6)
414 rs->read_task =
417 rset,
418 NULL,
420 rs);
static void read_response(void *cls)
Read a DNS response from the (unhindered) UDP-Socket.
Definition: dnsstub.c:426
Run with the default priority (normal P2P operations).
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1186
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1170
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:931
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:1836
Constant used to specify "forever".
collection of IO descriptors

References GNUNET_DNSSTUB_RequestSocket::dnsout4, GNUNET_DNSSTUB_RequestSocket::dnsout6, GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_destroy(), GNUNET_NETWORK_fdset_set(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_TIME_UNIT_FOREVER_REL, read_response(), and GNUNET_DNSSTUB_RequestSocket::read_task.

Referenced by read_response(), and transmit_query().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_query()

static void transmit_query ( void *  cls)

Task to (re)transmit the DNS query, possibly repeatedly until we succeed.

clsour struct GNUNET_DNSSTUB_RequestSocket *

Definition at line 454 of file dnsstub.c.

456 struct GNUNET_DNSSTUB_RequestSocket *rs = cls;
457 struct GNUNET_DNSSTUB_Context *ctx = rs->ctx;
458 const struct sockaddr *sa;
459 socklen_t salen;
460 struct DnsServer *ds;
461 struct GNUNET_NETWORK_Handle *dnsout;
463 rs->retry_task =
465 ds = rs->ds_pos;
466 rs->ds_pos = ds->next;
467 if (NULL == rs->ds_pos)
468 rs->ds_pos = ctx->dns_head;
469 GNUNET_assert (NULL != ds);
470 dnsout = NULL;
471 switch (ds->ss.ss_family)
472 {
473 case AF_INET:
474 if (NULL == rs->dnsout4)
475 rs->dnsout4 = open_socket (AF_INET);
476 dnsout = rs->dnsout4;
477 sa = (const struct sockaddr *) &ds->ss;
478 salen = sizeof(struct sockaddr_in);
479 break;
481 case AF_INET6:
482 if (NULL == rs->dnsout6)
483 rs->dnsout6 = open_socket (AF_INET6);
484 dnsout = rs->dnsout6;
485 sa = (const struct sockaddr *) &ds->ss;
486 salen = sizeof(struct sockaddr_in6);
487 break;
489 default:
490 return;
491 }
492 if (NULL == dnsout)
493 {
495 "Unable to use configure DNS server, skipping\n");
496 return;
497 }
499 rs->request,
500 rs->request_len,
501 sa,
502 salen))
504 _ ("Failed to send DNS request to %s: %s\n"),
505 GNUNET_a2s (sa, salen),
506 strerror (errno));
507 else
509 _ ("Sent DNS request to %s\n"),
510 GNUNET_a2s (sa, salen));
511 schedule_read (rs);
static void transmit_query(void *cls)
Task to (re)transmit the DNS query, possibly repeatedly until we succeed.
Definition: dnsstub.c:454
static struct GNUNET_NETWORK_Handle * open_socket(int af)
Open source port for sending DNS requests.
Definition: dnsstub.c:196
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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).
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:771
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:1278
size_t request_len
Number of bytes in request.
Definition: dnsstub.c:95
struct DnsServer * ds_pos
Next address we sent the DNS request to.
Definition: dnsstub.c:80

References _, ctx, GNUNET_DNSSTUB_RequestSocket::ctx, GNUNET_DNSSTUB_RequestSocket::dnsout4, GNUNET_DNSSTUB_RequestSocket::dnsout6, ds, GNUNET_DNSSTUB_RequestSocket::ds_pos, GNUNET_a2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_NETWORK_socket_sendto(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, open_socket(), GNUNET_DNSSTUB_RequestSocket::request, GNUNET_DNSSTUB_RequestSocket::request_len, GNUNET_DNSSTUB_RequestSocket::retry_task, schedule_read(), and transmit_query().

Referenced by GNUNET_DNSSTUB_resolve(), and transmit_query().

Here is the call graph for this function:
Here is the caller graph for this function: