summaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-11-21 12:56:10 -0500
committerDavid Goulet <dgoulet@torproject.org>2017-11-22 15:47:21 -0500
commit56833bf4491ef774163bc263bb18fa66fb378292 (patch)
tree3beda3d702e87d565ad4859edd674df80fd18d63 /src/or/relay.c
parent6d1ea7766b4fa6265744523fb3797cf8cf40d691 (diff)
downloadtor-56833bf4491ef774163bc263bb18fa66fb378292.tar.gz
tor-56833bf4491ef774163bc263bb18fa66fb378292.zip
channel: Requeue cell to circuit if channnel failed
If the channel layer failed to write a cell from the circuit queue, requeue it so it can be retried on the same channel later. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/relay.c')
-rw-r--r--src/or/relay.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/or/relay.c b/src/or/relay.c
index d6c103c146..f36fc78cda 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2521,6 +2521,17 @@ cell_queue_pop(cell_queue_t *queue)
return cell;
}
+/** Insert <b>cell</b> as the head of the <b>queue</b>. */
+static void
+cell_insert_head(cell_queue_t *queue, packed_cell_t *cell)
+{
+ tor_assert(queue);
+ tor_assert(cell);
+
+ TOR_SIMPLEQ_INSERT_HEAD(&queue->head, cell, next);
+ ++queue->n;
+}
+
/** Return the total number of bytes used for each packed_cell in a queue.
* Approximate. */
size_t
@@ -2746,7 +2757,10 @@ channel_flush_from_first_active_circuit, (channel_t *chan, int max))
/* this code is duplicated from some of the logic below. Ugly! XXXX */
tor_assert(destroy_queue->n > 0);
cell = cell_queue_pop(destroy_queue);
- channel_write_packed_cell(chan, cell);
+ if (channel_write_packed_cell(chan, cell) < 0) {
+ cell_insert_head(destroy_queue, cell);
+ continue;
+ }
/* Update the cmux destroy counter */
circuitmux_notify_xmit_destroy(cmux);
cell = NULL;
@@ -2823,7 +2837,12 @@ channel_flush_from_first_active_circuit, (channel_t *chan, int max))
DIRREQ_CIRC_QUEUE_FLUSHED);
/* Now send the cell */
- channel_write_packed_cell(chan, cell);
+ if (channel_write_packed_cell(chan, cell) < 0) {
+ /* Unable to send the cell, put it back at the start of the circuit
+ * queue so we can retry. */
+ cell_insert_head(queue, cell);
+ continue;
+ }
cell = NULL;
/*