diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-29 23:11:47 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-29 23:11:47 +0200 |
commit | b679501b9cd5a8d4fa6ee4e4dcad7eb908249f8c (patch) | |
tree | ccf0365fbcafc477b07d7335ce4ea220397b6096 /src/transport/gnunet-communicator-udp.c | |
parent | 6c9229f7a8266ea13cff1aff25269b41ce9f3b03 (diff) | |
download | gnunet-b679501b9cd5a8d4fa6ee4e4dcad7eb908249f8c.tar.gz gnunet-b679501b9cd5a8d4fa6ee4e4dcad7eb908249f8c.zip |
TNG: More work on UDP communicator.
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 768 |
1 files changed, 252 insertions, 516 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index c69fb233c..f697dc02e 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -37,6 +37,7 @@ | |||
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" | ||
40 | #include "platform.h" | 41 | #include "platform.h" |
41 | #include "gnunet_util_lib.h" | 42 | #include "gnunet_util_lib.h" |
42 | #include "gnunet_protocols.h" | 43 | #include "gnunet_protocols.h" |
@@ -93,7 +94,7 @@ | |||
93 | */ | 94 | */ |
94 | #define GCM_TAG_SIZE (128 / 8) | 95 | #define GCM_TAG_SIZE (128 / 8) |
95 | 96 | ||
96 | #define GENERATE_AT_ONCE 100 | 97 | #define GENERATE_AT_ONCE 2 |
97 | 98 | ||
98 | /** | 99 | /** |
99 | * If we fall below this number of available KCNs, | 100 | * If we fall below this number of available KCNs, |
@@ -254,13 +255,7 @@ struct UDPAck | |||
254 | * Sequence acknowledgement limit. Specifies current maximum sequence | 255 | * Sequence acknowledgement limit. Specifies current maximum sequence |
255 | * number supported by receiver. | 256 | * number supported by receiver. |
256 | */ | 257 | */ |
257 | uint32_t sequence_max GNUNET_PACKED; | 258 | uint32_t sequence_ack GNUNET_PACKED; |
258 | |||
259 | /** | ||
260 | * Sequence acknowledgement limit. Specifies current maximum sequence | ||
261 | * number supported by receiver. | ||
262 | */ | ||
263 | uint32_t acks_available GNUNET_PACKED; | ||
264 | 259 | ||
265 | /** | 260 | /** |
266 | * CMAC of the base key being acknowledged. | 261 | * CMAC of the base key being acknowledged. |
@@ -344,8 +339,7 @@ struct UDPBox | |||
344 | }; | 339 | }; |
345 | 340 | ||
346 | /** | 341 | /** |
347 | * UDP message box. Always sent encrypted, only allowed after | 342 | * Plaintext of a rekey payload in a UDPBox. |
348 | * the receiver sent a `struct UDPAck` for the base key! | ||
349 | */ | 343 | */ |
350 | struct UDPRekey | 344 | struct UDPRekey |
351 | { | 345 | { |
@@ -479,6 +473,26 @@ struct SharedSecret | |||
479 | * Number of active KCN entries. | 473 | * Number of active KCN entries. |
480 | */ | 474 | */ |
481 | unsigned int active_kce_count; | 475 | unsigned int active_kce_count; |
476 | |||
477 | /** | ||
478 | * Bytes sent with this shared secret | ||
479 | */ | ||
480 | size_t bytes_sent; | ||
481 | |||
482 | /** | ||
483 | * rekey initiated for this secret? | ||
484 | */ | ||
485 | int rekey_initiated; | ||
486 | |||
487 | /** | ||
488 | * ID of kce working queue task | ||
489 | */ | ||
490 | struct GNUNET_SCHEDULER_Task *kce_task; | ||
491 | |||
492 | /** | ||
493 | * Is the kce_task finished? | ||
494 | */ | ||
495 | int kce_task_finished; | ||
482 | }; | 496 | }; |
483 | 497 | ||
484 | 498 | ||
@@ -489,16 +503,6 @@ struct SharedSecret | |||
489 | struct SenderAddress | 503 | struct SenderAddress |
490 | { | 504 | { |
491 | /** | 505 | /** |
492 | * Shared secret we use with @e target for rekeying. | ||
493 | */ | ||
494 | struct SharedSecret *ss_rekey; | ||
495 | |||
496 | /** | ||
497 | * Flag indicating sender is initiated rekeying for this receiver. | ||
498 | */ | ||
499 | uint16_t rekeying; | ||
500 | |||
501 | /** | ||
502 | * To whom are we talking to. | 506 | * To whom are we talking to. |
503 | */ | 507 | */ |
504 | struct GNUNET_PeerIdentity target; | 508 | struct GNUNET_PeerIdentity target; |
@@ -554,21 +558,6 @@ struct SenderAddress | |||
554 | */ | 558 | */ |
555 | int sender_destroy_called; | 559 | int sender_destroy_called; |
556 | 560 | ||
557 | |||
558 | /** | ||
559 | * ID of kce working queue task | ||
560 | */ | ||
561 | struct GNUNET_SCHEDULER_Task *kce_task; | ||
562 | |||
563 | /** | ||
564 | * ID of kce rekey working queue task | ||
565 | */ | ||
566 | struct GNUNET_SCHEDULER_Task *kce_task_rekey; | ||
567 | |||
568 | /** | ||
569 | * Is the kce_task finished? | ||
570 | */ | ||
571 | int kce_task_finished; | ||
572 | }; | 561 | }; |
573 | 562 | ||
574 | 563 | ||
@@ -578,38 +567,12 @@ struct SenderAddress | |||
578 | */ | 567 | */ |
579 | struct ReceiverAddress | 568 | struct ReceiverAddress |
580 | { | 569 | { |
581 | |||
582 | /** | ||
583 | * Shared secret we use with @e target for rekeying. | ||
584 | */ | ||
585 | struct SharedSecret *ss_rekey; | ||
586 | |||
587 | /** | ||
588 | * Acks available when we started rekeying. | ||
589 | */ | ||
590 | unsigned int rekey_acks_available; | ||
591 | |||
592 | /** | ||
593 | * Send bytes for this receiver address. | ||
594 | */ | ||
595 | uint64_t rekey_send_bytes; | ||
596 | |||
597 | /** | 570 | /** |
598 | * Timeout for this receiver address. | 571 | * Timeout for this receiver address. |
599 | */ | 572 | */ |
600 | struct GNUNET_TIME_Absolute rekey_timeout; | 573 | struct GNUNET_TIME_Absolute rekey_timeout; |
601 | 574 | ||
602 | /** | 575 | /** |
603 | * Flag indicating sender is initiated rekeying for this receiver. | ||
604 | */ | ||
605 | uint16_t rekeying; | ||
606 | |||
607 | /** | ||
608 | * Number of kce we retain for sending the rekeying shared secret. | ||
609 | */ | ||
610 | int number_rekeying_kce; | ||
611 | |||
612 | /** | ||
613 | * To whom are we talking to. | 576 | * To whom are we talking to. |
614 | */ | 577 | */ |
615 | struct GNUNET_PeerIdentity target; | 578 | struct GNUNET_PeerIdentity target; |
@@ -763,10 +726,6 @@ static struct GNUNET_TIME_Relative rekey_interval; | |||
763 | * How often we do rekey based on number of bytes transmitted | 726 | * How often we do rekey based on number of bytes transmitted |
764 | */ | 727 | */ |
765 | static unsigned long long rekey_max_bytes; | 728 | static unsigned long long rekey_max_bytes; |
766 | /** | ||
767 | * Shared secret we finished the last kce working queue for. | ||
768 | */ | ||
769 | struct SharedSecret *ss_finished; | ||
770 | 729 | ||
771 | /** | 730 | /** |
772 | * Cache of pre-generated key IDs. | 731 | * Cache of pre-generated key IDs. |
@@ -1066,6 +1025,11 @@ secret_destroy (struct SharedSecret *ss, int withoutKce) | |||
1066 | "# KIDs active", | 1025 | "# KIDs active", |
1067 | GNUNET_CONTAINER_multishortmap_size (key_cache), | 1026 | GNUNET_CONTAINER_multishortmap_size (key_cache), |
1068 | GNUNET_NO); | 1027 | GNUNET_NO); |
1028 | if (NULL != ss->kce_task) | ||
1029 | { | ||
1030 | GNUNET_SCHEDULER_cancel (ss->kce_task); | ||
1031 | ss->kce_task = NULL; | ||
1032 | } | ||
1069 | GNUNET_free (ss); | 1033 | GNUNET_free (ss); |
1070 | return GNUNET_YES; | 1034 | return GNUNET_YES; |
1071 | } | 1035 | } |
@@ -1483,12 +1447,9 @@ add_acks (struct SharedSecret *ss, int acks_to_add) | |||
1483 | 1); | 1447 | 1); |
1484 | } | 1448 | } |
1485 | 1449 | ||
1486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1450 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1487 | "Tell transport we have %u more acks!\n", | 1451 | "Tell transport we have %u more acks!\n", |
1488 | acks_to_add); | 1452 | acks_to_add); |
1489 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1490 | "%u kce for rekeying.\n", | ||
1491 | receiver->number_rekeying_kce); | ||
1492 | 1453 | ||
1493 | // Until here for alternativ 1 | 1454 | // Until here for alternativ 1 |
1494 | 1455 | ||
@@ -1496,63 +1457,7 @@ add_acks (struct SharedSecret *ss, int acks_to_add) | |||
1496 | 1457 | ||
1497 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); | 1458 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); |
1498 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); | 1459 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); |
1499 | destroy_all_secrets (ss, GNUNET_YES); | 1460 | // destroy_all_secrets (ss, GNUNET_YES); |
1500 | } | ||
1501 | |||
1502 | |||
1503 | static uint32_t | ||
1504 | reset_rekey_kces (struct ReceiverAddress *receiver, | ||
1505 | uint32_t acks_to_add) | ||
1506 | { | ||
1507 | int needed_for_rekeying; | ||
1508 | |||
1509 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1510 | "%u kce for rekeying and %u acks_to_add\n", | ||
1511 | receiver->number_rekeying_kce, | ||
1512 | acks_to_add); | ||
1513 | |||
1514 | needed_for_rekeying = (3 - receiver->number_rekeying_kce); | ||
1515 | if (acks_to_add <= needed_for_rekeying) | ||
1516 | { | ||
1517 | receiver->number_rekeying_kce += acks_to_add; | ||
1518 | acks_to_add = 0; | ||
1519 | } | ||
1520 | else | ||
1521 | { | ||
1522 | acks_to_add -= (3 - receiver->number_rekeying_kce); | ||
1523 | receiver->number_rekeying_kce = 3; | ||
1524 | } | ||
1525 | |||
1526 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1527 | "%u kce for rekeying and %u acks_to_add\n", | ||
1528 | receiver->number_rekeying_kce, | ||
1529 | acks_to_add); | ||
1530 | return acks_to_add; | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | static void | ||
1535 | add_acks_rekey (struct ReceiverAddress *receiver) | ||
1536 | { | ||
1537 | uint32_t acks_to_add = receiver->ss_rekey->sequence_allowed; | ||
1538 | |||
1539 | if (receiver->number_rekeying_kce < 3) | ||
1540 | acks_to_add = reset_rekey_kces (receiver, acks_to_add); | ||
1541 | receiver->acks_available = receiver->ss_rekey->sequence_allowed; | ||
1542 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1543 | "%u receiver->acks_available 4\n", | ||
1544 | receiver->acks_available); | ||
1545 | if (0 != acks_to_add) | ||
1546 | { | ||
1547 | add_acks (receiver->ss_rekey, acks_to_add); | ||
1548 | } | ||
1549 | receiver->ss_rekey = NULL; | ||
1550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1551 | "# rekeying successful\n"); | ||
1552 | GNUNET_STATISTICS_update (stats, | ||
1553 | "# rekeying successful", | ||
1554 | 1, | ||
1555 | GNUNET_NO); | ||
1556 | } | 1461 | } |
1557 | 1462 | ||
1558 | 1463 | ||
@@ -1578,36 +1483,6 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) | |||
1578 | "in handle ack with cmac %s\n", | 1483 | "in handle ack with cmac %s\n", |
1579 | GNUNET_h2s (&ack->cmac)); | 1484 | GNUNET_h2s (&ack->cmac)); |
1580 | 1485 | ||
1581 | if (NULL != receiver->ss_rekey) | ||
1582 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1583 | "We have rekey secret with cmac %s \n", | ||
1584 | GNUNET_h2s (&receiver->ss_rekey->cmac)); | ||
1585 | |||
1586 | if ((NULL != receiver->ss_rekey) && (0 == memcmp (&ack->cmac, | ||
1587 | &receiver->ss_rekey->cmac, | ||
1588 | sizeof(struct | ||
1589 | GNUNET_HashCode))) ) | ||
1590 | { | ||
1591 | allowed = ntohl (ack->sequence_max); | ||
1592 | |||
1593 | if (allowed > receiver->ss_rekey->sequence_allowed) | ||
1594 | { | ||
1595 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1596 | "%u > %u (%u %u) for rekey secrect %s\n", allowed, | ||
1597 | receiver->ss_rekey->sequence_allowed, | ||
1598 | receiver->acks_available, | ||
1599 | ntohl (ack->acks_available), | ||
1600 | GNUNET_h2s (&receiver->ss_rekey->master)); | ||
1601 | |||
1602 | receiver->ss_rekey->sequence_allowed = allowed; | ||
1603 | |||
1604 | if (GNUNET_NO == receiver->rekeying) | ||
1605 | add_acks_rekey (receiver); | ||
1606 | |||
1607 | return GNUNET_NO; | ||
1608 | } | ||
1609 | } | ||
1610 | |||
1611 | (void) pid; | 1486 | (void) pid; |
1612 | for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) | 1487 | for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) |
1613 | { | 1488 | { |
@@ -1615,114 +1490,36 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) | |||
1615 | { | 1490 | { |
1616 | 1491 | ||
1617 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1492 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1618 | "Found matching mac\n"); | 1493 | "Found matching cmac\n"); |
1619 | 1494 | ||
1620 | allowed = ntohl (ack->sequence_max); | 1495 | allowed = ntohl (ack->sequence_ack); |
1621 | 1496 | ||
1622 | if (allowed > ss->sequence_allowed) | 1497 | if (allowed <= ss->sequence_allowed) |
1623 | { | 1498 | { |
1624 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1499 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1625 | "%u > %u (%u %u) for secret %s\n", allowed, | 1500 | "Ignoring ack, not giving us increased window\n."); |
1626 | ss->sequence_allowed, | 1501 | return GNUNET_NO; |
1627 | receiver->acks_available, | ||
1628 | ntohl (ack->acks_available), | ||
1629 | GNUNET_h2s (&ss->master)); | ||
1630 | acks_to_add = (allowed - ss->sequence_allowed); | ||
1631 | if ((GNUNET_NO == receiver->rekeying) && | ||
1632 | (receiver->number_rekeying_kce < 3) ) | ||
1633 | acks_to_add = reset_rekey_kces (receiver, acks_to_add); | ||
1634 | |||
1635 | if ((0 != acks_to_add) && (GNUNET_NO == receiver->rekeying)) | ||
1636 | { | ||
1637 | receiver->acks_available += (allowed - ss->sequence_allowed); | ||
1638 | ss->sequence_allowed = allowed; | ||
1639 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1640 | "%u receiver->acks_available 5\n", | ||
1641 | receiver->acks_available); | ||
1642 | add_acks (ss, acks_to_add); | ||
1643 | } | ||
1644 | } | 1502 | } |
1503 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1504 | "New sequence allows until %u from %u. Acks available to us: %u. For secret %s\n", | ||
1505 | allowed, | ||
1506 | ss->sequence_allowed, | ||
1507 | receiver->acks_available, | ||
1508 | GNUNET_h2s (&ss->master)); | ||
1509 | acks_to_add = (allowed - ss->sequence_allowed); | ||
1510 | GNUNET_assert (0 != acks_to_add); | ||
1511 | receiver->acks_available += (allowed - ss->sequence_allowed); | ||
1512 | ss->sequence_allowed = allowed; | ||
1513 | add_acks (ss, acks_to_add); | ||
1645 | return GNUNET_NO; | 1514 | return GNUNET_NO; |
1646 | } | 1515 | } |
1647 | } | 1516 | } |
1517 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1518 | "Matching cmac not found for ack!\n"); | ||
1648 | return GNUNET_YES; | 1519 | return GNUNET_YES; |
1649 | } | 1520 | } |
1650 | 1521 | ||
1651 | 1522 | ||
1652 | static void | ||
1653 | kce_generate_cb (void *cls) | ||
1654 | { | ||
1655 | struct SharedSecret *ss = cls; | ||
1656 | |||
1657 | ss->sender->kce_task = NULL; | ||
1658 | |||
1659 | if (((GNUNET_NO == ss->sender->rekeying) && (ss->sender->acks_available < | ||
1660 | KCN_TARGET) ) || | ||
1661 | ((ss->sender->ss_rekey == ss) && (GNUNET_YES == ss->sender->rekeying) && | ||
1662 | (ss->sender->acks_available < KCN_TARGET))) | ||
1663 | { | ||
1664 | |||
1665 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1666 | "Precomputing %u keys for master %s\n", | ||
1667 | GENERATE_AT_ONCE, | ||
1668 | GNUNET_h2s (&(ss->master))); | ||
1669 | |||
1670 | for (int i = 0; i < GENERATE_AT_ONCE; i++) | ||
1671 | kce_generate (ss, ++ss->sequence_allowed); | ||
1672 | |||
1673 | if (KCN_TARGET > ss->sender->acks_available) | ||
1674 | { | ||
1675 | ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed ( | ||
1676 | WORKING_QUEUE_INTERVALL, | ||
1677 | kce_generate_cb, | ||
1678 | ss); | ||
1679 | } | ||
1680 | else | ||
1681 | { | ||
1682 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1683 | "We have enough keys.\n"); | ||
1684 | ss_finished = ss; | ||
1685 | ss->sender->kce_task_finished = GNUNET_YES; | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | |||
1690 | } | ||
1691 | |||
1692 | |||
1693 | static void | ||
1694 | kce_generate_rekey_cb (void *cls) | ||
1695 | { | ||
1696 | struct SharedSecret *ss = cls; | ||
1697 | |||
1698 | ss->sender->kce_task_rekey = NULL; | ||
1699 | |||
1700 | if (NULL == ss->sender->kce_task) | ||
1701 | { | ||
1702 | |||
1703 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1704 | "Precomputing keys for rekey master %s\n", | ||
1705 | GNUNET_h2s (&(ss->master))); | ||
1706 | |||
1707 | for (int i = 0; i < GENERATE_AT_ONCE; i++) | ||
1708 | kce_generate (ss, ++ss->sequence_allowed); | ||
1709 | |||
1710 | ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed ( | ||
1711 | WORKING_QUEUE_INTERVALL, | ||
1712 | kce_generate_cb, | ||
1713 | ss); | ||
1714 | ss->sender->kce_task_rekey = NULL; | ||
1715 | } | ||
1716 | else | ||
1717 | { | ||
1718 | ss->sender->kce_task_rekey = GNUNET_SCHEDULER_add_delayed ( | ||
1719 | WORKING_QUEUE_INTERVALL, | ||
1720 | kce_generate_rekey_cb, | ||
1721 | ss); | ||
1722 | } | ||
1723 | } | ||
1724 | |||
1725 | |||
1726 | /** | 1523 | /** |
1727 | * We established a shared secret with a sender. We should try to send | 1524 | * We established a shared secret with a sender. We should try to send |
1728 | * the sender an `struct UDPAck` at the next opportunity to allow the | 1525 | * the sender an `struct UDPAck` at the next opportunity to allow the |
@@ -1730,26 +1527,18 @@ kce_generate_rekey_cb (void *cls) | |||
1730 | * recently). | 1527 | * recently). |
1731 | * | 1528 | * |
1732 | * @param ss shared secret to generate ACKs for | 1529 | * @param ss shared secret to generate ACKs for |
1733 | * @param initial The SharedSecret came with initial KX. | ||
1734 | */ | 1530 | */ |
1735 | static void | 1531 | static void |
1736 | consider_ss_ack (struct SharedSecret *ss, int initial) | 1532 | consider_ss_ack (struct SharedSecret *ss) |
1737 | { | 1533 | { |
1738 | struct GNUNET_SCHEDULER_Task *kce_task_rekey; | 1534 | struct UDPAck ack; |
1739 | struct GNUNET_SCHEDULER_Task *kce_task; | ||
1740 | int kce_task_finished; | ||
1741 | |||
1742 | kce_task_rekey = ss->sender->kce_task_rekey; | ||
1743 | kce_task_finished = ss->sender->kce_task_finished; | ||
1744 | kce_task = ss->sender->kce_task; | ||
1745 | |||
1746 | GNUNET_assert (NULL != ss->sender); | 1535 | GNUNET_assert (NULL != ss->sender); |
1747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1748 | "Considering SS UDPAck %s\n", | 1537 | "Considering SS UDPAck %s\n", |
1749 | GNUNET_i2s_full (&ss->sender->target)); | 1538 | GNUNET_i2s_full (&ss->sender->target)); |
1750 | 1539 | ||
1751 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1752 | "We have %u acks available.\n", | 1541 | "Sender has %u acks available.\n", |
1753 | ss->sender->acks_available); | 1542 | ss->sender->acks_available); |
1754 | /* drop ancient KeyCacheEntries */ | 1543 | /* drop ancient KeyCacheEntries */ |
1755 | while ((NULL != ss->kce_head) && | 1544 | while ((NULL != ss->kce_head) && |
@@ -1758,73 +1547,50 @@ consider_ss_ack (struct SharedSecret *ss, int initial) | |||
1758 | kce_destroy (ss->kce_tail); | 1547 | kce_destroy (ss->kce_tail); |
1759 | 1548 | ||
1760 | 1549 | ||
1761 | if (GNUNET_NO == initial) | 1550 | ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); |
1762 | kce_generate (ss, ++ss->sequence_allowed); | 1551 | ack.header.size = htons (sizeof(ack)); |
1552 | ack.sequence_ack = htonl (ss->sequence_allowed); | ||
1553 | ack.cmac = ss->cmac; | ||
1554 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1555 | "Notifying transport with UDPAck %s, sequence %u and master %s\n", | ||
1556 | GNUNET_i2s_full (&ss->sender->target), | ||
1557 | ss->sequence_allowed, | ||
1558 | GNUNET_h2s (&(ss->master))); | ||
1559 | GNUNET_TRANSPORT_communicator_notify (ch, | ||
1560 | &ss->sender->target, | ||
1561 | COMMUNICATOR_ADDRESS_PREFIX, | ||
1562 | &ack.header); | ||
1563 | } | ||
1763 | 1564 | ||
1764 | if (NULL != kce_task) | ||
1765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1766 | "kce_task is not NULL\n"); | ||
1767 | if (kce_task_finished) | ||
1768 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1769 | "kce_task_finished: GNUNET_YES\n"); | ||
1770 | if (initial) | ||
1771 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1772 | "initial: GNUNET_YES\n"); | ||
1773 | 1565 | ||
1774 | if (kce_task_finished || (GNUNET_NO == initial)) | 1566 | static void |
1775 | { | 1567 | kce_generate_cb (void *cls) |
1776 | struct UDPAck ack; | 1568 | { |
1777 | struct SharedSecret *ss_tell; | 1569 | struct SharedSecret *ss = cls; |
1778 | 1570 | ||
1779 | if (GNUNET_NO != initial) | 1571 | ss->kce_task = NULL; |
1780 | ss_tell = ss_finished; | ||
1781 | else | ||
1782 | ss_tell = ss; | ||
1783 | 1572 | ||
1784 | ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); | 1573 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1785 | ack.header.size = htons (sizeof(ack)); | 1574 | "Precomputing %u keys for master %s\n", |
1786 | ack.sequence_max = htonl (ss_tell->sequence_allowed); | 1575 | GENERATE_AT_ONCE, |
1787 | ack.acks_available = htonl (ss->sender->acks_available); | 1576 | GNUNET_h2s (&(ss->master))); |
1788 | ack.cmac = ss_tell->cmac; | 1577 | if (KCN_TARGET < ss->sender->acks_available) |
1789 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1578 | return; |
1790 | "Notifying transport of %u acks with UDPAck %s and initial %u and master %s\n", | 1579 | for (int i = 0; i < GENERATE_AT_ONCE; i++) |
1791 | ack.acks_available, | 1580 | kce_generate (ss, ++ss->sequence_allowed); |
1792 | GNUNET_i2s_full (&ss_tell->sender->target), | ||
1793 | initial, | ||
1794 | GNUNET_h2s (&(ss_tell->master))); | ||
1795 | GNUNET_TRANSPORT_communicator_notify (ch, | ||
1796 | &ss_tell->sender->target, | ||
1797 | COMMUNICATOR_ADDRESS_PREFIX, | ||
1798 | &ack.header); | ||
1799 | if (GNUNET_NO != initial) | ||
1800 | { | ||
1801 | destroy_all_secrets (ss, GNUNET_YES); | ||
1802 | ss->sender->kce_task_finished = GNUNET_NO; | ||
1803 | } | ||
1804 | } | ||
1805 | else if ((NULL == ss->sender->kce_task) && ((KCN_THRESHOLD > | ||
1806 | ss->sender->acks_available) || | ||
1807 | (GNUNET_YES == | ||
1808 | ss->sender->rekeying) || | ||
1809 | (ss->sender->num_secrets > | ||
1810 | MAX_SECRETS) )) | ||
1811 | { | ||
1812 | 1581 | ||
1813 | // 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. | 1582 | if (KCN_TARGET > ss->sender->acks_available) |
1814 | ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed ( | 1583 | { |
1584 | ss->kce_task = GNUNET_SCHEDULER_add_delayed ( | ||
1815 | WORKING_QUEUE_INTERVALL, | 1585 | WORKING_QUEUE_INTERVALL, |
1816 | kce_generate_cb, | 1586 | kce_generate_cb, |
1817 | ss); | 1587 | ss); |
1818 | ss->sender->kce_task_finished = GNUNET_NO; | 1588 | return; |
1819 | |||
1820 | } | ||
1821 | else if ((NULL == kce_task_rekey) && (GNUNET_YES == | ||
1822 | ss->sender->rekeying) ) | ||
1823 | { | ||
1824 | kce_task_rekey = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, | ||
1825 | kce_generate_rekey_cb, | ||
1826 | ss); | ||
1827 | } | 1589 | } |
1590 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1591 | "We have enough keys.\n"); | ||
1592 | ss->kce_task_finished = GNUNET_YES; | ||
1593 | consider_ss_ack (ss); | ||
1828 | } | 1594 | } |
1829 | 1595 | ||
1830 | 1596 | ||
@@ -1844,12 +1610,12 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1844 | const struct GNUNET_MessageHeader *hdr; | 1610 | const struct GNUNET_MessageHeader *hdr; |
1845 | const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_pubkey; | 1611 | const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_pubkey; |
1846 | const struct UDPAck *ack; | 1612 | const struct UDPAck *ack; |
1613 | const struct UDPRekey *rekey; | ||
1847 | struct SharedSecret *ss_rekey; | 1614 | struct SharedSecret *ss_rekey; |
1848 | const char *buf_pos = buf; | 1615 | const char *buf_pos = buf; |
1849 | size_t bytes_remaining = buf_size; | 1616 | size_t bytes_remaining = buf_size; |
1850 | uint16_t type; | 1617 | uint16_t type; |
1851 | 1618 | ||
1852 | buf_pos += sizeof (uint16_t); | ||
1853 | hdr = (struct GNUNET_MessageHeader*) buf_pos; | 1619 | hdr = (struct GNUNET_MessageHeader*) buf_pos; |
1854 | if (sizeof(*hdr) > bytes_remaining) | 1620 | if (sizeof(*hdr) > bytes_remaining) |
1855 | { | 1621 | { |
@@ -1868,14 +1634,13 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1868 | switch (type) | 1634 | switch (type) |
1869 | { | 1635 | { |
1870 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY: | 1636 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY: |
1871 | ephemeral_pubkey = (struct GNUNET_CRYPTO_EcdhePublicKey *) buf_pos; | 1637 | rekey = (struct UDPRekey*) buf_pos; |
1872 | ss_rekey = setup_shared_secret_dec (ephemeral_pubkey); | 1638 | ss_rekey = setup_shared_secret_dec (&rekey->ephemeral); |
1873 | ss_rekey->sender = sender; | 1639 | ss_rekey->sender = sender; |
1874 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey); | 1640 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey); |
1875 | sender->ss_rekey = ss_rekey; | ||
1876 | sender->num_secrets++; | 1641 | sender->num_secrets++; |
1877 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1642 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1878 | "Received secret with cmac %s\n", | 1643 | "Received rekey secret with cmac %s\n", |
1879 | GNUNET_h2s (&(ss_rekey->cmac))); | 1644 | GNUNET_h2s (&(ss_rekey->cmac))); |
1880 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1645 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1881 | "Received secret with master %s.\n", | 1646 | "Received secret with master %s.\n", |
@@ -1889,7 +1654,14 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1889 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1890 | "We have %u acks available.\n", | 1655 | "We have %u acks available.\n", |
1891 | ss_rekey->sender->acks_available); | 1656 | ss_rekey->sender->acks_available); |
1892 | consider_ss_ack (ss_rekey, GNUNET_YES); | 1657 | ss_rekey->kce_task = GNUNET_SCHEDULER_add_delayed ( |
1658 | WORKING_QUEUE_INTERVALL, | ||
1659 | kce_generate_cb, | ||
1660 | ss_rekey); | ||
1661 | // FIXME: Theoretically, this could be an Ack | ||
1662 | buf_pos += ntohs (hdr->size); | ||
1663 | bytes_remaining -= ntohs (hdr->size); | ||
1664 | pass_plaintext_to_core (sender, buf_pos, bytes_remaining); | ||
1893 | break; | 1665 | break; |
1894 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: | 1666 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: |
1895 | /* lookup master secret by 'cmac', then update sequence_max */ | 1667 | /* lookup master secret by 'cmac', then update sequence_max */ |
@@ -1939,6 +1711,7 @@ decrypt_box (const struct UDPBox *box, | |||
1939 | sizeof(out_buf), | 1711 | sizeof(out_buf), |
1940 | out_buf)) | 1712 | out_buf)) |
1941 | { | 1713 | { |
1714 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed decryption.\n"); | ||
1942 | GNUNET_STATISTICS_update (stats, | 1715 | GNUNET_STATISTICS_update (stats, |
1943 | "# Decryption failures with valid KCE", | 1716 | "# Decryption failures with valid KCE", |
1944 | 1, | 1717 | 1, |
@@ -2180,6 +1953,18 @@ sock_read (void *cls) | |||
2180 | "Found KCE with kid %s\n", | 1953 | "Found KCE with kid %s\n", |
2181 | GNUNET_sh2s (&box->kid)); | 1954 | GNUNET_sh2s (&box->kid)); |
2182 | decrypt_box (box, (size_t) rcvd, kce); | 1955 | decrypt_box (box, (size_t) rcvd, kce); |
1956 | if ((NULL == kce->ss->kce_task) && | ||
1957 | (GNUNET_YES == kce->ss->kce_task_finished) && | ||
1958 | (kce->ss->sender->acks_available < KCN_THRESHOLD)) | ||
1959 | { | ||
1960 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1961 | "Sender has %u ack left which is under threshold.\n", | ||
1962 | kce->ss->sender->acks_available); | ||
1963 | kce->ss->kce_task = GNUNET_SCHEDULER_add_delayed ( | ||
1964 | WORKING_QUEUE_INTERVALL, | ||
1965 | kce_generate_cb, | ||
1966 | kce->ss); | ||
1967 | } | ||
2183 | continue; | 1968 | continue; |
2184 | } | 1969 | } |
2185 | } | 1970 | } |
@@ -2270,7 +2055,6 @@ sock_read (void *cls) | |||
2270 | char pbuf[rcvd - sizeof(struct InitialKX)]; | 2055 | char pbuf[rcvd - sizeof(struct InitialKX)]; |
2271 | const struct UDPConfirmation *uc; | 2056 | const struct UDPConfirmation *uc; |
2272 | struct SenderAddress *sender; | 2057 | struct SenderAddress *sender; |
2273 | uint16_t rekeying; | ||
2274 | 2058 | ||
2275 | kx = (const struct InitialKX *) buf; | 2059 | kx = (const struct InitialKX *) buf; |
2276 | ss = setup_shared_secret_dec (&kx->ephemeral); | 2060 | ss = setup_shared_secret_dec (&kx->ephemeral); |
@@ -2315,6 +2099,15 @@ sock_read (void *cls) | |||
2315 | sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen); | 2099 | sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen); |
2316 | ss->sender = sender; | 2100 | ss->sender = sender; |
2317 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss); | 2101 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss); |
2102 | if ((NULL == ss->kce_task) && (GNUNET_NO == | ||
2103 | ss->kce_task_finished)) | ||
2104 | { | ||
2105 | // 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. | ||
2106 | ss->kce_task = GNUNET_SCHEDULER_add_delayed ( | ||
2107 | WORKING_QUEUE_INTERVALL, | ||
2108 | kce_generate_cb, | ||
2109 | ss); | ||
2110 | } | ||
2318 | sender->num_secrets++; | 2111 | sender->num_secrets++; |
2319 | GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO); | 2112 | GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO); |
2320 | GNUNET_STATISTICS_update (stats, | 2113 | GNUNET_STATISTICS_update (stats, |
@@ -2489,20 +2282,10 @@ do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size) | |||
2489 | } | 2282 | } |
2490 | 2283 | ||
2491 | 2284 | ||
2492 | /** | ||
2493 | * Signature of functions implementing the sending functionality of a | ||
2494 | * message queue. | ||
2495 | * | ||
2496 | * @param mq the message queue | ||
2497 | * @param msg the message to send | ||
2498 | * @param impl_state our `struct ReceiverAddress` | ||
2499 | */ | ||
2500 | static void | 2285 | static void |
2501 | mq_send_kx (struct GNUNET_MQ_Handle *mq, | 2286 | send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct |
2502 | const struct GNUNET_MessageHeader *msg, | 2287 | ReceiverAddress *receiver) |
2503 | void *impl_state) | ||
2504 | { | 2288 | { |
2505 | struct ReceiverAddress *receiver = impl_state; | ||
2506 | uint16_t msize = ntohs (msg->size); | 2289 | uint16_t msize = ntohs (msg->size); |
2507 | struct UdpHandshakeSignature uhs; | 2290 | struct UdpHandshakeSignature uhs; |
2508 | struct UDPConfirmation uc; | 2291 | struct UDPConfirmation uc; |
@@ -2510,10 +2293,8 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2510 | char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)]; | 2293 | char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)]; |
2511 | size_t dpos; | 2294 | size_t dpos; |
2512 | gcry_cipher_hd_t out_cipher; | 2295 | gcry_cipher_hd_t out_cipher; |
2513 | uint16_t rekey_nbo; | ||
2514 | struct SharedSecret *ss; | 2296 | struct SharedSecret *ss; |
2515 | 2297 | ||
2516 | GNUNET_assert (mq == receiver->kx_mq); | ||
2517 | if (msize > receiver->kx_mtu) | 2298 | if (msize > receiver->kx_mtu) |
2518 | { | 2299 | { |
2519 | GNUNET_break (0); | 2300 | GNUNET_break (0); |
@@ -2555,13 +2336,6 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2555 | &uc, | 2336 | &uc, |
2556 | sizeof(uc))); | 2337 | sizeof(uc))); |
2557 | dpos += sizeof(uc); | 2338 | dpos += sizeof(uc); |
2558 | rekey_nbo = htons (receiver->rekeying); | ||
2559 | GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher, | ||
2560 | &dgram[dpos], | ||
2561 | sizeof (uint16_t), | ||
2562 | &rekey_nbo, | ||
2563 | sizeof(uint16_t))); | ||
2564 | dpos += sizeof (uint16_t); | ||
2565 | /* Append encrypted payload to dgram */ | 2339 | /* Append encrypted payload to dgram */ |
2566 | GNUNET_assert ( | 2340 | GNUNET_assert ( |
2567 | 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); | 2341 | 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); |
@@ -2584,53 +2358,54 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2584 | msize, | 2358 | msize, |
2585 | GNUNET_a2s (receiver->address, | 2359 | GNUNET_a2s (receiver->address, |
2586 | receiver->address_len)); | 2360 | receiver->address_len)); |
2587 | GNUNET_MQ_impl_send_continue (mq); | ||
2588 | } | 2361 | } |
2589 | 2362 | ||
2590 | 2363 | ||
2364 | /** | ||
2365 | * Signature of functions implementing the sending functionality of a | ||
2366 | * message queue. | ||
2367 | * | ||
2368 | * @param mq the message queue | ||
2369 | * @param msg the message to send | ||
2370 | * @param impl_state our `struct ReceiverAddress` | ||
2371 | */ | ||
2591 | static void | 2372 | static void |
2592 | check_for_rekeying (struct ReceiverAddress *receiver) | 2373 | mq_send_kx (struct GNUNET_MQ_Handle *mq, |
2374 | const struct GNUNET_MessageHeader *msg, | ||
2375 | void *impl_state) | ||
2593 | { | 2376 | { |
2377 | struct ReceiverAddress *receiver = impl_state; | ||
2594 | 2378 | ||
2595 | struct GNUNET_TIME_Relative rt; | 2379 | GNUNET_assert (mq == receiver->kx_mq); |
2380 | send_msg_with_kx (msg, receiver); | ||
2381 | GNUNET_MQ_impl_send_continue (mq); | ||
2382 | } | ||
2596 | 2383 | ||
2597 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2598 | "Timeout is %llu\n.", | ||
2599 | (unsigned long long) receiver->rekey_timeout.abs_value_us); | ||
2600 | 2384 | ||
2601 | if (0 == receiver->rekey_timeout.abs_value_us) | 2385 | static void |
2602 | { | 2386 | create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct |
2603 | receiver->rekey_timeout = GNUNET_TIME_relative_to_absolute ( | 2387 | UDPRekey *rekey) |
2604 | rekey_interval); | 2388 | { |
2605 | } | 2389 | uint8_t is_ss_rekey_sequence_allowed_zero = GNUNET_NO; |
2606 | else | 2390 | uint8_t is_acks_available_below = GNUNET_NO; |
2607 | { | 2391 | uint8_t send_rekey = GNUNET_NO; |
2608 | rt = GNUNET_TIME_absolute_get_remaining (receiver->rekey_timeout); | 2392 | struct SharedSecret *ss_rekey; |
2609 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2610 | "Relative time is %llu and timeout is %llu\n.", | ||
2611 | (unsigned long long) rt.rel_value_us, | ||
2612 | (unsigned long long) receiver->rekey_timeout.abs_value_us); | ||
2613 | 2393 | ||
2614 | if ((0 == rt.rel_value_us) || (receiver->rekey_send_bytes > | 2394 | ss->rekey_initiated = GNUNET_YES; |
2615 | rekey_max_bytes) ) | 2395 | /* setup key material */ |
2616 | { | 2396 | ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral, |
2617 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2397 | receiver); |
2618 | "Bytes send %llu greater than %llu max bytes\n.", | 2398 | ss_rekey->sequence_allowed = 0; |
2619 | (unsigned long long) receiver->rekey_send_bytes, | 2399 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2620 | rekey_max_bytes); | 2400 | "Setup secret with k = %s\n", |
2621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2401 | GNUNET_h2s (&(ss_rekey->master))); |
2622 | "Relative time is %llu and timeout is %llu\n.", | 2402 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2623 | (unsigned long long) rt.rel_value_us, | 2403 | "Setup secret with H(k) = %s\n", |
2624 | (unsigned long long) receiver->rekey_timeout.abs_value_us); | 2404 | GNUNET_h2s (&(ss_rekey->cmac))); |
2625 | 2405 | ||
2626 | receiver->rekey_timeout.abs_value_us = 0; | 2406 | /* Append encrypted payload to dgram */ |
2627 | receiver->rekey_send_bytes = 0; | 2407 | rekey->header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY); |
2628 | receiver->ss_rekey = NULL; | 2408 | rekey->header.size = htons (sizeof (struct UDPRekey)); |
2629 | // destroy_all_secrets (ss, GNUNET_NO); | ||
2630 | receiver->rekeying = GNUNET_YES; | ||
2631 | receiver->rekey_acks_available = receiver->acks_available; | ||
2632 | } | ||
2633 | } | ||
2634 | } | 2409 | } |
2635 | 2410 | ||
2636 | 2411 | ||
@@ -2643,100 +2418,72 @@ send_UDPRekey (struct ReceiverAddress *receiver, struct SharedSecret *ss) | |||
2643 | uint16_t not_below; | 2418 | uint16_t not_below; |
2644 | struct UDPBox *box; | 2419 | struct UDPBox *box; |
2645 | struct UDPRekey rekey; | 2420 | struct UDPRekey rekey; |
2646 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_pubkey; | 2421 | struct SharedSecret *ss_rekey; |
2647 | size_t dpos; | 2422 | size_t dpos; |
2648 | 2423 | ||
2649 | char rekey_dgram[sizeof (struct UDPBox) + sizeof(struct UDPRekey) | 2424 | char rekey_dgram[sizeof (struct UDPBox) + sizeof(struct UDPRekey) |
2650 | + receiver->d_mtu]; | 2425 | + receiver->d_mtu]; |
2651 | 2426 | if (GNUNET_YES == ss->rekey_initiated) | |
2652 | if (NULL == receiver->ss_rekey) | ||
2653 | { | 2427 | { |
2654 | /* setup key material */ | 2428 | return; |
2655 | receiver->ss_rekey = setup_shared_secret_ephemeral (&ephemeral_pubkey, | 2429 | } |
2656 | receiver); | 2430 | ss->rekey_initiated = GNUNET_YES; |
2657 | receiver->ss_rekey->sequence_allowed = 0; | 2431 | /* setup key material */ |
2658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2432 | ss_rekey = setup_shared_secret_ephemeral (&rekey.ephemeral, |
2659 | "Setup secret with cmac %s\n", | 2433 | receiver); |
2660 | GNUNET_h2s (&(receiver->ss_rekey->cmac))); | 2434 | ss_rekey->sequence_allowed = 0; |
2661 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2662 | "Setup secret with master %s.\n", | ||
2663 | GNUNET_h2s (&(receiver->ss_rekey->master))); | ||
2664 | } | ||
2665 | /* WTF is this */ | ||
2666 | not_below = (receiver->rekey_acks_available | ||
2667 | - (receiver->rekey_acks_available % 3)) / 3; | ||
2668 | is_ss_rekey_sequence_allowed_zero = (0 == | ||
2669 | receiver->ss_rekey->sequence_allowed); | ||
2670 | is_acks_available_below = (receiver->acks_available >= not_below); | ||
2671 | send_rekey = (0 == (receiver->acks_available - not_below) % not_below) && | ||
2672 | is_acks_available_below && is_ss_rekey_sequence_allowed_zero; | ||
2673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2674 | "send_rekey: %u, %u, %u\n", | 2436 | "Setup secret with k = %s\n", |
2675 | send_rekey, | 2437 | GNUNET_h2s (&(ss_rekey->master))); |
2676 | receiver->rekey_acks_available, | 2438 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2677 | receiver->acks_available); | 2439 | "Setup secret with H(k) = %s\n", |
2440 | GNUNET_h2s (&(ss_rekey->cmac))); | ||
2678 | 2441 | ||
2679 | if (send_rekey) | 2442 | gcry_cipher_hd_t rekey_out_cipher; |
2680 | { | ||
2681 | GNUNET_assert (0 != receiver->number_rekeying_kce); | ||
2682 | gcry_cipher_hd_t rekey_out_cipher; | ||
2683 | 2443 | ||
2684 | while (NULL != ss && ss->sequence_used >= ss->sequence_allowed) | 2444 | /* Find suitable secret to encrypt this rekey message */ |
2685 | { | 2445 | // while (NULL != ss && ss->sequence_used >= ss->sequence_allowed) |
2686 | ss = ss->prev; | 2446 | // ss = ss->prev; |
2687 | } | ||
2688 | 2447 | ||
2689 | if (NULL != ss) | 2448 | box = (struct UDPBox *) rekey_dgram; |
2690 | { | 2449 | ss->sequence_used++; |
2691 | box = (struct UDPBox *) rekey_dgram; | 2450 | get_kid (&ss->master, ss->sequence_used, &box->kid); |
2692 | ss->sequence_used++; | 2451 | setup_cipher (&ss->master, ss->sequence_used, &rekey_out_cipher); |
2693 | get_kid (&ss->master, ss->sequence_used, &box->kid); | 2452 | /* Append encrypted payload to dgram */ |
2694 | receiver->number_rekeying_kce--; | 2453 | rekey.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY); |
2695 | setup_cipher (&ss->master, ss->sequence_used, &rekey_out_cipher); | 2454 | rekey.header.size = htons (sizeof (struct UDPRekey)); |
2696 | /* Append encrypted payload to dgram */ | ||
2697 | rekey.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY); | ||
2698 | rekey.header.size = htons (sizeof (struct UDPRekey)); | ||
2699 | |||
2700 | GNUNET_assert ( | ||
2701 | 0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey, | ||
2702 | sizeof(struct UDPRekey), | ||
2703 | &box[1], | ||
2704 | sizeof(struct UDPRekey))); | ||
2705 | dpos = sizeof(struct UDPRekey) + sizeof (struct UDPBox); | ||
2706 | do_pad (rekey_out_cipher, &rekey_dgram[dpos], sizeof(rekey_dgram) | ||
2707 | - dpos); | ||
2708 | GNUNET_assert (0 == gcry_cipher_gettag (rekey_out_cipher, | ||
2709 | box->gcm_tag, | ||
2710 | sizeof(box->gcm_tag))); | ||
2711 | gcry_cipher_close (rekey_out_cipher); | ||
2712 | 2455 | ||
2713 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2456 | GNUNET_assert ( |
2714 | "Sending rekey with kid %s and new pubkey\n", | 2457 | 0 == gcry_cipher_encrypt (rekey_out_cipher, &box[1], |
2715 | GNUNET_sh2s (&box->kid)); | 2458 | sizeof(struct UDPRekey), |
2716 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2459 | &rekey, |
2717 | "Sending rekey with cmac %s\n", | 2460 | sizeof(struct UDPRekey))); |
2718 | GNUNET_h2s (&(receiver->ss_rekey->cmac))); | 2461 | dpos = sizeof(struct UDPRekey) + sizeof (struct UDPBox); |
2719 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2462 | do_pad (rekey_out_cipher, &rekey_dgram[dpos], sizeof(rekey_dgram) |
2720 | "%u rekey kces left.\n", | 2463 | - dpos); |
2721 | receiver->number_rekeying_kce); | 2464 | GNUNET_assert (0 == gcry_cipher_gettag (rekey_out_cipher, |
2465 | box->gcm_tag, | ||
2466 | sizeof(box->gcm_tag))); | ||
2467 | gcry_cipher_close (rekey_out_cipher); | ||
2722 | 2468 | ||
2723 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | 2469 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2724 | rekey_dgram, | 2470 | "Sending rekey with kid %s and new pubkey\n", |
2725 | sizeof(rekey_dgram), | 2471 | GNUNET_sh2s (&box->kid)); |
2726 | receiver->address, | 2472 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, |
2727 | receiver->address_len)) | 2473 | rekey_dgram, |
2728 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | 2474 | sizeof(rekey_dgram), |
2475 | receiver->address, | ||
2476 | receiver->address_len)) | ||
2477 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | ||
2729 | 2478 | ||
2730 | receiver->acks_available--; | 2479 | /* FIXME what is this */ |
2731 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2480 | receiver->acks_available--; |
2732 | "%u receiver->acks_available 1\n", | 2481 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2733 | receiver->acks_available); | 2482 | "%u receiver->acks_available 1\n", |
2734 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2483 | receiver->acks_available); |
2735 | "Sending UDPRekey to %s\n", GNUNET_a2s (receiver->address, | 2484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2736 | receiver-> | 2485 | "Sending UDPRekey to %s\n", GNUNET_a2s (receiver->address, |
2737 | address_len)); | 2486 | receiver->address_len)); |
2738 | } | ||
2739 | } | ||
2740 | } | 2487 | } |
2741 | 2488 | ||
2742 | 2489 | ||
@@ -2754,6 +2501,8 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2754 | void *impl_state) | 2501 | void *impl_state) |
2755 | { | 2502 | { |
2756 | struct ReceiverAddress *receiver = impl_state; | 2503 | struct ReceiverAddress *receiver = impl_state; |
2504 | struct UDPRekey rekey; | ||
2505 | int inject_rekey = GNUNET_NO; | ||
2757 | uint16_t msize = ntohs (msg->size); | 2506 | uint16_t msize = ntohs (msg->size); |
2758 | 2507 | ||
2759 | GNUNET_assert (mq == receiver->d_mq); | 2508 | GNUNET_assert (mq == receiver->d_mq); |
@@ -2776,16 +2525,35 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2776 | /* begin "BOX" encryption method, scan for ACKs from tail! */ | 2525 | /* begin "BOX" encryption method, scan for ACKs from tail! */ |
2777 | for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev) | 2526 | for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev) |
2778 | { | 2527 | { |
2528 | size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu; | ||
2529 | if (ss->sequence_used >= ss->sequence_allowed) | ||
2530 | { | ||
2531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2532 | "Skipping ss because no acks to use.\n"); | ||
2533 | continue; | ||
2534 | } | ||
2535 | if (ss->bytes_sent > rekey_max_bytes - sizeof (struct UDPRekey) | ||
2536 | - receiver->d_mtu) | ||
2537 | { | ||
2538 | if (ss->rekey_initiated == GNUNET_NO) | ||
2539 | { | ||
2540 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2541 | "Injecting rekey for ss with byte sent %u\n", | ||
2542 | ss->bytes_sent); | ||
2543 | create_rekey (receiver, ss, &rekey); | ||
2544 | inject_rekey = GNUNET_YES; | ||
2545 | payload_len += sizeof (rekey); | ||
2546 | ss->rekey_initiated = GNUNET_YES; | ||
2547 | } | ||
2548 | } | ||
2779 | if (0 < ss->sequence_used) | 2549 | if (0 < ss->sequence_used) |
2780 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2781 | "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n", | 2551 | "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n", |
2782 | GNUNET_h2s (&ss->master), | 2552 | GNUNET_h2s (&ss->master), |
2783 | ss->sequence_used, | 2553 | ss->sequence_used, |
2784 | ss->sequence_allowed); | 2554 | ss->sequence_allowed); |
2785 | if (ss->sequence_used >= ss->sequence_allowed) | ||
2786 | continue; | ||
2787 | 2555 | ||
2788 | char dgram[sizeof(struct UDPBox) + receiver->d_mtu]; | 2556 | char dgram[payload_len]; |
2789 | struct UDPBox *box; | 2557 | struct UDPBox *box; |
2790 | gcry_cipher_hd_t out_cipher; | 2558 | gcry_cipher_hd_t out_cipher; |
2791 | size_t dpos; | 2559 | size_t dpos; |
@@ -2797,6 +2565,10 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2797 | /* Append encrypted payload to dgram */ | 2565 | /* Append encrypted payload to dgram */ |
2798 | dpos = sizeof(struct UDPBox); | 2566 | dpos = sizeof(struct UDPBox); |
2799 | GNUNET_assert ( | 2567 | GNUNET_assert ( |
2568 | 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey), | ||
2569 | &rekey, sizeof (rekey))); | ||
2570 | dpos += sizeof (rekey); | ||
2571 | GNUNET_assert ( | ||
2800 | 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); | 2572 | 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); |
2801 | dpos += msize; | 2573 | dpos += msize; |
2802 | do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); | 2574 | do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); |
@@ -2805,50 +2577,24 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2805 | sizeof(box->gcm_tag))); | 2577 | sizeof(box->gcm_tag))); |
2806 | gcry_cipher_close (out_cipher); | 2578 | gcry_cipher_close (out_cipher); |
2807 | 2579 | ||
2808 | receiver->rekey_send_bytes += sizeof(struct UDPBox) + receiver->d_mtu; | ||
2809 | |||
2810 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | 2580 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, |
2811 | dgram, | 2581 | dgram, |
2812 | sizeof(dgram), | 2582 | payload_len, // FIXME why always send sizeof dgram? |
2813 | receiver->address, | 2583 | receiver->address, |
2814 | receiver->address_len)) | 2584 | receiver->address_len)) |
2815 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | 2585 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); |
2816 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2586 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2817 | "Sending UDPBox with payload size %u, %u acks left\n", | 2587 | "Sending UDPBox with payload size %u, %u acks left, %u bytes sent\n", |
2818 | msize, | 2588 | msize, |
2819 | receiver->acks_available); | 2589 | receiver->acks_available); |
2590 | ss->bytes_sent += sizeof (dgram); | ||
2820 | GNUNET_MQ_impl_send_continue (mq); | 2591 | GNUNET_MQ_impl_send_continue (mq); |
2821 | receiver->acks_available--; | 2592 | receiver->acks_available--; |
2822 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2823 | "%u receiver->acks_available 2\n", | ||
2824 | receiver->acks_available); | ||
2825 | check_for_rekeying (receiver); | ||
2826 | if (0 == receiver->acks_available - receiver->number_rekeying_kce) | ||
2827 | { | ||
2828 | /* We have no more ACKs */ | ||
2829 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2830 | "No more acks\n"); | ||
2831 | if (GNUNET_YES == receiver->rekeying) | ||
2832 | { | ||
2833 | receiver->rekeying = GNUNET_NO; | ||
2834 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2835 | "Sender stopped rekeying\n"); | ||
2836 | |||
2837 | if ((NULL != receiver->ss_rekey) && (0 < | ||
2838 | receiver->ss_rekey-> | ||
2839 | sequence_allowed) ) | ||
2840 | add_acks_rekey (receiver); | ||
2841 | } | ||
2842 | else | ||
2843 | { | ||
2844 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2845 | "rekeying\n"); | ||
2846 | send_UDPRekey (receiver, ss); | ||
2847 | } | ||
2848 | } | ||
2849 | |||
2850 | return; | 2593 | return; |
2851 | } | 2594 | } |
2595 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2596 | "No suitable ss found, sending as KX...\n"); | ||
2597 | send_msg_with_kx (msg, receiver); | ||
2852 | } | 2598 | } |
2853 | 2599 | ||
2854 | 2600 | ||
@@ -3111,16 +2857,6 @@ get_sender_delete_it (void *cls, | |||
3111 | (void) cls; | 2857 | (void) cls; |
3112 | (void) target; | 2858 | (void) target; |
3113 | 2859 | ||
3114 | if (NULL != sender->kce_task_rekey) | ||
3115 | { | ||
3116 | GNUNET_SCHEDULER_cancel (sender->kce_task_rekey); | ||
3117 | sender->kce_task_rekey = NULL; | ||
3118 | } | ||
3119 | if (NULL != sender->kce_task) | ||
3120 | { | ||
3121 | GNUNET_SCHEDULER_cancel (sender->kce_task); | ||
3122 | sender->kce_task = NULL; | ||
3123 | } | ||
3124 | 2860 | ||
3125 | sender_destroy (sender); | 2861 | sender_destroy (sender); |
3126 | return GNUNET_OK; | 2862 | return GNUNET_OK; |