aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c645
1 files changed, 378 insertions, 267 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index e41a1b000..56a854a70 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -742,6 +742,11 @@ struct TransportDVBoxMessage
742 struct GNUNET_MessageHeader header; 742 struct GNUNET_MessageHeader header;
743 743
744 /** 744 /**
745 * Flag if the payload is a control message. In NBO.
746 */
747 unsigned int without_fc;
748
749 /**
745 * Number of total hops this messages travelled. In NBO. 750 * Number of total hops this messages travelled. In NBO.
746 * @e origin sets this to zero, to be incremented at 751 * @e origin sets this to zero, to be incremented at
747 * each hop. Peers should limit the @e total_hops value 752 * each hop. Peers should limit the @e total_hops value
@@ -1198,6 +1203,65 @@ struct CoreSentContext
1198 1203
1199 1204
1200/** 1205/**
1206 * Information we keep for a message that we are reassembling.
1207 */
1208struct ReassemblyContext
1209{
1210 /**
1211 * Original message ID for of the message that all the fragments
1212 * belong to.
1213 */
1214 struct MessageUUIDP msg_uuid;
1215
1216 /**
1217 * Which neighbour is this context for?
1218 */
1219 struct VirtualLink *virtual_link;
1220
1221 /**
1222 * Entry in the reassembly heap (sorted by expiration).
1223 */
1224 struct GNUNET_CONTAINER_HeapNode *hn;
1225
1226 /**
1227 * Bitfield with @e msg_size bits representing the positions
1228 * where we have received fragments. When we receive a fragment,
1229 * we check the bits in @e bitfield before incrementing @e msg_missing.
1230 *
1231 * Allocated after the reassembled message.
1232 */
1233 uint8_t *bitfield;
1234
1235 /**
1236 * At what time will we give up reassembly of this message?
1237 */
1238 struct GNUNET_TIME_Absolute reassembly_timeout;
1239
1240 /**
1241 * Time we received the last fragment. @e avg_ack_delay must be
1242 * incremented by now - @e last_frag multiplied by @e num_acks.
1243 */
1244 struct GNUNET_TIME_Absolute last_frag;
1245
1246 /**
1247 * How big is the message we are reassembling in total?
1248 */
1249 uint16_t msg_size;
1250
1251 /**
1252 * How many bytes of the message are still missing? Defragmentation
1253 * is complete when @e msg_missing == 0.
1254 */
1255 uint16_t msg_missing;
1256
1257 /* Followed by @e msg_size bytes of the (partially) defragmented original
1258 * message */
1259
1260 /* Followed by @e bitfield data */
1261};
1262
1263
1264/**
1201 * A virtual link is another reachable peer that is known to CORE. It 1265 * A virtual link is another reachable peer that is known to CORE. It
1202 * can be either a `struct Neighbour` with at least one confirmed 1266 * can be either a `struct Neighbour` with at least one confirmed
1203 * `struct Queue`, or a `struct DistanceVector` with at least one 1267 * `struct Queue`, or a `struct DistanceVector` with at least one
@@ -1213,6 +1277,25 @@ struct VirtualLink
1213 struct GNUNET_PeerIdentity target; 1277 struct GNUNET_PeerIdentity target;
1214 1278
1215 /** 1279 /**
1280 * Map with `struct ReassemblyContext` structs for fragments under
1281 * reassembly. May be NULL if we currently have no fragments from
1282 * this @e pid (lazy initialization).
1283 */
1284 struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map;
1285
1286 /**
1287 * Heap with `struct ReassemblyContext` structs for fragments under
1288 * reassembly. May be NULL if we currently have no fragments from
1289 * this @e pid (lazy initialization).
1290 */
1291 struct GNUNET_CONTAINER_Heap *reassembly_heap;
1292
1293 /**
1294 * Task to free old entries from the @e reassembly_heap and @e reassembly_map.
1295 */
1296 struct GNUNET_SCHEDULER_Task *reassembly_timeout_task;
1297
1298 /**
1216 * Communicators blocked for receiving on @e target as we are waiting 1299 * Communicators blocked for receiving on @e target as we are waiting
1217 * on the @e core_recv_window to increase. 1300 * on the @e core_recv_window to increase.
1218 */ 1301 */
@@ -1819,63 +1902,7 @@ struct Queue
1819}; 1902};
1820 1903
1821 1904
1822/**
1823 * Information we keep for a message that we are reassembling.
1824 */
1825struct ReassemblyContext
1826{
1827 /**
1828 * Original message ID for of the message that all the fragments
1829 * belong to.
1830 */
1831 struct MessageUUIDP msg_uuid;
1832 1905
1833 /**
1834 * Which neighbour is this context for?
1835 */
1836 struct Neighbour *neighbour;
1837
1838 /**
1839 * Entry in the reassembly heap (sorted by expiration).
1840 */
1841 struct GNUNET_CONTAINER_HeapNode *hn;
1842
1843 /**
1844 * Bitfield with @e msg_size bits representing the positions
1845 * where we have received fragments. When we receive a fragment,
1846 * we check the bits in @e bitfield before incrementing @e msg_missing.
1847 *
1848 * Allocated after the reassembled message.
1849 */
1850 uint8_t *bitfield;
1851
1852 /**
1853 * At what time will we give up reassembly of this message?
1854 */
1855 struct GNUNET_TIME_Absolute reassembly_timeout;
1856
1857 /**
1858 * Time we received the last fragment. @e avg_ack_delay must be
1859 * incremented by now - @e last_frag multiplied by @e num_acks.
1860 */
1861 struct GNUNET_TIME_Absolute last_frag;
1862
1863 /**
1864 * How big is the message we are reassembling in total?
1865 */
1866 uint16_t msg_size;
1867
1868 /**
1869 * How many bytes of the message are still missing? Defragmentation
1870 * is complete when @e msg_missing == 0.
1871 */
1872 uint16_t msg_missing;
1873
1874 /* Followed by @e msg_size bytes of the (partially) defragmented original
1875 * message */
1876
1877 /* Followed by @e bitfield data */
1878};
1879 1906
1880 1907
1881/** 1908/**
@@ -1889,25 +1916,6 @@ struct Neighbour
1889 struct GNUNET_PeerIdentity pid; 1916 struct GNUNET_PeerIdentity pid;
1890 1917
1891 /** 1918 /**
1892 * Map with `struct ReassemblyContext` structs for fragments under
1893 * reassembly. May be NULL if we currently have no fragments from
1894 * this @e pid (lazy initialization).
1895 */
1896 struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map;
1897
1898 /**
1899 * Heap with `struct ReassemblyContext` structs for fragments under
1900 * reassembly. May be NULL if we currently have no fragments from
1901 * this @e pid (lazy initialization).
1902 */
1903 struct GNUNET_CONTAINER_Heap *reassembly_heap;
1904
1905 /**
1906 * Task to free old entries from the @e reassembly_heap and @e reassembly_map.
1907 */
1908 struct GNUNET_SCHEDULER_Task *reassembly_timeout_task;
1909
1910 /**
1911 * Head of MDLL of DV hops that have this neighbour as next hop. Must be 1919 * Head of MDLL of DV hops that have this neighbour as next hop. Must be
1912 * purged if this neighbour goes down. 1920 * purged if this neighbour goes down.
1913 */ 1921 */
@@ -2941,6 +2949,75 @@ free_pending_message (struct PendingMessage *pm)
2941 2949
2942 2950
2943/** 2951/**
2952 * Free @a rc
2953 *
2954 * @param rc data structure to free
2955 */
2956static void
2957free_reassembly_context (struct ReassemblyContext *rc)
2958{
2959 struct VirtualLink *vl = rc->virtual_link;
2960
2961 GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
2962 GNUNET_assert (GNUNET_OK ==
2963 GNUNET_CONTAINER_multihashmap32_remove (vl->reassembly_map,
2964 rc->msg_uuid.uuid,
2965 rc));
2966 GNUNET_free (rc);
2967}
2968
2969
2970/**
2971 * Task run to clean up reassembly context of a neighbour that have expired.
2972 *
2973 * @param cls a `struct Neighbour`
2974 */
2975static void
2976reassembly_cleanup_task (void *cls)
2977{
2978 struct VirtualLink *vl = cls;
2979 struct ReassemblyContext *rc;
2980
2981 vl->reassembly_timeout_task = NULL;
2982 while (NULL != (rc = GNUNET_CONTAINER_heap_peek (vl->reassembly_heap)))
2983 {
2984 if (0 == GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)
2985 .rel_value_us)
2986 {
2987 free_reassembly_context (rc);
2988 continue;
2989 }
2990 GNUNET_assert (NULL == vl->reassembly_timeout_task);
2991 vl->reassembly_timeout_task =
2992 GNUNET_SCHEDULER_add_at (rc->reassembly_timeout,
2993 &reassembly_cleanup_task,
2994 vl);
2995 return;
2996 }
2997}
2998
2999
3000/**
3001 * function called to #free_reassembly_context().
3002 *
3003 * @param cls NULL
3004 * @param key unused
3005 * @param value a `struct ReassemblyContext` to free
3006 * @return #GNUNET_OK (continue iteration)
3007 */
3008static int
3009free_reassembly_cb (void *cls, uint32_t key, void *value)
3010{
3011 struct ReassemblyContext *rc = value;
3012
3013 (void) cls;
3014 (void) key;
3015 free_reassembly_context (rc);
3016 return GNUNET_OK;
3017}
3018
3019
3020/**
2944 * Free virtual link. 3021 * Free virtual link.
2945 * 3022 *
2946 * @param vl link data to free 3023 * @param vl link data to free
@@ -2951,6 +3028,21 @@ free_virtual_link (struct VirtualLink *vl)
2951 struct PendingMessage *pm; 3028 struct PendingMessage *pm;
2952 struct CoreSentContext *csc; 3029 struct CoreSentContext *csc;
2953 3030
3031 if (NULL != vl->reassembly_map)
3032 {
3033 GNUNET_CONTAINER_multihashmap32_iterate (vl->reassembly_map,
3034 &free_reassembly_cb,
3035 NULL);
3036 GNUNET_CONTAINER_multihashmap32_destroy (vl->reassembly_map);
3037 vl->reassembly_map = NULL;
3038 GNUNET_CONTAINER_heap_destroy (vl->reassembly_heap);
3039 vl->reassembly_heap = NULL;
3040 }
3041 if (NULL != vl->reassembly_timeout_task)
3042 {
3043 GNUNET_SCHEDULER_cancel (vl->reassembly_timeout_task);
3044 vl->reassembly_timeout_task = NULL;
3045 }
2954 while (NULL != (pm = vl->pending_msg_head)) 3046 while (NULL != (pm = vl->pending_msg_head))
2955 free_pending_message (pm); 3047 free_pending_message (pm);
2956 GNUNET_assert (GNUNET_YES == 3048 GNUNET_assert (GNUNET_YES ==
@@ -3268,75 +3360,6 @@ client_connect_cb (void *cls,
3268 3360
3269 3361
3270/** 3362/**
3271 * Free @a rc
3272 *
3273 * @param rc data structure to free
3274 */
3275static void
3276free_reassembly_context (struct ReassemblyContext *rc)
3277{
3278 struct Neighbour *n = rc->neighbour;
3279
3280 GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
3281 GNUNET_assert (GNUNET_OK ==
3282 GNUNET_CONTAINER_multihashmap32_remove (n->reassembly_map,
3283 rc->msg_uuid.uuid,
3284 rc));
3285 GNUNET_free (rc);
3286}
3287
3288
3289/**
3290 * Task run to clean up reassembly context of a neighbour that have expired.
3291 *
3292 * @param cls a `struct Neighbour`
3293 */
3294static void
3295reassembly_cleanup_task (void *cls)
3296{
3297 struct Neighbour *n = cls;
3298 struct ReassemblyContext *rc;
3299
3300 n->reassembly_timeout_task = NULL;
3301 while (NULL != (rc = GNUNET_CONTAINER_heap_peek (n->reassembly_heap)))
3302 {
3303 if (0 == GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)
3304 .rel_value_us)
3305 {
3306 free_reassembly_context (rc);
3307 continue;
3308 }
3309 GNUNET_assert (NULL == n->reassembly_timeout_task);
3310 n->reassembly_timeout_task =
3311 GNUNET_SCHEDULER_add_at (rc->reassembly_timeout,
3312 &reassembly_cleanup_task,
3313 n);
3314 return;
3315 }
3316}
3317
3318
3319/**
3320 * function called to #free_reassembly_context().
3321 *
3322 * @param cls NULL
3323 * @param key unused
3324 * @param value a `struct ReassemblyContext` to free
3325 * @return #GNUNET_OK (continue iteration)
3326 */
3327static int
3328free_reassembly_cb (void *cls, uint32_t key, void *value)
3329{
3330 struct ReassemblyContext *rc = value;
3331
3332 (void) cls;
3333 (void) key;
3334 free_reassembly_context (rc);
3335 return GNUNET_OK;
3336}
3337
3338
3339/**
3340 * Release memory used by @a neighbour. 3363 * Release memory used by @a neighbour.
3341 * 3364 *
3342 * @param neighbour neighbour entry to free 3365 * @param neighbour neighbour entry to free
@@ -3354,16 +3377,6 @@ free_neighbour (struct Neighbour *neighbour)
3354 neighbour)); 3377 neighbour));
3355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3356 "Freeing neighbour\n"); 3379 "Freeing neighbour\n");
3357 if (NULL != neighbour->reassembly_map)
3358 {
3359 GNUNET_CONTAINER_multihashmap32_iterate (neighbour->reassembly_map,
3360 &free_reassembly_cb,
3361 NULL);
3362 GNUNET_CONTAINER_multihashmap32_destroy (neighbour->reassembly_map);
3363 neighbour->reassembly_map = NULL;
3364 GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap);
3365 neighbour->reassembly_heap = NULL;
3366 }
3367 while (NULL != (dvh = neighbour->dv_head)) 3380 while (NULL != (dvh = neighbour->dv_head))
3368 { 3381 {
3369 struct DistanceVector *dv = dvh->dv; 3382 struct DistanceVector *dv = dvh->dv;
@@ -3372,11 +3385,6 @@ free_neighbour (struct Neighbour *neighbour)
3372 if (NULL == dv->dv_head) 3385 if (NULL == dv->dv_head)
3373 free_dv_route (dv); 3386 free_dv_route (dv);
3374 } 3387 }
3375 if (NULL != neighbour->reassembly_timeout_task)
3376 {
3377 GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task);
3378 neighbour->reassembly_timeout_task = NULL;
3379 }
3380 if (NULL != neighbour->get) 3388 if (NULL != neighbour->get)
3381 { 3389 {
3382 GNUNET_PEERSTORE_iterate_cancel (neighbour->get); 3390 GNUNET_PEERSTORE_iterate_cancel (neighbour->get);
@@ -4232,9 +4240,10 @@ update_ephemeral (struct DistanceVector *dv)
4232 GNUNET_CRYPTO_ecdhe_key_create (&dv->private_key); 4240 GNUNET_CRYPTO_ecdhe_key_create (&dv->private_key);
4233 GNUNET_CRYPTO_ecdhe_key_get_public (&dv->private_key, &dv->ephemeral_key); 4241 GNUNET_CRYPTO_ecdhe_key_get_public (&dv->private_key, &dv->ephemeral_key);
4234 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL); 4242 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
4235 ec.purpose.size = htonl (sizeof(ec));
4236 ec.target = dv->target; 4243 ec.target = dv->target;
4237 ec.ephemeral_key = dv->ephemeral_key; 4244 ec.ephemeral_key = dv->ephemeral_key;
4245 ec.sender_monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime);
4246 ec.purpose.size = htonl (sizeof(ec));
4238 GNUNET_CRYPTO_eddsa_sign (GST_my_private_key, 4247 GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
4239 &ec, 4248 &ec,
4240 &dv->sender_sig); 4249 &dv->sender_sig);
@@ -4455,7 +4464,8 @@ dv_setup_key_state_from_km (const struct GNUNET_HashCode *km,
4455 km, 4464 km,
4456 sizeof(*km), 4465 sizeof(*km),
4457 iv, 4466 iv,
4458 sizeof(*iv))); 4467 sizeof(*iv),
4468 NULL));
4459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4460 "Deriving backchannel key based on KM %s and IV %s\n", 4470 "Deriving backchannel key based on KM %s and IV %s\n",
4461 GNUNET_h2s (km), 4471 GNUNET_h2s (km),
@@ -4616,6 +4626,7 @@ typedef void (*DVMessageHandler) (void *cls,
4616 * @param use function to call with the encapsulated message 4626 * @param use function to call with the encapsulated message
4617 * @param use_cls closure for @a use 4627 * @param use_cls closure for @a use
4618 * @param options whether path must be confirmed or not, to be passed to @a use 4628 * @param options whether path must be confirmed or not, to be passed to @a use
4629 * @param shall this TransportDVBoxMessage be forwarded without flow control.
4619 * @return expected RTT for transmission, #GNUNET_TIME_UNIT_FOREVER_REL if sending failed 4630 * @return expected RTT for transmission, #GNUNET_TIME_UNIT_FOREVER_REL if sending failed
4620 */ 4631 */
4621static struct GNUNET_TIME_Relative 4632static struct GNUNET_TIME_Relative
@@ -4625,7 +4636,8 @@ encapsulate_for_dv (struct DistanceVector *dv,
4625 const struct GNUNET_MessageHeader *hdr, 4636 const struct GNUNET_MessageHeader *hdr,
4626 DVMessageHandler use, 4637 DVMessageHandler use,
4627 void *use_cls, 4638 void *use_cls,
4628 enum RouteMessageOptions options) 4639 enum RouteMessageOptions options,
4640 enum GNUNET_GenericReturnValue without_fc)
4629{ 4641{
4630 struct TransportDVBoxMessage box_hdr; 4642 struct TransportDVBoxMessage box_hdr;
4631 struct TransportDVBoxPayloadP payload_hdr; 4643 struct TransportDVBoxPayloadP payload_hdr;
@@ -4633,28 +4645,31 @@ encapsulate_for_dv (struct DistanceVector *dv,
4633 char enc[sizeof(struct TransportDVBoxPayloadP) + enc_body_size] GNUNET_ALIGN; 4645 char enc[sizeof(struct TransportDVBoxPayloadP) + enc_body_size] GNUNET_ALIGN;
4634 struct TransportDVBoxPayloadP *enc_payload_hdr = 4646 struct TransportDVBoxPayloadP *enc_payload_hdr =
4635 (struct TransportDVBoxPayloadP *) enc; 4647 (struct TransportDVBoxPayloadP *) enc;
4636 struct DVKeyState key; 4648 struct DVKeyState *key;
4637 struct GNUNET_TIME_Relative rtt; 4649 struct GNUNET_TIME_Relative rtt;
4638 4650
4651 key = GNUNET_new (struct DVKeyState);
4639 /* Encrypt payload */ 4652 /* Encrypt payload */
4640 box_hdr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); 4653 box_hdr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
4641 box_hdr.total_hops = htons (0); 4654 box_hdr.total_hops = htons (0);
4655 box_hdr.without_fc = htons (without_fc);
4642 update_ephemeral (dv); 4656 update_ephemeral (dv);
4643 box_hdr.ephemeral_key = dv->ephemeral_key; 4657 box_hdr.ephemeral_key = dv->ephemeral_key;
4644 payload_hdr.sender_sig = dv->sender_sig; 4658 payload_hdr.sender_sig = dv->sender_sig;
4659
4645 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 4660 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
4646 &box_hdr.iv, 4661 &box_hdr.iv,
4647 sizeof(box_hdr.iv)); 4662 sizeof(box_hdr.iv));
4648 dh_key_derive_eph_pid (&dv->private_key, &dv->target, &box_hdr.iv, &key); 4663 dh_key_derive_eph_pid (&dv->private_key, &dv->target, &box_hdr.iv, key);
4649 payload_hdr.sender = GST_my_identity; 4664 payload_hdr.sender = GST_my_identity;
4650 payload_hdr.monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime); 4665 payload_hdr.monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime);
4651 dv_encrypt (&key, &payload_hdr, enc_payload_hdr, sizeof(payload_hdr)); 4666 dv_encrypt (key, &payload_hdr, enc_payload_hdr, sizeof(payload_hdr));
4652 dv_encrypt (&key, 4667 dv_encrypt (key,
4653 hdr, 4668 hdr,
4654 &enc[sizeof(struct TransportDVBoxPayloadP)], 4669 &enc[sizeof(struct TransportDVBoxPayloadP)],
4655 enc_body_size); 4670 enc_body_size);
4656 dv_hmac (&key, &box_hdr.hmac, enc, sizeof(enc)); 4671 dv_hmac (key, &box_hdr.hmac, enc, sizeof(enc));
4657 dv_key_clean (&key); 4672 dv_key_clean (key);
4658 rtt = GNUNET_TIME_UNIT_FOREVER_REL; 4673 rtt = GNUNET_TIME_UNIT_FOREVER_REL;
4659 /* For each selected path, take the pre-computed header and body 4674 /* For each selected path, take the pre-computed header and body
4660 and add the path in the middle of the message; then send it. */ 4675 and add the path in the middle of the message; then send it. */
@@ -4681,7 +4696,7 @@ encapsulate_for_dv (struct DistanceVector *dv,
4681 char *path; 4696 char *path;
4682 4697
4683 path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity)); 4698 path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity));
4684 for (unsigned int j = 0; j <= num_hops; j++) 4699 for (unsigned int j = 0; j < num_hops; j++)
4685 { 4700 {
4686 char *tmp; 4701 char *tmp;
4687 4702
@@ -4694,7 +4709,7 @@ encapsulate_for_dv (struct DistanceVector *dv,
4694 ntohs (hdr->type), 4709 ntohs (hdr->type),
4695 GNUNET_i2s (&dv->target), 4710 GNUNET_i2s (&dv->target),
4696 i + 1, 4711 i + 1,
4697 num_dvhs + 1, 4712 num_dvhs,
4698 path); 4713 path);
4699 GNUNET_free (path); 4714 GNUNET_free (path);
4700 } 4715 }
@@ -4704,6 +4719,7 @@ encapsulate_for_dv (struct DistanceVector *dv,
4704 dvh->next_hop, 4719 dvh->next_hop,
4705 (const struct GNUNET_MessageHeader *) buf, 4720 (const struct GNUNET_MessageHeader *) buf,
4706 options); 4721 options);
4722 GNUNET_free (key);
4707 } 4723 }
4708 return rtt; 4724 return rtt;
4709} 4725}
@@ -4828,13 +4844,16 @@ route_control_message_without_fc (struct VirtualLink *vl,
4828 "Failed to route message, could not determine DV path\n"); 4844 "Failed to route message, could not determine DV path\n");
4829 return rtt1; 4845 return rtt1;
4830 } 4846 }
4847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4848 "encapsulate_for_dv 1\n");
4831 rtt2 = encapsulate_for_dv (dv, 4849 rtt2 = encapsulate_for_dv (dv,
4832 res, 4850 res,
4833 hops, 4851 hops,
4834 hdr, 4852 hdr,
4835 &send_dv_to_neighbour, 4853 &send_dv_to_neighbour,
4836 NULL, 4854 NULL,
4837 options & (~RMO_REDUNDANT)); 4855 options & (~RMO_REDUNDANT),
4856 GNUNET_YES);
4838 } 4857 }
4839 return GNUNET_TIME_relative_min (rtt1, rtt2); 4858 return GNUNET_TIME_relative_min (rtt1, rtt2);
4840} 4859}
@@ -4955,7 +4974,8 @@ check_vl_transmission (struct VirtualLink *vl)
4955 vl->outbound_fc_window_size) 4974 vl->outbound_fc_window_size)
4956 { 4975 {
4957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4958 "Stalled transmission on VL %s due to flow control: %llu < %llu\n", 4977 "Stalled message %lu transmission on VL %s due to flow control: %llu < %llu\n",
4978 pm->logging_uuid,
4959 GNUNET_i2s (&vl->target), 4979 GNUNET_i2s (&vl->target),
4960 (unsigned long long) vl->outbound_fc_window_size, 4980 (unsigned long long) vl->outbound_fc_window_size,
4961 (unsigned long long) (pm->bytes_msg 4981 (unsigned long long) (pm->bytes_msg
@@ -4964,6 +4984,14 @@ check_vl_transmission (struct VirtualLink *vl)
4964 return; /* We have a message, but flow control says "nope" */ 4984 return; /* We have a message, but flow control says "nope" */
4965 } 4985 }
4966 elig = GNUNET_YES; 4986 elig = GNUNET_YES;
4987 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4988 "Eligible message %lu of size %llu to %s: %llu/%llu\n",
4989 pm->logging_uuid,
4990 pm->bytes_msg,
4991 GNUNET_i2s (&vl->target),
4992 (unsigned long long) vl->outbound_fc_window_size,
4993 (unsigned long long) (pm->bytes_msg
4994 + vl->outbound_fc_window_size_used));
4967 break; 4995 break;
4968 } 4996 }
4969 if (GNUNET_NO == elig) 4997 if (GNUNET_NO == elig)
@@ -5482,7 +5510,7 @@ handle_raw_message (void *cls, const struct GNUNET_MessageHeader *mh)
5482 vl->incoming_fc_window_size_used += size; 5510 vl->incoming_fc_window_size_used += size;
5483 /* TODO-M1 */ 5511 /* TODO-M1 */
5484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5485 "Dropped message of type %u with %u bytes to CORE: no CORE client connected!", 5513 "Dropped message of type %u with %u bytes to CORE: no CORE client connected!\n",
5486 (unsigned int) ntohs (mh->type), 5514 (unsigned int) ntohs (mh->type),
5487 (unsigned int) ntohs (mh->size)); 5515 (unsigned int) ntohs (mh->size));
5488 finish_cmc_handling (cmc); 5516 finish_cmc_handling (cmc);
@@ -5567,7 +5595,7 @@ transmit_cummulative_ack_cb (void *cls)
5567 struct VirtualLink *vl; 5595 struct VirtualLink *vl;
5568 struct AcknowledgementCummulator *ac = cls; 5596 struct AcknowledgementCummulator *ac = cls;
5569 char buf[sizeof(struct TransportReliabilityAckMessage) 5597 char buf[sizeof(struct TransportReliabilityAckMessage)
5570 + ac->ack_counter + ac->num_acks 5598 + ac->num_acks
5571 * sizeof(struct TransportCummulativeAckPayloadP)] GNUNET_ALIGN; 5599 * sizeof(struct TransportCummulativeAckPayloadP)] GNUNET_ALIGN;
5572 struct TransportReliabilityAckMessage *ack = 5600 struct TransportReliabilityAckMessage *ack =
5573 (struct TransportReliabilityAckMessage *) buf; 5601 (struct TransportReliabilityAckMessage *) buf;
@@ -5576,16 +5604,16 @@ transmit_cummulative_ack_cb (void *cls)
5576 ac->task = NULL; 5604 ac->task = NULL;
5577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5578 "Sending ACK with %u components to %s\n", 5606 "Sending ACK with %u components to %s\n",
5579 ac->ack_counter, 5607 ac->num_acks,
5580 GNUNET_i2s (&ac->target)); 5608 GNUNET_i2s (&ac->target));
5581 GNUNET_assert (0 <= ac->ack_counter); 5609 GNUNET_assert (0 < ac->num_acks);
5582 ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK); 5610 ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
5583 ack->header.size = 5611 ack->header.size =
5584 htons (sizeof(*ack) 5612 htons (sizeof(*ack)
5585 + ac->ack_counter * sizeof(struct TransportCummulativeAckPayloadP)); 5613 + ac->num_acks * sizeof(struct TransportCummulativeAckPayloadP));
5586 ack->ack_counter = htonl (ac->ack_counter += ac->num_acks); 5614 ack->ack_counter = htonl (ac->ack_counter += ac->num_acks);
5587 ap = (struct TransportCummulativeAckPayloadP *) &ack[1]; 5615 ap = (struct TransportCummulativeAckPayloadP *) &ack[1];
5588 for (unsigned int i = 0; i < ac->ack_counter; i++) 5616 for (unsigned int i = 0; i < ac->num_acks; i++)
5589 { 5617 {
5590 ap[i].ack_uuid = ac->ack_uuids[i].ack_uuid; 5618 ap[i].ack_uuid = ac->ack_uuids[i].ack_uuid;
5591 ap[i].ack_delay = GNUNET_TIME_relative_hton ( 5619 ap[i].ack_delay = GNUNET_TIME_relative_hton (
@@ -5657,7 +5685,6 @@ cummulative_ack (const struct GNUNET_PeerIdentity *pid,
5657 if (MAX_CUMMULATIVE_ACKS == ac->num_acks) 5685 if (MAX_CUMMULATIVE_ACKS == ac->num_acks)
5658 { 5686 {
5659 /* must run immediately, ack buffer full! */ 5687 /* must run immediately, ack buffer full! */
5660 GNUNET_SCHEDULER_cancel (ac->task);
5661 transmit_cummulative_ack_cb (ac); 5688 transmit_cummulative_ack_cb (ac);
5662 } 5689 }
5663 GNUNET_SCHEDULER_cancel (ac->task); 5690 GNUNET_SCHEDULER_cancel (ac->task);
@@ -5727,7 +5754,7 @@ static void
5727handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) 5754handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
5728{ 5755{
5729 struct CommunicatorMessageContext *cmc = cls; 5756 struct CommunicatorMessageContext *cmc = cls;
5730 struct Neighbour *n; 5757 struct VirtualLink *vl;
5731 struct ReassemblyContext *rc; 5758 struct ReassemblyContext *rc;
5732 const struct GNUNET_MessageHeader *msg; 5759 const struct GNUNET_MessageHeader *msg;
5733 uint16_t msize; 5760 uint16_t msize;
@@ -5737,30 +5764,33 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
5737 struct GNUNET_TIME_Relative cdelay; 5764 struct GNUNET_TIME_Relative cdelay;
5738 struct FindByMessageUuidContext fc; 5765 struct FindByMessageUuidContext fc;
5739 5766
5740 n = lookup_neighbour (&cmc->im.sender); 5767 vl = lookup_virtual_link (&cmc->im.sender);
5741 if (NULL == n) 5768 if (NULL == vl)
5742 { 5769 {
5743 struct GNUNET_SERVICE_Client *client = cmc->tc->client; 5770 struct GNUNET_SERVICE_Client *client = cmc->tc->client;
5744 5771
5772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5773 "No virtual link for %s to handle fragment\n",
5774 GNUNET_i2s (&cmc->im.sender));
5745 GNUNET_break (0); 5775 GNUNET_break (0);
5746 finish_cmc_handling (cmc); 5776 finish_cmc_handling (cmc);
5747 GNUNET_SERVICE_client_drop (client); 5777 GNUNET_SERVICE_client_drop (client);
5748 return; 5778 return;
5749 } 5779 }
5750 if (NULL == n->reassembly_map) 5780 if (NULL == vl->reassembly_map)
5751 { 5781 {
5752 n->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8); 5782 vl->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8);
5753 n->reassembly_heap = 5783 vl->reassembly_heap =
5754 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 5784 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
5755 n->reassembly_timeout_task = 5785 vl->reassembly_timeout_task =
5756 GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION, 5786 GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION,
5757 &reassembly_cleanup_task, 5787 &reassembly_cleanup_task,
5758 n); 5788 vl);
5759 } 5789 }
5760 msize = ntohs (fb->msg_size); 5790 msize = ntohs (fb->msg_size);
5761 fc.message_uuid = fb->msg_uuid; 5791 fc.message_uuid = fb->msg_uuid;
5762 fc.rc = NULL; 5792 fc.rc = NULL;
5763 (void) GNUNET_CONTAINER_multihashmap32_get_multiple (n->reassembly_map, 5793 (void) GNUNET_CONTAINER_multihashmap32_get_multiple (vl->reassembly_map,
5764 fb->msg_uuid.uuid, 5794 fb->msg_uuid.uuid,
5765 &find_by_message_uuid, 5795 &find_by_message_uuid,
5766 &fc); 5796 &fc);
@@ -5769,17 +5799,17 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
5769 rc = GNUNET_malloc (sizeof(*rc) + msize /* reassembly payload buffer */ 5799 rc = GNUNET_malloc (sizeof(*rc) + msize /* reassembly payload buffer */
5770 + (msize + 7) / 8 * sizeof(uint8_t) /* bitfield */); 5800 + (msize + 7) / 8 * sizeof(uint8_t) /* bitfield */);
5771 rc->msg_uuid = fb->msg_uuid; 5801 rc->msg_uuid = fb->msg_uuid;
5772 rc->neighbour = n; 5802 rc->virtual_link = vl;
5773 rc->msg_size = msize; 5803 rc->msg_size = msize;
5774 rc->reassembly_timeout = 5804 rc->reassembly_timeout =
5775 GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION); 5805 GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION);
5776 rc->last_frag = GNUNET_TIME_absolute_get (); 5806 rc->last_frag = GNUNET_TIME_absolute_get ();
5777 rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap, 5807 rc->hn = GNUNET_CONTAINER_heap_insert (vl->reassembly_heap,
5778 rc, 5808 rc,
5779 rc->reassembly_timeout.abs_value_us); 5809 rc->reassembly_timeout.abs_value_us);
5780 GNUNET_assert (GNUNET_OK == 5810 GNUNET_assert (GNUNET_OK ==
5781 GNUNET_CONTAINER_multihashmap32_put ( 5811 GNUNET_CONTAINER_multihashmap32_put (
5782 n->reassembly_map, 5812 vl->reassembly_map,
5783 rc->msg_uuid.uuid, 5813 rc->msg_uuid.uuid,
5784 rc, 5814 rc,
5785 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 5815 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
@@ -6452,12 +6482,12 @@ learn_dv_path (const struct GNUNET_PeerIdentity *path,
6452 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos; 6482 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
6453 pos = pos->next_dv) 6483 pos = pos->next_dv)
6454 { 6484 {
6455 if (pos->distance < path_len - 2) 6485 if (pos->distance < path_len - 3)
6456 shorter_distance++; 6486 shorter_distance++;
6457 /* Note that the distances in 'pos' excludes us (path[0]) and 6487 /* Note that the distances in 'pos' excludes us (path[0]),
6458 the next_hop (path[1]), so we need to subtract two 6488 the next_hop (path[1]) and the target so we need to subtract three
6459 and check next_hop explicitly */ 6489 and check next_hop explicitly */
6460 if ((pos->distance == path_len - 2) && (pos->next_hop == next_hop)) 6490 if ((pos->distance == path_len - 3) && (pos->next_hop == next_hop))
6461 { 6491 {
6462 int match = GNUNET_YES; 6492 int match = GNUNET_YES;
6463 6493
@@ -6521,16 +6551,16 @@ learn_dv_path (const struct GNUNET_PeerIdentity *path,
6521 "Discovered new DV path to %s\n", 6551 "Discovered new DV path to %s\n",
6522 GNUNET_i2s (&dv->target)); 6552 GNUNET_i2s (&dv->target));
6523 hop = GNUNET_malloc (sizeof(struct DistanceVectorHop) 6553 hop = GNUNET_malloc (sizeof(struct DistanceVectorHop)
6524 + sizeof(struct GNUNET_PeerIdentity) * (path_len - 2)); 6554 + sizeof(struct GNUNET_PeerIdentity) * (path_len - 3));
6525 hop->next_hop = next_hop; 6555 hop->next_hop = next_hop;
6526 hop->dv = dv; 6556 hop->dv = dv;
6527 hop->path = (const struct GNUNET_PeerIdentity *) &hop[1]; 6557 hop->path = (const struct GNUNET_PeerIdentity *) &hop[1];
6528 memcpy (&hop[1], 6558 memcpy (&hop[1],
6529 &path[2], 6559 &path[2],
6530 sizeof(struct GNUNET_PeerIdentity) * (path_len - 2)); 6560 sizeof(struct GNUNET_PeerIdentity) * (path_len - 3));
6531 hop->timeout = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT); 6561 hop->timeout = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
6532 hop->path_valid_until = path_valid_until; 6562 hop->path_valid_until = path_valid_until;
6533 hop->distance = path_len - 2; 6563 hop->distance = path_len - 3;
6534 hop->pd.aged_rtt = network_latency; 6564 hop->pd.aged_rtt = network_latency;
6535 GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, hop); 6565 GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, hop);
6536 GNUNET_CONTAINER_MDLL_insert (neighbour, 6566 GNUNET_CONTAINER_MDLL_insert (neighbour,
@@ -6630,6 +6660,7 @@ forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
6630 fwd->init_sig = msg->init_sig; 6660 fwd->init_sig = msg->init_sig;
6631 fwd->initiator = msg->initiator; 6661 fwd->initiator = msg->initiator;
6632 fwd->challenge = msg->challenge; 6662 fwd->challenge = msg->challenge;
6663 fwd->monotonic_time = msg->monotonic_time;
6633 dhops = (struct DVPathEntryP *) &fwd[1]; 6664 dhops = (struct DVPathEntryP *) &fwd[1];
6634 GNUNET_memcpy (dhops, hops, sizeof(struct DVPathEntryP) * nhops); 6665 GNUNET_memcpy (dhops, hops, sizeof(struct DVPathEntryP) * nhops);
6635 dhops[nhops].hop = GST_my_identity; 6666 dhops[nhops].hop = GST_my_identity;
@@ -6795,6 +6826,9 @@ dv_neighbour_transmission (void *cls,
6795{ 6826{
6796 struct NeighbourSelectionContext *nsc = cls; 6827 struct NeighbourSelectionContext *nsc = cls;
6797 6828
6829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6830 "transmission %s\n",
6831 GNUNET_i2s (pid));
6798 (void) value; 6832 (void) value;
6799 if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator)) 6833 if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator))
6800 return GNUNET_YES; /* skip initiator */ 6834 return GNUNET_YES; /* skip initiator */
@@ -7012,7 +7046,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
7012 &dvl->init_sig)) 7046 &dvl->init_sig))
7013 { 7047 {
7014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 7048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7015 "DV learn signature from %s invalid", 7049 "DV learn signature from %s invalid\n",
7016 GNUNET_i2s (&dvl->initiator)); 7050 GNUNET_i2s (&dvl->initiator));
7017 GNUNET_break_op (0); 7051 GNUNET_break_op (0);
7018 return; 7052 return;
@@ -7141,7 +7175,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
7141 GNUNET_i2s (&path[i]), 7175 GNUNET_i2s (&path[i]),
7142 GNUNET_STRINGS_relative_time_to_string (ilat, GNUNET_YES)); 7176 GNUNET_STRINGS_relative_time_to_string (ilat, GNUNET_YES));
7143 learn_dv_path (path, 7177 learn_dv_path (path,
7144 i, 7178 i + 1,
7145 ilat, 7179 ilat,
7146 GNUNET_TIME_relative_to_absolute ( 7180 GNUNET_TIME_relative_to_absolute (
7147 ADDRESS_VALIDATION_LIFETIME)); 7181 ADDRESS_VALIDATION_LIFETIME));
@@ -7177,10 +7211,10 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
7177 7211
7178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 7212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7179 "Learned inverse path with %u hops to %s\n", 7213 "Learned inverse path with %u hops to %s\n",
7180 i + 1, 7214 i + 2,
7181 GNUNET_i2s (&path[i + 2])); 7215 GNUNET_i2s (&path[i + 2]));
7182 iret = learn_dv_path (path, 7216 iret = learn_dv_path (path,
7183 i + 2, 7217 i + 3,
7184 GNUNET_TIME_UNIT_FOREVER_REL, 7218 GNUNET_TIME_UNIT_FOREVER_REL,
7185 GNUNET_TIME_UNIT_ZERO_ABS); 7219 GNUNET_TIME_UNIT_ZERO_ABS);
7186 if (GNUNET_SYSERR == iret) 7220 if (GNUNET_SYSERR == iret)
@@ -7218,13 +7252,10 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
7218 return; 7252 return;
7219 } 7253 }
7220 7254
7221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7222 "8 handle dv learn message from %s\n",
7223 GNUNET_i2s (&dvl->initiator));
7224 /* Forward to initiator, if path non-trivial and possible */ 7255 /* Forward to initiator, if path non-trivial and possible */
7225 bi_history = (bi_history << 1) | (bi_hop ? 1 : 0); 7256 bi_history = (bi_history << 1) | (bi_hop ? 1 : 0);
7226 did_initiator = GNUNET_NO; 7257 did_initiator = GNUNET_NO;
7227 if ((1 < nhops) && 7258 if ((1 <= nhops) &&
7228 (GNUNET_YES == 7259 (GNUNET_YES ==
7229 GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator))) 7260 GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator)))
7230 { 7261 {
@@ -7327,7 +7358,7 @@ check_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7327 */ 7358 */
7328static void 7359static void
7329forward_dv_box (struct Neighbour *next_hop, 7360forward_dv_box (struct Neighbour *next_hop,
7330 const struct TransportDVBoxMessage *hdr, 7361 struct TransportDVBoxMessage *hdr,
7331 uint16_t total_hops, 7362 uint16_t total_hops,
7332 uint16_t num_hops, 7363 uint16_t num_hops,
7333 const struct GNUNET_PeerIdentity *hops, 7364 const struct GNUNET_PeerIdentity *hops,
@@ -7336,37 +7367,57 @@ forward_dv_box (struct Neighbour *next_hop,
7336{ 7367{
7337 struct VirtualLink *vl = next_hop->vl; 7368 struct VirtualLink *vl = next_hop->vl;
7338 struct PendingMessage *pm; 7369 struct PendingMessage *pm;
7339 size_t msg_size; 7370 size_t msg_size = sizeof(struct TransportDVBoxMessage)
7371 + num_hops * sizeof(struct GNUNET_PeerIdentity)
7372 + enc_payload_size;
7340 char *buf; 7373 char *buf;
7374 char msg_buf[msg_size] GNUNET_ALIGN;
7341 struct GNUNET_PeerIdentity *dhops; 7375 struct GNUNET_PeerIdentity *dhops;
7342 7376
7343 GNUNET_assert (NULL != vl); 7377 GNUNET_assert (GNUNET_YES == ntohs (hdr->without_fc) || NULL != vl);
7344 msg_size = sizeof(struct TransportDVBoxMessage) 7378
7345 + num_hops * sizeof(struct GNUNET_PeerIdentity) + enc_payload_size; 7379 hdr->num_hops = htons (num_hops);
7346 pm = GNUNET_malloc (sizeof(struct PendingMessage) + msg_size); 7380 hdr->total_hops = htons (total_hops);
7347 pm->pmt = PMT_DV_BOX; 7381 memcpy (msg_buf, hdr, sizeof(*hdr));
7348 pm->vl = vl; 7382 dhops = (struct GNUNET_PeerIdentity *) &msg_buf[sizeof(struct
7349 pm->timeout = GNUNET_TIME_relative_to_absolute (DV_FORWARD_TIMEOUT); 7383 TransportDVBoxMessage)];
7350 pm->logging_uuid = logging_uuid_gen++;
7351 pm->prefs = GNUNET_MQ_PRIO_BACKGROUND;
7352 pm->bytes_msg = msg_size;
7353 buf = (char *) &pm[1];
7354 memcpy (buf, hdr, sizeof(*hdr));
7355 dhops =
7356 (struct GNUNET_PeerIdentity *) &buf[sizeof(struct TransportDVBoxMessage)];
7357 memcpy (dhops, hops, num_hops * sizeof(struct GNUNET_PeerIdentity)); 7384 memcpy (dhops, hops, num_hops * sizeof(struct GNUNET_PeerIdentity));
7358 memcpy (&dhops[num_hops], enc_payload, enc_payload_size); 7385 memcpy (&dhops[num_hops], enc_payload, enc_payload_size);
7359 GNUNET_CONTAINER_MDLL_insert (vl, 7386
7360 vl->pending_msg_head, 7387 if (GNUNET_YES == ntohs (hdr->without_fc))
7361 vl->pending_msg_tail, 7388 {
7362 pm); 7389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 7390 "Forwarding control message in DV Box to next hop %s (%u/%u) \n",
7364 "Created pending message %llu for DV Box with next hop %s (%u/%u)\n", 7391 GNUNET_i2s (&next_hop->pid),
7365 pm->logging_uuid, 7392 (unsigned int) num_hops,
7366 GNUNET_i2s (&next_hop->pid), 7393 (unsigned int) total_hops);
7367 (unsigned int) num_hops, 7394 route_via_neighbour (next_hop, (const struct
7368 (unsigned int) total_hops); 7395 GNUNET_MessageHeader *) msg_buf,
7369 check_vl_transmission (vl); 7396 RMO_ANYTHING_GOES);
7397 }
7398 else
7399 {
7400 pm = GNUNET_malloc (sizeof(struct PendingMessage) + msg_size);
7401 pm->pmt = PMT_DV_BOX;
7402 pm->vl = vl;
7403 pm->timeout = GNUNET_TIME_relative_to_absolute (DV_FORWARD_TIMEOUT);
7404 pm->logging_uuid = logging_uuid_gen++;
7405 pm->prefs = GNUNET_MQ_PRIO_BACKGROUND;
7406 pm->bytes_msg = msg_size;
7407 buf = (char *) &pm[1];
7408 memcpy (buf, msg_buf, msg_size);
7409 GNUNET_CONTAINER_MDLL_insert (vl,
7410 vl->pending_msg_head,
7411 vl->pending_msg_tail,
7412 pm);
7413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7414 "Created pending message %llu for DV Box with next hop %s (%u/%u)\n",
7415 pm->logging_uuid,
7416 GNUNET_i2s (&next_hop->pid),
7417 (unsigned int) num_hops,
7418 (unsigned int) total_hops);
7419 check_vl_transmission (vl);
7420 }
7370} 7421}
7371 7422
7372 7423
@@ -7579,11 +7630,14 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7579 const char *enc_payload = (const char *) &hops[num_hops]; 7630 const char *enc_payload = (const char *) &hops[num_hops];
7580 uint16_t enc_payload_size = 7631 uint16_t enc_payload_size =
7581 size - (num_hops * sizeof(struct GNUNET_PeerIdentity)); 7632 size - (num_hops * sizeof(struct GNUNET_PeerIdentity));
7582 struct DVKeyState key; 7633 char enc[enc_payload_size];
7634 struct DVKeyState *key;
7583 struct GNUNET_HashCode hmac; 7635 struct GNUNET_HashCode hmac;
7584 const char *hdr; 7636 const char *hdr;
7585 size_t hdr_len; 7637 size_t hdr_len;
7586 7638
7639 key = GNUNET_new (struct DVKeyState);
7640
7587 if (GNUNET_EXTRA_LOGGING > 0) 7641 if (GNUNET_EXTRA_LOGGING > 0)
7588 { 7642 {
7589 char *path; 7643 char *path;
@@ -7624,8 +7678,9 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7624 "Skipping %u/%u hops ahead while routing DV Box\n", 7678 "Skipping %u/%u hops ahead while routing DV Box\n",
7625 i, 7679 i,
7626 num_hops); 7680 num_hops);
7681
7627 forward_dv_box (n, 7682 forward_dv_box (n,
7628 dvb, 7683 (struct TransportDVBoxMessage *) dvb,
7629 ntohs (dvb->total_hops) + 1, 7684 ntohs (dvb->total_hops) + 1,
7630 num_hops - i - 1, /* number of hops left */ 7685 num_hops - i - 1, /* number of hops left */
7631 &hops[i + 1], /* remaining hops */ 7686 &hops[i + 1], /* remaining hops */
@@ -7657,10 +7712,13 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7657 GNUNET_NO); 7712 GNUNET_NO);
7658 cmc->total_hops = ntohs (dvb->total_hops); 7713 cmc->total_hops = ntohs (dvb->total_hops);
7659 7714
7660 dh_key_derive_eph_pub (&dvb->ephemeral_key, &dvb->iv, &key); 7715 dh_key_derive_eph_pub (&dvb->ephemeral_key, &dvb->iv, key);
7661 hdr = (const char *) &dvb[1]; 7716 hdr = (const char *) &dvb[1];
7662 hdr_len = ntohs (dvb->header.size) - sizeof(*dvb); 7717 hdr_len = ntohs (dvb->header.size) - sizeof(*dvb) - sizeof(struct
7663 dv_hmac (&key, &hmac, hdr, hdr_len); 7718 GNUNET_PeerIdentity)
7719 * ntohs (dvb->total_hops);
7720
7721 dv_hmac (key, &hmac, hdr, hdr_len);
7664 if (0 != GNUNET_memcmp (&hmac, &dvb->hmac)) 7722 if (0 != GNUNET_memcmp (&hmac, &dvb->hmac))
7665 { 7723 {
7666 /* HMAC mismatch, discard! */ 7724 /* HMAC mismatch, discard! */
@@ -7679,9 +7737,9 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7679 7737
7680 GNUNET_assert (hdr_len >= 7738 GNUNET_assert (hdr_len >=
7681 sizeof(ppay) + sizeof(struct GNUNET_MessageHeader)); 7739 sizeof(ppay) + sizeof(struct GNUNET_MessageHeader));
7682 dv_decrypt (&key, &ppay, hdr, sizeof(ppay)); 7740 dv_decrypt (key, &ppay, hdr, sizeof(ppay));
7683 dv_decrypt (&key, &body, &hdr[sizeof(ppay)], hdr_len - sizeof(ppay)); 7741 dv_decrypt (key, &body, &hdr[sizeof(ppay)], hdr_len - sizeof(ppay));
7684 dv_key_clean (&key); 7742 dv_key_clean (key);
7685 if (ntohs (mh->size) != sizeof(body)) 7743 if (ntohs (mh->size) != sizeof(body))
7686 { 7744 {
7687 GNUNET_break_op (0); 7745 GNUNET_break_op (0);
@@ -7727,9 +7785,10 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
7727 struct EphemeralConfirmationPS ec; 7785 struct EphemeralConfirmationPS ec;
7728 7786
7729 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL); 7787 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
7730 ec.purpose.size = htonl (sizeof(ec));
7731 ec.target = GST_my_identity; 7788 ec.target = GST_my_identity;
7732 ec.ephemeral_key = dvb->ephemeral_key; 7789 ec.ephemeral_key = dvb->ephemeral_key;
7790 ec.purpose.size = htonl (sizeof(ec));
7791 ec.sender_monotonic_time = ppay.monotonic_time;
7733 if ( 7792 if (
7734 GNUNET_OK != 7793 GNUNET_OK !=
7735 GNUNET_CRYPTO_eddsa_verify ( 7794 GNUNET_CRYPTO_eddsa_verify (
@@ -8656,6 +8715,12 @@ fragment_message (struct Queue *queue,
8656 mtu = (UINT16_MAX == queue->mtu) 8715 mtu = (UINT16_MAX == queue->mtu)
8657 ? UINT16_MAX - sizeof(struct GNUNET_TRANSPORT_SendMessageTo) 8716 ? UINT16_MAX - sizeof(struct GNUNET_TRANSPORT_SendMessageTo)
8658 : queue->mtu; 8717 : queue->mtu;
8718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8719 "Fragmenting message <%llu> with size %u to %s for MTU %u\n",
8720 pm->logging_uuid,
8721 pm->bytes_msg,
8722 GNUNET_i2s (&pm->vl->target),
8723 (unsigned int) mtu);
8659 set_pending_message_uuid (pm); 8724 set_pending_message_uuid (pm);
8660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 8725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8661 "Fragmenting message %llu <%llu> with size %u to %s for MTU %u\n", 8726 "Fragmenting message %llu <%llu> with size %u to %s for MTU %u\n",
@@ -8789,7 +8854,8 @@ reliability_box_message (struct Queue *queue,
8789 bpm->logging_uuid = logging_uuid_gen++; 8854 bpm->logging_uuid = logging_uuid_gen++;
8790 bpm->vl = pm->vl; 8855 bpm->vl = pm->vl;
8791 bpm->frag_parent = pm; 8856 bpm->frag_parent = pm;
8792 GNUNET_CONTAINER_MDLL_insert (frag, pm->head_frag, pm->tail_frag, bpm); 8857 // Why was this needed?
8858 // GNUNET_CONTAINER_MDLL_insert (frag, pm->head_frag, pm->tail_frag, bpm);
8793 bpm->timeout = pm->timeout; 8859 bpm->timeout = pm->timeout;
8794 bpm->pmt = PMT_RELIABILITY_BOX; 8860 bpm->pmt = PMT_RELIABILITY_BOX;
8795 bpm->bytes_msg = pm->bytes_msg + sizeof(rbox); 8861 bpm->bytes_msg = pm->bytes_msg + sizeof(rbox);
@@ -8807,6 +8873,30 @@ reliability_box_message (struct Queue *queue,
8807} 8873}
8808 8874
8809 8875
8876static void
8877reorder_root_pm (struct PendingMessage *pm,
8878 struct GNUNET_TIME_Absolute next_attempt)
8879{
8880 struct VirtualLink *vl = pm->vl;
8881 struct PendingMessage *pos;
8882
8883 /* re-insert sort in neighbour list */
8884 GNUNET_CONTAINER_MDLL_remove (vl,
8885 vl->pending_msg_head,
8886 vl->pending_msg_tail,
8887 pm);
8888 pos = vl->pending_msg_tail;
8889 while ((NULL != pos) &&
8890 (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
8891 pos = pos->prev_vl;
8892 GNUNET_CONTAINER_MDLL_insert_after (vl,
8893 vl->pending_msg_head,
8894 vl->pending_msg_tail,
8895 pos,
8896 pm);
8897}
8898
8899
8810/** 8900/**
8811 * Change the value of the `next_attempt` field of @a pm 8901 * Change the value of the `next_attempt` field of @a pm
8812 * to @a next_attempt and re-order @a pm in the transmission 8902 * to @a next_attempt and re-order @a pm in the transmission
@@ -8829,22 +8919,11 @@ update_pm_next_attempt (struct PendingMessage *pm,
8829 8919
8830 if (NULL == pm->frag_parent) 8920 if (NULL == pm->frag_parent)
8831 { 8921 {
8832 struct PendingMessage *pos; 8922 reorder_root_pm (pm, next_attempt);
8833 8923 }
8834 /* re-insert sort in neighbour list */ 8924 else if ((PMT_RELIABILITY_BOX == pm->pmt)||(PMT_DV_BOX == pm->pmt))
8835 GNUNET_CONTAINER_MDLL_remove (vl, 8925 {
8836 vl->pending_msg_head, 8926 reorder_root_pm (pm->frag_parent, next_attempt);
8837 vl->pending_msg_tail,
8838 pm);
8839 pos = vl->pending_msg_tail;
8840 while ((NULL != pos) &&
8841 (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
8842 pos = pos->prev_vl;
8843 GNUNET_CONTAINER_MDLL_insert_after (vl,
8844 vl->pending_msg_head,
8845 vl->pending_msg_tail,
8846 pos,
8847 pm);
8848 } 8927 }
8849 else 8928 else
8850 { 8929 {
@@ -8862,6 +8941,15 @@ update_pm_next_attempt (struct PendingMessage *pm,
8862 fp->tail_frag, 8941 fp->tail_frag,
8863 pos, 8942 pos,
8864 pm); 8943 pm);
8944 if (NULL == pos)
8945 {
8946 pos = fp;
8947 // Get the root pm
8948 while (NULL != pos->frag_parent)
8949 pos = pos->frag_parent;
8950 pos->next_attempt = next_attempt;
8951 reorder_root_pm (pos, next_attempt);
8952 }
8865 } 8953 }
8866} 8954}
8867 8955
@@ -8965,8 +9053,18 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
8965 (0 == (pos->prefs & GNUNET_MQ_PREF_UNRELIABLE)) && 9053 (0 == (pos->prefs & GNUNET_MQ_PREF_UNRELIABLE)) &&
8966 (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)) 9054 (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc))
8967 { 9055 {
8968 relb = GNUNET_YES;
8969 real_overhead += sizeof(struct TransportReliabilityBoxMessage); 9056 real_overhead += sizeof(struct TransportReliabilityBoxMessage);
9057
9058 if ((0 != queue->mtu) && (pos->bytes_msg + real_overhead > queue->mtu))
9059 {
9060 frag = GNUNET_YES;
9061 real_overhead = overhead + sizeof(struct TransportFragmentBoxMessage);
9062 }
9063 else
9064 {
9065 relb = GNUNET_YES;
9066 }
9067
8970 } 9068 }
8971 9069
8972 /* Finally, compare to existing 'best' in sc to see if this 'pos' pending 9070 /* Finally, compare to existing 'best' in sc to see if this 'pos' pending
@@ -8980,7 +9078,8 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
8980 given message fits _this_ queue, and do not consider how well other 9078 given message fits _this_ queue, and do not consider how well other
8981 queues might suit the message. Taking other queues into consideration 9079 queues might suit the message. Taking other queues into consideration
8982 may further improve the result, but could also be expensive 9080 may further improve the result, but could also be expensive
8983 in terms of CPU time. */long long sc_score = sc->frag * 40 + sc->relb * 20 + sc->real_overhead; 9081 in terms of CPU time. */
9082 long long sc_score = sc->frag * 40 + sc->relb * 20 + sc->real_overhead;
8984 long long pm_score = frag * 40 + relb * 20 + real_overhead; 9083 long long pm_score = frag * 40 + relb * 20 + real_overhead;
8985 long long time_delta = 9084 long long time_delta =
8986 (sc->best->next_attempt.abs_value_us - pos->next_attempt.abs_value_us) 9085 (sc->best->next_attempt.abs_value_us - pos->next_attempt.abs_value_us)
@@ -8994,12 +9093,10 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
8994 time_delta *= 10; /* increase weight (always, both are low latency) */ 9093 time_delta *= 10; /* increase weight (always, both are low latency) */
8995 else if ((0 != (pos->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) && 9094 else if ((0 != (pos->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) &&
8996 (time_delta > 0)) 9095 (time_delta > 0))
8997 time_delta *= 9096 time_delta *= 10; /* increase weight, favors 'pos', which is low latency */
8998 10; /* increase weight, favors 'pos', which is low latency */
8999 else if ((0 != (sc->best->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) && 9097 else if ((0 != (sc->best->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) &&
9000 (time_delta < 0)) 9098 (time_delta < 0))
9001 time_delta *= 9099 time_delta *= 10; /* increase weight, favors 'sc->best', which is low latency */
9002 10; /* increase weight, favors 'sc->best', which is low latency */
9003 if (0 != queue->mtu) 9100 if (0 != queue->mtu)
9004 { 9101 {
9005 /* Grant bonus if we are below MTU, larger bonus the closer we will 9102 /* Grant bonus if we are below MTU, larger bonus the closer we will
@@ -9016,6 +9113,7 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
9016 sc->dvh = dvh; 9113 sc->dvh = dvh;
9017 sc->frag = frag; 9114 sc->frag = frag;
9018 sc->relb = relb; 9115 sc->relb = relb;
9116 sc->real_overhead = real_overhead;
9019 } 9117 }
9020} 9118}
9021 9119
@@ -9027,7 +9125,7 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
9027 * 9125 *
9028 * @param cls a `struct PendingMessageScoreContext` 9126 * @param cls a `struct PendingMessageScoreContext`
9029 * @param next_hop next hop of the DV path 9127 * @param next_hop next hop of the DV path
9030 * @param hdr encapsulated message, technically a `struct TransportDFBoxMessage` 9128 * @param hdr encapsulated message, technically a `struct TransportDVBoxMessage`
9031 * @param options options of the original message 9129 * @param options options of the original message
9032 */ 9130 */
9033static void 9131static void
@@ -9045,6 +9143,11 @@ extract_box_cb (void *cls,
9045 bpm = GNUNET_malloc (sizeof(struct PendingMessage) + bsize); 9143 bpm = GNUNET_malloc (sizeof(struct PendingMessage) + bsize);
9046 bpm->logging_uuid = logging_uuid_gen++; 9144 bpm->logging_uuid = logging_uuid_gen++;
9047 bpm->pmt = PMT_DV_BOX; 9145 bpm->pmt = PMT_DV_BOX;
9146 bpm->vl = pm->vl;
9147 bpm->timeout = pm->timeout;
9148 bpm->bytes_msg = bsize;
9149 bpm->frag_parent = pm;
9150 set_pending_message_uuid (bpm);
9048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 9151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
9049 "Creating DV Box %llu for original message %llu (next hop is %s)\n", 9152 "Creating DV Box %llu for original message %llu (next hop is %s)\n",
9050 bpm->logging_uuid, 9153 bpm->logging_uuid,
@@ -9132,13 +9235,16 @@ transmit_on_queue (void *cls)
9132 free_pending_message (sc.best->bpm); 9235 free_pending_message (sc.best->bpm);
9133 sc.best->bpm = NULL; 9236 sc.best->bpm = NULL;
9134 } 9237 }
9238 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
9239 "encapsulate_for_dv 2\n");
9135 encapsulate_for_dv (sc.dvh->dv, 9240 encapsulate_for_dv (sc.dvh->dv,
9136 1, 9241 1,
9137 &sc.dvh, 9242 &sc.dvh,
9138 (const struct GNUNET_MessageHeader *) &sc.best[1], 9243 (const struct GNUNET_MessageHeader *) &sc.best[1],
9139 &extract_box_cb, 9244 &extract_box_cb,
9140 &sc, 9245 &sc,
9141 RMO_NONE); 9246 RMO_NONE,
9247 GNUNET_NO);
9142 GNUNET_assert (NULL != sc.best->bpm); 9248 GNUNET_assert (NULL != sc.best->bpm);
9143 pm = sc.best->bpm; 9249 pm = sc.best->bpm;
9144 } 9250 }
@@ -9227,6 +9333,11 @@ transmit_on_queue (void *cls)
9227 OPTIMIZE: Note that in the future this heuristic should likely 9333 OPTIMIZE: Note that in the future this heuristic should likely
9228 be improved further (measure RTT stability, consider message 9334 be improved further (measure RTT stability, consider message
9229 urgency and size when delaying ACKs, etc.) */ 9335 urgency and size when delaying ACKs, etc.) */
9336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
9337 "Waiting %s for ACK\n",
9338 GNUNET_STRINGS_relative_time_to_string (
9339 GNUNET_TIME_relative_multiply (
9340 queue->pd.aged_rtt, 4), GNUNET_NO));
9230 update_pm_next_attempt (pm, 9341 update_pm_next_attempt (pm,
9231 GNUNET_TIME_relative_to_absolute ( 9342 GNUNET_TIME_relative_to_absolute (
9232 GNUNET_TIME_relative_multiply (queue->pd.aged_rtt, 9343 GNUNET_TIME_relative_multiply (queue->pd.aged_rtt,