aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_connection.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2016-10-26 04:20:44 +0000
committerBart Polot <bart@net.in.tum.de>2016-10-26 04:20:44 +0000
commit98d657cd445d60e793484594449c643655b23df5 (patch)
tree4498b35271cf38d55e587722d23d6fd7e0f51ef0 /src/cadet/gnunet-service-cadet_connection.c
parentf98d6a1587d1c3d0207f708cd0c1eec9f516cd9e (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.c106
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;
}