diff options
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 645 |
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 | */ | ||
1208 | struct 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 | */ | ||
1825 | struct 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 | */ | ||
2956 | static void | ||
2957 | free_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 | */ | ||
2975 | static void | ||
2976 | reassembly_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 | */ | ||
3008 | static int | ||
3009 | free_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 | */ | ||
3275 | static void | ||
3276 | free_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 | */ | ||
3294 | static void | ||
3295 | reassembly_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 | */ | ||
3327 | static int | ||
3328 | free_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 | */ |
4621 | static struct GNUNET_TIME_Relative | 4632 | static 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 | |||
5727 | handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) | 5754 | handle_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 | */ |
7328 | static void | 7359 | static void |
7329 | forward_dv_box (struct Neighbour *next_hop, | 7360 | forward_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 | ||
8876 | static void | ||
8877 | reorder_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 | */ |
9033 | static void | 9131 | static 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, |