diff options
-rw-r--r-- | src/or/connection.c | 54 | ||||
-rw-r--r-- | src/or/connection_or.c | 2 | ||||
-rw-r--r-- | src/or/control.c | 4 | ||||
-rw-r--r-- | src/or/main.c | 2 | ||||
-rw-r--r-- | src/or/or.h | 3 |
5 files changed, 13 insertions, 52 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index c2136ac858..d7c1b7955c 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1575,11 +1575,15 @@ connection_outbuf_too_full(connection_t *conn) * more bytes on conn->outbuf, then call connection_finished_flushing * on it too. * + * If <b>force</b>, then write as many bytes as possible, ignoring bandwidth + * limits. (Used for flushing messages to controller connections on fatal + * errors.) + * * Mark the connection and return -1 if you want to close it, else * return 0. */ int -connection_handle_write(connection_t *conn) +connection_handle_write(connection_t *conn, int force) { int e; socklen_t len=sizeof(e); @@ -1590,7 +1594,7 @@ connection_handle_write(connection_t *conn) tor_assert(!connection_is_listener(conn)); - if (conn->marked_for_close) + if (conn->marked_for_close || conn->s < 0) return 0; /* do nothing */ conn->timestamp_lastwritten = now; @@ -1631,7 +1635,8 @@ connection_handle_write(connection_t *conn) return -1; } - max_to_write = connection_bucket_write_limit(conn); + max_to_write = force ? (int)conn->outbuf_flushlen + : connection_bucket_write_limit(conn); if (connection_speaks_cells(conn) && conn->state > OR_CONN_STATE_PROXY_READING) { @@ -1738,49 +1743,6 @@ connection_handle_write(connection_t *conn) return 0; } -/* A controller event has just happened with such urgency that we - * need to write it onto controller <b>conn</b> immediately. */ -void -_connection_controller_force_write(control_connection_t *control_conn) -{ - /* XXXX012 This is hideous code duplication, but raising it seems a little - * tricky for now. Think more about this one. We only call it for - * EVENT_ERR_MSG, so messing with buckets a little isn't such a big problem. - */ - int result; - connection_t *conn; - tor_assert(control_conn); - conn = TO_CONN(control_conn); - - if (conn->marked_for_close || conn->s < 0) - return; - - CONN_LOG_PROTECT(conn, - result = flush_buf(conn->s, conn->outbuf, - conn->outbuf_flushlen, &conn->outbuf_flushlen)); - if (result < 0) { - connection_close_immediate(conn); /* Don't flush; connection is dead. */ - connection_mark_for_close(conn); - return; - } - - if (result > 0) { - if (!is_internal_IP(conn->addr, 0)) { /* remember it */ - rep_hist_note_bytes_written(result, time(NULL)); - global_write_bucket -= result; - } - if (connection_flushed_some(conn) < 0) - connection_mark_for_close(conn); - } - - if (!connection_wants_to_flush(conn)) { /* it's done flushing */ - if (connection_finished_flushing(conn) < 0) { - /* already marked */ - return; - } - } -} - /** Append <b>len</b> bytes of <b>string</b> onto <b>conn</b>'s * outbuf, and ask it to start writing. */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index bfb4247519..804848771c 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -717,7 +717,7 @@ connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn) int extra = conn->_base.outbuf_flushlen - MIN_TLS_FLUSHLEN; conn->_base.outbuf_flushlen = MIN_TLS_FLUSHLEN; connection_start_writing(TO_CONN(conn)); - if (connection_handle_write(TO_CONN(conn)) < 0) { + if (connection_handle_write(TO_CONN(conn), 0) < 0) { if (!conn->_base.marked_for_close) { /* this connection is broken. remove it. */ log_warn(LD_BUG, diff --git a/src/or/control.c b/src/or/control.c index 90ab2ca0cc..21b5350153 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -619,7 +619,7 @@ send_control0_event(uint16_t event, uint32_t len, const char *body) if (control_conn->event_mask & (1<<event)) { send_control0_message(control_conn, CONTROL0_CMD_EVENT, buflen, buf); if (event == EVENT_ERR_MSG) - _connection_controller_force_write(control_conn); + connection_handle_write(TO_CONN(control_conn), 1); } } } @@ -663,7 +663,7 @@ send_control1_event_string(uint16_t event, event_format_t which, if (control_conn->event_mask & (1<<event)) { connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn)); if (event == EVENT_ERR_MSG) - _connection_controller_force_write(control_conn); + connection_handle_write(TO_CONN(control_conn), 1); } } } diff --git a/src/or/main.c b/src/or/main.c index 2247210bf9..7d4117adcc 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -440,7 +440,7 @@ conn_write_callback(int fd, short events, void *_conn) assert_connection_ok(conn, time(NULL)); - if (connection_handle_write(conn) < 0) { + if (connection_handle_write(conn, 0) < 0) { if (!conn->marked_for_close) { /* this connection is broken. remove it. */ log_fn(LOG_WARN,LD_BUG, diff --git a/src/or/or.h b/src/or/or.h index 765b52a124..d8829c96f0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1999,8 +1999,7 @@ int connection_fetch_from_buf(char *string, size_t len, connection_t *conn); int connection_wants_to_flush(connection_t *conn); int connection_outbuf_too_full(connection_t *conn); -int connection_handle_write(connection_t *conn); -void _connection_controller_force_write(control_connection_t *conn); +int connection_handle_write(connection_t *conn, int force); void connection_write_to_buf(const char *string, size_t len, connection_t *conn); void connection_write_to_buf_zlib(dir_connection_t *conn, |