aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-communicator-udp.c170
1 files changed, 129 insertions, 41 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c
index bbfe2ebec..12c409b3d 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -24,7 +24,6 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - implement main BOXed sending logic
28 * - figure out what to do with MTU: 1280 for IPv6 is obvious; 27 * - figure out what to do with MTU: 1280 for IPv6 is obvious;
29 * what for IPv4? 1500? Also, consider differences in 28 * what for IPv4? 1500? Also, consider differences in
30 * headers for with/without box: need to give MIN of both 29 * headers for with/without box: need to give MIN of both
@@ -34,7 +33,7 @@
34 * - add and use util/ check for IPv6 availability (#V6) 33 * - add and use util/ check for IPv6 availability (#V6)
35 * - consider imposing transmission limits in the absence 34 * - consider imposing transmission limits in the absence
36 * of ACKs; or: maybe this should be done at TNG service level? 35 * of ACKs; or: maybe this should be done at TNG service level?
37 * - handle addresses discovered fro broadcasts (#) 36 * - handle addresses discovered from broadcasts (#)
38 * (think: what was the story again on address validation? 37 * (think: what was the story again on address validation?
39 * where is the API for that!?!) 38 * where is the API for that!?!)
40 * - support DNS names in BINDTO option (#5528) 39 * - support DNS names in BINDTO option (#5528)
@@ -574,6 +573,12 @@ struct ReceiverAddress
574 * Length of the DLL at @a ss_head. 573 * Length of the DLL at @a ss_head.
575 */ 574 */
576 unsigned int num_secrets; 575 unsigned int num_secrets;
576
577 /**
578 * Number of BOX keys from ACKs we have currently
579 * available for this receiver.
580 */
581 unsigned int acks_available;
577 582
578 /** 583 /**
579 * Which network type does this queue use? 584 * Which network type does this queue use?
@@ -913,6 +918,8 @@ secret_destroy (struct SharedSecret *ss)
913 receiver->ss_tail, 918 receiver->ss_tail,
914 ss); 919 ss);
915 receiver->num_secrets--; 920 receiver->num_secrets--;
921 receiver->acks_available
922 -= (ss->sequence_allowed - ss->sequence_used);
916 } 923 }
917 while (NULL != (kce = ss->kce_head)) 924 while (NULL != (kce = ss->kce_head))
918 kce_destroy (kce); 925 kce_destroy (kce);
@@ -1279,17 +1286,26 @@ handle_ack (void *cls,
1279 &ss->cmac, 1286 &ss->cmac,
1280 sizeof (struct GNUNET_HashCode))) 1287 sizeof (struct GNUNET_HashCode)))
1281 { 1288 {
1282 ss->sequence_allowed = GNUNET_MAX (ss->sequence_allowed, 1289 uint32_t allowed;
1283 ntohl (ack->sequence_max)); 1290
1284 /* move ss to head to avoid discarding it anytime soon! */ 1291 allowed = ntohl (ack->sequence_max);
1285 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, 1292
1286 receiver->ss_tail, 1293 if (allowed > ss->sequence_allowed)
1287 ss); 1294 {
1288 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, 1295 if (0 == receiver->acks_available)
1289 receiver->ss_tail, 1296 {
1290 ss); 1297 /* FIXME: update MTU / MQ of 'receiver'! */
1291 /* FIXME: if this changed sequence_allowed, 1298 }
1292 update MTU / MQ of 'receiver'! */ 1299 receiver->acks_available += (allowed - ss->sequence_allowed);
1300 ss->sequence_allowed = allowed;
1301 /* move ss to head to avoid discarding it anytime soon! */
1302 GNUNET_CONTAINER_DLL_remove (receiver->ss_head,
1303 receiver->ss_tail,
1304 ss);
1305 GNUNET_CONTAINER_DLL_insert (receiver->ss_head,
1306 receiver->ss_tail,
1307 ss);
1308 }
1293 return GNUNET_NO; 1309 return GNUNET_NO;
1294 } 1310 }
1295 } 1311 }
@@ -1855,6 +1871,43 @@ udp_address_to_sockaddr (const char *bindto,
1855 1871
1856 1872
1857/** 1873/**
1874 * Pad @a dgram by @a pad_size using @a out_cipher.
1875 *
1876 * @param out_cipher cipher to use
1877 * @param dgram datagram to pad
1878 * @param pad_size number of bytes of padding to append
1879 */
1880static void
1881do_pad (gcry_cipher_hd_t out_cipher,
1882 char *dgram,
1883 size_t pad_size)
1884{
1885 char pad[pad_size];
1886
1887 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
1888 pad,
1889 sizeof (pad));
1890 if (sizeof (pad) > sizeof (struct GNUNET_MessageHeader))
1891 {
1892 struct GNUNET_MessageHeader hdr = {
1893 .size = htons (sizeof (pad)),
1894 .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD)
1895 };
1896
1897 memcpy (pad,
1898 &hdr,
1899 sizeof (hdr));
1900 }
1901 GNUNET_assert (0 ==
1902 gcry_cipher_encrypt (out_cipher,
1903 dgram,
1904 sizeof (pad),
1905 pad,
1906 sizeof (pad)));
1907}
1908
1909
1910/**
1858 * Signature of functions implementing the sending functionality of a 1911 * Signature of functions implementing the sending functionality of a
1859 * message queue. 1912 * message queue.
1860 * 1913 *
@@ -1879,10 +1932,9 @@ mq_send (struct GNUNET_MQ_Handle *mq,
1879 } 1932 }
1880 reschedule_receiver_timeout (receiver); 1933 reschedule_receiver_timeout (receiver);
1881 1934
1882 // FIXME: add support for BOX encryption method! 1935 if (0 == receiver->acks_available)
1883
1884 /* KX encryption method */
1885 { 1936 {
1937 /* use KX encryption method */
1886 struct UdpHandshakeSignature uhs; 1938 struct UdpHandshakeSignature uhs;
1887 struct UDPConfirmation uc; 1939 struct UDPConfirmation uc;
1888 struct InitialKX kx; 1940 struct InitialKX kx;
@@ -1935,31 +1987,9 @@ mq_send (struct GNUNET_MQ_Handle *mq,
1935 msg, 1987 msg,
1936 msize)); 1988 msize));
1937 dpos += msize; 1989 dpos += msize;
1938 /* Pad to MTU */ 1990 do_pad (out_cipher,
1939 { 1991 &dgram[dpos],
1940 char pad[sizeof (dgram) - dpos]; 1992 sizeof (dgram) - dpos);
1941
1942 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
1943 pad,
1944 sizeof (pad));
1945 if (sizeof (pad) > sizeof (struct GNUNET_MessageHeader))
1946 {
1947 struct GNUNET_MessageHeader hdr = {
1948 .size = htons (sizeof (pad)),
1949 .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD)
1950 };
1951
1952 memcpy (pad,
1953 &hdr,
1954 sizeof (hdr));
1955 GNUNET_assert (0 ==
1956 gcry_cipher_encrypt (out_cipher,
1957 &dgram[dpos],
1958 sizeof (pad),
1959 pad,
1960 sizeof (pad)));
1961 }
1962 }
1963 /* Datagram starts with kx */ 1993 /* Datagram starts with kx */
1964 kx.ephemeral = uhs.ephemeral; 1994 kx.ephemeral = uhs.ephemeral;
1965 GNUNET_assert (0 == 1995 GNUNET_assert (0 ==
@@ -1979,7 +2009,65 @@ mq_send (struct GNUNET_MQ_Handle *mq,
1979 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 2009 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1980 "send"); 2010 "send");
1981 GNUNET_MQ_impl_send_continue (mq); 2011 GNUNET_MQ_impl_send_continue (mq);
2012 return;
1982 } /* End of KX encryption method */ 2013 } /* End of KX encryption method */
2014
2015 // FIXME: add support for BOX encryption method!
2016 /* begin "BOX" encryption method, scan for ACKs from tail! */
2017 for (struct SharedSecret *ss = receiver->ss_tail;
2018 NULL != ss;
2019 ss = ss->prev)
2020 {
2021 if (ss->sequence_used < ss->sequence_allowed)
2022 {
2023 char dgram[sizeof (struct UDPBox) + receiver->mtu];
2024 struct UDPBox *box;
2025 gcry_cipher_hd_t out_cipher;
2026 size_t dpos;
2027
2028 box = (struct UDPBox *) dgram;
2029 ss->sequence_used++;
2030 get_kid (&ss->master,
2031 ss->sequence_used,
2032 &box->kid);
2033 setup_cipher (&ss->master,
2034 ss->sequence_used,
2035 &out_cipher);
2036 /* Append encrypted payload to dgram */
2037 dpos = sizeof (struct UDPBox);
2038 GNUNET_assert (0 ==
2039 gcry_cipher_encrypt (out_cipher,
2040 &dgram[dpos],
2041 msize,
2042 msg,
2043 msize));
2044 dpos += msize;
2045 do_pad (out_cipher,
2046 &dgram[dpos],
2047 sizeof (dgram) - dpos);
2048 GNUNET_assert (0 ==
2049 gcry_cipher_gettag (out_cipher,
2050 box->gcm_tag,
2051 sizeof (box->gcm_tag)));
2052 gcry_cipher_close (out_cipher);
2053 if (-1 ==
2054 GNUNET_NETWORK_socket_sendto (udp_sock,
2055 dgram,
2056 sizeof (dgram),
2057 receiver->address,
2058 receiver->address_len))
2059 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
2060 "send");
2061 GNUNET_MQ_impl_send_continue (mq);
2062 receiver->acks_available--;
2063 if (0 == receiver->acks_available)
2064 {
2065 /* FIXME: update MTU / MQ of 'receiver'! */
2066 }
2067 return;
2068 }
2069 }
2070 GNUNET_assert (0);
1983} 2071}
1984 2072
1985 2073