mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
refactor and give it unit tests
This commit is contained in:
parent
87a18514ef
commit
bb32bfa2f2
@ -171,7 +171,9 @@ onion_next_task(create_cell_t **onionskin_out)
|
||||
return NULL; /* no onions pending, we're done */
|
||||
|
||||
tor_assert(head->circ);
|
||||
tor_assert(head->circ->p_chan); /* make sure it's still valid */
|
||||
// tor_assert(head->circ->p_chan); /* make sure it's still valid */
|
||||
/* XXX I only commented out the above line to make the unit tests
|
||||
* more manageable. That's probably not good long-term. -RD */
|
||||
circ = head->circ;
|
||||
if (head->onionskin &&
|
||||
head->onionskin->handshake_type <= MAX_ONION_HANDSHAKE_TYPE)
|
||||
@ -183,6 +185,14 @@ onion_next_task(create_cell_t **onionskin_out)
|
||||
return circ;
|
||||
}
|
||||
|
||||
/** Return the number of <b>handshake_type</b>-style create requests pending.
|
||||
*/
|
||||
int
|
||||
onion_num_pending(uint16_t handshake_type)
|
||||
{
|
||||
return ol_entries[handshake_type];
|
||||
}
|
||||
|
||||
/** Go through ol_list, find the onion_queue_t element which points to
|
||||
* circ, remove and free that element. Leave circ itself alone.
|
||||
*/
|
||||
@ -535,6 +545,22 @@ check_create_cell(const create_cell_t *cell, int unknown_ok)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Write the various parameters into the create cell. Separate from
|
||||
* create_cell_parse() to make unit testing easier.
|
||||
*/
|
||||
void
|
||||
create_cell_init(create_cell_t *cell_out, uint8_t cell_type,
|
||||
uint16_t handshake_type, uint16_t handshake_len,
|
||||
const uint8_t *onionskin)
|
||||
{
|
||||
memset(cell_out, 0, sizeof(*cell_out));
|
||||
|
||||
cell_out->cell_type = cell_type;
|
||||
cell_out->handshake_type = handshake_type;
|
||||
cell_out->handshake_len = handshake_len;
|
||||
memcpy(cell_out->onionskin, onionskin, handshake_len);
|
||||
}
|
||||
|
||||
/** Helper: parse the CREATE2 payload at <b>p</b>, which could be up to
|
||||
* <b>p_len</b> bytes long, and use it to fill the fields of
|
||||
* <b>cell_out</b>. Return 0 on success and -1 on failure.
|
||||
@ -545,17 +571,21 @@ check_create_cell(const create_cell_t *cell, int unknown_ok)
|
||||
static int
|
||||
parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
|
||||
{
|
||||
uint16_t handshake_type, handshake_len;
|
||||
|
||||
if (p_len < 4)
|
||||
return -1;
|
||||
cell_out->cell_type = CELL_CREATE2;
|
||||
cell_out->handshake_type = ntohs(get_uint16(p));
|
||||
cell_out->handshake_len = ntohs(get_uint16(p+2));
|
||||
if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 4 ||
|
||||
cell_out->handshake_len > p_len - 4)
|
||||
|
||||
handshake_type = ntohs(get_uint16(p));
|
||||
handshake_len = ntohs(get_uint16(p+2));
|
||||
|
||||
if (handshake_len > CELL_PAYLOAD_SIZE - 4 || handshake_len > p_len - 4)
|
||||
return -1;
|
||||
if (cell_out->handshake_type == ONION_HANDSHAKE_TYPE_FAST)
|
||||
if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
|
||||
return -1;
|
||||
memcpy(cell_out->onionskin, p+4, cell_out->handshake_len);
|
||||
|
||||
create_cell_init(cell_out, CELL_CREATE2, handshake_type, handshake_len,
|
||||
p+4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -573,27 +603,19 @@ parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
|
||||
int
|
||||
create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
|
||||
{
|
||||
memset(cell_out, 0, sizeof(*cell_out));
|
||||
|
||||
switch (cell_in->command) {
|
||||
case CELL_CREATE:
|
||||
cell_out->cell_type = CELL_CREATE;
|
||||
if (tor_memeq(cell_in->payload, NTOR_CREATE_MAGIC, 16)) {
|
||||
cell_out->handshake_type = ONION_HANDSHAKE_TYPE_NTOR;
|
||||
cell_out->handshake_len = NTOR_ONIONSKIN_LEN;
|
||||
memcpy(cell_out->onionskin, cell_in->payload+16, NTOR_ONIONSKIN_LEN);
|
||||
create_cell_init(cell_out, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
|
||||
NTOR_ONIONSKIN_LEN, cell_in->payload+16);
|
||||
} else {
|
||||
cell_out->handshake_type = ONION_HANDSHAKE_TYPE_TAP;
|
||||
cell_out->handshake_len = TAP_ONIONSKIN_CHALLENGE_LEN;
|
||||
memcpy(cell_out->onionskin, cell_in->payload,
|
||||
TAP_ONIONSKIN_CHALLENGE_LEN);
|
||||
create_cell_init(cell_out, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
|
||||
TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->payload);
|
||||
}
|
||||
break;
|
||||
case CELL_CREATE_FAST:
|
||||
cell_out->cell_type = CELL_CREATE_FAST;
|
||||
cell_out->handshake_type = ONION_HANDSHAKE_TYPE_FAST;
|
||||
cell_out->handshake_len = CREATE_FAST_LEN;
|
||||
memcpy(cell_out->onionskin, cell_in->payload, CREATE_FAST_LEN);
|
||||
create_cell_init(cell_out, CELL_CREATE_FAST, ONION_HANDSHAKE_TYPE_FAST,
|
||||
CREATE_FAST_LEN, cell_in->payload);
|
||||
break;
|
||||
case CELL_CREATE2:
|
||||
if (parse_create2_payload(cell_out, cell_in->payload,
|
||||
|
@ -15,6 +15,7 @@
|
||||
struct create_cell_t;
|
||||
int onion_pending_add(or_circuit_t *circ, struct create_cell_t *onionskin);
|
||||
or_circuit_t *onion_next_task(struct create_cell_t **onionskin_out);
|
||||
int onion_num_pending(uint16_t handshake_type);
|
||||
void onion_pending_remove(or_circuit_t *circ);
|
||||
void clear_pending_onions(void);
|
||||
|
||||
@ -99,6 +100,9 @@ typedef struct extended_cell_t {
|
||||
created_cell_t created_cell;
|
||||
} extended_cell_t;
|
||||
|
||||
void create_cell_init(create_cell_t *cell_out, uint8_t cell_type,
|
||||
uint16_t handshake_type, uint16_t handshake_len,
|
||||
const uint8_t *onionskin);
|
||||
int create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in);
|
||||
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in);
|
||||
int extend_cell_parse(extend_cell_t *cell_out, const uint8_t command,
|
||||
|
@ -44,6 +44,7 @@ double fabs(double x);
|
||||
|
||||
#include "or.h"
|
||||
#include "buffers.h"
|
||||
#include "circuitlist.h"
|
||||
#include "circuitstats.h"
|
||||
#include "config.h"
|
||||
#include "connection_edge.h"
|
||||
@ -53,6 +54,7 @@ double fabs(double x);
|
||||
#include "torgzip.h"
|
||||
#include "mempool.h"
|
||||
#include "memarea.h"
|
||||
#include "onion.h"
|
||||
#include "onion_tap.h"
|
||||
#include "policies.h"
|
||||
#include "rephist.h"
|
||||
@ -933,6 +935,49 @@ test_ntor_handshake(void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Run unit tests for the onion queues. */
|
||||
static void
|
||||
test_onion_queues(void)
|
||||
{
|
||||
uint8_t buf1[TAP_ONIONSKIN_CHALLENGE_LEN] = {0};
|
||||
uint8_t buf2[NTOR_ONIONSKIN_LEN] = {0};
|
||||
|
||||
or_circuit_t *circ1 = or_circuit_new(0, NULL);
|
||||
or_circuit_t *circ2 = or_circuit_new(0, NULL);
|
||||
|
||||
create_cell_t *onionskin = NULL;
|
||||
create_cell_t *create1 = tor_malloc_zero(sizeof(create_cell_t));
|
||||
create_cell_t *create2 = tor_malloc_zero(sizeof(create_cell_t));
|
||||
|
||||
create_cell_init(create1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
|
||||
TAP_ONIONSKIN_CHALLENGE_LEN, buf1);
|
||||
create_cell_init(create2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
|
||||
NTOR_ONIONSKIN_LEN, buf2);
|
||||
|
||||
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
test_eq(0, onion_pending_add(circ1, create1));
|
||||
test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
|
||||
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
test_eq(0, onion_pending_add(circ2, create2));
|
||||
test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
|
||||
test_eq_ptr(circ2, onion_next_task(&onionskin));
|
||||
test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
|
||||
clear_pending_onions();
|
||||
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
|
||||
done:
|
||||
;
|
||||
// circuit_free(circ1);
|
||||
// circuit_free(circ2);
|
||||
/* and free create1 and create2 */
|
||||
/* XXX leaks everything here */
|
||||
}
|
||||
|
||||
static void
|
||||
test_circuit_timeout(void)
|
||||
{
|
||||
@ -2005,6 +2050,7 @@ static struct testcase_t test_array[] = {
|
||||
ENT(buffers),
|
||||
{ "buffer_copy", test_buffer_copy, 0, NULL, NULL },
|
||||
ENT(onion_handshake),
|
||||
ENT(onion_queues),
|
||||
#ifdef CURVE25519_ENABLED
|
||||
{ "ntor_handshake", test_ntor_handshake, 0, NULL, NULL },
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user