diff options
-rw-r--r-- | src/include/gnunet_protocols.h | 10 | ||||
-rw-r--r-- | src/include/gnunet_signatures.h | 5 | ||||
-rw-r--r-- | src/include/gnunet_transport_communication_service.h | 6 | ||||
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 309 |
4 files changed, 249 insertions, 81 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 409356d77..793430184 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -3234,6 +3234,16 @@ extern "C" | |||
3234 | #define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH 1452 | 3234 | #define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH 1452 |
3235 | 3235 | ||
3236 | /** | 3236 | /** |
3237 | * UDP KX acknowledgement. | ||
3238 | */ | ||
3239 | #define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK 1460 | ||
3240 | |||
3241 | /** | ||
3242 | * UDP communicator padding. | ||
3243 | */ | ||
3244 | #define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD 1461 | ||
3245 | |||
3246 | /** | ||
3237 | * Next available: 1500 | 3247 | * Next available: 1500 |
3238 | */ | 3248 | */ |
3239 | 3249 | ||
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h index 4f4d546ff..289ea9860 100644 --- a/src/include/gnunet_signatures.h +++ b/src/include/gnunet_signatures.h | |||
@@ -212,6 +212,11 @@ extern "C" | |||
212 | */ | 212 | */ |
213 | #define GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY 32 | 213 | #define GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY 32 |
214 | 214 | ||
215 | /** | ||
216 | * Signature used by UDP communicator handshake, | ||
217 | */ | ||
218 | #define GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE 33 | ||
219 | |||
215 | #if 0 /* keep Emacsens' auto-indent happy */ | 220 | #if 0 /* keep Emacsens' auto-indent happy */ |
216 | { | 221 | { |
217 | #endif | 222 | #endif |
diff --git a/src/include/gnunet_transport_communication_service.h b/src/include/gnunet_transport_communication_service.h index 1cfc82540..b69cbbe06 100644 --- a/src/include/gnunet_transport_communication_service.h +++ b/src/include/gnunet_transport_communication_service.h | |||
@@ -105,9 +105,9 @@ enum GNUNET_TRANSPORT_CommunicatorCharacteristics { | |||
105 | 105 | ||
106 | 106 | ||
107 | /** | 107 | /** |
108 | * Function called when the transport service has received an | 108 | * Function called when the transport service has received a |
109 | * acknowledgement for this communicator (!) via a different return | 109 | * backchannel message for this communicator (!) via a different |
110 | * path. | 110 | * return path. |
111 | * | 111 | * |
112 | * Typically used to receive messages of type | 112 | * Typically used to receive messages of type |
113 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS or | 113 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS or |
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 8265c4970..f307f6052 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -24,11 +24,7 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * TODO: | 26 | * TODO: |
27 | * - main sending logic | 27 | * - main BOXed sending logic |
28 | * - actual generation of ACKs (-> integrate with sending logic!) | ||
29 | * (specifically, ACKs should go as backchannel, let TNG | ||
30 | * decide how to send!) | ||
31 | * - handle ACKs from backchannel! | ||
32 | * - figure out what to do with MTU: 1280 for IPv6 is obvious; | 28 | * - figure out what to do with MTU: 1280 for IPv6 is obvious; |
33 | * what for IPv4? 1500? Also, consider differences in | 29 | * what for IPv4? 1500? Also, consider differences in |
34 | * headers for with/without box: need to give MIN of both | 30 | * headers for with/without box: need to give MIN of both |
@@ -70,6 +66,36 @@ | |||
70 | #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES | 66 | #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES |
71 | 67 | ||
72 | /** | 68 | /** |
69 | * If we fall below this number of available KCNs, | ||
70 | * we generate additional ACKs until we reach | ||
71 | * #KCN_TARGET. | ||
72 | * Should be large enough that we don't generate ACKs all | ||
73 | * the time and still have enough time for the ACK to | ||
74 | * arrive before the sender runs out. So really this | ||
75 | * should ideally be based on the RTT. | ||
76 | */ | ||
77 | #define KCN_THRESHOLD 92 | ||
78 | |||
79 | /** | ||
80 | * How many KCNs do we keep around *after* we hit | ||
81 | * the #KCN_THRESHOLD? Should be larger than | ||
82 | * #KCN_THRESHOLD so we do not generate just one | ||
83 | * ACK at the time. | ||
84 | */ | ||
85 | #define KCN_TARGET 128 | ||
86 | |||
87 | /** | ||
88 | * What is the maximum delta between KCN sequence numbers | ||
89 | * that we allow. Used to expire 'ancient' KCNs that likely | ||
90 | * were dropped by the network. Must be larger than | ||
91 | * KCN_TARGET (otherwise we generate new KCNs all the time), | ||
92 | * but not too large (otherwise packet loss may cause | ||
93 | * sender to fall back to KX needlessly when sender runs | ||
94 | * out of ACK'ed KCNs due to losses). | ||
95 | */ | ||
96 | #define MAX_SQN_DELTA 160 | ||
97 | |||
98 | /** | ||
73 | * How often do we rekey based on number of bytes transmitted? | 99 | * How often do we rekey based on number of bytes transmitted? |
74 | * (additionally randomized). | 100 | * (additionally randomized). |
75 | */ | 101 | */ |
@@ -342,6 +368,11 @@ struct SharedSecret | |||
342 | * use this key? | 368 | * use this key? |
343 | */ | 369 | */ |
344 | uint32_t sequence_allowed; | 370 | uint32_t sequence_allowed; |
371 | |||
372 | /** | ||
373 | * Number of active KCN entries. | ||
374 | */ | ||
375 | unsigned int active_kce_count; | ||
345 | }; | 376 | }; |
346 | 377 | ||
347 | 378 | ||
@@ -581,6 +612,7 @@ kce_destroy (struct KeyCacheEntry *kce) | |||
581 | { | 612 | { |
582 | struct SharedSecret *ss = kce->ss; | 613 | struct SharedSecret *ss = kce->ss; |
583 | 614 | ||
615 | ss->active_kce_count--; | ||
584 | GNUNET_CONTAINER_DLL_remove (ss->kce_head, | 616 | GNUNET_CONTAINER_DLL_remove (ss->kce_head, |
585 | ss->kce_tail, | 617 | ss->kce_tail, |
586 | kce); | 618 | kce); |
@@ -642,6 +674,7 @@ kce_generate (struct SharedSecret *ss, | |||
642 | GNUNET_CONTAINER_DLL_insert (ss->kce_head, | 674 | GNUNET_CONTAINER_DLL_insert (ss->kce_head, |
643 | ss->kce_tail, | 675 | ss->kce_tail, |
644 | kce); | 676 | kce); |
677 | ss->active_kce_count++; | ||
645 | (void) GNUNET_CONTAINER_multishortmap_put (key_cache, | 678 | (void) GNUNET_CONTAINER_multishortmap_put (key_cache, |
646 | &kce->kid, | 679 | &kce->kid, |
647 | kce, | 680 | kce, |
@@ -1048,7 +1081,52 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, | |||
1048 | GNUNET_NO); | 1081 | GNUNET_NO); |
1049 | return ss; | 1082 | return ss; |
1050 | } | 1083 | } |
1051 | 1084 | ||
1085 | |||
1086 | /** | ||
1087 | * We received an ACK for @a pid. Check if it is for | ||
1088 | * the receiver in @a value and if so, handle it and | ||
1089 | * return #GNUNET_NO. Otherwise, return #GNUNET_YES. | ||
1090 | * | ||
1091 | * @param cls a `const struct UDPAck` | ||
1092 | * @param pid peer the ACK is from | ||
1093 | * @param value a `struct ReceiverAddress` | ||
1094 | * @return #GNUNET_YES to continue to iterate | ||
1095 | */ | ||
1096 | static int | ||
1097 | handle_ack (void *cls, | ||
1098 | const struct GNUNET_PeerIdentity *pid, | ||
1099 | void *value) | ||
1100 | { | ||
1101 | const struct UDPAck *ack = cls; | ||
1102 | struct ReceiverAddress *receiver = value; | ||
1103 | |||
1104 | (void) pid; | ||
1105 | for (struct SharedSecret *ss = receiver->ss_head; | ||
1106 | NULL != ss; | ||
1107 | ss = ss->next) | ||
1108 | { | ||
1109 | if (0 == memcmp (&ack->cmac, | ||
1110 | &ss->cmac, | ||
1111 | sizeof (struct GNUNET_HashCode))) | ||
1112 | { | ||
1113 | ss->sequence_allowed = GNUNET_MAX (ss->sequence_allowed, | ||
1114 | ntohl (ack->sequence_max)); | ||
1115 | /* move ss to head to avoid discarding it anytime soon! */ | ||
1116 | GNUNET_CONTAINER_DLL_remove (sender->ss_head, | ||
1117 | sender->ss_tail, | ||
1118 | ss); | ||
1119 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, | ||
1120 | sender->ss_tail, | ||
1121 | ss); | ||
1122 | /* FIXME: if this changed sequence_allowed, | ||
1123 | update MTU / MQ of 'receiver'! */ | ||
1124 | return GNUNET_NO; | ||
1125 | } | ||
1126 | } | ||
1127 | return GNUNET_YES; | ||
1128 | } | ||
1129 | |||
1052 | 1130 | ||
1053 | /** | 1131 | /** |
1054 | * Test if we have received a valid message in plaintext. | 1132 | * Test if we have received a valid message in plaintext. |
@@ -1078,26 +1156,10 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1078 | { | 1156 | { |
1079 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: | 1157 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: |
1080 | /* lookup master secret by 'cmac', then update sequence_max */ | 1158 | /* lookup master secret by 'cmac', then update sequence_max */ |
1081 | for (struct SharedSecret *ss = sender->ss_head; | 1159 | GNUNET_CONTAINER_multihashmap_get_multiple (receivers, |
1082 | NULL != ss; | 1160 | &sender->target, |
1083 | ss = ss->next) | 1161 | &handle_ack, |
1084 | { | 1162 | (void *) ack); |
1085 | if (0 == memcmp (&ack->cmac, | ||
1086 | &ss->cmac, | ||
1087 | sizeof (ss->cmac))) | ||
1088 | { | ||
1089 | ss->sequence_allowed = GNUNET_MAX (ss->sequence_allowed, | ||
1090 | ntohl (ack->sequence_max)); | ||
1091 | /* move ss to head to avoid discarding it anytime soon! */ | ||
1092 | GNUNET_CONTAINER_DLL_remove (sender->ss_head, | ||
1093 | sender->ss_tail, | ||
1094 | ss); | ||
1095 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, | ||
1096 | sender->ss_tail, | ||
1097 | ss); | ||
1098 | break; | ||
1099 | } | ||
1100 | } | ||
1101 | /* There could be more messages after the ACK, handle those as well */ | 1163 | /* There could be more messages after the ACK, handle those as well */ |
1102 | buf += ntohs (hdr->size); | 1164 | buf += ntohs (hdr->size); |
1103 | buf_size -= ntohs (hdr->size); | 1165 | buf_size -= ntohs (hdr->size); |
@@ -1105,6 +1167,9 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1105 | buf, | 1167 | buf, |
1106 | buf_size); | 1168 | buf_size); |
1107 | break; | 1169 | break; |
1170 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD: | ||
1171 | /* skip padding */ | ||
1172 | break; | ||
1108 | default: | 1173 | default: |
1109 | pass_plaintext_to_core (sender, | 1174 | pass_plaintext_to_core (sender, |
1110 | buf, | 1175 | buf, |
@@ -1118,15 +1183,33 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1118 | * the sender an `struct UDPAck` at the next opportunity to allow the | 1183 | * the sender an `struct UDPAck` at the next opportunity to allow the |
1119 | * sender to use @a ss longer (assuming we did not yet already | 1184 | * sender to use @a ss longer (assuming we did not yet already |
1120 | * recently). | 1185 | * recently). |
1186 | * | ||
1187 | * @param ss shared secret to generate ACKs for | ||
1121 | */ | 1188 | */ |
1122 | static void | 1189 | static void |
1123 | consider_ss_ack (struct SharedSecret *ss) | 1190 | consider_ss_ack (struct SharedSecret *ss) |
1124 | { | 1191 | { |
1125 | GNUNET_assert (NULL != ss->sender); | 1192 | GNUNET_assert (NULL != ss->sender); |
1126 | for (uint32_t i=1;i<0 /* FIXME: ack-based! */;i++) | 1193 | /* drop ancient KeyCacheEntries */ |
1127 | kce_generate (ss, | 1194 | while ( (NULL != ss->kce_head) && |
1128 | i); | 1195 | (MAX_SQN_DELTA < ss->kce_head->sequence_number - ss->kce_tail->sequence_number) ) |
1129 | // FIXME: consider generating ACK and more KCEs for ss! | 1196 | kce_destroy (ss->kce_tail); |
1197 | if (ss->active_kce_count < KCN_THRESHOLD) | ||
1198 | { | ||
1199 | struct UDPAck ack; | ||
1200 | |||
1201 | while (ss->active_kce_count < KCN_TARGET) | ||
1202 | kce_generate (ss, | ||
1203 | ++ss->sequence_used); | ||
1204 | ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); | ||
1205 | ack.header.size = htons (sizeof (ack)); | ||
1206 | ack.sequence_max = htonl (ss->sequence_max); | ||
1207 | ack.cmac = ss->cmac; | ||
1208 | GNUNET_TRANSPORT_communicator_notify (ch, | ||
1209 | &ss->sender->target, | ||
1210 | COMMUNICATOR_ADDRESS_PREFIX, | ||
1211 | &ack.header); | ||
1212 | } | ||
1130 | } | 1213 | } |
1131 | 1214 | ||
1132 | 1215 | ||
@@ -1392,8 +1475,8 @@ sock_read (void *cls) | |||
1392 | 1, | 1475 | 1, |
1393 | GNUNET_NO); | 1476 | GNUNET_NO); |
1394 | GNUNET_STATISTICS_update (stats, | 1477 | GNUNET_STATISTICS_update (stats, |
1395 | "# bytes decrypted without BOX", | 1478 | "# messages decrypted without BOX", |
1396 | sizeof (pbuf) - sizeof (*uc), | 1479 | 1, |
1397 | GNUNET_NO); | 1480 | GNUNET_NO); |
1398 | try_handle_plaintext (sender, | 1481 | try_handle_plaintext (sender, |
1399 | &uc[1], | 1482 | &uc[1], |
@@ -1557,45 +1640,106 @@ mq_send (struct GNUNET_MQ_Handle *mq, | |||
1557 | { | 1640 | { |
1558 | struct ReceiverAddress *receiver = impl_state; | 1641 | struct ReceiverAddress *receiver = impl_state; |
1559 | uint16_t msize = ntohs (msg->size); | 1642 | uint16_t msize = ntohs (msg->size); |
1560 | ssize_t sent; | ||
1561 | 1643 | ||
1562 | GNUNET_assert (mq == receiver->mq); | 1644 | GNUNET_assert (mq == receiver->mq); |
1563 | // FIXME: pick encryption method, encrypt and transmit!! | 1645 | if (msize > receiver->mtu) |
1564 | |||
1565 | #if 0 | ||
1566 | /* compute 'tc' and append in encrypted format to cwrite_buf */ | ||
1567 | tc.sender = my_identity; | ||
1568 | tc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | ||
1569 | ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE); | ||
1570 | ths.purpose.size = htonl (sizeof (ths)); | ||
1571 | ths.sender = my_identity; | ||
1572 | ths.receiver = queue->target; | ||
1573 | ths.ephemeral = *epub; | ||
1574 | ths.monotonic_time = tc.monotonic_time; | ||
1575 | GNUNET_assert (GNUNET_OK == | ||
1576 | GNUNET_CRYPTO_eddsa_sign (my_private_key, | ||
1577 | &ths.purpose, | ||
1578 | &tc.sender_sig)); | ||
1579 | GNUNET_assert (0 == | ||
1580 | gcry_cipher_encrypt (queue->out_cipher, | ||
1581 | &queue->cwrite_buf[queue->cwrite_off], | ||
1582 | sizeof (tc), | ||
1583 | &tc, | ||
1584 | sizeof (tc))); | ||
1585 | |||
1586 | sent = GNUNET_NETWORK_socket_sendto (udp_sock, | ||
1587 | ...); | ||
1588 | GNUNET_MQ_impl_send_continue (mq); | ||
1589 | if (-1 == sent) | ||
1590 | { | 1646 | { |
1591 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | 1647 | GNUNET_break (0); |
1592 | "send"); | 1648 | receiver_destroy (receiver); |
1593 | return; | 1649 | return; |
1594 | } | 1650 | } |
1651 | |||
1652 | // FIXME: add support for BOX encryption method! | ||
1595 | 1653 | ||
1596 | #endif | 1654 | /* KX encryption method */ |
1597 | 1655 | { | |
1656 | struct UdpHandshakeSignature uhs; | ||
1657 | struct UdpConfirmation uc; | ||
1658 | struct InitialKX kx; | ||
1659 | struct GNUNET_CRYPTO_EcdhePrivateKey epriv; | ||
1660 | char dgram[receiver->mtu + | ||
1661 | sizeof (uc) + | ||
1662 | sizeof (kx)]; | ||
1663 | size_t dpos; | ||
1664 | |||
1665 | GNUNET_assert (GNUNET_OK == | ||
1666 | GNUNET_CRYPTO_ecdhe_key_create2 (&epriv)); | ||
1667 | /* compute 'uc' */ | ||
1668 | uc.sender = my_identity; | ||
1669 | uc.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | ||
1670 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE); | ||
1671 | uhs.purpose.size = htonl (sizeof (uhs)); | ||
1672 | uhs.sender = my_identity; | ||
1673 | uhs.receiver = receiver->target; | ||
1674 | GNUNET_CRYPTO_ecdhe_key_get_public (&epriv, | ||
1675 | &uhs.ephemeral); | ||
1676 | uhs.monotonic_time = uc.monotonic_time; | ||
1677 | GNUNET_assert (GNUNET_OK == | ||
1678 | GNUNET_CRYPTO_eddsa_sign (my_private_key, | ||
1679 | &uhs.purpose, | ||
1680 | &uc.sender_sig)); | ||
1681 | /* Leave space for kx */ | ||
1682 | dpos = sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); | ||
1683 | /* Append encrypted uc to dgram */ | ||
1684 | GNUNET_assert (0 == | ||
1685 | gcry_cipher_encrypt (out_cipher, | ||
1686 | &dgram[dpos], | ||
1687 | sizeof (uc), | ||
1688 | &uc, | ||
1689 | sizeof (uc))); | ||
1690 | dpos += sizeof (uc); | ||
1691 | /* Append encrypted payload to dgram */ | ||
1692 | GNUNET_assert (0 == | ||
1693 | gcry_cipher_encrypt (out_cipher, | ||
1694 | &dgram[dpos], | ||
1695 | msize, | ||
1696 | msg, | ||
1697 | msize)); | ||
1698 | dpos += msize; | ||
1699 | /* Pad to MTU */ | ||
1700 | { | ||
1701 | char pad[sizeof (dgram) - pos]; | ||
1598 | 1702 | ||
1703 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1704 | pad, | ||
1705 | sizeof (pad)); | ||
1706 | if (sizeof (pad) > sizeof (struct GNUNET_MessageHeader)) | ||
1707 | { | ||
1708 | struct GNUNET_MessageHeader hdr = { | ||
1709 | .size = htons (sizeof (pad)), | ||
1710 | .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) | ||
1711 | }; | ||
1712 | |||
1713 | memcpy (pad, | ||
1714 | &hdr, | ||
1715 | sizeof (hdr)); | ||
1716 | GNUNET_assert (0 == | ||
1717 | gcry_cipher_encrypt (out_cipher, | ||
1718 | &dgram[dpos], | ||
1719 | sizeof (pad), | ||
1720 | pad, | ||
1721 | sizeof (pad))); | ||
1722 | } | ||
1723 | } | ||
1724 | /* Datagram starts with kx */ | ||
1725 | kx.ephemeral = uhs.ephemeral; | ||
1726 | GNUNET_assert (0 == | ||
1727 | gcry_cipher_gettag (out_cipher, | ||
1728 | kx.gcm_tag, | ||
1729 | sizeof (kx.gcm_tag))); | ||
1730 | memcpy (dgram, | ||
1731 | &kx, | ||
1732 | sizeof (kx)); | ||
1733 | if (-1 == | ||
1734 | GNUNET_NETWORK_socket_sendto (udp_sock, | ||
1735 | dgram, | ||
1736 | sizeof (dgram), | ||
1737 | receiver->address, | ||
1738 | receiver->address_len)) | ||
1739 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1740 | "send"); | ||
1741 | GNUNET_MQ_impl_send_continue (mq); | ||
1742 | } /* End of KX encryption method */ | ||
1599 | } | 1743 | } |
1600 | 1744 | ||
1601 | 1745 | ||
@@ -1697,6 +1841,7 @@ receiver_setup (const struct GNUNET_PeerIdentity *target, | |||
1697 | NULL, | 1841 | NULL, |
1698 | &mq_error, | 1842 | &mq_error, |
1699 | receiver); | 1843 | receiver); |
1844 | receiver->mtu = 1200 /* FIXME: MTU OK? */; | ||
1700 | if (NULL == timeout_task) | 1845 | if (NULL == timeout_task) |
1701 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, | 1846 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, |
1702 | NULL); | 1847 | NULL); |
@@ -1726,14 +1871,14 @@ receiver_setup (const struct GNUNET_PeerIdentity *target, | |||
1726 | default: | 1871 | default: |
1727 | GNUNET_assert (0); | 1872 | GNUNET_assert (0); |
1728 | } | 1873 | } |
1729 | queue->qh | 1874 | receiver->qh |
1730 | = GNUNET_TRANSPORT_communicator_mq_add (ch, | 1875 | = GNUNET_TRANSPORT_communicator_mq_add (ch, |
1731 | &receiver->target, | 1876 | &receiver->target, |
1732 | foreign_addr, | 1877 | foreign_addr, |
1733 | 1200 /* FIXME: MTU OK? */, | 1878 | receiver->mtu, |
1734 | queue->nt, | 1879 | receiver->nt, |
1735 | GNUNET_TRANSPORT_CS_OUTBOUND, | 1880 | GNUNET_TRANSPORT_CS_OUTBOUND, |
1736 | queue->mq); | 1881 | receiver->mq); |
1737 | GNUNET_free (foreign_addr); | 1882 | GNUNET_free (foreign_addr); |
1738 | } | 1883 | } |
1739 | } | 1884 | } |
@@ -1887,13 +2032,11 @@ do_shutdown (void *cls) | |||
1887 | 2032 | ||
1888 | 2033 | ||
1889 | /** | 2034 | /** |
1890 | * Function called when the transport service has received an | 2035 | * Function called when the transport service has received a |
1891 | * acknowledgement for this communicator (!) via a different return | 2036 | * backchannel message for this communicator (!) via a different return |
1892 | * path. | 2037 | * path. Should be an acknowledgement. |
1893 | * | ||
1894 | * Not applicable for UDP. | ||
1895 | * | 2038 | * |
1896 | * @param cls closure | 2039 | * @param cls closure, NULL |
1897 | * @param sender which peer sent the notification | 2040 | * @param sender which peer sent the notification |
1898 | * @param msg payload | 2041 | * @param msg payload |
1899 | */ | 2042 | */ |
@@ -1902,10 +2045,20 @@ enc_notify_cb (void *cls, | |||
1902 | const struct GNUNET_PeerIdentity *sender, | 2045 | const struct GNUNET_PeerIdentity *sender, |
1903 | const struct GNUNET_MessageHeader *msg) | 2046 | const struct GNUNET_MessageHeader *msg) |
1904 | { | 2047 | { |
2048 | const struct UDPAck *ack; | ||
2049 | |||
1905 | (void) cls; | 2050 | (void) cls; |
1906 | (void) sender; | 2051 | if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) || |
1907 | (void) msg; | 2052 | (ntohs (msg->size) != sizeof (struct UDPAck)) ) |
1908 | GNUNET_break_op (0); | 2053 | { |
2054 | GNUNET_break_op (0); | ||
2055 | return; | ||
2056 | } | ||
2057 | ack = (const struct UDPAck *) msg; | ||
2058 | GNUNET_CONTAINER_multihashmap_get_multiple (receivers, | ||
2059 | sender, | ||
2060 | &handle_ack, | ||
2061 | (void *) ack); | ||
1909 | } | 2062 | } |
1910 | 2063 | ||
1911 | 2064 | ||