X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdns%2Fdnsstub.c;h=68cd55275085ed85a70f8824e7f88b4d6af79798;hb=c253a40bae417335fab8446f3c7182c8c5d4833f;hp=0c3bf0ef3099616a6dcd56efd6c9a4a54860ffd6;hpb=3d66c5660bd67adafa44b98d1ffa66a3b1b2f105;p=oweals%2Fgnunet.git diff --git a/src/dns/dnsstub.c b/src/dns/dnsstub.c index 0c3bf0ef3..68cd55275 100644 --- a/src/dns/dnsstub.c +++ b/src/dns/dnsstub.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2012 Christian Grothoff (and other contributing authors) + Copyright (C) 2012 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** * @file dns/dnsstub.c @@ -24,6 +24,7 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_tun_lib.h" #include "gnunet_dnsstub_lib.h" /** @@ -43,7 +44,7 @@ */ struct GNUNET_DNSSTUB_RequestSocket { - + /** * UDP socket we use for this request for IPv4 */ @@ -60,14 +61,14 @@ struct GNUNET_DNSSTUB_RequestSocket GNUNET_DNSSTUB_ResultCallback rc; /** - * Closure for 'rc'. + * Closure for @e rc. */ void *rc_cls; /** * Task for reading from dnsout4 and dnsout6. */ - GNUNET_SCHEDULER_TaskIdentifier read_task; + struct GNUNET_SCHEDULER_Task * read_task; /** * When should this request time out? @@ -80,24 +81,27 @@ struct GNUNET_DNSSTUB_RequestSocket struct sockaddr_storage addr; /** - * Number of bytes in 'addr'. + * Number of bytes in @e addr. */ socklen_t addrlen; }; +/** + * Handle to the stub resolver. + */ struct GNUNET_DNSSTUB_Context { /** - * Array of all open sockets for DNS requests. + * Array of all open sockets for DNS requests. */ struct GNUNET_DNSSTUB_RequestSocket sockets[DNS_SOCKET_MAX]; /** * IP address to use for the DNS server if we are a DNS exit service - * (for VPN via mesh); otherwise NULL. + * (for VPN via cadet); otherwise NULL. */ char *dns_exit; }; @@ -105,7 +109,7 @@ struct GNUNET_DNSSTUB_Context /** - * We're done with a GNUNET_DNSSTUB_RequestSocket, close it for now. + * We're done with a `struct GNUNET_DNSSTUB_RequestSocket`, close it for now. * * @param rs request socket to clean up */ @@ -122,10 +126,10 @@ cleanup_rs (struct GNUNET_DNSSTUB_RequestSocket *rs) GNUNET_NETWORK_socket_close (rs->dnsout6); rs->dnsout6 = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != rs->read_task) + if (NULL != rs->read_task) { GNUNET_SCHEDULER_cancel (rs->read_task); - rs->read_task = GNUNET_SCHEDULER_NO_TASK; + rs->read_task = NULL; } } @@ -134,8 +138,8 @@ cleanup_rs (struct GNUNET_DNSSTUB_RequestSocket *rs) * Open source port for sending DNS requests * * @param af AF_INET or AF_INET6 - * @return GNUNET_OK on success - */ + * @return #GNUNET_OK on success + */ static struct GNUNET_NETWORK_Handle * open_socket (int af) { @@ -165,10 +169,10 @@ open_socket (int af) } sa->sa_family = af; if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret, - sa, + sa, alen)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not bind to any port: %s\n"), STRERROR (errno)); GNUNET_NETWORK_socket_close (ret); @@ -182,16 +186,14 @@ open_socket (int af) * Read a DNS response from the (unhindered) UDP-Socket * * @param cls socket to read from - * @param tc scheduler context (must be shutdown or read ready) */ static void -read_response (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +read_response (void *cls); /** * Get a socket of the specified address family to send out a - * UDP DNS request to the Internet. + * UDP DNS request to the Internet. * * @param ctx the DNSSTUB context * @param af desired address family @@ -204,7 +206,7 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, struct GNUNET_DNSSTUB_RequestSocket *rs; struct GNUNET_NETWORK_FDSet *rset; - rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, + rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, DNS_SOCKET_MAX)]; rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); switch (af) @@ -219,11 +221,11 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, break; default: return NULL; - } - if (GNUNET_SCHEDULER_NO_TASK != rs->read_task) + } + if (NULL != rs->read_task) { GNUNET_SCHEDULER_cancel (rs->read_task); - rs->read_task = GNUNET_SCHEDULER_NO_TASK; + rs->read_task = NULL; } if ( (NULL == rs->dnsout4) && (NULL == rs->dnsout6) ) @@ -247,7 +249,8 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, * Perform DNS resolution. * * @param ctx stub resolver to use - * @param af address family to use + * @param sa the socket address + * @param sa_len the socket length * @param request DNS request to transmit * @param request_len number of bytes in msg * @param rc function to call with result @@ -275,13 +278,25 @@ GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx, else ret = rs->dnsout6; GNUNET_assert (NULL != ret); + GNUNET_memcpy (&rs->addr, + sa, + sa_len); + rs->addrlen = sa_len; rs->rc = rc; rs->rc_cls = rc_cls; - GNUNET_NETWORK_socket_sendto (ret, - request, - request_len, - sa, - sa_len); + if (GNUNET_SYSERR == + GNUNET_NETWORK_socket_sendto (ret, + request, + request_len, + sa, + sa_len)) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to send DNS request to %s\n"), + GNUNET_a2s (sa, sa_len)); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Sent DNS request to %s\n"), + GNUNET_a2s (sa, sa_len)); return rs; } @@ -306,7 +321,7 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, int af; struct sockaddr_in v4; struct sockaddr_in6 v6; - struct sockaddr *so; + struct sockaddr *sa; socklen_t salen; struct GNUNET_NETWORK_Handle *dnsout; struct GNUNET_DNSSTUB_RequestSocket *rs; @@ -321,7 +336,7 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, #if HAVE_SOCKADDR_IN_SIN_LEN v4.sin_len = (u_char) salen; #endif - so = (struct sockaddr *) &v4; + sa = (struct sockaddr *) &v4; af = AF_INET; } else if (1 == inet_pton (AF_INET6, ctx->dns_exit, &v6.sin6_addr)) @@ -332,9 +347,9 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, #if HAVE_SOCKADDR_IN_SIN_LEN v6.sin6_len = (u_char) salen; #endif - so = (struct sockaddr *) &v6; + sa = (struct sockaddr *) &v6; af = AF_INET6; - } + } else { GNUNET_break (0); @@ -353,19 +368,21 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, ctx->dns_exit); return NULL; } - memcpy (&rs->addr, - so, + GNUNET_memcpy (&rs->addr, + sa, salen); rs->addrlen = salen; rs->rc = rc; rs->rc_cls = rc_cls; - GNUNET_NETWORK_socket_sendto (dnsout, - request, - request_len, so, salen); + if (GNUNET_SYSERR == + GNUNET_NETWORK_socket_sendto (dnsout, + request, + request_len, sa, salen)) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to send DNS request to %s\n"), + GNUNET_a2s (sa, salen)); rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); - return rs; - } @@ -375,7 +392,7 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, * * @param rs request socket with callback details * @param dnsout socket to read from - * @return GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket) + * @return #GNUNET_OK on success, #GNUNET_NO on drop, #GNUNET_SYSERR on IO-errors (closed socket) */ static int do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, @@ -397,13 +414,15 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, /* port the code above? */ len = UINT16_MAX; #endif - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Receiving %d byte DNS reply\n", + len); { unsigned char buf[len] GNUNET_ALIGN; addrlen = sizeof (addr); - memset (&addr, 0, sizeof (addr)); - r = GNUNET_NETWORK_socket_recvfrom (dnsout, + memset (&addr, 0, sizeof (addr)); + r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf), (struct sockaddr*) &addr, &addrlen); if (-1 == r) @@ -414,23 +433,29 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, } if (sizeof (struct GNUNET_TUN_DnsHeader) > r) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received DNS response that is too small (%u bytes)"), - r); + (unsigned int) r); return GNUNET_NO; } dns = (struct GNUNET_TUN_DnsHeader *) buf; if ( (addrlen != rs->addrlen) || - (0 != memcmp (&rs->addr, - &addr, - addrlen)) || - (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value) ) + (GNUNET_YES != + GNUNET_TUN_sockaddr_cmp ((struct sockaddr *) &rs->addr, + (struct sockaddr *) &addr, + GNUNET_YES)) || + (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Request timeout or invalid sender address; ignoring reply\n"); return GNUNET_NO; - rs->rc (rs->rc_cls, - rs, - dns, - r); - } + } + if (NULL != rs->rc) + rs->rc (rs->rc_cls, + rs, + dns, + r); + } return GNUNET_OK; } @@ -439,19 +464,19 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, * Read a DNS response from the (unhindered) UDP-Socket * * @param cls socket to read from - * @param tc scheduler context (must be shutdown or read ready) */ static void -read_response (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +read_response (void *cls) { struct GNUNET_DNSSTUB_RequestSocket *rs = cls; struct GNUNET_NETWORK_FDSet *rset; + const struct GNUNET_SCHEDULER_TaskContext *tc; - rs->read_task = GNUNET_SCHEDULER_NO_TASK; + rs->read_task = NULL; + tc = GNUNET_SCHEDULER_get_task_context (); if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) { - /* timeout or shutdown */ + /* timeout */ cleanup_rs (rs); return; } @@ -480,6 +505,17 @@ read_response (void *cls, } +/** + * Cancel DNS resolution. + * + * @param rs resolution to cancel + */ +void +GNUNET_DNSSTUB_resolve_cancel (struct GNUNET_DNSSTUB_RequestSocket *rs) +{ + rs->rc = NULL; +} + /** * Start a DNS stub resolver. @@ -491,8 +527,8 @@ struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start (const char *dns_ip) { struct GNUNET_DNSSTUB_Context *ctx; - - ctx = GNUNET_malloc (sizeof (struct GNUNET_DNSSTUB_Context)); + + ctx = GNUNET_new (struct GNUNET_DNSSTUB_Context); if (NULL != dns_ip) ctx->dns_exit = GNUNET_strdup (dns_ip); return ctx; @@ -509,7 +545,7 @@ GNUNET_DNSSTUB_stop (struct GNUNET_DNSSTUB_Context *ctx) { unsigned int i; - for (i=0;i<=UINT16_MAX;i++) + for (i=0;isockets[i]); if (NULL != ctx->dns_exit) {