From 26ddeacf0fe663630bb3f9e86c6fb85e33279544 Mon Sep 17 00:00:00 2001
From: ulfvonbelow <striness@tilde.club>
Date: Sun, 5 May 2024 23:43:04 -0500
Subject: [PATCH] TRANSPORT: fix add_global_addresses.

Previously the bytes of the current iteration's address would simply overwrite
the start of the output buffer each time. This meant that when a peer had
multiple global addresses, some would be missing and/or mangled.
---
 .../transport/gnunet-service-transport.c      | 24 ++++++++++++-------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/service/transport/gnunet-service-transport.c b/src/service/transport/gnunet-service-transport.c
index 311f269b7..38371032e 100644
--- a/src/service/transport/gnunet-service-transport.c
+++ b/src/service/transport/gnunet-service-transport.c
@@ -5345,16 +5345,21 @@ static char *
 get_address_without_port (const char *address);
 
 
+struct AddGlobalAddressesContext
+{
+  size_t off;
+  char *tgnas;
+};
+
 static enum GNUNET_GenericReturnValue
 add_global_addresses (void *cls,
                       const struct GNUNET_PeerIdentity *pid,
                       void *value)
 {
-  char *tgnas = cls;
+  struct AddGlobalAddressesContext *ctx = cls;
   struct TransportGlobalNattedAddress *tgna = value;
   char *addr = (char *) &tgna[1];
   size_t address_len = strlen (addr);
-  unsigned int off = 0;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "sending address %s length %u\n",
@@ -5363,9 +5368,9 @@ add_global_addresses (void *cls,
   tgna = GNUNET_malloc (sizeof (struct TransportGlobalNattedAddress) + address_len);
   tgna->address_length = htonl (address_len);
   GNUNET_memcpy (&tgna[1], addr, address_len);
-  GNUNET_memcpy (&tgnas[off], tgna, sizeof (struct TransportGlobalNattedAddress) + address_len);
+  GNUNET_memcpy (&(ctx->tgnas[ctx->off]), tgna, sizeof (struct TransportGlobalNattedAddress) + address_len);
   GNUNET_free (tgna);
-  off += sizeof(struct TransportGlobalNattedAddress) + address_len;
+  ctx->off += sizeof(struct TransportGlobalNattedAddress) + address_len;
 }
 
 
@@ -5387,17 +5392,20 @@ consider_sending_fc (void *cls)
 
   if (0 < n->number_of_addresses)
   {
-    char *tgnas = GNUNET_malloc (n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses);
-    size_t addresses_size;
+    size_t addresses_size =
+      n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses;
+    char *tgnas = GNUNET_malloc (addresses_size);
+    struct AddGlobalAddressesContext ctx;
+    ctx.off = 0;
+    ctx.tgnas = tgnas;
 
-    addresses_size = n->number_of_addresses * sizeof (struct TransportGlobalNattedAddress) + n->size_of_global_addresses;
     fc = GNUNET_malloc (sizeof (struct TransportFlowControlMessage) + addresses_size);
     fc->header.size = htons (sizeof(struct TransportFlowControlMessage) + addresses_size);
     fc->size_of_addresses = htonl (n->size_of_global_addresses);
     fc->number_of_addresses = htonl (n->number_of_addresses);
     GNUNET_CONTAINER_multipeermap_iterate (n->natted_addresses,
                                            &add_global_addresses,
-                                           tgnas);
+                                           &ctx);
     GNUNET_memcpy (&fc[1], tgnas, addresses_size);
     GNUNET_free (tgnas);
   }
-- 
2.41.0

