aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-12-10 09:56:28 +0000
committerBart Polot <bart@net.in.tum.de>2013-12-10 09:56:28 +0000
commit19bb57915c215d8b3f2b6641ab31f6c8bcfb6de6 (patch)
treef86bb1db9f4adf994c05265044c538013152ddd8
parent3d0407a554d5d2536bd75e77c1d17b7815d2efa6 (diff)
downloadgnunet-19bb57915c215d8b3f2b6641ab31f6c8bcfb6de6.tar.gz
gnunet-19bb57915c215d8b3f2b6641ab31f6c8bcfb6de6.zip
- simplify the crazyness of sending tunnel-queued data: avoid going back to channel, no more channel parameter necessary
-rw-r--r--src/mesh/gnunet-service-mesh_channel.c9
-rw-r--r--src/mesh/gnunet-service-mesh_tunnel.c317
-rw-r--r--src/mesh/gnunet-service-mesh_tunnel.h4
3 files changed, 176 insertions, 154 deletions
diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c
index a385fdca2..f06844584 100644
--- a/src/mesh/gnunet-service-mesh_channel.c
+++ b/src/mesh/gnunet-service-mesh_channel.c
@@ -848,7 +848,7 @@ fire_and_forget (const struct GNUNET_MessageHeader *msg,
848 struct MeshChannel *ch, 848 struct MeshChannel *ch,
849 int force) 849 int force)
850{ 850{
851 GNUNET_break (NULL == GMT_send_prebuilt_message (msg, ch->t, ch, force, 851 GNUNET_break (NULL == GMT_send_prebuilt_message (msg, ch->t, force,
852 NULL, NULL)); 852 NULL, NULL));
853} 853}
854 854
@@ -937,7 +937,10 @@ channel_rel_free_all (struct MeshChannelReliability *rel)
937 GNUNET_free (copy); 937 GNUNET_free (copy);
938 } 938 }
939 if (NULL != rel->uniq && NULL != rel->uniq->q) 939 if (NULL != rel->uniq && NULL != rel->uniq->q)
940 {
940 GMT_cancel (rel->uniq->q); 941 GMT_cancel (rel->uniq->q);
942 /* ch_message_sent is called freeing uniq */
943 }
941 if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task) 944 if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
942 { 945 {
943 GNUNET_SCHEDULER_cancel (rel->retry_task); 946 GNUNET_SCHEDULER_cancel (rel->retry_task);
@@ -2252,7 +2255,7 @@ GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2252 } 2255 }
2253 LOG (GNUNET_ERROR_TYPE_DEBUG, " new q: %p\n", q); 2256 LOG (GNUNET_ERROR_TYPE_DEBUG, " new q: %p\n", q);
2254 q->copy->q = q; 2257 q->copy->q = q;
2255 q->q = GMT_send_prebuilt_message (message, ch->t, ch, 2258 q->q = GMT_send_prebuilt_message (message, ch->t,
2256 NULL != existing_copy, 2259 NULL != existing_copy,
2257 &ch_message_sent, q); 2260 &ch_message_sent, q);
2258 /* q itself is stored in copy */ 2261 /* q itself is stored in copy */
@@ -2289,7 +2292,7 @@ GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2289 GNUNET_free (q->rel->uniq); 2292 GNUNET_free (q->rel->uniq);
2290 } 2293 }
2291 } 2294 }
2292 q->q = GMT_send_prebuilt_message (message, ch->t, ch, GNUNET_YES, 2295 q->q = GMT_send_prebuilt_message (message, ch->t, GNUNET_YES,
2293 &ch_message_sent, q); 2296 &ch_message_sent, q);
2294 q->rel->uniq = q; 2297 q->rel->uniq = q;
2295 break; 2298 break;
diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c
index d2cffca12..a008d8349 100644
--- a/src/mesh/gnunet-service-mesh_tunnel.c
+++ b/src/mesh/gnunet-service-mesh_tunnel.c
@@ -162,10 +162,9 @@ struct MeshTunnelDelayed
162 */ 162 */
163 struct MeshTunnel3 *t; 163 struct MeshTunnel3 *t;
164 164
165 /** 165 struct MeshTunnel3Queue *q;
166 * Channel. 166 GMT_sent cont;
167 */ 167 void *cont_cls;
168 struct MeshChannel *ch;
169 168
170 /** 169 /**
171 * Message to send. 170 * Message to send.
@@ -607,10 +606,35 @@ tunnel_get_connection (struct MeshTunnel3 *t)
607} 606}
608 607
609 608
609/**
610 * Callback called when a queued message is sent.
611 *
612 * Calculates the average time and connection packet tracking.
613 *
614 * @param cls Closure (TunnelQueue handle).
615 * @param c Connection this message was on.
616 * @param q Connection queue handle (unused).
617 * @param type Type of message sent.
618 * @param fwd Was this a FWD going message?
619 * @param size Size of the message.
620 */
621static void
622message_sent (void *cls,
623 struct MeshConnection *c,
624 struct MeshConnectionQueue *q,
625 uint16_t type, int fwd, size_t size)
626{
627 struct MeshTunnel3Queue *qt = cls;
628
629 GNUNET_assert (NULL != qt->cont);
630 qt->cont (qt->cont_cls, GMC_get_tunnel (c), qt, type, size);
631 GNUNET_free (qt);
632}
633
610 634
611/** 635/**
612 * Delete a queued message: most probably channel was destroyed before the 636 * Delete a queued message: either was sent or the channel was destroyed
613 * tunnel's key exchange had a chance to finish. 637 * before the tunnel's key exchange had a chance to finish.
614 * 638 *
615 * @param tq Queue handle. 639 * @param tq Queue handle.
616 */ 640 */
@@ -623,6 +647,138 @@ unqueue_data (struct MeshTunnelDelayed *tq)
623 647
624 648
625/** 649/**
650 * Cache a message to be sent once tunnel is online.
651 *
652 * @param t Tunnel to hold the message.
653 * @param msg Message itself (copy will be made).
654 */
655static struct MeshTunnelDelayed *
656queue_data (struct MeshTunnel3 *t, const struct GNUNET_MessageHeader *msg,
657 GMT_sent cont, void *cont_cls)
658{
659 struct MeshTunnelDelayed *tq;
660 uint16_t size = ntohs (msg->size);
661
662 LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t));
663
664 if (GNUNET_YES == is_ready (t))
665 {
666 GNUNET_break (0);
667 return NULL;
668 }
669
670 tq = GNUNET_malloc (sizeof (struct MeshTunnelDelayed) + size);
671
672 tq->t = t;
673 tq->cont = cont;
674 tq->cont_cls = cont_cls;
675 memcpy (&tq[1], msg, size);
676 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
677 return tq;
678}
679
680
681
682/**
683 * Sends an already built message on a tunnel, encrypting it and
684 * choosing the best connection.
685 *
686 * @param message Message to send. Function modifies it.
687 * @param t Tunnel on which this message is transmitted.
688 * @param force Force the tunnel to take the message (buffer overfill).
689 * @param cont Continuation to call once message is really sent.
690 * @param cont_cls Closure for @c cont.
691 * @param existing_q In case this a transmission of previously queued data,
692 * this should be TunnelQueue given to the client.
693 * Otherwise, NULL.
694 *
695 * @return Handle to cancel message. NULL if @c cont is NULL.
696 */
697static struct MeshTunnel3Queue *
698send_prebuilt_message (const struct GNUNET_MessageHeader *message,
699 struct MeshTunnel3 *t, int force,
700 GMT_sent cont, void *cont_cls,
701 struct MeshTunnel3Queue *existing_q)
702{
703 struct MeshTunnel3Queue *q;
704 struct MeshConnection *c;
705 struct GNUNET_MESH_Encrypted *msg;
706 size_t size = ntohs (message->size);
707 size_t encrypted_size;
708 char cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
709 uint32_t iv;
710 uint16_t type;
711 int fwd;
712
713 LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t));
714
715 if (GNUNET_NO == is_ready (t))
716 {
717 GNUNET_assert (NULL == existing_q);
718 q = GNUNET_new (struct MeshTunnel3Queue);
719 q->tq = queue_data (t, message, cont, cont_cls);
720 q->tq->q = q;
721 return q;
722 }
723
724 GNUNET_assert (GNUNET_NO == GMT_is_loopback (t));
725
726 iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
727 msg = (struct GNUNET_MESH_Encrypted *) cbuf;
728 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
729 msg->iv = iv;
730 encrypted_size = t_encrypt (t, &msg[1], message, size, iv);
731 msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted)
732 + encrypted_size);
733 c = tunnel_get_connection (t);
734 if (NULL == c)
735 {
736 GNUNET_break (GNUNET_YES == t->destroy);
737 return NULL;
738 }
739 type = ntohs (message->type);
740 switch (type)
741 {
742 case GNUNET_MESSAGE_TYPE_MESH_DATA:
743 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
744 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
745 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
746 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
747 msg->cid = *GMC_get_id (c);
748 msg->ttl = htonl (default_ttl);
749 break;
750 default:
751 LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
752 GM_m2s (type));
753 GNUNET_break (0);
754 }
755
756 fwd = GMC_is_origin (c, GNUNET_YES);
757
758 if (NULL == cont)
759 {
760 (void) GMC_send_prebuilt_message (&msg->header, c, fwd, force, NULL, NULL);
761 return NULL;
762 }
763 if (NULL == existing_q)
764 {
765 q = GNUNET_new (struct MeshTunnel3Queue); /* FIXME valgrind: leak*/
766 }
767 else
768 {
769 q = existing_q;
770 q->tq = NULL;
771 }
772 q->q = GMC_send_prebuilt_message (&msg->header, c, fwd, force,
773 &message_sent, q);
774 q->cont = cont;
775 q->cont_cls = cont_cls;
776
777 return q;
778}
779
780
781/**
626 * Send all cached messages that we can, tunnel is online. 782 * Send all cached messages that we can, tunnel is online.
627 * 783 *
628 * @param t Tunnel that holds the messages. Cannot be loopback. 784 * @param t Tunnel that holds the messages. Cannot be loopback.
@@ -656,23 +812,12 @@ send_queued_data (struct MeshTunnel3 *t)
656 LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head); 812 LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head);
657 for (tq = t->tq_head; NULL != tq && room > 0; tq = next) 813 for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
658 { 814 {
659 /* GMCH_send_prebuilt_message will call GMT_cancel on the current 815 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending queued data\n");
660 * queue handler, therefore free'ing tq before calling GMT_send.
661 * Since the data to send is part of tq, we need to provide a copy,
662 * so the data is not invalidated.
663 */
664 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) &tq[1];
665 size_t m_size = ntohs (msg->size);
666 char cbuf[m_size];
667 struct GNUNET_MessageHeader *copy = (struct GNUNET_MessageHeader *) cbuf;
668
669 LOG (GNUNET_ERROR_TYPE_DEBUG, " msg on channel %s\n", GMCH_2s (tq->ch));
670 next = tq->next; 816 next = tq->next;
671 room--; 817 room--;
672 memcpy (copy, msg, m_size); 818 send_prebuilt_message ((struct GNUNET_MessageHeader *)&tq[1],
673 GMCH_send_prebuilt_message (copy, 819 tq->t, GNUNET_YES, tq->cont, tq->cont_cls, tq->q);
674 tq->ch, GMCH_is_origin (tq->ch, GNUNET_YES), 820 unqueue_data (tq);
675 NULL);
676 } 821 }
677 LOG (GNUNET_ERROR_TYPE_DEBUG, 822 LOG (GNUNET_ERROR_TYPE_DEBUG,
678 "GMT_send_queued_data end\n", 823 "GMT_send_queued_data end\n",
@@ -681,40 +826,6 @@ send_queued_data (struct MeshTunnel3 *t)
681 826
682 827
683/** 828/**
684 * Cache a message to be sent once tunnel is online.
685 *
686 * @param t Tunnel to hold the message.
687 * @param ch Channel the message is about.
688 * @param msg Message itself (copy will be made).
689 */
690static struct MeshTunnelDelayed *
691queue_data (struct MeshTunnel3 *t,
692 struct MeshChannel *ch,
693 const struct GNUNET_MessageHeader *msg)
694{
695 struct MeshTunnelDelayed *tq;
696 uint16_t size = ntohs (msg->size);
697
698 LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t));
699
700 if (GNUNET_YES == is_ready (t))
701 {
702 GNUNET_break (0);
703 return NULL;
704 }
705
706 tq = GNUNET_malloc (sizeof (struct MeshTunnelDelayed) + size);
707
708 tq->ch = ch;
709 tq->t = t;
710 memcpy (&tq[1], msg, size);
711 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
712 return tq;
713}
714
715
716
717/**
718 * Sends key exchange message on a tunnel, choosing the best connection. 829 * Sends key exchange message on a tunnel, choosing the best connection.
719 * Should not be called on loopback tunnels. 830 * Should not be called on loopback tunnels.
720 * 831 *
@@ -2152,32 +2263,6 @@ GMT_send_connection_acks (struct MeshTunnel3 *t)
2152 2263
2153 2264
2154/** 2265/**
2155 * Callback called when a queued message is sent.
2156 *
2157 * Calculates the average time and connection packet tracking.
2158 *
2159 * @param cls Closure (TunnelQueue handle).
2160 * @param c Connection this message was on.
2161 * @param q Connection queue handle (unused).
2162 * @param type Type of message sent.
2163 * @param fwd Was this a FWD going message?
2164 * @param size Size of the message.
2165 */
2166static void
2167message_sent (void *cls,
2168 struct MeshConnection *c,
2169 struct MeshConnectionQueue *q,
2170 uint16_t type, int fwd, size_t size)
2171{
2172 struct MeshTunnel3Queue *qt = cls;
2173
2174 GNUNET_assert (NULL != qt->cont);
2175 qt->cont (qt->cont_cls, GMC_get_tunnel (c), qt, type, size);
2176 GNUNET_free (qt);
2177}
2178
2179
2180/**
2181 * Cancel a previously sent message while it's in the queue. 2266 * Cancel a previously sent message while it's in the queue.
2182 * 2267 *
2183 * ONLY can be called before the continuation given to the send function 2268 * ONLY can be called before the continuation given to the send function
@@ -2211,7 +2296,6 @@ GMT_cancel (struct MeshTunnel3Queue *q)
2211 * 2296 *
2212 * @param message Message to send. Function modifies it. 2297 * @param message Message to send. Function modifies it.
2213 * @param t Tunnel on which this message is transmitted. 2298 * @param t Tunnel on which this message is transmitted.
2214 * @param ch Channel on which this message is transmitted.
2215 * @param force Force the tunnel to take the message (buffer overfill). 2299 * @param force Force the tunnel to take the message (buffer overfill).
2216 * @param cont Continuation to call once message is really sent. 2300 * @param cont Continuation to call once message is really sent.
2217 * @param cont_cls Closure for @c cont. 2301 * @param cont_cls Closure for @c cont.
@@ -2220,76 +2304,13 @@ GMT_cancel (struct MeshTunnel3Queue *q)
2220 */ 2304 */
2221struct MeshTunnel3Queue * 2305struct MeshTunnel3Queue *
2222GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message, 2306GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2223 struct MeshTunnel3 *t, struct MeshChannel *ch, 2307 struct MeshTunnel3 *t, int force,
2224 int force,
2225 GMT_sent cont, void *cont_cls) 2308 GMT_sent cont, void *cont_cls)
2226{ 2309{
2227 struct MeshTunnel3Queue *q; 2310 return send_prebuilt_message (message, t, force, cont, cont_cls, NULL);
2228 struct MeshConnection *c;
2229 struct GNUNET_MESH_Encrypted *msg;
2230 size_t size = ntohs (message->size);
2231 size_t encrypted_size;
2232 char cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
2233 uint32_t iv;
2234 uint16_t type;
2235 int fwd;
2236
2237 LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t));
2238
2239 if (GNUNET_NO == is_ready (t))
2240 {
2241 q = GNUNET_new (struct MeshTunnel3Queue);
2242 q->tq = queue_data (t, ch, message);
2243 return q;
2244 }
2245
2246 GNUNET_assert (GNUNET_NO == GMT_is_loopback (t));
2247
2248 iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
2249 msg = (struct GNUNET_MESH_Encrypted *) cbuf;
2250 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
2251 msg->iv = iv;
2252 encrypted_size = t_encrypt (t, &msg[1], message, size, iv);
2253 msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + encrypted_size);
2254 c = tunnel_get_connection (t);
2255 if (NULL == c)
2256 {
2257 GNUNET_break (GNUNET_YES == t->destroy);
2258 return NULL;
2259 }
2260 type = ntohs (message->type);
2261 switch (type)
2262 {
2263 case GNUNET_MESSAGE_TYPE_MESH_DATA:
2264 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
2265 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
2266 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
2267 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
2268 msg->cid = *GMC_get_id (c);
2269 msg->ttl = htonl (default_ttl);
2270 break;
2271 default:
2272 LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
2273 GM_m2s (type));
2274 GNUNET_break (0);
2275 }
2276
2277 fwd = GMC_is_origin (c, GNUNET_YES);
2278
2279 if (NULL == cont)
2280 {
2281 (void) GMC_send_prebuilt_message (&msg->header, c, fwd, force, NULL, NULL);
2282 return NULL;
2283 }
2284 q = GNUNET_new (struct MeshTunnel3Queue); /* FIXME valgrind: leak*/
2285 q->q = GMC_send_prebuilt_message (&msg->header, c, fwd, force,
2286 &message_sent, q);
2287 q->cont = cont;
2288 q->cont_cls = cont_cls;
2289
2290 return q;
2291} 2311}
2292 2312
2313
2293/** 2314/**
2294 * Is the tunnel directed towards the local peer? 2315 * Is the tunnel directed towards the local peer?
2295 * 2316 *
diff --git a/src/mesh/gnunet-service-mesh_tunnel.h b/src/mesh/gnunet-service-mesh_tunnel.h
index fb51cf347..26064c642 100644
--- a/src/mesh/gnunet-service-mesh_tunnel.h
+++ b/src/mesh/gnunet-service-mesh_tunnel.h
@@ -392,7 +392,6 @@ GMT_cancel (struct MeshTunnel3Queue *q);
392 * 392 *
393 * @param message Message to send. Function modifies it. 393 * @param message Message to send. Function modifies it.
394 * @param t Tunnel on which this message is transmitted. 394 * @param t Tunnel on which this message is transmitted.
395 * @param ch Channel on which this message is transmitted.
396 * @param force Force the tunnel to take the message (buffer overfill). 395 * @param force Force the tunnel to take the message (buffer overfill).
397 * @param cont Continuation to call once message is really sent. 396 * @param cont Continuation to call once message is really sent.
398 * @param cont_cls Closure for @c cont. 397 * @param cont_cls Closure for @c cont.
@@ -401,8 +400,7 @@ GMT_cancel (struct MeshTunnel3Queue *q);
401 */ 400 */
402struct MeshTunnel3Queue * 401struct MeshTunnel3Queue *
403GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message, 402GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
404 struct MeshTunnel3 *t, 403 struct MeshTunnel3 *t, int force,
405 struct MeshChannel *ch, int force,
406 GMT_sent cont, void *cont_cls); 404 GMT_sent cont, void *cont_cls);
407 405
408/** 406/**