aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2024-03-14 21:59:32 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2024-03-14 21:59:32 +0100
commitbfe72f857072846102e031e4064100921399624b (patch)
tree208bb89e87c2fac375e41756684bb10e82965bf5
parentdcf85f8b41547667293ee55218007407b40c4686 (diff)
downloadgnunet-bfe72f857072846102e031e4064100921399624b.tar.gz
gnunet-bfe72f857072846102e031e4064100921399624b.zip
TRANSPORT(udp): Improve handling and lookup of existing connections similar to TCP communicator fix wrt Queue handling.
-rw-r--r--src/service/transport/gnunet-communicator-udp.c160
1 files changed, 92 insertions, 68 deletions
diff --git a/src/service/transport/gnunet-communicator-udp.c b/src/service/transport/gnunet-communicator-udp.c
index c8c7e8bf9..70528d7ec 100644
--- a/src/service/transport/gnunet-communicator-udp.c
+++ b/src/service/transport/gnunet-communicator-udp.c
@@ -527,6 +527,11 @@ struct SenderAddress
527 socklen_t address_len; 527 socklen_t address_len;
528 528
529 /** 529 /**
530 * The address key for this entry.
531 */
532 struct GNUNET_HashCode key;
533
534 /**
530 * Timeout for this sender. 535 * Timeout for this sender.
531 */ 536 */
532 struct GNUNET_TIME_Absolute timeout; 537 struct GNUNET_TIME_Absolute timeout;
@@ -586,6 +591,11 @@ struct ReceiverAddress
586 struct GNUNET_PeerIdentity target; 591 struct GNUNET_PeerIdentity target;
587 592
588 /** 593 /**
594 * The address key for this entry.
595 */
596 struct GNUNET_HashCode key;
597
598 /**
589 * Shared secrets we received from @e target, first used is head. 599 * Shared secrets we received from @e target, first used is head.
590 */ 600 */
591 struct SharedSecret *ss_head; 601 struct SharedSecret *ss_head;
@@ -768,12 +778,12 @@ static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
768/** 778/**
769 * Receivers (map from peer identity to `struct ReceiverAddress`) 779 * Receivers (map from peer identity to `struct ReceiverAddress`)
770 */ 780 */
771static struct GNUNET_CONTAINER_MultiPeerMap *receivers; 781static struct GNUNET_CONTAINER_MultiHashMap *receivers;
772 782
773/** 783/**
774 * Senders (map from peer identity to `struct SenderAddress`) 784 * Senders (map from peer identity to `struct SenderAddress`)
775 */ 785 */
776static struct GNUNET_CONTAINER_MultiPeerMap *senders; 786static struct GNUNET_CONTAINER_MultiHashMap *senders;
777 787
778/** 788/**
779 * Expiration heap for senders (contains `struct SenderAddress`) 789 * Expiration heap for senders (contains `struct SenderAddress`)
@@ -895,13 +905,13 @@ receiver_destroy (struct ReceiverAddress *receiver)
895 receiver->d_qh = NULL; 905 receiver->d_qh = NULL;
896 } 906 }
897 GNUNET_assert (GNUNET_YES == 907 GNUNET_assert (GNUNET_YES ==
898 GNUNET_CONTAINER_multipeermap_remove (receivers, 908 GNUNET_CONTAINER_multihashmap_remove (receivers,
899 &receiver->target, 909 &receiver->key,
900 receiver)); 910 receiver));
901 GNUNET_assert (receiver == GNUNET_CONTAINER_heap_remove_node (receiver->hn)); 911 GNUNET_assert (receiver == GNUNET_CONTAINER_heap_remove_node (receiver->hn));
902 GNUNET_STATISTICS_set (stats, 912 GNUNET_STATISTICS_set (stats,
903 "# receivers active", 913 "# receivers active",
904 GNUNET_CONTAINER_multipeermap_size (receivers), 914 GNUNET_CONTAINER_multihashmap_size (receivers),
905 GNUNET_NO); 915 GNUNET_NO);
906 GNUNET_free (receiver->address); 916 GNUNET_free (receiver->address);
907 GNUNET_free (receiver->foreign_addr); 917 GNUNET_free (receiver->foreign_addr);
@@ -1053,11 +1063,11 @@ sender_destroy (struct SenderAddress *sender)
1053 sender->sender_destroy_called = GNUNET_YES; 1063 sender->sender_destroy_called = GNUNET_YES;
1054 GNUNET_assert ( 1064 GNUNET_assert (
1055 GNUNET_YES == 1065 GNUNET_YES ==
1056 GNUNET_CONTAINER_multipeermap_remove (senders, &sender->target, sender)); 1066 GNUNET_CONTAINER_multihashmap_remove (senders, &sender->key, sender));
1057 GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn)); 1067 GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn));
1058 GNUNET_STATISTICS_set (stats, 1068 GNUNET_STATISTICS_set (stats,
1059 "# senders active", 1069 "# senders active",
1060 GNUNET_CONTAINER_multipeermap_size (senders), 1070 GNUNET_CONTAINER_multihashmap_size (senders),
1061 GNUNET_NO); 1071 GNUNET_NO);
1062 GNUNET_free (sender->address); 1072 GNUNET_free (sender->address);
1063 GNUNET_free (sender); 1073 GNUNET_free (sender);
@@ -1507,7 +1517,7 @@ add_acks (struct SharedSecret *ss, int acks_to_add)
1507 * @return #GNUNET_YES to continue to iterate 1517 * @return #GNUNET_YES to continue to iterate
1508 */ 1518 */
1509static int 1519static int
1510handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) 1520handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1511{ 1521{
1512 const struct UDPAck *ack = cls; 1522 const struct UDPAck *ack = cls;
1513 struct ReceiverAddress *receiver = value; 1523 struct ReceiverAddress *receiver = value;
@@ -1518,7 +1528,7 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1518 "in handle ack with cmac %s\n", 1528 "in handle ack with cmac %s\n",
1519 GNUNET_h2s (&ack->cmac)); 1529 GNUNET_h2s (&ack->cmac));
1520 1530
1521 (void) pid; 1531 (void) key;
1522 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) 1532 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1523 { 1533 {
1524 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode))) 1534 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
@@ -1722,8 +1732,8 @@ try_handle_plaintext (struct SenderAddress *sender,
1722 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: 1732 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK:
1723 /* lookup master secret by 'cmac', then update sequence_max */ 1733 /* lookup master secret by 'cmac', then update sequence_max */
1724 ack = (struct UDPAck*) buf_pos; 1734 ack = (struct UDPAck*) buf_pos;
1725 GNUNET_CONTAINER_multipeermap_get_multiple (receivers, 1735 GNUNET_CONTAINER_multihashmap_get_multiple (receivers,
1726 &sender->target, 1736 &sender->key,
1727 &handle_ack, 1737 &handle_ack,
1728 (void *) ack); 1738 (void *) ack);
1729 /* There could be more messages after the ACK, handle those as well */ 1739 /* There could be more messages after the ACK, handle those as well */
@@ -1854,32 +1864,6 @@ struct SearchContext
1854 1864
1855 1865
1856/** 1866/**
1857 * Find existing `struct SenderAddress` by matching addresses.
1858 *
1859 * @param cls a `struct SearchContext`
1860 * @param key ignored, must match already
1861 * @param value a `struct SenderAddress`
1862 * @return #GNUNET_YES if not found (continue to search), #GNUNET_NO if found
1863 */
1864static int
1865find_sender_by_address (void *cls,
1866 const struct GNUNET_PeerIdentity *key,
1867 void *value)
1868{
1869 struct SearchContext *sc = cls;
1870 struct SenderAddress *sender = value;
1871
1872 if ((sender->address_len == sc->address_len) &&
1873 (0 == memcmp (sender->address, sc->address, sender->address_len)))
1874 {
1875 sc->sender = sender;
1876 return GNUNET_NO; /* stop iterating! */
1877 }
1878 return GNUNET_YES;
1879}
1880
1881
1882/**
1883 * Create sender address for @a target. Note that we 1867 * Create sender address for @a target. Note that we
1884 * might already have one, so a fresh one is only allocated 1868 * might already have one, so a fresh one is only allocated
1885 * if one does not yet exist for @a address. 1869 * if one does not yet exist for @a address.
@@ -1896,31 +1880,33 @@ setup_sender (const struct GNUNET_PeerIdentity *target,
1896 socklen_t address_len) 1880 socklen_t address_len)
1897{ 1881{
1898 struct SenderAddress *sender; 1882 struct SenderAddress *sender;
1899 struct SearchContext sc = { .address = address, 1883 struct GNUNET_HashContext *hsh;
1900 .address_len = address_len, 1884 struct GNUNET_HashCode sender_key;
1901 .sender = NULL };
1902 1885
1903 GNUNET_CONTAINER_multipeermap_get_multiple (senders, 1886 hsh = GNUNET_CRYPTO_hash_context_start ();
1904 target, 1887 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1905 &find_sender_by_address, 1888 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1906 &sc); 1889 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1907 if (NULL != sc.sender) 1890
1891 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1892 if (NULL != sender)
1908 { 1893 {
1909 reschedule_sender_timeout (sc.sender); 1894 reschedule_sender_timeout (sender);
1910 return sc.sender; 1895 return sender;
1911 } 1896 }
1912 sender = GNUNET_new (struct SenderAddress); 1897 sender = GNUNET_new (struct SenderAddress);
1898 sender->key = sender_key;
1913 sender->target = *target; 1899 sender->target = *target;
1914 sender->address = GNUNET_memdup (address, address_len); 1900 sender->address = GNUNET_memdup (address, address_len);
1915 sender->address_len = address_len; 1901 sender->address_len = address_len;
1916 (void) GNUNET_CONTAINER_multipeermap_put ( 1902 (void) GNUNET_CONTAINER_multihashmap_put (
1917 senders, 1903 senders,
1918 &sender->target, 1904 &sender->key,
1919 sender, 1905 sender,
1920 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1906 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1921 GNUNET_STATISTICS_set (stats, 1907 GNUNET_STATISTICS_set (stats,
1922 "# senders active", 1908 "# senders active",
1923 GNUNET_CONTAINER_multipeermap_size (receivers), 1909 GNUNET_CONTAINER_multihashmap_size (receivers),
1924 GNUNET_NO); 1910 GNUNET_NO);
1925 sender->timeout = 1911 sender->timeout =
1926 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1912 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
@@ -2034,7 +2020,7 @@ sock_read (void *cls)
2034 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2020 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2035 "Failed to recv from %s family %d failed sock %p\n", 2021 "Failed to recv from %s family %d failed sock %p\n",
2036 GNUNET_a2s ((struct sockaddr*) &sa, 2022 GNUNET_a2s ((struct sockaddr*) &sa,
2037 sizeof (addr)), 2023 sizeof (*addr)),
2038 addr->sa_family, 2024 addr->sa_family,
2039 udp_sock); 2025 udp_sock);
2040 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recv"); 2026 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recv");
@@ -2863,6 +2849,8 @@ static int
2863mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) 2849mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2864{ 2850{
2865 struct ReceiverAddress *receiver; 2851 struct ReceiverAddress *receiver;
2852 struct GNUNET_HashContext *hsh;
2853 struct GNUNET_HashCode receiver_key;
2866 const char *path; 2854 const char *path;
2867 struct sockaddr *in; 2855 struct sockaddr *in;
2868 socklen_t in_len; 2856 socklen_t in_len;
@@ -2877,14 +2865,29 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2877 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; 2865 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2878 in = udp_address_to_sockaddr (path, &in_len); 2866 in = udp_address_to_sockaddr (path, &in_len);
2879 2867
2868 hsh = GNUNET_CRYPTO_hash_context_start ();
2869 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2870 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2871 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2872
2873 receiver = GNUNET_CONTAINER_multihashmap_get (receivers, &receiver_key);
2874 if (NULL != receiver)
2875 {
2876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2877 "receiver %s already exist or is begin connected to\n",
2878 address);
2879 return GNUNET_SYSERR;
2880 }
2881
2880 receiver = GNUNET_new (struct ReceiverAddress); 2882 receiver = GNUNET_new (struct ReceiverAddress);
2883 receiver->key = receiver_key;
2881 receiver->address = in; 2884 receiver->address = in;
2882 receiver->address_len = in_len; 2885 receiver->address_len = in_len;
2883 receiver->target = *peer; 2886 receiver->target = *peer;
2884 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len); 2887 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2885 (void) GNUNET_CONTAINER_multipeermap_put ( 2888 (void) GNUNET_CONTAINER_multihashmap_put (
2886 receivers, 2889 receivers,
2887 &receiver->target, 2890 &receiver->key,
2888 receiver, 2891 receiver,
2889 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 2892 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2897,7 +2900,7 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2897 receiver->timeout.abs_value_us); 2900 receiver->timeout.abs_value_us);
2898 GNUNET_STATISTICS_set (stats, 2901 GNUNET_STATISTICS_set (stats,
2899 "# receivers active", 2902 "# receivers active",
2900 GNUNET_CONTAINER_multipeermap_size (receivers), 2903 GNUNET_CONTAINER_multihashmap_size (receivers),
2901 GNUNET_NO); 2904 GNUNET_NO);
2902 receiver->foreign_addr = 2905 receiver->foreign_addr =
2903 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len); 2906 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
@@ -2918,7 +2921,7 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2918 */ 2921 */
2919static int 2922static int
2920get_receiver_delete_it (void *cls, 2923get_receiver_delete_it (void *cls,
2921 const struct GNUNET_PeerIdentity *target, 2924 const struct GNUNET_HashCode *target,
2922 void *value) 2925 void *value)
2923{ 2926{
2924 struct ReceiverAddress *receiver = value; 2927 struct ReceiverAddress *receiver = value;
@@ -2940,7 +2943,7 @@ get_receiver_delete_it (void *cls,
2940 */ 2943 */
2941static int 2944static int
2942get_sender_delete_it (void *cls, 2945get_sender_delete_it (void *cls,
2943 const struct GNUNET_PeerIdentity *target, 2946 const struct GNUNET_HashCode *target,
2944 void *value) 2947 void *value)
2945{ 2948{
2946 struct SenderAddress *sender = value; 2949 struct SenderAddress *sender = value;
@@ -2992,14 +2995,14 @@ do_shutdown (void *cls)
2992 GNUNET_NETWORK_socket_close (udp_sock)); 2995 GNUNET_NETWORK_socket_close (udp_sock));
2993 udp_sock = NULL; 2996 udp_sock = NULL;
2994 } 2997 }
2995 GNUNET_CONTAINER_multipeermap_iterate (receivers, 2998 GNUNET_CONTAINER_multihashmap_iterate (receivers,
2996 &get_receiver_delete_it, 2999 &get_receiver_delete_it,
2997 NULL); 3000 NULL);
2998 GNUNET_CONTAINER_multipeermap_destroy (receivers); 3001 GNUNET_CONTAINER_multihashmap_destroy (receivers);
2999 GNUNET_CONTAINER_multipeermap_iterate (senders, 3002 GNUNET_CONTAINER_multihashmap_iterate (senders,
3000 &get_sender_delete_it, 3003 &get_sender_delete_it,
3001 NULL); 3004 NULL);
3002 GNUNET_CONTAINER_multipeermap_destroy (senders); 3005 GNUNET_CONTAINER_multihashmap_destroy (senders);
3003 GNUNET_CONTAINER_multishortmap_destroy (key_cache); 3006 GNUNET_CONTAINER_multishortmap_destroy (key_cache);
3004 GNUNET_CONTAINER_heap_destroy (senders_heap); 3007 GNUNET_CONTAINER_heap_destroy (senders_heap);
3005 GNUNET_CONTAINER_heap_destroy (receivers_heap); 3008 GNUNET_CONTAINER_heap_destroy (receivers_heap);
@@ -3038,6 +3041,27 @@ do_shutdown (void *cls)
3038} 3041}
3039 3042
3040 3043
3044struct AckInfo
3045{
3046 const struct UDPAck *ack;
3047
3048 const struct GNUNET_PeerIdentity *sender;
3049};
3050
3051static int
3052handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3053{
3054 struct ReceiverAddress *receiver = value;
3055 struct AckInfo *ai = cls;
3056
3057 if (0 != GNUNET_memcmp(ai->sender, &receiver->target))
3058 {
3059 return GNUNET_YES;
3060 }
3061 handle_ack((void*) ai->ack, key, receiver);
3062 return GNUNET_YES;
3063}
3064
3041/** 3065/**
3042 * Function called when the transport service has received a 3066 * Function called when the transport service has received a
3043 * backchannel message for this communicator (!) via a different return 3067 * backchannel message for this communicator (!) via a different return
@@ -3052,7 +3076,7 @@ enc_notify_cb (void *cls,
3052 const struct GNUNET_PeerIdentity *sender, 3076 const struct GNUNET_PeerIdentity *sender,
3053 const struct GNUNET_MessageHeader *msg) 3077 const struct GNUNET_MessageHeader *msg)
3054{ 3078{
3055 const struct UDPAck *ack; 3079 struct AckInfo ai;
3056 3080
3057 (void) cls; 3081 (void) cls;
3058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3064,11 +3088,11 @@ enc_notify_cb (void *cls,
3064 GNUNET_break_op (0); 3088 GNUNET_break_op (0);
3065 return; 3089 return;
3066 } 3090 }
3067 ack = (const struct UDPAck *) msg; 3091 ai.ack = (const struct UDPAck *) msg;
3068 GNUNET_CONTAINER_multipeermap_get_multiple (receivers, 3092 ai.sender = sender;
3069 sender, 3093 GNUNET_CONTAINER_multihashmap_iterate (receivers,
3070 &handle_ack, 3094 &handle_ack_by_sender,
3071 (void *) ack); 3095 &ai);
3072} 3096}
3073 3097
3074 3098
@@ -3493,8 +3517,8 @@ run (void *cls,
3493 my_port = 0; 3517 my_port = 0;
3494 } 3518 }
3495 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg); 3519 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3496 senders = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); 3520 senders = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
3497 receivers = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); 3521 receivers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
3498 senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 3522 senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3499 receivers_heap = 3523 receivers_heap =
3500 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 3524 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);