[tor-commits] [tor/master] Make buf_pullup() expose the pulled-up data.

nickm at torproject.org nickm at torproject.org
Tue Sep 5 18:18:13 UTC 2017


commit f28e314b0d5a6d4c677b87378cea70dc6524546b
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Aug 8 12:07:25 2017 -0400

    Make buf_pullup() expose the pulled-up data.
    
    This lets us drop the testing-only function buf_get_first_chunk_data(),
    and lets us implement proto_http and proto_socks without looking at
    buf_t internals.
---
 src/or/buffers.c        | 32 ++++++++++++++++----------------
 src/or/buffers.h        |  4 ++--
 src/or/proto_http.c     | 10 ++++------
 src/or/proto_socks.c    | 20 ++++++++++++--------
 src/test/test_buffers.c | 16 ++++++----------
 5 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/src/or/buffers.c b/src/or/buffers.c
index ef8676cd9..18517b999 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -203,22 +203,33 @@ preferred_chunk_size(size_t target)
 /** Collapse data from the first N chunks from <b>buf</b> into buf->head,
  * growing it as necessary, until buf->head has the first <b>bytes</b> bytes
  * of data from the buffer, or until buf->head has all the data in <b>buf</b>.
+ *
+ * Set *<b>head_out</b> to point to the first byte of available data, and
+ * *<b>len_out</b> to the number of bytes of data available at
+ * *<b>head_out</b>. Note that *<b>len_out</b> may be more or less than
+ * <b>bytes</b>, depending on the number of bytes available.
  */
 void
-buf_pullup(buf_t *buf, size_t bytes)
+buf_pullup(buf_t *buf, size_t bytes, const char **head_out, size_t *len_out)
 {
   chunk_t *dest, *src;
   size_t capacity;
-  if (!buf->head)
+  if (!buf->head) {
+    *head_out = NULL;
+    *len_out = 0;
     return;
+  }
 
   check();
   if (buf->datalen < bytes)
     bytes = buf->datalen;
 
   capacity = bytes;
-  if (buf->head->datalen >= bytes)
+  if (buf->head->datalen >= bytes) {
+    *head_out = buf->head->data;
+    *len_out = buf->head->datalen;
     return;
+  }
 
   if (buf->head->memlen >= capacity) {
     /* We don't need to grow the first chunk, but we might need to repack it.*/
@@ -263,22 +274,11 @@ buf_pullup(buf_t *buf, size_t bytes)
   }
 
   check();
+  *head_out = buf->head->data;
+  *len_out = buf->head->datalen;
 }
 
 #ifdef TOR_UNIT_TESTS
-/* Return the data from the first chunk of buf in cp, and its length in sz. */
-void
-buf_get_first_chunk_data(const buf_t *buf, const char **cp, size_t *sz)
-{
-  if (!buf || !buf->head) {
-    *cp = NULL;
-    *sz = 0;
-  } else {
-    *cp = buf->head->data;
-    *sz = buf->head->datalen;
-  }
-}
-
 /* Write sz bytes from cp into a newly allocated buffer buf.
  * Returns NULL when passed a NULL cp or zero sz.
  * Asserts on failure: only for use in unit tests.
diff --git a/src/or/buffers.h b/src/or/buffers.h
index 5a6f510f5..e710ac64a 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -55,11 +55,11 @@ int buf_set_to_copy(buf_t **output,
 void assert_buf_ok(buf_t *buf);
 
 int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
-void buf_pullup(buf_t *buf, size_t bytes);
+void buf_pullup(buf_t *buf, size_t bytes,
+                const char **head_out, size_t *len_out);
 
 #ifdef BUFFERS_PRIVATE
 #ifdef TOR_UNIT_TESTS
-void buf_get_first_chunk_data(const buf_t *buf, const char **cp, size_t *sz);
 buf_t *buf_new_with_data(const char *cp, size_t sz);
 #endif
 ATTR_UNUSED STATIC size_t preferred_chunk_size(size_t target);
diff --git a/src/or/proto_http.c b/src/or/proto_http.c
index a47644a30..3977de186 100644
--- a/src/or/proto_http.c
+++ b/src/or/proto_http.c
@@ -4,7 +4,6 @@
  * Copyright (c) 2007-2017, The Tor Project, Inc. */
 /* See LICENSE for licensing information */
 
-#define BUFFERS_PRIVATE // XXXX remove.
 #define PROTO_HTTP_PRIVATE
 #include "or.h"
 #include "buffers.h"
