aboutsummaryrefslogtreecommitdiff
path: root/src/or/channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/channel.c')
-rw-r--r--src/or/channel.c134
1 files changed, 66 insertions, 68 deletions
diff --git a/src/or/channel.c b/src/or/channel.c
index 87fa721089..af5810788c 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -8,6 +8,32 @@
* transfer cells from Tor instance to Tor instance.
* Currently, there is only one implementation of the channel abstraction: in
* channeltls.c.
+ *
+ * Channels are a higher-level abstraction than or_connection_t: In general,
+ * any means that two Tor relays use to exchange cells, or any means that a
+ * relay and a client use to exchange cells, is a channel.
+ *
+ * Channels differ from pluggable transports in that they do not wrap an
+ * underlying protocol over which cells are transmitted: they <em>are</em> the
+ * underlying protocol.
+ *
+ * This module defines the generic parts of the channel_t interface, and
+ * provides the machinery necessary for specialized implementations to be
+ * created. At present, there is one specialized implementation in
+ * channeltls.c, which uses connection_or.c to send cells over a TLS
+ * connection.
+ *
+ * Every channel implementation is responsible for being able to transmit
+ * cells that are added to it with channel_write_cell() and related functions,
+ * and to receive incoming cells with the channel_queue_cell() and related
+ * functions. See the channel_t documentation for more information.
+ *
+ * When new cells arrive on a channel, they are passed to cell handler
+ * functions, which can be set by channel_set_cell_handlers()
+ * functions. (Tor's cell handlers are in command.c.)
+ *
+ * Tor flushes cells to channels from relay.c in
+ * channel_flush_from_first_active_circuit().
**/
/*
@@ -838,7 +864,7 @@ channel_free(channel_t *chan)
}
/* Call a free method if there is one */
- if (chan->free) chan->free(chan);
+ if (chan->free_fn) chan->free_fn(chan);
channel_clear_remote_end(chan);
@@ -878,7 +904,7 @@ channel_listener_free(channel_listener_t *chan_l)
tor_assert(!(chan_l->registered));
/* Call a free method if there is one */
- if (chan_l->free) chan_l->free(chan_l);
+ if (chan_l->free_fn) chan_l->free_fn(chan_l);
/*
* We're in CLOSED or ERROR, so the incoming channel queue is already
@@ -916,7 +942,7 @@ channel_force_free(channel_t *chan)
}
/* Call a free method if there is one */
- if (chan->free) chan->free(chan);
+ if (chan->free_fn) chan->free_fn(chan);
channel_clear_remote_end(chan);
@@ -958,7 +984,7 @@ channel_listener_force_free(channel_listener_t *chan_l)
chan_l);
/* Call a free method if there is one */
- if (chan_l->free) chan_l->free(chan_l);
+ if (chan_l->free_fn) chan_l->free_fn(chan_l);
/*
* The incoming list just gets emptied and freed; we request close on
@@ -1712,7 +1738,7 @@ channel_get_cell_queue_entry_size(channel_t *chan, cell_queue_entry_t *q)
rv = get_cell_network_size(chan->wide_circ_ids);
break;
default:
- tor_assert(1);
+ tor_assert_nonfatal_unreached_once();
}
return rv;
@@ -1812,45 +1838,58 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
}
}
-/**
- * Write a cell to a channel
+/** Write a generic cell type to a channel
*
- * Write a fixed-length cell to a channel using the write_cell() method.
- * This is equivalent to the pre-channels connection_or_write_cell_to_buf();
- * it is called by the transport-independent code to deliver a cell to a
- * channel for transmission.
+ * Write a generic cell to a channel. It is called by channel_write_cell(),
+ * channel_write_var_cell() and channel_write_packed_cell() in order to reduce
+ * code duplication. Notice that it takes cell as pointer of type void,
+ * this can be dangerous because no type check is performed.
*/
void
-channel_write_cell(channel_t *chan, cell_t *cell)
+channel_write_cell_generic_(channel_t *chan, const char *cell_type,
+ void *cell, cell_queue_entry_t *q)
{
- cell_queue_entry_t q;
tor_assert(chan);
tor_assert(cell);
if (CHANNEL_IS_CLOSING(chan)) {
- log_debug(LD_CHANNEL, "Discarding cell_t %p on closing channel %p with "
- "global ID "U64_FORMAT, cell, chan,
+ log_debug(LD_CHANNEL, "Discarding %c %p on closing channel %p with "
+ "global ID "U64_FORMAT, *cell_type, cell, chan,
U64_PRINTF_ARG(chan->global_identifier));
tor_free(cell);
return;
}
-
log_debug(LD_CHANNEL,
- "Writing cell_t %p to channel %p with global ID "
- U64_FORMAT,
+ "Writing %c %p to channel %p with global ID "
+ U64_FORMAT, *cell_type,
cell, chan, U64_PRINTF_ARG(chan->global_identifier));
- q.type = CELL_QUEUE_FIXED;
- q.u.fixed.cell = cell;
- channel_write_cell_queue_entry(chan, &q);
-
+ channel_write_cell_queue_entry(chan, q);
/* Update the queue size estimate */
channel_update_xmit_queue_size(chan);
}
/**
+ * Write a cell to a channel
+ *
+ * Write a fixed-length cell to a channel using the write_cell() method.
+ * This is equivalent to the pre-channels connection_or_write_cell_to_buf();
+ * it is called by the transport-independent code to deliver a cell to a
+ * channel for transmission.
+ */
+
+void
+channel_write_cell(channel_t *chan, cell_t *cell)
+{
+ cell_queue_entry_t q;
+ q.type = CELL_QUEUE_FIXED;
+ q.u.fixed.cell = cell;
+ channel_write_cell_generic_(chan, "cell_t", cell, &q);
+}
+
+/**
* Write a packed cell to a channel
*
* Write a packed cell to a channel using the write_cell() method. This is
@@ -1862,30 +1901,9 @@ void
channel_write_packed_cell(channel_t *chan, packed_cell_t *packed_cell)
{
cell_queue_entry_t q;
-
- tor_assert(chan);
- tor_assert(packed_cell);
-
- if (CHANNEL_IS_CLOSING(chan)) {
- log_debug(LD_CHANNEL, "Discarding packed_cell_t %p on closing channel %p "
- "with global ID "U64_FORMAT, packed_cell, chan,
- U64_PRINTF_ARG(chan->global_identifier));
- packed_cell_free(packed_cell);
- return;
- }
-
- log_debug(LD_CHANNEL,
- "Writing packed_cell_t %p to channel %p with global ID "
- U64_FORMAT,
- packed_cell, chan,
- U64_PRINTF_ARG(chan->global_identifier));
-
q.type = CELL_QUEUE_PACKED;
q.u.packed.packed_cell = packed_cell;
- channel_write_cell_queue_entry(chan, &q);
-
- /* Update the queue size estimate */
- channel_update_xmit_queue_size(chan);
+ channel_write_cell_generic_(chan, "packed_cell_t", packed_cell, &q);
}
/**
@@ -1901,30 +1919,9 @@ void
channel_write_var_cell(channel_t *chan, var_cell_t *var_cell)
{
cell_queue_entry_t q;
-
- tor_assert(chan);
- tor_assert(var_cell);
-
- if (CHANNEL_IS_CLOSING(chan)) {
- log_debug(LD_CHANNEL, "Discarding var_cell_t %p on closing channel %p "
- "with global ID "U64_FORMAT, var_cell, chan,
- U64_PRINTF_ARG(chan->global_identifier));
- var_cell_free(var_cell);
- return;
- }
-
- log_debug(LD_CHANNEL,
- "Writing var_cell_t %p to channel %p with global ID "
- U64_FORMAT,
- var_cell, chan,
- U64_PRINTF_ARG(chan->global_identifier));
-
q.type = CELL_QUEUE_VAR;
q.u.var.var_cell = var_cell;
- channel_write_cell_queue_entry(chan, &q);
-
- /* Update the queue size estimate */
- channel_update_xmit_queue_size(chan);
+ channel_write_cell_generic_(chan, "var_cell_t", var_cell, &q);
}
/**
@@ -3223,9 +3220,10 @@ channel_free_all(void)
channel_t *
channel_connect(const tor_addr_t *addr, uint16_t port,
- const char *id_digest)
+ const char *id_digest,
+ const ed25519_public_key_t *ed_id)
{
- return channel_tls_connect(addr, port, id_digest);
+ return channel_tls_connect(addr, port, id_digest, ed_id);
}
/**