summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-04-08 03:36:39 +0000
committerNick Mathewson <nickm@torproject.org>2005-04-08 03:36:39 +0000
commit74dc7eedc510d70ea600dd5938f45947a314bc24 (patch)
tree3c3cd636c2b88314e3adaa7e5b17e096dca09c22
parent31c12e265fbd135aba4c335da48ceb5a80f2859e (diff)
downloadtor-74dc7eedc510d70ea600dd5938f45947a314bc24.tar.gz
tor-74dc7eedc510d70ea600dd5938f45947a314bc24.zip
Add kludgy function to force controllers to flush EVENT_ERR_MSG events.
svn:r4057
-rw-r--r--src/or/connection.c34
-rw-r--r--src/or/control.c3
-rw-r--r--src/or/or.h1
3 files changed, 38 insertions, 0 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 1775f122e7..c19c9b9dd0 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1265,6 +1265,40 @@ int connection_handle_write(connection_t *conn) {
return 0;
}
+/* DOCDOC */
+void _connection_controller_force_write(connection_t *conn)
+{
+ /* XXX 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;
+ tor_assert(conn);
+ tor_assert(!conn->tls);
+ tor_assert(conn->type == CONN_TYPE_CONTROL);
+ if (conn->marked_for_close || conn->s < 0)
+ return;
+
+ result = flush_buf(conn->s, conn->outbuf, &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 && !is_local_IP(conn->addr)) { /* remember it */
+ rep_hist_note_bytes_written(result, time(NULL));
+ global_write_bucket -= result;
+ }
+
+ 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/control.c b/src/or/control.c
index 514ff0c6bd..d85d315067 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -330,6 +330,9 @@ send_control_event(uint16_t event, uint32_t len, const char *body)
conns[i]->state == CONTROL_CONN_STATE_OPEN &&
conns[i]->event_mask & (1<<event)) {
send_control_message(conns[i], CONTROL_CMD_EVENT, buflen, buf);
+ if (event == EVENT_ERR_MSG) {
+ _connection_controller_force_write(conns[i]);
+ }
}
}
diff --git a/src/or/or.h b/src/or/or.h
index 5f7c2823a2..853025e425 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1283,6 +1283,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(connection_t *conn);
void connection_write_to_buf(const char *string, size_t len, connection_t *conn);
connection_t *connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port);