mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
Clone fetch_var_cell_from_buf() for evbuffers.
This commit is contained in:
parent
0514917800
commit
4836014168
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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? */
|
||||
|
Loading…
Reference in New Issue
Block a user