aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-xdht_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-xdht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c203
1 files changed, 173 insertions, 30 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 758c71e19..0b66c38d5 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -88,6 +88,11 @@
88#define DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 88#define DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
89 89
90/** 90/**
91 * How long to wait before retrying notify successor.
92 */
93#define DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
94
95/**
91 * How long at most to wait for transmission of a request to a friend ? 96 * How long at most to wait for transmission of a request to a friend ?
92 */ 97 */
93#define PENDING_MESSAGE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) 98#define PENDING_MESSAGE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
@@ -865,6 +870,12 @@ static GNUNET_SCHEDULER_TaskIdentifier send_verify_successor_task;
865static GNUNET_SCHEDULER_TaskIdentifier send_verify_successor_retry_task; 870static GNUNET_SCHEDULER_TaskIdentifier send_verify_successor_retry_task;
866 871
867/** 872/**
873 * Task that sends verify successor message. This task is started when we get
874 * our successor for the first time.
875 */
876static GNUNET_SCHEDULER_TaskIdentifier send_notify_new_successor_retry_task;
877
878/**
868 * Identity of this peer. 879 * Identity of this peer.
869 */ 880 */
870static struct GNUNET_PeerIdentity my_identity; 881static struct GNUNET_PeerIdentity my_identity;
@@ -913,10 +924,15 @@ static struct GNUNET_TIME_Relative verify_successor_next_send_time;
913static struct GNUNET_TIME_Relative verify_successor_retry_time; 924static struct GNUNET_TIME_Relative verify_successor_retry_time;
914 925
915/** 926/**
927 * Time duration to retry send_notify_successor.
928 */
929static struct GNUNET_TIME_Relative notify_successor_retry_time;
930
931/**
916 * Are we waiting for confirmation from our new successor that it got the 932 * Are we waiting for confirmation from our new successor that it got the
917 * message 933 * message
918 */ 934 */
919static unsigned int waiting_for_notify_confirmation; 935//static unsigned int waiting_for_notify_confirmation;
920 936
921/* Below variables are used only for testing, and statistics collection. */ 937/* Below variables are used only for testing, and statistics collection. */
922/** 938/**
@@ -3168,6 +3184,9 @@ send_verify_successor_message (void *cls,
3168 unsigned int i = 0; 3184 unsigned int i = 0;
3169 struct FingerInfo *successor; 3185 struct FingerInfo *successor;
3170 3186
3187 /* This task will be scheduled when the result for Verify Successor is received. */
3188 send_verify_successor_task = GNUNET_SCHEDULER_NO_TASK;
3189
3171 /* After one round of verify successor, we do back off. */ 3190 /* After one round of verify successor, we do back off. */
3172 send_verify_successor_retry_task = 3191 send_verify_successor_retry_task =
3173 GNUNET_SCHEDULER_add_delayed (verify_successor_retry_time, 3192 GNUNET_SCHEDULER_add_delayed (verify_successor_retry_time,
@@ -3176,11 +3195,11 @@ send_verify_successor_message (void *cls,
3176 successor = &finger_table[0]; 3195 successor = &finger_table[0];
3177 /* We are waiting for a confirmation from the notify message and we have not 3196 /* We are waiting for a confirmation from the notify message and we have not
3178 * crossed the wait time, then return. */ 3197 * crossed the wait time, then return. */
3179 if ((1 == waiting_for_notify_confirmation) 3198// if ((1 == waiting_for_notify_confirmation)
3180 && (0 != GNUNET_TIME_absolute_get_remaining(successor->wait_notify_confirmation).rel_value_us)) 3199// && (0 != GNUNET_TIME_absolute_get_remaining(successor->wait_notify_confirmation).rel_value_us))
3181 { 3200// {
3182 return; 3201// return;
3183 } 3202// }
3184 /* Among all the trails to reach to successor, select first one which is present.*/ 3203 /* Among all the trails to reach to successor, select first one which is present.*/
3185 for (i = 0; i < successor->trails_count; i++) 3204 for (i = 0; i < successor->trails_count; i++)
3186 { 3205 {
@@ -3483,13 +3502,13 @@ finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3483 remove_existing_finger (existing_finger, finger_table_index); 3502 remove_existing_finger (existing_finger, finger_table_index);
3484 add_new_finger (finger_identity, finger_trail, finger_trail_length, 3503 add_new_finger (finger_identity, finger_trail, finger_trail_length,
3485 finger_trail_id, finger_table_index); 3504 finger_trail_id, finger_table_index);
3486 if ((0 == finger_table_index) && (1 == waiting_for_notify_confirmation)) 3505// if ((0 == finger_table_index) && (1 == waiting_for_notify_confirmation))
3487 { 3506// {
3488 /* SUPUS: We have removed our successor, but we are still waiting for a 3507// /* SUPUS: We have removed our successor, but we are still waiting for a
3489 * confirmation. As we have removed successor, then it does not make 3508// * confirmation. As we have removed successor, then it does not make
3490 sense to wait for the new successor. */ 3509// sense to wait for the new successor. */
3491 waiting_for_notify_confirmation = 0; 3510// waiting_for_notify_confirmation = 0;
3492 } 3511// }
3493 } 3512 }
3494 else 3513 else
3495 { 3514 {
@@ -4942,6 +4961,21 @@ check_trail_me_to_probable_succ (struct GNUNET_PeerIdentity probable_successor,
4942 return (struct GNUNET_PeerIdentity*)trail_me_to_probable_successor; 4961 return (struct GNUNET_PeerIdentity*)trail_me_to_probable_successor;
4943} 4962}
4944 4963
4964// TODO: Move up
4965struct SendNotifyContext
4966{
4967 struct GNUNET_PeerIdentity source_peer;
4968 struct GNUNET_PeerIdentity successor;
4969 struct GNUNET_PeerIdentity *successor_trail;
4970 unsigned int successor_trail_length;
4971 struct GNUNET_HashCode succesor_trail_id;
4972 struct FriendInfo *target_friend;
4973};
4974
4975void
4976send_notify_new_successor (void *cls,
4977 const struct GNUNET_SCHEDULER_TaskContext
4978 * tc);
4945 4979
4946/** 4980/**
4947 * Check if the peer which sent us verify successor result message is still ours 4981 * Check if the peer which sent us verify successor result message is still ours
@@ -4979,8 +5013,28 @@ compare_and_update_successor (struct GNUNET_PeerIdentity curr_succ,
4979 /* If probable successor is same as current_successor, do nothing. */ 5013 /* If probable successor is same as current_successor, do nothing. */
4980 if(0 == GNUNET_CRYPTO_cmp_peer_identity (&probable_successor, 5014 if(0 == GNUNET_CRYPTO_cmp_peer_identity (&probable_successor,
4981 &current_successor->finger_identity)) 5015 &current_successor->finger_identity))
5016 {
5017 if ((NULL != GDS_stats))
5018 {
5019 char *my_id_str;
5020 uint64_t succ;
5021 char *key;
5022
5023 my_id_str = GNUNET_strdup (GNUNET_i2s_full (&my_identity));
5024 memcpy(&succ, &current_successor->finger_identity, sizeof(uint64_t));
5025 GNUNET_asprintf (&key, "XDHT:%s:", my_id_str);
5026 GNUNET_free (my_id_str);
5027 GNUNET_STATISTICS_set (GDS_stats, key, succ, 0);
5028 GNUNET_free (key);
5029 }
5030 // TODO: Schedule verify_successor
5031 if (send_verify_successor_task == GNUNET_SCHEDULER_NO_TASK)
5032 send_verify_successor_task =
5033 GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time,
5034 &send_verify_successor_message,
5035 NULL);
4982 return; 5036 return;
4983 5037 }
4984 closest_peer = select_closest_peer (&probable_successor, 5038 closest_peer = select_closest_peer (&probable_successor,
4985 &current_successor->finger_identity, 5039 &current_successor->finger_identity,
4986 successor_value, is_predecessor); 5040 successor_value, is_predecessor);
@@ -5003,6 +5057,12 @@ compare_and_update_successor (struct GNUNET_PeerIdentity curr_succ,
5003 GNUNET_STATISTICS_set (GDS_stats, key, succ, 0); 5057 GNUNET_STATISTICS_set (GDS_stats, key, succ, 0);
5004 GNUNET_free (key); 5058 GNUNET_free (key);
5005 } 5059 }
5060 // TODO: Schedule verify_successor
5061 if (send_verify_successor_task == GNUNET_SCHEDULER_NO_TASK)
5062 send_verify_successor_task =
5063 GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time,
5064 &send_verify_successor_message,
5065 NULL);
5006 return; 5066 return;
5007 } 5067 }
5008 5068
@@ -5051,20 +5111,70 @@ compare_and_update_successor (struct GNUNET_PeerIdentity curr_succ,
5051 trail_me_to_probable_succ_len, trail_id, 0); 5111 trail_me_to_probable_succ_len, trail_id, 0);
5052 /* SUPUS We are sending notify message, but before sending the next request 5112 /* SUPUS We are sending notify message, but before sending the next request
5053 we should wait for confirmation. */ 5113 we should wait for confirmation. */
5054 waiting_for_notify_confirmation = 1; 5114 // TODO : remove the following commented part
5055 current_successor = &finger_table[0]; 5115// waiting_for_notify_confirmation = 1;
5056 current_successor->wait_notify_confirmation = 5116// current_successor = &finger_table[0];
5057 GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), 5117// current_successor->wait_notify_confirmation =
5058 WAIT_NOTIFY_CONFIRMATION); 5118// GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
5059 GDS_NEIGHBOURS_send_notify_new_successor (my_identity, probable_successor, 5119// WAIT_NOTIFY_CONFIRMATION);
5060 trail_me_to_probable_succ, 5120 struct SendNotifyContext *notify_ctx;
5061 trail_me_to_probable_succ_len, 5121
5062 trail_id, 5122 notify_ctx = GNUNET_new(struct SendNotifyContext);
5063 target_friend); 5123
5124 notify_ctx->source_peer = my_identity;
5125 notify_ctx->successor = probable_successor;
5126 notify_ctx->successor_trail =
5127 GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity) * trail_me_to_probable_succ_len);
5128 memcpy(notify_ctx->successor_trail, trail_me_to_probable_succ,
5129 sizeof(struct GNUNET_PeerIdentity) * trail_me_to_probable_succ_len);
5130 notify_ctx->successor_trail_length = trail_me_to_probable_succ_len;
5131 notify_ctx->succesor_trail_id = trail_id;
5132 notify_ctx->target_friend = target_friend;
5133
5134// GDS_NEIGHBOURS_send_notify_new_successor (my_identity, probable_successor,
5135// trail_me_to_probable_succ,
5136// trail_me_to_probable_succ_len,
5137// trail_id,
5138// target_friend);
5139
5140 GNUNET_SCHEDULER_add_now(&send_notify_new_successor, (void*)notify_ctx);
5141
5064 return; 5142 return;
5065} 5143}
5066 5144
5067 5145
5146
5147void
5148send_notify_new_successor (void *cls,
5149 const struct GNUNET_SCHEDULER_TaskContext
5150 * tc)
5151{
5152 struct SendNotifyContext *ctx = (struct SendNotifyContext *) cls;
5153
5154 GDS_NEIGHBOURS_send_notify_new_successor (ctx->source_peer,
5155 ctx->successor,
5156 ctx->successor_trail,
5157 ctx->successor_trail_length,
5158 ctx->succesor_trail_id,
5159 ctx->target_friend);
5160
5161 if (send_notify_new_successor_retry_task != GNUNET_SCHEDULER_NO_TASK)
5162 {
5163 // Result from previous notify successos hasn't arrived, so the retry task
5164 // hasn't been cancelled! Already a new notify successor must be called.
5165 // We will cancel the retry request.
5166 struct SendNotifyContext *old_notify_ctx;
5167 old_notify_ctx = GNUNET_SCHEDULER_cancel(send_notify_new_successor_retry_task);
5168 GNUNET_free (old_notify_ctx->successor_trail);
5169 GNUNET_free (old_notify_ctx);
5170 send_notify_new_successor_retry_task = GNUNET_SCHEDULER_NO_TASK;
5171 }
5172
5173 send_notify_new_successor_retry_task = GNUNET_SCHEDULER_add_delayed(notify_successor_retry_time,
5174 &send_notify_new_successor,
5175 cls);
5176}
5177
5068/* 5178/*
5069 * Core handle for p2p verify successor result messages. 5179 * Core handle for p2p verify successor result messages.
5070 * @param cls closure 5180 * @param cls closure
@@ -5130,13 +5240,14 @@ handle_dht_p2p_verify_successor_result(void *cls,
5130 { 5240 {
5131 GNUNET_SCHEDULER_cancel(send_verify_successor_retry_task); 5241 GNUNET_SCHEDULER_cancel(send_verify_successor_retry_task);
5132 send_verify_successor_retry_task = GNUNET_SCHEDULER_NO_TASK; 5242 send_verify_successor_retry_task = GNUNET_SCHEDULER_NO_TASK;
5133 } 5243 }
5244
5134 compare_and_update_successor (current_successor, 5245 compare_and_update_successor (current_successor,
5135 probable_successor, trail, trail_length); 5246 probable_successor, trail, trail_length);
5136 5247
5137 // Schedule send_verify_successor_task in appropriate time. 5248 // Schedule send_verify_successor_task in appropriate time.
5138 send_verify_successor_task = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, 5249// send_verify_successor_task = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time,
5139 send_verify_successor_message, NULL); 5250// send_verify_successor_message, NULL);
5140 5251
5141 return GNUNET_OK; 5252 return GNUNET_OK;
5142 } 5253 }
@@ -5290,7 +5401,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls,
5290 struct FriendInfo *target_friend; 5401 struct FriendInfo *target_friend;
5291 struct GNUNET_PeerIdentity *next_hop; 5402 struct GNUNET_PeerIdentity *next_hop;
5292 size_t msize; 5403 size_t msize;
5293 5404
5294 msize = ntohs (message->size); 5405 msize = ntohs (message->size);
5295 5406
5296 if (msize != sizeof (struct PeerNotifyConfirmationMessage)) 5407 if (msize != sizeof (struct PeerNotifyConfirmationMessage))
@@ -5325,7 +5436,25 @@ handle_dht_p2p_notify_succ_confirmation (void *cls,
5325 * which may or may not be source of this message. This message is used 5436 * which may or may not be source of this message. This message is used
5326 * only to ensure that we have a path setup to reach to our successor. 5437 * only to ensure that we have a path setup to reach to our successor.
5327 */ 5438 */
5328 waiting_for_notify_confirmation = 0; 5439
5440 // TODO: cancel schedule of notify_successor_retry_task
5441 if (send_notify_new_successor_retry_task != GNUNET_SCHEDULER_NO_TASK)
5442 {
5443 struct SendNotifyContext *notify_ctx;
5444 notify_ctx = GNUNET_SCHEDULER_cancel(send_notify_new_successor_retry_task);
5445 GNUNET_free (notify_ctx->successor_trail);
5446 GNUNET_free (notify_ctx);
5447 send_notify_new_successor_retry_task = GNUNET_SCHEDULER_NO_TASK;
5448 }
5449
5450 // TODO: Schedule verify_successor task
5451 if (send_verify_successor_task == GNUNET_SCHEDULER_NO_TASK)
5452 send_verify_successor_task =
5453 GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time,
5454 &send_verify_successor_message,
5455 NULL);
5456
5457// waiting_for_notify_confirmation = 0;
5329 //FIXME: Should we reset the time out to 0? 5458 //FIXME: Should we reset the time out to 0?
5330 } 5459 }
5331 else 5460 else
@@ -5974,6 +6103,12 @@ GDS_NEIGHBOURS_init (void)
5974 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 6103 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
5975 DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us); 6104 DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us);
5976 6105
6106 notify_successor_retry_time.rel_value_us =
6107 DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us +
6108 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
6109 DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us);
6110
6111
5977 return GNUNET_OK; 6112 return GNUNET_OK;
5978} 6113}
5979 6114
@@ -6017,7 +6152,6 @@ GDS_NEIGHBOURS_done (void)
6017 6152
6018 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task) 6153 if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
6019 { 6154 {
6020 GNUNET_break (0);
6021 GNUNET_SCHEDULER_cancel (find_finger_trail_task); 6155 GNUNET_SCHEDULER_cancel (find_finger_trail_task);
6022 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK; 6156 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
6023 } 6157 }
@@ -6033,6 +6167,15 @@ GDS_NEIGHBOURS_done (void)
6033 GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); 6167 GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task);
6034 send_verify_successor_retry_task = GNUNET_SCHEDULER_NO_TASK; 6168 send_verify_successor_retry_task = GNUNET_SCHEDULER_NO_TASK;
6035 } 6169 }
6170
6171 if (send_notify_new_successor_retry_task != GNUNET_SCHEDULER_NO_TASK)
6172 {
6173 struct SendNotifyContext *notify_ctx;
6174 notify_ctx = GNUNET_SCHEDULER_cancel(send_notify_new_successor_retry_task);
6175 GNUNET_free (notify_ctx->successor_trail);
6176 GNUNET_free (notify_ctx);
6177 send_notify_new_successor_retry_task = GNUNET_SCHEDULER_NO_TASK;
6178 }
6036} 6179}
6037 6180
6038 6181