[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] branch master updated: where applicable, check DNS
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] branch master updated: where applicable, check DNS ID in responses before processing further |
Date: |
Thu, 05 Apr 2018 16:25:59 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 32f590da9 where applicable, check DNS ID in responses before
processing further
32f590da9 is described below
commit 32f590da99c8c77c063b58e3a105a3c05fa5e988
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Apr 5 16:25:46 2018 +0200
where applicable, check DNS ID in responses before processing further
---
src/dns/dnsstub.c | 85 +++++++++++++++++++++++++----------
src/dns/gnunet-service-dns.c | 3 ++
src/exit/gnunet-daemon-exit.c | 2 +
src/gns/gnunet-dns2gns.c | 23 ++++++++--
src/gns/gnunet-service-gns_resolver.c | 27 ++++++++---
src/include/gnunet_dns_service.h | 9 ++--
src/include/gnunet_dnsparser_lib.h | 1 +
7 files changed, 114 insertions(+), 36 deletions(-)
diff --git a/src/dns/dnsstub.c b/src/dns/dnsstub.c
index 364b6fe28..c79502ce9 100644
--- a/src/dns/dnsstub.c
+++ b/src/dns/dnsstub.c
@@ -235,8 +235,22 @@ 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,
- DNS_SOCKET_MAX)];
+ for (unsigned int i=0;i<256;i++)
+ {
+ rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ DNS_SOCKET_MAX)];
+ if (NULL == rs->rc)
+ break;
+ }
+ if (NULL != rs->rc)
+ {
+ /* signal "failure" */
+ rs->rc (rs->rc_cls,
+ rs,
+ NULL,
+ 0);
+ rs->rc = NULL;
+ }
rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
switch (af)
{
@@ -271,9 +285,11 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx,
return NULL;
rset = GNUNET_NETWORK_fdset_create ();
if (NULL != rs->dnsout4)
- GNUNET_NETWORK_fdset_set (rset, rs->dnsout4);
+ GNUNET_NETWORK_fdset_set (rset,
+ rs->dnsout4);
if (NULL != rs->dnsout6)
- GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
+ GNUNET_NETWORK_fdset_set (rset,
+ rs->dnsout6);
rs->read_task = GNUNET_SCHEDULER_add_select
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
REQUEST_TIMEOUT,
rset,
@@ -326,11 +342,11 @@ transmit_query (void *cls)
*
* @param ctx stub resolver to use
* @param sa the socket address
- * @param sa_len the socket length
+ * @param sa_len the length of @a sa
* @param request DNS request to transmit
- * @param request_len number of bytes in msg
+ * @param request_len number of bytes in @a request
* @param rc function to call with result
- * @param rc_cls closure for 'rc'
+ * @param rc_cls closure for @a rc
* @return socket used for the request, NULL on error
*/
struct GNUNET_DNSSTUB_RequestSocket *
@@ -347,6 +363,7 @@ GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx,
if (NULL == (rs = get_request_socket (ctx,
sa->sa_family)))
return NULL;
+ GNUNET_assert (NULL == rs->rc);
GNUNET_memcpy (&rs->addr,
sa,
sa_len);
@@ -389,7 +406,9 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
memset (&v4, 0, sizeof (v4));
memset (&v6, 0, sizeof (v6));
- if (1 == inet_pton (AF_INET, ctx->dns_exit, &v4.sin_addr))
+ if (1 == inet_pton (AF_INET,
+ ctx->dns_exit,
+ &v4.sin_addr))
{
salen = sizeof (v4);
v4.sin_family = AF_INET;
@@ -400,7 +419,9 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
sa = (struct sockaddr *) &v4;
af = AF_INET;
}
- else if (1 == inet_pton (AF_INET6, ctx->dns_exit, &v6.sin6_addr))
+ else if (1 == inet_pton (AF_INET6,
+ ctx->dns_exit,
+ &v6.sin6_addr))
{
salen = sizeof (v6);
v6.sin6_family = AF_INET6;
@@ -416,8 +437,10 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context
*ctx,
GNUNET_break (0);
return NULL;
}
- if (NULL == (rs = get_request_socket (ctx, af)))
+ if (NULL == (rs = get_request_socket (ctx,
+ af)))
return NULL;
+ GNUNET_assert (NULL == rs->rc);
if (NULL != rs->dnsout4)
dnsout = rs->dnsout4;
else
@@ -430,15 +453,17 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context
*ctx,
return NULL;
}
GNUNET_memcpy (&rs->addr,
- sa,
- salen);
+ sa,
+ salen);
rs->addrlen = salen;
rs->rc = rc;
rs->rc_cls = rc_cls;
if (GNUNET_SYSERR ==
GNUNET_NETWORK_socket_sendto (dnsout,
request,
- request_len, sa, salen))
+ request_len,
+ sa,
+ salen))
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Failed to send DNS request to %s\n"),
GNUNET_a2s (sa, salen));
@@ -466,7 +491,9 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
int len;
#ifndef MINGW
- if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len))
+ if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout),
+ FIONREAD,
+ &len))
{
/* conservative choice: */
len = UINT16_MAX;
@@ -484,11 +511,14 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
addrlen = sizeof (addr);
memset (&addr, 0, sizeof (addr));
r = GNUNET_NETWORK_socket_recvfrom (dnsout,
- buf, sizeof (buf),
- (struct sockaddr*) &addr, &addrlen);
+ buf,
+ sizeof (buf),
+ (struct sockaddr*) &addr,
+ &addrlen);
if (-1 == r)
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom");
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "recvfrom");
GNUNET_NETWORK_socket_close (dnsout);
return GNUNET_SYSERR;
}
@@ -543,25 +573,32 @@ read_response (void *cls)
}
/* read and process ready sockets */
if ((NULL != rs->dnsout4) &&
- (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout4)) &&
- (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout4)))
+ (GNUNET_NETWORK_fdset_isset (tc->read_ready,
+ rs->dnsout4)) &&
+ (GNUNET_SYSERR == do_dns_read (rs,
+ rs->dnsout4)))
rs->dnsout4 = NULL;
if ((NULL != rs->dnsout6) &&
- (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout6)) &&
- (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout6)))
+ (GNUNET_NETWORK_fdset_isset (tc->read_ready,
+ rs->dnsout6)) &&
+ (GNUNET_SYSERR == do_dns_read (rs,
+ rs->dnsout6)))
rs->dnsout6 = NULL;
/* re-schedule read task */
rset = GNUNET_NETWORK_fdset_create ();
if (NULL != rs->dnsout4)
- GNUNET_NETWORK_fdset_set (rset, rs->dnsout4);
+ GNUNET_NETWORK_fdset_set (rset,
+ rs->dnsout4);
if (NULL != rs->dnsout6)
- GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
+ GNUNET_NETWORK_fdset_set (rset,
+ rs->dnsout6);
rs->read_task = GNUNET_SCHEDULER_add_select
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
GNUNET_TIME_absolute_get_remaining (rs->timeout),
rset,
NULL,
- &read_response, rs);
+ &read_response,
+ rs);
GNUNET_NETWORK_fdset_destroy (rset);
}
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c
index ffc94afb7..9feaa8413 100644
--- a/src/dns/gnunet-service-dns.c
+++ b/src/dns/gnunet-service-dns.c
@@ -729,6 +729,9 @@ process_dns_result (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Processing DNS result from stub resolver\n");
GNUNET_assert (NULL == cls);
+ if (NULL == dns)
+ return; /* ignore */
+
rr = &requests[dns->id];
if ( (rr->phase != RP_INTERNET_DNS) ||
(rr->rs != rs) )
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index c624e083e..0b3cc505a 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -475,6 +475,8 @@ process_dns_result (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Processing DNS result from stub resolver\n");
GNUNET_assert (NULL == cls);
+ if (NULL == dns)
+ return;
/* Handle case that this is a reply to a request from a CADET DNS channel */
ts = channels[dns->id];
if ( (NULL == ts) ||
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c
index 3d16cd773..47cc6dde0 100644
--- a/src/gns/gnunet-dns2gns.c
+++ b/src/gns/gnunet-dns2gns.c
@@ -85,6 +85,11 @@ struct Request
* Number of bytes in @e udp_msg.
*/
size_t udp_msg_size;
+
+ /**
+ * ID of the original request.
+ */
+ uint16_t original_request_id;
};
@@ -255,6 +260,18 @@ dns_result_processor (void *cls,
struct Request *request = cls;
(void) rs;
+ if (NULL == dns)
+ {
+ /* DNSSTUB gave up, so we trigger timeout early */
+ GNUNET_SCHEDULER_cancel (request->timeout_task);
+ do_timeout (request);
+ return;
+ }
+ if (request->original_request_id != dns->id)
+ {
+ /* for a another query, ignore */
+ return;
+ }
request->packet = GNUNET_DNSPARSER_parse ((char*)dns,
r);
send_response (request);
@@ -277,7 +294,6 @@ result_processor (void *cls,
{
struct Request *request = cls;
struct GNUNET_DNSPARSER_Packet *packet;
- uint32_t i;
struct GNUNET_DNSPARSER_Record rec;
request->lookup = NULL;
@@ -288,6 +304,7 @@ result_processor (void *cls,
"Using DNS resolver IP `%s' to resolve `%s'\n",
dns_ip,
request->packet->queries[0].name);
+ request->original_request_id = request->packet->id;
GNUNET_DNSPARSER_free_packet (request->packet);
request->packet = NULL;
request->dns_lookup = GNUNET_DNSSTUB_resolve2 (dns_stub,
@@ -296,7 +313,7 @@ result_processor (void *cls,
&dns_result_processor,
request);
return;
- }
+ }
packet = request->packet;
packet->flags.query_or_response = 1;
packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR;
@@ -307,7 +324,7 @@ result_processor (void *cls,
packet->flags.message_truncated = 0;
packet->flags.authoritative_answer = 0;
//packet->flags.opcode = GNUNET_TUN_DNS_OPCODE_STATUS; // ???
- for (i=0;i<rd_count;i++)
+ for (uint32_t i=0;i<rd_count;i++)
{
// FIXME: do we need to hanlde #GNUNET_GNSRECORD_RF_SHADOW_RECORD
// here? Or should we do this in libgnunetgns?
diff --git a/src/gns/gnunet-service-gns_resolver.c
b/src/gns/gnunet-service-gns_resolver.c
index 0b86ca267..7fbe3a410 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -383,6 +383,11 @@ struct GNS_ResolverHandle
*/
unsigned int loop_limiter;
+ /**
+ * 16 bit random ID we used in the @e dns_request.
+ */
+ uint16_t original_dns_id;
+
};
@@ -843,17 +848,28 @@ dns_result_parser (void *cls,
unsigned int i;
(void) rs;
- rh->dns_request = NULL;
- GNUNET_SCHEDULER_cancel (rh->task_id);
- rh->task_id = NULL;
+ if (NULL == dns)
+ {
+ rh->dns_request = NULL;
+ GNUNET_SCHEDULER_cancel (rh->task_id);
+ rh->task_id = NULL;
+ rh->proc (rh->proc_cls,
+ 0,
+ NULL);
+ GNS_resolver_lookup_cancel (rh);
+ return;
+ }
+ if (rh->original_dns_id != dns->id)
+ {
+ /* DNS answer, but for another query */
+ return;
+ }
p = GNUNET_DNSPARSER_parse ((const char *) dns,
dns_len);
if (NULL == p)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Failed to parse DNS response\n"));
- rh->proc (rh->proc_cls, 0, NULL);
- GNS_resolver_lookup_cancel (rh);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1097,6 +1113,7 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
}
else
{
+ rh->original_dns_id = p->id;
rh->dns_request = GNUNET_DNSSTUB_resolve (dns_handle,
(const struct sockaddr *)
&ac->authority_info.dns_authority.dns_ip,
sa_len,
diff --git a/src/include/gnunet_dns_service.h b/src/include/gnunet_dns_service.h
index 76b708dcf..017d5a039 100644
--- a/src/include/gnunet_dns_service.h
+++ b/src/include/gnunet_dns_service.h
@@ -122,10 +122,11 @@ enum GNUNET_DNS_Flags
* @param request_length number of bytes in request
* @param request udp payload of the DNS request
*/
-typedef void (*GNUNET_DNS_RequestHandler)(void *cls,
- struct GNUNET_DNS_RequestHandle *rh,
- size_t request_length,
- const char *request);
+typedef void
+(*GNUNET_DNS_RequestHandler)(void *cls,
+ struct GNUNET_DNS_RequestHandle *rh,
+ size_t request_length,
+ const char *request);
/**
diff --git a/src/include/gnunet_dnsparser_lib.h
b/src/include/gnunet_dnsparser_lib.h
index 9fe3491d6..80a67c3c7 100644
--- a/src/include/gnunet_dnsparser_lib.h
+++ b/src/include/gnunet_dnsparser_lib.h
@@ -49,6 +49,7 @@
/**
* A few common DNS types.
*/
+#define GNUNET_DNSPARSER_TYPE_ANY 0
#define GNUNET_DNSPARSER_TYPE_A 1
#define GNUNET_DNSPARSER_TYPE_NS 2
#define GNUNET_DNSPARSER_TYPE_CNAME 5
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [gnunet] branch master updated: where applicable, check DNS ID in responses before processing further,
gnunet <=