diff options
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 6e2ab884aa..479fc00b1c 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -20,6 +20,7 @@ static int connection_init_accepted_conn(connection_t *conn); static int connection_handle_listener_read(connection_t *conn, int new_type); static int connection_receiver_bucket_should_increase(connection_t *conn); static int connection_finished_flushing(connection_t *conn); +static int connection_flushed_some(connection_t *conn); static int connection_finished_connecting(connection_t *conn); static int connection_reached_eof(connection_t *conn); static int connection_read_to_buf(connection_t *conn, int *max_to_read); @@ -241,6 +242,14 @@ _connection_free(connection_t *conn) log_warn(LD_BUG, "called on OR conn with non-zeroed identity_digest"); connection_or_remove_from_identity_map(conn); } + if (conn->zlib_state) + tor_zlib_free(conn->zlib_state); + if (conn->fingerprint_stack) { + SMARTLIST_FOREACH(conn->fingerprint_stack, char *, cp, tor_free(cp)); + smartlist_free(conn->fingerprint_stack); + } + if (conn->cached_dir) + cached_dir_decref(conn->cached_dir); memset(conn, 0xAA, sizeof(connection_t)); /* poison memory */ tor_free(conn); @@ -1491,9 +1500,13 @@ connection_handle_write(connection_t *conn) } } - if (result > 0 && !is_local_IP(conn->addr)) { /* remember it */ - rep_hist_note_bytes_written(result, now); - global_write_bucket -= result; + if (result > 0) { + if (!is_local_IP(conn->addr)) { /* 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 */ @@ -1531,9 +1544,13 @@ _connection_controller_force_write(connection_t *conn) return; } - if (result > 0 && !is_local_IP(conn->addr)) { /* remember it */ - rep_hist_note_bytes_written(result, time(NULL)); - global_write_bucket -= result; + if (result > 0) { + if (!is_local_IP(conn->addr)) { /* 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 */ @@ -1913,6 +1930,17 @@ connection_process_inbuf(connection_t *conn, int package_partial) } } +/** Called whenever we've written data on a connection. */ +static int +connection_flushed_some(connection_t *conn) +{ + if (conn->type == CONN_TYPE_DIR && + conn->state == DIR_CONN_STATE_SERVER_WRITING) + return connection_dirserv_flushed_some(conn); + else + return 0; +} + /** We just finished flushing bytes from conn-\>outbuf, and there * are no more bytes remaining. * |