aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c373
1 files changed, 210 insertions, 163 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c
index 11fd29657..fe344fcbf 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -225,19 +225,18 @@ struct CadetPeer
225/** 225/**
226 * Get the static string for a peer ID. 226 * Get the static string for a peer ID.
227 * 227 *
228 * @param peer Peer. 228 * @param cp Peer.
229 *
230 * @return Static string for it's ID. 229 * @return Static string for it's ID.
231 */ 230 */
232const char * 231const char *
233GCP_2s (const struct CadetPeer *peer) 232GCP_2s (const struct CadetPeer *cp)
234{ 233{
235 static char buf[64]; 234 static char buf[32];
236 235
237 GNUNET_snprintf (buf, 236 GNUNET_snprintf (buf,
238 sizeof (buf), 237 sizeof (buf),
239 "P(%s)", 238 "P(%s)",
240 GNUNET_i2s (&peer->pid)); 239 GNUNET_i2s (&cp->pid));
241 return buf; 240 return buf;
242} 241}
243 242
@@ -297,6 +296,146 @@ destroy_peer (void *cls)
297 296
298 297
299/** 298/**
299 * This peer is now on more "active" duty, activate processes related to it.
300 *
301 * @param cp the more-active peer
302 */
303static void
304consider_peer_activate (struct CadetPeer *cp)
305{
306 uint32_t strength;
307
308 LOG (GNUNET_ERROR_TYPE_DEBUG,
309 "Updating peer %s activation state (%u connections)%s%s\n",
310 GCP_2s (cp),
311 GNUNET_CONTAINER_multishortmap_size (cp->connections),
312 (NULL == cp->t) ? "" : " with tunnel",
313 (NULL == cp->core_mq) ? "" : " with CORE link");
314 if (NULL != cp->destroy_task)
315 {
316 /* It's active, do not destory! */
317 GNUNET_SCHEDULER_cancel (cp->destroy_task);
318 cp->destroy_task = NULL;
319 }
320 if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
321 (NULL == cp->t) )
322 {
323 /* We're just on a path or directly connected; don't bother too much */
324 if (NULL != cp->connectivity_suggestion)
325 {
326 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
327 cp->connectivity_suggestion = NULL;
328 }
329 if (NULL != cp->search_h)
330 {
331 GCD_search_stop (cp->search_h);
332 cp->search_h = NULL;
333 }
334 return;
335 }
336 if (NULL == cp->core_mq)
337 {
338 /* Lacks direct connection, try to create one by querying the DHT */
339 if ( (NULL == cp->search_h) &&
340 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
341 cp->search_h
342 = GCD_search (&cp->pid);
343 }
344 else
345 {
346 /* Have direct connection, stop DHT search if active */
347 if (NULL != cp->search_h)
348 {
349 GCD_search_stop (cp->search_h);
350 cp->search_h = NULL;
351 }
352 }
353
354 /* If we have a tunnel, our urge for connections is much bigger */
355 strength = (NULL != cp->t) ? 32 : 1;
356 if (NULL != cp->connectivity_suggestion)
357 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
358 cp->connectivity_suggestion
359 = GNUNET_ATS_connectivity_suggest (ats_ch,
360 &cp->pid,
361 strength);
362}
363
364
365/**
366 * This peer may no longer be needed, consider cleaning it up.
367 *
368 * @param cp peer to clean up
369 */
370static void
371consider_peer_destroy (struct CadetPeer *cp);
372
373
374/**
375 * We really no longere care about a peer, stop hogging memory with paths to it.
376 * Afterwards, see if there is more to be cleaned up about this peer.
377 *
378 * @param cls a `struct CadetPeer`.
379 */
380static void
381drop_paths (void *cls)
382{
383 struct CadetPeer *cp = cls;
384 struct CadetPeerPath *path;
385
386 cp->destroy_task = NULL;
387 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
388 GCPP_release (path);
389 consider_peer_destroy (cp);
390}
391
392
393/**
394 * This peer may no longer be needed, consider cleaning it up.
395 *
396 * @param cp peer to clean up
397 */
398static void
399consider_peer_destroy (struct CadetPeer *cp)
400{
401 struct GNUNET_TIME_Relative exp;
402
403 if (NULL != cp->destroy_task)
404 {
405 GNUNET_SCHEDULER_cancel (cp->destroy_task);
406 cp->destroy_task = NULL;
407 }
408 if (NULL != cp->t)
409 return; /* still relevant! */
410 if (NULL != cp->core_mq)
411 return; /* still relevant! */
412 if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
413 return; /* still relevant! */
414 if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap))
415 {
416 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
417 &drop_paths,
418 cp);
419 return;
420 }
421 if (0 < cp->path_dll_length)
422 return; /* still relevant! */
423 if (NULL != cp->hello)
424 {
425 /* relevant only until HELLO expires */
426 exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello));
427 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
428 &destroy_peer,
429 cp);
430 return;
431 }
432 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
433 &destroy_peer,
434 cp);
435}
436
437
438/**
300 * Set the message queue to @a mq for peer @a cp and notify watchers. 439 * Set the message queue to @a mq for peer @a cp and notify watchers.
301 * 440 *
302 * @param cp peer to modify 441 * @param cp peer to modify
@@ -311,7 +450,6 @@ GCP_set_mq (struct CadetPeer *cp,
311 GCP_2s (cp), 450 GCP_2s (cp),
312 mq); 451 mq);
313 cp->core_mq = mq; 452 cp->core_mq = mq;
314
315 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; 453 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head;
316 NULL != mqm; 454 NULL != mqm;
317 mqm = mqm->next) 455 mqm = mqm->next)
@@ -338,6 +476,24 @@ GCP_set_mq (struct CadetPeer *cp,
338 GNUNET_YES); 476 GNUNET_YES);
339 } 477 }
340 } 478 }
479 if ( (NULL != mq) ||
480 (NULL != cp->t) )
481 consider_peer_activate (cp);
482 else
483 consider_peer_destroy (cp);
484
485 if ( (NULL != mq) &&
486 (NULL != cp->t) )
487 {
488 /* have a new, direct path to the target, notify tunnel */
489 struct CadetPeerPath *path;
490
491 path = GCPP_get_path_from_route (1,
492 &cp->pid);
493 GCT_consider_path (cp->t,
494 path,
495 0);
496 }
341} 497}
342 498
343 499
@@ -472,79 +628,6 @@ GCP_destroy_all_peers ()
472 628
473 629
474/** 630/**
475 * This peer may no longer be needed, consider cleaning it up.
476 *
477 * @param cp peer to clean up
478 */
479static void
480consider_peer_destroy (struct CadetPeer *cp);
481
482
483/**
484 * We really no longere care about a peer, stop hogging memory with paths to it.
485 * Afterwards, see if there is more to be cleaned up about this peer.
486 *
487 * @param cls a `struct CadetPeer`.
488 */
489static void
490drop_paths (void *cls)
491{
492 struct CadetPeer *cp = cls;
493 struct CadetPeerPath *path;
494
495 cp->destroy_task = NULL;
496 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
497 GCPP_release (path);
498 consider_peer_destroy (cp);
499}
500
501
502/**
503 * This peer may no longer be needed, consider cleaning it up.
504 *
505 * @param cp peer to clean up
506 */
507static void
508consider_peer_destroy (struct CadetPeer *cp)
509{
510 struct GNUNET_TIME_Relative exp;
511
512 if (NULL != cp->destroy_task)
513 {
514 GNUNET_SCHEDULER_cancel (cp->destroy_task);
515 cp->destroy_task = NULL;
516 }
517 if (NULL != cp->t)
518 return; /* still relevant! */
519 if (NULL != cp->core_mq)
520 return; /* still relevant! */
521 if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
522 return; /* still relevant! */
523 if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap))
524 {
525 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
526 &drop_paths,
527 cp);
528 return;
529 }
530 if (0 < cp->path_dll_length)
531 return; /* still relevant! */
532 if (NULL != cp->hello)
533 {
534 /* relevant only until HELLO expires */
535 exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello));
536 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
537 &destroy_peer,
538 cp);
539 return;
540 }
541 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
542 &destroy_peer,
543 cp);
544}
545
546
547/**
548 * Add an entry to the DLL of all of the paths that this peer is on. 631 * Add an entry to the DLL of all of the paths that this peer is on.
549 * 632 *
550 * @param cp peer to modify 633 * @param cp peer to modify
@@ -583,6 +666,14 @@ GCP_path_entry_add (struct CadetPeer *cp,
583 GCT_consider_path (cp->t, 666 GCT_consider_path (cp->t,
584 entry->path, 667 entry->path,
585 off); 668 off);
669
670 if ( (NULL != cp->search_h) &&
671 (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) )
672 {
673 /* Now I have enough paths, stop search */
674 GCD_search_stop (cp->search_h);
675 cp->search_h = NULL;
676 }
586} 677}
587 678
588 679
@@ -608,6 +699,12 @@ GCP_path_entry_remove (struct CadetPeer *cp,
608 entry); 699 entry);
609 GNUNET_assert (0 < cp->num_paths); 700 GNUNET_assert (0 < cp->num_paths);
610 cp->num_paths--; 701 cp->num_paths--;
702 if ( (NULL == cp->core_mq) &&
703 (NULL != cp->t) &&
704 (NULL == cp->search_h) &&
705 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
706 cp->search_h
707 = GCD_search (&cp->pid);
611} 708}
612 709
613 710
@@ -633,10 +730,10 @@ GCP_attach_path (struct CadetPeer *cp,
633 GNUNET_CONTAINER_HeapCostType root_desirability; 730 GNUNET_CONTAINER_HeapCostType root_desirability;
634 struct GNUNET_CONTAINER_HeapNode *hn; 731 struct GNUNET_CONTAINER_HeapNode *hn;
635 732
733 desirability = GCPP_get_desirability (path);
636 if (GNUNET_NO == force) 734 if (GNUNET_NO == force)
637 { 735 {
638 /* FIXME: desirability is not yet initialized; tricky! */ 736 /* FIXME: desirability is not yet initialized; tricky! */
639 desirability = GCPP_get_desirability (path);
640 if (GNUNET_NO == 737 if (GNUNET_NO ==
641 GNUNET_CONTAINER_heap_peek2 (cp->path_heap, 738 GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
642 (void **) &root, 739 (void **) &root,
@@ -665,7 +762,7 @@ GCP_attach_path (struct CadetPeer *cp,
665 762
666 /* Yes, we'd like to add this path, add to our heap */ 763 /* Yes, we'd like to add this path, add to our heap */
667 hn = GNUNET_CONTAINER_heap_insert (cp->path_heap, 764 hn = GNUNET_CONTAINER_heap_insert (cp->path_heap,
668 (void *) cp, 765 path,
669 desirability); 766 desirability);
670 767
671 /* Consider maybe dropping other paths because of the new one */ 768 /* Consider maybe dropping other paths because of the new one */
@@ -761,73 +858,6 @@ GCP_remove_connection (struct CadetPeer *cp,
761 858
762 859
763/** 860/**
764 * This peer is now on more "active" duty, activate processes related to it.
765 *
766 * @param cp the more-active peer
767 */
768static void
769consider_peer_activate (struct CadetPeer *cp)
770{
771 uint32_t strength;
772
773 LOG (GNUNET_ERROR_TYPE_DEBUG,
774 "Updating peer %s activation state (%u connections)%s%s\n",
775 GCP_2s (cp),
776 GNUNET_CONTAINER_multishortmap_size (cp->connections),
777 (NULL == cp->t) ? "" : " with tunnel",
778 (NULL == cp->core_mq) ? "" : " with CORE link");
779 if (NULL != cp->destroy_task)
780 {
781 /* It's active, do not destory! */
782 GNUNET_SCHEDULER_cancel (cp->destroy_task);
783 cp->destroy_task = NULL;
784 }
785 if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
786 (NULL == cp->t) )
787 {
788 /* We're just on a path or directly connected; don't bother too much */
789 if (NULL != cp->connectivity_suggestion)
790 {
791 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
792 cp->connectivity_suggestion = NULL;
793 }
794 if (NULL != cp->search_h)
795 {
796 GCD_search_stop (cp->search_h);
797 cp->search_h = NULL;
798 }
799 return;
800 }
801 if (NULL == cp->core_mq)
802 {
803 /* Lacks direct connection, try to create one by querying the DHT */
804 if ( (NULL == cp->search_h) &&
805 (DESIRED_CONNECTIONS_PER_TUNNEL < cp->num_paths) )
806 cp->search_h
807 = GCD_search (&cp->pid);
808 }
809 else
810 {
811 /* Have direct connection, stop DHT search if active */
812 if (NULL != cp->search_h)
813 {
814 GCD_search_stop (cp->search_h);
815 cp->search_h = NULL;
816 }
817 }
818
819 /* If we have a tunnel, our urge for connections is much bigger */
820 strength = (NULL != cp->t) ? 32 : 1;
821 if (NULL != cp->connectivity_suggestion)
822 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
823 cp->connectivity_suggestion
824 = GNUNET_ATS_connectivity_suggest (ats_ch,
825 &cp->pid,
826 strength);
827}
828
829
830/**
831 * Retrieve the CadetPeer stucture associated with the 861 * Retrieve the CadetPeer stucture associated with the
832 * peer. Optionally create one and insert it in the appropriate 862 * peer. Optionally create one and insert it in the appropriate
833 * structures if the peer is not known yet. 863 * structures if the peer is not known yet.
@@ -899,43 +929,60 @@ GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
899/** 929/**
900 * Count the number of known paths toward the peer. 930 * Count the number of known paths toward the peer.
901 * 931 *
902 * @param peer Peer to get path info. 932 * @param cp Peer to get path info.
903 * @return Number of known paths. 933 * @return Number of known paths.
904 */ 934 */
905unsigned int 935unsigned int
906GCP_count_paths (const struct CadetPeer *peer) 936GCP_count_paths (const struct CadetPeer *cp)
907{ 937{
908 return peer->num_paths; 938 return cp->num_paths;
909} 939}
910 940
911 941
912/** 942/**
913 * Iterate over the paths to a peer. 943 * Iterate over the paths to a peer.
914 * 944 *
915 * @param peer Peer to get path info. 945 * @param cp Peer to get path info.
916 * @param callback Function to call for every path. 946 * @param callback Function to call for every path.
917 * @param callback_cls Closure for @a callback. 947 * @param callback_cls Closure for @a callback.
918 * @return Number of iterated paths. 948 * @return Number of iterated paths.
919 */ 949 */
920unsigned int 950unsigned int
921GCP_iterate_paths (struct CadetPeer *peer, 951GCP_iterate_paths (struct CadetPeer *cp,
922 GCP_PathIterator callback, 952 GCP_PathIterator callback,
923 void *callback_cls) 953 void *callback_cls)
924{ 954{
925 unsigned int ret = 0; 955 unsigned int ret = 0;
926 956
927 for (unsigned int i=0;i<peer->path_dll_length;i++) 957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
958 "Iterating over paths to peer %s%s\n",
959 GCP_2s (cp),
960 (NULL == cp->core_mq) ? "" : " including direct link");
961 if (NULL != cp->core_mq)
962 {
963 struct CadetPeerPath *path;
964
965 path = GCPP_get_path_from_route (1,
966 &cp->pid);
967 ret++;
968 if (GNUNET_NO ==
969 callback (callback_cls,
970 path,
971 1))
972 return ret;
973 }
974 for (unsigned int i=0;i<cp->path_dll_length;i++)
928 { 975 {
929 for (struct CadetPeerPathEntry *pe = peer->path_heads[i]; 976 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
930 NULL != pe; 977 NULL != pe;
931 pe = pe->next) 978 pe = pe->next)
932 { 979 {
980 ret++;
933 if (GNUNET_NO == 981 if (GNUNET_NO ==
934 callback (callback_cls, 982 callback (callback_cls,
935 pe->path, 983 pe->path,
936 i)) 984 i))
937 return ret; 985 return ret;
938 ret++;
939 } 986 }
940 } 987 }
941 return ret; 988 return ret;
@@ -943,26 +990,26 @@ GCP_iterate_paths (struct CadetPeer *peer,
943 990
944 991
945/** 992/**
946 * Iterate over the paths to @a peer where 993 * Iterate over the paths to @a cp where
947 * @a peer is at distance @a dist from us. 994 * @a cp is at distance @a dist from us.
948 * 995 *
949 * @param peer Peer to get path info. 996 * @param cp Peer to get path info.
950 * @param dist desired distance of @a peer to us on the path 997 * @param dist desired distance of @a cp to us on the path
951 * @param callback Function to call for every path. 998 * @param callback Function to call for every path.
952 * @param callback_cls Closure for @a callback. 999 * @param callback_cls Closure for @a callback.
953 * @return Number of iterated paths. 1000 * @return Number of iterated paths.
954 */ 1001 */
955unsigned int 1002unsigned int
956GCP_iterate_paths_at (struct CadetPeer *peer, 1003GCP_iterate_paths_at (struct CadetPeer *cp,
957 unsigned int dist, 1004 unsigned int dist,
958 GCP_PathIterator callback, 1005 GCP_PathIterator callback,
959 void *callback_cls) 1006 void *callback_cls)
960{ 1007{
961 unsigned int ret = 0; 1008 unsigned int ret = 0;
962 1009
963 if (dist<peer->path_dll_length) 1010 if (dist <= cp->path_dll_length)
964 return 0; 1011 return 0;
965 for (struct CadetPeerPathEntry *pe = peer->path_heads[dist]; 1012 for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
966 NULL != pe; 1013 NULL != pe;
967 pe = pe->next) 1014 pe = pe->next)
968 { 1015 {