Clone fetch_var_cell_from_buf() for evbuffers.

This commit is contained in:
Nick Mathewson 2009-07-31 14:51:04 -04:00
parent 0514917800
commit 4836014168
3 changed files with 96 additions and 2 deletions

View File

@ -1008,6 +1008,98 @@ fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto)
return 1;
}
#ifdef USE_BUFFEREVENTS
static size_t
inspect_evbuffer(struct evbuffer *buf, char **data, size_t n, int *free_out)
{
int n_vecs, i;
if (evbuffer_get_length(buf) < n)
n = evbuffer_get_length(buf);
if (n == 0)
return 0;
n_vecs = evbuffer_peek(buf, n, NULL, NULL, 0);
if (n_vecs <= 0)
return -1;
if (n_vecs == 1) {
struct evbuffer_iovec v;
i = evbuffer_peek(buf, n, NULL, &v, 1);
tor_assert(i == 1);
*data = v.iov_base;
*free_out = 0;
return v.iov_len;
} else {
struct evbuffer_iovec *vecs =
tor_malloc(sizeof(struct evbuffer_iovec)*n_vecs);
size_t copied = 0;
i = evbuffer_peek(buf, n, NULL, vecs, n_vecs);
tor_assert(i == n_vecs);
*data = tor_malloc(n);
for (i=0; i < n_vecs; ++i) {
size_t copy = n - copied;
if (copy > vecs[i].iov_len)
copy = vecs[i].iov_len;
tor_assert(copied+copy <= n);
memcpy(data+copied, vecs[i].iov_base, copy);
copied += copy;
}
*free_out = 0;
return copied;
}
}
/** As fetch_var_cell_from_buf, buf works on an evbuffer. */
int
fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
int linkproto)
{
char *hdr = NULL;
int free_hdr = 0;
size_t n;
size_t buf_len;
uint8_t command;
uint16_t cell_length;
var_cell_t *cell;
int result;
if (linkproto == 1)
return 0;
*out = NULL;
buf_len = evbuffer_get_length(buf);
if (buf_len < VAR_CELL_HEADER_SIZE) {
result = 0;
goto done;
}
n = inspect_evbuffer(buf, &hdr, VAR_CELL_HEADER_SIZE, &free_hdr);
tor_assert(n == VAR_CELL_HEADER_SIZE);
command = get_uint8(hdr+2);
if (!(CELL_COMMAND_IS_VAR_LENGTH(command))) {
result = 0;
goto done;
}
cell_length = ntohs(get_uint16(hdr+3));
if (buf_len < (size_t)(VAR_CELL_HEADER_SIZE+cell_length)) {
result = 1; /* Not all here yet. */
goto done;
}
cell = var_cell_new(cell_length);
cell->command = command;
cell->circ_id = ntohs(get_uint16(hdr));
evbuffer_drain(buf, VAR_CELL_HEADER_SIZE);
evbuffer_remove(buf, cell->payload, cell_length);
*out = cell;
result = 1;
done:
if (free_hdr && hdr)
tor_free(hdr);
return result;
}
#endif
/** Move up to *<b>buf_flushlen</b> bytes from <b>buf_in</b> to
* <b>buf_out</b>, and modify *<b>buf_flushlen</b> appropriately.
* Return the number of bytes actually copied.

View File

@ -35,6 +35,10 @@ int write_to_buf(const char *string, size_t string_len, buf_t *buf);
int write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
const char *data, size_t data_len, int done);
int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
#ifdef USE_BUFFEREVENTS
int fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
int linkproto);
#endif
int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
int fetch_from_buf_http(buf_t *buf,

View File

@ -2974,8 +2974,6 @@ struct socks_request_t {
* every connection. */
};
/* all the function prototypes go here */
/********************************* circuitbuild.c **********************/
/** How many hops does a general-purpose circuit have by default? */