[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master 07/38] Clone fetch_var_cell_from_buf() for evbuffers.



Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Fri, 31 Jul 2009 14:51:04 -0400
Subject: Clone fetch_var_cell_from_buf() for evbuffers.
Commit: 4836014168067dc4ded2285a04a69ea169bb95a9

---
 src/or/buffers.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/buffers.h |    4 ++
 src/or/or.h      |    2 -
 3 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/src/or/buffers.c b/src/or/buffers.c
index 5a34bd2..c038ba1 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -1008,6 +1008,98 @@ fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto)
   return 1;
 }
 
+#ifdef USE_BUFFEREVENTS
+static size_t
+inspect_evbuffer(struct evbuffer *buf, char **data, size_t n, int *free_out)
+{
+  int n_vecs, i;
+
+  if (evbuffer_get_length(buf) < n)
+    n = evbuffer_get_length(buf);
+  if (n == 0)
+    return 0;
+  n_vecs = evbuffer_peek(buf, n, NULL, NULL, 0);
+  if (n_vecs <= 0)
+    return -1;
+  if (n_vecs == 1) {
+    struct evbuffer_iovec v;
+    i = evbuffer_peek(buf, n, NULL, &v, 1);
+    tor_assert(i == 1);
+    *data = v.iov_base;
+    *free_out = 0;
+    return v.iov_len;
+  } else {
+    struct evbuffer_iovec *vecs =
+      tor_malloc(sizeof(struct evbuffer_iovec)*n_vecs);
+    size_t copied = 0;
+    i = evbuffer_peek(buf, n, NULL, vecs, n_vecs);
+    tor_assert(i == n_vecs);
+    *data = tor_malloc(n);
+    for (i=0; i < n_vecs; ++i) {
+      size_t copy = n - copied;
+      if (copy > vecs[i].iov_len)
+        copy = vecs[i].iov_len;
+      tor_assert(copied+copy <= n);
+      memcpy(data+copied, vecs[i].iov_base, copy);
+      copied += copy;
+    }
+    *free_out = 0;
+    return copied;
+  }
+}
+
+/** As fetch_var_cell_from_buf, buf works on an evbuffer. */
+int
+fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
+                             int linkproto)
+{
+  char *hdr = NULL;
+  int free_hdr = 0;
+  size_t n;
+  size_t buf_len;
+  uint8_t command;
+  uint16_t cell_length;
+  var_cell_t *cell;
+  int result;
+  if (linkproto == 1)
+    return 0;
+
+  *out = NULL;
+  buf_len = evbuffer_get_length(buf);
+  if (buf_len < VAR_CELL_HEADER_SIZE) {
+    result = 0;
+    goto done;
+  }
+  n = inspect_evbuffer(buf, &hdr, VAR_CELL_HEADER_SIZE, &free_hdr);
+  tor_assert(n == VAR_CELL_HEADER_SIZE);
+
+  command = get_uint8(hdr+2);
+  if (!(CELL_COMMAND_IS_VAR_LENGTH(command))) {
+    result = 0;
+    goto done;
+  }
+
+  cell_length = ntohs(get_uint16(hdr+3));
+  if (buf_len < (size_t)(VAR_CELL_HEADER_SIZE+cell_length)) {
+    result = 1; /* Not all here yet. */
+    goto done;
+  }
+
+  cell = var_cell_new(cell_length);
+  cell->command = command;
+  cell->circ_id = ntohs(get_uint16(hdr));
+  evbuffer_drain(buf, VAR_CELL_HEADER_SIZE);
+  evbuffer_remove(buf, cell->payload, cell_length);
+  *out = cell;
+  result = 1;
+
+ done:
+  if (free_hdr && hdr)
+    tor_free(hdr);
+  return result;
+}
+#endif
+
 /** Move up to *<b>buf_flushlen</b> bytes from <b>buf_in</b> to
  * <b>buf_out</b>, and modify *<b>buf_flushlen</b> appropriately.
  * Return the number of bytes actually copied.
diff --git a/src/or/buffers.h b/src/or/buffers.h
index 8fd403d..f4174e9 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -35,6 +35,10 @@ int write_to_buf(const char *string, size_t string_len, buf_t *buf);
 int write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
                       const char *data, size_t data_len, int done);
 int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
+#ifdef USE_BUFFEREVENTS
+int fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
+                                 int linkproto);
+#endif
 int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
 int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
 int fetch_from_buf_http(buf_t *buf,
diff --git a/src/or/or.h b/src/or/or.h
index 0246da8..e0c259b 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2974,8 +2974,6 @@ struct socks_request_t {
                               * every connection. */
 };
 
-/* all the function prototypes go here */
-
 /********************************* circuitbuild.c **********************/
 
 /** How many hops does a general-purpose circuit have by default? */
-- 
1.7.1