aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r--src/transport/gnunet-communicator-udp.c131
1 files changed, 72 insertions, 59 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c
index 75f732d6c..2b014f890 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -37,8 +37,8 @@
37 * - support NAT connection reversal method (#5529) 37 * - support NAT connection reversal method (#5529)
38 * - support other UDP-specific NAT traversal methods (#) 38 * - support other UDP-specific NAT traversal methods (#)
39 */ 39 */
40#include "gnunet_common.h"
41#include "platform.h" 40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_util_lib.h" 42#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h" 43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h" 44#include "gnunet_signatures.h"
@@ -94,7 +94,7 @@
94 */ 94 */
95#define GCM_TAG_SIZE (128 / 8) 95#define GCM_TAG_SIZE (128 / 8)
96 96
97#define GENERATE_AT_ONCE 2 97#define GENERATE_AT_ONCE 16
98 98
99/** 99/**
100 * If we fall below this number of available KCNs, 100 * If we fall below this number of available KCNs,
@@ -105,7 +105,7 @@
105 * arrive before the sender runs out. So really this 105 * arrive before the sender runs out. So really this
106 * should ideally be based on the RTT. 106 * should ideally be based on the RTT.
107 */ 107 */
108#define KCN_THRESHOLD 92 108#define KCN_THRESHOLD 96
109 109
110/** 110/**
111 * How many KCNs do we keep around *after* we hit 111 * How many KCNs do we keep around *after* we hit
@@ -484,20 +484,7 @@ struct SharedSecret
484 */ 484 */
485 int rekey_initiated; 485 int rekey_initiated;
486 486
487 /**
488 * ID of kce working queue task
489 */
490 struct GNUNET_SCHEDULER_Task *kce_task;
491 487
492 /**
493 * Is the kce_task finished?
494 */
495 int kce_task_finished;
496
497 /**
498 * When KCE finishes, send ACK if GNUNET_YES
499 */
500 int kce_send_ack_on_finish;
501}; 488};
502 489
503 490
@@ -563,6 +550,20 @@ struct SenderAddress
563 */ 550 */
564 int sender_destroy_called; 551 int sender_destroy_called;
565 552
553 /**
554 * ID of kce working queue task
555 */
556 struct GNUNET_SCHEDULER_Task *kce_task;
557
558 /**
559 * Is the kce_task finished?
560 */
561 int kce_task_finished;
562
563 /**
564 * When KCE finishes, send ACK if GNUNET_YES
565 */
566 int kce_send_ack_on_finish;
566}; 567};
567 568
568 569
@@ -1030,10 +1031,10 @@ secret_destroy (struct SharedSecret *ss, int withoutKce)
1030 "# KIDs active", 1031 "# KIDs active",
1031 GNUNET_CONTAINER_multishortmap_size (key_cache), 1032 GNUNET_CONTAINER_multishortmap_size (key_cache),
1032 GNUNET_NO); 1033 GNUNET_NO);
1033 if (NULL != ss->kce_task) 1034 if (NULL != ss->sender->kce_task)
1034 { 1035 {
1035 GNUNET_SCHEDULER_cancel (ss->kce_task); 1036 GNUNET_SCHEDULER_cancel (ss->sender->kce_task);
1036 ss->kce_task = NULL; 1037 ss->sender->kce_task = NULL;
1037 } 1038 }
1038 GNUNET_free (ss); 1039 GNUNET_free (ss);
1039 return GNUNET_YES; 1040 return GNUNET_YES;
@@ -1452,7 +1453,7 @@ add_acks (struct SharedSecret *ss, int acks_to_add)
1452 1); 1453 1);
1453 } 1454 }
1454 1455
1455 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1456 "Tell transport we have %u more acks!\n", 1457 "Tell transport we have %u more acks!\n",
1457 acks_to_add); 1458 acks_to_add);
1458 1459
@@ -1501,25 +1502,25 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1501 1502
1502 if (allowed <= ss->sequence_allowed) 1503 if (allowed <= ss->sequence_allowed)
1503 { 1504 {
1504 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1505 "Ignoring ack, not giving us increased window\n."); 1506 "Ignoring ack, not giving us increased window\n.");
1506 return GNUNET_NO; 1507 return GNUNET_NO;
1507 } 1508 }
1508 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1509 "New sequence allows until %u from %u. Acks available to us: %u. For secret %s\n",
1510 allowed,
1511 ss->sequence_allowed,
1512 receiver->acks_available,
1513 GNUNET_h2s (&ss->master));
1514 acks_to_add = (allowed - ss->sequence_allowed); 1509 acks_to_add = (allowed - ss->sequence_allowed);
1515 GNUNET_assert (0 != acks_to_add); 1510 GNUNET_assert (0 != acks_to_add);
1516 receiver->acks_available += (allowed - ss->sequence_allowed); 1511 receiver->acks_available += (allowed - ss->sequence_allowed);
1517 ss->sequence_allowed = allowed; 1512 ss->sequence_allowed = allowed;
1518 add_acks (ss, acks_to_add); 1513 add_acks (ss, acks_to_add);
1514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1515 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1516 allowed,
1517 acks_to_add,
1518 receiver->acks_available,
1519 GNUNET_h2s (&ss->master));
1519 return GNUNET_NO; 1520 return GNUNET_NO;
1520 } 1521 }
1521 } 1522 }
1522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1523 "Matching cmac not found for ack!\n"); 1524 "Matching cmac not found for ack!\n");
1524 return GNUNET_YES; 1525 return GNUNET_YES;
1525} 1526}
@@ -1556,7 +1557,7 @@ consider_ss_ack (struct SharedSecret *ss)
1556 ack.header.size = htons (sizeof(ack)); 1557 ack.header.size = htons (sizeof(ack));
1557 ack.sequence_ack = htonl (ss->sequence_allowed); 1558 ack.sequence_ack = htonl (ss->sequence_allowed);
1558 ack.cmac = ss->cmac; 1559 ack.cmac = ss->cmac;
1559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1560 "Notifying transport with UDPAck %s, sequence %u and master %s\n", 1561 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1561 GNUNET_i2s_full (&ss->sender->target), 1562 GNUNET_i2s_full (&ss->sender->target),
1562 ss->sequence_allowed, 1563 ss->sequence_allowed,
@@ -1572,30 +1573,40 @@ static void
1572kce_generate_cb (void *cls) 1573kce_generate_cb (void *cls)
1573{ 1574{
1574 struct SharedSecret *ss = cls; 1575 struct SharedSecret *ss = cls;
1575 1576 static uint64_t kce_last_available = 0;
1576 ss->kce_task = NULL; 1577 ss->sender->kce_task = NULL;
1577 1578
1578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1579 "Precomputing %u keys for master %s\n", 1580 "Precomputing %u keys for master %s\n",
1580 GENERATE_AT_ONCE, 1581 GENERATE_AT_ONCE,
1581 GNUNET_h2s (&(ss->master))); 1582 GNUNET_h2s (&(ss->master)));
1582 if (KCN_TARGET < ss->sender->acks_available) 1583 if (KCN_TARGET < ss->sender->acks_available)
1584 {
1585 ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1586 WORKING_QUEUE_INTERVALL,
1587 kce_generate_cb,
1588 ss);
1583 return; 1589 return;
1590 }
1584 for (int i = 0; i < GENERATE_AT_ONCE; i++) 1591 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1585 kce_generate (ss, ++ss->sequence_allowed); 1592 kce_generate (ss, ++ss->sequence_allowed);
1586 1593
1594 /**
1595 * As long as we loose over 30% of max acks in reschedule,
1596 * We keep generating acks for this ss.
1597 */
1587 if (KCN_TARGET > ss->sender->acks_available) 1598 if (KCN_TARGET > ss->sender->acks_available)
1588 { 1599 {
1589 ss->kce_task = GNUNET_SCHEDULER_add_delayed ( 1600 ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1590 WORKING_QUEUE_INTERVALL, 1601 WORKING_QUEUE_INTERVALL,
1591 kce_generate_cb, 1602 kce_generate_cb,
1592 ss); 1603 ss);
1593 return; 1604 return;
1594 } 1605 }
1595 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1596 "We have enough keys.\n"); 1607 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1597 ss->kce_task_finished = GNUNET_YES; 1608 ss->sender->kce_task_finished = GNUNET_YES;
1598 if (ss->kce_send_ack_on_finish == GNUNET_YES) 1609 if (ss->sender->kce_send_ack_on_finish == GNUNET_YES)
1599 consider_ss_ack (ss); 1610 consider_ss_ack (ss);
1600} 1611}
1601 1612
@@ -1660,8 +1671,9 @@ try_handle_plaintext (struct SenderAddress *sender,
1660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1661 "We have %u acks available.\n", 1672 "We have %u acks available.\n",
1662 ss_rekey->sender->acks_available); 1673 ss_rekey->sender->acks_available);
1663 ss_rekey->kce_send_ack_on_finish = GNUNET_NO; 1674 ss_rekey->sender->kce_send_ack_on_finish = GNUNET_NO;
1664 ss_rekey->kce_task = GNUNET_SCHEDULER_add_delayed ( 1675 // FIXME
1676 ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1665 WORKING_QUEUE_INTERVALL, 1677 WORKING_QUEUE_INTERVALL,
1666 kce_generate_cb, 1678 kce_generate_cb,
1667 ss_rekey); 1679 ss_rekey);
@@ -1718,7 +1730,7 @@ decrypt_box (const struct UDPBox *box,
1718 sizeof(out_buf), 1730 sizeof(out_buf),
1719 out_buf)) 1731 out_buf))
1720 { 1732 {
1721 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed decryption.\n"); 1733 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1722 GNUNET_STATISTICS_update (stats, 1734 GNUNET_STATISTICS_update (stats,
1723 "# Decryption failures with valid KCE", 1735 "# Decryption failures with valid KCE",
1724 1, 1736 1,
@@ -1727,6 +1739,7 @@ decrypt_box (const struct UDPBox *box,
1727 return; 1739 return;
1728 } 1740 }
1729 kce_destroy (kce); 1741 kce_destroy (kce);
1742 kce = NULL;
1730 GNUNET_STATISTICS_update (stats, 1743 GNUNET_STATISTICS_update (stats,
1731 "# bytes decrypted with BOX", 1744 "# bytes decrypted with BOX",
1732 sizeof(out_buf), 1745 sizeof(out_buf),
@@ -1739,6 +1752,18 @@ decrypt_box (const struct UDPBox *box,
1739 "decrypted UDPBox with kid %s\n", 1752 "decrypted UDPBox with kid %s\n",
1740 GNUNET_sh2s (&box->kid)); 1753 GNUNET_sh2s (&box->kid));
1741 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); 1754 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1755 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1756 (NULL == ss->sender->kce_task) &&
1757 (GNUNET_YES == ss->sender->kce_task_finished))
1758 {
1759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1760 "Sender has %u ack left which is under threshold.\n",
1761 ss->sender->acks_available);
1762 ss->sender->kce_send_ack_on_finish = GNUNET_YES;
1763 ss->sender->kce_task = GNUNET_SCHEDULER_add_now (
1764 kce_generate_cb,
1765 ss);
1766 }
1742} 1767}
1743 1768
1744 1769
@@ -1960,19 +1985,6 @@ sock_read (void *cls)
1960 "Found KCE with kid %s\n", 1985 "Found KCE with kid %s\n",
1961 GNUNET_sh2s (&box->kid)); 1986 GNUNET_sh2s (&box->kid));
1962 decrypt_box (box, (size_t) rcvd, kce); 1987 decrypt_box (box, (size_t) rcvd, kce);
1963 if ((NULL == kce->ss->kce_task) &&
1964 (GNUNET_YES == kce->ss->kce_task_finished) &&
1965 (kce->ss->sender->acks_available < KCN_THRESHOLD))
1966 {
1967 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1968 "Sender has %u ack left which is under threshold.\n",
1969 kce->ss->sender->acks_available);
1970 kce->ss->kce_send_ack_on_finish = GNUNET_YES;
1971 kce->ss->kce_task = GNUNET_SCHEDULER_add_delayed (
1972 WORKING_QUEUE_INTERVALL,
1973 kce_generate_cb,
1974 kce->ss);
1975 }
1976 continue; 1988 continue;
1977 } 1989 }
1978 } 1990 }
@@ -2107,13 +2119,13 @@ sock_read (void *cls)
2107 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen); 2119 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2108 ss->sender = sender; 2120 ss->sender = sender;
2109 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss); 2121 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2110 if ((NULL == ss->kce_task) && (GNUNET_NO == 2122 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2111 ss->kce_task_finished)) 2123 (NULL == ss->sender->kce_task) &&
2124 (GNUNET_NO == ss->sender->kce_task_finished))
2112 { 2125 {
2113 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix. 2126 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2114 ss->kce_send_ack_on_finish = GNUNET_YES; 2127 ss->sender->kce_send_ack_on_finish = GNUNET_YES;
2115 ss->kce_task = GNUNET_SCHEDULER_add_delayed ( 2128 ss->sender->kce_task = GNUNET_SCHEDULER_add_now (
2116 WORKING_QUEUE_INTERVALL,
2117 kce_generate_cb, 2129 kce_generate_cb,
2118 ss); 2130 ss);
2119 } 2131 }
@@ -2600,13 +2612,14 @@ mq_send_d (struct GNUNET_MQ_Handle *mq,
2600 msize, 2612 msize,
2601 receiver->acks_available); 2613 receiver->acks_available);
2602 ss->bytes_sent += sizeof (dgram); 2614 ss->bytes_sent += sizeof (dgram);
2603 GNUNET_MQ_impl_send_continue (mq);
2604 receiver->acks_available--; 2615 receiver->acks_available--;
2616 GNUNET_MQ_impl_send_continue (mq);
2605 return; 2617 return;
2606 } 2618 }
2607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2608 "No suitable ss found, sending as KX...\n"); 2620 "No suitable ss found, sending as KX...\n");
2609 send_msg_with_kx (msg, receiver); 2621 send_msg_with_kx (msg, receiver);
2622 GNUNET_MQ_impl_send_continue (mq);
2610} 2623}
2611 2624
2612 2625