aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/defaults.conf1
-rw-r--r--src/nse/gnunet-service-nse.c138
2 files changed, 120 insertions, 19 deletions
diff --git a/contrib/defaults.conf b/contrib/defaults.conf
index 7a072f1d3..639c30f6a 100644
--- a/contrib/defaults.conf
+++ b/contrib/defaults.conf
@@ -431,6 +431,7 @@ ACCEPT_FROM6 = ::1;
431UNIXPATH = /tmp/test-nse-service-nse.unix 431UNIXPATH = /tmp/test-nse-service-nse.unix
432UNIX_MATCH_UID = YES 432UNIX_MATCH_UID = YES
433UNIX_MATCH_GID = YES 433UNIX_MATCH_GID = YES
434PROOFFILE = $SERVICEHOME/.nse-proof
434 435
435 436
436[vpn] 437[vpn]
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index c690eb1e2..066ba3463 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -34,9 +34,6 @@
34 * those peer from sending their messages at a later duration. So 34 * those peer from sending their messages at a later duration. So
35 * every peer should receive the same nearest peer message, and from 35 * every peer should receive the same nearest peer message, and from
36 * this can calculate the expected number of peers in the network. 36 * this can calculate the expected number of peers in the network.
37 *
38 * TODO:
39 * - generate proof-of-work asynchronously, store it on disk & load it back
40 */ 37 */
41#include "platform.h" 38#include "platform.h"
42#include "gnunet_util_lib.h" 39#include "gnunet_util_lib.h"
@@ -73,6 +70,11 @@
73 */ 70 */
74#define GNUNET_NSE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) 71#define GNUNET_NSE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
75 72
73/**
74 * Interval between proof find runs.
75 */
76#define PROOF_FIND_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 50)
77
76 78
77/** 79/**
78 * Per-peer information. 80 * Per-peer information.
@@ -223,6 +225,11 @@ static unsigned int estimate_count;
223static GNUNET_SCHEDULER_TaskIdentifier flood_task; 225static GNUNET_SCHEDULER_TaskIdentifier flood_task;
224 226
225/** 227/**
228 * Task scheduled to compute our proof.
229 */
230static GNUNET_SCHEDULER_TaskIdentifier proof_task;
231
232/**
226 * Notification context, simplifies client broadcasts. 233 * Notification context, simplifies client broadcasts.
227 */ 234 */
228static struct GNUNET_SERVER_NotificationContext *nc; 235static struct GNUNET_SERVER_NotificationContext *nc;
@@ -484,6 +491,24 @@ transmit_ready (void *cls, size_t size, void *buf)
484 &transmit_task, 491 &transmit_task,
485 peer_entry); 492 peer_entry);
486 } 493 }
494 if ( (ntohl (size_estimate_messages[idx].hop_count) == 0) &&
495 (GNUNET_SCHEDULER_NO_TASK != proof_task) )
496 {
497 GNUNET_STATISTICS_update (stats,
498 "# flood messages not generated (no proof yet)",
499 1,
500 GNUNET_NO);
501 return 0;
502 }
503 if (ntohl (size_estimate_messages[idx].hop_count) == 0)
504 GNUNET_STATISTICS_update (stats,
505 "# flood messages started",
506 1,
507 GNUNET_NO);
508 GNUNET_STATISTICS_update (stats,
509 "# flood messages transmitted",
510 1,
511 GNUNET_NO);
487 memcpy (buf, 512 memcpy (buf,
488 &size_estimate_messages[idx], 513 &size_estimate_messages[idx],
489 sizeof (struct GNUNET_NSE_FloodMessage)); 514 sizeof (struct GNUNET_NSE_FloodMessage));
@@ -705,35 +730,74 @@ check_proof_of_work(const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey,
705 730
706 731
707/** 732/**
708 * Given a public key, find an integer such that the hash of the key 733 * Write our current proof to disk.
709 * concatenated with the integer has NSE_WORK_REQUIRED leading 0 734 */
710 * bits. FIXME: this is a synchronous function... bad 735static void
736write_proof ()
737{
738 char *proof;
739
740 if (GNUNET_OK !=
741 GNUNET_CONFIGURATION_get_value_filename (cfg,
742 "NSE", "PROOFFILE",
743 &proof))
744 return;
745 if (sizeof (my_proof) !=
746 GNUNET_DISK_fn_write (proof,
747 &my_proof,
748 sizeof (my_proof),
749 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))
750 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
751 "write",
752 proof);
753 GNUNET_free (proof);
754
755}
756
757
758/**
759 * Find our proof of work.
711 * 760 *
712 * @param pkey the public key 761 * @param cls closure (unused)
713 * @return 64 bit number that satisfies the requirements 762 * @param tc task context
714 */ 763 */
715static uint64_t 764static void
716find_proof_of_work(const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey) 765find_proof (void *cls,
766 const struct GNUNET_SCHEDULER_TaskContext *tc)
717{ 767{
768#define ROUND_SIZE 10
718 uint64_t counter; 769 uint64_t counter;
719 char buf[sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + sizeof(uint64_t)]; 770 char buf[sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + sizeof(uint64_t)];
720 GNUNET_HashCode result; 771 GNUNET_HashCode result;
772 unsigned int i;
721 773
774 proof_task = GNUNET_SCHEDULER_NO_TASK;
722 memcpy (&buf[sizeof(uint64_t)], 775 memcpy (&buf[sizeof(uint64_t)],
723 pkey, 776 &my_public_key,
724 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 777 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
725 counter = 0; 778 i = 0;
726 while (counter != UINT64_MAX) 779 counter = my_proof;
780 while ( (counter != UINT64_MAX) && (i < ROUND_SIZE) )
727 { 781 {
728 memcpy (buf, 782 memcpy (buf,
729 &counter, 783 &counter,
730 sizeof(uint64_t)); 784 sizeof(uint64_t));
731 GNUNET_CRYPTO_hash (buf, sizeof (buf), &result); 785 GNUNET_CRYPTO_hash (buf, sizeof (buf), &result);
732 if (NSE_WORK_REQUIRED <= count_leading_zeroes(&result)) 786 if (NSE_WORK_REQUIRED <= count_leading_zeroes(&result))
733 break; 787 {
788 my_proof = counter;
789 write_proof ();
790 return;
791 }
734 counter++; 792 counter++;
793 i++;
735 } 794 }
736 return counter; 795 my_proof = counter;
796 if (0 == (my_proof % 100 * ROUND_SIZE))
797 write_proof (); /* remember progress every 100 rounds */
798 proof_task = GNUNET_SCHEDULER_add_delayed (PROOF_FIND_DELAY,
799 &find_proof,
800 NULL);
737} 801}
738 802
739 803
@@ -1011,6 +1075,12 @@ shutdown_task(void *cls,
1011 GNUNET_SCHEDULER_cancel (flood_task); 1075 GNUNET_SCHEDULER_cancel (flood_task);
1012 flood_task = GNUNET_SCHEDULER_NO_TASK; 1076 flood_task = GNUNET_SCHEDULER_NO_TASK;
1013 } 1077 }
1078 if (proof_task != GNUNET_SCHEDULER_NO_TASK)
1079 {
1080 GNUNET_SCHEDULER_cancel (proof_task);
1081 proof_task = GNUNET_SCHEDULER_NO_TASK;
1082 write_proof (); /* remember progress */
1083 }
1014 if (nc != NULL) 1084 if (nc != NULL)
1015 { 1085 {
1016 GNUNET_SERVER_notification_context_destroy (nc); 1086 GNUNET_SERVER_notification_context_destroy (nc);
@@ -1031,6 +1101,11 @@ shutdown_task(void *cls,
1031 GNUNET_CONTAINER_multihashmap_destroy (peers); 1101 GNUNET_CONTAINER_multihashmap_destroy (peers);
1032 peers = NULL; 1102 peers = NULL;
1033 } 1103 }
1104 if (my_private_key != NULL)
1105 {
1106 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1107 my_private_key = NULL;
1108 }
1034} 1109}
1035 1110
1036 1111
@@ -1060,9 +1135,7 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
1060 GNUNET_SCHEDULER_shutdown (); 1135 GNUNET_SCHEDULER_shutdown ();
1061 return; 1136 return;
1062 } 1137 }
1063 my_identity = *identity; 1138 GNUNET_assert (0 == memcmp (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity)));
1064 my_public_key = *publicKey;
1065
1066 now = GNUNET_TIME_absolute_get (); 1139 now = GNUNET_TIME_absolute_get ();
1067 current_timestamp.abs_value = (now.abs_value / GNUNET_NSE_INTERVAL.rel_value) * GNUNET_NSE_INTERVAL.rel_value; 1140 current_timestamp.abs_value = (now.abs_value / GNUNET_NSE_INTERVAL.rel_value) * GNUNET_NSE_INTERVAL.rel_value;
1068 next_timestamp.abs_value = current_timestamp.abs_value + GNUNET_NSE_INTERVAL.rel_value; 1141 next_timestamp.abs_value = current_timestamp.abs_value + GNUNET_NSE_INTERVAL.rel_value;
@@ -1077,7 +1150,6 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
1077 flood_task 1150 flood_task
1078 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_timestamp), 1151 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_timestamp),
1079 &update_flood_message, NULL); 1152 &update_flood_message, NULL);
1080 my_proof = find_proof_of_work (&my_public_key);
1081} 1153}
1082 1154
1083 1155
@@ -1093,6 +1165,7 @@ run(void *cls, struct GNUNET_SERVER_Handle *server,
1093 const struct GNUNET_CONFIGURATION_Handle *c) 1165 const struct GNUNET_CONFIGURATION_Handle *c)
1094{ 1166{
1095 char *keyfile; 1167 char *keyfile;
1168 char *proof;
1096 1169
1097 static const struct GNUNET_SERVER_MessageHandler handlers[] = 1170 static const struct GNUNET_SERVER_MessageHandler handlers[] =
1098 { 1171 {
@@ -1124,6 +1197,33 @@ run(void *cls, struct GNUNET_SERVER_Handle *server,
1124 GNUNET_SCHEDULER_shutdown (); 1197 GNUNET_SCHEDULER_shutdown ();
1125 return; 1198 return;
1126 } 1199 }
1200 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
1201 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_identity.hashPubKey);
1202 if (GNUNET_OK !=
1203 GNUNET_CONFIGURATION_get_value_filename (cfg,
1204 "NSE", "PROOFFILE",
1205 &proof))
1206 {
1207 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1208 _ ("NSE service is lacking key configuration settings. Exiting.\n"));
1209 if (my_private_key != NULL)
1210 {
1211 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1212 my_private_key = NULL;
1213 }
1214 GNUNET_SCHEDULER_shutdown ();
1215 return;
1216 }
1217 if (sizeof (my_proof) !=
1218 GNUNET_DISK_fn_read (proof,
1219 &my_proof,
1220 sizeof (my_proof)))
1221 my_proof = 0;
1222 GNUNET_free (proof);
1223 proof_task = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
1224 &find_proof,
1225 NULL);
1226
1127 peers = GNUNET_CONTAINER_multihashmap_create (128); 1227 peers = GNUNET_CONTAINER_multihashmap_create (128);
1128 GNUNET_SERVER_add_handlers (server, handlers); 1228 GNUNET_SERVER_add_handlers (server, handlers);
1129 nc = GNUNET_SERVER_notification_context_create (server, 1); 1229 nc = GNUNET_SERVER_notification_context_create (server, 1);