summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-02-28 19:14:11 +0000
committerNick Mathewson <nickm@torproject.org>2004-02-28 19:14:11 +0000
commitf039eca6581cc92a8c4b69ff6c413517cebb4aab (patch)
tree365e6ea7268e033783d1a5416b95f4c58394fd72
parent80410fa8dc1db2421c1b0b116ced2e52ecd8b705 (diff)
downloadtor-f039eca6581cc92a8c4b69ff6c413517cebb4aab.tar.gz
tor-f039eca6581cc92a8c4b69ff6c413517cebb4aab.zip
Stop trying to flush on broken sockets marked for close.
svn:r1163
-rw-r--r--src/or/buffers.c4
-rw-r--r--src/or/connection.c23
-rw-r--r--src/or/main.c6
-rw-r--r--src/or/or.h3
4 files changed, 27 insertions, 9 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c
index 071edad89d..40d6b04d87 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -132,6 +132,10 @@ buf_t *buf_new()
return buf_new_with_capacity(INITIAL_BUF_SIZE);
}
+void buf_clear(buf_t *buf)
+{
+ buf->datalen = 0;
+}
size_t buf_datalen(const buf_t *buf)
{
diff --git a/src/or/connection.c b/src/or/connection.c
index e4b99a4bfa..9c0ac58e14 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -141,6 +141,22 @@ void connection_free_all(void) {
connection_free(carray[i]);
}
+/* Close the underlying socket for conn, so we don't try to flush it.
+ * Must be used in conjunction with connection_mark_for_close
+ */
+void connection_close_immediate(connection_t *conn)
+{
+ assert_connection_ok(conn,0);
+ if (conn->s < 0) {
+ log_fn(LOG_WARN,"Attempt to close already-closed connection.");
+ return;
+ }
+ close(conn->s);
+ conn->s = -1;
+ buf_clear(conn->outbuf);
+ conn->outbuf_flushlen = 0;
+}
+
int
_connection_mark_for_close(connection_t *conn, char reason)
{
@@ -355,8 +371,7 @@ static void listener_close_if_present(int type) {
type == CONN_TYPE_DIR_LISTENER);
conn = connection_get_by_type(type);
if (conn) {
- close(conn->s);
- conn->s = -1;
+ connection_close_immediate(conn);
connection_mark_for_close(conn,0);
}
}
@@ -414,9 +429,7 @@ int connection_handle_read(connection_t *conn) {
router_mark_as_down(conn->nickname);
}
/* There's a read error; kill the connection.*/
- /* XXX This is the place. We need to somehow indicate to
- * conn that it should never try to flush, or do anything
- * with conn->s but close it. */
+ connection_close_immediate(conn); /* Don't flush; connection is dead. */
connection_mark_for_close(conn, END_STREAM_REASON_MISC);
return -1;
}
diff --git a/src/or/main.c b/src/or/main.c
index 8e701341d3..2dacb013d9 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -221,10 +221,10 @@ static void conn_close_if_marked(int i) {
assert_connection_ok(conn, time(NULL));
if(conn->marked_for_close) {
log_fn(LOG_INFO,"Cleaning up connection (fd %d).",conn->s);
- if(conn->s >= 0) { /* -1 means it's an incomplete edge connection */
+ if(conn->s >= 0) {
+ /* -1 means it's an incomplete edge connection, or that the socket
+ * has already been closed as unflushable. */
/* FIXME there's got to be a better way to check for this -- and make other checks? */
-/* XXX the below two calls to flush_buf should not happen if the
- * conn got hung up on. */
if(connection_speaks_cells(conn)) {
if(conn->state == OR_CONN_STATE_OPEN)
flush_buf_tls(conn->tls, conn->outbuf, &conn->outbuf_flushlen);
diff --git a/src/or/or.h b/src/or/or.h
index 369d0da8b3..0231cbf606 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -549,6 +549,7 @@ int find_on_inbuf(char *string, int string_len, buf_t *buf);
buf_t *buf_new();
buf_t *buf_new_with_capacity(size_t size);
void buf_free(buf_t *buf);
+void buf_clear(buf_t *buf);
size_t buf_datalen(const buf_t *buf);
size_t buf_capacity(const buf_t *buf);
@@ -637,7 +638,7 @@ int getconfig(int argc, char **argv, or_options_t *options);
connection_t *connection_new(int type);
void connection_free(connection_t *conn);
void connection_free_all(void);
-
+void connection_close_immediate(connection_t *conn);
int _connection_mark_for_close(connection_t *conn, char reason);
#define connection_mark_for_close(c,r) \