aboutsummaryrefslogtreecommitdiff
path: root/src/or/buffers.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-07-20 09:50:53 -0400
committerNick Mathewson <nickm@torproject.org>2011-07-20 09:50:53 -0400
commiteaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb (patch)
treeb304aaca9b8d5364517d4ab23ffd232cf420858d /src/or/buffers.c
parent195bcb6150eeaebab31a44998e2c567d78f9b936 (diff)
parent9a7c16fb00c6ffc32ef7d6cc7fbede5258fe4390 (diff)
downloadtor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.tar
tor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.tar.gz
Merge branch 'optimistic-client'
The conflicts are with the proposal 171 circuit isolation code, and they're all trivial: they're just a matter of both branches adding some unrelated code in the same places. Conflicts: src/or/circuituse.c src/or/connection.c
Diffstat (limited to 'src/or/buffers.c')
-rw-r--r--src/or/buffers.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c
index e2b0bd0e6..5b9e55ebd 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -557,6 +557,39 @@ buf_free(buf_t *buf)
tor_free(buf);
}
+/** Return a new copy of <b>in_chunk</b> */
+static chunk_t *
+chunk_copy(const chunk_t *in_chunk)
+{
+ chunk_t *newch = tor_memdup(in_chunk, CHUNK_ALLOC_SIZE(in_chunk->memlen));
+ newch->next = NULL;
+ if (in_chunk->data) {
+ off_t offset = in_chunk->data - in_chunk->mem;
+ newch->data = newch->mem + offset;
+ }
+ return newch;
+}
+
+/** Return a new copy of <b>buf</b> */
+buf_t *
+buf_copy(const buf_t *buf)
+{
+ chunk_t *ch;
+ buf_t *out = buf_new();
+ out->default_chunk_size = buf->default_chunk_size;
+ for (ch = buf->head; ch; ch = ch->next) {
+ chunk_t *newch = chunk_copy(ch);
+ if (out->tail) {
+ out->tail->next = newch;
+ out->tail = newch;
+ } else {
+ out->head = out->tail = newch;
+ }
+ }
+ out->datalen = buf->datalen;
+ return out;
+}
+
/** 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. */
@@ -2374,6 +2407,43 @@ write_to_evbuffer_zlib(struct evbuffer *buf, tor_zlib_state_t *state,
}
#endif
+/** Set *<b>output</b> to contain a copy of the data in *<b>input</b> */
+int
+generic_buffer_set_to_copy(generic_buffer_t **output,
+ const generic_buffer_t *input)
+{
+#ifdef USE_BUFFEREVENTS
+ struct evbuffer_ptr ptr;
+ size_t remaining = evbuffer_get_length(input);
+ if (*output) {
+ evbuffer_drain(*output, evbuffer_get_length(*output));
+ } else {
+ if (!(*output = evbuffer_new()))
+ return -1;
+ }
+ evbuffer_ptr_set((struct evbuffer*)input, &ptr, 0, EVBUFFER_PTR_SET);
+ while (remaining) {
+ struct evbuffer_iovec v[4];
+ int n_used, i;
+ n_used = evbuffer_peek((struct evbuffer*)input, -1, &ptr, v, 4);
+ if (n_used < 0)
+ return -1;
+ for (i=0;i<n_used;++i) {
+ evbuffer_add(*output, v[i].iov_base, v[i].iov_len);
+ tor_assert(v[i].iov_len <= remaining);
+ remaining -= v[i].iov_len;
+ evbuffer_ptr_set((struct evbuffer*)input,
+ &ptr, v[i].iov_len, EVBUFFER_PTR_ADD);
+ }
+ }
+#else
+ if (*output)
+ buf_free(*output);
+ *output = buf_copy(input);
+#endif
+ return 0;
+}
+
/** Log an error and exit if <b>buf</b> is corrupted.
*/
void