diff options
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 810 |
1 files changed, 660 insertions, 150 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index e967e8e9a..849adf4ab 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -51,7 +51,7 @@ | |||
51 | /** | 51 | /** |
52 | * How often do we rekey based on time (at least) | 52 | * How often do we rekey based on time (at least) |
53 | */ | 53 | */ |
54 | #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS | 54 | #define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * How long do we wait until we must have received the initial KX? | 57 | * How long do we wait until we must have received the initial KX? |
@@ -207,6 +207,11 @@ struct InitialKX | |||
207 | * key derived from the handshake with sequence number zero. | 207 | * key derived from the handshake with sequence number zero. |
208 | */ | 208 | */ |
209 | char gcm_tag[GCM_TAG_SIZE]; | 209 | char gcm_tag[GCM_TAG_SIZE]; |
210 | |||
211 | /** | ||
212 | * A flag indicating, if the sender is doing rekeying. | ||
213 | */ | ||
214 | int rekeying; | ||
210 | }; | 215 | }; |
211 | 216 | ||
212 | 217 | ||
@@ -339,8 +344,42 @@ struct UDPBox | |||
339 | * `struct UdpHandshakeSignature`. | 344 | * `struct UdpHandshakeSignature`. |
340 | */ | 345 | */ |
341 | char gcm_tag[GCM_TAG_SIZE]; | 346 | char gcm_tag[GCM_TAG_SIZE]; |
347 | |||
348 | /** | ||
349 | * A flag indicating, if the sender is doing rekeying. | ||
350 | */ | ||
351 | int rekeying; | ||
342 | }; | 352 | }; |
343 | 353 | ||
354 | /** | ||
355 | * UDP message box. Always sent encrypted, only allowed after | ||
356 | * the receiver sent a `struct UDPAck` for the base key! | ||
357 | */ | ||
358 | struct UDPRekey | ||
359 | { | ||
360 | /** | ||
361 | * Key and IV identification code. KDF applied to an acknowledged | ||
362 | * base key and a sequence number. Sequence numbers must be used | ||
363 | * monotonically increasing up to the maximum specified in | ||
364 | * `struct UDPAck`. Without further `struct UDPAck`s, the sender | ||
365 | * must fall back to sending handshakes! | ||
366 | */ | ||
367 | struct GNUNET_ShortHashCode kid; | ||
368 | |||
369 | /** | ||
370 | * 128-bit authentication tag for the following encrypted message, | ||
371 | * from GCM. MAC starts at the @e body_start that follows and | ||
372 | * extends until the end of the UDP payload. If the @e hmac is | ||
373 | * wrong, the receiver should check if the message might be a | ||
374 | * `struct UdpHandshakeSignature`. | ||
375 | */ | ||
376 | char gcm_tag[GCM_TAG_SIZE]; | ||
377 | |||
378 | /** | ||
379 | * Sender's identity | ||
380 | */ | ||
381 | struct GNUNET_PeerIdentity sender; | ||
382 | }; | ||
344 | 383 | ||
345 | GNUNET_NETWORK_STRUCT_END | 384 | GNUNET_NETWORK_STRUCT_END |
346 | 385 | ||
@@ -471,6 +510,11 @@ struct SharedSecret | |||
471 | struct SenderAddress | 510 | struct SenderAddress |
472 | { | 511 | { |
473 | /** | 512 | /** |
513 | * Flag indicating sender is initiated rekeying for this receiver. | ||
514 | */ | ||
515 | int rekeying; | ||
516 | |||
517 | /** | ||
474 | * To whom are we talking to. | 518 | * To whom are we talking to. |
475 | */ | 519 | */ |
476 | struct GNUNET_PeerIdentity target; | 520 | struct GNUNET_PeerIdentity target; |
@@ -520,6 +564,11 @@ struct SenderAddress | |||
520 | * Which network type does this queue use? | 564 | * Which network type does this queue use? |
521 | */ | 565 | */ |
522 | enum GNUNET_NetworkType nt; | 566 | enum GNUNET_NetworkType nt; |
567 | |||
568 | /** | ||
569 | * sender_destroy already called on sender. | ||
570 | */ | ||
571 | int sender_destroy_called; | ||
523 | }; | 572 | }; |
524 | 573 | ||
525 | 574 | ||
@@ -529,6 +578,37 @@ struct SenderAddress | |||
529 | */ | 578 | */ |
530 | struct ReceiverAddress | 579 | struct ReceiverAddress |
531 | { | 580 | { |
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 | /** | ||
598 | * Timeout for this receiver address. | ||
599 | */ | ||
600 | struct GNUNET_TIME_Absolute rekey_timeout; | ||
601 | |||
602 | /** | ||
603 | * Flag indicating sender is initiated rekeying for this receiver. | ||
604 | */ | ||
605 | int rekeying; | ||
606 | |||
607 | /** | ||
608 | * Numer of kce we retain for sending the rekeying shared secret. | ||
609 | */ | ||
610 | int number_rekeying_kce; | ||
611 | |||
532 | /** | 612 | /** |
533 | * To whom are we talking to. | 613 | * To whom are we talking to. |
534 | */ | 614 | */ |
@@ -615,8 +695,12 @@ struct ReceiverAddress | |||
615 | * Which network type does this queue use? | 695 | * Which network type does this queue use? |
616 | */ | 696 | */ |
617 | enum GNUNET_NetworkType nt; | 697 | enum GNUNET_NetworkType nt; |
618 | }; | ||
619 | 698 | ||
699 | /** | ||
700 | * receiver_destroy already called on receiver. | ||
701 | */ | ||
702 | int receiver_destroy_called; | ||
703 | }; | ||
620 | 704 | ||
621 | /** | 705 | /** |
622 | * Interface we broadcast our presence on. | 706 | * Interface we broadcast our presence on. |
@@ -671,9 +755,9 @@ struct BroadcastInterface | |||
671 | }; | 755 | }; |
672 | 756 | ||
673 | /** | 757 | /** |
674 | * Timeout for this receiver address. | 758 | * The rekey interval |
675 | */ | 759 | */ |
676 | struct GNUNET_TIME_Absolute *rekey_timeout; | 760 | static struct GNUNET_TIME_Relative rekey_interval; |
677 | 761 | ||
678 | /** | 762 | /** |
679 | * Shared secret we finished the last kce working queue for. | 763 | * Shared secret we finished the last kce working queue for. |
@@ -701,6 +785,11 @@ static struct GNUNET_SCHEDULER_Task *timeout_task; | |||
701 | static struct GNUNET_SCHEDULER_Task *kce_task; | 785 | static struct GNUNET_SCHEDULER_Task *kce_task; |
702 | 786 | ||
703 | /** | 787 | /** |
788 | * ID of kce rekey working queue task | ||
789 | */ | ||
790 | static struct GNUNET_SCHEDULER_Task *kce_task_rekey; | ||
791 | |||
792 | /** | ||
704 | * Is the kce_task finished? | 793 | * Is the kce_task finished? |
705 | */ | 794 | */ |
706 | static int kce_task_finished = GNUNET_NO; | 795 | static int kce_task_finished = GNUNET_NO; |
@@ -832,26 +921,28 @@ bi_destroy (struct BroadcastInterface *bi) | |||
832 | static void | 921 | static void |
833 | receiver_destroy (struct ReceiverAddress *receiver) | 922 | receiver_destroy (struct ReceiverAddress *receiver) |
834 | { | 923 | { |
835 | struct GNUNET_MQ_Handle *mq; | 924 | |
925 | receiver->receiver_destroy_called = GNUNET_YES; | ||
836 | 926 | ||
837 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 927 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
838 | "Disconnecting receiver for peer `%s'\n", | 928 | "Disconnecting receiver for peer `%s'\n", |
839 | GNUNET_i2s (&receiver->target)); | 929 | GNUNET_i2s (&receiver->target)); |
840 | if (NULL != (mq = receiver->kx_mq)) | 930 | /*if (NULL != (mq = receiver->kx_mq)) |
841 | { | 931 | { |
842 | receiver->kx_mq = NULL; | 932 | receiver->kx_mq = NULL; |
843 | GNUNET_MQ_destroy (mq); | 933 | GNUNET_MQ_destroy (mq); |
844 | } | 934 | }*/ |
845 | if (NULL != receiver->kx_qh) | 935 | if (NULL != receiver->kx_qh) |
846 | { | 936 | { |
847 | GNUNET_TRANSPORT_communicator_mq_del (receiver->kx_qh); | 937 | GNUNET_TRANSPORT_communicator_mq_del (receiver->kx_qh); |
848 | receiver->kx_qh = NULL; | 938 | receiver->kx_qh = NULL; |
939 | receiver->kx_mq = NULL; | ||
849 | } | 940 | } |
850 | if (NULL != (mq = receiver->d_mq)) | 941 | /*if (NULL != (mq = receiver->d_mq)) |
851 | { | 942 | { |
852 | receiver->d_mq = NULL; | 943 | receiver->d_mq = NULL; |
853 | GNUNET_MQ_destroy (mq); | 944 | GNUNET_MQ_destroy (mq); |
854 | } | 945 | }*/ |
855 | if (NULL != receiver->d_qh) | 946 | if (NULL != receiver->d_qh) |
856 | { | 947 | { |
857 | GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh); | 948 | GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh); |
@@ -956,8 +1047,9 @@ kce_generate (struct SharedSecret *ss, uint32_t seq) | |||
956 | * Destroy @a ss and associated key cache entries. | 1047 | * Destroy @a ss and associated key cache entries. |
957 | * | 1048 | * |
958 | * @param ss shared secret to destroy | 1049 | * @param ss shared secret to destroy |
1050 | * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. | ||
959 | */ | 1051 | */ |
960 | static void | 1052 | static int |
961 | secret_destroy (struct SharedSecret *ss, int withoutKce) | 1053 | secret_destroy (struct SharedSecret *ss, int withoutKce) |
962 | { | 1054 | { |
963 | struct SenderAddress *sender; | 1055 | struct SenderAddress *sender; |
@@ -970,7 +1062,7 @@ secret_destroy (struct SharedSecret *ss, int withoutKce) | |||
970 | ss->sequence_allowed); | 1062 | ss->sequence_allowed); |
971 | 1063 | ||
972 | if (withoutKce && (ss->sequence_allowed > 0)) | 1064 | if (withoutKce && (ss->sequence_allowed > 0)) |
973 | return; | 1065 | return GNUNET_NO; |
974 | 1066 | ||
975 | if (NULL != (sender = ss->sender)) | 1067 | if (NULL != (sender = ss->sender)) |
976 | { | 1068 | { |
@@ -993,6 +1085,7 @@ secret_destroy (struct SharedSecret *ss, int withoutKce) | |||
993 | GNUNET_CONTAINER_multishortmap_size (key_cache), | 1085 | GNUNET_CONTAINER_multishortmap_size (key_cache), |
994 | GNUNET_NO); | 1086 | GNUNET_NO); |
995 | GNUNET_free (ss); | 1087 | GNUNET_free (ss); |
1088 | return GNUNET_YES; | ||
996 | } | 1089 | } |
997 | 1090 | ||
998 | 1091 | ||
@@ -1005,6 +1098,7 @@ secret_destroy (struct SharedSecret *ss, int withoutKce) | |||
1005 | static void | 1098 | static void |
1006 | sender_destroy (struct SenderAddress *sender) | 1099 | sender_destroy (struct SenderAddress *sender) |
1007 | { | 1100 | { |
1101 | sender->sender_destroy_called = GNUNET_YES; | ||
1008 | GNUNET_assert ( | 1102 | GNUNET_assert ( |
1009 | GNUNET_YES == | 1103 | GNUNET_YES == |
1010 | GNUNET_CONTAINER_multipeermap_remove (senders, &sender->target, sender)); | 1104 | GNUNET_CONTAINER_multipeermap_remove (senders, &sender->target, sender)); |
@@ -1100,20 +1194,26 @@ check_timeouts (void *cls) | |||
1100 | rt = GNUNET_TIME_UNIT_FOREVER_REL; | 1194 | rt = GNUNET_TIME_UNIT_FOREVER_REL; |
1101 | while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap))) | 1195 | while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap))) |
1102 | { | 1196 | { |
1103 | rt = GNUNET_TIME_absolute_get_remaining (receiver->timeout); | 1197 | if (GNUNET_YES != receiver->receiver_destroy_called) |
1104 | if (0 != rt.rel_value_us) | 1198 | { |
1105 | break; | 1199 | rt = GNUNET_TIME_absolute_get_remaining (receiver->timeout); |
1106 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1200 | if (0 != rt.rel_value_us) |
1107 | "Receiver timed out\n"); | 1201 | break; |
1108 | receiver_destroy (receiver); | 1202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1203 | "Receiver timed out\n"); | ||
1204 | receiver_destroy (receiver); | ||
1205 | } | ||
1109 | } | 1206 | } |
1110 | st = GNUNET_TIME_UNIT_FOREVER_REL; | 1207 | st = GNUNET_TIME_UNIT_FOREVER_REL; |
1111 | while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap))) | 1208 | while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap))) |
1112 | { | 1209 | { |
1113 | st = GNUNET_TIME_absolute_get_remaining (sender->timeout); | 1210 | if (GNUNET_YES != sender->sender_destroy_called) |
1114 | if (0 != st.rel_value_us) | 1211 | { |
1115 | break; | 1212 | st = GNUNET_TIME_absolute_get_remaining (sender->timeout); |
1116 | sender_destroy (sender); | 1213 | if (0 != st.rel_value_us) |
1214 | break; | ||
1215 | sender_destroy (sender); | ||
1216 | } | ||
1117 | } | 1217 | } |
1118 | delay = GNUNET_TIME_relative_min (rt, st); | 1218 | delay = GNUNET_TIME_relative_min (rt, st); |
1119 | if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 1219 | if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) |
@@ -1289,7 +1389,7 @@ setup_shared_secret_dec (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral) | |||
1289 | */ | 1389 | */ |
1290 | static struct SharedSecret * | 1390 | static struct SharedSecret * |
1291 | setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, | 1391 | setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, |
1292 | struct ReceiverAddress *receiver) | 1392 | struct ReceiverAddress *receiver, int add_to_receiver) |
1293 | { | 1393 | { |
1294 | struct SharedSecret *ss; | 1394 | struct SharedSecret *ss; |
1295 | 1395 | ||
@@ -1316,6 +1416,114 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, | |||
1316 | static void | 1416 | static void |
1317 | setup_receiver_mq (struct ReceiverAddress *receiver); | 1417 | setup_receiver_mq (struct ReceiverAddress *receiver); |
1318 | 1418 | ||
1419 | /** | ||
1420 | * Destroying all secrets. Depending on parameter we keep those secrets having a kce. | ||
1421 | * | ||
1422 | * @param ss The secret we will not destroy. | ||
1423 | * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. | ||
1424 | */ | ||
1425 | static void | ||
1426 | destroy_all_secrets (struct SharedSecret *ss, int withoutKce) | ||
1427 | { | ||
1428 | struct SenderAddress *sender; | ||
1429 | struct ReceiverAddress *receiver; | ||
1430 | struct SharedSecret *ss_to_destroy; | ||
1431 | struct SharedSecret *ss_start; | ||
1432 | struct SharedSecret *pos; | ||
1433 | int at_least_one_destroyed = GNUNET_NO; | ||
1434 | |||
1435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1436 | "Starting destroy all.\n"); | ||
1437 | |||
1438 | if (NULL != (sender = ss->sender)) | ||
1439 | { | ||
1440 | ss_start = sender->ss_head; | ||
1441 | } | ||
1442 | else if (NULL != (receiver = ss->receiver)) | ||
1443 | { | ||
1444 | ss_start = receiver->ss_head; | ||
1445 | } | ||
1446 | else | ||
1447 | { | ||
1448 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1449 | "Shared secret has no sender or receiver!\n"); | ||
1450 | return; | ||
1451 | } | ||
1452 | |||
1453 | pos = ss_start; | ||
1454 | while ( NULL != pos) | ||
1455 | { | ||
1456 | ss_to_destroy = pos; | ||
1457 | pos = pos->next; | ||
1458 | |||
1459 | if (ss != ss_to_destroy) | ||
1460 | at_least_one_destroyed = secret_destroy (ss_to_destroy, withoutKce); | ||
1461 | } | ||
1462 | |||
1463 | if ((ss != ss_start) && ! at_least_one_destroyed) | ||
1464 | { | ||
1465 | destroy_all_secrets (ss_start, GNUNET_NO); | ||
1466 | } | ||
1467 | |||
1468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1469 | "Finished destroy all.\n"); | ||
1470 | } | ||
1471 | |||
1472 | static void | ||
1473 | add_acks (struct SharedSecret *ss, int acks_to_add, int remove_from_receiver) | ||
1474 | { | ||
1475 | |||
1476 | struct ReceiverAddress *receiver = ss->receiver; | ||
1477 | |||
1478 | if (NULL == ss) | ||
1479 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1480 | "secret NULL!\n"); | ||
1481 | |||
1482 | if (NULL == receiver) | ||
1483 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1484 | "Receiver NULL!\n"); | ||
1485 | if (NULL == receiver->d_qh) | ||
1486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1487 | "Queue NULL!\n"); | ||
1488 | |||
1489 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1490 | "Tell transport we have %u more acks!\n", | ||
1491 | acks_to_add); | ||
1492 | GNUNET_TRANSPORT_communicator_mq_update (ch, | ||
1493 | receiver->d_qh, | ||
1494 | acks_to_add, | ||
1495 | 1); | ||
1496 | // Until here for alternativ 1 | ||
1497 | |||
1498 | /* move ss to head to avoid discarding it anytime soon! */ | ||
1499 | if (remove_from_receiver) | ||
1500 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); | ||
1501 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); | ||
1502 | destroy_all_secrets (ss, GNUNET_YES); | ||
1503 | |||
1504 | |||
1505 | // Uncomment this for alternativ 2 of backchannel functionality | ||
1506 | /*if (receiver->acks_available != ack->acks_available) | ||
1507 | { | ||
1508 | receiver->acks_available = ack->acks_available; | ||
1509 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1510 | "Tell transport we have different number of acks!\n"); | ||
1511 | GNUNET_TRANSPORT_communicator_mq_update (ch, | ||
1512 | receiver->d_qh, | ||
1513 | receiver->acks_available, | ||
1514 | 1); | ||
1515 | }*/ | ||
1516 | // Until here for alternativ 2 | ||
1517 | } | ||
1518 | |||
1519 | static void | ||
1520 | add_acks_rekey (struct ReceiverAddress *receiver) | ||
1521 | { | ||
1522 | add_acks (receiver->ss_rekey, receiver->ss_rekey->sequence_allowed - 3, | ||
1523 | GNUNET_NO); | ||
1524 | receiver->acks_available = receiver->ss_rekey->sequence_allowed; | ||
1525 | receiver->ss_rekey = NULL; | ||
1526 | } | ||
1319 | 1527 | ||
1320 | /** | 1528 | /** |
1321 | * We received an ACK for @a pid. Check if it is for | 1529 | * We received an ACK for @a pid. Check if it is for |
@@ -1332,18 +1540,48 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) | |||
1332 | { | 1540 | { |
1333 | const struct UDPAck *ack = cls; | 1541 | const struct UDPAck *ack = cls; |
1334 | struct ReceiverAddress *receiver = value; | 1542 | struct ReceiverAddress *receiver = value; |
1335 | struct SharedSecret *pos; | 1543 | int acks_to_add; |
1544 | uint32_t allowed; | ||
1336 | 1545 | ||
1337 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1546 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1338 | "in handle ack\n"); | 1547 | "in handle ack\n"); |
1339 | struct SharedSecret *ss_to_destroy; | 1548 | |
1549 | if (NULL != receiver->ss_rekey) | ||
1550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1551 | "Received secret with cmac %s \n", | ||
1552 | GNUNET_h2s (&receiver->ss_rekey->cmac)); | ||
1553 | |||
1554 | if ((NULL != receiver->ss_rekey) && (0 == memcmp (&ack->cmac, | ||
1555 | &receiver->ss_rekey->cmac, | ||
1556 | sizeof(struct | ||
1557 | GNUNET_HashCode))) ) | ||
1558 | { | ||
1559 | allowed = ntohl (ack->sequence_max); | ||
1560 | |||
1561 | if (allowed > receiver->ss_rekey->sequence_allowed) | ||
1562 | { | ||
1563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1564 | "%u > %u (%u %u) for rekey secrect %s\n", allowed, | ||
1565 | receiver->ss_rekey->sequence_allowed, | ||
1566 | receiver->acks_available, | ||
1567 | ack->acks_available, | ||
1568 | GNUNET_h2s (&receiver->ss_rekey->master)); | ||
1569 | |||
1570 | receiver->ss_rekey->sequence_allowed = allowed; | ||
1571 | |||
1572 | if (GNUNET_NO == receiver->rekeying) | ||
1573 | add_acks_rekey (receiver); | ||
1574 | |||
1575 | return GNUNET_NO; | ||
1576 | } | ||
1577 | } | ||
1340 | 1578 | ||
1341 | (void) pid; | 1579 | (void) pid; |
1342 | for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) | 1580 | for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) |
1343 | { | 1581 | { |
1344 | if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode))) | 1582 | if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode))) |
1345 | { | 1583 | { |
1346 | uint32_t allowed; | 1584 | |
1347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1585 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1348 | "Found matching mac\n"); | 1586 | "Found matching mac\n"); |
1349 | 1587 | ||
@@ -1358,41 +1596,19 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) | |||
1358 | ack->acks_available, | 1596 | ack->acks_available, |
1359 | GNUNET_h2s (&ss->master)); | 1597 | GNUNET_h2s (&ss->master)); |
1360 | // Uncomment this for alternativ 1 of backchannel functionality | 1598 | // Uncomment this for alternativ 1 of backchannel functionality |
1599 | acks_to_add = (allowed - ss->sequence_allowed); | ||
1600 | if ((GNUNET_NO == receiver->rekeying) && | ||
1601 | (receiver->number_rekeying_kce < | ||
1602 | 3) ) | ||
1603 | { | ||
1604 | acks_to_add -= (3 - receiver->number_rekeying_kce); | ||
1605 | receiver->number_rekeying_kce = 3; | ||
1606 | } | ||
1361 | receiver->acks_available += (allowed - ss->sequence_allowed); | 1607 | receiver->acks_available += (allowed - ss->sequence_allowed); |
1362 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1363 | "Tell transport we have more acks!\n"); | ||
1364 | GNUNET_TRANSPORT_communicator_mq_update (ch, | ||
1365 | receiver->d_qh, | ||
1366 | (allowed | ||
1367 | - ss->sequence_allowed), | ||
1368 | 1); | ||
1369 | // Until here for alternativ 1 | ||
1370 | ss->sequence_allowed = allowed; | 1608 | ss->sequence_allowed = allowed; |
1371 | /* move ss to head to avoid discarding it anytime soon! */ | ||
1372 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); | ||
1373 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); | ||
1374 | pos = receiver->ss_head; | ||
1375 | while ( NULL != pos) | ||
1376 | { | ||
1377 | ss_to_destroy = pos; | ||
1378 | pos = pos->next; | ||
1379 | 1609 | ||
1380 | secret_destroy (ss_to_destroy, GNUNET_YES); | 1610 | add_acks (ss, acks_to_add, GNUNET_YES); |
1381 | } | ||
1382 | } | 1611 | } |
1383 | |||
1384 | // Uncomment this for alternativ 2 of backchannel functionality | ||
1385 | /*if (receiver->acks_available != ack->acks_available) | ||
1386 | { | ||
1387 | receiver->acks_available = ack->acks_available; | ||
1388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1389 | "Tell transport we have different number of acks!\n"); | ||
1390 | GNUNET_TRANSPORT_communicator_mq_update (ch, | ||
1391 | receiver->d_qh, | ||
1392 | receiver->acks_available, | ||
1393 | 1); | ||
1394 | }*/ | ||
1395 | // Until here for alternativ 2 | ||
1396 | return GNUNET_NO; | 1612 | return GNUNET_NO; |
1397 | } | 1613 | } |
1398 | } | 1614 | } |
@@ -1446,6 +1662,8 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1446 | } | 1662 | } |
1447 | } | 1663 | } |
1448 | 1664 | ||
1665 | |||
1666 | |||
1449 | static void | 1667 | static void |
1450 | kce_generate_cb (void *cls) | 1668 | kce_generate_cb (void *cls) |
1451 | { | 1669 | { |
@@ -1477,6 +1695,30 @@ kce_generate_cb (void *cls) | |||
1477 | 1695 | ||
1478 | } | 1696 | } |
1479 | 1697 | ||
1698 | static void | ||
1699 | kce_generate_rekey_cb (void *cls) | ||
1700 | { | ||
1701 | struct SharedSecret *ss = cls; | ||
1702 | |||
1703 | if (NULL == kce_task) | ||
1704 | { | ||
1705 | for (int i = 0; i < GENERATE_AT_ONCE; i++) | ||
1706 | kce_generate (ss, ++ss->sequence_allowed); | ||
1707 | |||
1708 | kce_task = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, | ||
1709 | kce_generate_cb, | ||
1710 | ss); | ||
1711 | kce_task_rekey = NULL; | ||
1712 | } | ||
1713 | else | ||
1714 | { | ||
1715 | kce_task_rekey = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, | ||
1716 | kce_generate_rekey_cb, | ||
1717 | ss); | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | |||
1480 | /** | 1722 | /** |
1481 | * We established a shared secret with a sender. We should try to send | 1723 | * We established a shared secret with a sender. We should try to send |
1482 | * the sender an `struct UDPAck` at the next opportunity to allow the | 1724 | * the sender an `struct UDPAck` at the next opportunity to allow the |
@@ -1489,9 +1731,6 @@ kce_generate_cb (void *cls) | |||
1489 | static void | 1731 | static void |
1490 | consider_ss_ack (struct SharedSecret *ss, int initial) | 1732 | consider_ss_ack (struct SharedSecret *ss, int initial) |
1491 | { | 1733 | { |
1492 | struct SharedSecret *ss_to_destroy; | ||
1493 | struct SharedSecret *pos; | ||
1494 | |||
1495 | GNUNET_assert (NULL != ss->sender); | 1734 | GNUNET_assert (NULL != ss->sender); |
1496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1735 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1497 | "Considering SS UDPAck %s\n", | 1736 | "Considering SS UDPAck %s\n", |
@@ -1535,18 +1774,13 @@ consider_ss_ack (struct SharedSecret *ss, int initial) | |||
1535 | &ss_finished->sender->target, | 1774 | &ss_finished->sender->target, |
1536 | COMMUNICATOR_ADDRESS_PREFIX, | 1775 | COMMUNICATOR_ADDRESS_PREFIX, |
1537 | &ack.header); | 1776 | &ack.header); |
1538 | pos = ss->sender->ss_head; | 1777 | destroy_all_secrets (ss, GNUNET_YES); |
1539 | while ( NULL != pos) | ||
1540 | { | ||
1541 | ss_to_destroy = pos; | ||
1542 | pos = pos->next; | ||
1543 | secret_destroy (ss_to_destroy, GNUNET_YES); | ||
1544 | } | ||
1545 | kce_task = NULL; | 1778 | kce_task = NULL; |
1779 | kce_task_finished = GNUNET_NO; | ||
1546 | } | 1780 | } |
1547 | else if (((NULL == kce_task) && (KCN_THRESHOLD > | 1781 | else if ((NULL == kce_task) && ((KCN_THRESHOLD > ss->sender->acks_available)|| |
1548 | ss->sender->acks_available)) || | 1782 | (GNUNET_YES == ss->sender->rekeying) || |
1549 | (ss->sender->num_secrets > MAX_SECRETS) ) | 1783 | (ss->sender->num_secrets > MAX_SECRETS) )) |
1550 | { | 1784 | { |
1551 | 1785 | ||
1552 | // kce_generate (ss, ++ss->sequence_allowed); | 1786 | // kce_generate (ss, ++ss->sequence_allowed); |
@@ -1556,39 +1790,13 @@ consider_ss_ack (struct SharedSecret *ss, int initial) | |||
1556 | ss); | 1790 | ss); |
1557 | 1791 | ||
1558 | } | 1792 | } |
1559 | 1793 | else if ((NULL == kce_task_rekey) && (GNUNET_YES == | |
1560 | 1794 | ss->sender->rekeying) ) | |
1561 | /*if (ss->active_kce_count < KCN_THRESHOLD) | ||
1562 | { | 1795 | { |
1563 | struct UDPAck ack; | 1796 | kce_task_rekey = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, |
1564 | 1797 | kce_generate_rekey_cb, | |
1565 | /** | 1798 | ss); |
1566 | * If we previously have seen this ss | 1799 | } |
1567 | * we now generate KCN_TARGET KCEs. | ||
1568 | * For the initial KX (active_kce_count==0), | ||
1569 | * we only generate a single KCE to prevent | ||
1570 | * unnecessary overhead. | ||
1571 | |||
1572 | if (0 < ss->active_kce_count) | ||
1573 | { | ||
1574 | while (ss->active_kce_count < KCN_TARGET) | ||
1575 | kce_generate (ss, ++ss->sequence_allowed); | ||
1576 | } | ||
1577 | else { | ||
1578 | kce_generate (ss, ++ss->sequence_allowed); | ||
1579 | } | ||
1580 | ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); | ||
1581 | ack.header.size = htons (sizeof(ack)); | ||
1582 | ack.sequence_max = htonl (ss->sequence_allowed); | ||
1583 | ack.cmac = ss->cmac; | ||
1584 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1585 | "Notifying transport of UDPAck %s\n", | ||
1586 | GNUNET_i2s_full (&ss->sender->target)); | ||
1587 | GNUNET_TRANSPORT_communicator_notify (ch, | ||
1588 | &ss->sender->target, | ||
1589 | COMMUNICATOR_ADDRESS_PREFIX, | ||
1590 | &ack.header); | ||
1591 | }*/ | ||
1592 | } | 1800 | } |
1593 | 1801 | ||
1594 | 1802 | ||
@@ -1631,9 +1839,107 @@ decrypt_box (const struct UDPBox *box, | |||
1631 | "decrypted UDPBox with kid %s\n", | 1839 | "decrypted UDPBox with kid %s\n", |
1632 | GNUNET_sh2s (&box->kid)); | 1840 | GNUNET_sh2s (&box->kid)); |
1633 | try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); | 1841 | try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); |
1634 | consider_ss_ack (ss, GNUNET_NO); | 1842 | if ((GNUNET_NO == box->rekeying) && (GNUNET_YES == ss->sender->rekeying)) |
1843 | { | ||
1844 | ss->sender->rekeying = GNUNET_NO; | ||
1845 | // destroy_all_secrets (ss, GNUNET_NO); | ||
1846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1847 | "Receiver stopped rekeying.\n"); | ||
1848 | } | ||
1849 | else if (GNUNET_NO == box->rekeying) | ||
1850 | consider_ss_ack (ss, GNUNET_YES); | ||
1851 | else{ | ||
1852 | ss->sender->rekeying = GNUNET_YES; | ||
1853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1854 | "Receiver started rekeying.\n"); | ||
1855 | } | ||
1635 | } | 1856 | } |
1636 | 1857 | ||
1858 | /** | ||
1859 | * We received a @a rekey with matching @a kce. Decrypt and process it. | ||
1860 | * | ||
1861 | * @param rekey the data we received | ||
1862 | * @param rekey_len number of bytes in @a rekey | ||
1863 | * @param kce key index to decrypt @a rekey | ||
1864 | */ | ||
1865 | static void | ||
1866 | decrypt_rekey (const struct UDPRekey *rekey, | ||
1867 | size_t rekey_len, | ||
1868 | struct KeyCacheEntry *kce, | ||
1869 | struct SenderAddress *sender) | ||
1870 | { | ||
1871 | struct SharedSecret *ss = kce->ss; | ||
1872 | struct SharedSecret *ss_rekey; | ||
1873 | char out_buf[rekey_len - sizeof(*rekey)]; | ||
1874 | struct GNUNET_HashCode *master; | ||
1875 | |||
1876 | |||
1877 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1878 | "decrypt_rekey.\n"); | ||
1879 | |||
1880 | GNUNET_assert (NULL != ss->sender); | ||
1881 | if (GNUNET_OK != try_decrypt (ss, | ||
1882 | rekey->gcm_tag, | ||
1883 | kce->sequence_number, | ||
1884 | (const char *) &rekey[1], | ||
1885 | sizeof(out_buf), | ||
1886 | out_buf)) | ||
1887 | { | ||
1888 | GNUNET_STATISTICS_update (stats, | ||
1889 | "# Decryption failures with valid KCE", | ||
1890 | 1, | ||
1891 | GNUNET_NO); | ||
1892 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1893 | "Decryption with kid %s failed\n", | ||
1894 | GNUNET_sh2s (&rekey->kid)); | ||
1895 | kce_destroy (kce); | ||
1896 | return; | ||
1897 | } | ||
1898 | kce_destroy (kce); | ||
1899 | GNUNET_STATISTICS_update (stats, | ||
1900 | "# bytes decrypted with Rekey", | ||
1901 | sizeof(out_buf), | ||
1902 | GNUNET_NO); | ||
1903 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1904 | "decrypted UDPRekey with kid %s\n", | ||
1905 | GNUNET_sh2s (&rekey->kid)); | ||
1906 | /*cmac = (struct GNUNET_HashCode *) out_buf; | ||
1907 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1908 | "Received secret with cmac %s \n", | ||
1909 | GNUNET_h2s (&cmac));*/ | ||
1910 | // ss_rekey = (struct SharedSecret *) out_buf; | ||
1911 | master = (struct GNUNET_HashCode *) out_buf; | ||
1912 | ss_rekey = GNUNET_new (struct SharedSecret); | ||
1913 | ss_rekey->master = *master; | ||
1914 | calculate_cmac (ss_rekey); | ||
1915 | ss_rekey->sender = sender; | ||
1916 | // ss_rekey->sequence_used = 0; | ||
1917 | // ss_rekey->sequence_allowed = 0; | ||
1918 | /* ss_rekey->active_kce_count = 0; */ | ||
1919 | /* ss_rekey->prev = NULL; */ | ||
1920 | /* ss_rekey->next = NULL; */ | ||
1921 | /* GNUNET_assert (ss_rekey->prev == NULL && sender->ss_head != ss_rekey); */ | ||
1922 | /* GNUNET_assert (ss_rekey->next == NULL && sender->ss_tail != ss_rekey); */ | ||
1923 | GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey); | ||
1924 | sender->num_secrets++; | ||
1925 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1926 | "Received secret with cmac %s\n", | ||
1927 | GNUNET_h2s (&(ss_rekey->cmac))); | ||
1928 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1929 | "Received secret with master %s.\n", | ||
1930 | GNUNET_h2s (&(ss_rekey->master))); | ||
1931 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1932 | "We have %u sequence_allowed.\n", | ||
1933 | ss_rekey->sequence_allowed); | ||
1934 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1935 | "We have a sender %p\n", | ||
1936 | ss_rekey->sender); | ||
1937 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1938 | "We have %u acks available.\n", | ||
1939 | ss_rekey->sender->acks_available); | ||
1940 | consider_ss_ack (ss_rekey, GNUNET_YES); | ||
1941 | |||
1942 | } | ||
1637 | 1943 | ||
1638 | /** | 1944 | /** |
1639 | * Closure for #find_sender_by_address() | 1945 | * Closure for #find_sender_by_address() |
@@ -1832,6 +2138,38 @@ sock_read (void *cls) | |||
1832 | } | 2138 | } |
1833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2139 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1834 | "Read %lu bytes\n", rcvd); | 2140 | "Read %lu bytes\n", rcvd); |
2141 | |||
2142 | if (rcvd > sizeof(struct UDPRekey)) | ||
2143 | { | ||
2144 | const struct UDPRekey *rekey; | ||
2145 | const struct UDPBox *box; | ||
2146 | struct KeyCacheEntry *kce; | ||
2147 | struct SenderAddress *sender; | ||
2148 | int do_decrypt = GNUNET_NO; | ||
2149 | |||
2150 | rekey = (const struct UDPRekey *) buf; | ||
2151 | box = (const struct UDPBox *) buf; | ||
2152 | kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &rekey->kid); | ||
2153 | |||
2154 | if ((GNUNET_YES == box->rekeying)||(GNUNET_NO == box->rekeying)) | ||
2155 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2156 | "UDPRekey has rekeying %u\n", | ||
2157 | box->rekeying); | ||
2158 | else | ||
2159 | do_decrypt = GNUNET_YES; | ||
2160 | if ((GNUNET_YES == do_decrypt)&& (NULL != kce) && (GNUNET_YES == | ||
2161 | kce->ss->sender->rekeying)) | ||
2162 | { | ||
2163 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2164 | "UDPRekey with kid %s\n", | ||
2165 | GNUNET_sh2s (&rekey->kid)); | ||
2166 | sender = setup_sender (&rekey->sender, (const struct sockaddr *) &sa, | ||
2167 | salen); | ||
2168 | decrypt_rekey (rekey, (size_t) rcvd, kce, sender); | ||
2169 | return; | ||
2170 | } | ||
2171 | } | ||
2172 | |||
1835 | /* first, see if it is a UDPBox */ | 2173 | /* first, see if it is a UDPBox */ |
1836 | if (rcvd > sizeof(struct UDPBox)) | 2174 | if (rcvd > sizeof(struct UDPBox)) |
1837 | { | 2175 | { |
@@ -1949,7 +2287,20 @@ sock_read (void *cls) | |||
1949 | 1, | 2287 | 1, |
1950 | GNUNET_NO); | 2288 | GNUNET_NO); |
1951 | try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); | 2289 | try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); |
1952 | consider_ss_ack (ss, GNUNET_YES); | 2290 | if ((GNUNET_NO == kx->rekeying) && (GNUNET_YES == ss->sender->rekeying)) |
2291 | { | ||
2292 | ss->sender->rekeying = GNUNET_NO; | ||
2293 | // destroy_all_secrets (ss, GNUNET_NO); | ||
2294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2295 | "Receiver stopped rekeying.\n"); | ||
2296 | } | ||
2297 | else if (GNUNET_NO == kx->rekeying) | ||
2298 | consider_ss_ack (ss, GNUNET_YES); | ||
2299 | else{ | ||
2300 | ss->sender->rekeying = GNUNET_YES; | ||
2301 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2302 | "Receiver started rekeying.\n"); | ||
2303 | } | ||
1953 | /*if (sender->num_secrets > MAX_SECRETS) | 2304 | /*if (sender->num_secrets > MAX_SECRETS) |
1954 | secret_destroy (sender->ss_tail);*/ | 2305 | secret_destroy (sender->ss_tail);*/ |
1955 | } | 2306 | } |
@@ -2138,26 +2489,13 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2138 | size_t dpos; | 2489 | size_t dpos; |
2139 | gcry_cipher_hd_t out_cipher; | 2490 | gcry_cipher_hd_t out_cipher; |
2140 | struct SharedSecret *ss; | 2491 | struct SharedSecret *ss; |
2141 | struct SharedSecret *ss_to_destroy; | ||
2142 | struct SharedSecret *pos; | ||
2143 | |||
2144 | if (receiver->num_secrets > MAX_SECRETS) | ||
2145 | { | ||
2146 | pos = receiver->ss_head; | ||
2147 | while ( NULL != pos) | ||
2148 | { | ||
2149 | ss_to_destroy = pos; | ||
2150 | pos = pos->next; | ||
2151 | secret_destroy (ss_to_destroy, GNUNET_YES); | ||
2152 | } | ||
2153 | } | ||
2154 | |||
2155 | 2492 | ||
2156 | GNUNET_assert (mq == receiver->kx_mq); | 2493 | GNUNET_assert (mq == receiver->kx_mq); |
2157 | if (msize > receiver->kx_mtu) | 2494 | if (msize > receiver->kx_mtu) |
2158 | { | 2495 | { |
2159 | GNUNET_break (0); | 2496 | GNUNET_break (0); |
2160 | receiver_destroy (receiver); | 2497 | if (GNUNET_YES != receiver->receiver_destroy_called) |
2498 | receiver_destroy (receiver); | ||
2161 | return; | 2499 | return; |
2162 | } | 2500 | } |
2163 | reschedule_receiver_timeout (receiver); | 2501 | reschedule_receiver_timeout (receiver); |
@@ -2165,7 +2503,13 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2165 | /* setup key material */ | 2503 | /* setup key material */ |
2166 | GNUNET_CRYPTO_ecdhe_key_create (&epriv); | 2504 | GNUNET_CRYPTO_ecdhe_key_create (&epriv); |
2167 | 2505 | ||
2168 | ss = setup_shared_secret_enc (&epriv, receiver); | 2506 | ss = setup_shared_secret_enc (&epriv, receiver, GNUNET_YES); |
2507 | |||
2508 | if (receiver->num_secrets > MAX_SECRETS) | ||
2509 | { | ||
2510 | destroy_all_secrets (ss, GNUNET_YES); | ||
2511 | } | ||
2512 | |||
2169 | setup_cipher (&ss->master, 0, &out_cipher); | 2513 | setup_cipher (&ss->master, 0, &out_cipher); |
2170 | /* compute 'uc' */ | 2514 | /* compute 'uc' */ |
2171 | uc.sender = my_identity; | 2515 | uc.sender = my_identity; |
@@ -2199,6 +2543,10 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2199 | GNUNET_assert ( | 2543 | GNUNET_assert ( |
2200 | 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); | 2544 | 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); |
2201 | gcry_cipher_close (out_cipher); | 2545 | gcry_cipher_close (out_cipher); |
2546 | if (GNUNET_NO == receiver->rekeying) | ||
2547 | kx.rekeying = GNUNET_NO; | ||
2548 | else | ||
2549 | kx.rekeying = GNUNET_YES; | ||
2202 | memcpy (dgram, &kx, sizeof(kx)); | 2550 | memcpy (dgram, &kx, sizeof(kx)); |
2203 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | 2551 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, |
2204 | dgram, | 2552 | dgram, |
@@ -2212,6 +2560,162 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2212 | GNUNET_MQ_impl_send_continue (mq); | 2560 | GNUNET_MQ_impl_send_continue (mq); |
2213 | } | 2561 | } |
2214 | 2562 | ||
2563 | static void | ||
2564 | check_for_rekeying (struct ReceiverAddress *receiver, struct UDPBox *box) | ||
2565 | { | ||
2566 | |||
2567 | struct GNUNET_TIME_Relative rt; | ||
2568 | |||
2569 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2570 | "Timeout is %lu\n.", | ||
2571 | receiver->rekey_timeout.abs_value_us); | ||
2572 | |||
2573 | if (0 == receiver->rekey_timeout.abs_value_us) | ||
2574 | { | ||
2575 | receiver->rekey_timeout = GNUNET_TIME_relative_to_absolute ( | ||
2576 | rekey_interval); | ||
2577 | } | ||
2578 | else | ||
2579 | { | ||
2580 | rt = GNUNET_TIME_absolute_get_remaining (receiver->rekey_timeout); | ||
2581 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2582 | "Relative time is %lu and timeout is %lu\n.", | ||
2583 | rt.rel_value_us, | ||
2584 | receiver->rekey_timeout.abs_value_us); | ||
2585 | |||
2586 | if ((0 == rt.rel_value_us)||(receiver->rekey_send_bytes > | ||
2587 | REKEY_MAX_BYTES) ) | ||
2588 | { | ||
2589 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2590 | "Bytes send %lu greater than %llu max bytes\n.", | ||
2591 | receiver->rekey_send_bytes, | ||
2592 | REKEY_MAX_BYTES); | ||
2593 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2594 | "Relative time is %lu and timeout is %lu\n.", | ||
2595 | rt.rel_value_us, | ||
2596 | receiver->rekey_timeout.abs_value_us); | ||
2597 | |||
2598 | receiver->rekey_timeout.abs_value_us = 0; | ||
2599 | receiver->rekey_send_bytes = 0; | ||
2600 | receiver->ss_rekey = NULL; | ||
2601 | // destroy_all_secrets (ss, GNUNET_NO); | ||
2602 | receiver->rekeying = GNUNET_YES; | ||
2603 | receiver->rekey_acks_available = receiver->acks_available; | ||
2604 | box->rekeying = GNUNET_YES; | ||
2605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2606 | "Sender started rekeying.\n"); | ||
2607 | if (GNUNET_YES == box->rekeying) | ||
2608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2609 | "Sending rekeying with kid %s\n", | ||
2610 | GNUNET_sh2s (&box->kid)); | ||
2611 | } | ||
2612 | } | ||
2613 | } | ||
2614 | |||
2615 | static void | ||
2616 | send_UDPRekey (struct ReceiverAddress *receiver, struct SharedSecret *ss) | ||
2617 | { | ||
2618 | uint8_t is_ss_rekey_sequence_allowed_zero = GNUNET_NO; | ||
2619 | uint8_t is_acks_available_below = GNUNET_NO; | ||
2620 | uint8_t send_rekey = GNUNET_NO; | ||
2621 | uint16_t not_below; | ||
2622 | struct GNUNET_CRYPTO_EcdhePrivateKey epriv; | ||
2623 | struct UDPRekey *rekey; | ||
2624 | size_t dpos; | ||
2625 | |||
2626 | char rekey_dgram[sizeof(struct UDPRekey) + receiver->d_mtu]; | ||
2627 | |||
2628 | if (NULL != receiver->ss_rekey) | ||
2629 | { | ||
2630 | not_below = (receiver->rekey_acks_available | ||
2631 | - (receiver->rekey_acks_available % 3)) / 3; | ||
2632 | is_ss_rekey_sequence_allowed_zero = (0 == | ||
2633 | receiver->ss_rekey->sequence_allowed); | ||
2634 | is_acks_available_below = (receiver->acks_available > not_below); | ||
2635 | send_rekey = (0 == (receiver->acks_available - not_below) % not_below) && | ||
2636 | is_acks_available_below && is_ss_rekey_sequence_allowed_zero; | ||
2637 | } | ||
2638 | else if (NULL == receiver->ss_rekey) | ||
2639 | { | ||
2640 | /* setup key material */ | ||
2641 | GNUNET_CRYPTO_ecdhe_key_create (&epriv); | ||
2642 | receiver->ss_rekey = setup_shared_secret_enc (&epriv, receiver, | ||
2643 | GNUNET_NO); | ||
2644 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2645 | "Setup secret with cmac %s\n", | ||
2646 | GNUNET_h2s (&(receiver->ss_rekey->cmac))); | ||
2647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2648 | "Setup secret with master %s.\n", | ||
2649 | GNUNET_h2s (&(receiver->ss_rekey->master))); | ||
2650 | } | ||
2651 | |||
2652 | if (send_rekey) | ||
2653 | { | ||
2654 | GNUNET_assert (0 != receiver->number_rekeying_kce); | ||
2655 | gcry_cipher_hd_t rekey_out_cipher; | ||
2656 | |||
2657 | while (NULL != ss && ss->sequence_used >= ss->sequence_allowed) | ||
2658 | { | ||
2659 | ss = ss->prev; | ||
2660 | } | ||
2661 | |||
2662 | if (NULL != ss) | ||
2663 | { | ||
2664 | rekey = (struct UDPRekey *) rekey_dgram; | ||
2665 | rekey->sender = my_identity; | ||
2666 | ss->sequence_used++; | ||
2667 | get_kid (&ss->master, ss->sequence_used, &rekey->kid); | ||
2668 | receiver->number_rekeying_kce--; | ||
2669 | setup_cipher (&ss->master, ss->sequence_used, &rekey_out_cipher); | ||
2670 | /* Append encrypted payload to dgram */ | ||
2671 | dpos = sizeof(struct UDPRekey); | ||
2672 | |||
2673 | GNUNET_assert ( | ||
2674 | 0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey_dgram[dpos], | ||
2675 | sizeof(receiver->ss_rekey->master), | ||
2676 | &(receiver->ss_rekey->master), | ||
2677 | sizeof(receiver->ss_rekey->master))); | ||
2678 | dpos += sizeof(receiver->ss_rekey->master); | ||
2679 | /* GNUNET_assert ( */ | ||
2680 | /* 0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey_dgram[dpos], */ | ||
2681 | /* /\*sizeof(receiver->ss_rekey->cmac), */ | ||
2682 | /* &(receiver->ss_rekey->cmac), */ | ||
2683 | /* sizeof(receiver->ss_rekey->cmac))); */ | ||
2684 | /* dpos += sizeof(receiver->ss_rekey->cmac);*\/ */ | ||
2685 | /* sizeof(receiver->ss_rekey), */ | ||
2686 | /* receiver->ss_rekey, */ | ||
2687 | /* sizeof(receiver->ss_rekey))); */ | ||
2688 | /* dpos += sizeof(receiver->ss_rekey); */ | ||
2689 | do_pad (rekey_out_cipher, &rekey_dgram[dpos], sizeof(rekey_dgram) | ||
2690 | - dpos); | ||
2691 | GNUNET_assert (0 == gcry_cipher_gettag (rekey_out_cipher, | ||
2692 | rekey->gcm_tag, | ||
2693 | sizeof(rekey->gcm_tag))); | ||
2694 | gcry_cipher_close (rekey_out_cipher); | ||
2695 | |||
2696 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2697 | "Sending rekey with kid %s and master %s\n", | ||
2698 | GNUNET_sh2s (&rekey->kid), | ||
2699 | GNUNET_h2s (&(receiver->ss_rekey->master))); | ||
2700 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2701 | "Sending rekey with cmac %s\n", | ||
2702 | GNUNET_h2s (&(receiver->ss_rekey->cmac))); | ||
2703 | |||
2704 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | ||
2705 | rekey_dgram, | ||
2706 | sizeof(rekey_dgram), | ||
2707 | receiver->address, | ||
2708 | receiver->address_len)) | ||
2709 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | ||
2710 | |||
2711 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2712 | "Sending UDPRekey to %s\n", GNUNET_a2s (receiver->address, | ||
2713 | receiver-> | ||
2714 | address_len)); | ||
2715 | } | ||
2716 | } | ||
2717 | } | ||
2718 | |||
2215 | 2719 | ||
2216 | /** | 2720 | /** |
2217 | * Signature of functions implementing the sending functionality of a | 2721 | * Signature of functions implementing the sending functionality of a |
@@ -2228,15 +2732,14 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2228 | { | 2732 | { |
2229 | struct ReceiverAddress *receiver = impl_state; | 2733 | struct ReceiverAddress *receiver = impl_state; |
2230 | uint16_t msize = ntohs (msg->size); | 2734 | uint16_t msize = ntohs (msg->size); |
2231 | struct GNUNET_TIME_Relative rt; | ||
2232 | struct SharedSecret *pos; | ||
2233 | 2735 | ||
2234 | GNUNET_assert (mq == receiver->d_mq); | 2736 | GNUNET_assert (mq == receiver->d_mq); |
2235 | if ((msize > receiver->d_mtu) || | 2737 | if ((msize > receiver->d_mtu) || |
2236 | (0 == receiver->acks_available)) | 2738 | (0 == receiver->acks_available)) |
2237 | { | 2739 | { |
2238 | GNUNET_break (0); | 2740 | GNUNET_break (0); |
2239 | receiver_destroy (receiver); | 2741 | if (GNUNET_YES != receiver->receiver_destroy_called) |
2742 | receiver_destroy (receiver); | ||
2240 | return; | 2743 | return; |
2241 | } | 2744 | } |
2242 | reschedule_receiver_timeout (receiver); | 2745 | reschedule_receiver_timeout (receiver); |
@@ -2278,6 +2781,16 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2278 | box->gcm_tag, | 2781 | box->gcm_tag, |
2279 | sizeof(box->gcm_tag))); | 2782 | sizeof(box->gcm_tag))); |
2280 | gcry_cipher_close (out_cipher); | 2783 | gcry_cipher_close (out_cipher); |
2784 | |||
2785 | receiver->rekey_send_bytes += sizeof(struct UDPBox) + receiver->d_mtu; | ||
2786 | |||
2787 | if (GNUNET_NO == receiver->rekeying) | ||
2788 | box->rekeying = GNUNET_NO; | ||
2789 | else | ||
2790 | box->rekeying = GNUNET_YES; | ||
2791 | |||
2792 | check_for_rekeying (receiver, box); | ||
2793 | |||
2281 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | 2794 | if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, |
2282 | dgram, | 2795 | dgram, |
2283 | sizeof(dgram), | 2796 | sizeof(dgram), |
@@ -2288,38 +2801,26 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2288 | "Sending UDPBox to %s\n", GNUNET_a2s (receiver->address, | 2801 | "Sending UDPBox to %s\n", GNUNET_a2s (receiver->address, |
2289 | receiver->address_len)); | 2802 | receiver->address_len)); |
2290 | GNUNET_MQ_impl_send_continue (mq); | 2803 | GNUNET_MQ_impl_send_continue (mq); |
2291 | // receiver->acks_available--; | 2804 | receiver->acks_available--; |
2292 | if (0 == receiver->acks_available) | 2805 | if (0 == receiver->acks_available) |
2293 | { | 2806 | { |
2294 | /* We have no more ACKs */ | 2807 | /* We have no more ACKs */ |
2295 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2808 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2296 | "No more acks\n"); | 2809 | "No more acks\n"); |
2297 | } | 2810 | if (GNUNET_YES == receiver->rekeying) |
2298 | |||
2299 | /* (NULL == rekey_timeout) | ||
2300 | rekey_timeout = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL); | ||
2301 | else | ||
2302 | { | ||
2303 | rt = GNUNET_TIME_absolute_get_remaining (rekey_timeout); | ||
2304 | if (0 == rt.rel_value_us) | ||
2305 | { | 2811 | { |
2306 | rekey_timeout = NULL; | 2812 | receiver->rekeying = GNUNET_NO; |
2307 | pos = receiver->ss_head; | ||
2308 | while ( NULL != pos) | ||
2309 | { | ||
2310 | ss_to_destroy = pos; | ||
2311 | pos = pos->next; | ||
2312 | secret_destroy (ss_to_destroy, GNUNET_NO); | ||
2313 | } | ||
2314 | if (0 != receiver->acks_available) | ||
2315 | GNUNET_TRANSPORT_communicator_mq_update (ch, | ||
2316 | receiver->d_qh, | ||
2317 | // TODO We can not do this. But how can we signal this queue is not able to handle a message. Test code interprets q-len as additional length. | ||
2318 | -receiver->acks_available, | ||
2319 | 1); | ||
2320 | } | ||
2321 | }*/ | ||
2322 | 2813 | ||
2814 | if ((NULL != receiver->ss_rekey) && (0 < | ||
2815 | receiver->ss_rekey-> | ||
2816 | sequence_allowed) ) | ||
2817 | add_acks_rekey (receiver); | ||
2818 | } | ||
2819 | } | ||
2820 | else if ((GNUNET_YES == receiver->rekeying) ) | ||
2821 | { | ||
2822 | send_UDPRekey (receiver, ss); | ||
2823 | } | ||
2323 | 2824 | ||
2324 | return; | 2825 | return; |
2325 | } | 2826 | } |
@@ -2343,7 +2844,8 @@ mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
2343 | if (mq == receiver->d_mq) | 2844 | if (mq == receiver->d_mq) |
2344 | { | 2845 | { |
2345 | receiver->d_mq = NULL; | 2846 | receiver->d_mq = NULL; |
2346 | receiver_destroy (receiver); | 2847 | if (GNUNET_YES != receiver->receiver_destroy_called) |
2848 | receiver_destroy (receiver); | ||
2347 | } | 2849 | } |
2348 | } | 2850 | } |
2349 | 2851 | ||
@@ -2365,7 +2867,8 @@ mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
2365 | if (mq == receiver->kx_mq) | 2867 | if (mq == receiver->kx_mq) |
2366 | { | 2868 | { |
2367 | receiver->kx_mq = NULL; | 2869 | receiver->kx_mq = NULL; |
2368 | receiver_destroy (receiver); | 2870 | if (GNUNET_YES != receiver->receiver_destroy_called) |
2871 | receiver_destroy (receiver); | ||
2369 | } | 2872 | } |
2370 | } | 2873 | } |
2371 | 2874 | ||
@@ -2997,6 +3500,13 @@ run (void *cls, | |||
2997 | return; | 3500 | return; |
2998 | } | 3501 | } |
2999 | 3502 | ||
3503 | if (GNUNET_OK != | ||
3504 | GNUNET_CONFIGURATION_get_value_time (cfg, | ||
3505 | COMMUNICATOR_CONFIG_SECTION, | ||
3506 | "REKEY_INTERVAL", | ||
3507 | &rekey_interval)) | ||
3508 | rekey_interval = DEFAULT_REKEY_TIME_INTERVAL; | ||
3509 | |||
3000 | in = udp_address_to_sockaddr (bindto, &in_len); | 3510 | in = udp_address_to_sockaddr (bindto, &in_len); |
3001 | if (NULL == in) | 3511 | if (NULL == in) |
3002 | { | 3512 | { |