diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-20 09:50:53 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-20 09:50:53 -0400 |
commit | eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb (patch) | |
tree | b304aaca9b8d5364517d4ab23ffd232cf420858d /src/or/buffers.c | |
parent | 195bcb6150eeaebab31a44998e2c567d78f9b936 (diff) | |
parent | 9a7c16fb00c6ffc32ef7d6cc7fbede5258fe4390 (diff) | |
download | tor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.tar.gz tor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.zip |
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.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index e2b0bd0e6f..5b9e55ebd5 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 |