X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmesh%2Fgnunet-service-mesh_tunnel.c;h=f192bb05b5ac49cc6a30c603164bff95c882721c;hb=a107ae89650629fb1d6981bff567ebbdae3dcb8b;hp=a008d834902f3b103d6d0662cb06d2aa856f4f44;hpb=19bb57915c215d8b3f2b6641ab31f6c8bcfb6de6;p=oweals%2Fgnunet.git diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index a008d8349..f192bb05b 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c @@ -162,9 +162,10 @@ struct MeshTunnelDelayed */ struct MeshTunnel3 *t; - struct MeshTunnel3Queue *q; - GMT_sent cont; - void *cont_cls; + /** + * Tunnel queue given to the channel to cancel request. Update on send_queued. + */ + struct MeshTunnel3Queue *tq; /** * Message to send. @@ -181,12 +182,12 @@ struct MeshTunnel3Queue /** * Connection queue handle, to cancel if necessary. */ - struct MeshConnectionQueue *q; + struct MeshConnectionQueue *cq; /** * Handle in case message hasn't been given to a connection yet. */ - struct MeshTunnelDelayed *tq; + struct MeshTunnelDelayed *tqd; /** * Continuation to call once sent. @@ -334,6 +335,8 @@ estate2s (enum MeshTunnel3EState es) static int is_ready (struct MeshTunnel3 *t) { + LOG (GNUNET_ERROR_TYPE_DEBUG, " ready: cs=%s, es=%s\n", + cstate2s (t->cstate), estate2s (t->estate)); return (MESH_TUNNEL3_READY == t->cstate && MESH_TUNNEL3_KEY_OK == t->estate) || GMT_is_loopback (t); @@ -653,10 +656,9 @@ unqueue_data (struct MeshTunnelDelayed *tq) * @param msg Message itself (copy will be made). */ static struct MeshTunnelDelayed * -queue_data (struct MeshTunnel3 *t, const struct GNUNET_MessageHeader *msg, - GMT_sent cont, void *cont_cls) +queue_data (struct MeshTunnel3 *t, const struct GNUNET_MessageHeader *msg) { - struct MeshTunnelDelayed *tq; + struct MeshTunnelDelayed *tqd; uint16_t size = ntohs (msg->size); LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t)); @@ -667,14 +669,12 @@ queue_data (struct MeshTunnel3 *t, const struct GNUNET_MessageHeader *msg, return NULL; } - tq = GNUNET_malloc (sizeof (struct MeshTunnelDelayed) + size); + tqd = GNUNET_malloc (sizeof (struct MeshTunnelDelayed) + size); - tq->t = t; - tq->cont = cont; - tq->cont_cls = cont_cls; - memcpy (&tq[1], msg, size); - GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq); - return tq; + tqd->t = t; + memcpy (&tqd[1], msg, size); + GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tqd); + return tqd; } @@ -700,11 +700,10 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, GMT_sent cont, void *cont_cls, struct MeshTunnel3Queue *existing_q) { - struct MeshTunnel3Queue *q; + struct MeshTunnel3Queue *tq; struct MeshConnection *c; struct GNUNET_MESH_Encrypted *msg; size_t size = ntohs (message->size); - size_t encrypted_size; char cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size]; uint32_t iv; uint16_t type; @@ -714,11 +713,20 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, if (GNUNET_NO == is_ready (t)) { + struct MeshTunnelDelayed *tqd; + /* A non null existing_q indicates sending of queued data. + * Should only happen after tunnel becomes ready. + */ GNUNET_assert (NULL == existing_q); - q = GNUNET_new (struct MeshTunnel3Queue); - q->tq = queue_data (t, message, cont, cont_cls); - q->tq->q = q; - return q; + tqd = queue_data (t, message); + if (NULL == cont) + return NULL; + tq = GNUNET_new (struct MeshTunnel3Queue); + tq->tqd = tqd; + tqd->tq = tq; + tq->cont = cont; + tq->cont_cls = cont_cls; + return tq; } GNUNET_assert (GNUNET_NO == GMT_is_loopback (t)); @@ -727,9 +735,8 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, msg = (struct GNUNET_MESH_Encrypted *) cbuf; msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED); msg->iv = iv; - encrypted_size = t_encrypt (t, &msg[1], message, size, iv); - msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) - + encrypted_size); + GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv) == size); + msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size); c = tunnel_get_connection (t); if (NULL == c) { @@ -762,19 +769,19 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, } if (NULL == existing_q) { - q = GNUNET_new (struct MeshTunnel3Queue); /* FIXME valgrind: leak*/ + tq = GNUNET_new (struct MeshTunnel3Queue); /* FIXME valgrind: leak*/ } else { - q = existing_q; - q->tq = NULL; + tq = existing_q; + tq->tqd = NULL; } - q->q = GMC_send_prebuilt_message (&msg->header, c, fwd, force, - &message_sent, q); - q->cont = cont; - q->cont_cls = cont_cls; + tq->cq = GMC_send_prebuilt_message (&msg->header, c, fwd, force, + &message_sent, tq); + tq->cont = cont; + tq->cont_cls = cont_cls; - return q; + return tq; } @@ -786,7 +793,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, static void send_queued_data (struct MeshTunnel3 *t) { - struct MeshTunnelDelayed *tq; + struct MeshTunnelDelayed *tqd; struct MeshTunnelDelayed *next; unsigned int room; @@ -810,18 +817,19 @@ send_queued_data (struct MeshTunnel3 *t) room = GMT_get_connections_buffer (t); LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head); - for (tq = t->tq_head; NULL != tq && room > 0; tq = next) + for (tqd = t->tq_head; NULL != tqd && room > 0; tqd = next) { LOG (GNUNET_ERROR_TYPE_DEBUG, " sending queued data\n"); - next = tq->next; + next = tqd->next; room--; - send_prebuilt_message ((struct GNUNET_MessageHeader *)&tq[1], - tq->t, GNUNET_YES, tq->cont, tq->cont_cls, tq->q); - unqueue_data (tq); + send_prebuilt_message ((struct GNUNET_MessageHeader *) &tqd[1], + tqd->t, GNUNET_YES, + NULL != tqd->tq ? tqd->tq->cont : NULL, + NULL != tqd->tq ? tqd->tq->cont_cls : NULL, + tqd->tq); + unqueue_data (tqd); } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "GMT_send_queued_data end\n", - GMP_2s (t->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_send_queued_data end\n", GMP_2s (t->peer)); } @@ -856,7 +864,7 @@ send_kx (struct MeshTunnel3 *t, /* Must have a connection. */ if (NULL == t->connection_head) { - GNUNET_break (0); + GNUNET_break (MESH_TUNNEL3_SEARCHING == t->cstate); return; } @@ -866,7 +874,7 @@ send_kx (struct MeshTunnel3 *t, c = tunnel_get_connection (t); if (NULL == c) { - GNUNET_break (GNUNET_YES == t->destroy); + GNUNET_break (GNUNET_YES == t->destroy || MESH_TUNNEL3_READY != t->cstate); return; } type = ntohs (message->type); @@ -1751,14 +1759,39 @@ void GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c) { struct MeshTConnection *aux; + struct MeshTConnection *next; - for (aux = t->connection_head; aux != NULL; aux = aux->next) + LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing connection %s from tunnel %s\n", + GMC_2s (c), GMT_2s (t)); + for (aux = t->connection_head; aux != NULL; aux = next) + { + next = aux->next; if (aux->c == c) { GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux); GNUNET_free (aux); - return; } + } + + /* Start new connections if needed */ + if (NULL == t->connection_head && GNUNET_NO == t->destroy) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, " no more connections\n"); + GMP_connect (t->peer); + t->cstate = MESH_TUNNEL3_SEARCHING; + return; + } + + /* If not marked as ready, no change is needed */ + if (MESH_TUNNEL3_READY != t->cstate) + return; + + /* Check if any connection is ready to maintaing cstate */ + for (aux = t->connection_head; aux != NULL; aux = aux->next) + if (MESH_CONNECTION_READY == GMC_get_state (aux->c)) + return; + + t->cstate = MESH_TUNNEL3_WAITING; } @@ -1908,6 +1941,8 @@ GMT_destroy (struct MeshTunnel3 *t) if (NULL == t) return; + t->destroy = 2; + LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer)); GNUNET_break (GNUNET_YES == @@ -1966,7 +2001,7 @@ GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p) } if (own_pos > p->length - 1) { - GNUNET_break (0); + GNUNET_break_op (0); return NULL; } @@ -2274,14 +2309,14 @@ GMT_send_connection_acks (struct MeshTunnel3 *t) void GMT_cancel (struct MeshTunnel3Queue *q) { - if (NULL != q->q) + if (NULL != q->cq) { - GMC_cancel (q->q); + GMC_cancel (q->cq); /* message_sent() will be called and free q */ } - else if (NULL != q->tq) + else if (NULL != q->tqd) { - unqueue_data (q->tq); + unqueue_data (q->tqd); } else {