diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-17 22:54:14 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-17 22:54:14 +0200 |
commit | c29a8124f885f28f287e91ce7a0dabcdd6b17d50 (patch) | |
tree | f21cc1557806c19d4b01437ab6b01538e7d9fa0d /src/transport | |
parent | bd337cf7c6993eb8e97976ec0b088b317c57da0e (diff) | |
download | gnunet-c29a8124f885f28f287e91ce7a0dabcdd6b17d50.tar.gz gnunet-c29a8124f885f28f287e91ce7a0dabcdd6b17d50.zip |
more work on route_message() logic
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 193 |
1 files changed, 149 insertions, 44 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index f3874724a..27c97860e 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -3326,50 +3326,148 @@ queue_send_msg (struct Queue *queue, | |||
3326 | 3326 | ||
3327 | 3327 | ||
3328 | /** | 3328 | /** |
3329 | * Which transmission options are allowable for transmission? | ||
3330 | * Interpreted bit-wise! | ||
3331 | */ | ||
3332 | enum RouteMessageOptions { | ||
3333 | /** | ||
3334 | * Only confirmed, non-DV direct neighbours. | ||
3335 | */ | ||
3336 | RMO_NONE = 0, | ||
3337 | |||
3338 | /** | ||
3339 | * We are allowed to use DV routing for this @a hdr | ||
3340 | */ | ||
3341 | RMO_DV_ALLOWED = 1, | ||
3342 | |||
3343 | /** | ||
3344 | * We are allowed to use unconfirmed queues or DV routes for this message | ||
3345 | */ | ||
3346 | RMO_UNCONFIRMED_ALLOWED = 2, | ||
3347 | |||
3348 | /** | ||
3349 | * Reliable and unreliable, DV and non-DV are all acceptable. | ||
3350 | */ | ||
3351 | RMO_ANYTHING_GOES = (RMO_DV_ALLOWED | RMO_UNCONFIRMED_ALLOWED), | ||
3352 | |||
3353 | /** | ||
3354 | * If we have multiple choices, it is OK to send this message | ||
3355 | * over multiple channels at the same time to improve loss tolerance. | ||
3356 | * (We do at most 2 transmissions.) | ||
3357 | */ | ||
3358 | RMO_REDUNDANT = 4 | ||
3359 | }; | ||
3360 | |||
3361 | |||
3362 | /** | ||
3363 | * Pick a queue of @a n under constraints @a options and schedule | ||
3364 | * transmission of @a hdr. | ||
3365 | * | ||
3366 | * @param n neighbour to send to | ||
3367 | * @param hdr message to send as payload | ||
3368 | * @param options whether queues must be confirmed or not, | ||
3369 | * and whether we may pick multiple (2) queues | ||
3370 | */ | ||
3371 | static void | ||
3372 | route_via_neighbour (const struct Neighbour *n, | ||
3373 | const struct GNUNET_MessageHeader *hdr, | ||
3374 | enum RouteMessageOptions options) | ||
3375 | { | ||
3376 | // FIXME: pick on or two 'random' queue (under constraints of options) | ||
3377 | // Then add wrapper and enqueue message! | ||
3378 | } | ||
3379 | |||
3380 | |||
3381 | /** | ||
3382 | * Pick a path of @a dv under constraints @a options and schedule | ||
3383 | * transmission of @a hdr. | ||
3384 | * | ||
3385 | * @param n neighbour to send to | ||
3386 | * @param hdr message to send as payload | ||
3387 | * @param options whether path must be confirmed or not | ||
3388 | * and whether we may pick multiple (2) paths | ||
3389 | */ | ||
3390 | static void | ||
3391 | route_via_dv (const struct DistanceVector *dv, | ||
3392 | const struct GNUNET_MessageHeader *hdr, | ||
3393 | enum RouteMessageOptions options) | ||
3394 | { | ||
3395 | // FIXME: pick on or two 'random' paths (under constraints of options) | ||
3396 | // Then add DVBox and enqueue message (possibly using | ||
3397 | // route_via_neighbour for 1st hop?) | ||
3398 | } | ||
3399 | |||
3400 | |||
3401 | /** | ||
3329 | * We need to transmit @a hdr to @a target. If necessary, this may | 3402 | * We need to transmit @a hdr to @a target. If necessary, this may |
3330 | * involve DV routing or even broadcasting and fragmentation. | 3403 | * involve DV routing. |
3331 | * | 3404 | * |
3332 | * @param target peer to receive @a hdr | 3405 | * @param target peer to receive @a hdr |
3333 | * @param hdr header of the message to route and #GNUNET_free() | 3406 | * @param hdr header of the message to route and #GNUNET_free() |
3407 | * @param options which transmission channels are allowed | ||
3334 | */ | 3408 | */ |
3335 | static void | 3409 | static void |
3336 | route_message (const struct GNUNET_PeerIdentity *target, | 3410 | route_message (const struct GNUNET_PeerIdentity *target, |
3337 | struct GNUNET_MessageHeader *hdr) | 3411 | struct GNUNET_MessageHeader *hdr, |
3338 | { | 3412 | enum RouteMessageOptions options) |
3339 | // Cases: | 3413 | { |
3340 | // 1: called to transmit backchannel message we initiated | 3414 | struct Neighbour *n; |
3341 | // 2: called to transmit fragment ack | 3415 | struct DistanceVector *dv; |
3342 | // 3: called to transmit reliability box | 3416 | |
3343 | // 4: called to forward backchannel message | 3417 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, |
3344 | // 5: called to forward DV learn message (caller already picked random neighbour(s))! | 3418 | target); |
3345 | // 6: called to forward DV Box message | 3419 | dv = (0 != (options & RMO_DV_ALLOWED)) |
3346 | // 7: called to forward valdiation response | 3420 | ? GNUNET_CONTAINER_multipeermap_get (dv_routes, |
3347 | 3421 | target) | |
3348 | // Choices: | 3422 | : NULL; |
3349 | // a) Send ONLY to a *confirmed* direct neighbour | 3423 | if (0 == (options & RMO_UNCONFIRMED_ALLOWED)) |
3350 | // b) Send allowed to *unconfirmed* direct neighbour | 3424 | { |
3351 | // c) Route also via *confirmed* DV to target | 3425 | /* if confirmed is required, and we do not have anything |
3352 | // c) Route allowed via *unconfirmed DV to target | 3426 | confirmed, drop respective options */ |
3353 | // => One BIT "dv allowed or not", plus one BIT "confirmed/unconfirmed" might do! | 3427 | if ( (NULL != n) && |
3354 | 3428 | (GNUNET_NO == n->core_visible) ) | |
3355 | // Case analysis: | 3429 | n = NULL; |
3356 | // 1 2 3 4 5 6 7 | 3430 | if ( (NULL != dv) && |
3357 | // a X X X X X X X | 3431 | (GNUNET_NO == dv->core_visible) ) |
3358 | // b X X | 3432 | dv = NULL; |
3359 | // c X X X X X | 3433 | } |
3360 | // d X | 3434 | if ( (NULL == n) && |
3361 | // | 3435 | (NULL == dv) ) |
3362 | 3436 | { | |
3363 | // FIXME: this one is tricky: | 3437 | GNUNET_STATISTICS_update (GST_stats, |
3364 | // - we could try a direct, reliable channel | 3438 | "# Messages dropped in routing: no acceptable method", |
3365 | // - if that is unavailable / for load balancing, we may try: | 3439 | 1, |
3366 | // * multiple (?) direct unreliable channels - depending on loss rate? | 3440 | GNUNET_NO); |
3367 | // * some (?) DV channels - if above unavailable / too lossy? | 3441 | GNUNET_free (hdr); |
3368 | // * _random_ other peers ("broadcasting") in hope of *discovering* | 3442 | return; |
3369 | // a path back! - if all else fails | 3443 | } |
3370 | // => need more on DV first! | 3444 | /* If both dv and n are possible and we must choose: |
3371 | 3445 | flip a coin for the choice between the two; for now 50/50 */ | |
3372 | // FIXME: send hdr to target, free hdr (possibly using DV, possibly broadcasting) | 3446 | if ( (NULL != n) && |
3447 | (NULL != dv) && | ||
3448 | (0 == (options & RMO_REDUNDANT)) ) | ||
3449 | { | ||
3450 | if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2)) | ||
3451 | n = NULL; | ||
3452 | else | ||
3453 | dv = NULL; | ||
3454 | } | ||
3455 | if ( (NULL != n) && | ||
3456 | (NULL != dv) ) | ||
3457 | options &= ~RMO_REDUNDANT; /* We will do one DV and one direct, that's | ||
3458 | enough for redunancy, so clear the flag. */ | ||
3459 | if (NULL != n) | ||
3460 | { | ||
3461 | route_via_neighbour (n, | ||
3462 | hdr, | ||
3463 | options); | ||
3464 | } | ||
3465 | if (NULL != dv) | ||
3466 | { | ||
3467 | route_via_dv (dv, | ||
3468 | hdr, | ||
3469 | options); | ||
3470 | } | ||
3373 | GNUNET_free (hdr); | 3471 | GNUNET_free (hdr); |
3374 | } | 3472 | } |
3375 | 3473 | ||
@@ -3627,7 +3725,8 @@ handle_communicator_backchannel (void *cls, | |||
3627 | sizeof (ppay) + ntohs (cb->header.size) - sizeof (*cb)); | 3725 | sizeof (ppay) + ntohs (cb->header.size) - sizeof (*cb)); |
3628 | bc_key_clean (&key); | 3726 | bc_key_clean (&key); |
3629 | route_message (&cb->pid, | 3727 | route_message (&cb->pid, |
3630 | &enc->header); | 3728 | &enc->header, |
3729 | RMO_DV_ALLOWED); | ||
3631 | GNUNET_SERVICE_client_continue (tc->client); | 3730 | GNUNET_SERVICE_client_continue (tc->client); |
3632 | } | 3731 | } |
3633 | 3732 | ||
@@ -3971,7 +4070,8 @@ send_fragment_ack (struct ReassemblyContext *rc) | |||
3971 | ack->reassembly_timeout | 4070 | ack->reassembly_timeout |
3972 | = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)); | 4071 | = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)); |
3973 | route_message (&rc->neighbour->pid, | 4072 | route_message (&rc->neighbour->pid, |
3974 | &ack->header); | 4073 | &ack->header, |
4074 | RMO_DV_ALLOWED); | ||
3975 | rc->avg_ack_delay = GNUNET_TIME_UNIT_ZERO; | 4075 | rc->avg_ack_delay = GNUNET_TIME_UNIT_ZERO; |
3976 | rc->num_acks = 0; | 4076 | rc->num_acks = 0; |
3977 | rc->extra_acks = 0LLU; | 4077 | rc->extra_acks = 0LLU; |
@@ -4327,7 +4427,8 @@ handle_reliability_box (void *cls, | |||
4327 | &rb->msg_uuid, | 4427 | &rb->msg_uuid, |
4328 | sizeof (struct GNUNET_ShortHashCode)); | 4428 | sizeof (struct GNUNET_ShortHashCode)); |
4329 | route_message (&cmc->im.sender, | 4429 | route_message (&cmc->im.sender, |
4330 | &ack->header); | 4430 | &ack->header, |
4431 | RMO_DV_ALLOWED); | ||
4331 | } | 4432 | } |
4332 | /* continue with inner message */ | 4433 | /* continue with inner message */ |
4333 | demultiplex_with_cmc (cmc, | 4434 | demultiplex_with_cmc (cmc, |
@@ -4470,7 +4571,8 @@ handle_backchannel_encapsulation (void *cls, | |||
4470 | /* FIXME: BE routing can be special, should we put all of this | 4571 | /* FIXME: BE routing can be special, should we put all of this |
4471 | on 'route_message'? Maybe at least pass some more arguments? */ | 4572 | on 'route_message'? Maybe at least pass some more arguments? */ |
4472 | route_message (&be->target, | 4573 | route_message (&be->target, |
4473 | GNUNET_copy_message (&be->header)); | 4574 | GNUNET_copy_message (&be->header), |
4575 | RMO_DV_ALLOWED); | ||
4474 | finish_cmc_handling (cmc); | 4576 | finish_cmc_handling (cmc); |
4475 | return; | 4577 | return; |
4476 | } | 4578 | } |
@@ -4818,7 +4920,8 @@ forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop, | |||
4818 | &dhops[nhops].hop_sig)); | 4920 | &dhops[nhops].hop_sig)); |
4819 | } | 4921 | } |
4820 | route_message (next_hop, | 4922 | route_message (next_hop, |
4821 | &fwd->header); | 4923 | &fwd->header, |
4924 | RMO_UNCONFIRMED_ALLOWED); | ||
4822 | } | 4925 | } |
4823 | 4926 | ||
4824 | 4927 | ||
@@ -5160,7 +5263,8 @@ forward_dv_box (struct Neighbour *next_hop, | |||
5160 | payload, | 5263 | payload, |
5161 | payload_size); | 5264 | payload_size); |
5162 | route_message (&next_hop->pid, | 5265 | route_message (&next_hop->pid, |
5163 | &dvb->header); | 5266 | &dvb->header, |
5267 | RMO_NONE); | ||
5164 | } | 5268 | } |
5165 | 5269 | ||
5166 | 5270 | ||
@@ -5290,7 +5394,8 @@ handle_validation_challenge (void *cls, | |||
5290 | &tvr->signature)); | 5394 | &tvr->signature)); |
5291 | } | 5395 | } |
5292 | route_message (&cmc->im.sender, | 5396 | route_message (&cmc->im.sender, |
5293 | &tvr->header); | 5397 | &tvr->header, |
5398 | RMO_ANYTHING_GOES | RMO_REDUNDANT); | ||
5294 | finish_cmc_handling (cmc); | 5399 | finish_cmc_handling (cmc); |
5295 | } | 5400 | } |
5296 | 5401 | ||