aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/connection.c37
-rw-r--r--src/or/directory.c2
-rw-r--r--src/or/dirserv.c22
-rw-r--r--src/or/or.h4
4 files changed, 54 insertions, 11 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 479fc00b1..451f21ea2 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1595,6 +1595,43 @@ connection_write_to_buf(const char *string, size_t len, connection_t *conn)
conn->outbuf_flushlen += len;
}
+void
+connection_write_to_buf_zlib(connection_t *conn,
+ tor_zlib_state_t *state,
+ const char *data, size_t data_len,
+ int done)
+{
+ int r;
+ if (!data_len)
+ return;
+ /* if it's marked for close, only allow write if we mean to flush it */
+ if (conn->marked_for_close && !conn->hold_open_until_flushed)
+ return;
+
+ /* XXXX TOO much duplicate code! XXXX012NM */
+ CONN_LOG_PROTECT(conn, r = write_to_buf_zlib(
+ conn->outbuf, state, data, data_len,
+ done));
+ if (r < 0) {
+ if (CONN_IS_EDGE(conn)) {
+ /* if it failed, it means we have our package/delivery windows set
+ wrong compared to our max outbuf size. close the whole circuit. */
+ log_warn(LD_NET,
+ "write_to_buf failed. Closing circuit (fd %d).", conn->s);
+ circuit_mark_for_close(circuit_get_by_edge_conn(conn),
+ END_CIRC_REASON_INTERNAL);
+ } else {
+ log_warn(LD_NET,
+ "write_to_buf failed. Closing connection (fd %d).", conn->s);
+ connection_mark_for_close(conn);
+ }
+ return;
+ }
+
+ connection_start_writing(conn);
+ conn->outbuf_flushlen += data_len;
+}
+
/** Return the conn to addr/port that has the most recent
* timestamp_created, or NULL if no such conn exists. */
connection_t *
diff --git a/src/or/directory.c b/src/or/directory.c
index 2aaa9f2c4..16ec51081 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1413,7 +1413,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
connection_write_to_buf(tmp, strlen(tmp), conn);
conn->cached_dir = d;
conn->cached_dir_offset = 0;
- if (deflated)
+ if (! deflated)
conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
++d->refcnt;
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e31434585..8788d2f21 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1771,19 +1771,21 @@ connection_dirserv_add_servers_to_outbuf(connection_t *conn)
if (!sd)
continue;
if (conn->zlib_state) {
- write_to_buf_zlib(conn->outbuf, conn->zlib_state,
+ connection_write_to_buf_zlib(
+ conn, conn->zlib_state,
sd->signed_descriptor_body, sd->signed_descriptor_len,
0);
} else {
- write_to_buf(sd->signed_descriptor_body, sd->signed_descriptor_len,
- conn->outbuf);
+ connection_write_to_buf(sd->signed_descriptor_body,
+ sd->signed_descriptor_len,
+ conn);
}
}
if (!smartlist_len(conn->fingerprint_stack)) {
/* We just wrote the last one; finish up. */
if (conn->zlib_state) {
- write_to_buf_zlib(conn->outbuf, conn->zlib_state, "", 0, 1);
+ connection_write_to_buf_zlib(conn, conn->zlib_state, "", 0, 1);
tor_zlib_free(conn->zlib_state);
conn->zlib_state = NULL;
}
@@ -1809,18 +1811,18 @@ connection_dirserv_add_dir_bytes_to_outbuf(connection_t *conn)
bytes = remaining;
if (conn->zlib_state) {
- write_to_buf_zlib(conn->outbuf, conn->zlib_state,
- conn->cached_dir->dir_z + conn->cached_dir_offset,
- bytes, bytes == remaining);
+ connection_write_to_buf_zlib(conn, conn->zlib_state,
+ conn->cached_dir->dir_z + conn->cached_dir_offset,
+ bytes, bytes == remaining);
} else {
- write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
- bytes, conn->outbuf);
+ connection_write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
+ bytes, conn);
}
conn->cached_dir_offset += bytes;
if (bytes == (int)conn->cached_dir->dir_z_len) {
/* We just wrote the last one; finish up. */
if (conn->zlib_state) {
- write_to_buf_zlib(conn->outbuf, conn->zlib_state, "", 0, 1);
+ connection_write_to_buf_zlib(conn, conn->zlib_state, "", 0, 1);
tor_zlib_free(conn->zlib_state);
conn->zlib_state = NULL;
}
diff --git a/src/or/or.h b/src/or/or.h
index f30115ba3..08527e066 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1679,6 +1679,10 @@ int connection_handle_write(connection_t *conn);
void _connection_controller_force_write(connection_t *conn);
void connection_write_to_buf(const char *string, size_t len,
connection_t *conn);
+void connection_write_to_buf_zlib(connection_t *conn,
+ tor_zlib_state_t *state,
+ const char *data, size_t data_len,
+ int done);
connection_t *connection_or_exact_get_by_addr_port(uint32_t addr,
uint16_t port);