From 701ec37b6908b900fea2df9c746af8ca8aab284f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 17 Apr 2019 12:50:33 +0200 Subject: implement proper SEND_MSG wrapping for control messages --- src/transport/gnunet-service-tng.c | 139 ++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 57 deletions(-) diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 41aed9630..29bf3bf95 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c @@ -33,8 +33,6 @@ * transport-to-transport traffic) * * Implement next: - * - FIXMEs: missing communicator-protocol wrappers around messages - * passed in MQ transmission requests on queues (see FIXME in code) * - route_message() implementation, including using DV data structures * (but not when routing certain message types, like DV learn, * MUST pay attention to content here -- or pass extra flags?) @@ -1460,7 +1458,12 @@ enum PendingMessageType /** * Any type of acknowledgement. */ - PMT_ACKNOWLEDGEMENT = 3 + PMT_ACKNOWLEDGEMENT = 3, + + /** + * Control traffic generated by the TRANSPORT service itself. + */ + PMT_CONTROL = 4 }; @@ -5670,6 +5673,55 @@ reliability_box_message (struct PendingMessage *pm) } +/** + * Send the control message @a payload on @a queue. + * + * @param queue the queue to use for transmission + * @param pm pending message to update once transmission is done, may be NULL! + * @param payload the payload to send (encapsulated in a + * #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG). + * @param payload_size number of bytes in @a payload + */ +static void +queue_send_msg (struct Queue *queue, + struct PendingMessage *pm, + const void *payload, + size_t payload_size) +{ + struct Neighbour *n = queue->neighbour; + struct GNUNET_TRANSPORT_SendMessageTo *smt; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra (smt, + payload_size, + GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG); + smt->qid = queue->qid; + smt->mid = queue->mid_gen; + smt->receiver = n->pid; + memcpy (&smt[1], + payload, + payload_size); + { + /* Pass the env to the communicator of queue for transmission. */ + struct QueueEntry *qe; + + qe = GNUNET_new (struct QueueEntry); + qe->mid = queue->mid_gen++; + qe->queue = queue; + // qe->pm = pm; // FIXME: not so easy, reference management on 'free(s)'! + // (also, note that pm may be NULL!) + GNUNET_CONTAINER_DLL_insert (queue->queue_head, + queue->queue_tail, + qe); + GNUNET_assert (CT_COMMUNICATOR == queue->tc->type); + queue->queue_length++; + queue->tc->details.communicator.total_queue_length++; + GNUNET_MQ_send (queue->tc->mq, + env); + } +} + + /** * We believe we are ready to transmit a message on a queue. Double-checks * with the queue's "tracker_out" and then gives the message to the @@ -5686,8 +5738,6 @@ transmit_on_queue (void *cls) struct PendingMessage *pm; struct PendingMessage *s; uint32_t overhead; - struct GNUNET_TRANSPORT_SendMessageTo *smt; - struct GNUNET_MQ_Envelope *env; queue->transmit_task = NULL; if (NULL == (pm = n->pending_msg_head)) @@ -5728,33 +5778,10 @@ transmit_on_queue (void *cls) } /* Pass 's' for transission to the communicator */ - env = GNUNET_MQ_msg_extra (smt, - s->bytes_msg, - GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG); - smt->qid = queue->qid; - smt->mid = queue->mid_gen; - smt->receiver = n->pid; - memcpy (&smt[1], - &s[1], - s->bytes_msg); - { - /* Pass the env to the communicator of queue for transmission. */ - struct QueueEntry *qe; - - qe = GNUNET_new (struct QueueEntry); - qe->mid = queue->mid_gen++; - qe->queue = queue; - // qe->pm = s; // FIXME: not so easy, reference management on 'free(s)'! - GNUNET_CONTAINER_DLL_insert (queue->queue_head, - queue->queue_tail, - qe); - GNUNET_assert (CT_COMMUNICATOR == queue->tc->type); - queue->queue_length++; - queue->tc->details.communicator.total_queue_length++; - GNUNET_MQ_send (queue->tc->mq, - env); - } - + queue_send_msg (queue, + s, + &s[1], + s->bytes_msg); // FIXME: do something similar to the logic below // in defragmentation / reliability ACK handling! @@ -6217,19 +6244,18 @@ static void validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs) { - struct GNUNET_MQ_Envelope *env; - struct TransportValidationChallenge *tvc; + struct TransportValidationChallenge tvc; vs->last_challenge_use = GNUNET_TIME_absolute_get (); - env = GNUNET_MQ_msg (tvc, - GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE); - tvc->reserved = htonl (0); - tvc->challenge = vs->challenge; - tvc->sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use); - // FIXME: not so easy, need to BOX this message - // in a transmission request! (mistake also done elsewhere!) - GNUNET_MQ_send (q->tc->mq, - env); + tvc.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE); + tvc.header.size = htons (sizeof (tvc)); + tvc.reserved = htonl (0); + tvc.challenge = vs->challenge; + tvc.sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use); + queue_send_msg (q, + NULL, + &tvc, + sizeof (tvc)); } @@ -6379,8 +6405,7 @@ start_dv_learn (void *cls) { struct LearnLaunchEntry *lle; struct QueueQualityContext qqc; - struct GNUNET_MQ_Envelope *env; - struct TransportDVLearn *dvl; + struct TransportDVLearn dvl; (void) cls; dvlearn_task = NULL; @@ -6433,11 +6458,11 @@ start_dv_learn (void *cls) &lle->challenge, lle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - env = GNUNET_MQ_msg (dvl, - GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); - dvl->num_hops = htons (0); - dvl->bidirectional = htons (0); - dvl->non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); + dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); + dvl.header.size = htons (sizeof (dvl)); + dvl.num_hops = htons (0); + dvl.bidirectional = htons (0); + dvl.non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); { struct DvInitPS dvip = { .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR), @@ -6448,10 +6473,10 @@ start_dv_learn (void *cls) GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key, &dvip.purpose, - &dvl->init_sig)); + &dvl.init_sig)); } - dvl->initiator = GST_my_identity; - dvl->challenge = lle->challenge; + dvl.initiator = GST_my_identity; + dvl.challenge = lle->challenge; qqc.quality_count = 0; qqc.k = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, @@ -6465,11 +6490,11 @@ start_dv_learn (void *cls) /* Do this as close to transmission time as possible! */ lle->launch_time = GNUNET_TIME_absolute_get (); - // FIXME: not so easy, need to BOX this message - // in a transmission request! (mistake also done elsewhere!) - GNUNET_MQ_send (qqc.q->tc->mq, - env); + queue_send_msg (qqc.q, + NULL, + &dvl, + sizeof (dvl)); /* reschedule this job, randomizing the time it runs (but no actual backoff!) */ dvlearn_task -- cgit v1.2.3