diff options
author | Bart Polot <bart@net.in.tum.de> | 2016-10-26 04:20:44 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2016-10-26 04:20:44 +0000 |
commit | 98d657cd445d60e793484594449c643655b23df5 (patch) | |
tree | 4498b35271cf38d55e587722d23d6fd7e0f51ef0 /src/cadet/gnunet-service-cadet_connection.c | |
parent | f98d6a1587d1c3d0207f708cd0c1eec9f516cd9e (diff) |
- add queue control in peer and connection to cancel MQ_env when those are destroyed, since callbacks could dereference freed memory
Diffstat (limited to 'src/cadet/gnunet-service-cadet_connection.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_connection.c | 106 |
1 files changed, 64 insertions, 42 deletions
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c index 12cabec213..47e728ed08 100644 --- a/src/cadet/gnunet-service-cadet_connection.c +++ b/src/cadet/gnunet-service-cadet_connection.c @@ -54,6 +54,37 @@ /******************************************************************************/ /** + * Handle for messages queued but not yet sent. + */ +struct CadetConnectionQueue +{ + + struct CadetConnectionQueue *next; + struct CadetConnectionQueue *prev; + + /** + * Peer queue handle, to cancel if necessary. + */ + struct CadetPeerQueue *peer_q; + + /** + * Continuation to call once sent. + */ + GCC_sent cont; + + /** + * Closure for @e cont. + */ + void *cont_cls; + + /** + * Was this a forced message? (Do not account for it) + */ + int forced; +}; + + +/** * Struct to encapsulate all the Flow Control information to a peer to which * we are directly connected (on a core level). */ @@ -64,6 +95,9 @@ struct CadetFlowControl */ struct CadetConnection *c; + struct CadetConnectionQueue *q_head; + struct CadetConnectionQueue *q_tail; + /** * How many messages are in the queue on this connection. */ @@ -265,32 +299,6 @@ struct CadetConnection }; -/** - * Handle for messages queued but not yet sent. - */ -struct CadetConnectionQueue -{ - /** - * Peer queue handle, to cancel if necessary. - */ - struct CadetPeerQueue *peer_q; - - /** - * Continuation to call once sent. - */ - GCC_sent cont; - - /** - * Closure for @e cont. - */ - void *cont_cls; - - /** - * Was this a forced message? (Do not account for it) - */ - int forced; -}; - /******************************************************************************/ /******************************* GLOBALS ***********************************/ /******************************************************************************/ @@ -694,6 +702,7 @@ conn_message_sent (void *cls, int forced; GCC_check_connections (); + LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n"); /* If c is NULL, nothing to update. */ if (NULL == c) @@ -708,16 +717,17 @@ conn_message_sent (void *cls, return; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n", + sent ? "" : "not ", GC_f2s (fwd), + GC_m2s (type), GC_m2s (payload_type), pid); GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); /* Update flow control info. */ fc = fwd ? &c->fwd_fc : &c->bck_fc; - LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n", - sent ? "" : "not ", GC_f2s (fwd), - GC_m2s (type), GC_m2s (payload_type), pid); + if (NULL != q) { + GNUNET_CONTAINER_DLL_remove (fc->q_head, fc->q_tail, q); forced = q->forced; if (NULL != q->cont) { @@ -728,12 +738,14 @@ conn_message_sent (void *cls, } else if (type == GNUNET_MESSAGE_TYPE_CADET_AX) { - /* If NULL == q and ENCRYPTED == type, message must have been ch_mngmnt */ + /* SHOULD NO LONGER HAPPEN FIXME: REMOVE CASE */ + // If NULL == q and ENCRYPTED == type, message must have been ch_mngmnt forced = GNUNET_YES; + GNUNET_assert (0); // FIXME } - else + else /* CONN_CREATE or CONN_ACK */ { - forced = GNUNET_NO; + forced = GNUNET_YES; } LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages); @@ -1091,22 +1103,21 @@ send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id, const struct GNUNET_PeerIdentity *id2, struct CadetPeer *neighbor) { - struct GNUNET_CADET_ConnectionBroken *msg; + struct GNUNET_CADET_ConnectionBroken msg; GCC_check_connections (); LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n", GNUNET_h2s (GC_h2hc (connection_id))); - msg = GNUNET_new (struct GNUNET_CADET_ConnectionBroken); - msg->header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBroken)); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); - msg->cid = *connection_id; - msg->peer1 = *id1; + msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBroken)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); + msg.cid = *connection_id; + msg.peer1 = *id1; if (NULL != id2) - msg->peer2 = *id2; + msg.peer2 = *id2; else - memset (&msg->peer2, 0, sizeof (msg->peer2)); - GNUNET_assert (NULL != GCP_send (neighbor, &msg->header, + memset (&msg.peer2, 0, sizeof (msg.peer2)); + GNUNET_assert (NULL != GCP_send (neighbor, &msg.header, UINT16_MAX, 2, NULL, GNUNET_SYSERR, /* connection, fwd */ NULL, NULL)); /* continuation */ @@ -1382,6 +1393,11 @@ connection_cancel_queues (struct CadetConnection *c, GCC_cancel (fc->poll_msg); LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc); } + + while (NULL != fc->q_head) + { + GCC_cancel (fc->q_head); + } GCC_check_connections (); } @@ -2849,6 +2865,11 @@ GCC_destroy (struct CadetConnection *c) { connection_cancel_queues (c, GNUNET_YES); connection_cancel_queues (c, GNUNET_NO); + if (NULL != c->maintenance_q) + { + GCP_send_cancel (c->maintenance_q); + c->maintenance_q = NULL; + } } unregister_neighbors (c); path_destroy (c->path); @@ -3354,6 +3375,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, } q->cont = cont; q->cont_cls = cont_cls; + GNUNET_CONTAINER_DLL_insert (fc->q_head, fc->q_tail, q); GCC_check_connections (); return (NULL == cont) ? NULL : q; } |