@@ -48,12 +47,12 @@ fetch_from_buf_http(buf_t *buf,
                     char **body_out, size_t *body_used, size_t max_bodylen,
                     int force_complete)
 {
-  char *headers;
+  const char *headers;
   size_t headerlen, bodylen, contentlen=0;
   int crlf_offset;
   int r;
 
-  if (!buf->head)
+  if (buf_datalen(buf) == 0)
     return 0;
 
   crlf_offset = buf_find_string_offset(buf, "\r\n\r\n", 4);
@@ -67,11 +66,10 @@ fetch_from_buf_http(buf_t *buf,
   }
   /* Okay, we have a full header.  Make sure it all appears in the first
    * chunk. */
-  if ((int)buf->head->datalen < crlf_offset + 4)
-    buf_pullup(buf, crlf_offset+4);
   headerlen = crlf_offset + 4;
+  size_t headers_in_chunk = 0;
+  buf_pullup(buf, headerlen, &headers, &headers_in_chunk);
 
-  headers = buf->head->data;
   bodylen = buf_datalen(buf) - headerlen;
   log_debug(LD_HTTP,"headerlen %d, bodylen %d.", (int)headerlen, (int)bodylen);
 
diff --git a/src/or/proto_socks.c b/src/or/proto_socks.c
index f1728bde3..7c7431cae 100644
--- a/src/or/proto_socks.c
+++ b/src/or/proto_socks.c
@@ -4,7 +4,6 @@
  * Copyright (c) 2007-2017, The Tor Project, Inc. */
 /* See LICENSE for licensing information */
 
-#define BUFFERS_PRIVATE // XXXX remove.
 #include "or.h"
 #include "addressmap.h"
 #include "buffers.h"
@@ -115,17 +114,19 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
   int res;
   ssize_t n_drain;
   size_t want_length = 128;
+  const char *head = NULL;
+  size_t datalen = 0;
 
   if (buf_datalen(buf) < 2) /* version and another byte */
     return 0;
 
   do {
     n_drain = 0;
-    buf_pullup(buf, want_length);
-    tor_assert(buf->head && buf->head->datalen >= 2);
+    buf_pullup(buf, want_length, &head, &datalen);
+    tor_assert(head && datalen >= 2);
     want_length = 0;
 
-    res = parse_socks(buf->head->data, buf->head->datalen, req, log_sockstype,
+    res = parse_socks(head, datalen, req, log_sockstype,
                       safe_socks, &n_drain, &want_length);
 
     if (n_drain < 0)
@@ -133,7 +134,7 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
     else if (n_drain > 0)
       buf_remove_from_front(buf, n_drain);
 
-  } while (res == 0 && buf->head && want_length < buf_datalen(buf) &&
+  } while (res == 0 && head && want_length < buf_datalen(buf) &&
            buf_datalen(buf) >= 2);
 
   return res;
@@ -591,13 +592,16 @@ fetch_from_buf_socks_client(buf_t *buf, int state, char **reason)
 {
   ssize_t drain = 0;
   int r;
+  const char *head = NULL;
+  size_t datalen = 0;
+
   if (buf_datalen(buf) < 2)
     return 0;
 
-  buf_pullup(buf, MAX_SOCKS_MESSAGE_LEN);
-  tor_assert(buf->head && buf->head->datalen >= 2);
+  buf_pullup(buf, MAX_SOCKS_MESSAGE_LEN, &head, &datalen);
+  tor_assert(head && datalen >= 2);
 
-  r = parse_socks_client((uint8_t*)buf->head->data, buf->head->datalen,
+  r = parse_socks_client((uint8_t*)head, datalen,
                          state, reason, &drain);
   if (drain > 0)
     buf_remove_from_front(buf, drain);
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index 3eb4ac2a3..49a1015d8 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -220,8 +220,7 @@ test_buffer_pullup(void *arg)
 
   /* There are a bunch of cases for pullup.  One is the trivial case. Let's
      mess around with an empty buffer. */
-  buf_pullup(buf, 16);
-  buf_get_first_chunk_data(buf, &cp, &sz);
+  buf_pullup(buf, 16, &cp, &sz);
   tt_ptr_op(cp, OP_EQ, NULL);
   tt_uint_op(sz, OP_EQ, 0);
 
@@ -234,7 +233,7 @@ test_buffer_pullup(void *arg)
   crypto_rand(stuff, 16384);
   write_to_buf(stuff, 3000, buf);
   write_to_buf(stuff+3000, 3000, buf);
-  buf_get_first_chunk_data(buf, &cp, &sz);
+  buf_pullup(buf, 0, &cp, &sz);
   tt_ptr_op(cp, OP_NE, NULL);
   tt_int_op(sz, OP_LE, 4096);
 
@@ -242,9 +241,8 @@ test_buffer_pullup(void *arg)
    * can get tested. */
   tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 3000);
   tt_mem_op(tmp,OP_EQ, stuff, 3000);
-  buf_pullup(buf, 2048);
+  buf_pullup(buf, 2048, &cp, &sz);
   assert_buf_ok(buf);
-  buf_get_first_chunk_data(buf, &cp, &sz);
   tt_ptr_op(cp, OP_NE, NULL);
   tt_int_op(sz, OP_GE, 2048);
   tt_mem_op(cp,OP_EQ, stuff+3000, 2048);
@@ -261,13 +259,12 @@ test_buffer_pullup(void *arg)
   write_to_buf(stuff+8000, 4000, buf);
   write_to_buf(stuff+12000, 4000, buf);
   tt_int_op(buf_datalen(buf), OP_EQ, 16000);
-  buf_get_first_chunk_data(buf, &cp, &sz);
+  buf_pullup(buf, 0, &cp, &sz);
   tt_ptr_op(cp, OP_NE, NULL);
   tt_int_op(sz, OP_LE, 4096);
 
-  buf_pullup(buf, 12500);
+  buf_pullup(buf, 12500, &cp, &sz);
   assert_buf_ok(buf);
-  buf_get_first_chunk_data(buf, &cp, &sz);
   tt_ptr_op(cp, OP_NE, NULL);
   tt_int_op(sz, OP_GE, 12500);
   tt_mem_op(cp,OP_EQ, stuff, 12500);
@@ -288,9 +285,8 @@ test_buffer_pullup(void *arg)
   write_to_buf(stuff, 4000, buf);
   write_to_buf(stuff+4000, 4000, buf);
   fetch_from_buf(tmp, 100, buf); /* dump 100 bytes from first chunk */
-  buf_pullup(buf, 16000); /* Way too much. */
+  buf_pullup(buf, 16000, &cp, &sz);
   assert_buf_ok(buf);
-  buf_get_first_chunk_data(buf, &cp, &sz);
   tt_ptr_op(cp, OP_NE, NULL);
   tt_int_op(sz, OP_EQ, 7900);
   tt_mem_op(cp,OP_EQ, stuff+100, 7900);





More information about the tor-commits mailing list