summaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/relay.c')
-rw-r--r--src/or/relay.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/src/or/relay.c b/src/or/relay.c
index f42602d412..2d11096309 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2013, The Tor Project, Inc. */
+ * Copyright (c) 2007-2015, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -39,6 +39,7 @@
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
+#include "scheduler.h"
static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
cell_direction_t cell_direction,
@@ -523,6 +524,7 @@ relay_header_unpack(relay_header_t *dest, const uint8_t *src)
static const char *
relay_command_to_string(uint8_t command)
{
+ static char buf[64];
switch (command) {
case RELAY_COMMAND_BEGIN: return "BEGIN";
case RELAY_COMMAND_DATA: return "DATA";
@@ -547,7 +549,12 @@ relay_command_to_string(uint8_t command)
case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
return "RENDEZVOUS_ESTABLISHED";
case RELAY_COMMAND_INTRODUCE_ACK: return "INTRODUCE_ACK";
- default: return "(unrecognized)";
+ case RELAY_COMMAND_EXTEND2: return "EXTEND2";
+ case RELAY_COMMAND_EXTENDED2: return "EXTENDED2";
+ default:
+ tor_snprintf(buf, sizeof(buf), "Unrecognized relay command %u",
+ (unsigned)command);
+ return buf;
}
}
@@ -1712,7 +1719,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
if (circ->package_window + CIRCWINDOW_INCREMENT >
CIRCWINDOW_START_MAX) {
static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
- log_fn_ratelim(&client_warn_ratelim, LOG_WARN, LD_PROTOCOL,
+ log_fn_ratelim(&client_warn_ratelim,LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Unexpected sendme cell from client. "
"Closing circ (window %d).",
circ->package_window);
@@ -2322,15 +2329,15 @@ packed_cell_free(packed_cell_t *cell)
void
dump_cell_pool_usage(int severity)
{
- circuit_t *c;
int n_circs = 0;
int n_cells = 0;
- TOR_LIST_FOREACH(c, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, c) {
n_cells += c->n_chan_cells.n;
if (!CIRCUIT_IS_ORIGIN(c))
n_cells += TO_OR_CIRCUIT(c)->p_chan_cells.n;
++n_circs;
}
+ SMARTLIST_FOREACH_END(c);
tor_log(severity, LD_MM,
"%d cells allocated on %d circuits. %d cells leaked.",
n_cells, n_circs, (int)total_cells_allocated - n_cells);
@@ -2426,6 +2433,12 @@ cell_queues_get_total_allocation(void)
return total_cells_allocated * packed_cell_mem_cost();
}
+/** How long after we've been low on memory should we try to conserve it? */
+#define MEMORY_PRESSURE_INTERVAL (30*60)
+
+/** The time at which we were last low on memory. */
+static time_t last_time_under_memory_pressure = 0;
+
/** Check whether we've got too much space used for cells. If so,
* call the OOM handler and return 1. Otherwise, return 0. */
STATIC int
@@ -2433,13 +2446,26 @@ cell_queues_check_size(void)
{
size_t alloc = cell_queues_get_total_allocation();
alloc += buf_get_total_allocation();
- if (alloc >= get_options()->MaxMemInQueues) {
- circuits_handle_oom(alloc);
- return 1;
+ alloc += tor_zlib_get_total_allocation();
+ if (alloc >= get_options()->MaxMemInQueues_low_threshold) {
+ last_time_under_memory_pressure = approx_time();
+ if (alloc >= get_options()->MaxMemInQueues) {
+ circuits_handle_oom(alloc);
+ return 1;
+ }
}
return 0;
}
+/** Return true if we've been under memory pressure in the last
+ * MEMORY_PRESSURE_INTERVAL seconds. */
+int
+have_been_under_memory_pressure(void)
+{
+ return last_time_under_memory_pressure + MEMORY_PRESSURE_INTERVAL
+ < approx_time();
+}
+
/**
* Update the number of cells available on the circuit's n_chan or p_chan's
* circuit mux.
@@ -2584,8 +2610,8 @@ packed_cell_get_circid(const packed_cell_t *cell, int wide_circ_ids)
* queue of the first active circuit on <b>chan</b>, and write them to
* <b>chan</b>-&gt;outbuf. Return the number of cells written. Advance
* the active circuit pointer to the next active circuit in the ring. */
-int
-channel_flush_from_first_active_circuit(channel_t *chan, int max)
+MOCK_IMPL(int,
+channel_flush_from_first_active_circuit, (channel_t *chan, int max))
{
circuitmux_t *cmux = NULL;
int n_flushed = 0;
@@ -2861,14 +2887,8 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
log_debug(LD_GENERAL, "Made a circuit active.");
}
- if (!channel_has_queued_writes(chan)) {
- /* There is no data at all waiting to be sent on the outbuf. Add a
- * cell, so that we can notice when it gets flushed, flushed_some can
- * get called, and we can start putting more data onto the buffer then.
- */
- log_debug(LD_GENERAL, "Primed a buffer.");
- channel_flush_from_first_active_circuit(chan, 1);
- }
+ /* New way: mark this as having waiting cells for the scheduler */
+ scheduler_channel_has_waiting_cells(chan);
}
/** Append an encoded value of <b>addr</b> to <b>payload_out</b>, which must