aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_or.c
diff options
context:
space:
mode:
authorAndrea Shepard <andrea@torproject.org>2016-03-15 07:40:19 +0000
committerNick Mathewson <nickm@torproject.org>2016-03-21 10:14:47 -0400
commitbd87d37a861c541afbeb660b4d8dd62df14d5b45 (patch)
treece2f375c8db8e9c3a08dd406342ce20bc92a8e79 /src/or/connection_or.c
parent1cdc7fddb2ed10d72f4e65e15d1af4d803a1acdb (diff)
downloadtor-bd87d37a861c541afbeb660b4d8dd62df14d5b45.tar.gz
tor-bd87d37a861c541afbeb660b4d8dd62df14d5b45.zip
Make sure channel_t queues its own copy of incoming cells
Diffstat (limited to 'src/or/connection_or.c')
-rw-r--r--src/or/connection_or.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index a967c93aca..994449419e 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -488,6 +488,28 @@ var_cell_new(uint16_t payload_len)
return cell;
}
+/**
+ * Copy a var_cell_t
+ */
+
+var_cell_t *
+var_cell_copy(const var_cell_t *src)
+{
+ var_cell_t *copy = NULL;
+ size_t size = 0;
+
+ if (src != NULL) {
+ size = STRUCT_OFFSET(var_cell_t, payload) + src->payload_len;
+ copy = tor_malloc_zero(size);
+ copy->payload_len = src->payload_len;
+ copy->command = src->command;
+ copy->circ_id = src->circ_id;
+ memcpy(copy->payload, src->payload, copy->payload_len);
+ }
+
+ return copy;
+}
+
/** Release all space held by <b>cell</b>. */
void
var_cell_free(var_cell_t *cell)
@@ -2060,6 +2082,19 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
{
var_cell_t *var_cell;
+ /*
+ * Note on memory management for incoming cells: below the channel layer,
+ * we shouldn't need to consider its internal queueing/copying logic. It
+ * is safe to pass cells to it on the stack or on the heap, but in the
+ * latter case we must be sure we free them later.
+ *
+ * The incoming cell queue code in channel.c will (in the common case)
+ * decide it can pass them to the upper layer immediately, in which case
+ * those functions may run directly on the cell pointers we pass here, or
+ * it may decide to queue them, in which case it will allocate its own
+ * buffer and copy the cell.
+ */
+
while (1) {
log_debug(LD_OR,
TOR_SOCKET_T_FORMAT": starting, inbuf_datalen %d "