diff options
-rw-r--r-- | src/nse/Makefile.am | 1 | ||||
-rw-r--r-- | src/nse/gnunet-service-nse.c | 430 | ||||
-rw-r--r-- | src/nse/nse.h | 42 |
3 files changed, 398 insertions, 75 deletions
diff --git a/src/nse/Makefile.am b/src/nse/Makefile.am index bb8e5f509..fa9d43f4d 100644 --- a/src/nse/Makefile.am +++ b/src/nse/Makefile.am | |||
@@ -40,6 +40,7 @@ gnunet_service_nse_LDADD = \ | |||
40 | $(top_builddir)/src/nse/libgnunetnse.la \ | 40 | $(top_builddir)/src/nse/libgnunetnse.la \ |
41 | $(top_builddir)/src/util/libgnunetutil.la \ | 41 | $(top_builddir)/src/util/libgnunetutil.la \ |
42 | $(top_builddir)/src/core/libgnunetcore.la \ | 42 | $(top_builddir)/src/core/libgnunetcore.la \ |
43 | -lm \ | ||
43 | $(GN_LIBINTL) | 44 | $(GN_LIBINTL) |
44 | gnunet_service_nse_DEPENDENCIES = \ | 45 | gnunet_service_nse_DEPENDENCIES = \ |
45 | libgnunetnse.la | 46 | libgnunetnse.la |
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c index 6c4466bc7..50ec9a013 100644 --- a/src/nse/gnunet-service-nse.c +++ b/src/nse/gnunet-service-nse.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "gnunet_constants.h" | 41 | #include "gnunet_constants.h" |
42 | #include "gnunet_container_lib.h" | 42 | #include "gnunet_container_lib.h" |
43 | #include "gnunet_protocols.h" | 43 | #include "gnunet_protocols.h" |
44 | #include "gnunet_signatures.h" | ||
44 | #include "gnunet_service_lib.h" | 45 | #include "gnunet_service_lib.h" |
45 | #include "gnunet_server_lib.h" | 46 | #include "gnunet_server_lib.h" |
46 | #include "gnunet_core_service.h" | 47 | #include "gnunet_core_service.h" |
@@ -52,7 +53,7 @@ | |||
52 | 53 | ||
53 | #define DEFAULT_CORE_QUEUE_SIZE 32 | 54 | #define DEFAULT_CORE_QUEUE_SIZE 32 |
54 | 55 | ||
55 | #define MILLISECONDS_PER_DAY 86400000 | 56 | #define DEFAULT_NSE_PRIORITY 0 |
56 | 57 | ||
57 | /** | 58 | /** |
58 | * Entry in the list of clients which | 59 | * Entry in the list of clients which |
@@ -78,6 +79,37 @@ struct ClientListEntry | |||
78 | }; | 79 | }; |
79 | 80 | ||
80 | /** | 81 | /** |
82 | * Per-peer information. | ||
83 | */ | ||
84 | struct NSEPeerEntry | ||
85 | { | ||
86 | /** | ||
87 | * Next peer entry (DLL) | ||
88 | */ | ||
89 | struct NSEPeerEntry *next; | ||
90 | |||
91 | /** | ||
92 | * Prev peer entry (DLL) | ||
93 | */ | ||
94 | struct NSEPeerEntry *prev; | ||
95 | |||
96 | /** | ||
97 | * Pending message for this peer. | ||
98 | */ | ||
99 | struct GNUNET_MessageHeader *pending_message; | ||
100 | |||
101 | /** | ||
102 | * Core handle for sending messages to this peer. | ||
103 | */ | ||
104 | struct GNUNET_CORE_TransmitHandle *th; | ||
105 | |||
106 | /** | ||
107 | * What is the identity of the peer? | ||
108 | */ | ||
109 | struct GNUNET_PeerIdentity id; | ||
110 | }; | ||
111 | |||
112 | /** | ||
81 | * Handle to our current configuration. | 113 | * Handle to our current configuration. |
82 | */ | 114 | */ |
83 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 115 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
@@ -85,12 +117,17 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
85 | /** | 117 | /** |
86 | * Handle to the core service. | 118 | * Handle to the core service. |
87 | */ | 119 | */ |
88 | struct GNUNET_CORE_Handle *coreAPI; | 120 | static struct GNUNET_CORE_Handle *coreAPI; |
89 | 121 | ||
90 | /** | 122 | /** |
91 | * Copy of this peer's identity. | 123 | * Head of global list of peers. |
92 | */ | 124 | */ |
93 | static struct GNUNET_PeerIdentity my_identity; | 125 | static struct NSEPeerEntry *peers_head; |
126 | |||
127 | /** | ||
128 | * Head of global list of clients. | ||
129 | */ | ||
130 | static struct NSEPeerEntry *peers_tail; | ||
94 | 131 | ||
95 | /** | 132 | /** |
96 | * Head of global list of clients. | 133 | * Head of global list of clients. |
@@ -104,6 +141,8 @@ static struct ClientListEntry *cle_tail; | |||
104 | 141 | ||
105 | /** | 142 | /** |
106 | * The current network size estimate. | 143 | * The current network size estimate. |
144 | * Number of bits matching on average | ||
145 | * thus far. | ||
107 | */ | 146 | */ |
108 | static double current_size_estimate; | 147 | static double current_size_estimate; |
109 | 148 | ||
@@ -115,9 +154,19 @@ static double current_std_dev; | |||
115 | 154 | ||
116 | /** | 155 | /** |
117 | * Array of the last DEFAULT_HISTORY_SIZE | 156 | * Array of the last DEFAULT_HISTORY_SIZE |
118 | * network size estimates. | 157 | * network size estimates (matching bits, actually). |
158 | */ | ||
159 | static unsigned int size_estimates[DEFAULT_HISTORY_SIZE]; | ||
160 | |||
161 | /** | ||
162 | * Array of size estimate messages. | ||
163 | */ | ||
164 | static struct GNUNET_NSE_FloodMessage size_estimate_messages[DEFAULT_HISTORY_SIZE]; | ||
165 | |||
166 | /** | ||
167 | * Index of most recent estimate. | ||
119 | */ | 168 | */ |
120 | //static double *size_estimates[DEFAULT_HISTORY_SIZE]; | 169 | static unsigned int estimate_index; |
121 | 170 | ||
122 | /** | 171 | /** |
123 | * Task scheduled to send flood message. | 172 | * Task scheduled to send flood message. |
@@ -125,6 +174,11 @@ static double current_std_dev; | |||
125 | static GNUNET_SCHEDULER_TaskIdentifier flood_task; | 174 | static GNUNET_SCHEDULER_TaskIdentifier flood_task; |
126 | 175 | ||
127 | /** | 176 | /** |
177 | * Task to schedule flood message and update state. | ||
178 | */ | ||
179 | static GNUNET_SCHEDULER_TaskIdentifier schedule_flood_task; | ||
180 | |||
181 | /** | ||
128 | * Notification context, simplifies client broadcasts. | 182 | * Notification context, simplifies client broadcasts. |
129 | */ | 183 | */ |
130 | static struct GNUNET_SERVER_NotificationContext *nc; | 184 | static struct GNUNET_SERVER_NotificationContext *nc; |
@@ -132,7 +186,7 @@ static struct GNUNET_SERVER_NotificationContext *nc; | |||
132 | /** | 186 | /** |
133 | * The previous major time. | 187 | * The previous major time. |
134 | */ | 188 | */ |
135 | struct GNUNET_TIME_Absolute previous_timestamp; | 189 | static struct GNUNET_TIME_Absolute previous_timestamp; |
136 | 190 | ||
137 | /** | 191 | /** |
138 | * The next major time. | 192 | * The next major time. |
@@ -150,6 +204,26 @@ static struct GNUNET_TIME_Relative increment; | |||
150 | static struct GNUNET_NSE_ClientMessage current_estimate_message; | 204 | static struct GNUNET_NSE_ClientMessage current_estimate_message; |
151 | 205 | ||
152 | /** | 206 | /** |
207 | * The public key of this peer. | ||
208 | */ | ||
209 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; | ||
210 | |||
211 | /** | ||
212 | * The private key of this peer. | ||
213 | */ | ||
214 | static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; | ||
215 | |||
216 | /** | ||
217 | * The peer identity of this peer. | ||
218 | */ | ||
219 | static struct GNUNET_PeerIdentity my_identity; | ||
220 | |||
221 | /** | ||
222 | * Our flood message, updated whenever a flood is sent. | ||
223 | */ | ||
224 | static struct GNUNET_NSE_FloodMessage flood_message; | ||
225 | |||
226 | /** | ||
153 | * Handler for START message from client, triggers an | 227 | * Handler for START message from client, triggers an |
154 | * immediate current network estimate notification. | 228 | * immediate current network estimate notification. |
155 | * Also, we remember the client for updates upon future | 229 | * Also, we remember the client for updates upon future |
@@ -172,45 +246,275 @@ handle_start_message (void *cls, | |||
172 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "NSE", "Received START message from client\n"); | 246 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "NSE", "Received START message from client\n"); |
173 | #endif | 247 | #endif |
174 | GNUNET_SERVER_notification_context_add (nc, client); | 248 | GNUNET_SERVER_notification_context_add (nc, client); |
175 | GNUNET_SERVER_notification_context_unicast (nc, client, | ||
176 | ¤t_estimate_message.header, | ||
177 | GNUNET_NO); | ||
178 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | 249 | GNUNET_SERVER_receive_done(client, GNUNET_OK); |
179 | } | 250 | } |
180 | 251 | ||
252 | |||
253 | /** | ||
254 | * Called when core is ready to send a message we asked for | ||
255 | * out to the destination. | ||
256 | * | ||
257 | * @param cls closure (NULL) | ||
258 | * @param size number of bytes available in buf | ||
259 | * @param buf where the callee should write the message | ||
260 | * @return number of bytes written to buf | ||
261 | */ | ||
262 | static size_t | ||
263 | transmit_ready (void *cls, size_t size, void *buf) | ||
264 | { | ||
265 | struct NSEPeerEntry *peer_entry = cls; | ||
266 | char *cbuf = buf; | ||
267 | |||
268 | size_t msize; | ||
269 | peer_entry->th = NULL; | ||
270 | if (buf == NULL) /* client disconnected */ | ||
271 | return 0; | ||
272 | |||
273 | if (peer_entry->pending_message == NULL) | ||
274 | return 0; | ||
275 | |||
276 | msize = ntohs(peer_entry->pending_message->size); | ||
277 | if (msize <= size) | ||
278 | memcpy(cbuf, peer_entry->pending_message, msize); | ||
279 | |||
280 | return msize; | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * We sent on our flood message or one that we received | ||
285 | * which was validated and closer than ours. Update the | ||
286 | * global list of recent messages and the average. Also | ||
287 | * re-broadcast the message to any clients. | ||
288 | * | ||
289 | * @param message the network flood message | ||
290 | */ | ||
291 | static void update_network_size_estimate(struct GNUNET_NSE_FloodMessage *message) | ||
292 | { | ||
293 | unsigned int i; | ||
294 | unsigned int count; | ||
295 | double average; | ||
296 | |||
297 | size_estimates[estimate_index] = htons(message->distance); | ||
298 | memcpy(&size_estimate_messages[estimate_index], message, sizeof(struct GNUNET_NSE_FloodMessage)); | ||
299 | |||
300 | count = 0; | ||
301 | for (i = 0; i < DEFAULT_HISTORY_SIZE; i++) | ||
302 | { | ||
303 | if (size_estimate_messages[i].distance != 0) | ||
304 | { | ||
305 | average += 1 << htons(size_estimate_messages[i].distance); | ||
306 | count++; | ||
307 | } | ||
308 | } | ||
309 | average /= (double)count; | ||
310 | current_estimate_message.size_estimate = average; | ||
311 | /* Finally, broadcast the current estimate to all clients */ | ||
312 | GNUNET_SERVER_notification_context_broadcast (nc, | ||
313 | ¤t_estimate_message.header, | ||
314 | GNUNET_NO); | ||
315 | } | ||
316 | |||
317 | static void | ||
318 | send_flood_message (void *cls, | ||
319 | const struct GNUNET_SCHEDULER_TaskContext * tc); | ||
320 | |||
321 | /** | ||
322 | * Schedule a flood message to be sent. | ||
323 | * | ||
324 | * @param cls unused | ||
325 | * @param tc context for this message | ||
326 | * | ||
327 | * This should be called on startup, | ||
328 | * when a valid flood message is received (and | ||
329 | * the next send flood message hasn't been | ||
330 | * scheduled yet) and when this peer sends | ||
331 | * a valid flood message. As such, there should | ||
332 | * always be a message scheduled to be sent. | ||
333 | */ | ||
334 | static void | ||
335 | schedule_flood_message (void *cls, | ||
336 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
337 | { | ||
338 | GNUNET_HashCode timestamp_hash; | ||
339 | struct GNUNET_TIME_Absolute curr_time; | ||
340 | struct GNUNET_TIME_Relative offset; | ||
341 | struct GNUNET_CRYPTO_RsaSignaturePurpose purpose; | ||
342 | unsigned int matching_bits; | ||
343 | double millisecond_offset; | ||
344 | |||
345 | schedule_flood_task = GNUNET_SCHEDULER_NO_TASK; | ||
346 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
347 | return; | ||
348 | |||
349 | GNUNET_assert(flood_task == GNUNET_SCHEDULER_NO_TASK); | ||
350 | |||
351 | if (0 != GNUNET_TIME_absolute_get_remaining(next_timestamp).rel_value) | ||
352 | { | ||
353 | GNUNET_break(0); /* Shouldn't ever happen! */ | ||
354 | schedule_flood_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(next_timestamp), &schedule_flood_message, NULL); | ||
355 | } | ||
356 | |||
357 | /* Get the current UTC time */ | ||
358 | curr_time = GNUNET_TIME_absolute_get(); | ||
359 | /* Find the previous interval start time */ | ||
360 | previous_timestamp.abs_value = (curr_time.abs_value / GNUNET_NSE_INTERVAL) * GNUNET_NSE_INTERVAL; | ||
361 | /* Find the next interval start time */ | ||
362 | next_timestamp.abs_value = (curr_time.abs_value / GNUNET_NSE_INTERVAL) * (GNUNET_NSE_INTERVAL + 1); | ||
363 | |||
364 | GNUNET_CRYPTO_hash(&next_timestamp.abs_value, sizeof(uint64_t), ×tamp_hash); | ||
365 | matching_bits = GNUNET_CRYPTO_hash_matching_bits(×tamp_hash, &my_identity.hashPubKey); | ||
366 | |||
367 | flood_message.timestamp = GNUNET_TIME_absolute_hton(next_timestamp); | ||
368 | flood_message.distance = htons(matching_bits); | ||
369 | flood_message.enc_type = htons(0); | ||
370 | flood_message.proof_of_work = htonl(0); | ||
371 | purpose.purpose = GNUNET_SIGNATURE_PURPOSE_NSE_SEND; | ||
372 | purpose.size = sizeof(struct GNUNET_NSE_FloodMessage) - sizeof(struct GNUNET_MessageHeader) - sizeof(flood_message.proof_of_work) - sizeof(flood_message.signature); | ||
373 | GNUNET_CRYPTO_rsa_sign(my_private_key, &purpose, &flood_message.signature); | ||
374 | |||
375 | /*S + f/2 - (f / pi) * (atan(x - p'))*/ | ||
376 | |||
377 | // S is next_timestamp | ||
378 | // f is frequency (GNUNET_NSE_INTERVAL) | ||
379 | // x is matching_bits | ||
380 | // p' is current_size_estimate | ||
381 | millisecond_offset = ((double)GNUNET_NSE_INTERVAL / (double)2) - ((GNUNET_NSE_INTERVAL / M_PI) * atan(matching_bits - current_size_estimate)); | ||
382 | |||
383 | fprintf(stderr, "my id matches %d bits, offset is %lu\n", matching_bits, (uint64_t)millisecond_offset); | ||
384 | |||
385 | estimate_index += 1; | ||
386 | |||
387 | if (estimate_index >= DEFAULT_HISTORY_SIZE) | ||
388 | estimate_index = 0; | ||
389 | |||
390 | offset.rel_value = (uint64_t)millisecond_offset + GNUNET_TIME_absolute_get_remaining (next_timestamp).rel_value; | ||
391 | flood_task = GNUNET_SCHEDULER_add_delayed (offset, | ||
392 | &send_flood_message, NULL); | ||
393 | |||
394 | } | ||
395 | |||
181 | /** | 396 | /** |
182 | * Core handler for size estimate flooding messages. | 397 | * Core handler for size estimate flooding messages. |
183 | * | 398 | * |
184 | * @param cls closure | 399 | * @param cls closure unused |
185 | * @param message message | 400 | * @param message message |
186 | * @param peer peer identity this notification is about | 401 | * @param peer peer identity this message is from (ignored) |
187 | * @param atsi performance data | 402 | * @param atsi performance data (ignored) |
188 | * | 403 | * |
189 | */ | 404 | */ |
190 | static int | 405 | static int |
191 | handle_p2p_size_estimate (void *cls, | 406 | handle_p2p_size_estimate(void *cls, const struct GNUNET_PeerIdentity *peer, |
192 | const struct GNUNET_PeerIdentity *peer, | 407 | const struct GNUNET_MessageHeader *message, |
193 | const struct GNUNET_MessageHeader *message, | 408 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) |
194 | const struct GNUNET_TRANSPORT_ATS_Information | ||
195 | *atsi) | ||
196 | { | 409 | { |
410 | struct GNUNET_NSE_FloodMessage *incoming_flood; | ||
411 | |||
412 | if (ntohs(message->size) != sizeof(struct GNUNET_NSE_FloodMessage)) | ||
413 | return GNUNET_NO; | ||
414 | |||
415 | incoming_flood = (struct GNUNET_NSE_FloodMessage *)message; | ||
416 | if (ntohs(incoming_flood->distance) <= ntohs(size_estimate_messages[estimate_index].distance)) /* Not closer than our most recent message */ | ||
417 | return GNUNET_OK; | ||
418 | |||
419 | /* Have a new, better size estimate! */ | ||
420 | update_network_size_estimate(incoming_flood); | ||
421 | |||
422 | if (schedule_flood_task != GNUNET_SCHEDULER_NO_TASK) | ||
423 | GNUNET_SCHEDULER_cancel(schedule_flood_task); | ||
424 | schedule_flood_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(next_timestamp), &schedule_flood_message, NULL); | ||
197 | 425 | ||
198 | return GNUNET_OK; | 426 | return GNUNET_OK; |
199 | } | 427 | } |
200 | 428 | ||
201 | |||
202 | /** | 429 | /** |
203 | * Send a flood message containing our peer's public key | 430 | * Send a flood message. |
204 | * and the hashed current timestamp. | 431 | * |
432 | * If we've gotten here, it means we haven't received | ||
433 | * a network size estimate message closer than ours. | ||
205 | */ | 434 | */ |
206 | static void | 435 | static void |
207 | send_flood_message (void *cls, | 436 | send_flood_message (void *cls, |
208 | const struct GNUNET_SCHEDULER_TaskContext * tc) | 437 | const struct GNUNET_SCHEDULER_TaskContext * tc) |
209 | { | 438 | { |
439 | struct NSEPeerEntry *peer_entry; | ||
440 | |||
441 | flood_task = GNUNET_SCHEDULER_NO_TASK; | ||
210 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 442 | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) |
211 | return; | 443 | return; |
444 | |||
445 | peer_entry = peers_head; | ||
446 | |||
447 | while (peer_entry != NULL) | ||
448 | { | ||
449 | peer_entry->th | ||
450 | = GNUNET_CORE_notify_transmit_ready (coreAPI, | ||
451 | GNUNET_YES, | ||
452 | DEFAULT_NSE_PRIORITY, | ||
453 | GNUNET_TIME_absolute_get_remaining ( | ||
454 | next_timestamp), | ||
455 | &peer_entry->id, | ||
456 | ntohs (flood_message.header.size), | ||
457 | &transmit_ready, peer_entry); | ||
458 | peer_entry = peer_entry->next; | ||
459 | } | ||
460 | |||
461 | update_network_size_estimate(&flood_message); | ||
462 | if (schedule_flood_task != GNUNET_SCHEDULER_NO_TASK) | ||
463 | GNUNET_SCHEDULER_cancel(schedule_flood_task); | ||
464 | schedule_flood_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(next_timestamp), &schedule_flood_message, NULL); | ||
465 | } | ||
466 | |||
467 | /** | ||
468 | * Method called whenever a peer connects. | ||
469 | * | ||
470 | * @param cls closure | ||
471 | * @param peer peer identity this notification is about | ||
472 | * @param atsi performance data | ||
473 | */ | ||
474 | static void | ||
475 | handle_core_connect (void *cls, | ||
476 | const struct GNUNET_PeerIdentity *peer, | ||
477 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | ||
478 | { | ||
479 | struct NSEPeerEntry *peer_entry; | ||
480 | |||
481 | peer_entry = GNUNET_malloc(sizeof(struct NSEPeerEntry)); | ||
482 | memcpy(&peer_entry->id, peer, sizeof(struct GNUNET_PeerIdentity)); | ||
483 | GNUNET_CONTAINER_DLL_insert(peers_head, peers_tail, peer_entry); | ||
484 | } | ||
485 | |||
486 | |||
487 | /** | ||
488 | * Method called whenever a peer disconnects. | ||
489 | * | ||
490 | * @param cls closure | ||
491 | * @param peer peer identity this notification is about | ||
492 | */ | ||
493 | static void | ||
494 | handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
495 | { | ||
496 | struct NSEPeerEntry *pos; | ||
497 | |||
498 | pos = peers_head; | ||
499 | while ((NULL != pos) && (0 != memcmp(&pos->id, peer, sizeof(struct GNUNET_PeerIdentity)))) | ||
500 | pos = pos->next; | ||
501 | if (pos == NULL) | ||
502 | { | ||
503 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received disconnect before connect!\n"); | ||
504 | GNUNET_break(0); /* Should never receive a disconnect message for a peer we don't know about... */ | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | if (pos->pending_message != NULL) | ||
509 | GNUNET_free(pos->pending_message); | ||
510 | |||
511 | if (pos->th != NULL) | ||
512 | GNUNET_CORE_notify_transmit_ready_cancel(pos->th); | ||
513 | GNUNET_CONTAINER_DLL_remove(peers_head, peers_tail, pos); | ||
514 | GNUNET_free(pos); | ||
212 | } | 515 | } |
213 | 516 | ||
517 | |||
214 | /** | 518 | /** |
215 | * A client disconnected. Remove it from the | 519 | * A client disconnected. Remove it from the |
216 | * global DLL of clients. | 520 | * global DLL of clients. |
@@ -254,6 +558,8 @@ shutdown_task (void *cls, | |||
254 | { | 558 | { |
255 | struct ClientListEntry *cle; | 559 | struct ClientListEntry *cle; |
256 | 560 | ||
561 | if (flood_task != GNUNET_SCHEDULER_NO_TASK) | ||
562 | GNUNET_SCHEDULER_cancel(flood_task); | ||
257 | GNUNET_SERVER_notification_context_destroy (nc); | 563 | GNUNET_SERVER_notification_context_destroy (nc); |
258 | nc = NULL; | 564 | nc = NULL; |
259 | while (NULL != (cle = cle_head)) | 565 | while (NULL != (cle = cle_head)) |
@@ -275,40 +581,6 @@ shutdown_task (void *cls, | |||
275 | 581 | ||
276 | 582 | ||
277 | /** | 583 | /** |
278 | * Task to schedule a flood message to be sent. | ||
279 | * | ||
280 | * @param cls closure | ||
281 | * @param tc context information (why was this task triggered now) | ||
282 | */ | ||
283 | static void schedule_flood_message (void *cls, | ||
284 | const struct | ||
285 | GNUNET_SCHEDULER_TaskContext * tc) | ||
286 | { | ||
287 | GNUNET_HashCode timestamp_hash; | ||
288 | struct GNUNET_TIME_Absolute curr_time; | ||
289 | unsigned int matching_bits; | ||
290 | |||
291 | /* Get the current UTC time */ | ||
292 | curr_time = GNUNET_TIME_absolute_get(); | ||
293 | /* Find the previous interval start time */ | ||
294 | previous_timestamp.abs_value = (curr_time.abs_value / GNUNET_NSE_INTERVAL) * GNUNET_NSE_INTERVAL; | ||
295 | /* Find the next interval start time */ | ||
296 | next_timestamp.abs_value = (curr_time.abs_value / GNUNET_NSE_INTERVAL) * (GNUNET_NSE_INTERVAL + 1); | ||
297 | |||
298 | GNUNET_CRYPTO_hash(&next_timestamp.abs_value, sizeof(uint64_t), ×tamp_hash); | ||
299 | matching_bits = GNUNET_CRYPTO_hash_matching_bits(×tamp_hash, &my_identity.hashPubKey); | ||
300 | |||
301 | GNUNET_SCHEDULER_add_delayed ( | ||
302 | GNUNET_TIME_relative_add ( | ||
303 | GNUNET_TIME_relative_multiply ( | ||
304 | increment, | ||
305 | matching_bits), | ||
306 | GNUNET_TIME_absolute_get_remaining ( | ||
307 | next_timestamp)), | ||
308 | &send_flood_message, NULL); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * Called on core init/fail. | 584 | * Called on core init/fail. |
313 | * | 585 | * |
314 | * @param cls service closure | 586 | * @param cls service closure |
@@ -340,8 +612,21 @@ core_init (void *cls, | |||
340 | 612 | ||
341 | /* Copy our identity so we can use it */ | 613 | /* Copy our identity so we can use it */ |
342 | memcpy (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity)); | 614 | memcpy (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity)); |
615 | /* Copy our public key for inclusion in flood messages */ | ||
616 | memcpy (&my_public_key, publicKey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
617 | |||
618 | flood_message.header.size = htons(sizeof(struct GNUNET_NSE_FloodMessage)); | ||
619 | flood_message.header.type = htons(GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD); | ||
620 | memcpy(&flood_message.pkey, &my_public_key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
621 | |||
622 | if (flood_task != GNUNET_SCHEDULER_NO_TASK) | ||
623 | GNUNET_SCHEDULER_cancel(flood_task); | ||
343 | 624 | ||
344 | flood_task = GNUNET_SCHEDULER_add_now(&schedule_flood_message, NULL); | 625 | schedule_flood_task = GNUNET_SCHEDULER_add_now(&schedule_flood_message, NULL); |
626 | |||
627 | GNUNET_SERVER_notification_context_broadcast (nc, | ||
628 | ¤t_estimate_message.header, | ||
629 | GNUNET_NO); | ||
345 | } | 630 | } |
346 | 631 | ||
347 | /** | 632 | /** |
@@ -356,6 +641,7 @@ run (void *cls, | |||
356 | struct GNUNET_SERVER_Handle *server, | 641 | struct GNUNET_SERVER_Handle *server, |
357 | const struct GNUNET_CONFIGURATION_Handle *c) | 642 | const struct GNUNET_CONFIGURATION_Handle *c) |
358 | { | 643 | { |
644 | char *keyfile; | ||
359 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 645 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
360 | {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START, 0}, | 646 | {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START, 0}, |
361 | {NULL, NULL, 0, 0} | 647 | {NULL, NULL, 0, 0} |
@@ -367,19 +653,43 @@ run (void *cls, | |||
367 | }; | 653 | }; |
368 | 654 | ||
369 | cfg = c; | 655 | cfg = c; |
656 | |||
657 | if (GNUNET_OK != | ||
658 | GNUNET_CONFIGURATION_get_value_filename (c, | ||
659 | "GNUNETD", | ||
660 | "HOSTKEY", &keyfile)) | ||
661 | { | ||
662 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
663 | _ | ||
664 | ("NSE service is lacking key configuration settings. Exiting.\n")); | ||
665 | GNUNET_SCHEDULER_shutdown (); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); | ||
670 | GNUNET_free (keyfile); | ||
671 | if (my_private_key == NULL) | ||
672 | { | ||
673 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
674 | _("NSE Service could not access hostkey. Exiting.\n")); | ||
675 | GNUNET_SCHEDULER_shutdown (); | ||
676 | return; | ||
677 | } | ||
678 | |||
370 | GNUNET_SERVER_add_handlers (server, handlers); | 679 | GNUNET_SERVER_add_handlers (server, handlers); |
371 | nc = GNUNET_SERVER_notification_context_create (server, 16); | 680 | nc = GNUNET_SERVER_notification_context_create (server, 16); |
372 | GNUNET_SERVER_disconnect_notify (server, | 681 | GNUNET_SERVER_disconnect_notify (server, |
373 | &handle_client_disconnect, | 682 | &handle_client_disconnect, |
374 | NULL); | 683 | NULL); |
375 | 684 | ||
685 | flood_task = GNUNET_SCHEDULER_NO_TASK; | ||
376 | /** Connect to core service and register core handlers */ | 686 | /** Connect to core service and register core handlers */ |
377 | coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */ | 687 | coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */ |
378 | DEFAULT_CORE_QUEUE_SIZE, /* queue size */ | 688 | DEFAULT_CORE_QUEUE_SIZE, /* queue size */ |
379 | NULL, /* Closure passed to functions */ | 689 | NULL, /* Closure passed to functions */ |
380 | &core_init, /* Call core_init once connected */ | 690 | &core_init, /* Call core_init once connected */ |
381 | NULL, /* Handle connects */ | 691 | &handle_core_connect, /* Handle connects */ |
382 | NULL, /* Handle disconnects */ | 692 | &handle_core_disconnect, /* Handle disconnects */ |
383 | NULL, /* Do we care about "status" updates? */ | 693 | NULL, /* Do we care about "status" updates? */ |
384 | NULL, /* Don't want notified about all incoming messages */ | 694 | NULL, /* Don't want notified about all incoming messages */ |
385 | GNUNET_NO, /* For header only inbound notification */ | 695 | GNUNET_NO, /* For header only inbound notification */ |
@@ -399,9 +709,9 @@ run (void *cls, | |||
399 | / (sizeof(GNUNET_HashCode) | 709 | / (sizeof(GNUNET_HashCode) |
400 | * 8)); | 710 | * 8)); |
401 | /* Set we have no idea defaults for network size estimate */ | 711 | /* Set we have no idea defaults for network size estimate */ |
402 | current_size_estimate = NAN; | 712 | current_size_estimate = 0.0; |
403 | current_std_dev = NAN; | 713 | current_std_dev = NAN; |
404 | 714 | size_estimates[estimate_index] = 0; | |
405 | current_estimate_message.header.size = htons(sizeof(struct GNUNET_NSE_ClientMessage)); | 715 | current_estimate_message.header.size = htons(sizeof(struct GNUNET_NSE_ClientMessage)); |
406 | current_estimate_message.header.type = htons(GNUNET_MESSAGE_TYPE_NSE_ESTIMATE); | 716 | current_estimate_message.header.type = htons(GNUNET_MESSAGE_TYPE_NSE_ESTIMATE); |
407 | current_estimate_message.size_estimate = current_size_estimate; | 717 | current_estimate_message.size_estimate = current_size_estimate; |
diff --git a/src/nse/nse.h b/src/nse/nse.h index ee9832dc6..59dd6bc1b 100644 --- a/src/nse/nse.h +++ b/src/nse/nse.h | |||
@@ -32,14 +32,6 @@ | |||
32 | 32 | ||
33 | #define DEBUG_NSE GNUNET_YES | 33 | #define DEBUG_NSE GNUNET_YES |
34 | 34 | ||
35 | #define SIGNED_TIMESTAMP_SIZE sizeof(struct GNUNET_TIME_Absolute) | ||
36 | |||
37 | /** FIXME: define NSE message types here. */ | ||
38 | |||
39 | struct GNUNET_Signed_Timestamp | ||
40 | { | ||
41 | char data[SIGNED_TIMESTAMP_SIZE]; | ||
42 | }; | ||
43 | 35 | ||
44 | /** | 36 | /** |
45 | * Network size estimate sent from the service | 37 | * Network size estimate sent from the service |
@@ -95,25 +87,45 @@ struct GNUNET_NSE_ClientMessage | |||
95 | * doesn't allow us to verify that the | 87 | * doesn't allow us to verify that the |
96 | * public/private key pair were generated, right? | 88 | * public/private key pair were generated, right? |
97 | */ | 89 | */ |
98 | struct GNUNET_NSE_ReplyMessage | 90 | struct GNUNET_NSE_FloodMessage |
99 | { | 91 | { |
100 | /** | 92 | /** |
101 | * Type: GNUNET_MESSAGE_TYPE_NSE_REPLY | 93 | * Type: GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD |
102 | */ | 94 | */ |
103 | struct GNUNET_MessageHeader header; | 95 | struct GNUNET_MessageHeader header; |
104 | 96 | ||
105 | /** | 97 | /** |
98 | * Magic header code(?) | ||
99 | */ | ||
100 | uint16_t enc_type; | ||
101 | |||
102 | /** | ||
103 | * Number of matching bits between the hash | ||
104 | * of timestamp and the initiator's public | ||
105 | * key. | ||
106 | */ | ||
107 | uint16_t distance; | ||
108 | |||
109 | /** | ||
106 | * The current timestamp value (which all | 110 | * The current timestamp value (which all |
107 | * peers should agree on) signed by the | 111 | * peers should agree on). |
108 | * private key of the initiating peer. | ||
109 | */ | 112 | */ |
110 | struct GNUNET_Signed_Timestamp timestamp; | 113 | struct GNUNET_TIME_AbsoluteNBO timestamp; |
111 | 114 | ||
112 | /** | 115 | /** |
113 | * Public key of the originator, signed timestamp | 116 | * Public key of the originator. |
114 | * is decrypted by this. | ||
115 | */ | 117 | */ |
116 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; | 118 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; |
119 | |||
120 | /** | ||
121 | * FIXME: use, document. | ||
122 | */ | ||
123 | uint32_t proof_of_work; | ||
124 | |||
125 | /** | ||
126 | * FIXME: use, document. | ||
127 | */ | ||
128 | struct GNUNET_CRYPTO_RsaSignature signature; | ||
117 | }; | 129 | }; |
118 | 130 | ||
119 | #endif | 131 | #endif |