diff options
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 119 |
1 files changed, 102 insertions, 17 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index f327976ee..2f7129478 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -24,8 +24,8 @@ | |||
24 | * | 24 | * |
25 | * TODO: | 25 | * TODO: |
26 | * Implement next: | 26 | * Implement next: |
27 | * - FIXME: transmit_on_queue: track dvh we may be using and pass it to | 27 | * - FIXME: handle_client_send(): pick DVH path, and box |
28 | * fragment_message() and reliability_box_message() if applicable | 28 | * message accordingly (if applicable, see FIXMEs) |
29 | * - proper use/initialization of timestamps in messages exchanged | 29 | * - proper use/initialization of timestamps in messages exchanged |
30 | * during DV learning | 30 | * during DV learning |
31 | * - persistence of monotonic time from DVInit to prevent | 31 | * - persistence of monotonic time from DVInit to prevent |
@@ -1194,6 +1194,16 @@ struct DistanceVectorHop | |||
1194 | struct DistanceVectorHop *prev_neighbour; | 1194 | struct DistanceVectorHop *prev_neighbour; |
1195 | 1195 | ||
1196 | /** | 1196 | /** |
1197 | * Head of MDLL of messages routed via this path. | ||
1198 | */ | ||
1199 | struct PendingMessage *pending_msg_head; | ||
1200 | |||
1201 | /** | ||
1202 | * Tail of MDLL of messages routed via this path. | ||
1203 | */ | ||
1204 | struct PendingMessage *pending_msg_tail; | ||
1205 | |||
1206 | /** | ||
1197 | * Head of DLL of PAs that used our @a path. | 1207 | * Head of DLL of PAs that used our @a path. |
1198 | */ | 1208 | */ |
1199 | struct PendingAcknowledgement *pa_head; | 1209 | struct PendingAcknowledgement *pa_head; |
@@ -1773,6 +1783,18 @@ struct PendingMessage | |||
1773 | struct PendingMessage *prev_frag; | 1783 | struct PendingMessage *prev_frag; |
1774 | 1784 | ||
1775 | /** | 1785 | /** |
1786 | * Kept in a MDLL of messages using this @a dvh (if @e dvh is | ||
1787 | * non-NULL). | ||
1788 | */ | ||
1789 | struct PendingMessage *next_dvh; | ||
1790 | |||
1791 | /** | ||
1792 | * Kept in a MDLL of messages using this @a dvh (if @e dvh is | ||
1793 | * non-NULL). | ||
1794 | */ | ||
1795 | struct PendingMessage *prev_dvh; | ||
1796 | |||
1797 | /** | ||
1776 | * Head of DLL of PAs for this pending message. | 1798 | * Head of DLL of PAs for this pending message. |
1777 | */ | 1799 | */ |
1778 | struct PendingAcknowledgement *pa_head; | 1800 | struct PendingAcknowledgement *pa_head; |
@@ -1789,11 +1811,18 @@ struct PendingMessage | |||
1789 | struct PendingMessage *bpm; | 1811 | struct PendingMessage *bpm; |
1790 | 1812 | ||
1791 | /** | 1813 | /** |
1792 | * Target of the request. | 1814 | * Target of the request (for transmission, may not be ultimate |
1815 | * destination!). | ||
1793 | */ | 1816 | */ |
1794 | struct Neighbour *target; | 1817 | struct Neighbour *target; |
1795 | 1818 | ||
1796 | /** | 1819 | /** |
1820 | * Distance vector path selected for this message, or | ||
1821 | * NULL if transmitted directly. | ||
1822 | */ | ||
1823 | struct DistanceVectorHop *dvh; | ||
1824 | |||
1825 | /** | ||
1797 | * Set to non-NULL value if this message is currently being given to a | 1826 | * Set to non-NULL value if this message is currently being given to a |
1798 | * communicator and we are awaiting that communicator's acknowledgement. | 1827 | * communicator and we are awaiting that communicator's acknowledgement. |
1799 | * Note that we must not retransmit a pending message while we're still | 1828 | * Note that we must not retransmit a pending message while we're still |
@@ -2573,7 +2602,16 @@ free_distance_vector_hop (struct DistanceVectorHop *dvh) | |||
2573 | struct Neighbour *n = dvh->next_hop; | 2602 | struct Neighbour *n = dvh->next_hop; |
2574 | struct DistanceVector *dv = dvh->dv; | 2603 | struct DistanceVector *dv = dvh->dv; |
2575 | struct PendingAcknowledgement *pa; | 2604 | struct PendingAcknowledgement *pa; |
2605 | struct PendingMessage *pm; | ||
2576 | 2606 | ||
2607 | while (NULL != (pm = dvh->pending_msg_head)) | ||
2608 | { | ||
2609 | GNUNET_CONTAINER_MDLL_remove (dvh, | ||
2610 | dvh->pending_msg_head, | ||
2611 | dvh->pending_msg_tail, | ||
2612 | pm); | ||
2613 | pm->dvh = NULL; | ||
2614 | } | ||
2577 | while (NULL != (pa = dvh->pa_head)) | 2615 | while (NULL != (pa = dvh->pa_head)) |
2578 | { | 2616 | { |
2579 | GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa); | 2617 | GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa); |
@@ -3122,6 +3160,7 @@ client_disconnect_cb (void *cls, | |||
3122 | struct TransportClient *tc = app_ctx; | 3160 | struct TransportClient *tc = app_ctx; |
3123 | 3161 | ||
3124 | (void) cls; | 3162 | (void) cls; |
3163 | (void) client; | ||
3125 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3126 | "Client %p disconnected, cleaning up.\n", | 3165 | "Client %p disconnected, cleaning up.\n", |
3127 | tc); | 3166 | tc); |
@@ -3301,6 +3340,7 @@ free_pending_message (struct PendingMessage *pm) | |||
3301 | { | 3340 | { |
3302 | struct TransportClient *tc = pm->client; | 3341 | struct TransportClient *tc = pm->client; |
3303 | struct Neighbour *target = pm->target; | 3342 | struct Neighbour *target = pm->target; |
3343 | struct DistanceVectorHop *dvh = pm->dvh; | ||
3304 | struct PendingAcknowledgement *pa; | 3344 | struct PendingAcknowledgement *pa; |
3305 | 3345 | ||
3306 | if (NULL != tc) | 3346 | if (NULL != tc) |
@@ -3310,6 +3350,13 @@ free_pending_message (struct PendingMessage *pm) | |||
3310 | tc->details.core.pending_msg_tail, | 3350 | tc->details.core.pending_msg_tail, |
3311 | pm); | 3351 | pm); |
3312 | } | 3352 | } |
3353 | if (NULL != dvh) | ||
3354 | { | ||
3355 | GNUNET_CONTAINER_MDLL_remove (dvh, | ||
3356 | dvh->pending_msg_head, | ||
3357 | dvh->pending_msg_tail, | ||
3358 | pm); | ||
3359 | } | ||
3313 | GNUNET_CONTAINER_MDLL_remove (neighbour, | 3360 | GNUNET_CONTAINER_MDLL_remove (neighbour, |
3314 | target->pending_msg_head, | 3361 | target->pending_msg_head, |
3315 | target->pending_msg_tail, | 3362 | target->pending_msg_tail, |
@@ -3418,14 +3465,22 @@ handle_client_send (void *cls, const struct OutboundMessage *obm) | |||
3418 | struct PendingMessage *pm; | 3465 | struct PendingMessage *pm; |
3419 | const struct GNUNET_MessageHeader *obmm; | 3466 | const struct GNUNET_MessageHeader *obmm; |
3420 | struct Neighbour *target; | 3467 | struct Neighbour *target; |
3468 | struct DistanceVector *dv; | ||
3469 | struct DistanceVectorHop *dvh; | ||
3421 | uint32_t bytes_msg; | 3470 | uint32_t bytes_msg; |
3422 | int was_empty; | 3471 | int was_empty; |
3472 | const void *payload; | ||
3473 | size_t payload_size; | ||
3423 | 3474 | ||
3424 | GNUNET_assert (CT_CORE == tc->type); | 3475 | GNUNET_assert (CT_CORE == tc->type); |
3425 | obmm = (const struct GNUNET_MessageHeader *) &obm[1]; | 3476 | obmm = (const struct GNUNET_MessageHeader *) &obm[1]; |
3426 | bytes_msg = ntohs (obmm->size); | 3477 | bytes_msg = ntohs (obmm->size); |
3427 | target = lookup_neighbour (&obm->peer); | 3478 | target = lookup_neighbour (&obm->peer); |
3428 | if (NULL == target) | 3479 | if (NULL == target) |
3480 | dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, &obm->peer); | ||
3481 | else | ||
3482 | dv = NULL; | ||
3483 | if ((NULL == target) && ((NULL == dv) || (GNUNET_NO == dv->core_visible))) | ||
3429 | { | 3484 | { |
3430 | /* Failure: don't have this peer as a neighbour (anymore). | 3485 | /* Failure: don't have this peer as a neighbour (anymore). |
3431 | Might have gone down asynchronously, so this is NOT | 3486 | Might have gone down asynchronously, so this is NOT |
@@ -3447,14 +3502,41 @@ handle_client_send (void *cls, const struct OutboundMessage *obm) | |||
3447 | GNUNET_NO); | 3502 | GNUNET_NO); |
3448 | return; | 3503 | return; |
3449 | } | 3504 | } |
3505 | if (NULL == target) | ||
3506 | { | ||
3507 | // FIXME: overall, similar logic exists already for DV boxing, | ||
3508 | // re-use! | ||
3509 | |||
3510 | // FIXME: dvh = pick_dv_hop (dv); | ||
3511 | target = dvh->next_hop; | ||
3512 | // FIXME: dv box message here! | ||
3513 | // FIXME: set payload & payload_size to box (and free box below!) | ||
3514 | } | ||
3515 | else | ||
3516 | { | ||
3517 | dvh = NULL; | ||
3518 | // box = NULL; | ||
3519 | payload = &obm[1]; | ||
3520 | payload_size = bytes_msg; | ||
3521 | } | ||
3522 | |||
3450 | was_empty = (NULL == target->pending_msg_head); | 3523 | was_empty = (NULL == target->pending_msg_head); |
3451 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + bytes_msg); | 3524 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + payload_size); |
3452 | pm->client = tc; | 3525 | pm->client = tc; |
3453 | pm->target = target; | 3526 | pm->target = target; |
3454 | pm->bytes_msg = bytes_msg; | 3527 | pm->bytes_msg = payload_size; |
3455 | pm->timeout = | 3528 | pm->timeout = |
3456 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout)); | 3529 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout)); |
3457 | memcpy (&pm[1], &obm[1], bytes_msg); | 3530 | memcpy (&pm[1], &obm[1], payload_size); |
3531 | // FIXME: GNUNET_free_non_null (box); | ||
3532 | pm->dvh = dvh; | ||
3533 | if (NULL != dvh) | ||
3534 | { | ||
3535 | GNUNET_CONTAINER_MDLL_insert (dvh, | ||
3536 | dvh->pending_msg_head, | ||
3537 | dvh->pending_msg_tail, | ||
3538 | pm); | ||
3539 | } | ||
3458 | GNUNET_CONTAINER_MDLL_insert (neighbour, | 3540 | GNUNET_CONTAINER_MDLL_insert (neighbour, |
3459 | target->pending_msg_head, | 3541 | target->pending_msg_head, |
3460 | target->pending_msg_tail, | 3542 | target->pending_msg_tail, |
@@ -3557,7 +3639,7 @@ check_communicator_backchannel ( | |||
3557 | 3639 | ||
3558 | (void) cls; | 3640 | (void) cls; |
3559 | msize = ntohs (cb->header.size) - sizeof (*cb); | 3641 | msize = ntohs (cb->header.size) - sizeof (*cb); |
3560 | if (UINT16_MAX - msize > | 3642 | if (((size_t) (UINT16_MAX - msize)) > |
3561 | sizeof (struct TransportBackchannelEncapsulationMessage) + | 3643 | sizeof (struct TransportBackchannelEncapsulationMessage) + |
3562 | sizeof (struct TransportBackchannelRequestPayloadP)) | 3644 | sizeof (struct TransportBackchannelRequestPayloadP)) |
3563 | { | 3645 | { |
@@ -3943,7 +4025,7 @@ route_message (const struct GNUNET_PeerIdentity *target, | |||
3943 | struct Neighbour *n; | 4025 | struct Neighbour *n; |
3944 | struct DistanceVector *dv; | 4026 | struct DistanceVector *dv; |
3945 | 4027 | ||
3946 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, target); | 4028 | n = lookup_neighbour (target); |
3947 | dv = (0 != (options & RMO_DV_ALLOWED)) | 4029 | dv = (0 != (options & RMO_DV_ALLOWED)) |
3948 | ? GNUNET_CONTAINER_multipeermap_get (dv_routes, target) | 4030 | ? GNUNET_CONTAINER_multipeermap_get (dv_routes, target) |
3949 | : NULL; | 4031 | : NULL; |
@@ -4518,6 +4600,7 @@ check_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) | |||
4518 | uint16_t size = ntohs (fb->header.size); | 4600 | uint16_t size = ntohs (fb->header.size); |
4519 | uint16_t bsize = size - sizeof (*fb); | 4601 | uint16_t bsize = size - sizeof (*fb); |
4520 | 4602 | ||
4603 | (void) cls; | ||
4521 | if (0 == bsize) | 4604 | if (0 == bsize) |
4522 | { | 4605 | { |
4523 | GNUNET_break_op (0); | 4606 | GNUNET_break_op (0); |
@@ -4706,7 +4789,7 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) | |||
4706 | struct GNUNET_TIME_Relative cdelay; | 4789 | struct GNUNET_TIME_Relative cdelay; |
4707 | struct FindByMessageUuidContext fc; | 4790 | struct FindByMessageUuidContext fc; |
4708 | 4791 | ||
4709 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); | 4792 | n = lookup_neighbour (&cmc->im.sender); |
4710 | if (NULL == n) | 4793 | if (NULL == n) |
4711 | { | 4794 | { |
4712 | struct GNUNET_SERVICE_Client *client = cmc->tc->client; | 4795 | struct GNUNET_SERVICE_Client *client = cmc->tc->client; |
@@ -4832,6 +4915,7 @@ static int | |||
4832 | check_reliability_box (void *cls, | 4915 | check_reliability_box (void *cls, |
4833 | const struct TransportReliabilityBoxMessage *rb) | 4916 | const struct TransportReliabilityBoxMessage *rb) |
4834 | { | 4917 | { |
4918 | (void) cls; | ||
4835 | GNUNET_MQ_check_boxed_message (rb); | 4919 | GNUNET_MQ_check_boxed_message (rb); |
4836 | return GNUNET_YES; | 4920 | return GNUNET_YES; |
4837 | } | 4921 | } |
@@ -5528,7 +5612,7 @@ check_dv_path_down (void *cls) | |||
5528 | } | 5612 | } |
5529 | /* all paths invalid, make dv core-invisible */ | 5613 | /* all paths invalid, make dv core-invisible */ |
5530 | dv->core_visible = GNUNET_NO; | 5614 | dv->core_visible = GNUNET_NO; |
5531 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &dv->target); | 5615 | n = lookup_neighbour (&dv->target); |
5532 | if ((NULL != n) && (GNUNET_YES == n->core_visible)) | 5616 | if ((NULL != n) && (GNUNET_YES == n->core_visible)) |
5533 | return; /* no need to tell core, connection still up! */ | 5617 | return; /* no need to tell core, connection still up! */ |
5534 | cores_send_disconnect_info (&dv->target); | 5618 | cores_send_disconnect_info (&dv->target); |
@@ -5554,7 +5638,7 @@ activate_core_visible_dv_path (struct DistanceVectorHop *hop) | |||
5554 | dv->core_visible = GNUNET_YES; | 5638 | dv->core_visible = GNUNET_YES; |
5555 | dv->visibility_task = | 5639 | dv->visibility_task = |
5556 | GNUNET_SCHEDULER_add_at (hop->path_valid_until, &check_dv_path_down, dv); | 5640 | GNUNET_SCHEDULER_add_at (hop->path_valid_until, &check_dv_path_down, dv); |
5557 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &dv->target); | 5641 | n = lookup_neighbour (&dv->target); |
5558 | if ((NULL != n) && (GNUNET_YES == n->core_visible)) | 5642 | if ((NULL != n) && (GNUNET_YES == n->core_visible)) |
5559 | return; /* no need to tell core, connection already up! */ | 5643 | return; /* no need to tell core, connection already up! */ |
5560 | cores_send_connect_info (&dv->target, | 5644 | cores_send_connect_info (&dv->target, |
@@ -5608,7 +5692,7 @@ learn_dv_path (const struct GNUNET_PeerIdentity *path, | |||
5608 | return GNUNET_SYSERR; | 5692 | return GNUNET_SYSERR; |
5609 | } | 5693 | } |
5610 | GNUNET_assert (0 == GNUNET_memcmp (&GST_my_identity, &path[0])); | 5694 | GNUNET_assert (0 == GNUNET_memcmp (&GST_my_identity, &path[0])); |
5611 | next_hop = GNUNET_CONTAINER_multipeermap_get (neighbours, &path[1]); | 5695 | next_hop = lookup_neighbour (&path[1]); |
5612 | if (NULL == next_hop) | 5696 | if (NULL == next_hop) |
5613 | { | 5697 | { |
5614 | /* next hop must be a neighbour, otherwise this whole thing is useless! */ | 5698 | /* next hop must be a neighbour, otherwise this whole thing is useless! */ |
@@ -5616,7 +5700,7 @@ learn_dv_path (const struct GNUNET_PeerIdentity *path, | |||
5616 | return GNUNET_SYSERR; | 5700 | return GNUNET_SYSERR; |
5617 | } | 5701 | } |
5618 | for (unsigned int i = 2; i < path_len; i++) | 5702 | for (unsigned int i = 2; i < path_len; i++) |
5619 | if (NULL != GNUNET_CONTAINER_multipeermap_get (neighbours, &path[i])) | 5703 | if (NULL != lookup_neighbour (&path[i])) |
5620 | { | 5704 | { |
5621 | /* Useless path, we have a direct connection to some hop | 5705 | /* Useless path, we have a direct connection to some hop |
5622 | in the middle of the path, so this one doesn't even | 5706 | in the middle of the path, so this one doesn't even |
@@ -6388,7 +6472,7 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb) | |||
6388 | finish_cmc_handling (cmc); | 6472 | finish_cmc_handling (cmc); |
6389 | return; | 6473 | return; |
6390 | } | 6474 | } |
6391 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &hops[i]); | 6475 | n = lookup_neighbour (&hops[i]); |
6392 | if (NULL == n) | 6476 | if (NULL == n) |
6393 | continue; | 6477 | continue; |
6394 | forward_dv_box (n, | 6478 | forward_dv_box (n, |
@@ -6609,7 +6693,7 @@ find_queue (const struct GNUNET_PeerIdentity *pid, const char *address) | |||
6609 | { | 6693 | { |
6610 | struct Neighbour *n; | 6694 | struct Neighbour *n; |
6611 | 6695 | ||
6612 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, pid); | 6696 | n = lookup_neighbour (pid); |
6613 | if (NULL == n) | 6697 | if (NULL == n) |
6614 | return NULL; | 6698 | return NULL; |
6615 | for (struct Queue *pos = n->queue_head; NULL != pos; | 6699 | for (struct Queue *pos = n->queue_head; NULL != pos; |
@@ -7267,7 +7351,7 @@ transmit_on_queue (void *cls) | |||
7267 | (NULL != pm->head_frag /* fragments already exist, should | 7351 | (NULL != pm->head_frag /* fragments already exist, should |
7268 | respect that even if MTU is 0 for | 7352 | respect that even if MTU is 0 for |
7269 | this queue */) ) | 7353 | this queue */) ) |
7270 | s = fragment_message (queue, NULL /*FIXME! */, s); | 7354 | s = fragment_message (queue, pm->dvh, s); |
7271 | if (NULL == s) | 7355 | if (NULL == s) |
7272 | { | 7356 | { |
7273 | /* Fragmentation failed, try next message... */ | 7357 | /* Fragmentation failed, try next message... */ |
@@ -7275,7 +7359,8 @@ transmit_on_queue (void *cls) | |||
7275 | return; | 7359 | return; |
7276 | } | 7360 | } |
7277 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) | 7361 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) |
7278 | s = reliability_box_message (queue, NULL /* FIXME! */, s); | 7362 | // FIXME-OPTIMIZE: and if reliability was requested for 's' by core! |
7363 | s = reliability_box_message (queue, pm->dvh, s); | ||
7279 | if (NULL == s) | 7364 | if (NULL == s) |
7280 | { | 7365 | { |
7281 | /* Reliability boxing failed, try next message... */ | 7366 | /* Reliability boxing failed, try next message... */ |