diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-08-08 12:07:25 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-09-05 13:57:51 -0400 |
commit | f28e314b0d5a6d4c677b87378cea70dc6524546b (patch) | |
tree | a119ec5ccaa8343618cacb3bacc125da69d20c60 /src | |
parent | cddac959e7fb5729956a5250351e0fa1289d719f (diff) | |
download | tor-f28e314b0d5a6d4c677b87378cea70dc6524546b.tar.gz tor-f28e314b0d5a6d4c677b87378cea70dc6524546b.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/or/buffers.c | 32 | ||||
-rw-r--r-- | src/or/buffers.h | 4 | ||||
-rw-r--r-- | src/or/proto_http.c | 10 | ||||
-rw-r--r-- | src/or/proto_socks.c | 20 | ||||
-rw-r--r-- | 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 ef8676cd9d..18517b999f 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 5a6f510f53..e710ac64a4 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 a47644a30a..3977de1866 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 f1728bde36..7c7431caea 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 3eb4ac2a35..49a1015d82 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); |