aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-04-23 11:04:53 +0000
committerChristian Grothoff <christian@grothoff.org>2014-04-23 11:04:53 +0000
commita19683a4b76e10843c4e75db928bac5750c6430a (patch)
tree7aeff0c4d49b5f3750c569216e77912016fd5a81 /src
parent21bac846638fbbbe2b03672295d4f14fc3ceb839 (diff)
fix #3348: send typemap confirmation messages, perform faster typemap retransmissions for unconfirmed typemaps, restart retransmissions on reconnect
Diffstat (limited to 'src')
-rw-r--r--src/core/gnunet-service-core_kx.c17
-rw-r--r--src/core/gnunet-service-core_sessions.c232
-rw-r--r--src/core/gnunet-service-core_sessions.h28
-rw-r--r--src/core/gnunet-service-core_typemap.c67
-rw-r--r--src/core/gnunet-service-core_typemap.h21
-rw-r--r--src/include/gnunet_protocols.h7
6 files changed, 326 insertions, 46 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index 79155a660b..8f13dd111b 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -821,13 +821,15 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
(GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status) ) &&
(end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) )
{
- GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys ignored"),
+ GNUNET_STATISTICS_update (GSC_stats,
+ gettext_noop ("# old ephemeral keys ignored"),
1, GNUNET_NO);
return;
}
start_t = GNUNET_TIME_absolute_ntoh (m->creation_time);
- GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# ephemeral keys received"),
+ GNUNET_STATISTICS_update (GSC_stats,
+ gettext_noop ("# ephemeral keys received"),
1, GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -884,11 +886,17 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
break;
case GNUNET_CORE_KX_STATE_KEY_SENT:
/* fine, need to send our key after updating our status, see below */
+ GSC_SESSIONS_reinit (&kx->peer);
break;
case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
+ /* other peer already got our key, but typemap did go down */
+ GSC_SESSIONS_reinit (&kx->peer);
+ break;
case GNUNET_CORE_KX_STATE_UP:
+ /* other peer already got our key, typemap NOT down */
+ break;
case GNUNET_CORE_KX_STATE_REKEY_SENT:
- /* other peer already got our key */
+ /* other peer already got our key, typemap NOT down */
break;
default:
GNUNET_break (0);
@@ -1509,6 +1517,9 @@ deliver_message (void *cls,
case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
GSC_SESSIONS_set_typemap (dmc->peer, m);
return GNUNET_OK;
+ case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
+ GSC_SESSIONS_confirm_typemap (dmc->peer, m);
+ return GNUNET_OK;
default:
GSC_CLIENTS_deliver_message (dmc->peer, m,
ntohs (m->size),
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c
index eb0013790a..09bb3d6c44 100644
--- a/src/core/gnunet-service-core_sessions.c
+++ b/src/core/gnunet-service-core_sessions.c
@@ -137,6 +137,12 @@ struct Session
GNUNET_SCHEDULER_TaskIdentifier typemap_task;
/**
+ * Retransmission delay we currently use for the typemap
+ * transmissions (if not confirmed).
+ */
+ struct GNUNET_TIME_Relative typemap_delay;
+
+ /**
* Is the neighbour queue empty and thus ready for us
* to transmit an encrypted message?
*/
@@ -151,6 +157,34 @@ struct Session
};
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message sent to confirm that a typemap was received.
+ */
+struct TypeMapConfirmationMessage
+{
+
+ /**
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Reserved, always zero.
+ */
+ uint32_t reserved GNUNET_PACKED;
+
+ /**
+ * Hash of the (decompressed) type map that was received.
+ */
+ struct GNUNET_HashCode tm_hash;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
/**
* Map of peer identities to `struct Session`.
*/
@@ -203,10 +237,16 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
}
while (NULL != (sme = session->sme_head))
{
- GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
+ GNUNET_CONTAINER_DLL_remove (session->sme_head,
+ session->sme_tail,
+ sme);
GNUNET_free (sme);
}
- GNUNET_SCHEDULER_cancel (session->typemap_task);
+ if (GNUNET_SCHEDULER_NO_TASK != session->typemap_task)
+ {
+ GNUNET_SCHEDULER_cancel (session->typemap_task);
+ session->typemap_task = GNUNET_SCHEDULER_NO_TASK;
+ }
GSC_CLIENTS_notify_clients_about_neighbour (&session->peer,
session->tmap, NULL);
GNUNET_assert (GNUNET_YES ==
@@ -224,7 +264,7 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
/**
* Transmit our current typemap message to the other peer.
- * (Done periodically in case an update got lost).
+ * (Done periodically until the typemap is confirmed).
*
* @param cls the `struct Session *`
* @param tc unused
@@ -237,20 +277,14 @@ transmit_typemap_task (void *cls,
struct GNUNET_MessageHeader *hdr;
struct GNUNET_TIME_Relative delay;
- if (0 == session->first_typemap)
- {
- delay = TYPEMAP_FREQUENCY_FIRST;
- session->first_typemap = 1;
- }
- else
- {
- delay = TYPEMAP_FREQUENCY;
- }
+ session->typemap_delay = GNUNET_TIME_STD_BACKOFF (session->typemap_delay);
+ delay = session->typemap_delay;
/* randomize a bit to avoid spont. sync */
delay.rel_value_us +=
GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000 * 1000);
session->typemap_task =
- GNUNET_SCHEDULER_add_delayed (delay, &transmit_typemap_task, session);
+ GNUNET_SCHEDULER_add_delayed (delay,
+ &transmit_typemap_task, session);
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop ("# type map refreshes sent"), 1,
GNUNET_NO);
@@ -261,6 +295,24 @@ transmit_typemap_task (void *cls,
/**
+ * Restart the typemap task for the given session.
+ *
+ * @param session session to restart typemap transmission for
+ */
+static void
+start_typemap_task (struct Session *session)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != session->typemap_task)
+ GNUNET_SCHEDULER_cancel (session->typemap_task);
+ session->typemap_delay = GNUNET_TIME_UNIT_SECONDS;
+ session->typemap_task =
+ GNUNET_SCHEDULER_add_delayed (session->typemap_delay,
+ &transmit_typemap_task,
+ session);
+}
+
+
+/**
* Create a session, a key exchange was just completed.
*
* @param peer peer that is now connected
@@ -279,10 +331,9 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
session->tmap = GSC_TYPEMAP_create ();
session->peer = *peer;
session->kxinfo = kx;
- session->typemap_task =
- GNUNET_SCHEDULER_add_now (&transmit_typemap_task, session);
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multipeermap_put (sessions, peer,
+ GNUNET_CONTAINER_multipeermap_put (sessions,
+ &session->peer,
session,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"),
@@ -290,6 +341,79 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
GNUNET_NO);
GSC_CLIENTS_notify_clients_about_neighbour (peer,
NULL, session->tmap);
+ start_typemap_task (session);
+}
+
+
+/**
+ * The other peer has indicated that he 'lost' the session
+ * (KX down), reinitialize the session on our end, in particular
+ * this means to restart the typemap transmission.
+ *
+ * @param peer peer that is now connected
+ */
+void
+GSC_SESSIONS_reinit (const struct GNUNET_PeerIdentity *peer)
+{
+ struct Session *session;
+
+ session = find_session (peer);
+ if (NULL == session)
+ {
+ /* KX/session is new for both sides; thus no need to restart what
+ has not yet begun */
+ return;
+ }
+ start_typemap_task (session);
+}
+
+
+/**
+ * The other peer has confirmed receiving our type map,
+ * check if it is current and if so, stop retransmitting it.
+ *
+ * @param peer peer that confirmed the type map
+ * @param msg confirmation message we received
+ */
+void
+GSC_SESSIONS_confirm_typemap (const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *msg)
+{
+ const struct TypeMapConfirmationMessage *cmsg;
+ struct Session *session;
+
+ session = find_session (peer);
+ if (NULL == session)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ if (ntohs (msg->size) != sizeof (struct TypeMapConfirmationMessage))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ cmsg = (const struct TypeMapConfirmationMessage *) msg;
+ if (GNUNET_YES !=
+ GSC_TYPEMAP_check_hash (&cmsg->tm_hash))
+ {
+ /* our typemap has changed in the meantime, do not
+ accept confirmation */
+ GNUNET_STATISTICS_update (GSC_stats,
+ gettext_noop
+ ("# outdated typemap confirmations received"),
+ 1, GNUNET_NO);
+ return;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != session->typemap_task)
+ {
+ GNUNET_SCHEDULER_cancel (session->typemap_task);
+ session->typemap_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_STATISTICS_update (GSC_stats,
+ gettext_noop
+ ("# valid typemap confirmations received"),
+ 1, GNUNET_NO);
}
@@ -325,7 +449,8 @@ void
GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client)
{
/* notify new client about existing sessions */
- GNUNET_CONTAINER_multipeermap_iterate (sessions, &notify_client_about_session,
+ GNUNET_CONTAINER_multipeermap_iterate (sessions,
+ &notify_client_about_session,
client);
}
@@ -592,11 +717,14 @@ try_transmission (struct Session *session)
size_t used;
used = 0;
- while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
+ while ( (NULL != (pos = session->sme_head)) &&
+ (used + pos->size <= msize) )
{
memcpy (&pbuf[used], &pos[1], pos->size);
used += pos->size;
- GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
+ GNUNET_CONTAINER_DLL_remove (session->sme_head,
+ session->sme_tail,
+ pos);
GNUNET_free (pos);
}
/* compute average payload size */
@@ -619,7 +747,8 @@ try_transmission (struct Session *session)
/**
- * Send a message to the neighbour now.
+ * Send an updated typemap message to the neighbour now,
+ * and restart typemap transmissions.
*
* @param cls the message
* @param key neighbour's identity
@@ -627,38 +756,42 @@ try_transmission (struct Session *session)
* @return always #GNUNET_OK
*/
static int
-do_send_message (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
+do_restart_typemap_message (void *cls,
+ const struct GNUNET_PeerIdentity *key,
+ void *value)
{
const struct GNUNET_MessageHeader *hdr = cls;
struct Session *session = value;
- struct SessionMessageEntry *m;
+ struct SessionMessageEntry *sme;
uint16_t size;
size = ntohs (hdr->size);
- m = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size);
- memcpy (&m[1], hdr, size);
- m->size = size;
- m->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
- GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, session->sme_tail, m);
+ sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size);
+ memcpy (&sme[1], hdr, size);
+ sme->size = size;
+ sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
+ GNUNET_CONTAINER_DLL_insert (session->sme_head,
+ session->sme_tail,
+ sme);
try_transmission (session);
+ start_typemap_task (session);
return GNUNET_OK;
}
/**
- * Broadcast a message to all neighbours.
+ * Broadcast an updated typemap message to all neighbours.
+ * Restarts the retransmissions until the typemaps are confirmed.
*
* @param msg message to transmit
*/
void
-GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg)
+GSC_SESSIONS_broadcast_typemap (const struct GNUNET_MessageHeader *msg)
{
if (NULL == sessions)
return;
GNUNET_CONTAINER_multipeermap_iterate (sessions,
- &do_send_message,
+ &do_restart_typemap_message,
(void *) msg);
}
@@ -732,7 +865,7 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car,
/**
- * We've received a typemap message from a peer, update ours.
+ * We have received a typemap message from a peer, update ours.
* Notifies clients about the session.
*
* @param peer peer this is about
@@ -744,6 +877,8 @@ GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
{
struct Session *session;
struct GSC_TypeMap *nmap;
+ struct SessionMessageEntry *sme;
+ struct TypeMapConfirmationMessage *tmc;
nmap = GSC_TYPEMAP_get_from_message (msg);
if (NULL == nmap)
@@ -754,8 +889,24 @@ GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
GNUNET_break (0);
return;
}
+ sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) +
+ sizeof (struct TypeMapConfirmationMessage));
+ sme->deadline = GNUNET_TIME_absolute_get ();
+ sme->size = sizeof (struct TypeMapConfirmationMessage);
+ sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
+ tmc = (struct TypeMapConfirmationMessage *) &sme[1];
+ tmc->header.size = htons (sizeof (struct TypeMapConfirmationMessage));
+ tmc->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP);
+ tmc->reserved = htonl (0);
+ GSC_TYPEMAP_hash (nmap,
+ &tmc->tm_hash);
+ GNUNET_CONTAINER_DLL_insert (session->sme_head,
+ session->sme_tail,
+ sme);
+ try_transmission (session);
GSC_CLIENTS_notify_clients_about_neighbour (peer,
- session->tmap, nmap);
+ session->tmap,
+ nmap);
GSC_TYPEMAP_destroy (session->tmap);
session->tmap = nmap;
}
@@ -776,7 +927,9 @@ GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
struct Session *session;
struct GSC_TypeMap *nmap;
- if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
+ if (0 == memcmp (peer,
+ &GSC_my_identity,
+ sizeof (struct GNUNET_PeerIdentity)))
return;
session = find_session (peer);
GNUNET_assert (NULL != session);
@@ -796,12 +949,14 @@ GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
void
GSC_SESSIONS_init ()
{
- sessions = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
+ sessions = GNUNET_CONTAINER_multipeermap_create (128,
+ GNUNET_YES);
}
/**
- * Helper function for GSC_SESSIONS_handle_client_iterate_peers.
+ * Helper function for #GSC_SESSIONS_done() to free all
+ * active sessions.
*
* @param cls NULL
* @param key identity of the connected peer
@@ -828,7 +983,8 @@ GSC_SESSIONS_done ()
{
if (NULL != sessions)
{
- GNUNET_CONTAINER_multipeermap_iterate (sessions, &free_session_helper, NULL);
+ GNUNET_CONTAINER_multipeermap_iterate (sessions,
+ &free_session_helper, NULL);
GNUNET_CONTAINER_multipeermap_destroy (sessions);
sessions = NULL;
}
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h
index 81581e84df..793d7af8c3 100644
--- a/src/core/gnunet-service-core_sessions.h
+++ b/src/core/gnunet-service-core_sessions.h
@@ -42,6 +42,29 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
/**
+ * The other peer has indicated that he 'lost' the session
+ * (KX down), reinitialize the session on our end, in particular
+ * this means to restart the typemap transmission.
+ *
+ * @param peer peer that is now connected
+ */
+void
+GSC_SESSIONS_reinit (const struct GNUNET_PeerIdentity *peer);
+
+
+/**
+ * The other peer has confirmed receiving our type map,
+ * check if it is current and if so, stop retransmitting it.
+ *
+ * @param peer peer that confirmed the type map
+ * @param msg confirmation message we received
+ */
+void
+GSC_SESSIONS_confirm_typemap (const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *msg);
+
+
+/**
* End the session with the given peer (we are no longer
* connected).
*
@@ -102,12 +125,13 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car,
/**
- * Broadcast a message to all neighbours.
+ * Broadcast an updated typemap message to all neighbours.
+ * Restarts the retransmissions until the typemaps are confirmed.
*
* @param msg message to transmit
*/
void
-GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg);
+GSC_SESSIONS_broadcast_typemap (const struct GNUNET_MessageHeader *msg);
/**
diff --git a/src/core/gnunet-service-core_typemap.c b/src/core/gnunet-service-core_typemap.c
index 8d9fcbec76..13f5309fbd 100644
--- a/src/core/gnunet-service-core_typemap.c
+++ b/src/core/gnunet-service-core_typemap.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
+ (C) 2011-2014 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -51,6 +51,63 @@ static struct GSC_TypeMap my_type_map;
*/
static uint8_t map_counters[UINT16_MAX + 1];
+/**
+ * Current hash of our (uncompressed) type map.
+ * Lazily computed when needed.
+ */
+static struct GNUNET_HashCode my_tm_hash;
+
+/**
+ * Is #my_tm_hash() current with respect to our type map?
+ */
+static int hash_current;
+
+
+/**
+ * Our type map changed, recompute its hash.
+ */
+static void
+rehash_typemap ()
+{
+ hash_current = GNUNET_NO;
+}
+
+
+/**
+ * Hash the contents of a type map.
+ *
+ * @param tm map to hash
+ * @param hc where to store the hash code
+ */
+void
+GSC_TYPEMAP_hash (const struct GSC_TypeMap *tm,
+ struct GNUNET_HashCode *hc)
+{
+ GNUNET_CRYPTO_hash (tm,
+ sizeof (struct GSC_TypeMap),
+ hc);
+}
+
+
+/**
+ * Check if the given hash matches our current type map.
+ *
+ * @param hc hash code to check if it matches our type map
+ * @return #GNUNET_YES if the hash matches, #GNUNET_NO if not
+ */
+int
+GSC_TYPEMAP_check_hash (const struct GNUNET_HashCode *hc)
+{
+ if (GNUNET_NO == hash_current)
+ {
+ GSC_TYPEMAP_hash (&my_type_map,
+ &my_tm_hash);
+ hash_current = GNUNET_YES;
+ }
+ return (0 == memcmp (hc, &my_tm_hash, sizeof (struct GNUNET_HashCode)))
+ ? GNUNET_YES : GNUNET_NO;
+}
+
/**
* Compute a type map message for this peer.
@@ -152,7 +209,7 @@ broadcast_my_type_map ()
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop ("# updates to my type map"), 1,
GNUNET_NO);
- GSC_SESSIONS_broadcast (hdr);
+ GSC_SESSIONS_broadcast_typemap (hdr);
GNUNET_free (hdr);
}
@@ -180,7 +237,10 @@ GSC_TYPEMAP_add (const uint16_t *types,
}
}
if (GNUNET_YES == changed)
+ {
+ rehash_typemap ();
broadcast_my_type_map ();
+ }
}
@@ -207,7 +267,10 @@ GSC_TYPEMAP_remove (const uint16_t *types,
}
}
if (GNUNET_YES == changed)
+ {
+ rehash_typemap ();
broadcast_my_type_map ();
+ }
}
diff --git a/src/core/gnunet-service-core_typemap.h b/src/core/gnunet-service-core_typemap.h
index 7572d39db9..1cf6972e9d 100644
--- a/src/core/gnunet-service-core_typemap.h
+++ b/src/core/gnunet-service-core_typemap.h
@@ -67,6 +67,27 @@ GSC_TYPEMAP_compute_type_map_message (void);
/**
+ * Check if the given hash matches our current type map.
+ *
+ * @param hc hash code to check if it matches our type map
+ * @return #GNUNET_YES if the hash matches, #GNUNET_NO if not
+ */
+int
+GSC_TYPEMAP_check_hash (const struct GNUNET_HashCode *hc);
+
+
+/**
+ * Hash the contents of a type map.
+ *
+ * @param tm map to hash
+ * @param hc where to store the hash code
+ */
+void
+GSC_TYPEMAP_hash (const struct GSC_TypeMap *tm,
+ struct GNUNET_HashCode *hc);
+
+
+/**
* Extract a type map from a
* #GNUNET_MESSAGE_TYPE_CORE_COMRESSED_TYPE_MAP or
* #GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP message.
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 39ce583770..9fed293041 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -378,6 +378,11 @@ extern "C"
*/
#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY 88
+/**
+ * Other peer confirms having received the type map
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP 89
+
/*******************************************************************************
* DATASTORE message types
@@ -636,7 +641,7 @@ extern "C"
#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT 162
/**
- * Trail Rejection Message.
+ * Trail Rejection Message.
*/
#define GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION 163
/*******************************************************************************