mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-01 08:03:31 +01:00
Teach cpuworker and others about create_cell_t and friends
The unit of work sent to a cpuworker is now a create_cell_t; its response is now a created_cell_t. Several of the things that call or get called by this chain of logic now take create_cell_t or created_cell_t too. Since all cpuworkers are forked or spawned by Tor, they don't need a stable wire protocol, so we can just send structs. This saves us some insanity, and helps p
This commit is contained in:
parent
5d15d597a9
commit
2802ccaeb6
@ -1359,7 +1359,7 @@ entry_guard_inc_first_hop_count(entry_guard_t *guard)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A created or extended cell came back to us on the circuit, and it included
|
/** A created or extended cell came back to us on the circuit, and it included
|
||||||
* <b>reply</b> as its body. (If <b>reply_type</b> is CELL_CREATED, the body
|
* reply_cell as its body. (If <b>reply_type</b> is CELL_CREATED, the body
|
||||||
* contains (the second DH key, plus KH). If <b>reply_type</b> is
|
* contains (the second DH key, plus KH). If <b>reply_type</b> is
|
||||||
* CELL_CREATED_FAST, the body contains a secret y and a hash H(x|y).)
|
* CELL_CREATED_FAST, the body contains a secret y and a hash H(x|y).)
|
||||||
*
|
*
|
||||||
@ -1369,8 +1369,8 @@ entry_guard_inc_first_hop_count(entry_guard_t *guard)
|
|||||||
* Return - reason if we want to mark circ for close, else return 0.
|
* Return - reason if we want to mark circ for close, else return 0.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type,
|
circuit_finish_handshake(origin_circuit_t *circ,
|
||||||
const uint8_t *reply)
|
const created_cell_t *reply)
|
||||||
{
|
{
|
||||||
char keys[CPATH_KEY_MATERIAL_LEN];
|
char keys[CPATH_KEY_MATERIAL_LEN];
|
||||||
crypt_path_t *hop;
|
crypt_path_t *hop;
|
||||||
@ -1391,23 +1391,9 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type,
|
|||||||
tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS);
|
tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS);
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t handshake_type = 0xffff;
|
if (onion_skin_client_handshake(hop->handshake_state.tag,
|
||||||
if (reply_type == CELL_CREATED)
|
|
||||||
handshake_type = ONION_HANDSHAKE_TYPE_TAP;
|
|
||||||
else if (reply_type == CELL_CREATED_FAST)
|
|
||||||
handshake_type = ONION_HANDSHAKE_TYPE_FAST;
|
|
||||||
|
|
||||||
if (handshake_type != hop->handshake_state.tag) {
|
|
||||||
log_warn(LD_PROTOCOL,"CREATED cell onionskin type (%u) did not "
|
|
||||||
"match CREATE cell onionskin type (%u).",
|
|
||||||
(unsigned)handshake_type,
|
|
||||||
(unsigned) hop->handshake_state.tag);
|
|
||||||
return -END_CIRC_REASON_TORPROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onion_skin_client_handshake(handshake_type,
|
|
||||||
&hop->handshake_state,
|
&hop->handshake_state,
|
||||||
reply,
|
reply->reply, reply->handshake_len,
|
||||||
(uint8_t*)keys, sizeof(keys),
|
(uint8_t*)keys, sizeof(keys),
|
||||||
(uint8_t*)hop->rend_circ_nonce) < 0) {
|
(uint8_t*)hop->rend_circ_nonce) < 0) {
|
||||||
log_warn(LD_CIRC,"onion_skin_client_handshake failed.");
|
log_warn(LD_CIRC,"onion_skin_client_handshake failed.");
|
||||||
@ -1422,8 +1408,7 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hop->state = CPATH_STATE_OPEN;
|
hop->state = CPATH_STATE_OPEN;
|
||||||
log_info(LD_CIRC,"Finished building %scircuit hop:",
|
log_info(LD_CIRC,"Finished building circuit hop:");
|
||||||
(reply_type == CELL_CREATED_FAST) ? "fast " : "");
|
|
||||||
circuit_log_path(LOG_INFO,LD_CIRC,circ);
|
circuit_log_path(LOG_INFO,LD_CIRC,circ);
|
||||||
control_event_circuit_status(circ, CIRC_EVENT_EXTENDED, 0);
|
control_event_circuit_status(circ, CIRC_EVENT_EXTENDED, 0);
|
||||||
|
|
||||||
@ -1484,7 +1469,8 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
|
onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
|
||||||
size_t payload_len, const char *keys)
|
size_t payload_len, const char *keys,
|
||||||
|
const uint8_t *rend_circ_nonce)
|
||||||
{
|
{
|
||||||
cell_t cell;
|
cell_t cell;
|
||||||
crypt_path_t *tmp_cpath;
|
crypt_path_t *tmp_cpath;
|
||||||
@ -1515,11 +1501,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
|
|||||||
tmp_cpath->magic = 0;
|
tmp_cpath->magic = 0;
|
||||||
tor_free(tmp_cpath);
|
tor_free(tmp_cpath);
|
||||||
|
|
||||||
/* XXXX Move responsibility for extracting this. */
|
memcpy(circ->rend_circ_nonce, rend_circ_nonce, DIGEST_LEN);
|
||||||
if (cell_type == CELL_CREATED)
|
|
||||||
memcpy(circ->rend_circ_nonce, cell.payload+DH_KEY_LEN, DIGEST_LEN);
|
|
||||||
else
|
|
||||||
memcpy(circ->rend_circ_nonce, cell.payload+DIGEST_LEN, DIGEST_LEN);
|
|
||||||
|
|
||||||
circ->is_first_hop = (cell_type == CELL_CREATED_FAST);
|
circ->is_first_hop = (cell_type == CELL_CREATED_FAST);
|
||||||
|
|
||||||
|
@ -30,13 +30,15 @@ void circuit_note_clock_jumped(int seconds_elapsed);
|
|||||||
int circuit_extend(cell_t *cell, circuit_t *circ);
|
int circuit_extend(cell_t *cell, circuit_t *circ);
|
||||||
int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
||||||
int reverse);
|
int reverse);
|
||||||
int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type,
|
struct created_cell_t;
|
||||||
const uint8_t *reply);
|
int circuit_finish_handshake(origin_circuit_t *circ,
|
||||||
|
const struct created_cell_t *created_cell);
|
||||||
int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer,
|
int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer,
|
||||||
int reason);
|
int reason);
|
||||||
int onionskin_answer(or_circuit_t *circ, uint8_t cell_type,
|
int onionskin_answer(or_circuit_t *circ, uint8_t cell_type,
|
||||||
const char *payload, size_t payload_len,
|
const char *payload, size_t payload_len,
|
||||||
const char *keys);
|
const char *keys,
|
||||||
|
const uint8_t *rend_circ_nonce);
|
||||||
int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
|
int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
|
||||||
int *need_capacity);
|
int *need_capacity);
|
||||||
|
|
||||||
|
@ -29,9 +29,7 @@
|
|||||||
#include "cpuworker.h"
|
#include "cpuworker.h"
|
||||||
#include "hibernate.h"
|
#include "hibernate.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
//#include "onion.h"
|
#include "onion.h"
|
||||||
#include "onion_tap.h"
|
|
||||||
#include "onion_fast.h"
|
|
||||||
#include "relay.h"
|
#include "relay.h"
|
||||||
#include "router.h"
|
#include "router.h"
|
||||||
#include "routerlist.h"
|
#include "routerlist.h"
|
||||||
@ -189,6 +187,7 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
|||||||
or_circuit_t *circ;
|
or_circuit_t *circ;
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
int id_is_high;
|
int id_is_high;
|
||||||
|
create_cell_t *create_cell;
|
||||||
|
|
||||||
tor_assert(cell);
|
tor_assert(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
@ -254,12 +253,18 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
|||||||
circ = or_circuit_new(cell->circ_id, chan);
|
circ = or_circuit_new(cell->circ_id, chan);
|
||||||
circ->base_.purpose = CIRCUIT_PURPOSE_OR;
|
circ->base_.purpose = CIRCUIT_PURPOSE_OR;
|
||||||
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);
|
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);
|
||||||
if (cell->command == CELL_CREATE) {
|
create_cell = tor_malloc_zero(sizeof(create_cell_t));
|
||||||
char *onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN);
|
if (create_cell_parse(create_cell, cell) < 0) {
|
||||||
memcpy(onionskin, cell->payload, TAP_ONIONSKIN_CHALLENGE_LEN);
|
tor_free(create_cell);
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
|
"Bogus/unrecognized create cell; closing.");
|
||||||
|
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create_cell->handshake_type != ONION_HANDSHAKE_TYPE_FAST) {
|
||||||
/* hand it off to the cpuworkers, and then return. */
|
/* hand it off to the cpuworkers, and then return. */
|
||||||
if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) {
|
if (assign_onionskin_to_cpuworker(NULL, circ, create_cell) < 0) {
|
||||||
log_debug(LD_GENERAL,"Failed to hand off onionskin. Closing.");
|
log_debug(LD_GENERAL,"Failed to hand off onionskin. Closing.");
|
||||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
|
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
|
||||||
return;
|
return;
|
||||||
@ -268,27 +273,35 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
|||||||
} else {
|
} else {
|
||||||
/* This is a CREATE_FAST cell; we can handle it immediately without using
|
/* This is a CREATE_FAST cell; we can handle it immediately without using
|
||||||
* a CPU worker. */
|
* a CPU worker. */
|
||||||
char keys[CPATH_KEY_MATERIAL_LEN];
|
uint8_t keys[CPATH_KEY_MATERIAL_LEN];
|
||||||
char reply[DIGEST_LEN*2];
|
uint8_t reply[MAX_ONIONSKIN_REPLY_LEN];
|
||||||
|
uint8_t rend_circ_nonce[DIGEST_LEN];
|
||||||
tor_assert(cell->command == CELL_CREATE_FAST);
|
int len;
|
||||||
|
|
||||||
/* Make sure we never try to use the OR connection on which we
|
/* Make sure we never try to use the OR connection on which we
|
||||||
* received this cell to satisfy an EXTEND request, */
|
* received this cell to satisfy an EXTEND request, */
|
||||||
channel_mark_client(chan);
|
channel_mark_client(chan);
|
||||||
|
|
||||||
if (fast_server_handshake(cell->payload, (uint8_t*)reply,
|
len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_FAST,
|
||||||
(uint8_t*)keys, sizeof(keys))<0) {
|
create_cell->onionskin,
|
||||||
|
create_cell->handshake_len,
|
||||||
|
NULL,
|
||||||
|
reply, keys, CPATH_KEY_MATERIAL_LEN,
|
||||||
|
rend_circ_nonce);
|
||||||
|
tor_free(create_cell);
|
||||||
|
if (len < 0) {
|
||||||
log_warn(LD_OR,"Failed to generate key material. Closing.");
|
log_warn(LD_OR,"Failed to generate key material. Closing.");
|
||||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
||||||
|
tor_free(create_cell);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (onionskin_answer(circ, CELL_CREATED_FAST, reply, sizeof(reply),
|
if (onionskin_answer(circ, CELL_CREATED_FAST, (const char *)reply, len,
|
||||||
keys)<0) {
|
(const char *)keys, rend_circ_nonce)<0) {
|
||||||
log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing.");
|
log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing.");
|
||||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memwipe(keys, 0, sizeof(keys));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +317,7 @@ static void
|
|||||||
command_process_created_cell(cell_t *cell, channel_t *chan)
|
command_process_created_cell(cell_t *cell, channel_t *chan)
|
||||||
{
|
{
|
||||||
circuit_t *circ;
|
circuit_t *circ;
|
||||||
|
extended_cell_t extended_cell;
|
||||||
|
|
||||||
circ = circuit_get_by_circid_channel(cell->circ_id, chan);
|
circ = circuit_get_by_circid_channel(cell->circ_id, chan);
|
||||||
|
|
||||||
@ -321,12 +335,18 @@ command_process_created_cell(cell_t *cell, channel_t *chan)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (created_cell_parse(&extended_cell.created_cell, cell) < 0) {
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_OR, "Unparseable created cell.");
|
||||||
|
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (CIRCUIT_IS_ORIGIN(circ)) { /* we're the OP. Handshake this. */
|
if (CIRCUIT_IS_ORIGIN(circ)) { /* we're the OP. Handshake this. */
|
||||||
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
||||||
int err_reason = 0;
|
int err_reason = 0;
|
||||||
log_debug(LD_OR,"at OP. Finishing handshake.");
|
log_debug(LD_OR,"at OP. Finishing handshake.");
|
||||||
if ((err_reason = circuit_finish_handshake(origin_circ, cell->command,
|
if ((err_reason = circuit_finish_handshake(origin_circ,
|
||||||
cell->payload)) < 0) {
|
&extended_cell.created_cell)) < 0) {
|
||||||
log_warn(LD_OR,"circuit_finish_handshake failed.");
|
log_warn(LD_OR,"circuit_finish_handshake failed.");
|
||||||
circuit_mark_for_close(circ, -err_reason);
|
circuit_mark_for_close(circ, -err_reason);
|
||||||
return;
|
return;
|
||||||
@ -339,11 +359,24 @@ command_process_created_cell(cell_t *cell, channel_t *chan)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else { /* pack it into an extended relay cell, and send it. */
|
} else { /* pack it into an extended relay cell, and send it. */
|
||||||
|
uint8_t command=0;
|
||||||
|
uint16_t len=0;
|
||||||
|
uint8_t payload[RELAY_PAYLOAD_SIZE];
|
||||||
log_debug(LD_OR,
|
log_debug(LD_OR,
|
||||||
"Converting created cell to extended relay cell, sending.");
|
"Converting created cell to extended relay cell, sending.");
|
||||||
relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED,
|
memset(payload, 0, sizeof(payload));
|
||||||
(char*)cell->payload, TAP_ONIONSKIN_REPLY_LEN,
|
if (extended_cell.created_cell.cell_type == CELL_CREATED2)
|
||||||
NULL);
|
extended_cell.cell_type = RELAY_COMMAND_EXTENDED2;
|
||||||
|
else
|
||||||
|
extended_cell.cell_type = RELAY_COMMAND_EXTENDED;
|
||||||
|
if (extended_cell_format(&command, &len, payload, &extended_cell) < 0) {
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_OR, "Can't format extended cell.");
|
||||||
|
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
relay_send_command_from_edge(0, circ, command,
|
||||||
|
(const char*)payload, len, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "cpuworker.h"
|
#include "cpuworker.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "onion.h"
|
#include "onion.h"
|
||||||
#include "onion_tap.h"
|
|
||||||
#include "router.h"
|
#include "router.h"
|
||||||
|
|
||||||
/** The maximum number of cpuworker processes we will keep around. */
|
/** The maximum number of cpuworker processes we will keep around. */
|
||||||
@ -33,9 +32,6 @@
|
|||||||
|
|
||||||
/** The tag specifies which circuit this onionskin was from. */
|
/** The tag specifies which circuit this onionskin was from. */
|
||||||
#define TAG_LEN 10
|
#define TAG_LEN 10
|
||||||
/** How many bytes are sent from the cpuworker back to tor? */
|
|
||||||
#define LEN_ONION_RESPONSE \
|
|
||||||
(1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN)
|
|
||||||
|
|
||||||
/** How many cpuworkers we have running right now. */
|
/** How many cpuworkers we have running right now. */
|
||||||
static int num_cpuworkers=0;
|
static int num_cpuworkers=0;
|
||||||
@ -71,7 +67,7 @@ connection_cpu_finished_flushing(connection_t *conn)
|
|||||||
/** Pack global_id and circ_id; set *tag to the result. (See note on
|
/** Pack global_id and circ_id; set *tag to the result. (See note on
|
||||||
* cpuworker_main for wire format.) */
|
* cpuworker_main for wire format.) */
|
||||||
static void
|
static void
|
||||||
tag_pack(char *tag, uint64_t chan_id, circid_t circ_id)
|
tag_pack(uint8_t *tag, uint64_t chan_id, circid_t circ_id)
|
||||||
{
|
{
|
||||||
/*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
|
/*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
|
||||||
/*XXXX DOUBLEPLUSTHIS!!!! AS AS AS AS*/
|
/*XXXX DOUBLEPLUSTHIS!!!! AS AS AS AS*/
|
||||||
@ -82,12 +78,38 @@ tag_pack(char *tag, uint64_t chan_id, circid_t circ_id)
|
|||||||
/** Unpack <b>tag</b> into addr, port, and circ_id.
|
/** Unpack <b>tag</b> into addr, port, and circ_id.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
tag_unpack(const char *tag, uint64_t *chan_id, circid_t *circ_id)
|
tag_unpack(const uint8_t *tag, uint64_t *chan_id, circid_t *circ_id)
|
||||||
{
|
{
|
||||||
*chan_id = get_uint64(tag);
|
*chan_id = get_uint64(tag);
|
||||||
*circ_id = get_uint16(tag+8);
|
*circ_id = get_uint16(tag+8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
#define CPUWORKER_REQUEST_MAGIC 0xda4afeed
|
||||||
|
#define CPUWORKER_REPLY_MAGIC 0x5eedf00d
|
||||||
|
|
||||||
|
/**DOCDOC*/
|
||||||
|
typedef struct cpuworker_request_t {
|
||||||
|
uint32_t magic;
|
||||||
|
/** Opaque tag to identify the job */
|
||||||
|
uint8_t tag[TAG_LEN];
|
||||||
|
uint8_t task;
|
||||||
|
|
||||||
|
create_cell_t create_cell;
|
||||||
|
/* Turn the above into a tagged union if needed. */
|
||||||
|
} cpuworker_request_t;
|
||||||
|
|
||||||
|
/**DOCDOC*/
|
||||||
|
typedef struct cpuworker_reply_t {
|
||||||
|
uint32_t magic;
|
||||||
|
uint8_t tag[TAG_LEN];
|
||||||
|
uint8_t success;
|
||||||
|
|
||||||
|
created_cell_t created_cell;
|
||||||
|
uint8_t keys[CPATH_KEY_MATERIAL_LEN];
|
||||||
|
uint8_t rend_auth_material[DIGEST_LEN];
|
||||||
|
} cpuworker_reply_t;
|
||||||
|
|
||||||
/** Called when the onion key has changed and we need to spawn new
|
/** Called when the onion key has changed and we need to spawn new
|
||||||
* cpuworkers. Close all currently idle cpuworkers, and mark the last
|
* cpuworkers. Close all currently idle cpuworkers, and mark the last
|
||||||
* rotation time as now.
|
* rotation time as now.
|
||||||
@ -133,8 +155,6 @@ connection_cpu_reached_eof(connection_t *conn)
|
|||||||
int
|
int
|
||||||
connection_cpu_process_inbuf(connection_t *conn)
|
connection_cpu_process_inbuf(connection_t *conn)
|
||||||
{
|
{
|
||||||
char success;
|
|
||||||
char buf[LEN_ONION_RESPONSE];
|
|
||||||
uint64_t chan_id;
|
uint64_t chan_id;
|
||||||
circid_t circ_id;
|
circid_t circ_id;
|
||||||
channel_t *p_chan = NULL;
|
channel_t *p_chan = NULL;
|
||||||
@ -147,15 +167,16 @@ connection_cpu_process_inbuf(connection_t *conn)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (conn->state == CPUWORKER_STATE_BUSY_ONION) {
|
if (conn->state == CPUWORKER_STATE_BUSY_ONION) {
|
||||||
if (connection_get_inbuf_len(conn) < LEN_ONION_RESPONSE)
|
cpuworker_reply_t rpl;
|
||||||
|
if (connection_get_inbuf_len(conn) < sizeof(cpuworker_reply_t))
|
||||||
return 0; /* not yet */
|
return 0; /* not yet */
|
||||||
tor_assert(connection_get_inbuf_len(conn) == LEN_ONION_RESPONSE);
|
tor_assert(connection_get_inbuf_len(conn) == sizeof(cpuworker_reply_t));
|
||||||
|
|
||||||
connection_fetch_from_buf(&success,1,conn);
|
connection_fetch_from_buf((void*)&rpl,sizeof(cpuworker_reply_t),conn);
|
||||||
connection_fetch_from_buf(buf,LEN_ONION_RESPONSE-1,conn);
|
|
||||||
|
|
||||||
|
tor_assert(rpl.magic == CPUWORKER_REPLY_MAGIC);
|
||||||
/* parse out the circ it was talking about */
|
/* parse out the circ it was talking about */
|
||||||
tag_unpack(buf, &chan_id, &circ_id);
|
tag_unpack(rpl.tag, &chan_id, &circ_id);
|
||||||
circ = NULL;
|
circ = NULL;
|
||||||
log_debug(LD_OR,
|
log_debug(LD_OR,
|
||||||
"Unpacking cpuworker reply, chan_id is " U64_FORMAT
|
"Unpacking cpuworker reply, chan_id is " U64_FORMAT
|
||||||
@ -166,7 +187,7 @@ connection_cpu_process_inbuf(connection_t *conn)
|
|||||||
if (p_chan)
|
if (p_chan)
|
||||||
circ = circuit_get_by_circid_channel(circ_id, p_chan);
|
circ = circuit_get_by_circid_channel(circ_id, p_chan);
|
||||||
|
|
||||||
if (success == 0) {
|
if (rpl.success == 0) {
|
||||||
log_debug(LD_OR,
|
log_debug(LD_OR,
|
||||||
"decoding onionskin failed. "
|
"decoding onionskin failed. "
|
||||||
"(Old key or bad software.) Closing.");
|
"(Old key or bad software.) Closing.");
|
||||||
@ -184,9 +205,12 @@ connection_cpu_process_inbuf(connection_t *conn)
|
|||||||
goto done_processing;
|
goto done_processing;
|
||||||
}
|
}
|
||||||
tor_assert(! CIRCUIT_IS_ORIGIN(circ));
|
tor_assert(! CIRCUIT_IS_ORIGIN(circ));
|
||||||
if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN,
|
if (onionskin_answer(TO_OR_CIRCUIT(circ),
|
||||||
TAP_ONIONSKIN_REPLY_LEN,
|
rpl.created_cell.cell_type,
|
||||||
buf+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN) < 0) {
|
(const char*)rpl.created_cell.reply,
|
||||||
|
rpl.created_cell.handshake_len,
|
||||||
|
(const char*)rpl.keys,
|
||||||
|
rpl.rend_auth_material) < 0) {
|
||||||
log_warn(LD_OR,"onionskin_answer failed. Closing.");
|
log_warn(LD_OR,"onionskin_answer failed. Closing.");
|
||||||
circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
|
circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
|
||||||
goto done_processing;
|
goto done_processing;
|
||||||
@ -213,32 +237,21 @@ connection_cpu_process_inbuf(connection_t *conn)
|
|||||||
* Read and writes from fdarray[1]. Reads requests, writes answers.
|
* Read and writes from fdarray[1]. Reads requests, writes answers.
|
||||||
*
|
*
|
||||||
* Request format:
|
* Request format:
|
||||||
* Task type [1 byte, always CPUWORKER_TASK_ONION]
|
* cpuworker_request_t.
|
||||||
* Opaque tag TAG_LEN
|
|
||||||
* Onionskin challenge TAP_ONIONSKIN_CHALLENGE_LEN
|
|
||||||
* Response format:
|
* Response format:
|
||||||
* Success/failure [1 byte, boolean.]
|
* cpuworker_reply_t
|
||||||
* Opaque tag TAG_LEN
|
|
||||||
* Onionskin challenge TAP_ONIONSKIN_REPLY_LEN
|
|
||||||
* Negotiated keys KEY_LEN*2+DIGEST_LEN*2
|
|
||||||
*
|
|
||||||
* (Note: this _should_ be by addr/port, since we're concerned with specific
|
|
||||||
* connections, not with routers (where we'd use identity).)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
cpuworker_main(void *data)
|
cpuworker_main(void *data)
|
||||||
{
|
{
|
||||||
char question[TAP_ONIONSKIN_CHALLENGE_LEN];
|
/* For talking to the parent thread/process */
|
||||||
uint8_t question_type;
|
|
||||||
tor_socket_t *fdarray = data;
|
tor_socket_t *fdarray = data;
|
||||||
tor_socket_t fd;
|
tor_socket_t fd;
|
||||||
|
|
||||||
/* variables for onion processing */
|
/* variables for onion processing */
|
||||||
char keys[CPATH_KEY_MATERIAL_LEN];
|
|
||||||
char reply_to_proxy[MAX_ONIONSKIN_REPLY_LEN];
|
|
||||||
char buf[LEN_ONION_RESPONSE];
|
|
||||||
char tag[TAG_LEN];
|
|
||||||
server_onion_keys_t onion_keys;
|
server_onion_keys_t onion_keys;
|
||||||
|
cpuworker_request_t req;
|
||||||
|
cpuworker_reply_t rpl;
|
||||||
|
|
||||||
fd = fdarray[1]; /* this side is ours */
|
fd = fdarray[1]; /* this side is ours */
|
||||||
#ifndef TOR_IS_MULTITHREADED
|
#ifndef TOR_IS_MULTITHREADED
|
||||||
@ -252,65 +265,64 @@ cpuworker_main(void *data)
|
|||||||
setup_server_onion_keys(&onion_keys);
|
setup_server_onion_keys(&onion_keys);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t r;
|
if (read_all(fd, (void *)&req, sizeof(req), 1) != sizeof(req)) {
|
||||||
|
log_info(LD_OR, "read request failed. Exiting.");
|
||||||
if ((r = recv(fd, (void *)&question_type, 1, 0)) != 1) {
|
|
||||||
// log_fn(LOG_ERR,"read type failed. Exiting.");
|
|
||||||
if (r == 0) {
|
|
||||||
log_info(LD_OR,
|
|
||||||
"CPU worker exiting because Tor process closed connection "
|
|
||||||
"(either rotated keys or died).");
|
|
||||||
} else {
|
|
||||||
log_info(LD_OR,
|
|
||||||
"CPU worker exiting because of error on connection to Tor "
|
|
||||||
"process.");
|
|
||||||
log_info(LD_OR,"(Error on %d was %s)",
|
|
||||||
fd, tor_socket_strerror(tor_socket_errno(fd)));
|
|
||||||
}
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
tor_assert(question_type == CPUWORKER_TASK_ONION);
|
tor_assert(req.magic == CPUWORKER_REQUEST_MAGIC);
|
||||||
|
|
||||||
if (read_all(fd, tag, TAG_LEN, 1) != TAG_LEN) {
|
memset(&rpl, 0, sizeof(rpl));
|
||||||
log_err(LD_BUG,"read tag failed. Exiting.");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read_all(fd, question, TAP_ONIONSKIN_CHALLENGE_LEN, 1) !=
|
if (req.task == CPUWORKER_TASK_ONION) {
|
||||||
TAP_ONIONSKIN_CHALLENGE_LEN) {
|
const create_cell_t *cc = &req.create_cell;
|
||||||
log_err(LD_BUG,"read question failed. Exiting.");
|
created_cell_t *cell_out = &rpl.created_cell;
|
||||||
goto end;
|
int n;
|
||||||
}
|
n = onion_skin_server_handshake(cc->handshake_type,
|
||||||
|
cc->onionskin, cc->handshake_len,
|
||||||
if (question_type == CPUWORKER_TASK_ONION) {
|
|
||||||
if (onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_TAP,
|
|
||||||
(const uint8_t*)question,
|
|
||||||
&onion_keys,
|
&onion_keys,
|
||||||
(uint8_t*)reply_to_proxy,
|
cell_out->reply,
|
||||||
(uint8_t*)keys, CPATH_KEY_MATERIAL_LEN) < 0) {
|
rpl.keys, CPATH_KEY_MATERIAL_LEN,
|
||||||
|
rpl.rend_auth_material);
|
||||||
|
if (n < 0) {
|
||||||
/* failure */
|
/* failure */
|
||||||
log_debug(LD_OR,"onion_skin_server_handshake failed.");
|
log_debug(LD_OR,"onion_skin_server_handshake failed.");
|
||||||
*buf = 0; /* indicate failure in first byte */
|
memset(&rpl, 0, sizeof(rpl));
|
||||||
memcpy(buf+1,tag,TAG_LEN);
|
memcpy(rpl.tag, req.tag, TAG_LEN);
|
||||||
/* send all zeros as answer */
|
rpl.success = 0;
|
||||||
memset(buf+1+TAG_LEN, 0, LEN_ONION_RESPONSE-(1+TAG_LEN));
|
|
||||||
} else {
|
} else {
|
||||||
/* success */
|
/* success */
|
||||||
log_debug(LD_OR,"onion_skin_server_handshake succeeded.");
|
log_debug(LD_OR,"onion_skin_server_handshake succeeded.");
|
||||||
buf[0] = 1; /* 1 means success */
|
memcpy(rpl.tag, req.tag, TAG_LEN);
|
||||||
memcpy(buf+1,tag,TAG_LEN);
|
cell_out->handshake_len = n;
|
||||||
memcpy(buf+1+TAG_LEN,reply_to_proxy,TAP_ONIONSKIN_REPLY_LEN);
|
switch (cc->cell_type) {
|
||||||
memcpy(buf+1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN,keys,
|
case CELL_CREATE:
|
||||||
CPATH_KEY_MATERIAL_LEN);
|
cell_out->cell_type = CELL_CREATED; break;
|
||||||
|
case CELL_CREATE2:
|
||||||
|
cell_out->cell_type = CELL_CREATED2; break;
|
||||||
|
case CELL_CREATE_FAST:
|
||||||
|
cell_out->cell_type = CELL_CREATED_FAST; break;
|
||||||
|
default:
|
||||||
|
tor_assert(0);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) {
|
rpl.success = 1;
|
||||||
|
}
|
||||||
|
rpl.magic = CPUWORKER_REPLY_MAGIC;
|
||||||
|
if (write_all(fd, (void*)&rpl, sizeof(rpl), 1) != sizeof(rpl)) {
|
||||||
log_err(LD_BUG,"writing response buf failed. Exiting.");
|
log_err(LD_BUG,"writing response buf failed. Exiting.");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
log_debug(LD_OR,"finished writing response.");
|
log_debug(LD_OR,"finished writing response.");
|
||||||
|
} else if (req.task == CPUWORKER_TASK_SHUTDOWN) {
|
||||||
|
log_info(LD_OR,"Clean shutdown: exiting");
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
memwipe(&req, 0, sizeof(req));
|
||||||
|
memwipe(&rpl, 0, sizeof(req));
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
|
memwipe(&req, 0, sizeof(req));
|
||||||
|
memwipe(&rpl, 0, sizeof(req));
|
||||||
release_server_onion_keys(&onion_keys);
|
release_server_onion_keys(&onion_keys);
|
||||||
tor_close_socket(fd);
|
tor_close_socket(fd);
|
||||||
crypto_thread_cleanup();
|
crypto_thread_cleanup();
|
||||||
@ -394,7 +406,7 @@ static void
|
|||||||
process_pending_task(connection_t *cpuworker)
|
process_pending_task(connection_t *cpuworker)
|
||||||
{
|
{
|
||||||
or_circuit_t *circ;
|
or_circuit_t *circ;
|
||||||
char *onionskin = NULL;
|
create_cell_t *onionskin = NULL;
|
||||||
|
|
||||||
tor_assert(cpuworker);
|
tor_assert(cpuworker);
|
||||||
|
|
||||||
@ -447,10 +459,10 @@ cull_wedged_cpuworkers(void)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
||||||
or_circuit_t *circ, char *onionskin)
|
or_circuit_t *circ,
|
||||||
|
create_cell_t *onionskin)
|
||||||
{
|
{
|
||||||
char qbuf[1];
|
cpuworker_request_t req;
|
||||||
char tag[TAG_LEN];
|
|
||||||
time_t now = approx_time();
|
time_t now = approx_time();
|
||||||
static time_t last_culled_cpuworkers = 0;
|
static time_t last_culled_cpuworkers = 0;
|
||||||
|
|
||||||
@ -486,7 +498,10 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
|||||||
tor_free(onionskin);
|
tor_free(onionskin);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tag_pack(tag, circ->p_chan->global_identifier,
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.magic = CPUWORKER_REQUEST_MAGIC;
|
||||||
|
tag_pack(req.tag, circ->p_chan->global_identifier,
|
||||||
circ->p_circ_id);
|
circ->p_circ_id);
|
||||||
|
|
||||||
cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
|
cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
|
||||||
@ -496,11 +511,13 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
|||||||
cpuworker->timestamp_lastwritten = time(NULL);
|
cpuworker->timestamp_lastwritten = time(NULL);
|
||||||
num_cpuworkers_busy++;
|
num_cpuworkers_busy++;
|
||||||
|
|
||||||
qbuf[0] = CPUWORKER_TASK_ONION;
|
req.task = CPUWORKER_TASK_ONION;
|
||||||
connection_write_to_buf(qbuf, 1, cpuworker);
|
memcpy(&req.create_cell, onionskin, sizeof(create_cell_t));
|
||||||
connection_write_to_buf(tag, sizeof(tag), cpuworker);
|
|
||||||
connection_write_to_buf(onionskin, TAP_ONIONSKIN_CHALLENGE_LEN, cpuworker);
|
|
||||||
tor_free(onionskin);
|
tor_free(onionskin);
|
||||||
|
|
||||||
|
connection_write_to_buf((void*)&req, sizeof(req), cpuworker);
|
||||||
|
memwipe(&req, 0, sizeof(req));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,10 @@ void cpuworkers_rotate(void);
|
|||||||
int connection_cpu_finished_flushing(connection_t *conn);
|
int connection_cpu_finished_flushing(connection_t *conn);
|
||||||
int connection_cpu_reached_eof(connection_t *conn);
|
int connection_cpu_reached_eof(connection_t *conn);
|
||||||
int connection_cpu_process_inbuf(connection_t *conn);
|
int connection_cpu_process_inbuf(connection_t *conn);
|
||||||
|
struct create_cell_t;
|
||||||
int assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
int assign_onionskin_to_cpuworker(connection_t *cpuworker,
|
||||||
or_circuit_t *circ,
|
or_circuit_t *circ,
|
||||||
char *onionskin);
|
struct create_cell_t *onionskin);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* to process a waiting onion handshake. */
|
* to process a waiting onion handshake. */
|
||||||
typedef struct onion_queue_t {
|
typedef struct onion_queue_t {
|
||||||
or_circuit_t *circ;
|
or_circuit_t *circ;
|
||||||
char *onionskin;
|
create_cell_t *onionskin;
|
||||||
time_t when_added;
|
time_t when_added;
|
||||||
struct onion_queue_t *next;
|
struct onion_queue_t *next;
|
||||||
} onion_queue_t;
|
} onion_queue_t;
|
||||||
@ -48,7 +48,7 @@ static int ol_length=0;
|
|||||||
* if ol_list is too long, in which case do nothing and return -1.
|
* if ol_list is too long, in which case do nothing and return -1.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
onion_pending_add(or_circuit_t *circ, char *onionskin)
|
onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
|
||||||
{
|
{
|
||||||
onion_queue_t *tmp;
|
onion_queue_t *tmp;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
@ -105,7 +105,7 @@ onion_pending_add(or_circuit_t *circ, char *onionskin)
|
|||||||
* NULL if the list is empty.
|
* NULL if the list is empty.
|
||||||
*/
|
*/
|
||||||
or_circuit_t *
|
or_circuit_t *
|
||||||
onion_next_task(char **onionskin_out)
|
onion_next_task(create_cell_t **onionskin_out)
|
||||||
{
|
{
|
||||||
or_circuit_t *circ;
|
or_circuit_t *circ;
|
||||||
|
|
||||||
@ -302,37 +302,60 @@ onion_skin_create(int type,
|
|||||||
* using the keys in <b>keys</b>. On success, write our response into
|
* using the keys in <b>keys</b>. On success, write our response into
|
||||||
* <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
|
* <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
|
||||||
* in <b>keys_out_len</b>, and return the length of the reply. On failure,
|
* in <b>keys_out_len</b>, and return the length of the reply. On failure,
|
||||||
* return -1. */
|
* return -1.
|
||||||
|
* DOCDOC rend_nonce_out
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
onion_skin_server_handshake(int type,
|
onion_skin_server_handshake(int type,
|
||||||
const uint8_t *onion_skin,
|
const uint8_t *onion_skin, size_t onionskin_len,
|
||||||
const server_onion_keys_t *keys,
|
const server_onion_keys_t *keys,
|
||||||
uint8_t *reply_out,
|
uint8_t *reply_out,
|
||||||
uint8_t *keys_out, size_t keys_out_len)
|
uint8_t *keys_out, size_t keys_out_len,
|
||||||
|
uint8_t *rend_nonce_out)
|
||||||
{
|
{
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ONION_HANDSHAKE_TYPE_TAP:
|
case ONION_HANDSHAKE_TYPE_TAP:
|
||||||
|
if (onionskin_len != TAP_ONIONSKIN_CHALLENGE_LEN)
|
||||||
|
return -1;
|
||||||
if (onion_skin_TAP_server_handshake((const char*)onion_skin,
|
if (onion_skin_TAP_server_handshake((const char*)onion_skin,
|
||||||
keys->onion_key, keys->last_onion_key,
|
keys->onion_key, keys->last_onion_key,
|
||||||
(char*)reply_out,
|
(char*)reply_out,
|
||||||
(char*)keys_out, keys_out_len)<0)
|
(char*)keys_out, keys_out_len)<0)
|
||||||
return -1;
|
return -1;
|
||||||
r = TAP_ONIONSKIN_REPLY_LEN;
|
r = TAP_ONIONSKIN_REPLY_LEN;
|
||||||
|
memcpy(rend_nonce_out, reply_out+DH_KEY_LEN, DIGEST_LEN);
|
||||||
break;
|
break;
|
||||||
case ONION_HANDSHAKE_TYPE_FAST:
|
case ONION_HANDSHAKE_TYPE_FAST:
|
||||||
|
if (onionskin_len != CREATE_FAST_LEN)
|
||||||
|
return -1;
|
||||||
if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
|
if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
|
||||||
return -1;
|
return -1;
|
||||||
r = CREATED_FAST_LEN;
|
r = CREATED_FAST_LEN;
|
||||||
|
memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
|
||||||
break;
|
break;
|
||||||
case ONION_HANDSHAKE_TYPE_NTOR:
|
case ONION_HANDSHAKE_TYPE_NTOR:
|
||||||
#ifdef CURVE25519_ENABLED
|
#ifdef CURVE25519_ENABLED
|
||||||
if (onion_skin_ntor_server_handshake(onion_skin, keys->curve25519_key_map,
|
if (onionskin_len != NTOR_ONIONSKIN_LEN)
|
||||||
keys->my_identity,
|
|
||||||
reply_out, keys_out, keys_out_len)<0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
{
|
||||||
|
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
|
||||||
|
uint8_t *keys_tmp = tor_malloc(keys_out_len + DIGEST_LEN);
|
||||||
|
|
||||||
|
if (onion_skin_ntor_server_handshake(
|
||||||
|
onion_skin, keys->curve25519_key_map,
|
||||||
|
keys->my_identity,
|
||||||
|
reply_out, keys_tmp, keys_tmp_len)<0) {
|
||||||
|
tor_free(keys_tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(keys_out, keys_tmp, keys_out_len);
|
||||||
|
memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
|
||||||
|
memwipe(keys_tmp, 0, keys_tmp_len);
|
||||||
|
tor_free(keys_tmp);
|
||||||
r = NTOR_REPLY_LEN;
|
r = NTOR_REPLY_LEN;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
@ -343,12 +366,6 @@ onion_skin_server_handshake(int type,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXXX we should generate the rendezvous nonce stuff too. Some notes
|
|
||||||
* below */
|
|
||||||
// memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN);
|
|
||||||
|
|
||||||
//memcpy(hop->handshake_digest, reply+DIGEST_LEN, DIGEST_LEN);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +379,7 @@ onion_skin_server_handshake(int type,
|
|||||||
int
|
int
|
||||||
onion_skin_client_handshake(int type,
|
onion_skin_client_handshake(int type,
|
||||||
const onion_handshake_state_t *handshake_state,
|
const onion_handshake_state_t *handshake_state,
|
||||||
const uint8_t *reply,
|
const uint8_t *reply, size_t reply_len,
|
||||||
uint8_t *keys_out, size_t keys_out_len,
|
uint8_t *keys_out, size_t keys_out_len,
|
||||||
uint8_t *rend_authenticator_out)
|
uint8_t *rend_authenticator_out)
|
||||||
{
|
{
|
||||||
@ -371,6 +388,8 @@ onion_skin_client_handshake(int type,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ONION_HANDSHAKE_TYPE_TAP:
|
case ONION_HANDSHAKE_TYPE_TAP:
|
||||||
|
if (reply_len != TAP_ONIONSKIN_REPLY_LEN)
|
||||||
|
return -1;
|
||||||
if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
|
if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
|
||||||
(const char*)reply,
|
(const char*)reply,
|
||||||
(char *)keys_out, keys_out_len) < 0)
|
(char *)keys_out, keys_out_len) < 0)
|
||||||
@ -380,6 +399,8 @@ onion_skin_client_handshake(int type,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case ONION_HANDSHAKE_TYPE_FAST:
|
case ONION_HANDSHAKE_TYPE_FAST:
|
||||||
|
if (reply_len != CREATED_FAST_LEN)
|
||||||
|
return -1;
|
||||||
if (fast_client_handshake(handshake_state->u.fast, reply,
|
if (fast_client_handshake(handshake_state->u.fast, reply,
|
||||||
keys_out, keys_out_len) < 0)
|
keys_out, keys_out_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -388,6 +409,8 @@ onion_skin_client_handshake(int type,
|
|||||||
return 0;
|
return 0;
|
||||||
#ifdef CURVE25519_ENABLED
|
#ifdef CURVE25519_ENABLED
|
||||||
case ONION_HANDSHAKE_TYPE_NTOR:
|
case ONION_HANDSHAKE_TYPE_NTOR:
|
||||||
|
if (reply_len != NTOR_REPLY_LEN)
|
||||||
|
return -1;
|
||||||
{
|
{
|
||||||
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
|
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
|
||||||
uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
|
uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
|
||||||
|
@ -12,8 +12,9 @@
|
|||||||
#ifndef TOR_ONION_H
|
#ifndef TOR_ONION_H
|
||||||
#define TOR_ONION_H
|
#define TOR_ONION_H
|
||||||
|
|
||||||
int onion_pending_add(or_circuit_t *circ, char *onionskin);
|
struct create_cell_t;
|
||||||
or_circuit_t *onion_next_task(char **onionskin_out);
|
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);
|
||||||
void onion_pending_remove(or_circuit_t *circ);
|
void onion_pending_remove(or_circuit_t *circ);
|
||||||
void clear_pending_onions(void);
|
void clear_pending_onions(void);
|
||||||
|
|
||||||
@ -39,14 +40,14 @@ int onion_skin_create(int type,
|
|||||||
onion_handshake_state_t *state_out,
|
onion_handshake_state_t *state_out,
|
||||||
uint8_t *onion_skin_out);
|
uint8_t *onion_skin_out);
|
||||||
int onion_skin_server_handshake(int type,
|
int onion_skin_server_handshake(int type,
|
||||||
const uint8_t *onion_skin,
|
const uint8_t *onion_skin, size_t onionskin_len,
|
||||||
const server_onion_keys_t *keys,
|
const server_onion_keys_t *keys,
|
||||||
uint8_t *reply_out,
|
uint8_t *reply_out,
|
||||||
uint8_t *keys_out, size_t key_out_len);
|
uint8_t *keys_out, size_t key_out_len,
|
||||||
// uint8_t *rend_authenticator_out);
|
uint8_t *rend_nonce_out);
|
||||||
int onion_skin_client_handshake(int type,
|
int onion_skin_client_handshake(int type,
|
||||||
const onion_handshake_state_t *handshake_state,
|
const onion_handshake_state_t *handshake_state,
|
||||||
const uint8_t *reply,
|
const uint8_t *reply, size_t reply_len,
|
||||||
uint8_t *keys_out, size_t key_out_len,
|
uint8_t *keys_out, size_t key_out_len,
|
||||||
uint8_t *rend_authenticator_out);
|
uint8_t *rend_authenticator_out);
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ typedef enum {
|
|||||||
#define CPUWORKER_STATE_MAX_ 2
|
#define CPUWORKER_STATE_MAX_ 2
|
||||||
|
|
||||||
#define CPUWORKER_TASK_ONION CPUWORKER_STATE_BUSY_ONION
|
#define CPUWORKER_TASK_ONION CPUWORKER_STATE_BUSY_ONION
|
||||||
|
#define CPUWORKER_TASK_SHUTDOWN 255
|
||||||
|
|
||||||
#define OR_CONN_STATE_MIN_ 1
|
#define OR_CONN_STATE_MIN_ 1
|
||||||
/** State for a connection to an OR: waiting for connect() to finish. */
|
/** State for a connection to an OR: waiting for connect() to finish. */
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "mempool.h"
|
#include "mempool.h"
|
||||||
#include "networkstatus.h"
|
#include "networkstatus.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
|
#include "onion.h"
|
||||||
#include "policies.h"
|
#include "policies.h"
|
||||||
#include "reasons.h"
|
#include "reasons.h"
|
||||||
#include "relay.h"
|
#include "relay.h"
|
||||||
@ -1296,12 +1297,21 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_debug(domain,"Got an extended cell! Yay.");
|
log_debug(domain,"Got an extended cell! Yay.");
|
||||||
|
{
|
||||||
|
extended_cell_t extended_cell;
|
||||||
|
if (extended_cell_parse(&extended_cell, rh.command,
|
||||||
|
(const uint8_t*)cell->payload+RELAY_HEADER_SIZE,
|
||||||
|
rh.length)<0) {
|
||||||
|
log_warn(LD_PROTOCOL,
|
||||||
|
"Can't parse EXTENDED cell; killing circuit.");
|
||||||
|
return -END_CIRC_REASON_TORPROTOCOL;
|
||||||
|
}
|
||||||
if ((reason = circuit_finish_handshake(TO_ORIGIN_CIRCUIT(circ),
|
if ((reason = circuit_finish_handshake(TO_ORIGIN_CIRCUIT(circ),
|
||||||
CELL_CREATED,
|
&extended_cell.created_cell)) < 0) {
|
||||||
cell->payload+RELAY_HEADER_SIZE)) < 0) {
|
|
||||||
log_warn(domain,"circuit_finish_handshake failed.");
|
log_warn(domain,"circuit_finish_handshake failed.");
|
||||||
return reason;
|
return reason;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((reason=circuit_send_next_onion_skin(TO_ORIGIN_CIRCUIT(circ)))<0) {
|
if ((reason=circuit_send_next_onion_skin(TO_ORIGIN_CIRCUIT(circ)))<0) {
|
||||||
log_info(domain,"circuit_send_next_onion_skin() failed.");
|
log_info(domain,"circuit_send_next_onion_skin() failed.");
|
||||||
return reason;
|
return reason;
|
||||||
|
Loading…
Reference in New Issue
Block a user