aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dns/Makefile.am12
-rw-r--r--src/dns/dnsparser.c5
-rw-r--r--src/dns/dnsstub.c94
-rw-r--r--src/dns/gnunet-service-dns.c3
-rw-r--r--src/dns/gnunet-zoneimport.c589
-rw-r--r--src/exit/gnunet-daemon-exit.c2
-rw-r--r--src/gns/gnunet-dns2gns.c23
-rw-r--r--src/gns/gnunet-service-gns_resolver.c27
-rw-r--r--src/include/gnunet_common.h19
-rw-r--r--src/include/gnunet_dns_service.h9
-rw-r--r--src/include/gnunet_dnsparser_lib.h36
-rw-r--r--src/rps/gnunet-service-rps.c9
-rw-r--r--src/rps/rps-test_util.c14
-rw-r--r--src/rps/rps-test_util.h14
-rw-r--r--src/rps/test_rps.c434
-rw-r--r--src/rps/test_rps.conf2
16 files changed, 1156 insertions, 136 deletions
diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am
index 5af228121..8e5b06043 100644
--- a/src/dns/Makefile.am
+++ b/src/dns/Makefile.am
@@ -35,7 +35,9 @@ libexec_PROGRAMS = \
35 gnunet-service-dns $(HIJACKBIN) 35 gnunet-service-dns $(HIJACKBIN)
36 36
37noinst_PROGRAMS = \ 37noinst_PROGRAMS = \
38 gnunet-dns-monitor gnunet-dns-redirector 38 gnunet-dns-monitor \
39 gnunet-dns-redirector \
40 gnunet-zoneimport
39 41
40plugin_LTLIBRARIES = \ 42plugin_LTLIBRARIES = \
41 libgnunet_plugin_block_dns.la 43 libgnunet_plugin_block_dns.la
@@ -60,6 +62,14 @@ gnunet_dns_monitor_LDADD = \
60 $(top_builddir)/src/util/libgnunetutil.la \ 62 $(top_builddir)/src/util/libgnunetutil.la \
61 $(GN_LIBINTL) 63 $(GN_LIBINTL)
62 64
65gnunet_zoneimport_SOURCES = \
66 gnunet-zoneimport.c
67gnunet_zoneimport_LDADD = \
68 libgnunetdnsparser.la \
69 libgnunetdnsstub.la \
70 $(top_builddir)/src/util/libgnunetutil.la \
71 $(GN_LIBINTL)
72
63gnunet_dns_redirector_SOURCES = \ 73gnunet_dns_redirector_SOURCES = \
64 gnunet-dns-redirector.c 74 gnunet-dns-redirector.c
65gnunet_dns_redirector_LDADD = \ 75gnunet_dns_redirector_LDADD = \
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c
index 1fe6f595f..ab833f7c5 100644
--- a/src/dns/dnsparser.c
+++ b/src/dns/dnsparser.c
@@ -615,6 +615,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
615 { 615 {
616 case GNUNET_DNSPARSER_TYPE_NS: 616 case GNUNET_DNSPARSER_TYPE_NS:
617 case GNUNET_DNSPARSER_TYPE_CNAME: 617 case GNUNET_DNSPARSER_TYPE_CNAME:
618 case GNUNET_DNSPARSER_TYPE_DNAME:
618 case GNUNET_DNSPARSER_TYPE_PTR: 619 case GNUNET_DNSPARSER_TYPE_PTR:
619 r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload, 620 r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload,
620 udp_payload_length, 621 udp_payload_length,
@@ -659,7 +660,9 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
659 default: 660 default:
660 r->data.raw.data = GNUNET_malloc (data_len); 661 r->data.raw.data = GNUNET_malloc (data_len);
661 r->data.raw.data_len = data_len; 662 r->data.raw.data_len = data_len;
662 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len); 663 GNUNET_memcpy (r->data.raw.data,
664 &udp_payload[*off],
665 data_len);
663 break; 666 break;
664 } 667 }
665 (*off) += data_len; 668 (*off) += data_len;
diff --git a/src/dns/dnsstub.c b/src/dns/dnsstub.c
index 364b6fe28..f9dc7a696 100644
--- a/src/dns/dnsstub.c
+++ b/src/dns/dnsstub.c
@@ -235,8 +235,22 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx,
235 struct GNUNET_DNSSTUB_RequestSocket *rs; 235 struct GNUNET_DNSSTUB_RequestSocket *rs;
236 struct GNUNET_NETWORK_FDSet *rset; 236 struct GNUNET_NETWORK_FDSet *rset;
237 237
238 rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 238 for (unsigned int i=0;i<256;i++)
239 DNS_SOCKET_MAX)]; 239 {
240 rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
241 DNS_SOCKET_MAX)];
242 if (NULL == rs->rc)
243 break;
244 }
245 if (NULL != rs->rc)
246 {
247 /* signal "failure" */
248 rs->rc (rs->rc_cls,
249 rs,
250 NULL,
251 0);
252 rs->rc = NULL;
253 }
240 rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); 254 rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
241 switch (af) 255 switch (af)
242 { 256 {
@@ -271,9 +285,11 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx,
271 return NULL; 285 return NULL;
272 rset = GNUNET_NETWORK_fdset_create (); 286 rset = GNUNET_NETWORK_fdset_create ();
273 if (NULL != rs->dnsout4) 287 if (NULL != rs->dnsout4)
274 GNUNET_NETWORK_fdset_set (rset, rs->dnsout4); 288 GNUNET_NETWORK_fdset_set (rset,
289 rs->dnsout4);
275 if (NULL != rs->dnsout6) 290 if (NULL != rs->dnsout6)
276 GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); 291 GNUNET_NETWORK_fdset_set (rset,
292 rs->dnsout6);
277 rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 293 rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
278 REQUEST_TIMEOUT, 294 REQUEST_TIMEOUT,
279 rset, 295 rset,
@@ -326,11 +342,11 @@ transmit_query (void *cls)
326 * 342 *
327 * @param ctx stub resolver to use 343 * @param ctx stub resolver to use
328 * @param sa the socket address 344 * @param sa the socket address
329 * @param sa_len the socket length 345 * @param sa_len the length of @a sa
330 * @param request DNS request to transmit 346 * @param request DNS request to transmit
331 * @param request_len number of bytes in msg 347 * @param request_len number of bytes in @a request
332 * @param rc function to call with result 348 * @param rc function to call with result
333 * @param rc_cls closure for 'rc' 349 * @param rc_cls closure for @a rc
334 * @return socket used for the request, NULL on error 350 * @return socket used for the request, NULL on error
335 */ 351 */
336struct GNUNET_DNSSTUB_RequestSocket * 352struct GNUNET_DNSSTUB_RequestSocket *
@@ -347,6 +363,7 @@ GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx,
347 if (NULL == (rs = get_request_socket (ctx, 363 if (NULL == (rs = get_request_socket (ctx,
348 sa->sa_family))) 364 sa->sa_family)))
349 return NULL; 365 return NULL;
366 GNUNET_assert (NULL == rs->rc);
350 GNUNET_memcpy (&rs->addr, 367 GNUNET_memcpy (&rs->addr,
351 sa, 368 sa,
352 sa_len); 369 sa_len);
@@ -389,7 +406,9 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
389 406
390 memset (&v4, 0, sizeof (v4)); 407 memset (&v4, 0, sizeof (v4));
391 memset (&v6, 0, sizeof (v6)); 408 memset (&v6, 0, sizeof (v6));
392 if (1 == inet_pton (AF_INET, ctx->dns_exit, &v4.sin_addr)) 409 if (1 == inet_pton (AF_INET,
410 ctx->dns_exit,
411 &v4.sin_addr))
393 { 412 {
394 salen = sizeof (v4); 413 salen = sizeof (v4);
395 v4.sin_family = AF_INET; 414 v4.sin_family = AF_INET;
@@ -400,7 +419,9 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
400 sa = (struct sockaddr *) &v4; 419 sa = (struct sockaddr *) &v4;
401 af = AF_INET; 420 af = AF_INET;
402 } 421 }
403 else if (1 == inet_pton (AF_INET6, ctx->dns_exit, &v6.sin6_addr)) 422 else if (1 == inet_pton (AF_INET6,
423 ctx->dns_exit,
424 &v6.sin6_addr))
404 { 425 {
405 salen = sizeof (v6); 426 salen = sizeof (v6);
406 v6.sin6_family = AF_INET6; 427 v6.sin6_family = AF_INET6;
@@ -416,8 +437,10 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
416 GNUNET_break (0); 437 GNUNET_break (0);
417 return NULL; 438 return NULL;
418 } 439 }
419 if (NULL == (rs = get_request_socket (ctx, af))) 440 if (NULL == (rs = get_request_socket (ctx,
441 af)))
420 return NULL; 442 return NULL;
443 GNUNET_assert (NULL == rs->rc);
421 if (NULL != rs->dnsout4) 444 if (NULL != rs->dnsout4)
422 dnsout = rs->dnsout4; 445 dnsout = rs->dnsout4;
423 else 446 else
@@ -430,15 +453,17 @@ GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx,
430 return NULL; 453 return NULL;
431 } 454 }
432 GNUNET_memcpy (&rs->addr, 455 GNUNET_memcpy (&rs->addr,
433 sa, 456 sa,
434 salen); 457 salen);
435 rs->addrlen = salen; 458 rs->addrlen = salen;
436 rs->rc = rc; 459 rs->rc = rc;
437 rs->rc_cls = rc_cls; 460 rs->rc_cls = rc_cls;
438 if (GNUNET_SYSERR == 461 if (GNUNET_SYSERR ==
439 GNUNET_NETWORK_socket_sendto (dnsout, 462 GNUNET_NETWORK_socket_sendto (dnsout,
440 request, 463 request,
441 request_len, sa, salen)) 464 request_len,
465 sa,
466 salen))
442 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 467 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
443 _("Failed to send DNS request to %s\n"), 468 _("Failed to send DNS request to %s\n"),
444 GNUNET_a2s (sa, salen)); 469 GNUNET_a2s (sa, salen));
@@ -466,7 +491,9 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
466 int len; 491 int len;
467 492
468#ifndef MINGW 493#ifndef MINGW
469 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len)) 494 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout),
495 FIONREAD,
496 &len))
470 { 497 {
471 /* conservative choice: */ 498 /* conservative choice: */
472 len = UINT16_MAX; 499 len = UINT16_MAX;
@@ -484,11 +511,14 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs,
484 addrlen = sizeof (addr); 511 addrlen = sizeof (addr);
485 memset (&addr, 0, sizeof (addr)); 512 memset (&addr, 0, sizeof (addr));
486 r = GNUNET_NETWORK_socket_recvfrom (dnsout, 513 r = GNUNET_NETWORK_socket_recvfrom (dnsout,
487 buf, sizeof (buf), 514 buf,
488 (struct sockaddr*) &addr, &addrlen); 515 sizeof (buf),
516 (struct sockaddr*) &addr,
517 &addrlen);
489 if (-1 == r) 518 if (-1 == r)
490 { 519 {
491 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom"); 520 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
521 "recvfrom");
492 GNUNET_NETWORK_socket_close (dnsout); 522 GNUNET_NETWORK_socket_close (dnsout);
493 return GNUNET_SYSERR; 523 return GNUNET_SYSERR;
494 } 524 }
@@ -537,31 +567,47 @@ read_response (void *cls)
537 tc = GNUNET_SCHEDULER_get_task_context (); 567 tc = GNUNET_SCHEDULER_get_task_context ();
538 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 568 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
539 { 569 {
570 /* signal "failure" (from timeout) */
571 if (NULL != rs->rc)
572 {
573 rs->rc (rs->rc_cls,
574 rs,
575 NULL,
576 0);
577 rs->rc = NULL;
578 }
540 /* timeout */ 579 /* timeout */
541 cleanup_rs (rs); 580 cleanup_rs (rs);
542 return; 581 return;
543 } 582 }
544 /* read and process ready sockets */ 583 /* read and process ready sockets */
545 if ((NULL != rs->dnsout4) && 584 if ((NULL != rs->dnsout4) &&
546 (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout4)) && 585 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
547 (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout4))) 586 rs->dnsout4)) &&
587 (GNUNET_SYSERR == do_dns_read (rs,
588 rs->dnsout4)))
548 rs->dnsout4 = NULL; 589 rs->dnsout4 = NULL;
549 if ((NULL != rs->dnsout6) && 590 if ((NULL != rs->dnsout6) &&
550 (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout6)) && 591 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
551 (GNUNET_SYSERR == do_dns_read (rs, rs->dnsout6))) 592 rs->dnsout6)) &&
593 (GNUNET_SYSERR == do_dns_read (rs,
594 rs->dnsout6)))
552 rs->dnsout6 = NULL; 595 rs->dnsout6 = NULL;
553 596
554 /* re-schedule read task */ 597 /* re-schedule read task */
555 rset = GNUNET_NETWORK_fdset_create (); 598 rset = GNUNET_NETWORK_fdset_create ();
556 if (NULL != rs->dnsout4) 599 if (NULL != rs->dnsout4)
557 GNUNET_NETWORK_fdset_set (rset, rs->dnsout4); 600 GNUNET_NETWORK_fdset_set (rset,
601 rs->dnsout4);
558 if (NULL != rs->dnsout6) 602 if (NULL != rs->dnsout6)
559 GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); 603 GNUNET_NETWORK_fdset_set (rset,
604 rs->dnsout6);
560 rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 605 rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
561 GNUNET_TIME_absolute_get_remaining (rs->timeout), 606 GNUNET_TIME_absolute_get_remaining (rs->timeout),
562 rset, 607 rset,
563 NULL, 608 NULL,
564 &read_response, rs); 609 &read_response,
610 rs);
565 GNUNET_NETWORK_fdset_destroy (rset); 611 GNUNET_NETWORK_fdset_destroy (rset);
566} 612}
567 613
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,
729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
730 "Processing DNS result from stub resolver\n"); 730 "Processing DNS result from stub resolver\n");
731 GNUNET_assert (NULL == cls); 731 GNUNET_assert (NULL == cls);
732 if (NULL == dns)
733 return; /* ignore */
734
732 rr = &requests[dns->id]; 735 rr = &requests[dns->id];
733 if ( (rr->phase != RP_INTERNET_DNS) || 736 if ( (rr->phase != RP_INTERNET_DNS) ||
734 (rr->rs != rs) ) 737 (rr->rs != rs) )
diff --git a/src/dns/gnunet-zoneimport.c b/src/dns/gnunet-zoneimport.c
new file mode 100644
index 000000000..914868af4
--- /dev/null
+++ b/src/dns/gnunet-zoneimport.c
@@ -0,0 +1,589 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2018 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file src/dns/gnunet-zoneimport.c
23 * @brief import a DNS zone for analysis, brute force
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include <gnunet_util_lib.h>
28#include <gnunet_dnsstub_lib.h>
29#include <gnunet_dnsparser_lib.h>
30
31/**
32 * Request we should make.
33 */
34struct Request
35{
36 /**
37 * Requests are kept in a DLL.
38 */
39 struct Request *next;
40
41 /**
42 * Requests are kept in a DLL.
43 */
44 struct Request *prev;
45
46 /**
47 * Socket used to make the request, NULL if not active.
48 */
49 struct GNUNET_DNSSTUB_RequestSocket *rs;
50
51 /**
52 * Raw DNS query.
53 */
54 void *raw;
55
56 /**
57 * Number of bytes in @e raw.
58 */
59 size_t raw_len;
60
61 /**
62 * Hostname we are resolving.
63 */
64 char *hostname;
65
66 /**
67 * When did we last issue this request?
68 */
69 time_t time;
70
71 /**
72 * How often did we issue this query?
73 */
74 int issue_num;
75
76 /**
77 * random 16-bit DNS query identifier.
78 */
79 uint16_t id;
80};
81
82
83/**
84 * Context for DNS resolution.
85 */
86static struct GNUNET_DNSSTUB_Context *ctx;
87
88/**
89 * The number of queries that are outstanding
90 */
91static unsigned int pending;
92
93/**
94 * Number of lookups we performed overall.
95 */
96static unsigned int lookups;
97
98/**
99 * Number of lookups that failed.
100 */
101static unsigned int failures;
102
103/**
104 * Number of records we found.
105 */
106static unsigned int records;
107
108/**
109 * Head of DLL of all requests to perform.
110 */
111static struct Request *req_head;
112
113/**
114 * Tail of DLL of all requests to perform.
115 */
116static struct Request *req_tail;
117
118/**
119 * Main task.
120 */
121static struct GNUNET_SCHEDULER_Task *t;
122
123/**
124 * Maximum number of queries pending at the same time.
125 */
126#define THRESH 20
127
128/**
129 * TIME_THRESH is in usecs. How quickly do we submit fresh queries.
130 * Used as an additional throttle.
131 */
132#define TIME_THRESH 10
133
134/**
135 * How often do we retry a query before giving up for good?
136 */
137#define MAX_RETRIES 5
138
139
140/**
141 * We received @a rec for @a req. Remember the answer.
142 *
143 * @param req request
144 * @param rec response
145 */
146static void
147process_record (struct Request *req,
148 struct GNUNET_DNSPARSER_Record *rec)
149{
150 char buf[INET6_ADDRSTRLEN];
151
152 records++;
153 switch (rec->type)
154 {
155 case GNUNET_DNSPARSER_TYPE_A:
156 fprintf (stdout,
157 "%s A %s\n",
158 req->hostname,
159 inet_ntop (AF_INET,
160 rec->data.raw.data,
161 buf,
162 sizeof (buf)));
163 break;
164 case GNUNET_DNSPARSER_TYPE_AAAA:
165 fprintf (stdout,
166 "%s AAAA %s\n",
167 req->hostname,
168 inet_ntop (AF_INET6,
169 rec->data.raw.data,
170 buf,
171 sizeof (buf)));
172 break;
173 case GNUNET_DNSPARSER_TYPE_NS:
174 fprintf (stdout,
175 "%s NS %s\n",
176 req->hostname,
177 rec->data.hostname);
178 break;
179 case GNUNET_DNSPARSER_TYPE_CNAME:
180 fprintf (stdout,
181 "%s CNAME %s\n",
182 req->hostname,
183 rec->data.hostname);
184 break;
185 case GNUNET_DNSPARSER_TYPE_MX:
186 fprintf (stdout,
187 "%s MX %u %s\n",
188 req->hostname,
189 (unsigned int) rec->data.mx->preference,
190 rec->data.mx->mxhost);
191 break;
192 case GNUNET_DNSPARSER_TYPE_SOA:
193 fprintf (stdout,
194 "%s SOA %s %s %u %u %u %u %u\n",
195 req->hostname,
196 rec->data.soa->mname,
197 rec->data.soa->rname,
198 (unsigned int) rec->data.soa->serial,
199 (unsigned int) rec->data.soa->refresh,
200 (unsigned int) rec->data.soa->retry,
201 (unsigned int) rec->data.soa->expire,
202 (unsigned int) rec->data.soa->minimum_ttl);
203 break;
204 case GNUNET_DNSPARSER_TYPE_SRV:
205 fprintf (stdout,
206 "%s SRV %s %u %u %u\n",
207 req->hostname,
208 rec->data.srv->target,
209 rec->data.srv->priority,
210 rec->data.srv->weight,
211 rec->data.srv->port);
212 break;
213 case GNUNET_DNSPARSER_TYPE_PTR:
214 fprintf (stdout,
215 "%s PTR %s\n",
216 req->hostname,
217 rec->data.hostname);
218 break;
219 case GNUNET_DNSPARSER_TYPE_TXT:
220 fprintf (stdout,
221 "%s TXT %.*s\n",
222 req->hostname,
223 (int) rec->data.raw.data_len,
224 (char *) rec->data.raw.data);
225 break;
226 case GNUNET_DNSPARSER_TYPE_DNAME:
227 fprintf (stdout,
228 "%s DNAME %s\n",
229 req->hostname,
230 rec->data.hostname);
231 break;
232
233 /* obscure records */
234 case GNUNET_DNSPARSER_TYPE_AFSDB:
235 case GNUNET_DNSPARSER_TYPE_NAPTR:
236 case GNUNET_DNSPARSER_TYPE_APL:
237 case GNUNET_DNSPARSER_TYPE_DHCID:
238 case GNUNET_DNSPARSER_TYPE_HIP:
239 case GNUNET_DNSPARSER_TYPE_LOC:
240 case GNUNET_DNSPARSER_TYPE_RP:
241 case GNUNET_DNSPARSER_TYPE_TKEY:
242 case GNUNET_DNSPARSER_TYPE_TSIG:
243 case GNUNET_DNSPARSER_TYPE_URI:
244 case GNUNET_DNSPARSER_TYPE_TA:
245
246 /* DNSSEC */
247 case GNUNET_DNSPARSER_TYPE_DS:
248 case GNUNET_DNSPARSER_TYPE_RRSIG:
249 case GNUNET_DNSPARSER_TYPE_NSEC:
250 case GNUNET_DNSPARSER_TYPE_DNSKEY:
251 case GNUNET_DNSPARSER_TYPE_NSEC3:
252 case GNUNET_DNSPARSER_TYPE_NSEC3PARAM:
253 case GNUNET_DNSPARSER_TYPE_CDS:
254 case GNUNET_DNSPARSER_TYPE_CDNSKEY:
255
256 /* DNSSEC payload */
257 case GNUNET_DNSPARSER_TYPE_CERT:
258 case GNUNET_DNSPARSER_TYPE_SSHFP:
259 case GNUNET_DNSPARSER_TYPE_IPSECKEY:
260 case GNUNET_DNSPARSER_TYPE_TLSA:
261 case GNUNET_DNSPARSER_TYPE_OPENPGPKEY:
262
263 /* obsolete records */
264 case GNUNET_DNSPARSER_TYPE_SIG:
265 case GNUNET_DNSPARSER_TYPE_KEY:
266 case GNUNET_DNSPARSER_TYPE_KX:
267 {
268 char *base32;
269
270 base32 = GNUNET_STRINGS_data_to_string_alloc (rec->data.raw.data,
271 rec->data.raw.data_len);
272 fprintf (stdout,
273 "%s (%u) %s\n",
274 req->hostname,
275 rec->type,
276 base32);
277 GNUNET_free (base32);
278 }
279 break;
280 default:
281 fprintf (stderr,
282 "Unsupported type %u\n",
283 (unsigned int) rec->type);
284 break;
285 }
286}
287
288
289/**
290 * Function called with the result of a DNS resolution.
291 *
292 * @param cls closure with the `struct Request`
293 * @param rs socket that received the response
294 * @param dns dns response, never NULL
295 * @param dns_len number of bytes in @a dns
296 */
297static void
298process_result (void *cls,
299 struct GNUNET_DNSSTUB_RequestSocket *rs,
300 const struct GNUNET_TUN_DnsHeader *dns,
301 size_t dns_len)
302{
303 struct Request *req = cls;
304 struct GNUNET_DNSPARSER_Packet *p;
305
306 if (NULL == dns)
307 {
308 /* stub gave up */
309 pending--;
310 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
311 "Stub gave up on DNS reply for `%s'\n",
312 req->hostname);
313 GNUNET_CONTAINER_DLL_remove (req_head,
314 req_tail,
315 req);
316 if (req->issue_num > MAX_RETRIES)
317 {
318 failures++;
319 GNUNET_free (req->hostname);
320 GNUNET_free (req->raw);
321 GNUNET_free (req);
322 return;
323 }
324 GNUNET_CONTAINER_DLL_insert_tail (req_head,
325 req_tail,
326 req);
327 req->rs = NULL;
328 return;
329 }
330 if (req->id != dns->id)
331 return;
332 pending--;
333 GNUNET_DNSSTUB_resolve_cancel (req->rs);
334 req->rs = NULL;
335 GNUNET_CONTAINER_DLL_remove (req_head,
336 req_tail,
337 req);
338 p = GNUNET_DNSPARSER_parse ((const char *) dns,
339 dns_len);
340 if (NULL == p)
341 {
342 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
343 "Failed to parse DNS reply for `%s'\n",
344 req->hostname);
345 if (req->issue_num > MAX_RETRIES)
346 {
347 failures++;
348 GNUNET_free (req->hostname);
349 GNUNET_free (req->raw);
350 GNUNET_free (req);
351 return;
352 }
353 GNUNET_CONTAINER_DLL_insert_tail (req_head,
354 req_tail,
355 req);
356 return;
357 }
358 for (unsigned int i=0;i<p->num_answers;i++)
359 {
360 struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
361
362 process_record (req,
363 rs);
364 }
365 for (unsigned int i=0;i<p->num_authority_records;i++)
366 {
367 struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
368
369 process_record (req,
370 rs);
371 }
372 for (unsigned int i=0;i<p->num_additional_records;i++)
373 {
374 struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
375
376 process_record (req,
377 rs);
378 }
379 GNUNET_DNSPARSER_free_packet (p);
380 GNUNET_free (req->hostname);
381 GNUNET_free (req->raw);
382 GNUNET_free (req);
383}
384
385
386/**
387 * Submit a request to DNS unless we need to slow down because
388 * we are at the rate limit.
389 *
390 * @param req request to submit
391 * @return #GNUNET_OK if request was submitted
392 * #GNUNET_NO if request was already submitted
393 * #GNUNET_SYSERR if we are at the rate limit
394 */
395static int
396submit_req (struct Request *req)
397{
398 static struct timeval last_request;
399 struct timeval now;
400
401 if (NULL != req->rs)
402 return GNUNET_NO; /* already submitted */
403 gettimeofday (&now,
404 NULL);
405 if ( ( ( (now.tv_sec - last_request.tv_sec) == 0) &&
406 ( (now.tv_usec - last_request.tv_usec) < TIME_THRESH) ) ||
407 (pending >= THRESH) )
408 return GNUNET_SYSERR;
409 GNUNET_assert (NULL == req->rs);
410 req->rs = GNUNET_DNSSTUB_resolve2 (ctx,
411 req->raw,
412 req->raw_len,
413 &process_result,
414 req);
415 GNUNET_assert (NULL != req->rs);
416 req->issue_num++;
417 last_request = now;
418 lookups++;
419 pending++;
420 req->time = time (NULL);
421 return GNUNET_OK;
422}
423
424
425/**
426 * Process as many requests as possible from the queue.
427 *
428 * @param cls NULL
429 */
430static void
431process_queue(void *cls)
432{
433 (void) cls;
434 t = NULL;
435 for (struct Request *req = req_head;
436 NULL != req;
437 req = req->next)
438 {
439 if (GNUNET_SYSERR == submit_req (req))
440 break;
441 }
442 if (NULL != req_head)
443 t = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
444 &process_queue,
445 NULL);
446 else
447 GNUNET_SCHEDULER_shutdown ();
448}
449
450
451/**
452 * Clean up and terminate the process.
453 *
454 * @param cls NULL
455 */
456static void
457do_shutdown (void *cls)
458{
459 (void) cls;
460 if (NULL != t)
461 {
462 GNUNET_SCHEDULER_cancel (t);
463 t = NULL;
464 }
465 GNUNET_DNSSTUB_stop (ctx);
466 ctx = NULL;
467}
468
469
470/**
471 * Process requests from the queue, then if the queue is
472 * not empty, try again.
473 *
474 * @param cls NULL
475 */
476static void
477run (void *cls)
478{
479 (void) cls;
480
481 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
482 NULL);
483 t = GNUNET_SCHEDULER_add_now (&process_queue,
484 NULL);
485}
486
487
488/**
489 * Add @a hostname to the list of requests to be made.
490 *
491 * @param hostname name to resolve
492 */
493static void
494queue (const char *hostname)
495{
496 struct GNUNET_DNSPARSER_Packet p;
497 struct GNUNET_DNSPARSER_Query q;
498 struct Request *req;
499 char *raw;
500 size_t raw_size;
501
502 if (GNUNET_OK !=
503 GNUNET_DNSPARSER_check_name (hostname))
504 {
505 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
506 "Refusing invalid hostname `%s'\n",
507 hostname);
508 return;
509 }
510 q.name = (char *) hostname;
511 q.type = GNUNET_DNSPARSER_TYPE_NS;
512 q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
513
514 memset (&p,
515 0,
516 sizeof (p));
517 p.num_queries = 1;
518 p.queries = &q;
519 p.id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
520 UINT16_MAX);
521
522 if (GNUNET_OK !=
523 GNUNET_DNSPARSER_pack (&p,
524 UINT16_MAX,
525 &raw,
526 &raw_size))
527 {
528 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
529 "Failed to pack query for hostname `%s'\n",
530 hostname);
531 return;
532 }
533
534 req = GNUNET_new (struct Request);
535 req->hostname = strdup (hostname);
536 req->raw = raw;
537 req->raw_len = raw_size;
538 req->id = p.id;
539 GNUNET_CONTAINER_DLL_insert_tail (req_head,
540 req_tail,
541 req);
542}
543
544
545/**
546 * Call with IP address of resolver to query.
547 *
548 * @param argc should be 2
549 * @param argv[1] should contain IP address
550 * @return 0 on success
551 */
552int
553main (int argc,
554 char **argv)
555{
556 char hn[256];
557
558 if (2 != argc)
559 {
560 fprintf (stderr,
561 "Missing required configuration argument\n");
562 return -1;
563 }
564 ctx = GNUNET_DNSSTUB_start (argv[1]);
565 if (NULL == ctx)
566 {
567 fprintf (stderr,
568 "Failed to initialize GNUnet DNS STUB\n");
569 return 1;
570 }
571 while (NULL !=
572 fgets (hn,
573 sizeof (hn),
574 stdin))
575 {
576 if (strlen(hn) > 0)
577 hn[strlen(hn)-1] = '\0'; /* eat newline */
578 queue (hn);
579 }
580 GNUNET_SCHEDULER_run (&run,
581 NULL);
582 fprintf (stderr,
583 "Did %u lookups, found %u records, %u lookups failed, %u pending on shutdown\n",
584 lookups,
585 records,
586 failures,
587 pending);
588 return 0;
589}
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,
475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
476 "Processing DNS result from stub resolver\n"); 476 "Processing DNS result from stub resolver\n");
477 GNUNET_assert (NULL == cls); 477 GNUNET_assert (NULL == cls);
478 if (NULL == dns)
479 return;
478 /* Handle case that this is a reply to a request from a CADET DNS channel */ 480 /* Handle case that this is a reply to a request from a CADET DNS channel */
479 ts = channels[dns->id]; 481 ts = channels[dns->id];
480 if ( (NULL == ts) || 482 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
85 * Number of bytes in @e udp_msg. 85 * Number of bytes in @e udp_msg.
86 */ 86 */
87 size_t udp_msg_size; 87 size_t udp_msg_size;
88
89 /**
90 * ID of the original request.
91 */
92 uint16_t original_request_id;
88}; 93};
89 94
90 95
@@ -255,6 +260,18 @@ dns_result_processor (void *cls,
255 struct Request *request = cls; 260 struct Request *request = cls;
256 261
257 (void) rs; 262 (void) rs;
263 if (NULL == dns)
264 {
265 /* DNSSTUB gave up, so we trigger timeout early */
266 GNUNET_SCHEDULER_cancel (request->timeout_task);
267 do_timeout (request);
268 return;
269 }
270 if (request->original_request_id != dns->id)
271 {
272 /* for a another query, ignore */
273 return;
274 }
258 request->packet = GNUNET_DNSPARSER_parse ((char*)dns, 275 request->packet = GNUNET_DNSPARSER_parse ((char*)dns,
259 r); 276 r);
260 send_response (request); 277 send_response (request);
@@ -277,7 +294,6 @@ result_processor (void *cls,
277{ 294{
278 struct Request *request = cls; 295 struct Request *request = cls;
279 struct GNUNET_DNSPARSER_Packet *packet; 296 struct GNUNET_DNSPARSER_Packet *packet;
280 uint32_t i;
281 struct GNUNET_DNSPARSER_Record rec; 297 struct GNUNET_DNSPARSER_Record rec;
282 298
283 request->lookup = NULL; 299 request->lookup = NULL;
@@ -288,6 +304,7 @@ result_processor (void *cls,
288 "Using DNS resolver IP `%s' to resolve `%s'\n", 304 "Using DNS resolver IP `%s' to resolve `%s'\n",
289 dns_ip, 305 dns_ip,
290 request->packet->queries[0].name); 306 request->packet->queries[0].name);
307 request->original_request_id = request->packet->id;
291 GNUNET_DNSPARSER_free_packet (request->packet); 308 GNUNET_DNSPARSER_free_packet (request->packet);
292 request->packet = NULL; 309 request->packet = NULL;
293 request->dns_lookup = GNUNET_DNSSTUB_resolve2 (dns_stub, 310 request->dns_lookup = GNUNET_DNSSTUB_resolve2 (dns_stub,
@@ -296,7 +313,7 @@ result_processor (void *cls,
296 &dns_result_processor, 313 &dns_result_processor,
297 request); 314 request);
298 return; 315 return;
299 } 316 }
300 packet = request->packet; 317 packet = request->packet;
301 packet->flags.query_or_response = 1; 318 packet->flags.query_or_response = 1;
302 packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR; 319 packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR;
@@ -307,7 +324,7 @@ result_processor (void *cls,
307 packet->flags.message_truncated = 0; 324 packet->flags.message_truncated = 0;
308 packet->flags.authoritative_answer = 0; 325 packet->flags.authoritative_answer = 0;
309 //packet->flags.opcode = GNUNET_TUN_DNS_OPCODE_STATUS; // ??? 326 //packet->flags.opcode = GNUNET_TUN_DNS_OPCODE_STATUS; // ???
310 for (i=0;i<rd_count;i++) 327 for (uint32_t i=0;i<rd_count;i++)
311 { 328 {
312 // FIXME: do we need to hanlde #GNUNET_GNSRECORD_RF_SHADOW_RECORD 329 // FIXME: do we need to hanlde #GNUNET_GNSRECORD_RF_SHADOW_RECORD
313 // here? Or should we do this in libgnunetgns? 330 // 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
383 */ 383 */
384 unsigned int loop_limiter; 384 unsigned int loop_limiter;
385 385
386 /**
387 * 16 bit random ID we used in the @e dns_request.
388 */
389 uint16_t original_dns_id;
390
386}; 391};
387 392
388 393
@@ -843,17 +848,28 @@ dns_result_parser (void *cls,
843 unsigned int i; 848 unsigned int i;
844 849
845 (void) rs; 850 (void) rs;
846 rh->dns_request = NULL; 851 if (NULL == dns)
847 GNUNET_SCHEDULER_cancel (rh->task_id); 852 {
848 rh->task_id = NULL; 853 rh->dns_request = NULL;
854 GNUNET_SCHEDULER_cancel (rh->task_id);
855 rh->task_id = NULL;
856 rh->proc (rh->proc_cls,
857 0,
858 NULL);
859 GNS_resolver_lookup_cancel (rh);
860 return;
861 }
862 if (rh->original_dns_id != dns->id)
863 {
864 /* DNS answer, but for another query */
865 return;
866 }
849 p = GNUNET_DNSPARSER_parse ((const char *) dns, 867 p = GNUNET_DNSPARSER_parse ((const char *) dns,
850 dns_len); 868 dns_len);
851 if (NULL == p) 869 if (NULL == p)
852 { 870 {
853 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 871 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
854 _("Failed to parse DNS response\n")); 872 _("Failed to parse DNS response\n"));
855 rh->proc (rh->proc_cls, 0, NULL);
856 GNS_resolver_lookup_cancel (rh);
857 return; 873 return;
858 } 874 }
859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1097,6 +1113,7 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh)
1097 } 1113 }
1098 else 1114 else
1099 { 1115 {
1116 rh->original_dns_id = p->id;
1100 rh->dns_request = GNUNET_DNSSTUB_resolve (dns_handle, 1117 rh->dns_request = GNUNET_DNSSTUB_resolve (dns_handle,
1101 (const struct sockaddr *) &ac->authority_info.dns_authority.dns_ip, 1118 (const struct sockaddr *) &ac->authority_info.dns_authority.dns_ip,
1102 sa_len, 1119 sa_len,
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 7d23e6f9b..0fb39575c 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -160,6 +160,19 @@ extern "C"
160#endif 160#endif
161 161
162 162
163/**
164 * Macro used to avoid using 0 for the length of a variable-size
165 * array (Non-Zero-Length).
166 *
167 * Basically, C standard says that "int[n] x;" is undefined if n=0.
168 * This was supposed to prevent issues with pointer aliasing.
169 * However, C compilers may conclude that n!=0 as n=0 would be
170 * undefined, and then optimize under the assumption n!=0, which
171 * could cause actual issues. Hence, when initializing an array
172 * on the stack with a variable-length that might be zero, write
173 * "int[GNUNET_NZL(n)] x;" instead of "int[n] x".
174 */
175#define GNUNET_NZL(l) GNUNET_MAX(1,l)
163 176
164 177
165/** 178/**
@@ -988,7 +1001,7 @@ GNUNET_ntoh_double (double d);
988 * arr is important since size is the number of elements and 1001 * arr is important since size is the number of elements and
989 * not the size in bytes 1002 * not the size in bytes
990 * @param size the number of elements in the existing vector (number 1003 * @param size the number of elements in the existing vector (number
991 * of elements to copy over), will be updated with the new 1004 * of elements to copy over), will be updated with the new
992 * array size 1005 * array size
993 * @param tsize the target size for the resulting vector, use 0 to 1006 * @param tsize the target size for the resulting vector, use 0 to
994 * free the vector (then, arr will be NULL afterwards). 1007 * free the vector (then, arr will be NULL afterwards).
@@ -998,13 +1011,13 @@ GNUNET_ntoh_double (double d);
998/** 1011/**
999 * @ingroup memory 1012 * @ingroup memory
1000 * Append an element to a list (growing the list by one). 1013 * Append an element to a list (growing the list by one).
1001 * 1014 *
1002 * @param arr base-pointer of the vector, may be NULL if size is 0; 1015 * @param arr base-pointer of the vector, may be NULL if size is 0;
1003 * will be updated to reflect the new address. The TYPE of 1016 * will be updated to reflect the new address. The TYPE of
1004 * arr is important since size is the number of elements and 1017 * arr is important since size is the number of elements and
1005 * not the size in bytes 1018 * not the size in bytes
1006 * @param size the number of elements in the existing vector (number 1019 * @param size the number of elements in the existing vector (number
1007 * of elements to copy over), will be updated with the new 1020 * of elements to copy over), will be updated with the new
1008 * array size 1021 * array size
1009 * @param element the element that will be appended to the array 1022 * @param element the element that will be appended to the array
1010 */ 1023 */
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
122 * @param request_length number of bytes in request 122 * @param request_length number of bytes in request
123 * @param request udp payload of the DNS request 123 * @param request udp payload of the DNS request
124 */ 124 */
125typedef void (*GNUNET_DNS_RequestHandler)(void *cls, 125typedef void
126 struct GNUNET_DNS_RequestHandle *rh, 126(*GNUNET_DNS_RequestHandler)(void *cls,
127 size_t request_length, 127 struct GNUNET_DNS_RequestHandle *rh,
128 const char *request); 128 size_t request_length,
129 const char *request);
129 130
130 131
131/** 132/**
diff --git a/src/include/gnunet_dnsparser_lib.h b/src/include/gnunet_dnsparser_lib.h
index 9fe3491d6..3a2f785d3 100644
--- a/src/include/gnunet_dnsparser_lib.h
+++ b/src/include/gnunet_dnsparser_lib.h
@@ -49,6 +49,7 @@
49/** 49/**
50 * A few common DNS types. 50 * A few common DNS types.
51 */ 51 */
52#define GNUNET_DNSPARSER_TYPE_ANY 0
52#define GNUNET_DNSPARSER_TYPE_A 1 53#define GNUNET_DNSPARSER_TYPE_A 1
53#define GNUNET_DNSPARSER_TYPE_NS 2 54#define GNUNET_DNSPARSER_TYPE_NS 2
54#define GNUNET_DNSPARSER_TYPE_CNAME 5 55#define GNUNET_DNSPARSER_TYPE_CNAME 5
@@ -56,11 +57,36 @@
56#define GNUNET_DNSPARSER_TYPE_PTR 12 57#define GNUNET_DNSPARSER_TYPE_PTR 12
57#define GNUNET_DNSPARSER_TYPE_MX 15 58#define GNUNET_DNSPARSER_TYPE_MX 15
58#define GNUNET_DNSPARSER_TYPE_TXT 16 59#define GNUNET_DNSPARSER_TYPE_TXT 16
60#define GNUNET_DNSPARSER_TYPE_RP 17
61#define GNUNET_DNSPARSER_TYPE_AFSDB 18
62#define GNUNET_DNSPARSER_TYPE_SIG 24
63#define GNUNET_DNSPARSER_TYPE_KEY 25
59#define GNUNET_DNSPARSER_TYPE_AAAA 28 64#define GNUNET_DNSPARSER_TYPE_AAAA 28
65#define GNUNET_DNSPARSER_TYPE_LOC 29
60#define GNUNET_DNSPARSER_TYPE_SRV 33 66#define GNUNET_DNSPARSER_TYPE_SRV 33
67#define GNUNET_DNSPARSER_TYPE_NAPTR 35
68#define GNUNET_DNSPARSER_TYPE_KX 36
61#define GNUNET_DNSPARSER_TYPE_CERT 37 69#define GNUNET_DNSPARSER_TYPE_CERT 37
70#define GNUNET_DNSPARSER_TYPE_DNAME 39
71#define GNUNET_DNSPARSER_TYPE_APL 42
72#define GNUNET_DNSPARSER_TYPE_DS 43
73#define GNUNET_DNSPARSER_TYPE_SSHFP 44
74#define GNUNET_DNSPARSER_TYPE_IPSECKEY 45
75#define GNUNET_DNSPARSER_TYPE_RRSIG 46
76#define GNUNET_DNSPARSER_TYPE_NSEC 47
77#define GNUNET_DNSPARSER_TYPE_DNSKEY 48
78#define GNUNET_DNSPARSER_TYPE_DHCID 49
79#define GNUNET_DNSPARSER_TYPE_NSEC3 50
80#define GNUNET_DNSPARSER_TYPE_NSEC3PARAM 51
62#define GNUNET_DNSPARSER_TYPE_TLSA 52 81#define GNUNET_DNSPARSER_TYPE_TLSA 52
63 82#define GNUNET_DNSPARSER_TYPE_HIP 55
83#define GNUNET_DNSPARSER_TYPE_CDS 59
84#define GNUNET_DNSPARSER_TYPE_CDNSKEY 60
85#define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61
86#define GNUNET_DNSPARSER_TYPE_TKEY 249
87#define GNUNET_DNSPARSER_TYPE_TSIG 250
88#define GNUNET_DNSPARSER_TYPE_URI 256
89#define GNUNET_DNSPARSER_TYPE_TA 32768
64 90
65/** 91/**
66 * A DNS query. 92 * A DNS query.
@@ -413,10 +439,10 @@ struct GNUNET_DNSPARSER_Record
413 439
414 /** 440 /**
415 * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname. 441 * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
416 * In UTF-8 format. The library will convert from and to DNS-IDNA 442 * In UTF-8 format. The library will convert from and to DNS-IDNA
417 * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an 443 * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an
418 * individual label is well-formed. If a given name is not well-formed, 444 * individual label is well-formed. If a given name is not well-formed,
419 * creating the DNS packet will fail. 445 * creating the DNS packet will fail.
420 */ 446 */
421 char *hostname; 447 char *hostname;
422 448
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 30d677849..c23a64285 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -2270,6 +2270,12 @@ insert_in_view (const struct GNUNET_PeerIdentity *peer)
2270} 2270}
2271 2271
2272/** 2272/**
2273 * @brief sends updates to clients that are interested
2274 */
2275static void
2276clients_notify_view_update (void);
2277
2278/**
2273 * Put random peer from sampler into the view as history update. 2279 * Put random peer from sampler into the view as history update.
2274 */ 2280 */
2275static void 2281static void
@@ -2286,6 +2292,7 @@ hist_update (void *cls,
2286 "+%s\t(hist)", 2292 "+%s\t(hist)",
2287 GNUNET_i2s_full (ids)); 2293 GNUNET_i2s_full (ids));
2288 } 2294 }
2295 clients_notify_view_update();
2289} 2296}
2290 2297
2291 2298
@@ -4261,7 +4268,7 @@ run (void *cls,
4261 } 4268 }
4262 4269
4263 4270
4264 View_create (4); 4271 View_create (view_size_est_min);
4265 4272
4266 /* file_name_view_log */ 4273 /* file_name_view_log */
4267 if (GNUNET_OK != GNUNET_DISK_directory_create ("/tmp/rps/")) 4274 if (GNUNET_OK != GNUNET_DISK_directory_create ("/tmp/rps/"))
diff --git a/src/rps/rps-test_util.c b/src/rps/rps-test_util.c
index e492b76b7..817967e0c 100644
--- a/src/rps/rps-test_util.c
+++ b/src/rps/rps-test_util.c
@@ -39,10 +39,11 @@
39 39
40#ifdef TO_FILE 40#ifdef TO_FILE
41void 41void
42to_file_ (char *file_name, char *line) 42to_file_ (const char *file_name, char *line)
43{ 43{
44 struct GNUNET_DISK_FileHandle *f; 44 struct GNUNET_DISK_FileHandle *f;
45 char output_buffer[512]; 45 char output_buffer[512];
46 size_t output_buffer_size = 512;
46 char *output_buffer_p; 47 char *output_buffer_p;
47 //size_t size; 48 //size_t size;
48 int size; 49 int size;
@@ -63,16 +64,17 @@ to_file_ (char *file_name, char *line)
63 file_name); 64 file_name);
64 return; 65 return;
65 } 66 }
66 if (512 < strlen (line) + 18) 67 output_buffer_size = strlen (line) + 18;
68 if (512 < output_buffer_size)
67 { 69 {
68 output_buffer_p = GNUNET_malloc ((strlen (line) + 18) * sizeof (char)); 70 output_buffer_p = GNUNET_malloc ((output_buffer_size) * sizeof (char));
69 } else { 71 } else {
70 output_buffer_p = &output_buffer[0]; 72 output_buffer_p = &output_buffer[0];
71 } 73 }
72 size = GNUNET_snprintf (output_buffer_p, 74 size = GNUNET_snprintf (output_buffer_p,
73 sizeof (output_buffer_p), 75 output_buffer_size,
74 "%llu %s\n", 76 "%llu %s\n",
75 GNUNET_TIME_absolute_get ().abs_value_us, 77 (GNUNET_TIME_absolute_get ().abs_value_us) / 1000000, // microsec -> sec
76 line); 78 line);
77 if (0 > size) 79 if (0 > size)
78 { 80 {
@@ -97,7 +99,7 @@ to_file_ (char *file_name, char *line)
97 return; 99 return;
98 } 100 }
99 101
100 if (512 < strlen (line) + 18) 102 if (512 < output_buffer_size)
101 { 103 {
102 GNUNET_free (output_buffer_p); 104 GNUNET_free (output_buffer_p);
103 } 105 }
diff --git a/src/rps/rps-test_util.h b/src/rps/rps-test_util.h
index 225db4b1d..725be815c 100644
--- a/src/rps/rps-test_util.h
+++ b/src/rps/rps-test_util.h
@@ -34,9 +34,9 @@
34 34
35 35
36void 36void
37to_file_ (char *file_name, char *line); 37to_file_ (const char *file_name, char *line);
38 38
39char * 39char *
40auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key); 40auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key);
41 41
42struct GNUNET_CRYPTO_AuthKey 42struct GNUNET_CRYPTO_AuthKey
@@ -58,8 +58,18 @@ create_file (const char *name);
58 else\ 58 else\
59 to_file_(file_name,tmp_buf);\ 59 to_file_(file_name,tmp_buf);\
60 } while (0); 60 } while (0);
61# define to_file_w_len(file_name, len, ...) do {char tmp_buf[len];\
62 int size;\
63 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\
64 if (0 > size)\
65 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\
66 "Failed to create tmp_buf\n");\
67 else\
68 to_file_(file_name,tmp_buf);\
69 } while (0);
61#else /* TO_FILE */ 70#else /* TO_FILE */
62# define to_file(file_name, ...) 71# define to_file(file_name, ...)
72# define to_file_w_len(file_name, len, ...)
63#endif /* TO_FILE */ 73#endif /* TO_FILE */
64 74
65#endif /* RPS_TEST_UTIL_H */ 75#endif /* RPS_TEST_UTIL_H */
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c
index 93a406aaf..03524eaeb 100644
--- a/src/rps/test_rps.c
+++ b/src/rps/test_rps.c
@@ -257,7 +257,12 @@ struct RPSPeer
257 /** 257 /**
258 * @brief File name of the file the stats are finally written to 258 * @brief File name of the file the stats are finally written to
259 */ 259 */
260 char *file_name_stats; 260 const char *file_name_stats;
261
262 /**
263 * @brief File name of the file the stats are finally written to
264 */
265 const char *file_name_probs;
261 266
262 /** 267 /**
263 * @brief The current view 268 * @brief The current view
@@ -270,6 +275,11 @@ struct RPSPeer
270 uint32_t cur_view_count; 275 uint32_t cur_view_count;
271 276
272 /** 277 /**
278 * @brief Number of occurrences in other peer's view
279 */
280 uint32_t count_in_views;
281
282 /**
273 * @brief statistics values 283 * @brief statistics values
274 */ 284 */
275 uint64_t num_rounds; 285 uint64_t num_rounds;
@@ -349,6 +359,11 @@ static struct RPSPeer *eval_peer;
349static unsigned int num_peers_online; 359static unsigned int num_peers_online;
350 360
351/** 361/**
362 * @brief The added sizes of the peer's views
363 */
364static unsigned int view_sizes;
365
366/**
352 * Return value from 'main'. 367 * Return value from 'main'.
353 */ 368 */
354static int ok; 369static int ok;
@@ -1813,20 +1828,26 @@ static int ensure_folder_exist (void)
1813 return GNUNET_YES; 1828 return GNUNET_YES;
1814} 1829}
1815 1830
1816static void 1831static const char *
1817store_stats_file_name (struct RPSPeer *rps_peer) 1832store_prefix_file_name (struct RPSPeer *rps_peer, const char *prefix)
1818{ 1833{
1819 unsigned int len_file_name; 1834 unsigned int len_file_name;
1820 unsigned int out_size; 1835 unsigned int out_size;
1821 char *file_name; 1836 char *file_name;
1822 1837 const char *pid_long;
1823 if (GNUNET_SYSERR == ensure_folder_exist()) return; 1838
1824 len_file_name = (14 + strlen (GNUNET_i2s_full (rps_peer->peer_id)) + 1) * sizeof (char); 1839 if (GNUNET_SYSERR == ensure_folder_exist()) return NULL;
1840 pid_long = GNUNET_i2s_full (rps_peer->peer_id);
1841 len_file_name = (strlen (prefix) +
1842 strlen (pid_long) +
1843 11)
1844 * sizeof (char);
1825 file_name = GNUNET_malloc (len_file_name); 1845 file_name = GNUNET_malloc (len_file_name);
1826 out_size = GNUNET_snprintf (file_name, 1846 out_size = GNUNET_snprintf (file_name,
1827 len_file_name, 1847 len_file_name,
1828 "/tmp/rps/stat-%s", 1848 "/tmp/rps/%s-%s",
1829 GNUNET_i2s_full (rps_peer->peer_id)); 1849 prefix,
1850 pid_long);
1830 if (len_file_name < out_size || 1851 if (len_file_name < out_size ||
1831 0 > out_size) 1852 0 > out_size)
1832 { 1853 {
@@ -1835,10 +1856,237 @@ store_stats_file_name (struct RPSPeer *rps_peer)
1835 len_file_name, 1856 len_file_name,
1836 out_size); 1857 out_size);
1837 } 1858 }
1838 rps_peer->file_name_stats = file_name; 1859 return file_name;
1860}
1861
1862static uint32_t fac (uint32_t x)
1863{
1864 if (1 >= x)
1865 {
1866 return x;
1867 }
1868 return x * fac (x - 1);
1869}
1870
1871static uint32_t binom (uint32_t n, uint32_t k)
1872{
1873 //GNUNET_assert (n >= k);
1874 if (k > n) return 0;
1875 if (0 > n) return 0;
1876 if (0 > k) return 0;
1877 if (0 == k) return 1;
1878 return fac (n)
1879 /
1880 fac(k) * fac(n - k);
1881}
1882
1883/**
1884 * @brief is b in view of a?
1885 *
1886 * @param a
1887 * @param b
1888 *
1889 * @return
1890 */
1891static int is_in_view (uint32_t a, uint32_t b)
1892{
1893 uint32_t i;
1894 for (i = 0; i < rps_peers[a].cur_view_count; i++)
1895 {
1896 if (0 == memcmp (rps_peers[b].peer_id,
1897 &rps_peers[a].cur_view[i],
1898 sizeof (struct GNUNET_PeerIdentity)))
1899 {
1900 return GNUNET_YES;
1901 }
1902 }
1903 return GNUNET_NO;
1904}
1905
1906static uint32_t get_idx_of_pid (const struct GNUNET_PeerIdentity *pid)
1907{
1908 uint32_t i;
1909
1910 for (i = 0; i < num_peers; i++)
1911 {
1912 if (0 == memcmp (pid,
1913 rps_peers[i].peer_id,
1914 sizeof (struct GNUNET_PeerIdentity)))
1915 {
1916 return i;
1917 }
1918 }
1919 //return 0; /* Should not happen - make compiler happy */
1920 GNUNET_assert (0);
1839} 1921}
1840 1922
1841void count_peer_in_views (uint32_t *count_peers) 1923/**
1924 * @brief Counts number of peers in view of a that have b in their view
1925 *
1926 * @param a
1927 * @param uint32_tb
1928 *
1929 * @return
1930 */
1931static uint32_t count_containing_views (uint32_t a, uint32_t b)
1932{
1933 uint32_t i;
1934 uint32_t peer_idx;
1935 uint32_t count = 0;
1936
1937 for (i = 0; i < rps_peers[a].cur_view_count; i++)
1938 {
1939 peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
1940 if (GNUNET_YES == is_in_view (peer_idx, b))
1941 {
1942 count++;
1943 }
1944 }
1945 return count;
1946}
1947
1948/**
1949 * @brief Computes the probability for each other peer to be selected by the
1950 * sampling process based on the views of all peers
1951 *
1952 * @param peer_idx index of the peer that is about to sample
1953 */
1954static void compute_probabilities (uint32_t peer_idx)
1955{
1956 //double probs[num_peers] = { 0 };
1957 double probs[num_peers];
1958 size_t probs_as_str_size = (num_peers * 6 + 1) * sizeof (char);
1959 char *probs_as_str = GNUNET_malloc (probs_as_str_size);
1960 char *probs_as_str_cpy;
1961 uint32_t i;
1962 double prob_push;
1963 double prob_pull;
1964 uint32_t view_size;
1965 uint32_t cont_views;
1966 uint32_t number_of_being_in_pull_events;
1967 int tmp;
1968 uint32_t count_non_zero_prob = 0;
1969
1970 /* Firstly without knowledge of old views */
1971 for (i = 0; i < num_peers; i++)
1972 {
1973 view_size = rps_peers[i].cur_view_count;
1974 /* For peer i the probability of being sampled is
1975 * evenly distributed among all possibly observed peers. */
1976 /* We could have observed a peer in three cases:
1977 * 1. peer sent a push
1978 * 2. peer was contained in a pull reply
1979 * 3. peer was in history (sampler) - ignored for now */
1980 /* 1. Probability of having received a push from peer i */
1981 if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
1982 (1 <= (0.45 * view_size)))
1983 {
1984 prob_push = 1.0 * binom (0.45 * view_size, 1)
1985 /
1986 binom (view_size, 0.45 * view_size);
1987 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1988 "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
1989 peer_idx,
1990 i,
1991 prob_push);
1992 } else {
1993 prob_push = 0;
1994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1995 "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
1996 peer_idx,
1997 i);
1998 }
1999 /* 2. Probability of peer i being contained in pulls */
2000 view_size = rps_peers[peer_idx].cur_view_count;
2001 cont_views = count_containing_views (peer_idx, i);
2002 number_of_being_in_pull_events =
2003 (binom (view_size, 0.45 * view_size) -
2004 binom (view_size - cont_views, 0.45 * view_size));
2005 if (0 != number_of_being_in_pull_events)
2006 {
2007 prob_pull = 1.0 / number_of_being_in_pull_events;
2008 } else
2009 {
2010 prob_pull = 0;
2011 }
2012 probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2013
2014 if (0 != probs[i]) count_non_zero_prob++;
2015 }
2016 /* normalize */
2017 if (0 != count_non_zero_prob)
2018 {
2019 for (i = 0; i < num_peers; i++)
2020 {
2021 probs[i] = probs[i] * (1.0 / count_non_zero_prob);
2022 }
2023 } else {
2024 for (i = 0; i < num_peers; i++)
2025 {
2026 probs[i] = 0;
2027 }
2028 }
2029 /* str repr */
2030 for (i = 0; i < num_peers; i++)
2031 {
2032 probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2033 tmp = GNUNET_snprintf (probs_as_str,
2034 probs_as_str_size,
2035 "%s %3.2f", probs_as_str_cpy, probs[i]);
2036 GNUNET_free (probs_as_str_cpy);
2037 GNUNET_assert (0 <= tmp);
2038 }
2039
2040 to_file_w_len (rps_peers[peer_idx].file_name_probs,
2041 probs_as_str_size,
2042 probs_as_str);
2043 GNUNET_free (probs_as_str);
2044}
2045
2046/**
2047 * @brief This counts the number of peers in which views a given peer occurs.
2048 *
2049 * It also stores this value in the rps peer.
2050 *
2051 * @param peer_idx the index of the peer to count the representation
2052 *
2053 * @return the number of occurrences
2054 */
2055static uint32_t count_peer_in_views_2 (uint32_t peer_idx)
2056{
2057 uint32_t i, j;
2058 uint32_t count = 0;
2059
2060 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2061 {
2062 for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2063 {
2064 if (0 == memcmp (rps_peers[peer_idx].peer_id,
2065 &rps_peers[i].cur_view[j],
2066 sizeof (struct GNUNET_PeerIdentity)))
2067 {
2068 count++;
2069 break;
2070 }
2071 }
2072 }
2073 rps_peers[peer_idx].count_in_views = count;
2074 return count;
2075}
2076
2077static uint32_t cumulated_view_sizes ()
2078{
2079 uint32_t i;
2080
2081 view_sizes = 0;
2082 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2083 {
2084 view_sizes += rps_peers[i].cur_view_count;
2085 }
2086 return view_sizes;
2087}
2088
2089static void count_peer_in_views (uint32_t *count_peers)
1842{ 2090{
1843 uint32_t i, j; 2091 uint32_t i, j;
1844 2092
@@ -1901,11 +2149,7 @@ void compute_diversity ()
1901void print_view_sizes() 2149void print_view_sizes()
1902{ 2150{
1903 uint32_t i; 2151 uint32_t i;
1904 char *view_sizes_str = NULL;
1905 uint32_t view_sizes_str_len = 0;
1906 char view_size_curr[32] = { 0 };
1907 2152
1908 GNUNET_array_grow (view_sizes_str, view_sizes_str_len, num_peers * 3);
1909 for (i = 0; i < num_peers; i++) /* Peer to count */ 2153 for (i = 0; i < num_peers; i++) /* Peer to count */
1910 { 2154 {
1911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1913,19 +2157,7 @@ void print_view_sizes()
1913 i, 2157 i,
1914 GNUNET_i2s (rps_peers[i].peer_id), 2158 GNUNET_i2s (rps_peers[i].peer_id),
1915 rps_peers[i].cur_view_count); 2159 rps_peers[i].cur_view_count);
1916 GNUNET_snprintf (view_size_curr,
1917 sizeof (view_size_curr),
1918 " %" PRIu32 "",
1919 rps_peers[i].cur_view_count);
1920 if (view_sizes_str_len < view_sizes_str_len + strlen (view_size_curr))
1921 {
1922 GNUNET_array_grow (view_sizes_str, view_sizes_str_len, view_sizes_str_len + 10);
1923 }
1924 strncat (view_sizes_str, view_size_curr, strlen(view_size_curr));
1925 } 2160 }
1926 to_file_ ("/tmp/rps/view_sizes.txt",
1927 view_sizes_str);
1928 GNUNET_array_grow (view_sizes_str, view_sizes_str_len, 0);
1929} 2161}
1930 2162
1931void all_views_updated_cb() 2163void all_views_updated_cb()
@@ -1935,30 +2167,57 @@ void all_views_updated_cb()
1935} 2167}
1936 2168
1937void view_update_cb (void *cls, 2169void view_update_cb (void *cls,
1938 uint64_t num_peers, 2170 uint64_t view_size,
1939 const struct GNUNET_PeerIdentity *peers) 2171 const struct GNUNET_PeerIdentity *peers)
1940{ 2172{
1941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1942 "View was updated (%" PRIu64 ")\n", num_peers); 2174 "View was updated (%" PRIu64 ")\n", view_size);
1943 struct RPSPeer *rps_peer = (struct RPSPeer *) cls; 2175 struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
1944 for (int i = 0; i < num_peers; i++) 2176 to_file ("/tmp/rps/view_sizes.txt",
2177 "%" PRIu64 " %" PRIu32 "",
2178 rps_peer->index,
2179 view_size);
2180 for (int i = 0; i < view_size; i++)
1945 { 2181 {
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1947 "\t%s\n", GNUNET_i2s (&peers[i])); 2183 "\t%s\n", GNUNET_i2s (&peers[i]));
1948 } 2184 }
1949 GNUNET_array_grow (rps_peer->cur_view, 2185 GNUNET_array_grow (rps_peer->cur_view,
1950 rps_peer->cur_view_count, 2186 rps_peer->cur_view_count,
1951 num_peers); 2187 view_size);
1952 //*rps_peer->cur_view = *peers; 2188 //*rps_peer->cur_view = *peers;
1953 memcpy (rps_peer->cur_view, 2189 memcpy (rps_peer->cur_view,
1954 peers, 2190 peers,
1955 num_peers * sizeof (struct GNUNET_PeerIdentity)); 2191 view_size * sizeof (struct GNUNET_PeerIdentity));
2192 to_file ("/tmp/rps/count_in_views.txt",
2193 "%" PRIu64 " %" PRIu32 "",
2194 rps_peer->index,
2195 count_peer_in_views_2 (rps_peer->index));
2196 cumulated_view_sizes();
2197 to_file ("/tmp/rps/repr.txt",
2198 "%" PRIu64 /* index */
2199 " %" PRIu32 /* occurrence in views */
2200 " %" PRIu32 /* view sizes */
2201 " %f" /* fraction of repr in views */
2202 " %f" /* average view size */
2203 " %f" /* prob of occurrence in view slot */
2204 " %f" "", /* exp frac of repr in views */
2205 rps_peer->index,
2206 count_peer_in_views_2 (rps_peer->index),
2207 view_sizes,
2208 count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2209 view_sizes / (view_size * 1.0), /* average view size */
2210 1.0 /view_size, /* prob of occurrence in view slot */
2211 (1.0/view_size) * (view_sizes/view_size) /* expected fraction of repr in views */
2212 );
2213 compute_probabilities (rps_peer->index);
1956 all_views_updated_cb(); 2214 all_views_updated_cb();
1957} 2215}
1958 2216
1959static void 2217static void
1960pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h) 2218pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1961{ 2219{
2220 rps_peer->file_name_probs = store_prefix_file_name (rps_peer, "probs");
1962 GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer); 2221 GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
1963} 2222}
1964 2223
@@ -1968,11 +2227,14 @@ void write_final_stats (void){
1968 for (i = 0; i < num_peers; i++) 2227 for (i = 0; i < num_peers; i++)
1969 { 2228 {
1970 to_file ("/tmp/rps/final_stats.dat", 2229 to_file ("/tmp/rps/final_stats.dat",
1971 "%s %" PRIu64 2230 "%" PRIu32 " " /* index */
1972 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 /* blocking */ 2231 "%s %" /* id */
1973 " %" PRIu64 " %" PRIu64 " %" PRIu64 /* issued */ 2232 PRIu64 " %" /* rounds */
1974 " %" PRIu64 " %" PRIu64 " %" PRIu64 /* sent */ 2233 PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" /* blocking */
1975 " %" PRIu64 " %" PRIu64 " %" PRIu64 /* recv */, 2234 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* issued */
2235 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* sent */
2236 PRIu64 " %" PRIu64 " %" PRIu64 /* recv */,
2237 i,
1976 GNUNET_i2s (rps_peers[i].peer_id), 2238 GNUNET_i2s (rps_peers[i].peer_id),
1977 rps_peers[i].num_rounds, 2239 rps_peers[i].num_rounds,
1978 rps_peers[i].num_blocks, 2240 rps_peers[i].num_blocks,
@@ -2028,9 +2290,10 @@ post_test_shutdown_ready_cb (void *cls,
2028 GNUNET_TESTBED_operation_done (rps_peer->stat_op); 2290 GNUNET_TESTBED_operation_done (rps_peer->stat_op);
2029 } 2291 }
2030 2292
2293 write_final_stats ();
2031 if (GNUNET_YES == check_statistics_collect_completed()) 2294 if (GNUNET_YES == check_statistics_collect_completed())
2032 { 2295 {
2033 write_final_stats (); 2296 //write_final_stats ();
2034 GNUNET_free (stat_cls); 2297 GNUNET_free (stat_cls);
2035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2036 "Shutting down\n"); 2299 "Shutting down\n");
@@ -2049,67 +2312,67 @@ post_test_shutdown_ready_cb (void *cls,
2049 */ 2312 */
2050enum STAT_TYPE stat_str_2_type (const char *stat_str) 2313enum STAT_TYPE stat_str_2_type (const char *stat_str)
2051{ 2314{
2052 if (GNUNET_YES == strncmp ("# rounds", stat_str, strlen ("# rounds"))) 2315 if (0 == strncmp ("# rounds blocked - no pull replies", stat_str, strlen ("# rounds blocked - no pull replies")))
2053 { 2316 {
2054 return STAT_TYPE_ROUNDS; 2317 return STAT_TYPE_BLOCKS_NO_PULL;
2055 } 2318 }
2056 if (GNUNET_YES == strncmp ("# rounds blocked", stat_str, strlen ("# rounds blocked"))) 2319 else if (0 == strncmp ("# rounds blocked - too many pushes, no pull replies", stat_str, strlen ("# rounds blocked - too many pushes, no pull replies")))
2057 { 2320 {
2058 return STAT_TYPE_BLOCKS; 2321 return STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL;
2059 } 2322 }
2060 if (0 == strncmp ("# rounds blocked - too many pushes", stat_str, strlen ("# rounds blocked - too many pushes"))) 2323 else if (0 == strncmp ("# rounds blocked - too many pushes", stat_str, strlen ("# rounds blocked - too many pushes")))
2061 { 2324 {
2062 return STAT_TYPE_BLOCKS_MANY_PUSH; 2325 return STAT_TYPE_BLOCKS_MANY_PUSH;
2063 } 2326 }
2064 if (0 == strncmp ("# rounds blocked - no pushes", stat_str, strlen ("# rounds blocked - no pushes"))) 2327 else if (0 == strncmp ("# rounds blocked - no pushes, no pull replies", stat_str, strlen ("# rounds blocked - no pushes, no pull replies")))
2065 { 2328 {
2066 return STAT_TYPE_BLOCKS_NO_PUSH; 2329 return STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL;
2067 } 2330 }
2068 if (0 == strncmp ("# rounds blocked - no pull replies", stat_str, strlen ("# rounds blocked - no pull replies"))) 2331 else if (0 == strncmp ("# rounds blocked - no pushes", stat_str, strlen ("# rounds blocked - no pushes")))
2069 { 2332 {
2070 return STAT_TYPE_BLOCKS_NO_PULL; 2333 return STAT_TYPE_BLOCKS_NO_PUSH;
2071 } 2334 }
2072 if (0 == strncmp ("# rounds blocked - too many pushes, no pull replies", stat_str, strlen ("# rounds blocked - too many pushes, no pull replies"))) 2335 else if (0 == strncmp ("# rounds blocked", stat_str, strlen ("# rounds blocked")))
2073 { 2336 {
2074 return STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL; 2337 return STAT_TYPE_BLOCKS;
2075 } 2338 }
2076 if (0 == strncmp ("# rounds blocked - no pushes, no pull replies", stat_str, strlen ("# rounds blocked - no pushes, no pull replies"))) 2339 else if (0 == strncmp ("# rounds", stat_str, strlen ("# rounds")))
2077 { 2340 {
2078 return STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL; 2341 return STAT_TYPE_ROUNDS;
2079 } 2342 }
2080 if (0 == strncmp ("# push send issued", stat_str, strlen ("# push send issued"))) 2343 else if (0 == strncmp ("# push send issued", stat_str, strlen ("# push send issued")))
2081 { 2344 {
2082 return STAT_TYPE_ISSUED_PUSH_SEND; 2345 return STAT_TYPE_ISSUED_PUSH_SEND;
2083 } 2346 }
2084 if (0 == strncmp ("# pull request send issued", stat_str, strlen ("# pull request send issued"))) 2347 else if (0 == strncmp ("# pull request send issued", stat_str, strlen ("# pull request send issued")))
2085 { 2348 {
2086 return STAT_TYPE_ISSUED_PULL_REQ; 2349 return STAT_TYPE_ISSUED_PULL_REQ;
2087 } 2350 }
2088 if (0 == strncmp ("# pull reply send issued", stat_str, strlen ("# pull reply send issued"))) 2351 else if (0 == strncmp ("# pull reply send issued", stat_str, strlen ("# pull reply send issued")))
2089 { 2352 {
2090 return STAT_TYPE_ISSUED_PULL_REP; 2353 return STAT_TYPE_ISSUED_PULL_REP;
2091 } 2354 }
2092 if (0 == strncmp ("# pushes sent", stat_str, strlen ("# pushes sent"))) 2355 else if (0 == strncmp ("# pushes sent", stat_str, strlen ("# pushes sent")))
2093 { 2356 {
2094 return STAT_TYPE_SENT_PUSH_SEND; 2357 return STAT_TYPE_SENT_PUSH_SEND;
2095 } 2358 }
2096 if (0 == strncmp ("# pull requests sent", stat_str, strlen ("# pull requests sent"))) 2359 else if (0 == strncmp ("# pull requests sent", stat_str, strlen ("# pull requests sent")))
2097 { 2360 {
2098 return STAT_TYPE_SENT_PULL_REQ; 2361 return STAT_TYPE_SENT_PULL_REQ;
2099 } 2362 }
2100 if (0 == strncmp ("# pull replys sent", stat_str, strlen ("# pull replys sent"))) 2363 else if (0 == strncmp ("# pull replys sent", stat_str, strlen ("# pull replys sent")))
2101 { 2364 {
2102 return STAT_TYPE_SENT_PULL_REP; 2365 return STAT_TYPE_SENT_PULL_REP;
2103 } 2366 }
2104 if (0 == strncmp ("# push message received", stat_str, strlen ("# push message received"))) 2367 else if (0 == strncmp ("# push message received", stat_str, strlen ("# push message received")))
2105 { 2368 {
2106 return STAT_TYPE_RECV_PUSH_SEND; 2369 return STAT_TYPE_RECV_PUSH_SEND;
2107 } 2370 }
2108 if (0 == strncmp ("# pull request message received", stat_str, strlen ("# pull request message received"))) 2371 else if (0 == strncmp ("# pull request message received", stat_str, strlen ("# pull request message received")))
2109 { 2372 {
2110 return STAT_TYPE_RECV_PULL_REQ; 2373 return STAT_TYPE_RECV_PULL_REQ;
2111 } 2374 }
2112 if (0 == strncmp ("# pull reply messages received", stat_str, strlen ("# pull reply messages received"))) 2375 else if (0 == strncmp ("# pull reply messages received", stat_str, strlen ("# pull reply messages received")))
2113 { 2376 {
2114 return STAT_TYPE_RECV_PULL_REP; 2377 return STAT_TYPE_RECV_PULL_REP;
2115 } 2378 }
@@ -2191,49 +2454,66 @@ stat_iterator (void *cls,
2191 //stat_type_2_str (stat_cls->stat_type), 2454 //stat_type_2_str (stat_cls->stat_type),
2192 name, 2455 name,
2193 value); 2456 value);
2194 //to_file (rps_peer->file_name_stats, 2457 to_file (rps_peer->file_name_stats,
2195 // "%s: %" PRIu64 "\n", 2458 "%s: %" PRIu64 "\n",
2196 // name, 2459 name,
2197 // value); 2460 value);
2198 switch (stat_str_2_type (name)) 2461 switch (stat_str_2_type (name))
2199 { 2462 {
2200 case STAT_TYPE_ROUNDS: 2463 case STAT_TYPE_ROUNDS:
2201 rps_peer->num_blocks = value; 2464 rps_peer->num_rounds = value;
2465 break;
2202 case STAT_TYPE_BLOCKS: 2466 case STAT_TYPE_BLOCKS:
2203 rps_peer->num_blocks = value; 2467 rps_peer->num_blocks = value;
2468 break;
2204 case STAT_TYPE_BLOCKS_MANY_PUSH: 2469 case STAT_TYPE_BLOCKS_MANY_PUSH:
2205 rps_peer->num_blocks_many_push = value; 2470 rps_peer->num_blocks_many_push = value;
2471 break;
2206 case STAT_TYPE_BLOCKS_NO_PUSH: 2472 case STAT_TYPE_BLOCKS_NO_PUSH:
2207 rps_peer->num_blocks_no_push = value; 2473 rps_peer->num_blocks_no_push = value;
2474 break;
2208 case STAT_TYPE_BLOCKS_NO_PULL: 2475 case STAT_TYPE_BLOCKS_NO_PULL:
2209 rps_peer->num_blocks_no_pull = value; 2476 rps_peer->num_blocks_no_pull = value;
2477 break;
2210 case STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL: 2478 case STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL:
2211 rps_peer->num_blocks_many_push_no_pull = value; 2479 rps_peer->num_blocks_many_push_no_pull = value;
2480 break;
2212 case STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL: 2481 case STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL:
2213 rps_peer->num_blocks_no_push_no_pull = value; 2482 rps_peer->num_blocks_no_push_no_pull = value;
2483 break;
2214 case STAT_TYPE_ISSUED_PUSH_SEND: 2484 case STAT_TYPE_ISSUED_PUSH_SEND:
2215 rps_peer->num_issued_push = value; 2485 rps_peer->num_issued_push = value;
2486 break;
2216 case STAT_TYPE_ISSUED_PULL_REQ: 2487 case STAT_TYPE_ISSUED_PULL_REQ:
2217 rps_peer->num_issued_pull_req = value; 2488 rps_peer->num_issued_pull_req = value;
2489 break;
2218 case STAT_TYPE_ISSUED_PULL_REP: 2490 case STAT_TYPE_ISSUED_PULL_REP:
2219 rps_peer->num_issued_pull_rep = value; 2491 rps_peer->num_issued_pull_rep = value;
2492 break;
2220 case STAT_TYPE_SENT_PUSH_SEND: 2493 case STAT_TYPE_SENT_PUSH_SEND:
2221 rps_peer->num_sent_push = value; 2494 rps_peer->num_sent_push = value;
2495 break;
2222 case STAT_TYPE_SENT_PULL_REQ: 2496 case STAT_TYPE_SENT_PULL_REQ:
2223 rps_peer->num_sent_pull_req = value; 2497 rps_peer->num_sent_pull_req = value;
2498 break;
2224 case STAT_TYPE_SENT_PULL_REP: 2499 case STAT_TYPE_SENT_PULL_REP:
2225 rps_peer->num_sent_pull_rep = value; 2500 rps_peer->num_sent_pull_rep = value;
2501 break;
2226 case STAT_TYPE_RECV_PUSH_SEND: 2502 case STAT_TYPE_RECV_PUSH_SEND:
2227 rps_peer->num_recv_push = value; 2503 rps_peer->num_recv_push = value;
2504 break;
2228 case STAT_TYPE_RECV_PULL_REQ: 2505 case STAT_TYPE_RECV_PULL_REQ:
2229 rps_peer->num_recv_pull_req = value; 2506 rps_peer->num_recv_pull_req = value;
2507 break;
2230 case STAT_TYPE_RECV_PULL_REP: 2508 case STAT_TYPE_RECV_PULL_REP:
2231 rps_peer->num_recv_pull_rep = value; 2509 rps_peer->num_recv_pull_rep = value;
2510 break;
2232 case STAT_TYPE_MAX: 2511 case STAT_TYPE_MAX:
2233 default: 2512 default:
2234 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2513 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2235 "Unknown statistics string: %s\n", 2514 "Unknown statistics string: %s\n",
2236 name); 2515 name);
2516 break;
2237 } 2517 }
2238 return GNUNET_OK; 2518 return GNUNET_OK;
2239} 2519}
@@ -2260,7 +2540,7 @@ void post_profiler (struct RPSPeer *rps_peer)
2260 stat_cls = GNUNET_malloc (sizeof (struct STATcls)); 2540 stat_cls = GNUNET_malloc (sizeof (struct STATcls));
2261 stat_cls->rps_peer = rps_peer; 2541 stat_cls->rps_peer = rps_peer;
2262 stat_cls->stat_type = stat_type; 2542 stat_cls->stat_type = stat_type;
2263 store_stats_file_name (rps_peer); 2543 rps_peer->file_name_stats = store_prefix_file_name (rps_peer, "stats");
2264 GNUNET_STATISTICS_get (rps_peer->stats_h, 2544 GNUNET_STATISTICS_get (rps_peer->stats_h,
2265 "rps", 2545 "rps",
2266 stat_type_2_str (stat_type), 2546 stat_type_2_str (stat_type),
@@ -2303,7 +2583,6 @@ run (void *cls,
2303{ 2583{
2304 unsigned int i; 2584 unsigned int i;
2305 struct OpListEntry *entry; 2585 struct OpListEntry *entry;
2306 uint32_t num_mal_peers;
2307 2586
2308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n"); 2587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2309 2588
@@ -2344,24 +2623,19 @@ run (void *cls,
2344 } 2623 }
2345 2624
2346 /* Bring peers up */ 2625 /* Bring peers up */
2347 num_mal_peers = round (portion * num_peers);
2348 GNUNET_assert (num_peers == n_peers); 2626 GNUNET_assert (num_peers == n_peers);
2349 for (i = 0; i < n_peers; i++) 2627 for (i = 0; i < n_peers; i++)
2350 { 2628 {
2351 rps_peers[i].index = i; 2629 rps_peers[i].index = i;
2352 if ( (rps_peers[i].num_recv_ids < rps_peers[i].num_ids_to_request) || 2630 rps_peers[i].op =
2353 (i < num_mal_peers) ) 2631 GNUNET_TESTBED_service_connect (&rps_peers[i],
2354 { 2632 peers[i],
2355 rps_peers[i].op = 2633 "rps",
2356 GNUNET_TESTBED_service_connect (&rps_peers[i], 2634 &rps_connect_complete_cb,
2357 peers[i], 2635 &rps_peers[i],
2358 "rps", 2636 &rps_connect_adapter,
2359 &rps_connect_complete_cb, 2637 &rps_disconnect_adapter,
2360 &rps_peers[i], 2638 &rps_peers[i]);
2361 &rps_connect_adapter,
2362 &rps_disconnect_adapter,
2363 &rps_peers[i]);
2364 }
2365 /* Connect all peers to statistics service */ 2639 /* Connect all peers to statistics service */
2366 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics) 2640 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics)
2367 { 2641 {
diff --git a/src/rps/test_rps.conf b/src/rps/test_rps.conf
index fce07c945..0b49b4e76 100644
--- a/src/rps/test_rps.conf
+++ b/src/rps/test_rps.conf
@@ -19,7 +19,7 @@ FILENAME_VALID_PEERS = $GNUNET_DATA_HOME/rps/valid_peers.txt
19# until we receive the first estimate from NSE. 19# until we receive the first estimate from NSE.
20# Keep in mind, that (networksize)^(1/3) should be enough. 20# Keep in mind, that (networksize)^(1/3) should be enough.
21# So, 50 is enough for a network of size 50^3 = 125000 21# So, 50 is enough for a network of size 50^3 = 125000
22INITSIZE = 4 22MINSIZE = 4
23 23
24[testbed] 24[testbed]
25HOSTNAME = localhost 25HOSTNAME = localhost