X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmesh%2Fgnunet-service-mesh.c;h=7ebe7d199d188696f36268b002a872fa3a1b1ae1;hb=b552dea05cbfacacf1c65c6eb1f54220f4e4beb5;hp=83186a3e69f7c7b9b2b3168bc6cfc60d5660b76a;hpb=32350f0ada76a31d4d7fc90ea793cb601985838a;p=oweals%2Fgnunet.git diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 83186a3e6..7ebe7d199 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c @@ -2381,7 +2381,8 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, return; } info->peer = neighbor; - GNUNET_assert (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK != type); + if (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK == type) + type = 0; queue_add (info, type, size, @@ -3598,6 +3599,7 @@ tunnel_get_children_fwd_ack (struct MeshTunnel *t) ctx.t = t; ctx.max_child_ack = 0; ctx.nchildren = 0; + ctx.init = GNUNET_NO; tree_iterate_children (t->tree, tunnel_get_child_fwd_ack, &ctx); if (0 == ctx.nchildren) @@ -4166,14 +4168,17 @@ tunnel_destroy (struct MeshTunnel *t) r = GNUNET_SYSERR; } - GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); - if (NULL != c && - GNUNET_YES != - GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t)) + if (NULL != c) { - GNUNET_break (0); - r = GNUNET_SYSERR; + GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); + if (GNUNET_YES != + GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t)) + { + GNUNET_break (0); + r = GNUNET_SYSERR; + } } + GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); for (i = 0; i < t->nclients; i++) { @@ -4195,6 +4200,7 @@ tunnel_destroy (struct MeshTunnel *t) r = GNUNET_SYSERR; } } + if (t->nclients > 0) { if (GNUNET_YES != @@ -4205,6 +4211,7 @@ tunnel_destroy (struct MeshTunnel *t) } GNUNET_free (t->clients); } + if (NULL != t->peers) { GNUNET_CONTAINER_multihashmap_iterate (t->peers, &peer_info_delete_tunnel, @@ -4335,14 +4342,13 @@ tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer) * @param key the hash of the local tunnel id (used to access the hashmap) * @param value the value stored at the key (tunnel to destroy) * - * @return GNUNET_OK on success + * @return GNUNET_OK, keep iterating. */ static int tunnel_destroy_iterator (void *cls, const struct GNUNET_HashCode * key, void *value) { struct MeshTunnel *t = value; struct MeshClient *c = cls; - int r; send_client_tunnel_disconnect(t, c); if (c != t->owner) @@ -4354,8 +4360,10 @@ tunnel_destroy_iterator (void *cls, const struct GNUNET_HashCode * key, void *va return GNUNET_OK; } tunnel_send_destroy(t); - r = tunnel_destroy (t); - return r; + t->owner = NULL; + t->destroy = GNUNET_YES; + + return GNUNET_OK; } @@ -4444,6 +4452,7 @@ send_core_path_create (void *cls, size_t size, void *buf) if (GNUNET_YES == t->nobuffer) opt |= MESH_TUNNEL_OPT_NOBUFFER; msg->opt = htonl(opt); + msg->reserved = 0; peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1]; for (i = 0; i < p->length; i++) @@ -4565,24 +4574,32 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls) { struct MeshTransmissionDescriptor *dd; struct MeshPathInfo *path_info; + struct MeshTunnelChildInfo *cinfo; + struct GNUNET_PeerIdentity id; + unsigned int i; + unsigned int max; if (GNUNET_YES == clear_cls) { switch (queue->type) { - case GNUNET_MESSAGE_TYPE_MESH_UNICAST: - case GNUNET_MESSAGE_TYPE_MESH_MULTICAST: - case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type payload\n"); + case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " cancelling TUNNEL_DESTROY\n"); + /* fall through */ + case GNUNET_MESSAGE_TYPE_MESH_UNICAST: + case GNUNET_MESSAGE_TYPE_MESH_MULTICAST: + case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " type prebuilt (payload, tunnel destroy)\n"); dd = queue->cls; data_descriptor_decrement_rc (dd->mesh_data); break; - case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE: + case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type create path\n"); path_info = queue->cls; path_destroy (path_info->path); break; - default: + default: GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " type %s unknown!\n", @@ -4593,6 +4610,36 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls) GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head, queue->peer->queue_tail, queue); + + /* Delete from child_fc in the appropiate tunnel */ + max = queue->tunnel->fwd_queue_max; + GNUNET_PEER_resolve (queue->peer->id, &id); + cinfo = tunnel_get_neighbor_fc (queue->tunnel, &id); + for (i = 0; i < cinfo->send_buffer_n; i++) + { + unsigned int i2; + i2 = (cinfo->send_buffer_start + i) % max; + if (cinfo->send_buffer[i2] == queue) + { + /* Found corresponding entry in the send_buffer. Move all others back. */ + unsigned int j; + unsigned int j2; + unsigned int j3; + + for (j = i, j2 = 0, j3 = 0; j < cinfo->send_buffer_n - 1; j++) + { + j2 = (cinfo->send_buffer_start + j) % max; + j3 = (cinfo->send_buffer_start + j + 1) % max; + cinfo->send_buffer[j2] = cinfo->send_buffer[j3]; + } + + cinfo->send_buffer[j3] = NULL; + + cinfo->send_buffer_n--; + } + } + //queue-> + GNUNET_free (queue); } @@ -4824,13 +4871,14 @@ queue_send (void *cls, size_t size, void *buf) if (cinfo->send_buffer[cinfo->send_buffer_start] != queue) { GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "at pos %u (%p) != %p\n", cinfo->send_buffer_start, cinfo->send_buffer[cinfo->send_buffer_start], queue); } - if (cinfo->send_buffer_n > 0) { + if (cinfo->send_buffer_n > 0) + { cinfo->send_buffer[cinfo->send_buffer_start] = NULL; cinfo->send_buffer_n--; cinfo->send_buffer_start++; @@ -4966,13 +5014,15 @@ queue_add (void *cls, uint16_t type, size_t size, if (NULL != cinfo->send_buffer[i]) { GNUNET_break (cinfo->send_buffer_n == t->fwd_queue_max); // aka i == start - queue_destroy(cinfo->send_buffer[cinfo->send_buffer_start], GNUNET_YES); + queue_destroy (cinfo->send_buffer[cinfo->send_buffer_start], GNUNET_YES); cinfo->send_buffer_start++; cinfo->send_buffer_start %= t->fwd_queue_max; - cinfo->send_buffer_n--; + } + else + { + cinfo->send_buffer_n++; } cinfo->send_buffer[i] = queue; - cinfo->send_buffer_n++; if (cinfo->send_buffer_n > t->fwd_queue_max) { GNUNET_break (0); @@ -7722,13 +7772,15 @@ core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) while (NULL != q) { n = q->next; - if (q->peer == pi) - { - /* try to reroute this traffic instead */ - queue_destroy(q, GNUNET_YES); - } + /* TODO try to reroute this traffic instead */ + queue_destroy(q, GNUNET_YES); q = n; } + if (NULL != pi->core_transmit) + { + GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit); + pi->core_transmit = NULL; + } peer_info_remove_path (pi, pi->id, myid); if (myid == pi->id) { @@ -8100,7 +8152,6 @@ main (int argc, char *const *argv) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n", GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack); - return ret; }