aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-04-20 11:31:06 +0200
committerChristian Grothoff <christian@grothoff.org>2019-04-20 11:31:10 +0200
commite719520ad6f3f4ad6f694525f5a018044d83a279 (patch)
tree46fcd871de166be0226f01308a7184957791f96c /src/transport/gnunet-service-tng.c
parent607cabb248ee06fc2b8b556e6468f7edb317fb2d (diff)
downloadgnunet-e719520ad6f3f4ad6f694525f5a018044d83a279.tar.gz
gnunet-e719520ad6f3f4ad6f694525f5a018044d83a279.zip
add logic to build DVBox messages in TNG
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c93
1 files changed, 86 insertions, 7 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index bca03574d..ace248a23 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -223,6 +223,7 @@
223 */ 223 */
224#define MAX_ADDRESS_VALID_UNTIL \ 224#define MAX_ADDRESS_VALID_UNTIL \
225 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1) 225 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
226
226/** 227/**
227 * How long do we consider an address valid if we just checked? 228 * How long do we consider an address valid if we just checked?
228 */ 229 */
@@ -1031,7 +1032,7 @@ struct DistanceVectorHop
1031 /** 1032 /**
1032 * Array of @e distance hops to the target, excluding @e next_hop. 1033 * Array of @e distance hops to the target, excluding @e next_hop.
1033 * NULL if the entire path is us to @e next_hop to `target`. Allocated 1034 * NULL if the entire path is us to @e next_hop to `target`. Allocated
1034 * at the end of this struct. 1035 * at the end of this struct. Excludes the target itself!
1035 */ 1036 */
1036 const struct GNUNET_PeerIdentity *path; 1037 const struct GNUNET_PeerIdentity *path;
1037 1038
@@ -1046,13 +1047,15 @@ struct DistanceVectorHop
1046 * Set to ZERO if the path is learned by snooping on DV learn messages 1047 * Set to ZERO if the path is learned by snooping on DV learn messages
1047 * initiated by other peers, and to the time at which we generated the 1048 * initiated by other peers, and to the time at which we generated the
1048 * challenge for DV learn operations this peer initiated. 1049 * challenge for DV learn operations this peer initiated.
1050 *
1051 * FIXME: freshness is currently never set!
1049 */ 1052 */
1050 struct GNUNET_TIME_Absolute freshness; 1053 struct GNUNET_TIME_Absolute freshness;
1051 1054
1052 /** 1055 /**
1053 * How many hops in total to the `target` (excluding @e next_hop and `target` 1056 * Number of hops in total to the `target` (excluding @e next_hop and `target`
1054 * itself), thus 0 still means a distance of 2 hops (to @e next_hop and then 1057 * itself). Thus 0 still means a distance of 2 hops (to @e next_hop and then
1055 * to `target`)? 1058 * to `target`).
1056 */ 1059 */
1057 unsigned int distance; 1060 unsigned int distance;
1058}; 1061};
@@ -3365,6 +3368,39 @@ route_via_neighbour (const struct Neighbour *n,
3365 3368
3366 3369
3367/** 3370/**
3371 * Given a distance vector path @a dvh route @a payload to
3372 * the ultimate destination respecting @a options.
3373 * Sets up the boxed message and queues it at the next hop.
3374 *
3375 * @param dvh choice of the path for the message
3376 * @param payload body to transmit
3377 * @param options options to use for control
3378 */
3379static void
3380forward_via_dvh (const struct DistanceVectorHop *dvh,
3381 const struct GNUNET_MessageHeader *payload,
3382 enum RouteMessageOptions options)
3383{
3384 uint16_t mlen = ntohs (payload->size);
3385 char boxram[sizeof (struct TransportDVBox) +
3386 (dvh->distance + 1) * sizeof (struct GNUNET_PeerIdentity) +
3387 mlen] GNUNET_ALIGN;
3388 struct TransportDVBox *box = (struct TransportDVBox *) boxram;
3389 struct GNUNET_PeerIdentity *path = (struct GNUNET_PeerIdentity *) &box[1];
3390
3391 box->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
3392 box->header.size = htons (sizeof (boxram));
3393 box->total_hops = htons (0);
3394 box->num_hops = htons (dvh->distance + 1);
3395 box->origin = GST_my_identity;
3396 memcpy (path, dvh->path, dvh->distance * sizeof (struct GNUNET_PeerIdentity));
3397 path[dvh->distance] = dvh->dv->target;
3398 memcpy (&path[dvh->distance + 1], payload, mlen);
3399 route_via_neighbour (dvh->next_hop, &box->header, options);
3400}
3401
3402
3403/**
3368 * Pick a path of @a dv under constraints @a options and schedule 3404 * Pick a path of @a dv under constraints @a options and schedule
3369 * transmission of @a hdr. 3405 * transmission of @a hdr.
3370 * 3406 *
@@ -3378,9 +3414,52 @@ route_via_dv (const struct DistanceVector *dv,
3378 const struct GNUNET_MessageHeader *hdr, 3414 const struct GNUNET_MessageHeader *hdr,
3379 enum RouteMessageOptions options) 3415 enum RouteMessageOptions options)
3380{ 3416{
3381 // FIXME: pick on or two 'random' paths (under constraints of options) 3417 struct DistanceVectorHop *h1;
3382 // Then add DVBox and enqueue message (possibly using 3418 struct DistanceVectorHop *h2;
3383 // route_via_neighbour for 1st hop?) 3419 uint64_t num_dv;
3420 uint64_t choice1;
3421 uint64_t choice2;
3422
3423 /* Pick random vectors, but weighted by distance, giving more weight
3424 to shorter vectors */
3425 num_dv = 0;
3426 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3427 pos = pos->next_dv)
3428 {
3429 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3430 (GNUNET_TIME_absolute_get_duration (pos->freshness).rel_value_us >
3431 ADDRESS_VALIDATION_LIFETIME.rel_value_us))
3432 continue; /* pos unconfirmed and confirmed required */
3433 num_dv += MAX_DV_HOPS_ALLOWED - pos->distance;
3434 }
3435 if (0 == num_dv)
3436 {
3437 GNUNET_break (0);
3438 return;
3439 }
3440 choice1 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3441 choice2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3442 num_dv = 0;
3443 h1 = NULL;
3444 h2 = NULL;
3445 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3446 pos = pos->next_dv)
3447 {
3448 uint32_t delta = MAX_DV_HOPS_ALLOWED - pos->distance;
3449
3450 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3451 (GNUNET_TIME_absolute_get_duration (pos->freshness).rel_value_us >
3452 ADDRESS_VALIDATION_LIFETIME.rel_value_us))
3453 continue; /* pos unconfirmed and confirmed required */
3454 if ((num_dv <= choice1) && (num_dv + delta > choice1))
3455 h1 = pos;
3456 if ((num_dv <= choice2) && (num_dv + delta > choice2))
3457 h2 = pos;
3458 num_dv += delta;
3459 }
3460 forward_via_dvh (h1, hdr, options & (~RMO_REDUNDANT));
3461 if (0 == (options & RMO_REDUNDANT))
3462 forward_via_dvh (h2, hdr, options & (~RMO_REDUNDANT));
3384} 3463}
3385 3464
3386 3465