diff options
Diffstat (limited to 'src/dht/dht_api.c')
-rw-r--r-- | src/dht/dht_api.c | 534 |
1 files changed, 252 insertions, 282 deletions
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 11f13b184..101751487 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -60,12 +60,12 @@ struct PendingMessage | |||
60 | * of this struct. | 60 | * of this struct. |
61 | */ | 61 | */ |
62 | const struct GNUNET_MessageHeader *msg; | 62 | const struct GNUNET_MessageHeader *msg; |
63 | 63 | ||
64 | /** | 64 | /** |
65 | * Handle to the DHT API context. | 65 | * Handle to the DHT API context. |
66 | */ | 66 | */ |
67 | struct GNUNET_DHT_Handle *handle; | 67 | struct GNUNET_DHT_Handle *handle; |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * Continuation to call when the request has been | 70 | * Continuation to call when the request has been |
71 | * transmitted (for the first time) to the service; can be NULL. | 71 | * transmitted (for the first time) to the service; can be NULL. |
@@ -203,10 +203,7 @@ struct GNUNET_DHT_Handle | |||
203 | /** | 203 | /** |
204 | * Transmit the next pending message, called by notify_transmit_ready | 204 | * Transmit the next pending message, called by notify_transmit_ready |
205 | */ | 205 | */ |
206 | static size_t | 206 | static size_t transmit_pending (void *cls, size_t size, void *buf); |
207 | transmit_pending (void *cls, | ||
208 | size_t size, | ||
209 | void *buf); | ||
210 | 207 | ||
211 | 208 | ||
212 | /** | 209 | /** |
@@ -215,8 +212,7 @@ transmit_pending (void *cls, | |||
215 | * | 212 | * |
216 | */ | 213 | */ |
217 | static void | 214 | static void |
218 | service_message_handler (void *cls, | 215 | service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg); |
219 | const struct GNUNET_MessageHeader *msg); | ||
220 | 216 | ||
221 | 217 | ||
222 | 218 | ||
@@ -233,19 +229,18 @@ try_connect (struct GNUNET_DHT_Handle *handle) | |||
233 | return GNUNET_OK; | 229 | return GNUNET_OK; |
234 | handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); | 230 | handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); |
235 | if (handle->client == NULL) | 231 | if (handle->client == NULL) |
236 | { | 232 | { |
237 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 233 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
238 | _("Failed to connect to the DHT service!\n")); | 234 | _("Failed to connect to the DHT service!\n")); |
239 | return GNUNET_NO; | 235 | return GNUNET_NO; |
240 | } | 236 | } |
241 | #if DEBUG_DHT | 237 | #if DEBUG_DHT |
242 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
243 | "Starting to process replies from DHT\n"); | 239 | "Starting to process replies from DHT\n"); |
244 | #endif | 240 | #endif |
245 | GNUNET_CLIENT_receive (handle->client, | 241 | GNUNET_CLIENT_receive (handle->client, |
246 | &service_message_handler, | 242 | &service_message_handler, |
247 | handle, | 243 | handle, GNUNET_TIME_UNIT_FOREVER_REL); |
248 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
249 | return GNUNET_YES; | 244 | return GNUNET_YES; |
250 | } | 245 | } |
251 | 246 | ||
@@ -260,20 +255,17 @@ try_connect (struct GNUNET_DHT_Handle *handle) | |||
260 | * @return GNUNET_YES (always) | 255 | * @return GNUNET_YES (always) |
261 | */ | 256 | */ |
262 | static int | 257 | static int |
263 | add_request_to_pending (void *cls, | 258 | add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) |
264 | const GNUNET_HashCode *key, | ||
265 | void *value) | ||
266 | { | 259 | { |
267 | struct GNUNET_DHT_Handle *handle = cls; | 260 | struct GNUNET_DHT_Handle *handle = cls; |
268 | struct GNUNET_DHT_RouteHandle *rh = value; | 261 | struct GNUNET_DHT_RouteHandle *rh = value; |
269 | 262 | ||
270 | if (GNUNET_NO == rh->message->in_pending_queue) | 263 | if (GNUNET_NO == rh->message->in_pending_queue) |
271 | { | 264 | { |
272 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, | 265 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, |
273 | handle->pending_tail, | 266 | handle->pending_tail, rh->message); |
274 | rh->message); | 267 | rh->message->in_pending_queue = GNUNET_YES; |
275 | rh->message->in_pending_queue = GNUNET_YES; | 268 | } |
276 | } | ||
277 | return GNUNET_YES; | 269 | return GNUNET_YES; |
278 | } | 270 | } |
279 | 271 | ||
@@ -282,8 +274,7 @@ add_request_to_pending (void *cls, | |||
282 | * Try to send messages from list of messages to send | 274 | * Try to send messages from list of messages to send |
283 | * @param handle DHT_Handle | 275 | * @param handle DHT_Handle |
284 | */ | 276 | */ |
285 | static void | 277 | static void process_pending_messages (struct GNUNET_DHT_Handle *handle); |
286 | process_pending_messages (struct GNUNET_DHT_Handle *handle); | ||
287 | 278 | ||
288 | 279 | ||
289 | /** | 280 | /** |
@@ -293,8 +284,7 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle); | |||
293 | * @param tc scheduler context | 284 | * @param tc scheduler context |
294 | */ | 285 | */ |
295 | static void | 286 | static void |
296 | try_reconnect (void *cls, | 287 | try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
297 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
298 | { | 288 | { |
299 | struct GNUNET_DHT_Handle *handle = cls; | 289 | struct GNUNET_DHT_Handle *handle = cls; |
300 | 290 | ||
@@ -308,14 +298,12 @@ try_reconnect (void *cls, | |||
308 | handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 298 | handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
309 | handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); | 299 | handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); |
310 | if (handle->client == NULL) | 300 | if (handle->client == NULL) |
311 | { | 301 | { |
312 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "dht reconnect failed(!)\n"); |
313 | "dht reconnect failed(!)\n"); | 303 | return; |
314 | return; | 304 | } |
315 | } | ||
316 | GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, | 305 | GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, |
317 | &add_request_to_pending, | 306 | &add_request_to_pending, handle); |
318 | handle); | ||
319 | process_pending_messages (handle); | 307 | process_pending_messages (handle); |
320 | } | 308 | } |
321 | 309 | ||
@@ -330,7 +318,7 @@ do_disconnect (struct GNUNET_DHT_Handle *handle) | |||
330 | { | 318 | { |
331 | if (handle->client == NULL) | 319 | if (handle->client == NULL) |
332 | return; | 320 | return; |
333 | GNUNET_assert(handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); | 321 | GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); |
334 | GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); | 322 | GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); |
335 | handle->client = NULL; | 323 | handle->client = NULL; |
336 | handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time, | 324 | handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time, |
@@ -348,25 +336,24 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle) | |||
348 | struct PendingMessage *head; | 336 | struct PendingMessage *head; |
349 | 337 | ||
350 | if (handle->client == NULL) | 338 | if (handle->client == NULL) |
351 | { | 339 | { |
352 | do_disconnect(handle); | 340 | do_disconnect (handle); |
353 | return; | 341 | return; |
354 | } | 342 | } |
355 | if (handle->th != NULL) | 343 | if (handle->th != NULL) |
356 | return; | 344 | return; |
357 | if (NULL == (head = handle->pending_head)) | 345 | if (NULL == (head = handle->pending_head)) |
358 | return; | 346 | return; |
359 | handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, | 347 | handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, |
360 | ntohs (head->msg->size), | 348 | ntohs (head->msg->size), |
361 | GNUNET_TIME_UNIT_FOREVER_REL, | 349 | GNUNET_TIME_UNIT_FOREVER_REL, |
362 | GNUNET_YES, | 350 | GNUNET_YES, |
363 | &transmit_pending, | 351 | &transmit_pending, handle); |
364 | handle); | 352 | if (NULL == handle->th) |
365 | if (NULL == handle->th) | 353 | { |
366 | { | 354 | do_disconnect (handle); |
367 | do_disconnect (handle); | 355 | return; |
368 | return; | 356 | } |
369 | } | ||
370 | } | 357 | } |
371 | 358 | ||
372 | 359 | ||
@@ -374,9 +361,7 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle) | |||
374 | * Transmit the next pending message, called by notify_transmit_ready | 361 | * Transmit the next pending message, called by notify_transmit_ready |
375 | */ | 362 | */ |
376 | static size_t | 363 | static size_t |
377 | transmit_pending (void *cls, | 364 | transmit_pending (void *cls, size_t size, void *buf) |
378 | size_t size, | ||
379 | void *buf) | ||
380 | { | 365 | { |
381 | struct GNUNET_DHT_Handle *handle = cls; | 366 | struct GNUNET_DHT_Handle *handle = cls; |
382 | struct PendingMessage *head; | 367 | struct PendingMessage *head; |
@@ -384,44 +369,44 @@ transmit_pending (void *cls, | |||
384 | 369 | ||
385 | handle->th = NULL; | 370 | handle->th = NULL; |
386 | if (buf == NULL) | 371 | if (buf == NULL) |
387 | { | 372 | { |
388 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Transmission to DHT service failed! Reconnecting!\n"); | 373 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
389 | do_disconnect (handle); | 374 | "Transmission to DHT service failed! Reconnecting!\n"); |
390 | return 0; | 375 | do_disconnect (handle); |
391 | } | 376 | return 0; |
377 | } | ||
392 | if (NULL == (head = handle->pending_head)) | 378 | if (NULL == (head = handle->pending_head)) |
393 | return 0; | 379 | return 0; |
394 | 380 | ||
395 | tsize = ntohs (head->msg->size); | 381 | tsize = ntohs (head->msg->size); |
396 | if (size < tsize) | 382 | if (size < tsize) |
397 | { | 383 | { |
398 | process_pending_messages (handle); | 384 | process_pending_messages (handle); |
399 | return 0; | 385 | return 0; |
400 | } | 386 | } |
401 | memcpy (buf, head->msg, tsize); | 387 | memcpy (buf, head->msg, tsize); |
402 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, | 388 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, |
403 | handle->pending_tail, | 389 | handle->pending_tail, head); |
404 | head); | ||
405 | if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) | 390 | if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) |
406 | { | 391 | { |
407 | GNUNET_SCHEDULER_cancel (head->timeout_task); | 392 | GNUNET_SCHEDULER_cancel (head->timeout_task); |
408 | head->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 393 | head->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
409 | } | 394 | } |
410 | if (NULL != head->cont) | 395 | if (NULL != head->cont) |
411 | { | 396 | { |
412 | GNUNET_SCHEDULER_add_continuation (head->cont, | 397 | GNUNET_SCHEDULER_add_continuation (head->cont, |
413 | head->cont_cls, | 398 | head->cont_cls, |
414 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 399 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
415 | head->cont = NULL; | 400 | head->cont = NULL; |
416 | head->cont_cls = NULL; | 401 | head->cont_cls = NULL; |
417 | } | 402 | } |
418 | head->in_pending_queue = GNUNET_NO; | 403 | head->in_pending_queue = GNUNET_NO; |
419 | if (GNUNET_YES == head->free_on_send) | 404 | if (GNUNET_YES == head->free_on_send) |
420 | GNUNET_free (head); | 405 | GNUNET_free (head); |
421 | process_pending_messages (handle); | 406 | process_pending_messages (handle); |
422 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 407 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
423 | "Forwarded request of %u bytes to DHT service\n", | 408 | "Forwarded request of %u bytes to DHT service\n", |
424 | (unsigned int) tsize); | 409 | (unsigned int) tsize); |
425 | return tsize; | 410 | return tsize; |
426 | } | 411 | } |
427 | 412 | ||
@@ -431,9 +416,7 @@ transmit_pending (void *cls, | |||
431 | * request. | 416 | * request. |
432 | */ | 417 | */ |
433 | static int | 418 | static int |
434 | process_reply (void *cls, | 419 | process_reply (void *cls, const GNUNET_HashCode * key, void *value) |
435 | const GNUNET_HashCode *key, | ||
436 | void *value) | ||
437 | { | 420 | { |
438 | const struct GNUNET_DHT_RouteResultMessage *dht_msg = cls; | 421 | const struct GNUNET_DHT_RouteResultMessage *dht_msg = cls; |
439 | struct GNUNET_DHT_RouteHandle *rh = value; | 422 | struct GNUNET_DHT_RouteHandle *rh = value; |
@@ -448,47 +431,46 @@ process_reply (void *cls, | |||
448 | 431 | ||
449 | uid = GNUNET_ntohll (dht_msg->unique_id); | 432 | uid = GNUNET_ntohll (dht_msg->unique_id); |
450 | if (uid != rh->uid) | 433 | if (uid != rh->uid) |
451 | { | 434 | { |
452 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
453 | "Reply UID did not match request UID\n"); | 436 | "Reply UID did not match request UID\n"); |
454 | return GNUNET_YES; | 437 | return GNUNET_YES; |
455 | } | 438 | } |
456 | enc_msg = (const struct GNUNET_MessageHeader *)&dht_msg[1]; | 439 | enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1]; |
457 | enc_size = ntohs (enc_msg->size); | 440 | enc_size = ntohs (enc_msg->size); |
458 | if (enc_size < sizeof (struct GNUNET_MessageHeader)) | 441 | if (enc_size < sizeof (struct GNUNET_MessageHeader)) |
459 | { | 442 | { |
460 | GNUNET_break (0); | 443 | GNUNET_break (0); |
461 | return GNUNET_NO; | 444 | return GNUNET_NO; |
462 | } | 445 | } |
463 | path_offset = (char *)&dht_msg[1]; | 446 | path_offset = (char *) &dht_msg[1]; |
464 | path_offset += enc_size; | 447 | path_offset += enc_size; |
465 | pos = (const struct GNUNET_PeerIdentity *) path_offset; | 448 | pos = (const struct GNUNET_PeerIdentity *) path_offset; |
466 | outgoing_path_length = ntohl (dht_msg->outgoing_path_length); | 449 | outgoing_path_length = ntohl (dht_msg->outgoing_path_length); |
467 | if (outgoing_path_length * sizeof (struct GNUNET_PeerIdentity) > ntohs(dht_msg->header.size) - enc_size) | 450 | if (outgoing_path_length * sizeof (struct GNUNET_PeerIdentity) > |
468 | { | 451 | ntohs (dht_msg->header.size) - enc_size) |
469 | GNUNET_break (0); | 452 | { |
470 | return GNUNET_NO; | 453 | GNUNET_break (0); |
471 | } | 454 | return GNUNET_NO; |
455 | } | ||
472 | 456 | ||
473 | if (outgoing_path_length > 0) | 457 | if (outgoing_path_length > 0) |
458 | { | ||
459 | outgoing_path = | ||
460 | GNUNET_malloc ((outgoing_path_length + | ||
461 | 1) * sizeof (struct GNUNET_PeerIdentity *)); | ||
462 | for (i = 0; i < outgoing_path_length; i++) | ||
474 | { | 463 | { |
475 | outgoing_path = GNUNET_malloc ((outgoing_path_length + 1) * sizeof (struct GNUNET_PeerIdentity*)); | 464 | outgoing_path[i] = pos; |
476 | for (i = 0; i < outgoing_path_length; i++) | 465 | pos++; |
477 | { | ||
478 | outgoing_path[i] = pos; | ||
479 | pos++; | ||
480 | } | ||
481 | outgoing_path[outgoing_path_length] = NULL; | ||
482 | } | 466 | } |
467 | outgoing_path[outgoing_path_length] = NULL; | ||
468 | } | ||
483 | else | 469 | else |
484 | outgoing_path = NULL; | 470 | outgoing_path = NULL; |
485 | 471 | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 472 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing reply.\n"); |
487 | "Processing reply.\n"); | 473 | rh->iter (rh->iter_cls, &rh->key, outgoing_path, enc_msg); |
488 | rh->iter (rh->iter_cls, | ||
489 | &rh->key, | ||
490 | outgoing_path, | ||
491 | enc_msg); | ||
492 | GNUNET_free_non_null (outgoing_path); | 474 | GNUNET_free_non_null (outgoing_path); |
493 | return GNUNET_YES; | 475 | return GNUNET_YES; |
494 | } | 476 | } |
@@ -502,42 +484,40 @@ process_reply (void *cls, | |||
502 | * @param msg the incoming message | 484 | * @param msg the incoming message |
503 | */ | 485 | */ |
504 | static void | 486 | static void |
505 | service_message_handler (void *cls, | 487 | service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) |
506 | const struct GNUNET_MessageHeader *msg) | ||
507 | { | 488 | { |
508 | struct GNUNET_DHT_Handle *handle = cls; | 489 | struct GNUNET_DHT_Handle *handle = cls; |
509 | const struct GNUNET_DHT_RouteResultMessage *dht_msg; | 490 | const struct GNUNET_DHT_RouteResultMessage *dht_msg; |
510 | 491 | ||
511 | if (msg == NULL) | 492 | if (msg == NULL) |
512 | { | 493 | { |
513 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
514 | "Error receiving data from DHT service, reconnecting\n"); | 495 | "Error receiving data from DHT service, reconnecting\n"); |
515 | do_disconnect (handle); | 496 | do_disconnect (handle); |
516 | return; | 497 | return; |
517 | } | 498 | } |
518 | if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT) | 499 | if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT) |
519 | { | 500 | { |
520 | GNUNET_break (0); | 501 | GNUNET_break (0); |
521 | do_disconnect (handle); | 502 | do_disconnect (handle); |
522 | return; | 503 | return; |
523 | } | 504 | } |
524 | if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_RouteResultMessage)) | 505 | if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_RouteResultMessage)) |
525 | { | 506 | { |
526 | GNUNET_break (0); | 507 | GNUNET_break (0); |
527 | do_disconnect (handle); | 508 | do_disconnect (handle); |
528 | return; | 509 | return; |
529 | } | 510 | } |
530 | dht_msg = (const struct GNUNET_DHT_RouteResultMessage *) msg; | 511 | dht_msg = (const struct GNUNET_DHT_RouteResultMessage *) msg; |
531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 512 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
532 | "Comparing reply `%s' against %u pending requests.\n", | 513 | "Comparing reply `%s' against %u pending requests.\n", |
533 | GNUNET_h2s (&dht_msg->key), | 514 | GNUNET_h2s (&dht_msg->key), |
534 | GNUNET_CONTAINER_multihashmap_size (handle->active_requests)); | 515 | GNUNET_CONTAINER_multihashmap_size (handle->active_requests)); |
535 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, | 516 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, |
536 | &dht_msg->key, | 517 | &dht_msg->key, |
537 | &process_reply, | 518 | &process_reply, (void *) dht_msg); |
538 | (void*) dht_msg); | ||
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 519 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
540 | "Continuing to process replies from DHT\n"); | 520 | "Continuing to process replies from DHT\n"); |
541 | GNUNET_CLIENT_receive (handle->client, | 521 | GNUNET_CLIENT_receive (handle->client, |
542 | &service_message_handler, | 522 | &service_message_handler, |
543 | handle, GNUNET_TIME_UNIT_FOREVER_REL); | 523 | handle, GNUNET_TIME_UNIT_FOREVER_REL); |
@@ -562,13 +542,14 @@ GNUNET_DHT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
562 | 542 | ||
563 | handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_Handle)); | 543 | handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_Handle)); |
564 | handle->cfg = cfg; | 544 | handle->cfg = cfg; |
565 | handle->uid_gen = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | 545 | handle->uid_gen = |
546 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | ||
566 | handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); | 547 | handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); |
567 | if (GNUNET_NO == try_connect (handle)) | 548 | if (GNUNET_NO == try_connect (handle)) |
568 | { | 549 | { |
569 | GNUNET_DHT_disconnect (handle); | 550 | GNUNET_DHT_disconnect (handle); |
570 | return NULL; | 551 | return NULL; |
571 | } | 552 | } |
572 | return handle; | 553 | return handle; |
573 | } | 554 | } |
574 | 555 | ||
@@ -582,36 +563,37 @@ void | |||
582 | GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) | 563 | GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) |
583 | { | 564 | { |
584 | struct PendingMessage *pm; | 565 | struct PendingMessage *pm; |
585 | GNUNET_assert(handle != NULL); | 566 | |
586 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size(handle->active_requests)); | 567 | GNUNET_assert (handle != NULL); |
568 | GNUNET_assert (0 == | ||
569 | GNUNET_CONTAINER_multihashmap_size (handle->active_requests)); | ||
587 | if (handle->th != NULL) | 570 | if (handle->th != NULL) |
588 | { | 571 | { |
589 | GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); | 572 | GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); |
590 | handle->th = NULL; | 573 | handle->th = NULL; |
591 | } | 574 | } |
592 | while (NULL != (pm = handle->pending_head)) | 575 | while (NULL != (pm = handle->pending_head)) |
593 | { | 576 | { |
594 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, | 577 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, |
595 | handle->pending_tail, | 578 | handle->pending_tail, pm); |
596 | pm); | 579 | GNUNET_assert (GNUNET_YES == pm->free_on_send); |
597 | GNUNET_assert (GNUNET_YES == pm->free_on_send); | 580 | if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) |
598 | if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) | 581 | GNUNET_SCHEDULER_cancel (pm->timeout_task); |
599 | GNUNET_SCHEDULER_cancel (pm->timeout_task); | 582 | if (NULL != pm->cont) |
600 | if (NULL != pm->cont) | 583 | GNUNET_SCHEDULER_add_continuation (pm->cont, |
601 | GNUNET_SCHEDULER_add_continuation (pm->cont, | 584 | pm->cont_cls, |
602 | pm->cont_cls, | 585 | GNUNET_SCHEDULER_REASON_TIMEOUT); |
603 | GNUNET_SCHEDULER_REASON_TIMEOUT); | 586 | pm->in_pending_queue = GNUNET_NO; |
604 | pm->in_pending_queue = GNUNET_NO; | 587 | GNUNET_free (pm); |
605 | GNUNET_free (pm); | 588 | } |
606 | } | ||
607 | if (handle->client != NULL) | 589 | if (handle->client != NULL) |
608 | { | 590 | { |
609 | GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES); | 591 | GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES); |
610 | handle->client = NULL; | 592 | handle->client = NULL; |
611 | } | 593 | } |
612 | if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) | 594 | if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) |
613 | GNUNET_SCHEDULER_cancel(handle->reconnect_task); | 595 | GNUNET_SCHEDULER_cancel (handle->reconnect_task); |
614 | GNUNET_CONTAINER_multihashmap_destroy(handle->active_requests); | 596 | GNUNET_CONTAINER_multihashmap_destroy (handle->active_requests); |
615 | GNUNET_free (handle); | 597 | GNUNET_free (handle); |
616 | } | 598 | } |
617 | 599 | ||
@@ -628,25 +610,22 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) | |||
628 | * @param tc scheduler context | 610 | * @param tc scheduler context |
629 | */ | 611 | */ |
630 | static void | 612 | static void |
631 | timeout_route_request (void *cls, | 613 | timeout_route_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
632 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
633 | { | 614 | { |
634 | struct PendingMessage *pending = cls; | 615 | struct PendingMessage *pending = cls; |
635 | struct GNUNET_DHT_Handle *handle; | 616 | struct GNUNET_DHT_Handle *handle; |
636 | 617 | ||
637 | if (pending->free_on_send != GNUNET_YES) | 618 | if (pending->free_on_send != GNUNET_YES) |
638 | { | 619 | { |
639 | /* timeouts should only apply to fire & forget requests! */ | 620 | /* timeouts should only apply to fire & forget requests! */ |
640 | GNUNET_break (0); | 621 | GNUNET_break (0); |
641 | return; | 622 | return; |
642 | } | 623 | } |
643 | handle = pending->handle; | 624 | handle = pending->handle; |
644 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, | 625 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, |
645 | handle->pending_tail, | 626 | handle->pending_tail, pending); |
646 | pending); | ||
647 | if (pending->cont != NULL) | 627 | if (pending->cont != NULL) |
648 | pending->cont (pending->cont_cls, | 628 | pending->cont (pending->cont_cls, tc); |
649 | tc); | ||
650 | GNUNET_free (pending); | 629 | GNUNET_free (pending); |
651 | } | 630 | } |
652 | 631 | ||
@@ -674,15 +653,14 @@ timeout_route_request (void *cls, | |||
674 | */ | 653 | */ |
675 | struct GNUNET_DHT_RouteHandle * | 654 | struct GNUNET_DHT_RouteHandle * |
676 | GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | 655 | GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, |
677 | const GNUNET_HashCode *key, | 656 | const GNUNET_HashCode * key, |
678 | uint32_t desired_replication_level, | 657 | uint32_t desired_replication_level, |
679 | enum GNUNET_DHT_RouteOption options, | 658 | enum GNUNET_DHT_RouteOption options, |
680 | const struct GNUNET_MessageHeader *enc, | 659 | const struct GNUNET_MessageHeader *enc, |
681 | struct GNUNET_TIME_Relative timeout, | 660 | struct GNUNET_TIME_Relative timeout, |
682 | GNUNET_DHT_ReplyProcessor iter, | 661 | GNUNET_DHT_ReplyProcessor iter, |
683 | void *iter_cls, | 662 | void *iter_cls, |
684 | GNUNET_SCHEDULER_Task cont, | 663 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
685 | void *cont_cls) | ||
686 | { | 664 | { |
687 | struct PendingMessage *pending; | 665 | struct PendingMessage *pending; |
688 | struct GNUNET_DHT_RouteMessage *message; | 666 | struct GNUNET_DHT_RouteMessage *message; |
@@ -691,19 +669,20 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
691 | uint16_t esize; | 669 | uint16_t esize; |
692 | 670 | ||
693 | esize = ntohs (enc->size); | 671 | esize = ntohs (enc->size); |
694 | if (sizeof (struct GNUNET_DHT_RouteMessage) + esize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 672 | if (sizeof (struct GNUNET_DHT_RouteMessage) + esize >= |
695 | { | 673 | GNUNET_SERVER_MAX_MESSAGE_SIZE) |
696 | GNUNET_break (0); | 674 | { |
697 | return NULL; | 675 | GNUNET_break (0); |
698 | } | 676 | return NULL; |
677 | } | ||
699 | msize = sizeof (struct GNUNET_DHT_RouteMessage) + esize; | 678 | msize = sizeof (struct GNUNET_DHT_RouteMessage) + esize; |
700 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 679 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); |
701 | message = (struct GNUNET_DHT_RouteMessage*) &pending[1]; | 680 | message = (struct GNUNET_DHT_RouteMessage *) &pending[1]; |
702 | pending->msg = &message->header; | 681 | pending->msg = &message->header; |
703 | pending->handle = handle; | 682 | pending->handle = handle; |
704 | pending->cont = cont; | 683 | pending->cont = cont; |
705 | pending->cont_cls = cont_cls; | 684 | pending->cont_cls = cont_cls; |
706 | 685 | ||
707 | message->header.size = htons (msize); | 686 | message->header.size = htons (msize); |
708 | message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE); | 687 | message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE); |
709 | message->options = htonl ((uint32_t) options); | 688 | message->options = htonl ((uint32_t) options); |
@@ -715,35 +694,34 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
715 | memcpy (&message[1], enc, esize); | 694 | memcpy (&message[1], enc, esize); |
716 | 695 | ||
717 | if (iter != NULL) | 696 | if (iter != NULL) |
718 | { | 697 | { |
719 | route_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_RouteHandle)); | 698 | route_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_RouteHandle)); |
720 | route_handle->key = *key; | 699 | route_handle->key = *key; |
721 | route_handle->iter = iter; | 700 | route_handle->iter = iter; |
722 | route_handle->iter_cls = iter_cls; | 701 | route_handle->iter_cls = iter_cls; |
723 | route_handle->dht_handle = handle; | 702 | route_handle->dht_handle = handle; |
724 | route_handle->uid = handle->uid_gen; | 703 | route_handle->uid = handle->uid_gen; |
725 | route_handle->message = pending; | 704 | route_handle->message = pending; |
726 | GNUNET_CONTAINER_multihashmap_put (handle->active_requests, | 705 | GNUNET_CONTAINER_multihashmap_put (handle->active_requests, |
727 | key, | 706 | key, |
728 | route_handle, | 707 | route_handle, |
729 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 708 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
730 | } | 709 | } |
731 | else | 710 | else |
732 | { | 711 | { |
733 | route_handle = NULL; | 712 | route_handle = NULL; |
734 | pending->free_on_send = GNUNET_YES; | 713 | pending->free_on_send = GNUNET_YES; |
735 | pending->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, | 714 | pending->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, |
736 | &timeout_route_request, | 715 | &timeout_route_request, |
737 | pending); | 716 | pending); |
738 | } | 717 | } |
739 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, | 718 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, |
740 | handle->pending_tail, | 719 | handle->pending_tail, pending); |
741 | pending); | ||
742 | pending->in_pending_queue = GNUNET_YES; | 720 | pending->in_pending_queue = GNUNET_YES; |
743 | process_pending_messages (handle); | 721 | process_pending_messages (handle); |
744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 722 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
745 | "DHT route start request processed, returning %p\n", | 723 | "DHT route start request processed, returning %p\n", |
746 | route_handle); | 724 | route_handle); |
747 | return route_handle; | 725 | return route_handle; |
748 | } | 726 | } |
749 | 727 | ||
@@ -763,42 +741,38 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) | |||
763 | 741 | ||
764 | handle = route_handle->dht_handle; | 742 | handle = route_handle->dht_handle; |
765 | if (GNUNET_NO == route_handle->message->in_pending_queue) | 743 | if (GNUNET_NO == route_handle->message->in_pending_queue) |
766 | { | 744 | { |
767 | /* need to send stop message */ | 745 | /* need to send stop message */ |
768 | msize = sizeof (struct GNUNET_DHT_StopMessage); | 746 | msize = sizeof (struct GNUNET_DHT_StopMessage); |
769 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + | 747 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); |
770 | msize); | 748 | message = (struct GNUNET_DHT_StopMessage *) &pending[1]; |
771 | message = (struct GNUNET_DHT_StopMessage*) &pending[1]; | 749 | pending->msg = &message->header; |
772 | pending->msg = &message->header; | 750 | message->header.size = htons (msize); |
773 | message->header.size = htons (msize); | 751 | message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_STOP); |
774 | message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_STOP); | 752 | message->reserved = 0; |
775 | message->reserved = 0; | 753 | message->unique_id = GNUNET_htonll (route_handle->uid); |
776 | message->unique_id = GNUNET_htonll (route_handle->uid); | 754 | message->key = route_handle->key; |
777 | message->key = route_handle->key; | 755 | pending->handle = handle; |
778 | pending->handle = handle; | 756 | pending->free_on_send = GNUNET_YES; |
779 | pending->free_on_send = GNUNET_YES; | 757 | pending->in_pending_queue = GNUNET_YES; |
780 | pending->in_pending_queue = GNUNET_YES; | 758 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, |
781 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, | 759 | handle->pending_tail, pending); |
782 | handle->pending_tail, | 760 | process_pending_messages (handle); |
783 | pending); | 761 | } |
784 | process_pending_messages (handle); | ||
785 | } | ||
786 | else | 762 | else |
787 | { | 763 | { |
788 | /* simply remove pending request from message queue before | 764 | /* simply remove pending request from message queue before |
789 | transmission, no need to transmit STOP request! */ | 765 | * transmission, no need to transmit STOP request! */ |
790 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, | 766 | GNUNET_CONTAINER_DLL_remove (handle->pending_head, |
791 | handle->pending_tail, | 767 | handle->pending_tail, route_handle->message); |
792 | route_handle->message); | 768 | } |
793 | } | ||
794 | GNUNET_assert (GNUNET_YES == | 769 | GNUNET_assert (GNUNET_YES == |
795 | GNUNET_CONTAINER_multihashmap_remove (route_handle->dht_handle->active_requests, | 770 | GNUNET_CONTAINER_multihashmap_remove |
796 | &route_handle->key, | 771 | (route_handle->dht_handle->active_requests, &route_handle->key, |
797 | route_handle)); | 772 | route_handle)); |
798 | GNUNET_free(route_handle->message); | 773 | GNUNET_free (route_handle->message); |
799 | GNUNET_free(route_handle); | 774 | GNUNET_free (route_handle); |
800 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 775 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT route stop request processed\n"); |
801 | "DHT route stop request processed\n"); | ||
802 | } | 776 | } |
803 | 777 | ||
804 | 778 | ||
@@ -817,29 +791,27 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) | |||
817 | */ | 791 | */ |
818 | static void | 792 | static void |
819 | send_control_message (struct GNUNET_DHT_Handle *handle, | 793 | send_control_message (struct GNUNET_DHT_Handle *handle, |
820 | uint16_t command, | 794 | uint16_t command, |
821 | uint16_t variable, | 795 | uint16_t variable, |
822 | GNUNET_SCHEDULER_Task cont, | 796 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
823 | void *cont_cls) | ||
824 | { | 797 | { |
825 | struct GNUNET_DHT_ControlMessage *msg; | 798 | struct GNUNET_DHT_ControlMessage *msg; |
826 | struct PendingMessage *pending; | 799 | struct PendingMessage *pending; |
827 | 800 | ||
828 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + | 801 | pending = GNUNET_malloc (sizeof (struct PendingMessage) + |
829 | sizeof(struct GNUNET_DHT_ControlMessage)); | 802 | sizeof (struct GNUNET_DHT_ControlMessage)); |
830 | msg = (struct GNUNET_DHT_ControlMessage*) &pending[1]; | 803 | msg = (struct GNUNET_DHT_ControlMessage *) &pending[1]; |
831 | pending->msg = &msg->header; | 804 | pending->msg = &msg->header; |
832 | msg->header.size = htons (sizeof(struct GNUNET_DHT_ControlMessage)); | 805 | msg->header.size = htons (sizeof (struct GNUNET_DHT_ControlMessage)); |
833 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CONTROL); | 806 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CONTROL); |
834 | msg->command = htons (command); | 807 | msg->command = htons (command); |
835 | msg->variable = htons (variable); | 808 | msg->variable = htons (variable); |
836 | pending->free_on_send = GNUNET_YES; | 809 | pending->free_on_send = GNUNET_YES; |
837 | pending->cont = cont; | 810 | pending->cont = cont; |
838 | pending->cont_cls = cont_cls; | 811 | pending->cont_cls = cont_cls; |
839 | pending->in_pending_queue = GNUNET_YES; | 812 | pending->in_pending_queue = GNUNET_YES; |
840 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, | 813 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, |
841 | handle->pending_tail, | 814 | handle->pending_tail, pending); |
842 | pending); | ||
843 | process_pending_messages (handle); | 815 | process_pending_messages (handle); |
844 | } | 816 | } |
845 | 817 | ||
@@ -857,12 +829,10 @@ send_control_message (struct GNUNET_DHT_Handle *handle, | |||
857 | */ | 829 | */ |
858 | void | 830 | void |
859 | GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle, | 831 | GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle, |
860 | GNUNET_SCHEDULER_Task cont, | 832 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
861 | void *cont_cls) | ||
862 | { | 833 | { |
863 | send_control_message (handle, | 834 | send_control_message (handle, |
864 | GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0, | 835 | GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0, cont, cont_cls); |
865 | cont, cont_cls); | ||
866 | } | 836 | } |
867 | 837 | ||
868 | 838 | ||
@@ -880,17 +850,17 @@ GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle, | |||
880 | */ | 850 | */ |
881 | void | 851 | void |
882 | GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle, | 852 | GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle, |
883 | struct GNUNET_TIME_Relative frequency, GNUNET_SCHEDULER_Task cont, | 853 | struct GNUNET_TIME_Relative frequency, |
884 | void *cont_cls) | 854 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
885 | { | 855 | { |
886 | if (frequency.rel_value > UINT16_MAX) | 856 | if (frequency.rel_value > UINT16_MAX) |
887 | { | 857 | { |
888 | GNUNET_break (0); | 858 | GNUNET_break (0); |
889 | return; | 859 | return; |
890 | } | 860 | } |
891 | send_control_message (handle, | 861 | send_control_message (handle, |
892 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET, frequency.rel_value, | 862 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET, |
893 | cont, cont_cls); | 863 | frequency.rel_value, cont, cont_cls); |
894 | } | 864 | } |
895 | 865 | ||
896 | /** | 866 | /** |
@@ -902,20 +872,20 @@ GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle, | |||
902 | * @param cont continuation to call when done (transmitting request to service) | 872 | * @param cont continuation to call when done (transmitting request to service) |
903 | * @param cont_cls closure for cont | 873 | * @param cont_cls closure for cont |
904 | */ | 874 | */ |
905 | void | 875 | void |
906 | GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle, | 876 | GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle, |
907 | struct GNUNET_TIME_Relative frequency, GNUNET_SCHEDULER_Task cont, | 877 | struct GNUNET_TIME_Relative frequency, |
908 | void *cont_cls) | 878 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
909 | { | 879 | { |
910 | if (frequency.rel_value > UINT16_MAX) | 880 | if (frequency.rel_value > UINT16_MAX) |
911 | { | 881 | { |
912 | GNUNET_break (0); | 882 | GNUNET_break (0); |
913 | return; | 883 | return; |
914 | } | 884 | } |
915 | 885 | ||
916 | send_control_message (handle, | 886 | send_control_message (handle, |
917 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT, frequency.rel_value, | 887 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT, |
918 | cont, cont_cls); | 888 | frequency.rel_value, cont, cont_cls); |
919 | } | 889 | } |
920 | 890 | ||
921 | 891 | ||
@@ -928,9 +898,9 @@ GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle, | |||
928 | * @param cont_cls closure for cont | 898 | * @param cont_cls closure for cont |
929 | * | 899 | * |
930 | */ | 900 | */ |
931 | void | 901 | void |
932 | GNUNET_DHT_set_malicious_dropper (struct GNUNET_DHT_Handle *handle, GNUNET_SCHEDULER_Task cont, | 902 | GNUNET_DHT_set_malicious_dropper (struct GNUNET_DHT_Handle *handle, |
933 | void *cont_cls) | 903 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
934 | { | 904 | { |
935 | send_control_message (handle, | 905 | send_control_message (handle, |
936 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP, 0, | 906 | GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP, 0, |