aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-02-26 20:26:31 +0100
committerChristian Grothoff <christian@grothoff.org>2017-02-26 20:26:40 +0100
commitfc44a16d5a5761fcc14c1de29daa3451be251edd (patch)
tree1b62e0fad489b08d06786c3a20f30ae518343a8f /src
parenta5ed93ab801ed92f77d1dffd566dff56ac3d6e2e (diff)
downloadgnunet-fc44a16d5a5761fcc14c1de29daa3451be251edd.tar.gz
gnunet-fc44a16d5a5761fcc14c1de29daa3451be251edd.zip
move path destruction to separate task to avoid deep-recursion free-while-in-use issue
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c
index 7b944afd8..350c8efae 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -157,9 +157,9 @@ struct CadetPeer
157 struct GCD_search_handle *search_h; 157 struct GCD_search_handle *search_h;
158 158
159 /** 159 /**
160 * Task to stop the DHT search for paths to this peer 160 * Task to clean up @e path_heap asynchronously.
161 */ 161 */
162 struct GNUNET_SCHEDULER_Task *search_delayedXXX; 162 struct GNUNET_SCHEDULER_Task *heap_cleanup_task;
163 163
164 /** 164 /**
165 * Task to destroy this entry. 165 * Task to destroy this entry.
@@ -361,6 +361,11 @@ destroy_peer (void *cls)
361 GNUNET_CONTAINER_heap_destroy (cp->path_heap); 361 GNUNET_CONTAINER_heap_destroy (cp->path_heap);
362 cp->path_heap = NULL; 362 cp->path_heap = NULL;
363 } 363 }
364 if (NULL != cp->heap_cleanup_task)
365 {
366 GNUNET_SCHEDULER_cancel (cp->heap_cleanup_task);
367 cp->heap_cleanup_task = NULL;
368 }
364 GNUNET_free_non_null (cp->hello); 369 GNUNET_free_non_null (cp->hello);
365 /* Peer should not be freed if paths exist; if there are no paths, 370 /* Peer should not be freed if paths exist; if there are no paths,
366 there ought to be no connections, and without connections, no 371 there ought to be no connections, and without connections, no
@@ -892,6 +897,41 @@ GCP_path_entry_remove (struct CadetPeer *cp,
892 897
893 898
894/** 899/**
900 * Prune down the number of paths to this peer, we seem to
901 * have way too many.
902 *
903 * @param cls the `struct CadetPeer` to maintain the path heap for
904 */
905static void
906path_heap_cleanup (void *cls)
907{
908 struct CadetPeer *cp = cls;
909 struct CadetPeerPath *root;
910
911 cp->heap_cleanup_task = NULL;
912 while (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
913 2 * DESIRED_CONNECTIONS_PER_TUNNEL)
914 {
915 /* Now we have way too many, drop least desirable UNLESS it is in use!
916 (Note that this intentionally keeps highly desireable, but currently
917 unused paths around in the hope that we might be able to switch, even
918 if the number of paths exceeds the threshold.) */
919 root = GNUNET_CONTAINER_heap_peek (cp->path_heap);
920 if (NULL !=
921 GCPP_get_connection (root,
922 cp,
923 GCPP_get_length (root) - 1))
924 break; /* can't fix */
925 /* Got plenty of paths to this destination, and this is a low-quality
926 one that we don't care about. Allow it to die. */
927 GNUNET_assert (root ==
928 GNUNET_CONTAINER_heap_remove_root (cp->path_heap));
929 GCPP_release (root);
930 }
931}
932
933
934/**
895 * Try adding a @a path to this @a peer. If the peer already 935 * Try adding a @a path to this @a peer. If the peer already
896 * has plenty of paths, return NULL. 936 * has plenty of paths, return NULL.
897 * 937 *
@@ -958,27 +998,11 @@ GCP_attach_path (struct CadetPeer *cp,
958 desirability); 998 desirability);
959 999
960 /* Consider maybe dropping other paths because of the new one */ 1000 /* Consider maybe dropping other paths because of the new one */
961 if (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >= 1001 if ( (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
962 2 * DESIRED_CONNECTIONS_PER_TUNNEL) 1002 2 * DESIRED_CONNECTIONS_PER_TUNNEL) &&
963 { 1003 (NULL != cp->heap_cleanup_task) )
964 /* Now we have way too many, drop least desirable UNLESS it is in use! 1004 cp->heap_cleanup_task = GNUNET_SCHEDULER_add_now (&path_heap_cleanup,
965 (Note that this intentionally keeps highly desireable, but currently 1005 cp);
966 unused paths around in the hope that we might be able to switch, even
967 if the number of paths exceeds the threshold.) */
968 root = GNUNET_CONTAINER_heap_peek (cp->path_heap);
969 if ( (path != root) &&
970 (NULL ==
971 GCPP_get_connection (root,
972 cp,
973 GCPP_get_length (root) - 1)) )
974 {
975 /* Got plenty of paths to this destination, and this is a low-quality
976 one that we don't care about. Allow it to die. */
977 GNUNET_assert (root ==
978 GNUNET_CONTAINER_heap_remove_root (cp->path_heap));
979 GCPP_release (root);
980 }
981 }
982 return hn; 1006 return hn;
983} 1007}
984 1008