diff options
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 380 | ||||
-rw-r--r-- | src/transport/transport.h | 4 | ||||
-rw-r--r-- | src/transport/transport_api2_core.c | 6 |
3 files changed, 345 insertions, 45 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 3365ea5d5..76d5265a8 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -428,31 +428,50 @@ struct TransportDVLearn | |||
428 | 428 | ||
429 | /** | 429 | /** |
430 | * Outer layer of an encapsulated message send over multiple hops. | 430 | * Outer layer of an encapsulated message send over multiple hops. |
431 | * The path given only includes the identities of the subsequent | ||
432 | * peers, i.e. it will be empty if we are the receiver. Each | ||
433 | * forwarding peer should scan the list from the end, and if it can, | ||
434 | * forward to the respective peer. The list should then be shortened | ||
435 | * by all the entries up to and including that peer. Each hop should | ||
436 | * also increment @e total_hops to allow the receiver to get a precise | ||
437 | * estimate on the number of hops the message travelled. Senders must | ||
438 | * provide a learned path that thus should work, but intermediaries | ||
439 | * know of a shortcut, they are allowed to send the message via that | ||
440 | * shortcut. | ||
441 | * | ||
442 | * If a peer finds itself still on the list, it must drop the message. | ||
431 | */ | 443 | */ |
432 | struct TransportDVBox | 444 | struct TransportDVBox |
433 | { | 445 | { |
434 | /** | 446 | /** |
435 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV | 447 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX |
436 | */ | 448 | */ |
437 | struct GNUNET_MessageHeader header; | 449 | struct GNUNET_MessageHeader header; |
438 | 450 | ||
439 | /** | 451 | /** |
452 | * Number of total hops this messages travelled. In NBO. | ||
453 | * @e origin sets this to zero, to be incremented at | ||
454 | * each hop. | ||
455 | */ | ||
456 | uint16_t total_hops GNUNET_PACKED; | ||
457 | |||
458 | /** | ||
440 | * Number of hops this messages includes. In NBO. | 459 | * Number of hops this messages includes. In NBO. |
441 | */ | 460 | */ |
442 | uint16_t num_hops GNUNET_PACKED; | 461 | uint16_t num_hops GNUNET_PACKED; |
443 | 462 | ||
444 | /** | 463 | /** |
445 | * Position of our peer in the sequence. | 464 | * Identity of the peer that originated the message. |
446 | * To be incremented at each hop. In NBO. | ||
447 | */ | 465 | */ |
448 | uint16_t current_hop GNUNET_PACKED; | 466 | struct GNUNET_PeerIdentity origin; |
449 | 467 | ||
450 | /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values; | 468 | /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values; |
451 | the first is the sender, the last the receiver; the current | 469 | excluding the @e origin and the current peer, the last must be |
452 | peer may be one in the middle. */ | 470 | the ultimate target; if @e num_hops is zero, the receiver of this |
471 | message is the ultimate target. */ | ||
453 | 472 | ||
454 | /* Followed by the actual message, which itself may be | 473 | /* Followed by the actual message, which itself may be |
455 | another box, but not a DV_LEARN message! */ | 474 | another box, but not a DV_LEARN or DV_BOX message! */ |
456 | }; | 475 | }; |
457 | 476 | ||
458 | 477 | ||
@@ -696,7 +715,60 @@ struct Neighbour | |||
696 | 715 | ||
697 | 716 | ||
698 | /** | 717 | /** |
699 | * Transmission request from CORE that is awaiting delivery. | 718 | * Types of different pending messages. |
719 | */ | ||
720 | enum PendingMessageType | ||
721 | { | ||
722 | |||
723 | /** | ||
724 | * Ordinary message received from the CORE service. | ||
725 | */ | ||
726 | PMT_CORE = 0, | ||
727 | |||
728 | /** | ||
729 | * Fragment box. | ||
730 | */ | ||
731 | PMT_FRAGMENT_BOX = 1, | ||
732 | |||
733 | /** | ||
734 | * Reliability box. | ||
735 | */ | ||
736 | PMT_RELIABILITY_BOX = 2, | ||
737 | |||
738 | /** | ||
739 | * Any type of acknowledgement. | ||
740 | */ | ||
741 | PMT_ACKNOWLEDGEMENT = 3 | ||
742 | |||
743 | |||
744 | }; | ||
745 | |||
746 | |||
747 | /** | ||
748 | * Transmission request that is awaiting delivery. The original | ||
749 | * transmission requests from CORE may be too big for some queues. | ||
750 | * In this case, a *tree* of fragments is created. At each | ||
751 | * level of the tree, fragments are kept in a DLL ordered by which | ||
752 | * fragment should be sent next (at the head). The tree is searched | ||
753 | * top-down, with the original message at the root. | ||
754 | * | ||
755 | * To select a node for transmission, first it is checked if the | ||
756 | * current node's message fits with the MTU. If it does not, we | ||
757 | * either calculate the next fragment (based on @e frag_off) from the | ||
758 | * current node, or, if all fragments have already been created, | ||
759 | * descend to the @e head_frag. Even though the node was already | ||
760 | * fragmented, the fragment may be too big if the fragment was | ||
761 | * generated for a queue with a larger MTU. In this case, the node | ||
762 | * may be fragmented again, thus creating a tree. | ||
763 | * | ||
764 | * When acknowledgements for fragments are received, the tree | ||
765 | * must be pruned, removing those parts that were already | ||
766 | * acknowledged. When fragments are sent over a reliable | ||
767 | * channel, they can be immediately removed. | ||
768 | * | ||
769 | * If a message is ever fragmented, then the original "full" message | ||
770 | * is never again transmitted (even if it fits below the MTU), and | ||
771 | * only (remaining) fragments are sent. | ||
700 | */ | 772 | */ |
701 | struct PendingMessage | 773 | struct PendingMessage |
702 | { | 774 | { |
@@ -711,26 +783,51 @@ struct PendingMessage | |||
711 | struct PendingMessage *prev_neighbour; | 783 | struct PendingMessage *prev_neighbour; |
712 | 784 | ||
713 | /** | 785 | /** |
714 | * Kept in a MDLL of messages from this @a client. | 786 | * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE) |
715 | */ | 787 | */ |
716 | struct PendingMessage *next_client; | 788 | struct PendingMessage *next_client; |
717 | 789 | ||
718 | /** | 790 | /** |
719 | * Kept in a MDLL of messages from this @a client. | 791 | * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE) |
720 | */ | 792 | */ |
721 | struct PendingMessage *prev_client; | 793 | struct PendingMessage *prev_client; |
722 | 794 | ||
723 | /** | 795 | /** |
796 | * Kept in a MDLL of messages from this @a cpm (if @e pmt is #PMT_FRAGMENT_BOx) | ||
797 | */ | ||
798 | struct PendingMessage *next_frag; | ||
799 | |||
800 | /** | ||
801 | * Kept in a MDLL of messages from this @a cpm (if @e pmt is #PMT_FRAGMENT_BOX) | ||
802 | */ | ||
803 | struct PendingMessage *prev_frag; | ||
804 | |||
805 | /** | ||
724 | * Target of the request. | 806 | * Target of the request. |
725 | */ | 807 | */ |
726 | struct Neighbour *target; | 808 | struct Neighbour *target; |
727 | 809 | ||
728 | /** | 810 | /** |
729 | * Client that issued the transmission request. | 811 | * Client that issued the transmission request, if @e pmt is #PMT_CORE. |
730 | */ | 812 | */ |
731 | struct TransportClient *client; | 813 | struct TransportClient *client; |
814 | |||
815 | /** | ||
816 | * Head of a MDLL of fragments created for this core message. | ||
817 | */ | ||
818 | struct PendingMessage *head_frag; | ||
819 | |||
820 | /** | ||
821 | * Tail of a MDLL of fragments created for this core message. | ||
822 | */ | ||
823 | struct PendingMessage *tail_frag; | ||
732 | 824 | ||
733 | /** | 825 | /** |
826 | * Our parent in the fragmentation tree. | ||
827 | */ | ||
828 | struct PendingMessage *frag_parent; | ||
829 | |||
830 | /** | ||
734 | * At what time should we give up on the transmission (and no longer retry)? | 831 | * At what time should we give up on the transmission (and no longer retry)? |
735 | */ | 832 | */ |
736 | struct GNUNET_TIME_Absolute timeout; | 833 | struct GNUNET_TIME_Absolute timeout; |
@@ -739,12 +836,38 @@ struct PendingMessage | |||
739 | * What is the earliest time for us to retry transmission of this message? | 836 | * What is the earliest time for us to retry transmission of this message? |
740 | */ | 837 | */ |
741 | struct GNUNET_TIME_Absolute next_attempt; | 838 | struct GNUNET_TIME_Absolute next_attempt; |
839 | |||
840 | /** | ||
841 | * UUID to use for this message (used for reassembly of fragments, only | ||
842 | * initialized if @e msg_uuid_set is #GNUNET_YES). | ||
843 | */ | ||
844 | struct GNUNET_ShortHashCode msg_uuid; | ||
845 | |||
846 | /** | ||
847 | * Counter incremented per generated fragment. | ||
848 | */ | ||
849 | uint32_t frag_uuidgen; | ||
742 | 850 | ||
743 | /** | 851 | /** |
852 | * Type of the pending message. | ||
853 | */ | ||
854 | enum PendingMessageType pmt; | ||
855 | |||
856 | /** | ||
744 | * Size of the original message. | 857 | * Size of the original message. |
745 | */ | 858 | */ |
746 | uint32_t bytes_msg; | 859 | uint16_t bytes_msg; |
747 | 860 | ||
861 | /** | ||
862 | * Offset at which we should generate the next fragment. | ||
863 | */ | ||
864 | uint16_t frag_off; | ||
865 | |||
866 | /** | ||
867 | * #GNUNET_YES once @e msg_uuid was initialized | ||
868 | */ | ||
869 | int16_t msg_uuid_set; | ||
870 | |||
748 | /* Followed by @e bytes_msg to transmit */ | 871 | /* Followed by @e bytes_msg to transmit */ |
749 | }; | 872 | }; |
750 | 873 | ||
@@ -1483,6 +1606,28 @@ check_client_send (void *cls, | |||
1483 | 1606 | ||
1484 | 1607 | ||
1485 | /** | 1608 | /** |
1609 | * Free fragment tree below @e root, excluding @e root itself. | ||
1610 | * | ||
1611 | * @param root root of the tree to free | ||
1612 | */ | ||
1613 | static void | ||
1614 | free_fragment_tree (struct PendingMessage *root) | ||
1615 | { | ||
1616 | struct PendingMessage *frag; | ||
1617 | |||
1618 | while (NULL != (frag = root->head_frag)) | ||
1619 | { | ||
1620 | free_fragment_tree (frag); | ||
1621 | GNUNET_CONTAINER_MDLL_remove (frag, | ||
1622 | root->head_frag, | ||
1623 | root->tail_frag, | ||
1624 | frag); | ||
1625 | GNUNET_free (frag); | ||
1626 | } | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | /** | ||
1486 | * Send a response to the @a pm that we have processed a | 1631 | * Send a response to the @a pm that we have processed a |
1487 | * "send" request with status @a success. We | 1632 | * "send" request with status @a success. We |
1488 | * transmitted @a bytes_physical on the actual wire. | 1633 | * transmitted @a bytes_physical on the actual wire. |
@@ -1509,7 +1654,7 @@ client_send_response (struct PendingMessage *pm, | |||
1509 | env = GNUNET_MQ_msg (som, | 1654 | env = GNUNET_MQ_msg (som, |
1510 | GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); | 1655 | GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); |
1511 | som->success = htonl ((uint32_t) success); | 1656 | som->success = htonl ((uint32_t) success); |
1512 | som->bytes_msg = htonl (pm->bytes_msg); | 1657 | som->bytes_msg = htons (pm->bytes_msg); |
1513 | som->bytes_physical = htonl (bytes_physical); | 1658 | som->bytes_physical = htonl (bytes_physical); |
1514 | som->peer = target->pid; | 1659 | som->peer = target->pid; |
1515 | GNUNET_MQ_send (tc->mq, | 1660 | GNUNET_MQ_send (tc->mq, |
@@ -1523,6 +1668,7 @@ client_send_response (struct PendingMessage *pm, | |||
1523 | target->pending_msg_head, | 1668 | target->pending_msg_head, |
1524 | target->pending_msg_tail, | 1669 | target->pending_msg_tail, |
1525 | pm); | 1670 | pm); |
1671 | free_fragment_tree (pm); | ||
1526 | GNUNET_free (pm); | 1672 | GNUNET_free (pm); |
1527 | } | 1673 | } |
1528 | 1674 | ||
@@ -2024,18 +2170,98 @@ static struct PendingMessage * | |||
2024 | fragment_message (struct PendingMessage *pm, | 2170 | fragment_message (struct PendingMessage *pm, |
2025 | uint16_t mtu) | 2171 | uint16_t mtu) |
2026 | { | 2172 | { |
2027 | if (0) | 2173 | struct PendingMessage *ff; |
2174 | |||
2175 | if (GNUNET_NO == pm->msg_uuid_set) | ||
2028 | { | 2176 | { |
2029 | /* mtu too small */ | 2177 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, |
2030 | // FIMXE: bitch | 2178 | &pm->msg_uuid, |
2031 | client_send_response (pm, | 2179 | sizeof (pm->msg_uuid)); |
2032 | GNUNET_NO, | 2180 | pm->msg_uuid_set = GNUNET_YES; |
2033 | 0); | 2181 | } |
2034 | return NULL; | 2182 | |
2183 | /* This invariant is established in #handle_add_queue_message() */ | ||
2184 | GNUNET_assert (mtu > sizeof (struct TransportFragmentBox)); | ||
2185 | |||
2186 | /* select fragment for transmission, descending the tree if it has | ||
2187 | been expanded until we are at a leaf or at a fragment that is small enough */ | ||
2188 | ff = pm; | ||
2189 | while ( ( (ff->bytes_msg > mtu) || | ||
2190 | (pm == ff) ) && | ||
2191 | (ff->frag_off == ff->bytes_msg) && | ||
2192 | (NULL != ff->head_frag) ) | ||
2193 | { | ||
2194 | ff = ff->head_frag; /* descent into fragmented fragments */ | ||
2035 | } | 2195 | } |
2036 | 2196 | ||
2037 | /* FIXME: return first fragment here! */ | 2197 | if ( ( (ff->bytes_msg > mtu) || |
2038 | return NULL; | 2198 | (pm == ff) ) && |
2199 | (pm->frag_off < pm->bytes_msg) ) | ||
2200 | { | ||
2201 | /* Did not yet calculate all fragments, calculate next fragment */ | ||
2202 | struct PendingMessage *frag; | ||
2203 | struct TransportFragmentBox tfb; | ||
2204 | const char *orig; | ||
2205 | char *msg; | ||
2206 | uint16_t fragmax; | ||
2207 | uint16_t fragsize; | ||
2208 | uint16_t msize; | ||
2209 | uint16_t xoff = 0; | ||
2210 | |||
2211 | orig = (const char *) &ff[1]; | ||
2212 | msize = ff->bytes_msg; | ||
2213 | if (pm != ff) | ||
2214 | { | ||
2215 | const struct TransportFragmentBox *tfbo; | ||
2216 | |||
2217 | tfbo = (const struct TransportFragmentBox *) orig; | ||
2218 | orig += sizeof (struct TransportFragmentBox); | ||
2219 | msize -= sizeof (struct TransportFragmentBox); | ||
2220 | xoff = ntohs (tfbo->frag_off); | ||
2221 | } | ||
2222 | fragmax = mtu - sizeof (struct TransportFragmentBox); | ||
2223 | fragsize = GNUNET_MIN (msize - ff->frag_off, | ||
2224 | fragmax); | ||
2225 | frag = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
2226 | sizeof (struct TransportFragmentBox) + | ||
2227 | fragsize); | ||
2228 | frag->target = pm->target; | ||
2229 | frag->frag_parent = ff; | ||
2230 | frag->timeout = pm->timeout; | ||
2231 | frag->bytes_msg = sizeof (struct TransportFragmentBox) + fragsize; | ||
2232 | frag->pmt = PMT_FRAGMENT_BOX; | ||
2233 | msg = (char *) &frag[1]; | ||
2234 | tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT); | ||
2235 | tfb.header.size = htons (sizeof (struct TransportFragmentBox) + | ||
2236 | fragsize); | ||
2237 | tfb.frag_uuid = htonl (pm->frag_uuidgen++); | ||
2238 | tfb.msg_uuid = pm->msg_uuid; | ||
2239 | tfb.frag_off = htons (ff->frag_off + xoff); | ||
2240 | tfb.msg_size = htons (pm->bytes_msg); | ||
2241 | memcpy (msg, | ||
2242 | &tfb, | ||
2243 | sizeof (tfb)); | ||
2244 | memcpy (&msg[sizeof (tfb)], | ||
2245 | &orig[ff->frag_off], | ||
2246 | fragsize); | ||
2247 | GNUNET_CONTAINER_MDLL_insert (frag, | ||
2248 | ff->head_frag, | ||
2249 | ff->tail_frag, | ||
2250 | frag); | ||
2251 | ff->frag_off += fragsize; | ||
2252 | ff = frag; | ||
2253 | } | ||
2254 | |||
2255 | /* Move head to the tail and return it */ | ||
2256 | GNUNET_CONTAINER_MDLL_remove (frag, | ||
2257 | ff->frag_parent->head_frag, | ||
2258 | ff->frag_parent->tail_frag, | ||
2259 | ff); | ||
2260 | GNUNET_CONTAINER_MDLL_insert_tail (frag, | ||
2261 | ff->frag_parent->head_frag, | ||
2262 | ff->frag_parent->tail_frag, | ||
2263 | ff); | ||
2264 | return ff; | ||
2039 | } | 2265 | } |
2040 | 2266 | ||
2041 | 2267 | ||
@@ -2052,11 +2278,12 @@ fragment_message (struct PendingMessage *pm, | |||
2052 | static struct PendingMessage * | 2278 | static struct PendingMessage * |
2053 | reliability_box_message (struct PendingMessage *pm) | 2279 | reliability_box_message (struct PendingMessage *pm) |
2054 | { | 2280 | { |
2055 | if (0) // FIXME | 2281 | if (PMT_CORE != pm->pmt) |
2056 | { | 2282 | { |
2057 | /* already fragmented or reliability boxed, do nothing */ | 2283 | /* already fragmented or reliability boxed, or control message: do nothing */ |
2058 | return pm; | 2284 | return pm; |
2059 | } | 2285 | } |
2286 | |||
2060 | if (0) // FIXME | 2287 | if (0) // FIXME |
2061 | { | 2288 | { |
2062 | /* failed hard */ | 2289 | /* failed hard */ |
@@ -2086,6 +2313,7 @@ transmit_on_queue (void *cls) | |||
2086 | struct GNUNET_ATS_Session *queue = cls; | 2313 | struct GNUNET_ATS_Session *queue = cls; |
2087 | struct Neighbour *n = queue->neighbour; | 2314 | struct Neighbour *n = queue->neighbour; |
2088 | struct PendingMessage *pm; | 2315 | struct PendingMessage *pm; |
2316 | struct PendingMessage *s; | ||
2089 | uint32_t overhead; | 2317 | uint32_t overhead; |
2090 | 2318 | ||
2091 | queue->transmit_task = NULL; | 2319 | queue->transmit_task = NULL; |
@@ -2100,38 +2328,102 @@ transmit_on_queue (void *cls) | |||
2100 | overhead = 0; | 2328 | overhead = 0; |
2101 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) | 2329 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) |
2102 | overhead += sizeof (struct TransportReliabilityBox); | 2330 | overhead += sizeof (struct TransportReliabilityBox); |
2103 | if ( (0 != queue->mtu) && | 2331 | s = pm; |
2104 | (pm->bytes_msg + overhead > queue->mtu) ) | 2332 | if ( ( (0 != queue->mtu) && |
2105 | pm = fragment_message (pm, | 2333 | (pm->bytes_msg + overhead > queue->mtu) ) || |
2106 | queue->mtu); | 2334 | (NULL != pm->head_frag /* fragments already exist, should |
2107 | if (NULL == pm) | 2335 | respect that even if MTU is 0 for |
2336 | this queue */) ) | ||
2337 | s = fragment_message (s, | ||
2338 | (0 == queue->mtu) | ||
2339 | ? UINT16_MAX /* no real maximum */ | ||
2340 | : queue->mtu); | ||
2341 | if (NULL == s) | ||
2108 | { | 2342 | { |
2109 | /* Fragmentation failed, try next message... */ | 2343 | /* Fragmentation failed, try next message... */ |
2110 | schedule_transmit_on_queue (queue); | 2344 | schedule_transmit_on_queue (queue); |
2111 | return; | 2345 | return; |
2112 | } | 2346 | } |
2113 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) | 2347 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) |
2114 | pm = reliability_box_message (pm); | 2348 | s = reliability_box_message (s); |
2115 | if (NULL == pm) | 2349 | if (NULL == s) |
2116 | { | 2350 | { |
2117 | /* Reliability boxing failed, try next message... */ | 2351 | /* Reliability boxing failed, try next message... */ |
2118 | schedule_transmit_on_queue (queue); | 2352 | schedule_transmit_on_queue (queue); |
2119 | return; | 2353 | return; |
2120 | } | 2354 | } |
2121 | 2355 | ||
2122 | // FIXME: actually do transmission | 2356 | // FIXME: actually give 's' to communicator for transmission here! |
2123 | 2357 | ||
2124 | // FIXME: unless 'pm' is an ACK or control, move 'pm' back in the | 2358 | // FIXME: do something similar to the logic below |
2125 | // transmission queue (simplistic: to the end, better: with position | 2359 | // in defragmentation / reliability ACK handling! |
2126 | // depending on type, timeout, etc.) | 2360 | |
2127 | 2361 | /* Check if this transmission somehow conclusively finished handing 'pm' | |
2128 | // FIXME: do something similar in defragmentation / reliability ACK handling! | 2362 | even without any explicit ACKs */ |
2129 | if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) | 2363 | if ( (PMT_CORE == s->pmt) && |
2364 | (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) ) | ||
2130 | { | 2365 | { |
2366 | /* Full message sent, and over reliabile channel */ | ||
2131 | client_send_response (pm, | 2367 | client_send_response (pm, |
2132 | GNUNET_YES, | 2368 | GNUNET_YES, |
2133 | pm->bytes_msg); | 2369 | pm->bytes_msg); |
2134 | } | 2370 | } |
2371 | else if ( (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) && | ||
2372 | (PMT_FRAGMENT_BOX == s->pmt) ) | ||
2373 | { | ||
2374 | struct PendingMessage *pos; | ||
2375 | |||
2376 | /* Fragment sent over reliabile channel */ | ||
2377 | free_fragment_tree (s); | ||
2378 | pos = s->frag_parent; | ||
2379 | GNUNET_CONTAINER_MDLL_remove (frag, | ||
2380 | pos->head_frag, | ||
2381 | pos->tail_frag, | ||
2382 | s); | ||
2383 | GNUNET_free (s); | ||
2384 | /* check if subtree is done */ | ||
2385 | while ( (NULL == pos->head_frag) && | ||
2386 | (pos->frag_off == pos->bytes_msg) && | ||
2387 | (pos != pm) ) | ||
2388 | { | ||
2389 | s = pos; | ||
2390 | pos = s->frag_parent; | ||
2391 | GNUNET_CONTAINER_MDLL_remove (frag, | ||
2392 | pos->head_frag, | ||
2393 | pos->tail_frag, | ||
2394 | s); | ||
2395 | GNUNET_free (s); | ||
2396 | } | ||
2397 | |||
2398 | /* Was this the last applicable fragmment? */ | ||
2399 | if ( (NULL == pm->head_frag) && | ||
2400 | (pm->frag_off == pm->bytes_msg) ) | ||
2401 | client_send_response (pm, | ||
2402 | GNUNET_YES, | ||
2403 | pm->bytes_msg /* FIXME: calculate and add overheads! */); | ||
2404 | } | ||
2405 | else if (PMT_CORE != pm->pmt) | ||
2406 | { | ||
2407 | /* This was an acknowledgement of some type, always free */ | ||
2408 | |||
2409 | struct Neighbour *neighbour = pm->target; | ||
2410 | GNUNET_CONTAINER_MDLL_remove (neighbour, | ||
2411 | neighbour->pending_msg_head, | ||
2412 | neighbour->pending_msg_tail, | ||
2413 | pm); | ||
2414 | GNUNET_free (pm); | ||
2415 | } | ||
2416 | else | ||
2417 | { | ||
2418 | /* message not finished, waiting for acknowledgement */ | ||
2419 | // FIXME: update time by which we might retransmit 's' based on | ||
2420 | // queue characteristics (i.e. RTT) | ||
2421 | |||
2422 | // FIXME: move 'pm' back in the transmission queue (simplistic: to | ||
2423 | // the end, better: with position depending on type, timeout, | ||
2424 | // etc.) | ||
2425 | } | ||
2426 | |||
2135 | /* finally, re-schedule self */ | 2427 | /* finally, re-schedule self */ |
2136 | schedule_transmit_on_queue (queue); | 2428 | schedule_transmit_on_queue (queue); |
2137 | } | 2429 | } |
@@ -2217,6 +2509,14 @@ handle_add_queue_message (void *cls, | |||
2217 | const char *addr; | 2509 | const char *addr; |
2218 | uint16_t addr_len; | 2510 | uint16_t addr_len; |
2219 | 2511 | ||
2512 | if (ntohl (aqm->mtu) <= sizeof (struct TransportFragmentBox)) | ||
2513 | { | ||
2514 | /* MTU so small as to be useless for transmissions, | ||
2515 | required for #fragment_message()! */ | ||
2516 | GNUNET_break_op (0); | ||
2517 | GNUNET_SERVICE_client_drop (tc->client); | ||
2518 | return; | ||
2519 | } | ||
2220 | neighbour = lookup_neighbour (&aqm->receiver); | 2520 | neighbour = lookup_neighbour (&aqm->receiver); |
2221 | if (NULL == neighbour) | 2521 | if (NULL == neighbour) |
2222 | { | 2522 | { |
diff --git a/src/transport/transport.h b/src/transport/transport.h index 00d475e2b..6b1a2cac1 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h | |||
@@ -223,12 +223,12 @@ struct SendOkMessage | |||
223 | * in either case, it is now OK for this client to | 223 | * in either case, it is now OK for this client to |
224 | * send us another message for the given peer. | 224 | * send us another message for the given peer. |
225 | */ | 225 | */ |
226 | uint32_t success GNUNET_PACKED; | 226 | uint16_t success GNUNET_PACKED; |
227 | 227 | ||
228 | /** | 228 | /** |
229 | * Size of message sent | 229 | * Size of message sent |
230 | */ | 230 | */ |
231 | uint32_t bytes_msg GNUNET_PACKED; | 231 | uint16_t bytes_msg GNUNET_PACKED; |
232 | 232 | ||
233 | /** | 233 | /** |
234 | * Size of message sent over wire | 234 | * Size of message sent over wire |
diff --git a/src/transport/transport_api2_core.c b/src/transport/transport_api2_core.c index 607f26777..f00d00a44 100644 --- a/src/transport/transport_api2_core.c +++ b/src/transport/transport_api2_core.c | |||
@@ -600,15 +600,15 @@ handle_send_ok (void *cls, | |||
600 | { | 600 | { |
601 | struct GNUNET_TRANSPORT_CoreHandle *h = cls; | 601 | struct GNUNET_TRANSPORT_CoreHandle *h = cls; |
602 | struct Neighbour *n; | 602 | struct Neighbour *n; |
603 | uint32_t bytes_msg; | 603 | uint16_t bytes_msg; |
604 | uint32_t bytes_physical; | 604 | uint32_t bytes_physical; |
605 | 605 | ||
606 | bytes_msg = ntohl (okm->bytes_msg); | 606 | bytes_msg = ntohs (okm->bytes_msg); |
607 | bytes_physical = ntohl (okm->bytes_physical); | 607 | bytes_physical = ntohl (okm->bytes_physical); |
608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 608 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
609 | "Receiving SEND_OK message, transmission to %s %s.\n", | 609 | "Receiving SEND_OK message, transmission to %s %s.\n", |
610 | GNUNET_i2s (&okm->peer), | 610 | GNUNET_i2s (&okm->peer), |
611 | (GNUNET_OK == ntohl (okm->success)) | 611 | (GNUNET_OK == ntohs (okm->success)) |
612 | ? "succeeded" | 612 | ? "succeeded" |
613 | : "failed"); | 613 | : "failed"); |
614 | n = neighbour_find (h, | 614 | n = neighbour_find (h, |