diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-03-03 05:08:01 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-03-03 05:08:01 +0000 |
commit | f4e4dac80163625d0d1713ee8ff6c2d9f0c3d394 (patch) | |
tree | c1ff86f96ea8b10847ab71a4f26f962b9698357b | |
parent | 8275e2302ca3995f15a0b78e7a5341230653694c (diff) | |
download | tor-f4e4dac80163625d0d1713ee8ff6c2d9f0c3d394.tar.gz tor-f4e4dac80163625d0d1713ee8ff6c2d9f0c3d394.zip |
Implement hold_open_until_flushed. I may have missed something important.
svn:r1209
-rw-r--r-- | src/or/connection.c | 21 | ||||
-rw-r--r-- | src/or/main.c | 10 | ||||
-rw-r--r-- | src/or/or.h | 4 |
3 files changed, 34 insertions, 1 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 934543c6d7..30741ebead 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -209,6 +209,27 @@ _connection_mark_for_close(connection_t *conn, char reason) return retval; } +void connection_expire_held_open(void) +{ + connection_t **carray, *conn; + int n, i; + time_t now; + + now = time(NULL); + + get_connection_array(&carray, &n); + for (i = 0; i < n; ++i) { + conn = carray[i]; + /* If we've been holding the connection open, but we haven't written + * for 15 seconds... + */ + if (conn->marked_for_close && conn->hold_open_until_flushed && + now - conn->timestamp_lastwritten >= 15) { + conn->hold_open_until_flushed = 0; + } + } +} + int connection_create_listener(char *bindaddress, uint16_t bindport, int type) { struct sockaddr_in bindaddr; /* where to bind */ struct hostent *rent; diff --git a/src/or/main.c b/src/or/main.c index d9eeff2864..04c1e99494 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -229,6 +229,10 @@ static void conn_close_if_marked(int i) { conn = connection_array[i]; assert_connection_ok(conn, time(NULL)); if(conn->marked_for_close) { + if (conn->hold_open_until_flushed && conn->s >= 0 && + connection_wants_to_flush(conn)) + return; + log_fn(LOG_INFO,"Cleaning up connection (fd %d).",conn->s); if(conn->s >= 0 && connection_wants_to_flush(conn)) { /* -1 means it's an incomplete edge connection, or that the socket @@ -237,7 +241,6 @@ static void conn_close_if_marked(int i) { log_fn(LOG_WARN, "Conn (fd %d, type %d, state %d) marked for close, but wants to flush.", conn->s, conn->type, conn->state); - if(connection_speaks_cells(conn)) { if(conn->state == OR_CONN_STATE_OPEN) { flush_buf_tls(conn->tls, conn->outbuf, &conn->outbuf_flushlen); @@ -348,6 +351,11 @@ static void run_scheduled_events(time_t now) { */ connection_ap_expire_beginning(); + + /* 2c. And expire connections that we've holding open for too long. + */ + connection_expire_held_open(); + /* 3. Every second, we try a new circuit if there are no valid * circuits. Every NewCircuitPeriod seconds, we expire circuits * that became dirty more than NewCircuitPeriod seconds ago, diff --git a/src/or/or.h b/src/or/or.h index 17ed66967e..97e74275de 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -318,6 +318,7 @@ struct connection_t { */ char *marked_for_close_file; /* for debugging: in which file were we marked * for close? */ + int hold_open_until_flushed; buf_t *inbuf; int inbuf_reached_eof; /* did read() return 0 on this conn? */ @@ -668,6 +669,8 @@ int _connection_mark_for_close(connection_t *conn, char reason); } \ } while (0) +void connection_expire_held_open(void); + int connection_create_listener(char *bindaddress, uint16_t bindport, int type); int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port); @@ -787,6 +790,7 @@ void connection_watch_events(connection_t *conn, short events); int connection_is_reading(connection_t *conn); void connection_stop_reading(connection_t *conn); void connection_start_reading(connection_t *conn); + int connection_is_writing(connection_t *conn); void connection_stop_writing(connection_t *conn); void connection_start_writing(connection_t *conn); |