summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2010-09-13 16:05:22 -0400
committerNick Mathewson <nickm@torproject.org>2010-09-13 18:59:42 -0400
commitb582eb32b820e53dcd8ac9db58f6000b88cf2e4e (patch)
tree0cdb1c9e17163bd724eacb8523ca9f8af18542b1
parent61b7e36312f5a097602ff110478072e0a13178c1 (diff)
downloadtor-b582eb32b820e53dcd8ac9db58f6000b88cf2e4e.tar.gz
tor-b582eb32b820e53dcd8ac9db58f6000b88cf2e4e.zip
Add a max_cells arg to connection_edge_process_raw_inbuf
I'm going to use this to implement more fairness in circuit_resume_edge_reading_helper in an attempt to fix bug 1298. (Updated with fixes from arma and Sebastian)
-rw-r--r--src/or/connection_edge.c2
-rw-r--r--src/or/relay.c27
-rw-r--r--src/or/relay.h3
3 files changed, 23 insertions, 9 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index df182c6194..6a3a5ef0a9 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -147,7 +147,7 @@ connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
return 0;
case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN:
- if (connection_edge_package_raw_inbuf(conn, package_partial) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return -1;
diff --git a/src/or/relay.c b/src/or/relay.c
index 7608674a9f..7d3d780f2e 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -946,7 +946,7 @@ connection_edge_process_relay_cell_not_open(
}
/* handle anything that might have queued */
- if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return 0;
@@ -1241,7 +1241,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
}
connection_start_reading(TO_CONN(conn));
/* handle whatever might still be on the inbuf */
- if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
+ if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
return 0;
@@ -1307,15 +1307,19 @@ uint64_t stats_n_data_cells_received = 0;
* ever received were completely full of data. */
uint64_t stats_n_data_bytes_received = 0;
-/** While conn->inbuf has an entire relay payload of bytes on it,
- * and the appropriate package windows aren't empty, grab a cell
- * and send it down the circuit.
+/** If <b>conn</b> has an entire relay payload of bytes on its inbuf (or
+ * <b>package_partial</b> is true), and the appropriate package windows aren't
+ * empty, grab a cell and send it down the circuit.
+ *
+ * If *<b>max_cells</b> is given, package no more than max_cells. Decrement
+ * *<b>max_cells</b> by the number of cells packaged.
*
* Return -1 (and send a RELAY_COMMAND_END cell if necessary) if conn should
* be marked for close, else return 0.
*/
int
-connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
+connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
+ int *max_cells)
{
size_t amount_to_process, length;
char payload[CELL_PAYLOAD_SIZE];
@@ -1331,6 +1335,9 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
return 0;
}
+ if (max_cells && *max_cells <= 0)
+ return 0;
+
repeat_connection_edge_package_raw_inbuf:
circ = circuit_get_by_edge_conn(conn);
@@ -1392,6 +1399,12 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
}
log_debug(domain,"conn->package_window is now %d",conn->package_window);
+ if (max_cells) {
+ *max_cells -= 1;
+ if (*max_cells <= 0)
+ return 0;
+ }
+
/* handle more if there's more, or return 0 if there isn't */
goto repeat_connection_edge_package_raw_inbuf;
}
@@ -1470,7 +1483,7 @@ circuit_resume_edge_reading_helper(edge_connection_t *conn,
conn->cpath_layer == layer_hint)) {
connection_start_reading(TO_CONN(conn));
/* handle whatever might still be on the inbuf */
- if (connection_edge_package_raw_inbuf(conn, 1)<0) {
+ if (connection_edge_package_raw_inbuf(conn, 1, NULL)<0) {
/* (We already sent an end cell if possible) */
connection_mark_for_close(TO_CONN(conn));
continue;
diff --git a/src/or/relay.h b/src/or/relay.h
index 0ef17b6ffd..66d17579a3 100644
--- a/src/or/relay.h
+++ b/src/or/relay.h
@@ -27,7 +27,8 @@ int connection_edge_send_command(edge_connection_t *fromconn,
uint8_t relay_command, const char *payload,
size_t payload_len);
int connection_edge_package_raw_inbuf(edge_connection_t *conn,
- int package_partial);
+ int package_partial,
+ int *max_cells);
void connection_edge_consider_sending_sendme(edge_connection_t *conn);
extern uint64_t stats_n_data_cells_packaged;