aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-tng.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index ccce8bbbc..bca03574d 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -3309,8 +3309,58 @@ route_via_neighbour (const struct Neighbour *n,
3309 const struct GNUNET_MessageHeader *hdr, 3309 const struct GNUNET_MessageHeader *hdr,
3310 enum RouteMessageOptions options) 3310 enum RouteMessageOptions options)
3311{ 3311{
3312 // FIXME: pick on or two 'random' queue (under constraints of options) 3312 struct GNUNET_TIME_Absolute now;
3313 // Then add wrapper and enqueue message! 3313 unsigned int candidates;
3314 unsigned int sel1;
3315 unsigned int sel2;
3316
3317 /* Pick one or two 'random' queues from n (under constraints of options) */
3318 now = GNUNET_TIME_absolute_get ();
3319 /* FIXME-OPTIMIZE: give queues 'weights' and pick proportional to
3320 weight in the future; weight could be assigned by observed
3321 bandwidth (note: not sure if we should do this for this type
3322 of control traffic though). */
3323 candidates = 0;
3324 for (struct Queue *pos = n->queue_head; NULL != pos;
3325 pos = pos->next_neighbour)
3326 {
3327 /* Count the queue with the visibility task in all cases, as
3328 otherwise we may end up with no queues just because the
3329 time for the visibility task just expired but the scheduler
3330 just ran this task first */
3331 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) ||
3332 (pos->validated_until.abs_value_us > now.abs_value_us) ||
3333 (NULL != pos->visibility_task))
3334 candidates++;
3335 }
3336 if (0 == candidates)
3337 {
3338 /* Given that we above check for pos->visibility task,
3339 this should be strictly impossible. */
3340 GNUNET_break (0);
3341 return;
3342 }
3343 sel1 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
3344 if (0 == (options & RMO_REDUNDANT))
3345 sel2 = candidates; /* picks none! */
3346 else
3347 sel2 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
3348 candidates = 0;
3349 for (struct Queue *pos = n->queue_head; NULL != pos;
3350 pos = pos->next_neighbour)
3351 {
3352 /* Count the queue with the visibility task in all cases, as
3353 otherwise we may end up with no queues just because the
3354 time for the visibility task just expired but the scheduler
3355 just ran this task first */
3356 if ((pos->validated_until.abs_value_us > now.abs_value_us) ||
3357 (NULL != pos->visibility_task))
3358 {
3359 if ((sel1 == candidates) || (sel2 == candidates))
3360 queue_send_msg (pos, NULL, hdr, ntohs (hdr->size));
3361 candidates++;
3362 }
3363 }
3314} 3364}
3315 3365
3316 3366