Commit 05149178 authored by Nick Mathewson's avatar Nick Mathewson 🐘
Browse files

Add a new connection_fetch_from_buf_line() that can handle bufferevents

parent 54485014
Loading
Loading
Loading
Loading
+6 −6
Changes for src/or/buffers.c: 6 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -1755,12 +1755,12 @@ buf_find_offset_of_char(buf_t *buf, char ch)
  return -1;
}

/** Try to read a single LF-terminated line from <b>buf</b>, and write it,
 * NUL-terminated, into the *<b>data_len</b> byte buffer at <b>data_out</b>.
 * Set *<b>data_len</b> to the number of bytes in the line, not counting the
 * terminating NUL.  Return 1 if we read a whole line, return 0 if we don't
 * have a whole line yet, and return -1 if the line length exceeds
 * *<b>data_len</b>.
/** Try to read a single LF-terminated line from <b>buf</b>, and write it
 * (including the LF), NUL-terminated, into the *<b>data_len</b> byte buffer
 * at <b>data_out</b>.  Set *<b>data_len</b> to the number of bytes in the
 * line, not counting the terminating NUL.  Return 1 if we read a whole line,
 * return 0 if we don't have a whole line yet, and return -1 if the line
 * length exceeds *<b>data_len</b>.
 */
int
fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len)
+26 −0
Changes for src/or/connection.c: 26 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -2616,6 +2616,32 @@ connection_fetch_from_buf(char *string, size_t len, connection_t *conn)
  }
}

/** As fetch_from_buf_line(), but read from a connection's input buffer. */
int
connection_fetch_from_buf_line(connection_t *conn, char *data,
                               size_t *data_len)
{
  IF_HAS_BUFFEREVENT(conn, {
    int r;
    size_t eol_len=0;
    struct evbuffer *input = bufferevent_get_input(conn->bufev);
    struct evbuffer_ptr ptr =
      evbuffer_search_eol(input, NULL, &eol_len, EVBUFFER_EOL_LF);
    if (ptr.pos == -1)
      return 0; /* No EOL found. */
    if ((size_t)ptr.pos+eol_len >= *data_len) {
      return -1; /* Too long */
    }
    *data_len = ptr.pos+eol_len;
    r = evbuffer_remove(input, data, ptr.pos+eol_len);
    tor_assert(r >= 0);
    data[ptr.pos+eol_len] = '\0';
    return 1;
  }) ELSE_IF_NO_BUFFEREVENT {
    return fetch_from_buf_line(conn->inbuf, data, data_len);
  }
}

/** Return conn-\>outbuf_flushlen: how many bytes conn wants to flush
 * from its outbuf. */
int
+2 −0
Changes for src/or/connection.h: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ void connection_bucket_refill(int seconds_elapsed, time_t now);
int connection_handle_read(connection_t *conn);

int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
int connection_fetch_from_buf_line(connection_t *conn, char *data,
                                   size_t *data_len);

int connection_wants_to_flush(connection_t *conn);
int connection_outbuf_too_full(connection_t *conn);
+1 −1
Changes for src/or/connection_edge.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -1997,7 +1997,7 @@ connection_ap_process_natd(edge_connection_t *conn)

  /* look for LF-terminated "[DEST ip_addr port]"
   * where ip_addr is a dotted-quad and port is in string form */
  err = fetch_from_buf_line(conn->_base.inbuf, tmp_buf, &tlen);
  err = connection_fetch_from_buf_line(TO_CONN(conn), tmp_buf, &tlen);
  if (err == 0)
    return 0;
  if (err < 0) {
+1 −1
Changes for src/or/control.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -2801,7 +2801,7 @@ connection_control_process_inbuf(control_connection_t *conn)
    /* First, fetch a line. */
    do {
      data_len = conn->incoming_cmd_len - conn->incoming_cmd_cur_len;
      r = fetch_from_buf_line(conn->_base.inbuf,
      r = connection_fetch_from_buf_line(TO_CONN(conn),
                              conn->incoming_cmd+conn->incoming_cmd_cur_len,
                              &data_len);
      if (r == 0)