From 8c40115c58f639edc17ff242ec1a79c2078dc301 Mon Sep 17 00:00:00 2001 From: t3sserakt Date: Tue, 6 Oct 2020 07:20:10 +0200 Subject: - first attempt to fix the udp backchannel --- src/transport/gnunet-communicator-udp.c | 372 +++++++++++++++++++------------- src/transport/test_communicator_basic.c | 174 +++++++++++---- 2 files changed, 363 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 5ca5a4e86..579f744e5 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c @@ -75,6 +75,9 @@ */ #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS +#define WORKING_QUEUE_INTERVALL \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1) + /** * AES key size. */ @@ -90,6 +93,8 @@ */ #define GCM_TAG_SIZE (128 / 8) +#define GENERATE_AT_ONCE 20 + /** * If we fall below this number of available KCNs, * we generate additional ACKs until we reach @@ -499,6 +504,12 @@ struct SenderAddress */ unsigned int num_secrets; + /** + * Number of BOX keys from ACKs we have currently + * available for this sender. + */ + unsigned int acks_available; + /** * Which network type does this queue use? */ @@ -796,26 +807,15 @@ bi_destroy (struct BroadcastInterface *bi) static void receiver_destroy (struct ReceiverAddress *receiver) { - struct GNUNET_MQ_Handle *mq; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting receiver for peer `%s'\n", GNUNET_i2s (&receiver->target)); - if (NULL != (mq = receiver->kx_mq)) - { - receiver->kx_mq = NULL; - GNUNET_MQ_destroy (mq); - } if (NULL != receiver->kx_qh) { GNUNET_TRANSPORT_communicator_mq_del (receiver->kx_qh); receiver->kx_qh = NULL; } - if (NULL != (mq = receiver->d_mq)) - { - receiver->d_mq = NULL; - GNUNET_MQ_destroy (mq); - } if (NULL != receiver->d_qh) { GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh); @@ -847,6 +847,7 @@ kce_destroy (struct KeyCacheEntry *kce) struct SharedSecret *ss = kce->ss; ss->active_kce_count--; + ss->sender->acks_available--; GNUNET_CONTAINER_DLL_remove (ss->kce_head, ss->kce_tail, kce); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (key_cache, &kce->kid, @@ -902,6 +903,7 @@ kce_generate (struct SharedSecret *ss, uint32_t seq) get_kid (&ss->master, seq, &kce->kid); GNUNET_CONTAINER_DLL_insert (ss->kce_head, ss->kce_tail, kce); ss->active_kce_count++; + ss->sender->acks_available++; (void) GNUNET_CONTAINER_multishortmap_put ( key_cache, &kce->kid, @@ -930,12 +932,19 @@ secret_destroy (struct SharedSecret *ss) { GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss); sender->num_secrets--; + sender->acks_available -= ss->active_kce_count; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u acks available after secrect destroy.\n", + sender->acks_available); } if (NULL != (receiver = ss->receiver)) { GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); receiver->num_secrets--; receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u acks available after secrect destroy.\n", + receiver->acks_available); } while (NULL != (kce = ss->kce_head)) kce_destroy (kce); @@ -1250,6 +1259,10 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, &receiver->target.public_key, &ss->master); calculate_cmac (ss); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Created cmac %s for secret %p.\n", + GNUNET_h2s (&ss->cmac), + ss); ss->receiver = receiver; GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); receiver->num_secrets++; @@ -1298,12 +1311,11 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) allowed = ntohl (ack->sequence_max); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u > %u (%u)\n", allowed, ss->sequence_allowed, + receiver->acks_available); if (allowed > ss->sequence_allowed) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%u > %u (%u)\n", allowed, ss->sequence_allowed, - receiver->acks_available); - receiver->acks_available += (allowed - ss->sequence_allowed); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Tell transport we have more acks!\n"); @@ -1312,6 +1324,9 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) (allowed - ss->sequence_allowed), 1); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u acks made available.\n", + receiver->acks_available); ss->sequence_allowed = allowed; /* move ss to head to avoid discarding it anytime soon! */ GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); @@ -1370,6 +1385,19 @@ try_handle_plaintext (struct SenderAddress *sender, } } +static void +kce_generate_cb (void *cls) +{ + struct SharedSecret *ss = cls; + + for (int i = 0; i < GENERATE_AT_ONCE; i++) + kce_generate (ss, ++ss->sequence_allowed); + + /*GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, + kce_generate_cb, + ss);*/ + +} /** * We established a shared secret with a sender. We should try to send @@ -1392,7 +1420,12 @@ consider_ss_ack (struct SharedSecret *ss) (MAX_SQN_DELTA < ss->kce_head->sequence_number - ss->kce_tail->sequence_number)) kce_destroy (ss->kce_tail); - if (ss->active_kce_count < KCN_THRESHOLD) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u active count and %u acks available\n", + ss->active_kce_count, + ss->sender->acks_available); + if ((ss->active_kce_count < KCN_THRESHOLD) && (ss->sender->acks_available < + KCN_TARGET) ) { struct UDPAck ack; @@ -1403,15 +1436,19 @@ consider_ss_ack (struct SharedSecret *ss) * we only generate a single KCE to prevent * unnecessary overhead. */ - if (0 < ss->active_kce_count) { + GNUNET_SCHEDULER_add_now (kce_generate_cb, ss); + /*if (0 < ss->sequence_allowed) + { while (ss->active_kce_count < KCN_TARGET) kce_generate (ss, ++ss->sequence_allowed); - } else { - kce_generate (ss, ++ss->sequence_allowed); } + else {*/ + /*kce_generate (ss, ++ss->sequence_allowed); + kce_generate (ss, ++ss->sequence_allowed);*/ + // } ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); ack.header.size = htons (sizeof(ack)); - ack.sequence_max = htonl (ss->sequence_allowed); + ack.sequence_max = htonl (ss->sequence_allowed + GENERATE_AT_ONCE); ack.cmac = ss->cmac; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of UDPAck %s\n", @@ -1452,6 +1489,10 @@ decrypt_box (const struct UDPBox *box, 1, GNUNET_NO); kce_destroy (kce); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "decrypting of UDPBox with kid %s and cmac %s failed\n", + GNUNET_sh2s (&box->kid), + GNUNET_h2s (&ss->cmac)); return; } kce_destroy (kce); @@ -1459,6 +1500,9 @@ decrypt_box (const struct UDPBox *box, "# bytes decrypted with BOX", sizeof(out_buf), GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "decrypted UDPBox with kid %s\n", + GNUNET_sh2s (&box->kid)); try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); consider_ss_ack (ss); } @@ -1517,7 +1561,7 @@ find_sender_by_address (void *cls, * might already have one, so a fresh one is only allocated * if one does not yet exist for @a address. * - * @param target peer to generate address for + * @param target peer to generate address for (can be NULL, if we already have one). * @param address target address * @param address_len number of bytes in @a address * @return data structure to keep track of key material for @@ -1530,14 +1574,14 @@ setup_sender (const struct GNUNET_PeerIdentity *target, { struct SenderAddress *sender; struct SearchContext sc = { .address = address, - .address_len = address_len, - .sender = NULL }; + .address_len = address_len, + .sender = NULL }; GNUNET_CONTAINER_multipeermap_get_multiple (senders, target, &find_sender_by_address, &sc); - if (NULL != sc.sender) + if ((NULL != sc.sender)||(NULL == target)) { reschedule_sender_timeout (sc.sender); return sc.sender; @@ -1547,10 +1591,10 @@ setup_sender (const struct GNUNET_PeerIdentity *target, sender->address = GNUNET_memdup (address, address_len); sender->address_len = address_len; (void) GNUNET_CONTAINER_multipeermap_put ( - senders, - &sender->target, - sender, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + senders, + &sender->target, + sender, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GNUNET_STATISTICS_set (stats, "# senders active", GNUNET_CONTAINER_multipeermap_size (receivers), @@ -1587,10 +1631,10 @@ verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, uhs.ephemeral = *ephemeral; uhs.monotonic_time = uc->monotonic_time; return GNUNET_CRYPTO_eddsa_verify ( - GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, - &uhs, - &uc->sender_sig, - &uc->sender.public_key); + GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, + &uhs, + &uc->sender_sig, + &uc->sender.public_key); } @@ -1610,22 +1654,22 @@ sockaddr_to_udpaddr_string (const struct sockaddr *address, switch (address->sa_family) { - case AF_INET: - GNUNET_asprintf (&ret, - "%s-%s", - COMMUNICATOR_ADDRESS_PREFIX, - GNUNET_a2s (address, address_len)); - break; + case AF_INET: + GNUNET_asprintf (&ret, + "%s-%s", + COMMUNICATOR_ADDRESS_PREFIX, + GNUNET_a2s (address, address_len)); + break; - case AF_INET6: - GNUNET_asprintf (&ret, - "%s-%s", - COMMUNICATOR_ADDRESS_PREFIX, - GNUNET_a2s (address, address_len)); - break; + case AF_INET6: + GNUNET_asprintf (&ret, + "%s-%s", + COMMUNICATOR_ADDRESS_PREFIX, + GNUNET_a2s (address, address_len)); + break; - default: - GNUNET_assert (0); + default: + GNUNET_assert (0); } return ret; } @@ -1660,7 +1704,8 @@ sock_read (void *cls) return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Read %lu bytes\n", rcvd); + "Read %lu bytes.\n", + rcvd); /* first, see if it is a UDPBox */ if (rcvd > sizeof(struct UDPBox)) { @@ -1674,6 +1719,9 @@ sock_read (void *cls) decrypt_box (box, (size_t) rcvd, kce); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No kid %s.\n", + GNUNET_sh2s (&box->kid)); } /* next, check if it is a broadcast */ @@ -1731,7 +1779,8 @@ sock_read (void *cls) kx = (const struct InitialKX *) buf; ss = setup_shared_secret_dec (&kx->ephemeral); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Before DEC\n"); + "Before DEC with ephemeral %s\n", + GNUNET_e2s (&kx->ephemeral)); if (GNUNET_OK != try_decrypt (ss, kx->gcm_tag, @@ -1744,10 +1793,10 @@ sock_read (void *cls) "Unable to decrypt tag, dropping...\n"); GNUNET_free (ss); GNUNET_STATISTICS_update ( - stats, - "# messages dropped (no kid, AEAD decryption failed)", - 1, - GNUNET_NO); + stats, + "# messages dropped (no kid, AEAD decryption failed)", + 1, + GNUNET_NO); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1768,6 +1817,10 @@ sock_read (void *cls) "Before SETUP_SENDER\n"); calculate_cmac (ss); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got cmac %s for secret %p.\n", + GNUNET_h2s (&ss->cmac), + ss); sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen); ss->sender = sender; GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss); @@ -1778,9 +1831,12 @@ sock_read (void *cls) 1, GNUNET_NO); try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "We have %u secrets\n", + sender->num_secrets); + /*if (sender->num_secrets > MAX_SECRETS) + secret_destroy (sender->ss_tail);*/ consider_ss_ack (ss); - if (sender->num_secrets > MAX_SECRETS) - secret_destroy (sender->ss_tail); } } @@ -1859,9 +1915,9 @@ udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len) else { GNUNET_log ( - GNUNET_ERROR_TYPE_ERROR, - "BINDTO specification `%s' invalid: last ':' not followed by number\n", - bindto); + GNUNET_ERROR_TYPE_ERROR, + "BINDTO specification `%s' invalid: last ':' not followed by number\n", + bindto); GNUNET_free (cp); return NULL; } @@ -1939,8 +1995,8 @@ do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size) memcpy (pad, &hdr, sizeof(hdr)); } GNUNET_assert ( - 0 == - gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad))); + 0 == + gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad))); } @@ -1982,6 +2038,8 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, GNUNET_CRYPTO_ecdhe_key_create (&epriv); ss = setup_shared_secret_enc (&epriv, receiver); + /*if (receiver->num_secrets > MAX_SECRETS) + secret_destroy (receiver->ss_tail);*/ setup_cipher (&ss->master, 0, &out_cipher); /* compute 'uc' */ uc.sender = my_identity; @@ -2007,13 +2065,13 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, dpos += sizeof(uc); /* Append encrypted payload to dgram */ GNUNET_assert ( - 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); + 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); dpos += msize; do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); /* Datagram starts with kx */ kx.ephemeral = uhs.ephemeral; GNUNET_assert ( - 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); + 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); gcry_cipher_close (out_cipher); memcpy (dgram, &kx, sizeof(kx)); if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, @@ -2023,8 +2081,10 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, receiver->address_len)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending KX to %s\n", GNUNET_a2s (receiver->address, - receiver->address_len)); + "Sending KX to %s with ephemeral %s\n", + GNUNET_a2s (receiver->address, + receiver->address_len), + GNUNET_e2s (&kx.ephemeral)); GNUNET_MQ_impl_send_continue (mq); } @@ -2045,6 +2105,11 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, struct ReceiverAddress *receiver = impl_state; uint16_t msize = ntohs (msg->size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "sending to receiver %s with %u acks available.\n", + receiver->foreign_addr, + receiver->acks_available); + GNUNET_assert (mq == receiver->d_mq); if ((msize > receiver->d_mtu) || (0 == receiver->acks_available)) @@ -2069,12 +2134,16 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, box = (struct UDPBox *) dgram; ss->sequence_used++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "get kid with sequence number %u and cmac %s.\n", + ss->sequence_used, + GNUNET_h2s (&ss->cmac)); get_kid (&ss->master, ss->sequence_used, &box->kid); setup_cipher (&ss->master, ss->sequence_used, &out_cipher); /* Append encrypted payload to dgram */ dpos = sizeof(struct UDPBox); GNUNET_assert ( - 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); + 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); dpos += msize; do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); GNUNET_assert (0 == gcry_cipher_gettag (out_cipher, @@ -2087,8 +2156,19 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, receiver->address, receiver->address_len)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending UDPBox to %s with shared secrect %p and kid %s\n", + GNUNET_a2s ( + receiver->address, + receiver + ->address_len), + ss, + GNUNET_sh2s (&box->kid)); GNUNET_MQ_impl_send_continue (mq); receiver->acks_available--; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u acks available after sending.\n", + receiver->acks_available); if (0 == receiver->acks_available) { /* We have no more ACKs */ @@ -2205,25 +2285,25 @@ setup_receiver_mq (struct ReceiverAddress *receiver) // GNUNET_assert (NULL == receiver->mq); switch (receiver->address->sa_family) { - case AF_INET: - base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ - - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */ - - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; - break; + case AF_INET: + base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ + - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */ + - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; + break; - case AF_INET6: - base_mtu = 1280 /* Minimum MTU required by IPv6 */ - - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */ - - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; - break; + case AF_INET6: + base_mtu = 1280 /* Minimum MTU required by IPv6 */ + - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */ + - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; + break; - default: - GNUNET_assert (0); - break; + default: + GNUNET_assert (0); + break; } /* MTU based on full KX messages */ receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */ - - sizeof(struct UDPConfirmation); /* 104 */ + - sizeof(struct UDPConfirmation); /* 104 */ /* MTU based on BOXed messages */ receiver->d_mtu = base_mtu - sizeof(struct UDPBox); @@ -2314,10 +2394,10 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) receiver->target = *peer; receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len); (void) GNUNET_CONTAINER_multipeermap_put ( - receivers, - &receiver->target, - receiver, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + receivers, + &receiver->target, + receiver, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added %s to receivers\n", GNUNET_i2s_full (&receiver->target)); @@ -2553,55 +2633,55 @@ ifc_broadcast (void *cls) switch (bi->sa->sa_family) { - case AF_INET: { - static int yes = 1; - static int no = 0; - ssize_t sent; - - if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, - SOL_SOCKET, - SO_BROADCAST, - &yes, - sizeof(int))) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); - sent = GNUNET_NETWORK_socket_sendto (udp_sock, - &bi->bcm, - sizeof(bi->bcm), - bi->ba, - bi->salen); - if (-1 == sent) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); - if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, - SOL_SOCKET, - SO_BROADCAST, - &no, - sizeof(int))) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); - break; - } - - case AF_INET6: { - ssize_t sent; - struct sockaddr_in6 dst; - - dst.sin6_family = AF_INET6; - dst.sin6_port = htons (my_port); - dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr; - dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id; - - sent = GNUNET_NETWORK_socket_sendto (udp_sock, - &bi->bcm, - sizeof(bi->bcm), - (const struct sockaddr *) &dst, - sizeof(dst)); - if (-1 == sent) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); - break; - } - - default: - GNUNET_break (0); - break; + case AF_INET: { + static int yes = 1; + static int no = 0; + ssize_t sent; + + if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, + SOL_SOCKET, + SO_BROADCAST, + &yes, + sizeof(int))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + sent = GNUNET_NETWORK_socket_sendto (udp_sock, + &bi->bcm, + sizeof(bi->bcm), + bi->ba, + bi->salen); + if (-1 == sent) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); + if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, + SOL_SOCKET, + SO_BROADCAST, + &no, + sizeof(int))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + break; + } + + case AF_INET6: { + ssize_t sent; + struct sockaddr_in6 dst; + + dst.sin6_family = AF_INET6; + dst.sin6_port = htons (my_port); + dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr; + dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id; + + sent = GNUNET_NETWORK_socket_sendto (udp_sock, + &bi->bcm, + sizeof(bi->bcm), + (const struct sockaddr *) &dst, + sizeof(dst)); + if (-1 == sent) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); + break; + } + + default: + GNUNET_break (0); + break; } } @@ -2683,7 +2763,7 @@ iface_proc (void *cls, (const struct sockaddr_in6 *) broadcast_addr; GNUNET_assert ( - 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr)); + 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr)); /* http://tools.ietf.org/html/rfc2553#section-5.2: * @@ -2820,17 +2900,17 @@ run (void *cls, GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len)); switch (in->sa_family) { - case AF_INET: - my_port = ntohs (((struct sockaddr_in *) in)->sin_port); - break; + case AF_INET: + my_port = ntohs (((struct sockaddr_in *) in)->sin_port); + break; - case AF_INET6: - my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port); - break; + case AF_INET6: + my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port); + break; - default: - GNUNET_break (0); - my_port = 0; + default: + GNUNET_break (0); + my_port = 0; } stats = GNUNET_STATISTICS_create ("C-UDP", cfg); senders = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); @@ -2845,9 +2925,9 @@ run (void *cls, if (NULL == my_private_key) { GNUNET_log ( - GNUNET_ERROR_TYPE_ERROR, - _ ( - "Transport service is lacking key configuration settings. Exiting.\n")); + GNUNET_ERROR_TYPE_ERROR, + _ ( + "Transport service is lacking key configuration settings. Exiting.\n")); GNUNET_SCHEDULER_shutdown (); return; } @@ -2923,8 +3003,8 @@ main (int argc, char *const *argv) options, &run, NULL)) - ? 0 - : 1; + ? 0 + : 1; GNUNET_free_nz ((void *) argv); return ret; } diff --git a/src/transport/test_communicator_basic.c b/src/transport/test_communicator_basic.c index e3573ac2c..2d550dc16 100644 --- a/src/transport/test_communicator_basic.c +++ b/src/transport/test_communicator_basic.c @@ -82,6 +82,9 @@ static struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *my_tc; static unsigned int iterations_left = TOTAL_ITERATIONS; +#define DELAY \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1000) + #define SHORT_BURST_WINDOW \ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2) @@ -97,13 +100,21 @@ enum TestPhase }; -static size_t num_sent = 0; +static size_t num_sent_short = 0; + +static size_t num_sent_long = 0; + +static size_t num_sent_size = 0; static uint32_t ack = 0; static enum TestPhase phase; -static size_t num_received = 0; +static size_t num_received_short = 0; + +static size_t num_received_long = 0; + +static size_t num_received_size = 0; static uint64_t avg_latency = 0; @@ -230,6 +241,10 @@ make_payload (size_t payload_size) static void latency_timeout (void *cls) { + + size_t num_sent = 0; + size_t num_received = 0; + to_task = NULL; if (GNUNET_TIME_absolute_get_remaining (timeout).rel_value_us > 0) { @@ -239,6 +254,21 @@ latency_timeout (void *cls) return; } + switch (phase) + { + case TP_BURST_SHORT: + num_sent = num_sent_short; + num_received = num_received_short; + break; + case TP_BURST_LONG: + num_sent = num_sent_long; + num_received = num_received_long; + break; + case TP_SIZE_CHECK: + num_sent = num_sent_size; + num_received = num_received_size; + break; + } LOG (GNUNET_ERROR_TYPE_ERROR, "Latency too high. Test failed. (Phase: %d. Sent: %lu, Received: %lu)\n", phase, num_sent, num_received); @@ -246,6 +276,8 @@ latency_timeout (void *cls) GNUNET_SCHEDULER_shutdown (); } +/*static void + size_test (void *cls);*/ static void size_test (void *cls) @@ -253,6 +285,9 @@ size_test (void *cls) char *payload; size_t max_size = 64000; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "size_test_cb %u\n", + num_sent_size); GNUNET_assert (TP_SIZE_CHECK == phase); if (LONG_MESSAGE_SIZE != long_message_size) max_size = long_message_size; @@ -260,7 +295,7 @@ size_test (void *cls) return; /* Leave some room for our protocol, so not 2^16 exactly */ ack += 10; payload = make_payload (ack); - num_sent++; + num_sent_size++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, (ack < max_size) ? &size_test @@ -272,17 +307,34 @@ size_test (void *cls) timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); } +/*static void +size_test (void *cls) +{ + GNUNET_SCHEDULER_add_delayed (DELAY, + &size_test_cb, + NULL); + }*/ + +static void +long_test (void *cls); static void -long_test (void *cls) +long_test_cb (void *cls) { char *payload; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "long_test_cb %u/%u\n", + num_sent_long, + num_received_long); payload = make_payload (long_message_size); - num_sent++; + num_sent_long++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, - (BURST_PACKETS == - num_sent) + ((BURST_PACKETS + * 0.91 == + num_received_long) || + (BURST_PACKETS == + num_sent_long)) ? NULL : &long_test, NULL, @@ -292,17 +344,37 @@ long_test (void *cls) timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); } +static void +long_test (void *cls) +{ + /*LOG (GNUNET_ERROR_TYPE_DEBUG, + "long_test %u\n", + num_sent_long);*/ + GNUNET_SCHEDULER_add_delayed (DELAY, + &long_test_cb, + NULL); +} static void -short_test (void *cls) +short_test (void *cls); + +static void +short_test_cb (void *cls) { char *payload; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "short_test_cb %u/%u\n", + num_sent_short, + num_received_short); payload = make_payload (SHORT_MESSAGE_SIZE); - num_sent++; + num_sent_short++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, - (BURST_PACKETS == - num_sent) + ((BURST_PACKETS + * 0.91 == + num_received_short) || + (BURST_PACKETS == + num_sent_short)) ? NULL : &short_test, NULL, @@ -312,6 +384,14 @@ short_test (void *cls) timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); } +static void +short_test (void *cls) +{ + GNUNET_SCHEDULER_add_delayed (DELAY, + &short_test_cb, + NULL); +} + static int test_prepared = GNUNET_NO; @@ -388,10 +468,23 @@ update_avg_latency (const char*payload) struct GNUNET_TIME_AbsoluteNBO *ts_n; struct GNUNET_TIME_Absolute ts; struct GNUNET_TIME_Relative latency; + size_t num_received = 0; ts_n = (struct GNUNET_TIME_AbsoluteNBO *) payload; ts = GNUNET_TIME_absolute_ntoh (*ts_n); latency = GNUNET_TIME_absolute_get_duration (ts); + switch (phase) + { + case TP_BURST_SHORT: + num_received = num_received_short; + break; + case TP_BURST_LONG: + num_received = num_received_long; + break; + case TP_SIZE_CHECK: + num_received = num_received_size; + break; + } if (1 >= num_received) avg_latency = latency.rel_value_us; else @@ -400,7 +493,6 @@ update_avg_latency (const char*payload) } - /** * @brief Handle an incoming message * @@ -412,7 +504,8 @@ update_avg_latency (const char*payload) */ static void incoming_message_cb (void *cls, - struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle + struct + GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h, const char*payload, size_t payload_len) @@ -433,30 +526,31 @@ incoming_message_cb (void *cls, case TP_BURST_SHORT: { GNUNET_assert (SHORT_MESSAGE_SIZE == payload_len); - num_received++; + num_received_short++; duration = GNUNET_TIME_absolute_get_duration (start_short); update_avg_latency (payload); - if (num_received == BURST_PACKETS) + if (num_received_short == BURST_PACKETS * 0.91) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Short size packet test done.\n"); char *goodput = GNUNET_STRINGS_byte_size_fancy ((SHORT_MESSAGE_SIZE - * num_received * 1000 + * num_received_short + * 1000 * 1000) / duration.rel_value_us); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets in %llu us (%s/s) -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_short, + (unsigned long) num_sent_short, (unsigned long long) duration.rel_value_us, goodput, (unsigned long long) avg_latency); GNUNET_free (goodput); start_long = GNUNET_TIME_absolute_get (); phase = TP_BURST_LONG; - num_sent = 0; + // num_sent_short = 0; avg_latency = 0; - num_received = 0; + // num_received = 0; long_test (NULL); } break; @@ -467,32 +561,34 @@ incoming_message_cb (void *cls, { LOG (GNUNET_ERROR_TYPE_WARNING, "Ignoring packet with wrong length\n"); - return; // Ignore + return; // Ignore } - num_received++; + num_received_long++; duration = GNUNET_TIME_absolute_get_duration (start_long); update_avg_latency (payload); - if (num_received == BURST_PACKETS) + if (num_received_long == BURST_PACKETS * 0.91) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Long size packet test done.\n"); char *goodput = GNUNET_STRINGS_byte_size_fancy ((long_message_size - * num_received * 1000 + * num_received_long + * 1000 * 1000) - / duration.rel_value_us); + / duration. + rel_value_us); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets in %llu us (%s/s) -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_long, + (unsigned long) num_sent_long, (unsigned long long) duration.rel_value_us, goodput, (unsigned long long) avg_latency); GNUNET_free (goodput); ack = 0; phase = TP_SIZE_CHECK; - num_received = 0; - num_sent = 0; + // num_received = 0; + // num_sent_long = 0; avg_latency = 0; size_test (NULL); } @@ -505,25 +601,29 @@ incoming_message_cb (void *cls, GNUNET_assert (TP_SIZE_CHECK == phase); if (LONG_MESSAGE_SIZE != long_message_size) max_size = long_message_size; - num_received++; + num_received_size++; update_avg_latency (payload); - if (num_received >= (max_size) / 10) + if (num_received_size >= (max_size) / 10) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Size packet test done.\n"); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_size, + (unsigned long) num_sent_size, (unsigned long long) avg_latency); - num_received = 0; - num_sent = 0; + num_received_size = 0; + num_sent_size = 0; avg_latency = 0; iterations_left--; if (0 != iterations_left) { start_short = GNUNET_TIME_absolute_get (); phase = TP_BURST_SHORT; + num_sent_short = 0; + num_sent_long = 0; + num_received_short = 0; + num_received_long = 0; short_test (NULL); break; } @@ -561,8 +661,8 @@ static void run (void *cls) { ret = 0; - num_received = 0; - num_sent = 0; + // num_received = 0; + // num_sent = 0; for (unsigned int i = 0; i < NUM_PEERS; i++) { tc_hs[i] = GNUNET_TRANSPORT_TESTING_transport_communicator_service_start ( -- cgit v1.2.3