* TODO:
* Implement next:
* - track RTT, distance, loss, etc. => requires extra data structures!
+ * - consider replacing random `struct GNUNET_ShortHashCode` message UUIDs
+ * with (incrementing) 64-bit numbers (compacting both
+ * `struct TransportReliabilityBox` and `struct
+ * TransportReliabilityAckMessage`), and using *different* UUIDs for each
+ * transmission (even of the same message!)
* - proper use/initialization of timestamps in messages exchanged
* during DV learning
+ * - persistence of monotonic time from DVInit to prevent
+ * replay attacks using DVInit messages
* - persistence of monotonic time obtained from other peers
* in PEERSTORE (by message type) -- done for backchannel, needed elsewhere?
* - change transport-core API to provide proper flow control in both
GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Unique identifier we attach to a message.
+ */
+struct MessageUUID
+{
+ /**
+ * Unique value.
+ */
+ struct GNUNET_ShortHashCode uuid;
+};
+
+
+/**
+ * Unique identifier we attach to a message.
+ */
+struct FragmentUUIDP
+{
+ /**
+ * Unique value identifying a fragment, in NBO.
+ */
+ uint32_t uuid GNUNET_PACKED;
+};
+
+
+/**
+ * Type of a nonce used for challenges.
+ */
+struct ChallengeNonce
+{
+ /**
+ * The value of the nonce. Note that this is NOT a hash.
+ */
+ struct GNUNET_ShortHashCode value;
+};
+
+
/**
* Outer layer of an encapsulated backchannel message.
*/
* messages sent over possibly unreliable channels. Should
* be a random.
*/
- struct GNUNET_ShortHashCode msg_uuid;
+ struct MessageUUID msg_uuid;
};
*/
struct GNUNET_TIME_RelativeNBO avg_ack_delay;
- /* followed by any number of `struct GNUNET_ShortHashCode`
+ /* followed by any number of `struct MessageUUID`
messages providing ACKs */
};
* fragment (same @e frag_off), it must send
* #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK immediately.
*/
- uint32_t frag_uuid GNUNET_PACKED;
+ struct FragmentUUIDP frag_uuid;
/**
- * Original message ID for of the message that all the1
+ * Original message ID for of the message that all the
* fragments belong to. Must be the same for all fragments.
*/
- struct GNUNET_ShortHashCode msg_uuid;
+ struct MessageUUID msg_uuid;
/**
* Offset of this fragment in the overall message.
/**
* Unique ID of the lowest fragment UUID being acknowledged.
*/
- uint32_t frag_uuid GNUNET_PACKED;
+ struct FragmentUUIDP frag_uuid;
/**
* Bitfield of up to 64 additional fragments following the
* Original message ID for of the message that all the
* fragments belong to.
*/
- struct GNUNET_ShortHashCode msg_uuid;
+ struct MessageUUID msg_uuid;
/**
* How long was the ACK delayed relative to the average time of
/**
* Challenge value used by the initiator to re-identify the path.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
};
/**
* Challenge value used by the initiator to re-identify the path.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
};
/**
* Challenge value used by the initiator to re-identify the path.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
/* Followed by @e num_hops `struct DVPathEntryP` values,
excluding the initiator of the DV trace; the last entry is the
/**
* Challenge to be signed by the receiving peer.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
/**
* Timestamp of the sender, to be copied into the reply
/**
* Challenge signed by the receiving peer.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
};
/**
* The challenge that was signed by the receiving peer.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
/**
* Original timestamp of the sender (was @code{sender_time}),
/**
* Challenge that uniquely identifies this activity.
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
/**
* When did we transmit the DV learn message (used to calculate RTT) and
* Original message ID for of the message that all the
* fragments belong to.
*/
- struct GNUNET_ShortHashCode msg_uuid;
+ struct MessageUUID msg_uuid;
/**
* Which neighbour is this context for?
* UUID to use for this message (used for reassembly of fragments, only
* initialized if @e msg_uuid_set is #GNUNET_YES).
*/
- struct GNUNET_ShortHashCode msg_uuid;
+ struct MessageUUID msg_uuid;
/**
* Counter incremented per generated fragment.
* (We must not rotate more often as otherwise we may discard valid answers
* due to packet losses, latency and reorderings on the network).
*/
- struct GNUNET_ShortHashCode challenge;
+ struct ChallengeNonce challenge;
/**
* Claimed address of the peer.
GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multishortmap_remove (n->reassembly_map,
- &rc->msg_uuid,
+ &rc->msg_uuid.uuid,
rc));
GNUNET_free (rc);
}
};
+/**
+ * FIXME: comment!
+ */
static void
bc_setup_key_state_from_km (const struct GNUNET_HashCode *km,
const struct GNUNET_ShortHashCode *iv,
ack = GNUNET_new (struct TransportFragmentAckMessage);
ack->header.size = htons (sizeof (struct TransportFragmentAckMessage));
ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK);
- ack->frag_uuid = htonl (rc->frag_uuid);
+ ack->frag_uuid.uuid = htonl (rc->frag_uuid);
ack->extra_acks = GNUNET_htonll (rc->extra_acks);
ack->msg_uuid = rc->msg_uuid;
ack->avg_ack_delay = GNUNET_TIME_relative_hton (rc->avg_ack_delay);
n);
}
msize = ntohs (fb->msg_size);
- rc = GNUNET_CONTAINER_multishortmap_get (n->reassembly_map, &fb->msg_uuid);
+ rc =
+ GNUNET_CONTAINER_multishortmap_get (n->reassembly_map, &fb->msg_uuid.uuid);
if (NULL == rc)
{
rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multishortmap_put (
n->reassembly_map,
- &rc->msg_uuid,
+ &rc->msg_uuid.uuid,
rc,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
target = (char *) &rc[1];
}
/* Compute cummulative ACK */
- frag_uuid = ntohl (fb->frag_uuid);
+ frag_uuid = ntohl (fb->frag_uuid.uuid);
cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag);
cdelay = GNUNET_TIME_relative_multiply (cdelay, rc->num_acks);
rc->last_frag = GNUNET_TIME_absolute_get ();
{
int match;
struct PendingMessage *nxt;
- uint32_t fs = ntohl (fa->frag_uuid);
+ uint32_t fs = ntohl (fa->frag_uuid.uuid);
uint64_t xtra = GNUNET_ntohll (fa->extra_acks);
match = GNUNET_NO;
{
const struct TransportFragmentBox *tfb =
(const struct TransportFragmentBox *) &pm[1];
- uint32_t fu = ntohl (tfb->frag_uuid);
+ uint32_t fu = ntohl (tfb->frag_uuid.uuid);
GNUNET_assert (PMT_FRAGMENT_BOX == frag->pmt);
nxt = frag->next_frag;
/* FIXME-OPTIMIZE: implement cummulative ACKs and ack_countdown,
then setting the avg_ack_delay field below: */
- ack = GNUNET_malloc (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode));
+ ack = GNUNET_malloc (sizeof (*ack) + sizeof (struct MessageUUID));
ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
- ack->header.size =
- htons (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode));
- memcpy (&ack[1], &rb->msg_uuid, sizeof (struct GNUNET_ShortHashCode));
+ ack->header.size = htons (sizeof (*ack) + sizeof (struct MessageUUID));
+ memcpy (&ack[1], &rb->msg_uuid, sizeof (struct MessageUUID));
route_message (&cmc->im.sender, &ack->header, RMO_DV_ALLOWED);
}
/* continue with inner message */
struct CommunicatorMessageContext *cmc = cls;
struct Neighbour *n;
unsigned int n_acks;
- const struct GNUNET_ShortHashCode *msg_uuids;
+ const struct MessageUUID *msg_uuids;
struct PendingMessage *nxt;
int matched;
GNUNET_SERVICE_client_drop (client);
return;
}
- n_acks = (ntohs (ra->header.size) - sizeof (*ra)) /
- sizeof (struct GNUNET_ShortHashCode);
- msg_uuids = (const struct GNUNET_ShortHashCode *) &ra[1];
+ n_acks =
+ (ntohs (ra->header.size) - sizeof (*ra)) / sizeof (struct MessageUUID);
+ msg_uuids = (const struct MessageUUID *) &ra[1];
/* FIXME-OPTIMIZE: maybe use another hash map here? */
matched = GNUNET_NO;
static int
validate_dv_initiator_signature (
const struct GNUNET_PeerIdentity *init,
- const struct GNUNET_ShortHashCode *challenge,
+ const struct ChallengeNonce *challenge,
const struct GNUNET_CRYPTO_EddsaSignature *init_sig)
{
struct DvInitPS ip = {.purpose.purpose = htonl (
/**
* Set to the challenge we are looking for.
*/
- const struct GNUNET_ShortHashCode *challenge;
+ const struct ChallengeNonce *challenge;
/**
* Set to a matching validation state, if one was found.
msg = (char *) &frag[1];
tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT);
tfb.header.size = htons (sizeof (struct TransportFragmentBox) + fragsize);
- tfb.frag_uuid = htonl (pm->frag_uuidgen++);
+ tfb.frag_uuid.uuid = htonl (pm->frag_uuidgen++);
tfb.msg_uuid = pm->msg_uuid;
tfb.frag_off = htons (ff->frag_off + xoff);
tfb.msg_size = htons (pm->bytes_msg);
lle = lle_tail;
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multishortmap_remove (dvlearn_map,
- &lle->challenge,
+ &lle->challenge.value,
lle));
GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle);
GNUNET_free (lle);
GNUNET_break (GNUNET_YES ==
GNUNET_CONTAINER_multishortmap_put (
dvlearn_map,
- &lle->challenge,
+ &lle->challenge.value,
lle,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);