[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Move the tls parts of buffers.c into buffers_tls.c
commit 150089cbd7445f76a5d29df7d33c15c3a1ada034
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Tue Aug 8 15:06:40 2017 -0400
Move the tls parts of buffers.c into buffers_tls.c
---
src/or/buffers.c | 181 +-----------------------------------------------
src/or/buffers.h | 27 ++++++--
src/or/buffers_tls.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++
src/or/buffers_tls.h | 19 +++++
src/or/connection.c | 1 +
src/or/include.am | 2 +
src/or/main.c | 1 +
src/test/test_buffers.c | 1 +
8 files changed, 222 insertions(+), 185 deletions(-)
diff --git a/src/or/buffers.c b/src/or/buffers.c
index ee888b42a..1a9144e14 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -27,7 +27,6 @@
#include "util.h"
#include "torint.h"
#include "torlog.h"
-#include "tortls.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -101,22 +100,6 @@
} while (0)
#endif
-/** Return the next character in <b>chunk</b> onto which data can be appended.
- * If the chunk is full, this might be off the end of chunk->mem. */
-static inline char *
-CHUNK_WRITE_PTR(chunk_t *chunk)
-{
- return chunk->data + chunk->datalen;
-}
-
-/** Return the number of bytes that can be written onto <b>chunk</b> without
- * running out of space. */
-static inline size_t
-CHUNK_REMAINING_CAPACITY(const chunk_t *chunk)
-{
- return (chunk->mem + chunk->memlen) - (chunk->data + chunk->datalen);
-}
-
/** Move all bytes stored in <b>chunk</b> to the front of <b>chunk</b>->mem,
* to free up space at the end. */
static inline void
@@ -183,9 +166,6 @@ chunk_grow(chunk_t *chunk, size_t sz)
return chunk;
}
-/** If a read onto the end of a chunk would be smaller than this number, then
- * just start a new chunk. */
-#define MIN_READ_LEN 8
/** Every chunk should take up at least this many bytes. */
#define MIN_CHUNK_ALLOC 256
/** No chunk should take up more than this many bytes. */
@@ -479,7 +459,7 @@ buf_copy(const buf_t *buf)
/** Append a new chunk with enough capacity to hold <b>capacity</b> bytes to
* the tail of <b>buf</b>. If <b>capped</b>, don't allocate a chunk bigger
* than MAX_CHUNK_ALLOC. */
-static chunk_t *
+chunk_t *
buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
{
chunk_t *chunk;
@@ -564,23 +544,6 @@ read_to_chunk(buf_t *buf, chunk_t *chunk, tor_socket_t fd, size_t at_most,
}
}
-/** As read_to_chunk(), but return (negative) error code on error, blocking,
- * or TLS, and the number of bytes read otherwise. */
-static inline int
-read_to_chunk_tls(buf_t *buf, chunk_t *chunk, tor_tls_t *tls,
- size_t at_most)
-{
- int read_result;
-
- tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most);
- read_result = tor_tls_read(tls, CHUNK_WRITE_PTR(chunk), at_most);
- if (read_result < 0)
- return read_result;
- buf->datalen += read_result;
- chunk->datalen += read_result;
- return read_result;
-}
-
/** Read from socket <b>s</b>, writing onto end of <b>buf</b>. Read at most
* <b>at_most</b> bytes, growing the buffer as necessary. If recv() returns 0
* (because of EOF), set *<b>reached_eof</b> to 1 and return 0. Return -1 on
@@ -633,67 +596,6 @@ read_to_buf(tor_socket_t s, size_t at_most, buf_t *buf, int *reached_eof,
return (int)total_read;
}
-/** As read_to_buf, but reads from a TLS connection, and returns a TLS
- * status value rather than the number of bytes read.
- *
- * Using TLS on OR connections complicates matters in two ways.
- *
- * First, a TLS stream has its own read buffer independent of the
- * connection's read buffer. (TLS needs to read an entire frame from
- * the network before it can decrypt any data. Thus, trying to read 1
- * byte from TLS can require that several KB be read from the network
- * and decrypted. The extra data is stored in TLS's decrypt buffer.)
- * Because the data hasn't been read by Tor (it's still inside the TLS),
- * this means that sometimes a connection "has stuff to read" even when
- * poll() didn't return POLLIN. The tor_tls_get_pending_bytes function is
- * used in connection.c to detect TLS objects with non-empty internal
- * buffers and read from them again.
- *
- * Second, the TLS stream's events do not correspond directly to network
- * events: sometimes, before a TLS stream can read, the network must be
- * ready to write -- or vice versa.
- */
-int
-read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf)
-{
- int r = 0;
- size_t total_read = 0;
-
- check_no_tls_errors();
-
- check();
-
- if (BUG(buf->datalen >= INT_MAX))
- return -1;
- if (BUG(buf->datalen >= INT_MAX - at_most))
- return -1;
-
- while (at_most > total_read) {
- size_t readlen = at_most - total_read;
- chunk_t *chunk;
- if (!buf->tail || CHUNK_REMAINING_CAPACITY(buf->tail) < MIN_READ_LEN) {
- chunk = buf_add_chunk_with_capacity(buf, at_most, 1);
- if (readlen > chunk->memlen)
- readlen = chunk->memlen;
- } else {
- size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail);
- chunk = buf->tail;
- if (cap < readlen)
- readlen = cap;
- }
-
- r = read_to_chunk_tls(buf, chunk, tls, readlen);
- check();
- if (r < 0)
- return r; /* Error */
- tor_assert(total_read+r < INT_MAX);
- total_read += r;
- if ((size_t)r < readlen) /* eof, block, or no more to read. */
- break;
- }
- return (int)total_read;
-}
-
/** Helper for flush_buf(): try to write <b>sz</b> bytes from chunk
* <b>chunk</b> of buffer <b>buf</b> onto socket <b>s</b>. On success, deduct
* the bytes written from *<b>buf_flushlen</b>. Return the number of bytes
@@ -728,43 +630,6 @@ flush_chunk(tor_socket_t s, buf_t *buf, chunk_t *chunk, size_t sz,
}
}
-/** Helper for flush_buf_tls(): try to write <b>sz</b> bytes from chunk
- * <b>chunk</b> of buffer <b>buf</b> onto socket <b>s</b>. (Tries to write
- * more if there is a forced pending write size.) On success, deduct the
- * bytes written from *<b>buf_flushlen</b>. Return the number of bytes
- * written on success, and a TOR_TLS error code on failure or blocking.
- */
-static inline int
-flush_chunk_tls(tor_tls_t *tls, buf_t *buf, chunk_t *chunk,
- size_t sz, size_t *buf_flushlen)
-{
- int r;
- size_t forced;
- char *data;
-
- forced = tor_tls_get_forced_write_size(tls);
- if (forced > sz)
- sz = forced;
- if (chunk) {
- data = chunk->data;
- tor_assert(sz <= chunk->datalen);
- } else {
- data = NULL;
- tor_assert(sz == 0);
- }
- r = tor_tls_write(tls, data, sz);
- if (r < 0)
- return r;
- if (*buf_flushlen > (size_t)r)
- *buf_flushlen -= r;
- else
- *buf_flushlen = 0;
- buf_remove_from_front(buf, r);
- log_debug(LD_NET,"flushed %d bytes, %d ready to flush, %d remain.",
- r,(int)*buf_flushlen,(int)buf->datalen);
- return r;
-}
-
/** Write data from <b>buf</b> to the socket <b>s</b>. Write at most
* <b>sz</b> bytes, decrement *<b>buf_flushlen</b> by
* the number of bytes actually written, and remove the written bytes
@@ -806,50 +671,6 @@ flush_buf(tor_socket_t s, buf_t *buf, size_t sz, size_t *buf_flushlen)
return (int)flushed;
}
-/** As flush_buf(), but writes data to a TLS connection. Can write more than
- * <b>flushlen</b> bytes.
- */
-int
-flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t flushlen,
- size_t *buf_flushlen)
-{
- int r;
- size_t flushed = 0;
- ssize_t sz;
- tor_assert(buf_flushlen);
- tor_assert(*buf_flushlen <= buf->datalen);
- tor_assert(flushlen <= *buf_flushlen);
- sz = (ssize_t) flushlen;
-
- /* we want to let tls write even if flushlen is zero, because it might
- * have a partial record pending */
- check_no_tls_errors();
-
- check();
- do {
- size_t flushlen0;
- if (buf->head) {
- if ((ssize_t)buf->head->datalen >= sz)
- flushlen0 = sz;
- else
- flushlen0 = buf->head->datalen;
- } else {
- flushlen0 = 0;
- }
-
- r = flush_chunk_tls(tls, buf, buf->head, flushlen0, buf_flushlen);
- check();
- if (r < 0)
- return r;
- flushed += r;
- sz -= r;
- if (r == 0) /* Can't flush any more now. */
- break;
- } while (sz > 0);
- tor_assert(flushed < INT_MAX);
- return (int)flushed;
-}
-
/** Append <b>string_len</b> bytes from <b>string</b> to the end of
* <b>buf</b>.
*
diff --git a/src/or/buffers.h b/src/or/buffers.h
index 35fa46593..77cc9ce0f 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -19,9 +19,7 @@
typedef struct buf_t buf_t;
-struct tor_tls_t;
struct tor_compress_state_t;
-struct ext_or_cmd_t;
buf_t *buf_new(void);
buf_t *buf_new_with_capacity(size_t size);
@@ -39,11 +37,8 @@ size_t buf_get_total_allocation(void);
int read_to_buf(tor_socket_t s, size_t at_most, buf_t *buf, int *reached_eof,
int *socket_error);
-int read_to_buf_tls(struct tor_tls_t *tls, size_t at_most, buf_t *buf);
int flush_buf(tor_socket_t s, buf_t *buf, size_t sz, size_t *buf_flushlen);
-int flush_buf_tls(struct tor_tls_t *tls, buf_t *buf, size_t sz,
- size_t *buf_flushlen);
int write_to_buf(const char *string, size_t string_len, buf_t *buf);
int write_to_buf_compress(buf_t *buf, struct tor_compress_state_t *state,
@@ -100,6 +95,28 @@ struct buf_t {
chunk_t *head; /**< First chunk in the list, or NULL for none. */
chunk_t *tail; /**< Last chunk in the list, or NULL for none. */
};
+
+chunk_t *buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped);
+/** If a read onto the end of a chunk would be smaller than this number, then
+ * just start a new chunk. */
+#define MIN_READ_LEN 8
+
+/** Return the number of bytes that can be written onto <b>chunk</b> without
+ * running out of space. */
+static inline size_t
+CHUNK_REMAINING_CAPACITY(const chunk_t *chunk)
+{
+ return (chunk->mem + chunk->memlen) - (chunk->data + chunk->datalen);
+}
+
+/** Return the next character in <b>chunk</b> onto which data can be appended.
+ * If the chunk is full, this might be off the end of chunk->mem. */
+static inline char *
+CHUNK_WRITE_PTR(chunk_t *chunk)
+{
+ return chunk->data + chunk->datalen;
+}
+
#endif
#endif
diff --git a/src/or/buffers_tls.c b/src/or/buffers_tls.c
new file mode 100644
index 000000000..e47073869
--- /dev/null
+++ b/src/or/buffers_tls.c
@@ -0,0 +1,175 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define BUFFERS_PRIVATE
+#include "orconfig.h"
+#include <stddef.h>
+#include "buffers.h"
+#include "buffers_tls.h"
+#include "compat.h"
+#include "compress.h"
+#include "util.h"
+#include "torint.h"
+#include "torlog.h"
+#include "tortls.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/** As read_to_chunk(), but return (negative) error code on error, blocking,
+ * or TLS, and the number of bytes read otherwise. */
+static inline int
+read_to_chunk_tls(buf_t *buf, chunk_t *chunk, tor_tls_t *tls,
+ size_t at_most)
+{
+ int read_result;
+
+ tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most);
+ read_result = tor_tls_read(tls, CHUNK_WRITE_PTR(chunk), at_most);
+ if (read_result < 0)
+ return read_result;
+ buf->datalen += read_result;
+ chunk->datalen += read_result;
+ return read_result;
+}
+
+/** As read_to_buf, but reads from a TLS connection, and returns a TLS
+ * status value rather than the number of bytes read.
+ *
+ * Using TLS on OR connections complicates matters in two ways.
+ *
+ * First, a TLS stream has its own read buffer independent of the
+ * connection's read buffer. (TLS needs to read an entire frame from
+ * the network before it can decrypt any data. Thus, trying to read 1
+ * byte from TLS can require that several KB be read from the network
+ * and decrypted. The extra data is stored in TLS's decrypt buffer.)
+ * Because the data hasn't been read by Tor (it's still inside the TLS),
+ * this means that sometimes a connection "has stuff to read" even when
+ * poll() didn't return POLLIN. The tor_tls_get_pending_bytes function is
+ * used in connection.c to detect TLS objects with non-empty internal
+ * buffers and read from them again.
+ *
+ * Second, the TLS stream's events do not correspond directly to network
+ * events: sometimes, before a TLS stream can read, the network must be
+ * ready to write -- or vice versa.
+ */
+int
+read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf)
+{
+ int r = 0;
+ size_t total_read = 0;
+
+ check_no_tls_errors();
+
+ if (BUG(buf->datalen >= INT_MAX))
+ return -1;
+ if (BUG(buf->datalen >= INT_MAX - at_most))
+ return -1;
+
+ while (at_most > total_read) {
+ size_t readlen = at_most - total_read;
+ chunk_t *chunk;
+ if (!buf->tail || CHUNK_REMAINING_CAPACITY(buf->tail) < MIN_READ_LEN) {
+ chunk = buf_add_chunk_with_capacity(buf, at_most, 1);
+ if (readlen > chunk->memlen)
+ readlen = chunk->memlen;
+ } else {
+ size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail);
+ chunk = buf->tail;
+ if (cap < readlen)
+ readlen = cap;
+ }
+
+ r = read_to_chunk_tls(buf, chunk, tls, readlen);
+ if (r < 0)
+ return r; /* Error */
+ tor_assert(total_read+r < INT_MAX);
+ total_read += r;
+ if ((size_t)r < readlen) /* eof, block, or no more to read. */
+ break;
+ }
+ return (int)total_read;
+}
+
+/** Helper for flush_buf_tls(): try to write <b>sz</b> bytes from chunk
+ * <b>chunk</b> of buffer <b>buf</b> onto socket <b>s</b>. (Tries to write
+ * more if there is a forced pending write size.) On success, deduct the
+ * bytes written from *<b>buf_flushlen</b>. Return the number of bytes
+ * written on success, and a TOR_TLS error code on failure or blocking.
+ */
+static inline int
+flush_chunk_tls(tor_tls_t *tls, buf_t *buf, chunk_t *chunk,
+ size_t sz, size_t *buf_flushlen)
+{
+ int r;
+ size_t forced;
+ char *data;
+
+ forced = tor_tls_get_forced_write_size(tls);
+ if (forced > sz)
+ sz = forced;
+ if (chunk) {
+ data = chunk->data;
+ tor_assert(sz <= chunk->datalen);
+ } else {
+ data = NULL;
+ tor_assert(sz == 0);
+ }
+ r = tor_tls_write(tls, data, sz);
+ if (r < 0)
+ return r;
+ if (*buf_flushlen > (size_t)r)
+ *buf_flushlen -= r;
+ else
+ *buf_flushlen = 0;
+ buf_remove_from_front(buf, r);
+ log_debug(LD_NET,"flushed %d bytes, %d ready to flush, %d remain.",
+ r,(int)*buf_flushlen,(int)buf->datalen);
+ return r;
+}
+
+/** As flush_buf(), but writes data to a TLS connection. Can write more than
+ * <b>flushlen</b> bytes.
+ */
+int
+flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t flushlen,
+ size_t *buf_flushlen)
+{
+ int r;
+ size_t flushed = 0;
+ ssize_t sz;
+ tor_assert(buf_flushlen);
+ tor_assert(*buf_flushlen <= buf->datalen);
+ tor_assert(flushlen <= *buf_flushlen);
+ sz = (ssize_t) flushlen;
+
+ /* we want to let tls write even if flushlen is zero, because it might
+ * have a partial record pending */
+ check_no_tls_errors();
+
+ do {
+ size_t flushlen0;
+ if (buf->head) {
+ if ((ssize_t)buf->head->datalen >= sz)
+ flushlen0 = sz;
+ else
+ flushlen0 = buf->head->datalen;
+ } else {
+ flushlen0 = 0;
+ }
+
+ r = flush_chunk_tls(tls, buf, buf->head, flushlen0, buf_flushlen);
+ if (r < 0)
+ return r;
+ flushed += r;
+ sz -= r;
+ if (r == 0) /* Can't flush any more now. */
+ break;
+ } while (sz > 0);
+ tor_assert(flushed < INT_MAX);
+ return (int)flushed;
+}
+
diff --git a/src/or/buffers_tls.h b/src/or/buffers_tls.h
new file mode 100644
index 000000000..4fce6c113
--- /dev/null
+++ b/src/or/buffers_tls.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_BUFFERS_TLS_H
+#define TOR_BUFFERS_TLS_H
+
+struct buf_t;
+struct tor_tls_t;
+
+int read_to_buf_tls(struct tor_tls_t *tls, size_t at_most,
+ struct buf_t *buf);
+int flush_buf_tls(struct tor_tls_t *tls, struct buf_t *buf, size_t sz,
+ size_t *buf_flushlen);
+
+#endif
+
diff --git a/src/or/connection.c b/src/or/connection.c
index 637b38cec..866ce5e0b 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -58,6 +58,7 @@
#include "or.h"
#include "bridges.h"
#include "buffers.h"
+#include "buffers_tls.h"
/*
* Define this so we get channel internal functions, since we're implementing
* part of a subclass (channel_tls_t).
diff --git a/src/or/include.am b/src/or/include.am
index fe860339f..6dc43749b 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -21,6 +21,7 @@ LIBTOR_A_SOURCES = \
src/or/addressmap.c \
src/or/bridges.c \
src/or/buffers.c \
+ src/or/buffers_tls.c \
src/or/channel.c \
src/or/channelpadding.c \
src/or/channeltls.c \
@@ -156,6 +157,7 @@ ORHEADERS = \
src/or/addressmap.h \
src/or/bridges.h \
src/or/buffers.h \
+ src/or/buffers_tls.h \
src/or/channel.h \
src/or/channelpadding.h \
src/or/channeltls.h \
diff --git a/src/or/main.c b/src/or/main.c
index 7939f1984..a9d4bdb6e 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -52,6 +52,7 @@
#include "backtrace.h"
#include "bridges.h"
#include "buffers.h"
+#include "buffers_tls.h"
#include "channel.h"
#include "channeltls.h"
#include "channelpadding.h"
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index 26c062597..d2d1223f3 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -7,6 +7,7 @@
#define PROTO_HTTP_PRIVATE
#include "or.h"
#include "buffers.h"
+#include "buffers_tls.h"
#include "ext_orport.h"
#include "proto_cell.h"
#include "proto_ext_or.h"
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits