aboutsummaryrefslogtreecommitdiff
path: root/src/nse/gnunet-service-nse.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-05-04 22:16:24 +0200
committerChristian Grothoff <christian@grothoff.org>2019-05-04 22:16:24 +0200
commit80f480c752fd8dfa1be51d78fce314d9f0650b50 (patch)
tree459c21a3fde3b5f66194ac9960632de53586c5f0 /src/nse/gnunet-service-nse.c
parent3d2a951fa12546c09809f0a4d7e789ef8e971b03 (diff)
downloadgnunet-80f480c752fd8dfa1be51d78fce314d9f0650b50.tar.gz
gnunet-80f480c752fd8dfa1be51d78fce314d9f0650b50.zip
simplify MQ logic to always carry the same kinds of flags, and extend transport API to pass them to (TNG) service
Diffstat (limited to 'src/nse/gnunet-service-nse.c')
-rw-r--r--src/nse/gnunet-service-nse.c627
1 files changed, 258 insertions, 369 deletions
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 5b12c4b98..09316dbcf 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -51,7 +51,6 @@
51#include <gcrypt.h> 51#include <gcrypt.h>
52 52
53 53
54
55/** 54/**
56 * Should messages be delayed randomly? This option should be set to 55 * Should messages be delayed randomly? This option should be set to
57 * #GNUNET_NO only for experiments, not in production. 56 * #GNUNET_NO only for experiments, not in production.
@@ -69,12 +68,15 @@
69#define HISTORY_SIZE 64 68#define HISTORY_SIZE 64
70 69
71/** 70/**
72 * Message priority to use. 71 * Message priority to use. No real rush, reliability not
72 * required. Corking OK.
73 */ 73 */
74#define NSE_PRIORITY GNUNET_CORE_PRIO_CRITICAL_CONTROL 74#define NSE_PRIORITY \
75 (GNUNET_MQ_PRIO_BACKGROUND | GNUNET_MQ_PREF_UNRELIABLE | \
76 GNUNET_MQ_PREF_CORK_ALLOWED)
75 77
76#if FREEBSD 78#if FREEBSD
77#define log2(a) (log(a)/log(2)) 79#define log2(a) (log (a) / log (2))
78#endif 80#endif
79 81
80/** 82/**
@@ -158,7 +160,6 @@ struct NSEPeerEntry
158 unsigned int last_transmitted_size; 160 unsigned int last_transmitted_size;
159 161
160#endif 162#endif
161
162}; 163};
163 164
164 165
@@ -380,13 +381,14 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
380 if (0 != estimate_count) 381 if (0 != estimate_count)
381 { 382 {
382 mean = sum / estimate_count; 383 mean = sum / estimate_count;
383 variance = (vsq - mean * sum) / (estimate_count - 1.0); // terrible for numerical stability... 384 variance = (vsq - mean * sum) /
385 (estimate_count - 1.0); // terrible for numerical stability...
384 } 386 }
385#endif 387#endif
386 if (variance >= 0) 388 if (variance >= 0)
387 std_dev = sqrt (variance); 389 std_dev = sqrt (variance);
388 else 390 else
389 std_dev = variance; /* must be infinity due to estimate_count == 0 */ 391 std_dev = variance; /* must be infinity due to estimate_count == 0 */
390 current_std_dev = std_dev; 392 current_std_dev = std_dev;
391 current_size_estimate = mean; 393 current_size_estimate = mean;
392 394
@@ -401,14 +403,12 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
401 j = 1; /* Avoid log2(0); can only happen if CORE didn't report 403 j = 1; /* Avoid log2(0); can only happen if CORE didn't report
402 connection to self yet */ 404 connection to self yet */
403 nsize = log2 (j); 405 nsize = log2 (j);
404 em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, 406 em->size_estimate = GNUNET_hton_double (GNUNET_MAX (se, nsize));
405 nsize));
406 em->std_deviation = GNUNET_hton_double (std_dev); 407 em->std_deviation = GNUNET_hton_double (std_dev);
407 GNUNET_STATISTICS_set (stats, 408 GNUNET_STATISTICS_set (stats,
408 "# nodes in the network (estimate)", 409 "# nodes in the network (estimate)",
409 (uint64_t) pow (2, GNUNET_MAX (se, 410 (uint64_t) pow (2, GNUNET_MAX (se, nsize)),
410 nsize)), 411 GNUNET_NO);
411 GNUNET_NO);
412 } 412 }
413} 413}
414 414
@@ -423,23 +423,19 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
423 * @param message the message received 423 * @param message the message received
424 */ 424 */
425static void 425static void
426handle_start (void *cls, 426handle_start (void *cls, const struct GNUNET_MessageHeader *message)
427 const struct GNUNET_MessageHeader *message)
428{ 427{
429 struct GNUNET_SERVICE_Client *client = cls; 428 struct GNUNET_SERVICE_Client *client = cls;
430 struct GNUNET_MQ_Handle *mq; 429 struct GNUNET_MQ_Handle *mq;
431 struct GNUNET_NSE_ClientMessage em; 430 struct GNUNET_NSE_ClientMessage em;
432 struct GNUNET_MQ_Envelope *env; 431 struct GNUNET_MQ_Envelope *env;
433 432
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
435 "Received START message from client\n");
436 mq = GNUNET_SERVICE_client_get_mq (client); 434 mq = GNUNET_SERVICE_client_get_mq (client);
437 GNUNET_notification_context_add (nc, 435 GNUNET_notification_context_add (nc, mq);
438 mq);
439 setup_estimate_message (&em); 436 setup_estimate_message (&em);
440 env = GNUNET_MQ_msg_copy (&em.header); 437 env = GNUNET_MQ_msg_copy (&em.header);
441 GNUNET_MQ_send (mq, 438 GNUNET_MQ_send (mq, env);
442 env);
443 GNUNET_SERVICE_client_continue (client); 439 GNUNET_SERVICE_client_continue (client);
444} 440}
445 441
@@ -459,8 +455,8 @@ get_matching_bits_delay (uint32_t matching_bits)
459 // x is matching_bits 455 // x is matching_bits
460 // p' is current_size_estimate 456 // p' is current_size_estimate
461 return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0) - 457 return ((double) gnunet_nse_interval.rel_value_us / (double) 2.0) -
462 ((gnunet_nse_interval.rel_value_us / M_PI) * 458 ((gnunet_nse_interval.rel_value_us / M_PI) *
463 atan (matching_bits - current_size_estimate)); 459 atan (matching_bits - current_size_estimate));
464} 460}
465 461
466 462
@@ -482,10 +478,10 @@ get_delay_randomization (uint32_t matching_bits)
482 i = (uint32_t) (d / (double) (hop_count_max + 1)); 478 i = (uint32_t) (d / (double) (hop_count_max + 1));
483 ret.rel_value_us = i; 479 ret.rel_value_us = i;
484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485 "Randomizing flood using latencies up to %s\n", 481 "Randomizing flood using latencies up to %s\n",
486 GNUNET_STRINGS_relative_time_to_string (ret, 482 GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES));
487 GNUNET_YES)); 483 ret.rel_value_us =
488 ret.rel_value_us = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, i + 1); 484 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, i + 1);
489 return ret; 485 return ret;
490#else 486#else
491 return GNUNET_TIME_UNIT_ZERO; 487 return GNUNET_TIME_UNIT_ZERO;
@@ -501,19 +497,18 @@ get_delay_randomization (uint32_t matching_bits)
501 * @param result where to write the resulting hash 497 * @param result where to write the resulting hash
502 */ 498 */
503static void 499static void
504pow_hash (const void *buf, 500pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
505 size_t buf_len,
506 struct GNUNET_HashCode *result)
507{ 501{
508 GNUNET_break (0 == 502 GNUNET_break (
509 gcry_kdf_derive (buf, buf_len, 503 0 == gcry_kdf_derive (buf,
510 GCRY_KDF_SCRYPT, 504 buf_len,
511 1 /* subalgo */, 505 GCRY_KDF_SCRYPT,
512 "gnunet-proof-of-work", 506 1 /* subalgo */,
513 strlen ("gnunet-proof-of-work"), 507 "gnunet-proof-of-work",
514 2 /* iterations; keep cost of individual op small */, 508 strlen ("gnunet-proof-of-work"),
515 sizeof (struct GNUNET_HashCode), 509 2 /* iterations; keep cost of individual op small */,
516 result)); 510 sizeof (struct GNUNET_HashCode),
511 result));
517} 512}
518 513
519 514
@@ -534,11 +529,8 @@ get_matching_bits (struct GNUNET_TIME_Absolute timestamp,
534 GNUNET_CRYPTO_hash (&timestamp.abs_value_us, 529 GNUNET_CRYPTO_hash (&timestamp.abs_value_us,
535 sizeof (timestamp.abs_value_us), 530 sizeof (timestamp.abs_value_us),
536 &timestamp_hash); 531 &timestamp_hash);
537 GNUNET_CRYPTO_hash (id, 532 GNUNET_CRYPTO_hash (id, sizeof (struct GNUNET_PeerIdentity), &pid_hash);
538 sizeof (struct GNUNET_PeerIdentity), 533 return GNUNET_CRYPTO_hash_matching_bits (&timestamp_hash, &pid_hash);
539 &pid_hash);
540 return GNUNET_CRYPTO_hash_matching_bits (&timestamp_hash,
541 &pid_hash);
542} 534}
543 535
544 536
@@ -563,20 +555,19 @@ get_transmit_delay (int round_offset)
563 case -1: 555 case -1:
564 /* previous round is randomized between 0 and 50 ms */ 556 /* previous round is randomized between 0 and 50 ms */
565#if USE_RANDOM_DELAYS 557#if USE_RANDOM_DELAYS
566 ret.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 558 ret.rel_value_us =
567 50); 559 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 50);
568#else 560#else
569 ret = GNUNET_TIME_UNIT_ZERO; 561 ret = GNUNET_TIME_UNIT_ZERO;
570#endif 562#endif
571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
572 "Transmitting previous round behind schedule in %s\n", 564 "Transmitting previous round behind schedule in %s\n",
573 GNUNET_STRINGS_relative_time_to_string (ret, 565 GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES));
574 GNUNET_YES));
575 return ret; 566 return ret;
576 case 0: 567 case 0:
577 /* current round is based on best-known matching_bits */ 568 /* current round is based on best-known matching_bits */
578 matching_bits = 569 matching_bits =
579 ntohl (size_estimate_messages[estimate_index].matching_bits); 570 ntohl (size_estimate_messages[estimate_index].matching_bits);
580 dist_delay = get_matching_bits_delay (matching_bits); 571 dist_delay = get_matching_bits_delay (matching_bits);
581 dist_delay += get_delay_randomization (matching_bits).rel_value_us; 572 dist_delay += get_delay_randomization (matching_bits).rel_value_us;
582 ret.rel_value_us = (uint64_t) dist_delay; 573 ret.rel_value_us = (uint64_t) dist_delay;
@@ -584,11 +575,9 @@ get_transmit_delay (int round_offset)
584 "For round %s, delay for %u matching bits is %s\n", 575 "For round %s, delay for %u matching bits is %s\n",
585 GNUNET_STRINGS_absolute_time_to_string (current_timestamp), 576 GNUNET_STRINGS_absolute_time_to_string (current_timestamp),
586 (unsigned int) matching_bits, 577 (unsigned int) matching_bits,
587 GNUNET_STRINGS_relative_time_to_string (ret, 578 GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES));
588 GNUNET_YES));
589 /* now consider round start time and add delay to it */ 579 /* now consider round start time and add delay to it */
590 tgt = GNUNET_TIME_absolute_add (current_timestamp, 580 tgt = GNUNET_TIME_absolute_add (current_timestamp, ret);
591 ret);
592 return GNUNET_TIME_absolute_get_remaining (tgt); 581 return GNUNET_TIME_absolute_get_remaining (tgt);
593 } 582 }
594 GNUNET_break (0); 583 GNUNET_break (0);
@@ -614,10 +603,10 @@ transmit_task_cb (void *cls)
614 { 603 {
615 idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE; 604 idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
616 peer_entry->previous_round = GNUNET_YES; 605 peer_entry->previous_round = GNUNET_YES;
617 peer_entry->transmit_task 606 peer_entry->transmit_task =
618 = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), 607 GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0),
619 &transmit_task_cb, 608 &transmit_task_cb,
620 peer_entry); 609 peer_entry);
621 } 610 }
622 if ((0 == ntohl (size_estimate_messages[idx].hop_count)) && 611 if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
623 (NULL != proof_task)) 612 (NULL != proof_task))
@@ -625,7 +614,7 @@ transmit_task_cb (void *cls)
625 GNUNET_STATISTICS_update (stats, 614 GNUNET_STATISTICS_update (stats,
626 "# flood messages not generated (no proof yet)", 615 "# flood messages not generated (no proof yet)",
627 1, 616 1,
628 GNUNET_NO); 617 GNUNET_NO);
629 return; 618 return;
630 } 619 }
631 if (0 == ntohs (size_estimate_messages[idx].header.size)) 620 if (0 == ntohs (size_estimate_messages[idx].header.size))
@@ -633,31 +622,29 @@ transmit_task_cb (void *cls)
633 GNUNET_STATISTICS_update (stats, 622 GNUNET_STATISTICS_update (stats,
634 "# flood messages not generated (lack of history)", 623 "# flood messages not generated (lack of history)",
635 1, 624 1,
636 GNUNET_NO); 625 GNUNET_NO);
637 return; 626 return;
638 } 627 }
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
640 "In round %s, sending to `%s' estimate with %u bits\n", 629 "In round %s, sending to `%s' estimate with %u bits\n",
641 GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (size_estimate_messages[idx].timestamp)), 630 GNUNET_STRINGS_absolute_time_to_string (
631 GNUNET_TIME_absolute_ntoh (
632 size_estimate_messages[idx].timestamp)),
642 GNUNET_i2s (peer_entry->id), 633 GNUNET_i2s (peer_entry->id),
643 (unsigned int) ntohl (size_estimate_messages[idx].matching_bits)); 634 (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
644 if (0 == ntohl (size_estimate_messages[idx].hop_count)) 635 if (0 == ntohl (size_estimate_messages[idx].hop_count))
645 GNUNET_STATISTICS_update (stats, 636 GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO);
646 "# flood messages started",
647 1,
648 GNUNET_NO);
649 GNUNET_STATISTICS_update (stats, 637 GNUNET_STATISTICS_update (stats,
650 "# flood messages transmitted", 638 "# flood messages transmitted",
651 1, 639 1,
652 GNUNET_NO); 640 GNUNET_NO);
653#if ENABLE_NSE_HISTOGRAM 641#if ENABLE_NSE_HISTOGRAM
654 peer_entry->transmitted_messages++; 642 peer_entry->transmitted_messages++;
655 peer_entry->last_transmitted_size 643 peer_entry->last_transmitted_size =
656 = ntohl(size_estimate_messages[idx].matching_bits); 644 ntohl (size_estimate_messages[idx].matching_bits);
657#endif 645#endif
658 env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header); 646 env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header);
659 GNUNET_MQ_send (peer_entry->mq, 647 GNUNET_MQ_send (peer_entry->mq, env);
660 env);
661} 648}
662 649
663 650
@@ -673,9 +660,7 @@ update_network_size_estimate ()
673 struct GNUNET_NSE_ClientMessage em; 660 struct GNUNET_NSE_ClientMessage em;
674 661
675 setup_estimate_message (&em); 662 setup_estimate_message (&em);
676 GNUNET_notification_context_broadcast (nc, 663 GNUNET_notification_context_broadcast (nc, &em.header, GNUNET_YES);
677 &em.header,
678 GNUNET_YES);
679} 664}
680 665
681 666
@@ -687,36 +672,31 @@ update_network_size_estimate ()
687 * @param ts timestamp to use 672 * @param ts timestamp to use
688 */ 673 */
689static void 674static void
690setup_flood_message (unsigned int slot, 675setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
691 struct GNUNET_TIME_Absolute ts)
692{ 676{
693 struct GNUNET_NSE_FloodMessage *fm; 677 struct GNUNET_NSE_FloodMessage *fm;
694 uint32_t matching_bits; 678 uint32_t matching_bits;
695 679
696 matching_bits = get_matching_bits (ts, 680 matching_bits = get_matching_bits (ts, &my_identity);
697 &my_identity);
698 fm = &size_estimate_messages[slot]; 681 fm = &size_estimate_messages[slot];
699 fm->header.size = htons (sizeof (struct GNUNET_NSE_FloodMessage)); 682 fm->header.size = htons (sizeof (struct GNUNET_NSE_FloodMessage));
700 fm->header.type = htons (GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD); 683 fm->header.type = htons (GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD);
701 fm->hop_count = htonl (0); 684 fm->hop_count = htonl (0);
702 fm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_NSE_SEND); 685 fm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_NSE_SEND);
703 fm->purpose.size = 686 fm->purpose.size =
704 htonl (sizeof (struct GNUNET_NSE_FloodMessage) - 687 htonl (sizeof (struct GNUNET_NSE_FloodMessage) -
705 sizeof (struct GNUNET_MessageHeader) - sizeof (uint32_t) - 688 sizeof (struct GNUNET_MessageHeader) - sizeof (uint32_t) -
706 sizeof (struct GNUNET_CRYPTO_EddsaSignature)); 689 sizeof (struct GNUNET_CRYPTO_EddsaSignature));
707 fm->matching_bits = htonl (matching_bits); 690 fm->matching_bits = htonl (matching_bits);
708 fm->timestamp = GNUNET_TIME_absolute_hton (ts); 691 fm->timestamp = GNUNET_TIME_absolute_hton (ts);
709 fm->origin = my_identity; 692 fm->origin = my_identity;
710 fm->proof_of_work = my_proof; 693 fm->proof_of_work = my_proof;
711 if (nse_work_required > 0) 694 if (nse_work_required > 0)
712 GNUNET_assert (GNUNET_OK == 695 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_private_key,
713 GNUNET_CRYPTO_eddsa_sign (my_private_key, 696 &fm->purpose,
714 &fm->purpose, 697 &fm->signature));
715 &fm->signature));
716 else 698 else
717 memset (&fm->signature, 699 memset (&fm->signature, 0, sizeof (fm->signature));
718 0,
719 sizeof (fm->signature));
720} 700}
721 701
722 702
@@ -731,8 +711,8 @@ setup_flood_message (unsigned int slot,
731 */ 711 */
732static int 712static int
733schedule_current_round (void *cls, 713schedule_current_round (void *cls,
734 const struct GNUNET_PeerIdentity * key, 714 const struct GNUNET_PeerIdentity *key,
735 void *value) 715 void *value)
736{ 716{
737 struct NSEPeerEntry *peer_entry = value; 717 struct NSEPeerEntry *peer_entry = value;
738 struct GNUNET_TIME_Relative delay; 718 struct GNUNET_TIME_Relative delay;
@@ -744,20 +724,18 @@ schedule_current_round (void *cls,
744 } 724 }
745#if ENABLE_NSE_HISTOGRAM 725#if ENABLE_NSE_HISTOGRAM
746 if (peer_entry->received_messages > 1) 726 if (peer_entry->received_messages > 1)
747 GNUNET_STATISTICS_update(stats, 727 GNUNET_STATISTICS_update (stats,
748 "# extra messages", 728 "# extra messages",
749 peer_entry->received_messages - 1, 729 peer_entry->received_messages - 1,
750 GNUNET_NO); 730 GNUNET_NO);
751 peer_entry->transmitted_messages = 0; 731 peer_entry->transmitted_messages = 0;
752 peer_entry->last_transmitted_size = 0; 732 peer_entry->last_transmitted_size = 0;
753 peer_entry->received_messages = 0; 733 peer_entry->received_messages = 0;
754#endif 734#endif
755 delay = 735 delay =
756 get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0); 736 get_transmit_delay ((GNUNET_NO == peer_entry->previous_round) ? -1 : 0);
757 peer_entry->transmit_task = 737 peer_entry->transmit_task =
758 GNUNET_SCHEDULER_add_delayed (delay, 738 GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
759 &transmit_task_cb,
760 peer_entry);
761 return GNUNET_OK; 739 return GNUNET_OK;
762} 740}
763 741
@@ -779,9 +757,7 @@ update_flood_message (void *cls)
779 { 757 {
780 /* somehow run early, delay more */ 758 /* somehow run early, delay more */
781 flood_task = 759 flood_task =
782 GNUNET_SCHEDULER_add_delayed (offset, 760 GNUNET_SCHEDULER_add_delayed (offset, &update_flood_message, NULL);
783 &update_flood_message,
784 NULL);
785 return; 761 return;
786 } 762 }
787 estimate_index = (estimate_index + 1) % HISTORY_SIZE; 763 estimate_index = (estimate_index + 1) % HISTORY_SIZE;
@@ -789,32 +765,27 @@ update_flood_message (void *cls)
789 estimate_count++; 765 estimate_count++;
790 current_timestamp = next_timestamp; 766 current_timestamp = next_timestamp;
791 next_timestamp = 767 next_timestamp =
792 GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval); 768 GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval);
793 if ( (current_timestamp.abs_value_us == 769 if ((current_timestamp.abs_value_us ==
794 GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value_us) && 770 GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value_us) &&
795 (get_matching_bits (current_timestamp, &my_identity) < 771 (get_matching_bits (current_timestamp, &my_identity) <
796 ntohl(next_message.matching_bits)) ) 772 ntohl (next_message.matching_bits)))
797 { 773 {
798 /* we received a message for this round way early, use it! */ 774 /* we received a message for this round way early, use it! */
799 size_estimate_messages[estimate_index] = next_message; 775 size_estimate_messages[estimate_index] = next_message;
800 size_estimate_messages[estimate_index].hop_count = 776 size_estimate_messages[estimate_index].hop_count =
801 htonl (1 + ntohl (next_message.hop_count)); 777 htonl (1 + ntohl (next_message.hop_count));
802 } 778 }
803 else 779 else
804 setup_flood_message (estimate_index, 780 setup_flood_message (estimate_index, current_timestamp);
805 current_timestamp); 781 next_message.matching_bits = htonl (0); /* reset for 'next' round */
806 next_message.matching_bits = htonl (0); /* reset for 'next' round */
807 hop_count_max = 0; 782 hop_count_max = 0;
808 for (i = 0; i < HISTORY_SIZE; i++) 783 for (i = 0; i < HISTORY_SIZE; i++)
809 hop_count_max = GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), 784 hop_count_max =
810 hop_count_max); 785 GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max);
811 GNUNET_CONTAINER_multipeermap_iterate (peers, 786 GNUNET_CONTAINER_multipeermap_iterate (peers, &schedule_current_round, NULL);
812 &schedule_current_round, 787 flood_task =
813 NULL); 788 GNUNET_SCHEDULER_add_at (next_timestamp, &update_flood_message, NULL);
814 flood_task
815 = GNUNET_SCHEDULER_add_at (next_timestamp,
816 &update_flood_message,
817 NULL);
818} 789}
819 790
820 791
@@ -830,8 +801,7 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
830 unsigned int hash_count; 801 unsigned int hash_count;
831 802
832 hash_count = 0; 803 hash_count = 0;
833 while (0 == GNUNET_CRYPTO_hash_get_bit (hash, 804 while (0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count))
834 hash_count))
835 hash_count++; 805 hash_count++;
836 return hash_count; 806 return hash_count;
837} 807}
@@ -853,17 +823,13 @@ check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
853 sizeof (val)] GNUNET_ALIGN; 823 sizeof (val)] GNUNET_ALIGN;
854 struct GNUNET_HashCode result; 824 struct GNUNET_HashCode result;
855 825
856 GNUNET_memcpy (buf, 826 GNUNET_memcpy (buf, &val, sizeof (val));
857 &val,
858 sizeof (val));
859 GNUNET_memcpy (&buf[sizeof (val)], 827 GNUNET_memcpy (&buf[sizeof (val)],
860 pkey, 828 pkey,
861 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); 829 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
862 pow_hash (buf, 830 pow_hash (buf, sizeof (buf), &result);
863 sizeof (buf), 831 return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES
864 &result); 832 : GNUNET_NO;
865 return (count_leading_zeroes (&result) >=
866 nse_work_required) ? GNUNET_YES : GNUNET_NO;
867} 833}
868 834
869 835
@@ -876,20 +842,14 @@ write_proof ()
876 char *proof; 842 char *proof;
877 843
878 if (GNUNET_OK != 844 if (GNUNET_OK !=
879 GNUNET_CONFIGURATION_get_value_filename (cfg, 845 GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
880 "NSE",
881 "PROOFFILE",
882 &proof))
883 return; 846 return;
884 if (sizeof (my_proof) != 847 if (sizeof (my_proof) != GNUNET_DISK_fn_write (proof,
885 GNUNET_DISK_fn_write (proof, 848 &my_proof,
886 &my_proof, 849 sizeof (my_proof),
887 sizeof (my_proof), 850 GNUNET_DISK_PERM_USER_READ |
888 GNUNET_DISK_PERM_USER_READ | 851 GNUNET_DISK_PERM_USER_WRITE))
889 GNUNET_DISK_PERM_USER_WRITE)) 852 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", proof);
890 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
891 "write",
892 proof);
893 GNUNET_free (proof); 853 GNUNET_free (proof);
894} 854}
895 855
@@ -910,8 +870,9 @@ find_proof (void *cls)
910 unsigned int i; 870 unsigned int i;
911 871
912 proof_task = NULL; 872 proof_task = NULL;
913 GNUNET_memcpy (&buf[sizeof (uint64_t)], &my_identity, 873 GNUNET_memcpy (&buf[sizeof (uint64_t)],
914 sizeof (struct GNUNET_PeerIdentity)); 874 &my_identity,
875 sizeof (struct GNUNET_PeerIdentity));
915 i = 0; 876 i = 0;
916 counter = my_proof; 877 counter = my_proof;
917 while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) 878 while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
@@ -921,7 +882,8 @@ find_proof (void *cls)
921 if (nse_work_required <= count_leading_zeroes (&result)) 882 if (nse_work_required <= count_leading_zeroes (&result))
922 { 883 {
923 my_proof = counter; 884 my_proof = counter;
924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof of work found: %llu!\n", 885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
886 "Proof of work found: %llu!\n",
925 (unsigned long long) GNUNET_ntohll (counter)); 887 (unsigned long long) GNUNET_ntohll (counter));
926 write_proof (); 888 write_proof ();
927 setup_flood_message (estimate_index, current_timestamp); 889 setup_flood_message (estimate_index, current_timestamp);
@@ -944,9 +906,10 @@ find_proof (void *cls)
944 my_proof = counter; 906 my_proof = counter;
945 } 907 }
946 proof_task = 908 proof_task =
947 GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, 909 GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay,
948 GNUNET_SCHEDULER_PRIORITY_IDLE, 910 GNUNET_SCHEDULER_PRIORITY_IDLE,
949 &find_proof, NULL); 911 &find_proof,
912 NULL);
950} 913}
951 914
952 915
@@ -962,23 +925,22 @@ find_proof (void *cls)
962static int 925static int
963verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood) 926verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
964{ 927{
965 if (GNUNET_YES != 928 if (GNUNET_YES != check_proof_of_work (&incoming_flood->origin.public_key,
966 check_proof_of_work (&incoming_flood->origin.public_key, 929 incoming_flood->proof_of_work))
967 incoming_flood->proof_of_work))
968 { 930 {
969 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 931 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
970 "Proof of work invalid: %llu!\n", 932 "Proof of work invalid: %llu!\n",
971 (unsigned long long) 933 (unsigned long long) GNUNET_ntohll (
972 GNUNET_ntohll (incoming_flood->proof_of_work)); 934 incoming_flood->proof_of_work));
973 GNUNET_break_op (0); 935 GNUNET_break_op (0);
974 return GNUNET_NO; 936 return GNUNET_NO;
975 } 937 }
976 if ((nse_work_required > 0) && 938 if ((nse_work_required > 0) &&
977 (GNUNET_OK != 939 (GNUNET_OK !=
978 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_NSE_SEND, 940 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_NSE_SEND,
979 &incoming_flood->purpose, 941 &incoming_flood->purpose,
980 &incoming_flood->signature, 942 &incoming_flood->signature,
981 &incoming_flood->origin.public_key))) 943 &incoming_flood->origin.public_key)))
982 { 944 {
983 GNUNET_break_op (0); 945 GNUNET_break_op (0);
984 return GNUNET_NO; 946 return GNUNET_NO;
@@ -998,15 +960,15 @@ verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
998 */ 960 */
999static int 961static int
1000update_flood_times (void *cls, 962update_flood_times (void *cls,
1001 const struct GNUNET_PeerIdentity *key, 963 const struct GNUNET_PeerIdentity *key,
1002 void *value) 964 void *value)
1003{ 965{
1004 struct NSEPeerEntry *exclude = cls; 966 struct NSEPeerEntry *exclude = cls;
1005 struct NSEPeerEntry *peer_entry = value; 967 struct NSEPeerEntry *peer_entry = value;
1006 struct GNUNET_TIME_Relative delay; 968 struct GNUNET_TIME_Relative delay;
1007 969
1008 if (peer_entry == exclude) 970 if (peer_entry == exclude)
1009 return GNUNET_OK; /* trigger of the update */ 971 return GNUNET_OK; /* trigger of the update */
1010 if (GNUNET_NO == peer_entry->previous_round) 972 if (GNUNET_NO == peer_entry->previous_round)
1011 { 973 {
1012 /* still stuck in previous round, no point to update, check that 974 /* still stuck in previous round, no point to update, check that
@@ -1024,8 +986,7 @@ update_flood_times (void *cls,
1024 } 986 }
1025 delay = get_transmit_delay (0); 987 delay = get_transmit_delay (0);
1026 peer_entry->transmit_task = 988 peer_entry->transmit_task =
1027 GNUNET_SCHEDULER_add_delayed (delay, 989 GNUNET_SCHEDULER_add_delayed (delay, &transmit_task_cb, peer_entry);
1028 &transmit_task_cb, peer_entry);
1029 return GNUNET_OK; 990 return GNUNET_OK;
1030} 991}
1031 992
@@ -1038,7 +999,7 @@ update_flood_times (void *cls,
1038 */ 999 */
1039static void 1000static void
1040handle_p2p_estimate (void *cls, 1001handle_p2p_estimate (void *cls,
1041 const struct GNUNET_NSE_FloodMessage *incoming_flood) 1002 const struct GNUNET_NSE_FloodMessage *incoming_flood)
1042{ 1003{
1043 struct NSEPeerEntry *peer_entry = cls; 1004 struct NSEPeerEntry *peer_entry = cls;
1044 struct GNUNET_TIME_Absolute ts; 1005 struct GNUNET_TIME_Absolute ts;
@@ -1049,17 +1010,14 @@ handle_p2p_estimate (void *cls,
1049 { 1010 {
1050 uint64_t t; 1011 uint64_t t;
1051 1012
1052 t = GNUNET_TIME_absolute_get().abs_value_us; 1013 t = GNUNET_TIME_absolute_get ().abs_value_us;
1053 if (NULL != lh) 1014 if (NULL != lh)
1054 GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof (uint64_t)); 1015 GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof (uint64_t));
1055 if (NULL != histogram) 1016 if (NULL != histogram)
1056 GNUNET_BIO_write_int64 (histogram, t); 1017 GNUNET_BIO_write_int64 (histogram, t);
1057 } 1018 }
1058#endif 1019#endif
1059 GNUNET_STATISTICS_update (stats, 1020 GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
1060 "# flood messages received",
1061 1,
1062 GNUNET_NO);
1063 matching_bits = ntohl (incoming_flood->matching_bits); 1021 matching_bits = ntohl (incoming_flood->matching_bits);
1064#if DEBUG_NSE 1022#if DEBUG_NSE
1065 { 1023 {
@@ -1068,19 +1026,17 @@ handle_p2p_estimate (void *cls,
1068 struct GNUNET_PeerIdentity os; 1026 struct GNUNET_PeerIdentity os;
1069 1027
1070 GNUNET_snprintf (origin, 1028 GNUNET_snprintf (origin,
1071 sizeof (origin), 1029 sizeof (origin),
1072 "%s", 1030 "%s",
1073 GNUNET_i2s (&incoming_flood->origin)); 1031 GNUNET_i2s (&incoming_flood->origin));
1074 GNUNET_snprintf (pred, 1032 GNUNET_snprintf (pred, sizeof (pred), "%s", GNUNET_i2s (peer_entry->id));
1075 sizeof (pred),
1076 "%s",
1077 GNUNET_i2s (peer_entry->id));
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1033 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1079 "Flood at %s from `%s' via `%s' at `%s' with bits %u\n", 1034 "Flood at %s from `%s' via `%s' at `%s' with bits %u\n",
1080 GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)), 1035 GNUNET_STRINGS_absolute_time_to_string (
1036 GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp)),
1081 origin, 1037 origin,
1082 pred, 1038 pred,
1083 GNUNET_i2s (&my_identity), 1039 GNUNET_i2s (&my_identity),
1084 (unsigned int) matching_bits); 1040 (unsigned int) matching_bits);
1085 } 1041 }
1086#endif 1042#endif
@@ -1089,10 +1045,7 @@ handle_p2p_estimate (void *cls,
1089 peer_entry->received_messages++; 1045 peer_entry->received_messages++;
1090 if (peer_entry->transmitted_messages > 0 && 1046 if (peer_entry->transmitted_messages > 0 &&
1091 peer_entry->last_transmitted_size >= matching_bits) 1047 peer_entry->last_transmitted_size >= matching_bits)
1092 GNUNET_STATISTICS_update(stats, 1048 GNUNET_STATISTICS_update (stats, "# cross messages", 1, GNUNET_NO);
1093 "# cross messages",
1094 1,
1095 GNUNET_NO);
1096#endif 1049#endif
1097 1050
1098 ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp); 1051 ts = GNUNET_TIME_absolute_ntoh (incoming_flood->timestamp);
@@ -1104,9 +1057,8 @@ handle_p2p_estimate (void *cls,
1104 else if (ts.abs_value_us == next_timestamp.abs_value_us) 1057 else if (ts.abs_value_us == next_timestamp.abs_value_us)
1105 { 1058 {
1106 if (matching_bits <= ntohl (next_message.matching_bits)) 1059 if (matching_bits <= ntohl (next_message.matching_bits))
1107 return; /* ignore, simply too early/late */ 1060 return; /* ignore, simply too early/late */
1108 if (GNUNET_YES != 1061 if (GNUNET_YES != verify_message_crypto (incoming_flood))
1109 verify_message_crypto (incoming_flood))
1110 { 1062 {
1111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1063 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1112 "Peer %s is likely ill-configured!\n", 1064 "Peer %s is likely ill-configured!\n",
@@ -1121,21 +1073,18 @@ handle_p2p_estimate (void *cls,
1121 { 1073 {
1122 GNUNET_STATISTICS_update (stats, 1074 GNUNET_STATISTICS_update (stats,
1123 "# flood messages discarded (clock skew too large)", 1075 "# flood messages discarded (clock skew too large)",
1124 1, GNUNET_NO); 1076 1,
1077 GNUNET_NO);
1125 return; 1078 return;
1126 } 1079 }
1127 if (0 == (GNUNET_memcmp (peer_entry->id, 1080 if (0 == (GNUNET_memcmp (peer_entry->id, &my_identity)))
1128 &my_identity)))
1129 { 1081 {
1130 /* send to self, update our own estimate IF this also comes from us! */ 1082 /* send to self, update our own estimate IF this also comes from us! */
1131 if (0 == 1083 if (0 == GNUNET_memcmp (&incoming_flood->origin, &my_identity))
1132 GNUNET_memcmp (&incoming_flood->origin,
1133 &my_identity))
1134 update_network_size_estimate (); 1084 update_network_size_estimate ();
1135 return; 1085 return;
1136 } 1086 }
1137 if (matching_bits == 1087 if (matching_bits == ntohl (size_estimate_messages[idx].matching_bits))
1138 ntohl (size_estimate_messages[idx].matching_bits))
1139 { 1088 {
1140 /* Cancel transmission in the other direction, as this peer clearly has 1089 /* Cancel transmission in the other direction, as this peer clearly has
1141 up-to-date information already. Even if we didn't talk to this peer in 1090 up-to-date information already. Even if we didn't talk to this peer in
@@ -1159,26 +1108,23 @@ handle_p2p_estimate (void *cls,
1159 } 1108 }
1160 if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits)) 1109 if (matching_bits < ntohl (size_estimate_messages[idx].matching_bits))
1161 { 1110 {
1162 if ( (idx < estimate_index) && 1111 if ((idx < estimate_index) && (peer_entry->previous_round == GNUNET_YES))
1163 (peer_entry->previous_round == GNUNET_YES))
1164 { 1112 {
1165 peer_entry->previous_round = GNUNET_NO; 1113 peer_entry->previous_round = GNUNET_NO;
1166 } 1114 }
1167 /* push back our result now, that peer is spreading bad information... */ 1115 /* push back our result now, that peer is spreading bad information... */
1168 if (NULL != peer_entry->transmit_task) 1116 if (NULL != peer_entry->transmit_task)
1169 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); 1117 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1170 peer_entry->transmit_task 1118 peer_entry->transmit_task =
1171 = GNUNET_SCHEDULER_add_now (&transmit_task_cb, 1119 GNUNET_SCHEDULER_add_now (&transmit_task_cb, peer_entry);
1172 peer_entry);
1173 /* Not closer than our most recent message, no need to do work here */ 1120 /* Not closer than our most recent message, no need to do work here */
1174 GNUNET_STATISTICS_update (stats, 1121 GNUNET_STATISTICS_update (stats,
1175 "# flood messages ignored (had closer already)", 1122 "# flood messages ignored (had closer already)",
1176 1, 1123 1,
1177 GNUNET_NO); 1124 GNUNET_NO);
1178 return; 1125 return;
1179 } 1126 }
1180 if (GNUNET_YES != 1127 if (GNUNET_YES != verify_message_crypto (incoming_flood))
1181 verify_message_crypto (incoming_flood))
1182 { 1128 {
1183 GNUNET_break_op (0); 1129 GNUNET_break_op (0);
1184 return; 1130 return;
@@ -1200,20 +1146,20 @@ handle_p2p_estimate (void *cls,
1200 } 1146 }
1201 size_estimate_messages[idx] = *incoming_flood; 1147 size_estimate_messages[idx] = *incoming_flood;
1202 size_estimate_messages[idx].hop_count = 1148 size_estimate_messages[idx].hop_count =
1203 htonl (ntohl (incoming_flood->hop_count) + 1); 1149 htonl (ntohl (incoming_flood->hop_count) + 1);
1204 hop_count_max = 1150 hop_count_max =
1205 GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, 1151 GNUNET_MAX (ntohl (incoming_flood->hop_count) + 1, hop_count_max);
1206 hop_count_max);
1207 GNUNET_STATISTICS_set (stats, 1152 GNUNET_STATISTICS_set (stats,
1208 "# estimated network diameter", 1153 "# estimated network diameter",
1209 hop_count_max, GNUNET_NO); 1154 hop_count_max,
1155 GNUNET_NO);
1210 1156
1211 /* have a new, better size estimate, inform clients */ 1157 /* have a new, better size estimate, inform clients */
1212 update_network_size_estimate (); 1158 update_network_size_estimate ();
1213 1159
1214 /* flood to rest */ 1160 /* flood to rest */
1215 GNUNET_CONTAINER_multipeermap_iterate (peers, 1161 GNUNET_CONTAINER_multipeermap_iterate (peers,
1216 &update_flood_times, 1162 &update_flood_times,
1217 peer_entry); 1163 peer_entry);
1218} 1164}
1219 1165
@@ -1227,40 +1173,31 @@ handle_p2p_estimate (void *cls,
1227 */ 1173 */
1228static void * 1174static void *
1229handle_core_connect (void *cls, 1175handle_core_connect (void *cls,
1230 const struct GNUNET_PeerIdentity *peer, 1176 const struct GNUNET_PeerIdentity *peer,
1231 struct GNUNET_MQ_Handle *mq) 1177 struct GNUNET_MQ_Handle *mq)
1232{ 1178{
1233 struct NSEPeerEntry *peer_entry; 1179 struct NSEPeerEntry *peer_entry;
1234 uint64_t flags;
1235 const void *extra;
1236 1180
1237 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1238 "Peer `%s' connected to us\n", 1182 "Peer `%s' connected to us\n",
1239 GNUNET_i2s (peer)); 1183 GNUNET_i2s (peer));
1240 /* set our default transmission options */ 1184 /* set our default transmission options */
1241 extra = GNUNET_CORE_get_mq_options (GNUNET_NO, 1185 GNUNET_MQ_set_options (mq, NSE_PRIORITY);
1242 NSE_PRIORITY,
1243 &flags);
1244 GNUNET_MQ_set_options (mq,
1245 flags,
1246 extra);
1247 /* create our peer entry for this peer */ 1186 /* create our peer entry for this peer */
1248 peer_entry = GNUNET_new (struct NSEPeerEntry); 1187 peer_entry = GNUNET_new (struct NSEPeerEntry);
1249 peer_entry->id = peer; 1188 peer_entry->id = peer;
1250 peer_entry->mq = mq; 1189 peer_entry->mq = mq;
1251 GNUNET_assert (GNUNET_OK == 1190 GNUNET_assert (GNUNET_OK ==
1252 GNUNET_CONTAINER_multipeermap_put (peers, 1191 GNUNET_CONTAINER_multipeermap_put (
1253 peer_entry->id, 1192 peers,
1254 peer_entry, 1193 peer_entry->id,
1255 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1194 peer_entry,
1195 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1256 peer_entry->transmit_task = 1196 peer_entry->transmit_task =
1257 GNUNET_SCHEDULER_add_delayed (get_transmit_delay (-1), 1197 GNUNET_SCHEDULER_add_delayed (get_transmit_delay (-1),
1258 &transmit_task_cb, 1198 &transmit_task_cb,
1259 peer_entry); 1199 peer_entry);
1260 GNUNET_STATISTICS_update (stats, 1200 GNUNET_STATISTICS_update (stats, "# peers connected", 1, GNUNET_NO);
1261 "# peers connected",
1262 1,
1263 GNUNET_NO);
1264 return peer_entry; 1201 return peer_entry;
1265} 1202}
1266 1203
@@ -1275,28 +1212,23 @@ handle_core_connect (void *cls,
1275 */ 1212 */
1276static void 1213static void
1277handle_core_disconnect (void *cls, 1214handle_core_disconnect (void *cls,
1278 const struct GNUNET_PeerIdentity *peer, 1215 const struct GNUNET_PeerIdentity *peer,
1279 void *internal_cls) 1216 void *internal_cls)
1280{ 1217{
1281 struct NSEPeerEntry *pos = internal_cls; 1218 struct NSEPeerEntry *pos = internal_cls;
1282 1219
1283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1284 "Peer `%s' disconnected from us\n", 1221 "Peer `%s' disconnected from us\n",
1285 GNUNET_i2s (peer)); 1222 GNUNET_i2s (peer));
1286 GNUNET_assert (GNUNET_YES == 1223 GNUNET_assert (GNUNET_YES ==
1287 GNUNET_CONTAINER_multipeermap_remove (peers, 1224 GNUNET_CONTAINER_multipeermap_remove (peers, peer, pos));
1288 peer,
1289 pos));
1290 if (NULL != pos->transmit_task) 1225 if (NULL != pos->transmit_task)
1291 { 1226 {
1292 GNUNET_SCHEDULER_cancel (pos->transmit_task); 1227 GNUNET_SCHEDULER_cancel (pos->transmit_task);
1293 pos->transmit_task = NULL; 1228 pos->transmit_task = NULL;
1294 } 1229 }
1295 GNUNET_free (pos); 1230 GNUNET_free (pos);
1296 GNUNET_STATISTICS_update (stats, 1231 GNUNET_STATISTICS_update (stats, "# peers connected", -1, GNUNET_NO);
1297 "# peers connected",
1298 -1,
1299 GNUNET_NO);
1300} 1232}
1301 1233
1302 1234
@@ -1309,8 +1241,7 @@ handle_core_disconnect (void *cls,
1309 * @param size the amount of data sent (ignored) 1241 * @param size the amount of data sent (ignored)
1310 */ 1242 */
1311static void 1243static void
1312flush_comp_cb (void *cls, 1244flush_comp_cb (void *cls, size_t size)
1313 size_t size)
1314{ 1245{
1315 GNUNET_TESTBED_LOGGER_disconnect (lh); 1246 GNUNET_TESTBED_LOGGER_disconnect (lh);
1316 lh = NULL; 1247 lh = NULL;
@@ -1335,7 +1266,7 @@ shutdown_task (void *cls)
1335 { 1266 {
1336 GNUNET_SCHEDULER_cancel (proof_task); 1267 GNUNET_SCHEDULER_cancel (proof_task);
1337 proof_task = NULL; 1268 proof_task = NULL;
1338 write_proof (); /* remember progress */ 1269 write_proof (); /* remember progress */
1339 } 1270 }
1340 if (NULL != nc) 1271 if (NULL != nc)
1341 { 1272 {
@@ -1370,9 +1301,7 @@ shutdown_task (void *cls)
1370 } 1301 }
1371 if (NULL != lh) 1302 if (NULL != lh)
1372 { 1303 {
1373 GNUNET_TESTBED_LOGGER_flush (lh, 1304 GNUNET_TESTBED_LOGGER_flush (lh, &flush_comp_cb, NULL);
1374 &flush_comp_cb,
1375 NULL);
1376 } 1305 }
1377 if (NULL != histogram) 1306 if (NULL != histogram)
1378 { 1307 {
@@ -1390,48 +1319,37 @@ shutdown_task (void *cls)
1390 * @param identity the public identity of this peer 1319 * @param identity the public identity of this peer
1391 */ 1320 */
1392static void 1321static void
1393core_init (void *cls, 1322core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
1394 const struct GNUNET_PeerIdentity *identity)
1395{ 1323{
1396 struct GNUNET_TIME_Absolute now; 1324 struct GNUNET_TIME_Absolute now;
1397 struct GNUNET_TIME_Absolute prev_time; 1325 struct GNUNET_TIME_Absolute prev_time;
1398 1326
1399 if (NULL == identity) 1327 if (NULL == identity)
1400 { 1328 {
1401 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to core FAILED!\n");
1402 "Connection to core FAILED!\n");
1403 GNUNET_SCHEDULER_shutdown (); 1330 GNUNET_SCHEDULER_shutdown ();
1404 return; 1331 return;
1405 } 1332 }
1406 GNUNET_assert (0 == 1333 GNUNET_assert (0 == GNUNET_memcmp (&my_identity, identity));
1407 GNUNET_memcmp (&my_identity,
1408 identity));
1409 now = GNUNET_TIME_absolute_get (); 1334 now = GNUNET_TIME_absolute_get ();
1410 current_timestamp.abs_value_us = 1335 current_timestamp.abs_value_us =
1411 (now.abs_value_us / gnunet_nse_interval.rel_value_us) * 1336 (now.abs_value_us / gnunet_nse_interval.rel_value_us) *
1412 gnunet_nse_interval.rel_value_us; 1337 gnunet_nse_interval.rel_value_us;
1413 next_timestamp = 1338 next_timestamp =
1414 GNUNET_TIME_absolute_add (current_timestamp, 1339 GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval);
1415 gnunet_nse_interval);
1416 estimate_index = HISTORY_SIZE - 1; 1340 estimate_index = HISTORY_SIZE - 1;
1417 estimate_count = 0; 1341 estimate_count = 0;
1418 if (GNUNET_YES == 1342 if (GNUNET_YES == check_proof_of_work (&my_identity.public_key, my_proof))
1419 check_proof_of_work (&my_identity.public_key,
1420 my_proof))
1421 { 1343 {
1422 int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE; 1344 int idx = (estimate_index + HISTORY_SIZE - 1) % HISTORY_SIZE;
1423 prev_time.abs_value_us = 1345 prev_time.abs_value_us =
1424 current_timestamp.abs_value_us - gnunet_nse_interval.rel_value_us; 1346 current_timestamp.abs_value_us - gnunet_nse_interval.rel_value_us;
1425 setup_flood_message (idx, 1347 setup_flood_message (idx, prev_time);
1426 prev_time); 1348 setup_flood_message (estimate_index, current_timestamp);
1427 setup_flood_message (estimate_index,
1428 current_timestamp);
1429 estimate_count++; 1349 estimate_count++;
1430 } 1350 }
1431 flood_task 1351 flood_task =
1432 = GNUNET_SCHEDULER_add_at (next_timestamp, 1352 GNUNET_SCHEDULER_add_at (next_timestamp, &update_flood_message, NULL);
1433 &update_flood_message,
1434 NULL);
1435} 1353}
1436 1354
1437 1355
@@ -1445,14 +1363,12 @@ core_init (void *cls,
1445 * #GNUNET_SYSERR if the configuration is invalid 1363 * #GNUNET_SYSERR if the configuration is invalid
1446 */ 1364 */
1447static void 1365static void
1448status_cb (void *cls, 1366status_cb (void *cls, int status)
1449 int status)
1450{ 1367{
1451 logger_test = NULL; 1368 logger_test = NULL;
1452 if (GNUNET_YES != status) 1369 if (GNUNET_YES != status)
1453 { 1370 {
1454 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1371 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed logger not running\n");
1455 "Testbed logger not running\n");
1456 return; 1372 return;
1457 } 1373 }
1458 if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg))) 1374 if (NULL == (lh = GNUNET_TESTBED_LOGGER_connect (cfg)))
@@ -1477,59 +1393,49 @@ run (void *cls,
1477 const struct GNUNET_CONFIGURATION_Handle *c, 1393 const struct GNUNET_CONFIGURATION_Handle *c,
1478 struct GNUNET_SERVICE_Handle *service) 1394 struct GNUNET_SERVICE_Handle *service)
1479{ 1395{
1480 struct GNUNET_MQ_MessageHandler core_handlers[] = { 1396 struct GNUNET_MQ_MessageHandler core_handlers[] =
1481 GNUNET_MQ_hd_fixed_size (p2p_estimate, 1397 {GNUNET_MQ_hd_fixed_size (p2p_estimate,
1482 GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD, 1398 GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD,
1483 struct GNUNET_NSE_FloodMessage, 1399 struct GNUNET_NSE_FloodMessage,
1484 NULL), 1400 NULL),
1485 GNUNET_MQ_handler_end () 1401 GNUNET_MQ_handler_end ()};
1486 };
1487 char *proof; 1402 char *proof;
1488 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 1403 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
1489 1404
1490 cfg = c; 1405 cfg = c;
1491 if (GNUNET_OK != 1406 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
1492 GNUNET_CONFIGURATION_get_value_time (cfg, 1407 "NSE",
1493 "NSE", 1408 "INTERVAL",
1494 "INTERVAL", 1409 &gnunet_nse_interval))
1495 &gnunet_nse_interval))
1496 { 1410 {
1497 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 1411 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "INTERVAL");
1498 "NSE",
1499 "INTERVAL");
1500 GNUNET_SCHEDULER_shutdown (); 1412 GNUNET_SCHEDULER_shutdown ();
1501 return; 1413 return;
1502 } 1414 }
1503 if (GNUNET_OK != 1415 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
1504 GNUNET_CONFIGURATION_get_value_time (cfg, 1416 "NSE",
1505 "NSE", 1417 "WORKDELAY",
1506 "WORKDELAY", 1418 &proof_find_delay))
1507 &proof_find_delay))
1508 { 1419 {
1509 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 1420 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY");
1510 "NSE",
1511 "WORKDELAY");
1512 GNUNET_SCHEDULER_shutdown (); 1421 GNUNET_SCHEDULER_shutdown ();
1513 return; 1422 return;
1514 } 1423 }
1515 if (GNUNET_OK != 1424 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1516 GNUNET_CONFIGURATION_get_value_number (cfg, 1425 "NSE",
1517 "NSE", 1426 "WORKBITS",
1518 "WORKBITS", 1427 &nse_work_required))
1519 &nse_work_required))
1520 { 1428 {
1521 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 1429 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS");
1522 "NSE",
1523 "WORKBITS");
1524 GNUNET_SCHEDULER_shutdown (); 1430 GNUNET_SCHEDULER_shutdown ();
1525 return; 1431 return;
1526 } 1432 }
1527 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) 1433 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
1528 { 1434 {
1529 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 1435 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1530 "NSE", 1436 "NSE",
1531 "WORKBITS", 1437 "WORKBITS",
1532 _("Value is too large.\n")); 1438 _ ("Value is too large.\n"));
1533 GNUNET_SCHEDULER_shutdown (); 1439 GNUNET_SCHEDULER_shutdown ();
1534 return; 1440 return;
1535 } 1441 }
@@ -1539,49 +1445,38 @@ run (void *cls,
1539 char *histogram_dir; 1445 char *histogram_dir;
1540 char *histogram_fn; 1446 char *histogram_fn;
1541 1447
1542 if (GNUNET_OK == 1448 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
1543 GNUNET_CONFIGURATION_get_value_filename (cfg, 1449 "NSE",
1544 "NSE", 1450 "HISTOGRAM_DIR",
1545 "HISTOGRAM_DIR", 1451 &histogram_dir))
1546 &histogram_dir))
1547 { 1452 {
1548 GNUNET_assert (0 < GNUNET_asprintf (&histogram_fn, 1453 GNUNET_assert (
1549 "%s/timestamps", 1454 0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1550 histogram_dir));
1551 GNUNET_free (histogram_dir); 1455 GNUNET_free (histogram_dir);
1552 histogram = GNUNET_BIO_write_open (histogram_fn); 1456 histogram = GNUNET_BIO_write_open (histogram_fn);
1553 if (NULL == histogram) 1457 if (NULL == histogram)
1554 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1458 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1555 "Unable to open histogram file `%s'\n", 1459 "Unable to open histogram file `%s'\n",
1556 histogram_fn); 1460 histogram_fn);
1557 GNUNET_free (histogram_fn); 1461 GNUNET_free (histogram_fn);
1558 } 1462 }
1559 logger_test = 1463 logger_test = GNUNET_CLIENT_service_test ("testbed-logger",
1560 GNUNET_CLIENT_service_test ("testbed-logger", 1464 cfg,
1561 cfg, 1465 GNUNET_TIME_UNIT_SECONDS,
1562 GNUNET_TIME_UNIT_SECONDS, 1466 &status_cb,
1563 &status_cb, 1467 NULL);
1564 NULL);
1565
1566 } 1468 }
1567#endif 1469#endif
1568 1470
1569 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1471 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
1570 NULL);
1571 pk = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); 1472 pk = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
1572 GNUNET_assert (NULL != pk); 1473 GNUNET_assert (NULL != pk);
1573 my_private_key = pk; 1474 my_private_key = pk;
1574 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, 1475 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
1575 &my_identity.public_key);
1576 if (GNUNET_OK != 1476 if (GNUNET_OK !=
1577 GNUNET_CONFIGURATION_get_value_filename (cfg, 1477 GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof))
1578 "NSE",
1579 "PROOFFILE",
1580 &proof))
1581 { 1478 {
1582 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 1479 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
1583 "NSE",
1584 "PROOFFILE");
1585 GNUNET_free (my_private_key); 1480 GNUNET_free (my_private_key);
1586 my_private_key = NULL; 1481 my_private_key = NULL;
1587 GNUNET_SCHEDULER_shutdown (); 1482 GNUNET_SCHEDULER_shutdown ();
@@ -1589,33 +1484,30 @@ run (void *cls,
1589 } 1484 }
1590 if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) || 1485 if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) ||
1591 (sizeof (my_proof) != 1486 (sizeof (my_proof) !=
1592 GNUNET_DISK_fn_read (proof, 1487 GNUNET_DISK_fn_read (proof, &my_proof, sizeof (my_proof))))
1593 &my_proof,
1594 sizeof (my_proof))))
1595 my_proof = 0; 1488 my_proof = 0;
1596 GNUNET_free (proof); 1489 GNUNET_free (proof);
1597 proof_task = 1490 proof_task =
1598 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, 1491 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
1599 &find_proof, 1492 &find_proof,
1600 NULL); 1493 NULL);
1601 1494
1602 peers = GNUNET_CONTAINER_multipeermap_create (128, 1495 peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES);
1603 GNUNET_YES);
1604 nc = GNUNET_notification_context_create (1); 1496 nc = GNUNET_notification_context_create (1);
1605 /* Connect to core service and register core handlers */ 1497 /* Connect to core service and register core handlers */
1606 core_api = GNUNET_CORE_connect (cfg, /* Main configuration */ 1498 core_api =
1607 NULL, /* Closure passed to functions */ 1499 GNUNET_CORE_connect (cfg, /* Main configuration */
1608 &core_init, /* Call core_init once connected */ 1500 NULL, /* Closure passed to functions */
1609 &handle_core_connect, /* Handle connects */ 1501 &core_init, /* Call core_init once connected */
1610 &handle_core_disconnect, /* Handle disconnects */ 1502 &handle_core_connect, /* Handle connects */
1611 core_handlers); /* Register these handlers */ 1503 &handle_core_disconnect, /* Handle disconnects */
1504 core_handlers); /* Register these handlers */
1612 if (NULL == core_api) 1505 if (NULL == core_api)
1613 { 1506 {
1614 GNUNET_SCHEDULER_shutdown (); 1507 GNUNET_SCHEDULER_shutdown ();
1615 return; 1508 return;
1616 } 1509 }
1617 stats = GNUNET_STATISTICS_create ("nse", 1510 stats = GNUNET_STATISTICS_create ("nse", cfg);
1618 cfg);
1619} 1511}
1620 1512
1621 1513
@@ -1629,8 +1521,8 @@ run (void *cls,
1629 */ 1521 */
1630static void * 1522static void *
1631client_connect_cb (void *cls, 1523client_connect_cb (void *cls,
1632 struct GNUNET_SERVICE_Client *c, 1524 struct GNUNET_SERVICE_Client *c,
1633 struct GNUNET_MQ_Handle *mq) 1525 struct GNUNET_MQ_Handle *mq)
1634{ 1526{
1635 return c; 1527 return c;
1636} 1528}
@@ -1645,8 +1537,8 @@ client_connect_cb (void *cls,
1645 */ 1537 */
1646static void 1538static void
1647client_disconnect_cb (void *cls, 1539client_disconnect_cb (void *cls,
1648 struct GNUNET_SERVICE_Client *c, 1540 struct GNUNET_SERVICE_Client *c,
1649 void *internal_cls) 1541 void *internal_cls)
1650{ 1542{
1651 GNUNET_assert (c == internal_cls); 1543 GNUNET_assert (c == internal_cls);
1652} 1544}
@@ -1655,18 +1547,17 @@ client_disconnect_cb (void *cls,
1655/** 1547/**
1656 * Define "main" method using service macro. 1548 * Define "main" method using service macro.
1657 */ 1549 */
1658GNUNET_SERVICE_MAIN 1550GNUNET_SERVICE_MAIN ("nse",
1659("nse", 1551 GNUNET_SERVICE_OPTION_NONE,
1660 GNUNET_SERVICE_OPTION_NONE, 1552 &run,
1661 &run, 1553 &client_connect_cb,
1662 &client_connect_cb, 1554 &client_disconnect_cb,
1663 &client_disconnect_cb, 1555 NULL,
1664 NULL, 1556 GNUNET_MQ_hd_fixed_size (start,
1665 GNUNET_MQ_hd_fixed_size (start, 1557 GNUNET_MESSAGE_TYPE_NSE_START,
1666 GNUNET_MESSAGE_TYPE_NSE_START, 1558 struct GNUNET_MessageHeader,
1667 struct GNUNET_MessageHeader, 1559 NULL),
1668 NULL), 1560 GNUNET_MQ_handler_end ());
1669 GNUNET_MQ_handler_end ());
1670 1561
1671 1562
1672#if defined(LINUX) && defined(__GLIBC__) 1563#if defined(LINUX) && defined(__GLIBC__)
@@ -1675,8 +1566,7 @@ GNUNET_SERVICE_MAIN
1675/** 1566/**
1676 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 1567 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
1677 */ 1568 */
1678void __attribute__ ((constructor)) 1569void __attribute__ ((constructor)) GNUNET_ARM_memory_init ()
1679GNUNET_ARM_memory_init ()
1680{ 1570{
1681 mallopt (M_TRIM_THRESHOLD, 4 * 1024); 1571 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1682 mallopt (M_TOP_PAD, 1 * 1024); 1572 mallopt (M_TOP_PAD, 1 * 1024);
@@ -1685,5 +1575,4 @@ GNUNET_ARM_memory_init ()
1685#endif 1575#endif
1686 1576
1687 1577
1688
1689/* end of gnunet-service-nse.c */ 1578/* end of gnunet-service-nse.c */