diff --git a/src/core/include.am b/src/core/include.am index 9824601725..067b6857ae 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -52,6 +52,7 @@ LIBTOR_APP_A_SOURCES = \ src/core/or/scheduler.c \ src/core/or/scheduler_kist.c \ src/core/or/scheduler_vanilla.c \ + src/core/or/sendme.c \ src/core/or/status.c \ src/core/or/versions.c \ src/core/proto/proto_cell.c \ @@ -272,6 +273,7 @@ noinst_HEADERS += \ src/core/or/relay.h \ src/core/or/relay_crypto_st.h \ src/core/or/scheduler.h \ + src/core/or/sendme.h \ src/core/or/server_port_cfg_st.h \ src/core/or/socks_request_st.h \ src/core/or/status.h \ diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 33ba723971..fa72fb7716 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -73,6 +73,7 @@ #include "core/or/policies.h" #include "core/or/reasons.h" #include "core/or/relay.h" +#include "core/or/sendme.h" #include "core/proto/proto_http.h" #include "core/proto/proto_socks.h" #include "feature/client/addressmap.h" @@ -767,7 +768,7 @@ connection_edge_flushed_some(edge_connection_t *conn) /* falls through. */ case EXIT_CONN_STATE_OPEN: - connection_edge_consider_sending_sendme(conn); + sendme_connection_edge_consider_sending(conn); break; } return 0; @@ -791,7 +792,7 @@ connection_edge_finished_flushing(edge_connection_t *conn) switch (conn->base_.state) { case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: - connection_edge_consider_sending_sendme(conn); + sendme_connection_edge_consider_sending(conn); return 0; case AP_CONN_STATE_SOCKS_WAIT: case AP_CONN_STATE_NATD_WAIT: diff --git a/src/core/or/relay.c b/src/core/or/relay.c index a166904a5f..7cfacf761a 100644 --- a/src/core/or/relay.c +++ b/src/core/or/relay.c @@ -93,13 +93,12 @@ #include "core/or/origin_circuit_st.h" #include "feature/nodelist/routerinfo_st.h" #include "core/or/socks_request_st.h" +#include "core/or/sendme.h" static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t *layer_hint); -static void circuit_consider_sending_sendme(circuit_t *circ, - crypt_path_t *layer_hint); static void circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint); static int circuit_resume_edge_reading_helper(edge_connection_t *conn, @@ -1564,7 +1563,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, log_debug(domain,"circ deliver_window now %d.", layer_hint ? layer_hint->deliver_window : circ->deliver_window); - circuit_consider_sending_sendme(circ, layer_hint); + sendme_circuit_consider_sending(circ, layer_hint); if (rh.stream_id == 0) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero " @@ -1615,7 +1614,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, /* Only send a SENDME if we're not getting optimistic data; otherwise * a SENDME could arrive before the CONNECTED. */ - connection_edge_consider_sending_sendme(conn); + sendme_connection_edge_consider_sending(conn); } return 0; @@ -1869,7 +1868,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, /* Don't allow the other endpoint to request more than our maximum * (i.e. initial) stream SENDME window worth of data. Well-behaved * stock clients will not request more than this max (as per the check - * in the while loop of connection_edge_consider_sending_sendme()). + * in the while loop of sendme_connection_edge_consider_sending()). */ if (conn->package_window + STREAMWINDOW_INCREMENT > STREAMWINDOW_START_MAX) { @@ -2117,42 +2116,6 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial, goto repeat_connection_edge_package_raw_inbuf; } -/** Called when we've just received a relay data cell, when - * we've just finished flushing all bytes to stream conn, - * or when we've flushed *some* bytes to the stream conn. - * - * If conn->outbuf is not too full, and our deliver window is - * low, send back a suitable number of stream-level sendme cells. - */ -void -connection_edge_consider_sending_sendme(edge_connection_t *conn) -{ - circuit_t *circ; - - if (connection_outbuf_too_full(TO_CONN(conn))) - return; - - circ = circuit_get_by_edge_conn(conn); - if (!circ) { - /* this can legitimately happen if the destroy has already - * arrived and torn down the circuit */ - log_info(LD_APP,"No circuit associated with conn. Skipping."); - return; - } - - while (conn->deliver_window <= STREAMWINDOW_START - STREAMWINDOW_INCREMENT) { - log_debug(conn->base_.type == CONN_TYPE_AP ?LD_APP:LD_EXIT, - "Outbuf %d, Queuing stream sendme.", - (int)conn->base_.outbuf_flushlen); - conn->deliver_window += STREAMWINDOW_INCREMENT; - if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME, - NULL, 0) < 0) { - log_warn(LD_APP,"connection_edge_send_command failed. Skipping."); - return; /* the circuit's closed, don't continue */ - } - } -} - /** The circuit circ has received a circuit-level sendme * (on hop layer_hint, if we're the OP). Go through all the * attached streams and let them resume reading and packaging, if @@ -2369,33 +2332,6 @@ circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint) return 0; } -/** Check if the deliver_window for circuit circ (at hop - * layer_hint if it's defined) is low enough that we should - * send a circuit-level sendme back down the circuit. If so, send - * enough sendmes that the window would be overfull if we sent any - * more. - */ -static void -circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint) -{ -// log_fn(LOG_INFO,"Considering: layer_hint is %s", -// layer_hint ? "defined" : "null"); - while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <= - CIRCWINDOW_START - CIRCWINDOW_INCREMENT) { - log_debug(LD_CIRC,"Queuing circuit sendme."); - if (layer_hint) - layer_hint->deliver_window += CIRCWINDOW_INCREMENT; - else - circ->deliver_window += CIRCWINDOW_INCREMENT; - if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME, - NULL, 0, layer_hint) < 0) { - log_warn(LD_CIRC, - "relay_send_command_from_edge failed. Circuit's closed."); - return; /* the circuit's closed, don't continue */ - } - } -} - /** The total number of cells we have allocated. */ static size_t total_cells_allocated = 0; diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c new file mode 100644 index 0000000000..3e00721d26 --- /dev/null +++ b/src/core/or/sendme.c @@ -0,0 +1,76 @@ +/* Copyright (c) 2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file sendme.c + * \brief Code that is related to SENDME cells both in terms of + * creating/parsing cells and handling the content. + */ + +#include "core/or/or.h" + +#include "core/mainloop/connection.h" +#include "core/or/circuitlist.h" +#include "core/or/relay.h" +#include "core/or/sendme.h" + +/** Called when we've just received a relay data cell, when + * we've just finished flushing all bytes to stream conn, + * or when we've flushed *some* bytes to the stream conn. + * + * If conn->outbuf is not too full, and our deliver window is + * low, send back a suitable number of stream-level sendme cells. + */ +void +sendme_connection_edge_consider_sending(edge_connection_t *conn) +{ + circuit_t *circ; + + if (connection_outbuf_too_full(TO_CONN(conn))) + return; + + circ = circuit_get_by_edge_conn(conn); + if (!circ) { + /* this can legitimately happen if the destroy has already + * arrived and torn down the circuit */ + log_info(LD_APP,"No circuit associated with conn. Skipping."); + return; + } + + while (conn->deliver_window <= STREAMWINDOW_START - STREAMWINDOW_INCREMENT) { + log_debug(conn->base_.type == CONN_TYPE_AP ?LD_APP:LD_EXIT, + "Outbuf %d, Queuing stream sendme.", + (int)conn->base_.outbuf_flushlen); + conn->deliver_window += STREAMWINDOW_INCREMENT; + if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME, + NULL, 0) < 0) { + log_warn(LD_APP,"connection_edge_send_command failed. Skipping."); + return; /* the circuit's closed, don't continue */ + } + } +} + +/** Check if the deliver_window for circuit circ (at hop + * layer_hint if it's defined) is low enough that we should + * send a circuit-level sendme back down the circuit. If so, send + * enough sendmes that the window would be overfull if we sent any + * more. + */ +void +sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint) +{ + while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <= + CIRCWINDOW_START - CIRCWINDOW_INCREMENT) { + log_debug(LD_CIRC,"Queuing circuit sendme."); + if (layer_hint) + layer_hint->deliver_window += CIRCWINDOW_INCREMENT; + else + circ->deliver_window += CIRCWINDOW_INCREMENT; + if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME, + NULL, 0, layer_hint) < 0) { + log_warn(LD_CIRC, + "relay_send_command_from_edge failed. Circuit's closed."); + return; /* the circuit's closed, don't continue */ + } + } +} diff --git a/src/core/or/sendme.h b/src/core/or/sendme.h new file mode 100644 index 0000000000..3ff1d98e64 --- /dev/null +++ b/src/core/or/sendme.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file sendme.h + * \brief Header file for sendme.c. + **/ + +#ifndef TOR_SENDME_H +#define TOR_SENDME_H + +#include "core/or/edge_connection_st.h" +#include "core/or/crypt_path_st.h" +#include "core/or/circuit_st.h" + +void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn); +void sendme_circuit_consider_sending(circuit_t *circ, + crypt_path_t *layer_hint); + +#endif /* !defined(TOR_SENDME_H) */