Commit f039eca6 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Stop trying to flush on broken sockets marked for close.


svn:r1163
parent 80410fa8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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)
{
+18 −5
Original line number Diff line number Diff line
@@ -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;
  }
+3 −3
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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)                                  \