commit 299ad80cfd43e08553eed6ba31d51668b3b1190c
parent 1767337a644615aa438190b37d3c4856783b43ef
Author: Jacki <jacki@thejackimonster.de>
Date: Fri, 7 Feb 2025 22:50:27 +0100
Fix behavior of ping tool and write benchmark for latency
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
4 files changed, 155 insertions(+), 138 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -34,3 +34,6 @@ libgnunetchat-*.tar.gz
# Valgrind
vgcore.*
+
+# Benchmark
+.build_benchmark/
diff --git a/benchmark/latency.sh b/benchmark/latency.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+COUNT=$1
+ITERATIONS=$2
+shift 2
+
+$(dirname $0)/setup.sh
+PING=$(dirname $0)/../.build_benchmark/tools/messenger_ping
+
+for INDEX in $(seq $COUNT); do
+ $PING -P -c $ITERATIONS $@ > /dev/null &
+ sleep 0.2
+done
+
+$PING -c $ITERATIONS $@
diff --git a/benchmark/setup.sh b/benchmark/setup.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+gnunet-arm -e 2> /dev/null
+
+rm -r ~/.cache/gnunet 2> /dev/null
+rm -r ~/.local/share/gnunet/messenger 2> /dev/null
+rm -r ~/.local/share/gnunet/identity 2> /dev/null
+rm -r ~/.local/share/gnunet/fs 2> /dev/null
+rm -r ~/.local/share/gnunet/namecache 2> /dev/null
+rm -r ~/.local/share/gnunet/namestore 2> /dev/null
+rm -r ~/.local/share/gnunet/datastore 2> /dev/null
+rm -r ~/.local/share/gnunet/rest 2> /dev/null
+rm ~/.local/share/gnunet/revocation.dat 2> /dev/null
+
+gnunet-arm -s
+sleep 0.5
+
+BUILD_DIR=$(dirname $0)/../.build_benchmark
+
+rm -r $BUILD_DIR 2> /dev/null
+meson setup $BUILD_DIR > /dev/null
+meson compile -C $BUILD_DIR > /dev/null
diff --git a/tools/gnunet_messenger_ping.c b/tools/gnunet_messenger_ping.c
@@ -33,16 +33,31 @@
#include <stdio.h>
#include <string.h>
+struct GNUNET_MESSENGER_Ping
+{
+ struct GNUNET_HashCode hash;
+
+ struct GNUNET_TIME_Absolute ping_time;
+ const struct GNUNET_MESSENGER_Contact *sender;
+
+ struct GNUNET_CONTAINER_MultiShortmap *pong_map;
+
+ size_t pong_missing;
+ size_t traffic;
+};
+
struct GNUNET_MESSENGER_PingTool
{
const struct GNUNET_CONFIGURATION_Handle *cfg;
struct GNUNET_IDENTITY_EgoLookup *lookup;
struct GNUNET_MESSENGER_Handle *handle;
+ struct GNUNET_MESSENGER_Room *room;
struct GNUNET_SCHEDULER_Task *hook;
struct GNUNET_SCHEDULER_Task *task;
struct GNUNET_CONTAINER_MultiHashMap *map;
struct GNUNET_CONTAINER_MultiHashMap *ping_map;
+ struct GNUNET_MESSENGER_Ping *last_ping;
char *ego_name;
char *room_name;
@@ -50,23 +65,11 @@ struct GNUNET_MESSENGER_PingTool
uint timeout;
int public_room;
int auto_pong;
- int require_pong;
- bool quit;
+ bool permanent;
size_t counter;
};
-struct GNUNET_MESSENGER_Ping
-{
- struct GNUNET_TIME_Absolute ping_time;
- const struct GNUNET_MESSENGER_Contact *sender;
-
- struct GNUNET_CONTAINER_MultiShortmap *pong_map;
-
- size_t pong_missing;
- size_t traffic;
-};
-
static const struct GNUNET_ShortHashCode*
hash_contact (const struct GNUNET_MESSENGER_Contact *contact)
{
@@ -80,24 +83,19 @@ hash_contact (const struct GNUNET_MESSENGER_Contact *contact)
}
static void
-idle (void *cls)
+finish_ping (struct GNUNET_MESSENGER_PingTool *tool,
+ struct GNUNET_MESSENGER_Ping *ping,
+ struct GNUNET_MESSENGER_Room *room);
+
+static void
+cleanup (void *cls)
{
struct GNUNET_MESSENGER_PingTool *tool = cls;
- if ((tool->auto_pong) && (!(tool->quit)))
- {
- tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
- GNUNET_TIME_relative_multiply(
- GNUNET_TIME_relative_get_second_(), tool->timeout),
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- idle,
- tool
- );
- return;
- }
-
tool->task = NULL;
- tool->quit = true;
+
+ if (tool->last_ping)
+ finish_ping(tool, tool->last_ping, tool->room);
if (tool->hook)
{
@@ -105,11 +103,23 @@ idle (void *cls)
tool->hook = NULL;
}
+ if (tool->room)
+ {
+ GNUNET_MESSENGER_close_room(tool->room);
+ tool->room = NULL;
+ }
+
if (tool->handle)
+ {
GNUNET_MESSENGER_disconnect(tool->handle);
+ tool->handle = NULL;
+ }
if (tool->lookup)
+ {
GNUNET_IDENTITY_ego_lookup_cancel(tool->lookup);
+ tool->lookup = NULL;
+ }
}
static void
@@ -118,7 +128,7 @@ shutdown_hook (void *cls)
struct GNUNET_MESSENGER_PingTool *tool = cls;
tool->hook = NULL;
- tool->quit = true;
+ tool->permanent = false;
if (tool->task)
{
@@ -126,7 +136,21 @@ shutdown_hook (void *cls)
tool->task = NULL;
}
- idle(cls);
+ cleanup(cls);
+}
+
+static void
+finish (void *cls)
+{
+ struct GNUNET_MESSENGER_PingTool *tool = cls;
+
+ tool->task = NULL;
+
+ if (tool->room)
+ {
+ GNUNET_MESSENGER_close_room(tool->room);
+ tool->room = NULL;
+ }
}
static enum GNUNET_GenericReturnValue
@@ -145,31 +169,6 @@ member_callback (void *cls,
return GNUNET_YES;
}
-static bool
-is_hash_following (struct GNUNET_MESSENGER_PingTool *tool,
- const struct GNUNET_HashCode *hash,
- const struct GNUNET_HashCode *prev)
-{
- if (!prev)
- return false;
-
- bool first = true;
- while (hash)
- {
- if (0 == GNUNET_CRYPTO_hash_cmp(hash, prev))
- return true;
-
- if (first)
- first = false;
- else if (0 == GNUNET_CRYPTO_hash_cmp(hash + 1, prev))
- return true;
-
- hash = GNUNET_CONTAINER_multihashmap_get(tool->map, hash);
- }
-
- return false;
-}
-
static void
send_ping (struct GNUNET_MESSENGER_PingTool *tool,
struct GNUNET_MESSENGER_Room *room)
@@ -180,9 +179,6 @@ send_ping (struct GNUNET_MESSENGER_PingTool *tool,
GNUNET_MESSENGER_send_message(room, &message, NULL);
tool->counter++;
-
- if (tool->count)
- tool->count--;
}
static void
@@ -208,28 +204,30 @@ send_pong (struct GNUNET_MESSENGER_PingTool *tool,
GNUNET_MESSENGER_send_message(room, &message, NULL);
tool->counter++;
- if ((tool->count) && (tool->count < UINT_MAX))
- tool->count--;
-
- if (!(tool->count))
- tool->quit = true;
+ if ((!(tool->permanent)) && (tool->counter >= tool->count))
+ {
+ if (tool->task)
+ GNUNET_SCHEDULER_cancel(tool->task);
- if (tool->quit)
- GNUNET_SCHEDULER_shutdown();
+ tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
+ GNUNET_TIME_relative_get_second_(),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ finish,
+ tool);
+ }
}
static void
finish_ping (struct GNUNET_MESSENGER_PingTool *tool,
struct GNUNET_MESSENGER_Ping *ping,
- struct GNUNET_MESSENGER_Room *room,
- const struct GNUNET_HashCode *hash)
+ struct GNUNET_MESSENGER_Room *room)
{
const size_t recipients = GNUNET_CONTAINER_multishortmap_size(ping->pong_map);
const size_t loss_rate = recipients? 100 * ping->pong_missing / recipients : 100;
const struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(
ping->ping_time, GNUNET_TIME_absolute_get());
- printf("--- %s ping statistics ---\n", GNUNET_h2s(hash));
+ printf("--- %s ping statistics ---\n", GNUNET_h2s(&(ping->hash)));
struct GNUNET_TIME_Relative min = GNUNET_TIME_relative_get_forever_();
struct GNUNET_TIME_Relative avg = GNUNET_TIME_relative_get_zero_();
@@ -298,16 +296,22 @@ finish_ping (struct GNUNET_MESSENGER_PingTool *tool,
((float) max.rel_value_us) / GNUNET_TIME_relative_get_millisecond_().rel_value_us,
((float) mdev.rel_value_us) / GNUNET_TIME_relative_get_millisecond_().rel_value_us);
- if (!(tool->quit))
+ if (ping == tool->last_ping)
+ tool->last_ping = NULL;
+
+ if ((tool->permanent) || (tool->counter < tool->count))
+ send_ping(tool, room);
+ else
{
- if (tool->count)
- send_ping(tool, room);
- else
- tool->quit = true;
- }
+ if (tool->task)
+ GNUNET_SCHEDULER_cancel(tool->task);
- if (tool->quit)
- GNUNET_SCHEDULER_shutdown();
+ tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
+ GNUNET_TIME_relative_get_second_(),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ finish,
+ tool);
+ }
}
static void
@@ -321,15 +325,6 @@ message_callback (void *cls,
{
struct GNUNET_MESSENGER_PingTool *tool = cls;
- if (tool->auto_pong)
- {
- if ((!(GNUNET_MESSENGER_FLAG_SENT & flags)) &&
- (GNUNET_MESSENGER_KIND_TEXT == message->header.kind))
- send_pong(tool, room, hash, GNUNET_TIME_absolute_ntoh(message->header.timestamp));
-
- goto skip_ping;
- }
-
if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains(tool->map, hash))
{
struct GNUNET_HashCode *copy = GNUNET_malloc(sizeof(struct GNUNET_HashCode) * 2);
@@ -350,13 +345,22 @@ message_callback (void *cls,
{
case GNUNET_MESSENGER_KIND_JOIN:
{
- send_ping(tool, room);
+ if (!(tool->auto_pong))
+ send_ping(tool, room);
+
+ break;
+ }
+ case GNUNET_MESSENGER_KIND_LEAVE:
+ {
+ GNUNET_SCHEDULER_shutdown();
break;
}
case GNUNET_MESSENGER_KIND_TEXT:
{
struct GNUNET_MESSENGER_Ping *ping = GNUNET_new(struct GNUNET_MESSENGER_Ping);
+ GNUNET_memcpy(&(ping->hash), hash, sizeof(ping->hash));
+
ping->ping_time = GNUNET_TIME_absolute_ntoh(message->header.timestamp);
ping->sender = sender;
@@ -370,8 +374,10 @@ message_callback (void *cls,
GNUNET_CONTAINER_multihashmap_put(tool->ping_map, hash, ping,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ tool->last_ping = ping;
+
if (0 >= ping->pong_missing)
- finish_ping (tool, ping, room, hash);
+ finish_ping (tool, ping, room);
break;
}
@@ -381,13 +387,14 @@ message_callback (void *cls,
}
else
{
+ if ((tool->auto_pong) && (GNUNET_MESSENGER_KIND_TEXT == message->header.kind))
+ send_pong(tool, room, hash, GNUNET_TIME_absolute_ntoh(message->header.timestamp));
+
struct GNUNET_CONTAINER_MultiHashMapIterator *iter =
GNUNET_CONTAINER_multihashmap_iterator_create(tool->ping_map);
- struct GNUNET_HashCode key;
const void *value;
-
- while (GNUNET_NO != GNUNET_CONTAINER_multihashmap_iterator_next(iter, &key, &value))
+ while (GNUNET_NO != GNUNET_CONTAINER_multihashmap_iterator_next(iter, NULL, &value))
{
struct GNUNET_MESSENGER_Ping *ping = (struct GNUNET_MESSENGER_Ping*) value;
@@ -396,9 +403,8 @@ message_callback (void *cls,
ping->traffic++;
- if ((tool->require_pong) &&
- ((GNUNET_MESSENGER_KIND_TAG != message->header.kind) ||
- (0 != GNUNET_CRYPTO_hash_cmp(&(message->body.tag.hash), &key))))
+ if (((GNUNET_MESSENGER_KIND_TAG != message->header.kind) ||
+ (0 != GNUNET_CRYPTO_hash_cmp(&(message->body.tag.hash), &(ping->hash)))))
continue;
if (!sender)
@@ -407,9 +413,6 @@ message_callback (void *cls,
if (GNUNET_YES != GNUNET_CONTAINER_multishortmap_contains_value(ping->pong_map, hash_contact (sender), NULL))
continue;
- if ((!(tool->require_pong)) && (!is_hash_following (tool, hash, &key)))
- continue;
-
struct GNUNET_TIME_Absolute *time = GNUNET_new(struct GNUNET_TIME_Absolute);
*time = GNUNET_TIME_absolute_ntoh(message->header.timestamp);
@@ -419,7 +422,7 @@ message_callback (void *cls,
printf("%s as response to %s from: sender=%lu time=%.3f ms\n",
GNUNET_MESSENGER_name_of_kind(message->header.kind),
- GNUNET_h2s(&key),
+ GNUNET_h2s(&(ping->hash)),
GNUNET_MESSENGER_contact_get_id(sender),
((float) difference.rel_value_us) / GNUNET_TIME_relative_get_millisecond_().rel_value_us);
}
@@ -431,35 +434,11 @@ message_callback (void *cls,
if (0 < ping->pong_missing)
continue;
- finish_ping (tool, ping, room, &key);
+ finish_ping (tool, ping, room);
}
GNUNET_CONTAINER_multihashmap_iterator_destroy(iter);
}
-
-skip_ping:
- if (!(tool->quit))
- {
- if (tool->task)
- GNUNET_SCHEDULER_cancel(tool->task);
-
- tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
- GNUNET_TIME_relative_multiply(
- GNUNET_TIME_relative_get_second_(), tool->timeout),
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- idle,
- tool
- );
- }
- else if (!(tool->task))
- tool->task = GNUNET_SCHEDULER_add_with_priority(
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- idle,
- tool
- );
-
- if (tool->quit)
- GNUNET_MESSENGER_close_room(room);
}
static void
@@ -511,21 +490,32 @@ ego_lookup (void *cls,
printf(" (%s): ",
GNUNET_h2s(&hash));
- if (UINT_MAX == tool->count)
+ if (0 == tool->count)
+ {
printf("infinite\n");
+ tool->permanent = true;
+ }
else
printf("%u times\n", tool->count);
- struct GNUNET_MESSENGER_Room *room;
- room = GNUNET_MESSENGER_enter_room(
+ tool->room = GNUNET_MESSENGER_enter_room(
tool->handle,
&peer,
&hash
);
- if (room)
+ if (tool->room)
GNUNET_MESSENGER_use_room_keys(
- room, tool->public_room? GNUNET_NO : GNUNET_YES);
+ tool->room, tool->public_room? GNUNET_NO : GNUNET_YES);
+
+ if (tool->timeout)
+ tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
+ GNUNET_TIME_relative_multiply(
+ GNUNET_TIME_relative_get_second_(), tool->timeout),
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ finish,
+ tool
+ );
}
static void
@@ -536,12 +526,6 @@ run (void *cls,
{
struct GNUNET_MESSENGER_PingTool *tool = cls;
- if (!(tool->count))
- tool->count = UINT_MAX;
-
- if (!(tool->timeout))
- tool->timeout = UINT_MAX;
-
tool->cfg = cfg;
tool->hook = GNUNET_SCHEDULER_add_shutdown(shutdown_hook, tool);
@@ -644,12 +628,6 @@ main (int argc,
"only send back pong messages after a ping",
&(tool.auto_pong)
),
- GNUNET_GETOPT_option_flag(
- 'R',
- "require-pong",
- "only react to pong messages after a ping",
- &(tool.require_pong)
- ),
GNUNET_GETOPT_OPTION_END
};