From 2f3bf5f8f2f80ead818e514ab2f69052cc201a78 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Wed, 26 Oct 2016 04:20:48 +0000 Subject: [PATCH] - don't allocate message copies on the heap --- src/cadet/gnunet-service-cadet_connection.c | 77 +++++++++++++++------ src/cadet/gnunet-service-cadet_connection.h | 3 +- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c index 1b8bb1c3e..11f7fd9eb 100644 --- a/src/cadet/gnunet-service-cadet_connection.c +++ b/src/cadet/gnunet-service-cadet_connection.c @@ -3233,11 +3233,12 @@ GCC_is_direct (struct CadetConnection *c) /** + * Internal implementation of the send function. + * * Sends an already built message on a connection, properly registering * all used resources. * - * @param message Message to send. Function makes a copy of it. - * If message is not hop-by-hop, decrements TTL of copy. + * @param message Modificable copy of the message to send. * @param payload_type Type of payload, in case the message is encrypted. * @param payload_id ID of the payload (PID, ACK, ...). * @param c Connection on which this message is transmitted. @@ -3250,11 +3251,11 @@ GCC_is_direct (struct CadetConnection *c) * NULL on error or if @c cont is NULL. * Invalid on @c cont call. */ -struct CadetConnectionQueue * -GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, - uint16_t payload_type, uint32_t payload_id, - struct CadetConnection *c, int fwd, int force, - GCC_sent cont, void *cont_cls) +static struct CadetConnectionQueue * +send_prebuilt_message (struct GNUNET_MessageHeader *message, + uint16_t payload_type, uint32_t payload_id, + struct CadetConnection *c, int fwd, int force, + GCC_sent cont, void *cont_cls) { struct GNUNET_CADET_AX *axmsg; struct GNUNET_CADET_KX *kmsg; @@ -3264,7 +3265,6 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, struct GNUNET_CADET_ConnectionBroken *bmsg; struct CadetFlowControl *fc; struct CadetConnectionQueue *q; - struct GNUNET_MessageHeader *copy; size_t size; uint16_t type; int droppable; @@ -3278,8 +3278,6 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, } size = ntohs (message->size); - copy = GNUNET_malloc (size); - GNUNET_memcpy (copy, message, size); type = ntohs (message->type); LOG (GNUNET_ERROR_TYPE_INFO, "--> %s (%s %4u) on conn %s (%p) %s [%5u]\n", @@ -3289,7 +3287,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, switch (type) { case GNUNET_MESSAGE_TYPE_CADET_AX: - axmsg = (struct GNUNET_CADET_AX *) copy; + axmsg = (struct GNUNET_CADET_AX *) message; axmsg->cid = c->id; axmsg->pid = htonl (GCC_get_pid (c, fwd)); LOG (GNUNET_ERROR_TYPE_DEBUG, " Q_N+ %p %u\n", fc, fc->queue_n); @@ -3306,33 +3304,33 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, break; case GNUNET_MESSAGE_TYPE_CADET_KX: - kmsg = (struct GNUNET_CADET_KX *) copy; + kmsg = (struct GNUNET_CADET_KX *) message; kmsg->reserved = htonl (0); kmsg->cid = c->id; break; case GNUNET_MESSAGE_TYPE_CADET_ACK: - amsg = (struct GNUNET_CADET_ACK *) copy; + amsg = (struct GNUNET_CADET_ACK *) message; amsg->cid = c->id; LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack)); droppable = GNUNET_NO; break; case GNUNET_MESSAGE_TYPE_CADET_POLL: - pmsg = (struct GNUNET_CADET_Poll *) copy; + pmsg = (struct GNUNET_CADET_Poll *) message; pmsg->cid = c->id; LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL %u\n", ntohl (pmsg->pid)); droppable = GNUNET_NO; break; case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY: - dmsg = (struct GNUNET_CADET_ConnectionDestroy *) copy; + dmsg = (struct GNUNET_CADET_ConnectionDestroy *) message; dmsg->reserved = htonl (0); dmsg->cid = c->id; break; case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN: - bmsg = (struct GNUNET_CADET_ConnectionBroken *) copy; + bmsg = (struct GNUNET_CADET_ConnectionBroken *) message; bmsg->reserved = htonl (0); bmsg->cid = c->id; break; @@ -3344,7 +3342,6 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, default: GNUNET_break (0); - GNUNET_free (copy); return NULL; } @@ -3359,7 +3356,6 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, { fc->queue_n--; } - GNUNET_free (copy); return NULL; /* Drop this message */ } @@ -3369,14 +3365,13 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, q = GNUNET_new (struct CadetConnectionQueue); q->forced = !droppable; - q->peer_q = GCP_send (get_hop (c, fwd), copy, + q->peer_q = GCP_send (get_hop (c, fwd), message, payload_type, payload_id, c, fwd, &conn_message_sent, q); if (NULL == q->peer_q) { LOG (GNUNET_ERROR_TYPE_DEBUG, "dropping msg on %s, NULL q\n", GCC_2s (c)); - GNUNET_free (copy); GNUNET_free (q); GCC_check_connections (); return NULL; @@ -3389,6 +3384,48 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, } +/** + * Sends an already built message on a connection, properly registering + * all used resources. + * + * @param message Message to send. + * @param payload_type Type of payload, in case the message is encrypted. + * @param payload_id ID of the payload (PID, ACK, ...). + * @param c Connection on which this message is transmitted. + * @param fwd Is this a fwd message? + * @param force Force the connection to accept the message (buffer overfill). + * @param cont Continuation called once message is sent. Can be NULL. + * @param cont_cls Closure for @c cont. + * + * @return Handle to cancel the message before it's sent. + * NULL on error or if @c cont is NULL. + * Invalid on @c cont call. + */ +struct CadetConnectionQueue * +GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, + uint16_t payload_type, uint32_t payload_id, + struct CadetConnection *c, int fwd, int force, + GCC_sent cont, void *cont_cls) +{ + uint16_t size; + + /* Allocate a copy of the message on the stack, so we can modify it as needed, + * adding the Connection ID. + */ + size = ntohs (message->size); + { + struct GNUNET_MessageHeader *copy; + unsigned char cbuf[size]; + + copy = (struct GNUNET_MessageHeader *)cbuf; + GNUNET_memcpy (copy, message, size); + return send_prebuilt_message (copy, payload_type, payload_id, + c, fwd, force, + cont, cont_cls); + } +} + + /** * Cancel a previously sent message while it's in the queue. * diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h index ac2a1492f..7c41a28bf 100644 --- a/src/cadet/gnunet-service-cadet_connection.h +++ b/src/cadet/gnunet-service-cadet_connection.h @@ -491,8 +491,7 @@ GCC_cancel (struct CadetConnectionQueue *q); * Sends an already built message on a connection, properly registering * all used resources. * - * @param message Message to send. Function makes a copy of it. - * If message is not hop-by-hop, decrements TTL of copy. + * @param message Message to send. * @param payload_type Type of payload, in case the message is encrypted. * @param payload_id ID of the payload (PID, ACK, ...). * @param c Connection on which this message is transmitted. -- 2.25.1