summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-02-27 04:42:14 +0000
committerRoger Dingledine <arma@torproject.org>2004-02-27 04:42:14 +0000
commit195dfd35a80685a1cc545a5a308a588bd2b12220 (patch)
treeb967b8271b10d6d8355626f3ba73ef4c93675bc7
parentfeafba073dc06ae3deb2e716923f3ec2907115dc (diff)
downloadtor-195dfd35a80685a1cc545a5a308a588bd2b12220.tar.gz
tor-195dfd35a80685a1cc545a5a308a588bd2b12220.zip
Fix a bug where you might flush some data on a tls connection, and then
add some more data to be flushed but never turn POLLOUT on. not sure how commonly this bug was hit, but it would be a doozy. Also add some asserts to see if it happens elsewhere. svn:r1142
-rw-r--r--src/or/connection.c15
-rw-r--r--src/or/main.c4
-rw-r--r--src/or/or.h1
3 files changed, 16 insertions, 4 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 4d7933696d..1e9876f8c5 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -506,7 +506,7 @@ int connection_handle_write(connection_t *conn) {
} else {
if(flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen) < 0)
return -1;
- /* conns in CONNECTING state will fall through... */
+ /* conns in CONNECTING state will fall through... */
}
if(!connection_wants_to_flush(conn)) /* it's done flushing */
@@ -527,9 +527,8 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) {
return;
}
- /* XXX if linkpadding, this only applies to conns that aren't open OR connections */
connection_start_writing(conn);
-#define MIN_TLS_FLUSHLEN 16300
+#define MIN_TLS_FLUSHLEN 15872
/* openssl tls record size is 16383, this is close. The goal here is to
* push data out as soon as we know there's enough for a tls record, so
* during periods of high load we won't read the entire megabyte from
@@ -544,7 +543,11 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) {
log_fn(LOG_WARN,"flushing failed.");
}
}
- conn->outbuf_flushlen += len;
+ if(len > 0) { /* if there's any left over */
+ conn->outbuf_flushlen += len;
+ connection_start_writing(conn);
+ /* because connection_handle_write() above might have stopped writing */
+ }
}
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) {
@@ -758,6 +761,10 @@ void assert_connection_ok(connection_t *conn, time_t now)
assert(conn->type >= _CONN_TYPE_MIN);
assert(conn->type <= _CONN_TYPE_MAX);
+ if(conn->outbuf_flushlen > 0) {
+ assert(connection_is_writing(conn) || conn->wants_to_write);
+ }
+
/* XXX check: wants_to_read, wants_to_write, s, poll_index,
* marked_for_close. */
diff --git a/src/or/main.c b/src/or/main.c
index 9abb8aef2b..7a394fd5af 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -136,6 +136,10 @@ void connection_start_reading(connection_t *conn) {
poll_array[conn->poll_index].events |= POLLIN;
}
+int connection_is_writing(connection_t *conn) {
+ return poll_array[conn->poll_index].events & POLLOUT;
+}
+
void connection_stop_writing(connection_t *conn) {
assert(conn && conn->poll_index < nfds);
diff --git a/src/or/or.h b/src/or/or.h
index 3aff946379..d7cd00cdb5 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -748,6 +748,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);