Skip to content

Commit

Permalink
add relay_sendme and the cell windows so that the
Browse files Browse the repository at this point in the history
full consensus can be fetched without the windows closing, fixed bugs related to consensus fetching
  • Loading branch information
jpbland1 committed Sep 1, 2023
1 parent 2bdc34f commit 0a195e6
Show file tree
Hide file tree
Showing 16 changed files with 291 additions and 137 deletions.
5 changes: 3 additions & 2 deletions h/circuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ int d_process_certs( DlConnection* or_connection, CellVariable* certs_cell, int
int d_process_challenge( DlConnection* or_connection, CellVariable* challenge_cell, int length );
int d_process_netinfo( DlConnection* or_connection, Cell* netinfo_cell );
int d_router_begin_dir( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id );
int d_rounter_relay_data_cell( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id, uint8_t* data, uint32_t data_len );
int d_router_relay_end( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id );
int d_router_relay_data_cell( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id, uint8_t* data, uint32_t data_len );
int d_router_relay_end(OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id);
int d_router_relay_sendme(OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id);

#endif
3 changes: 3 additions & 0 deletions h/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

#define WATCHDOG_TIMEOUT_PERIOD 30

#define RELAY_WINDOW_DEFAULT 1000
#define STREAM_RELAY_WINDOW_DEFAULT 500

#endif
7 changes: 7 additions & 0 deletions h/structures/cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,13 @@ typedef union __attribute__((__packed__)) CellPayload
uint8_t destroy_code;

uint8_t data[RELAY_PAYLOAD_LEN];

struct __attribute__((__packed__))
{
uint8_t version;
uint16_t data_len;
uint8_t data[];
} sendme;
};
} relay;

Expand Down
2 changes: 2 additions & 0 deletions h/structures/circuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ typedef struct OnionCircuit
int desc_index;
int target_relay_index;
int relay_early_count;
uint16_t stream_package_windows[5];
uint16_t stream_deliver_windows[5];
} OnionCircuit;

extern unsigned int circ_id_counter;
Expand Down
5 changes: 4 additions & 1 deletion h/structures/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ struct DoublyLinkedOnionRelay {
DoublyLinkedOnionRelay* next;
OnionRelay* relay;
RelayCrypto* relay_crypto;
unsigned int package_window;
unsigned int deliver_window;
};

typedef struct DoublyLinkedOnionRelayList {
Expand All @@ -119,7 +121,8 @@ typedef struct DoublyLinkedOnionRelayList {

void v_add_relay_to_list( DoublyLinkedOnionRelay* node, DoublyLinkedOnionRelayList* list );
void v_pop_relay_from_list_back( DoublyLinkedOnionRelayList* list );
OnionRelay* px_get_relay_by_index( DoublyLinkedOnionRelayList* list, int index );
DoublyLinkedOnionRelay* px_get_dl_relay_by_index(DoublyLinkedOnionRelayList* list, int index);
OnionRelay* px_get_relay_by_index(DoublyLinkedOnionRelayList* list, int index);

// shared state must be protected by mutex
extern NetworkConsensus network_consensus;
Expand Down
1 change: 0 additions & 1 deletion h/structures/onion_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ typedef enum OnionMessageType
CLIENT_RELAY_END,
CLIENT_CLOSED,
CONSENSUS_FETCHED,
EXTERNAL_CONSENSUS_FETCHED,
} OnionMessageType;

typedef struct OnionMessage
Expand Down
3 changes: 2 additions & 1 deletion src/cell.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,5 +632,6 @@ int d_decrypt_cell( Cell* cell, int circ_id_length, DoublyLinkedOnionRelayList*
}
}

return 0;
// return the circuit index that sent this cell
return i;
}
121 changes: 81 additions & 40 deletions src/circuit.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ int d_prepare_onion_circuit( OnionCircuit* circuit, int length, OnionRelay* star
if ( start_relay != NULL )
{
dl_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );
memset(dl_relay, 0, sizeof(DoublyLinkedOnionRelay));
dl_relay->package_window = RELAY_WINDOW_DEFAULT;
dl_relay->deliver_window = RELAY_WINDOW_DEFAULT;
dl_relay->relay = start_relay;

dl_relay->next = circuit->relay_list.head;
Expand All @@ -183,8 +186,10 @@ int d_prepare_onion_circuit( OnionCircuit* circuit, int length, OnionRelay* star
// append the destination_relay to the list
if ( end_relay != NULL )
{

dl_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );
memset(dl_relay, 0, sizeof(DoublyLinkedOnionRelay));
dl_relay->package_window = RELAY_WINDOW_DEFAULT;
dl_relay->deliver_window = RELAY_WINDOW_DEFAULT;
dl_relay->relay = end_relay;

v_add_relay_to_list( dl_relay, &circuit->relay_list );
Expand All @@ -207,48 +212,51 @@ int d_prepare_onion_circuit( OnionCircuit* circuit, int length, OnionRelay* star

int d_get_suitable_relay( DoublyLinkedOnionRelayList* relay_list, int guard, uint8_t* exclude_start, uint8_t* exclude_end )
{
DoublyLinkedOnionRelay* db_relay;
DoublyLinkedOnionRelay* dl_relay;

db_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );
db_relay->relay = px_get_random_fast_relay( guard, relay_list, exclude_start, exclude_end );
dl_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );
memset(dl_relay, 0, sizeof(DoublyLinkedOnionRelay));
dl_relay->package_window = RELAY_WINDOW_DEFAULT;
dl_relay->deliver_window = RELAY_WINDOW_DEFAULT;
dl_relay->relay = px_get_random_fast_relay( guard, relay_list, exclude_start, exclude_end );

if ( db_relay->relay == NULL )
if ( dl_relay->relay == NULL )
{
MINITOR_LOG( MINITOR_TAG, "Failed to get guard relay" );

free( db_relay );
free( dl_relay );

return -1;
}

v_add_relay_to_list( db_relay, relay_list );
v_add_relay_to_list( dl_relay, relay_list );

return 0;
}

int d_get_suitable_onion_relays( DoublyLinkedOnionRelayList* relay_list, int desired_length, uint8_t* exclude_start, uint8_t* exclude_end )
{
int i;
DoublyLinkedOnionRelay* db_relay;
DoublyLinkedOnionRelay* dl_relay;

for ( i = relay_list->length; i < desired_length; i++ )
{
db_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );
dl_relay = malloc( sizeof( DoublyLinkedOnionRelay ) );

if ( i == 0 )
{
db_relay->relay = px_get_random_fast_relay( 1, NULL, exclude_start, exclude_end );
dl_relay->relay = px_get_random_fast_relay( 1, NULL, exclude_start, exclude_end );
}
else
{
db_relay->relay = px_get_random_fast_relay( 0, relay_list, exclude_start, exclude_end );
dl_relay->relay = px_get_random_fast_relay( 0, relay_list, exclude_start, exclude_end );
}

if ( db_relay->relay == NULL )
if ( dl_relay->relay == NULL )
{
MINITOR_LOG( MINITOR_TAG, "Failed to get guard relay" );

free( db_relay );
free( dl_relay );

while ( relay_list->length > 0 )
{
Expand All @@ -258,7 +266,7 @@ int d_get_suitable_onion_relays( DoublyLinkedOnionRelayList* relay_list, int des
return -1;
}

v_add_relay_to_list( db_relay, relay_list );
v_add_relay_to_list( dl_relay, relay_list );
}

return 0;
Expand Down Expand Up @@ -632,7 +640,7 @@ int d_ntor_handshake_start( unsigned char* handshake_data, OnionRelay* relay, cu
return 0;
}

int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db_relay, curve25519_key* key )
int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* dl_relay, curve25519_key* key )
{
int wolf_succ;
unsigned int idx;
Expand All @@ -654,12 +662,12 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db
wc_curve25519_init( &responder_handshake_public_key );
wc_curve25519_init( &ntor_onion_key );

db_relay->relay_crypto = malloc( sizeof( RelayCrypto ) );
dl_relay->relay_crypto = malloc( sizeof( RelayCrypto ) );

wc_InitSha( &db_relay->relay_crypto->running_sha_forward );
wc_InitSha( &db_relay->relay_crypto->running_sha_backward );
wc_AesInit( &db_relay->relay_crypto->aes_forward, NULL, INVALID_DEVID );
wc_AesInit( &db_relay->relay_crypto->aes_backward, NULL, INVALID_DEVID );
wc_InitSha( &dl_relay->relay_crypto->running_sha_forward );
wc_InitSha( &dl_relay->relay_crypto->running_sha_backward );
wc_AesInit( &dl_relay->relay_crypto->aes_forward, NULL, INVALID_DEVID );
wc_AesInit( &dl_relay->relay_crypto->aes_backward, NULL, INVALID_DEVID );

wolf_succ = wc_curve25519_import_public_ex( handshake_data, G_LENGTH, &responder_handshake_public_key, EC25519_LITTLE_ENDIAN );

Expand All @@ -670,7 +678,7 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db
goto fail;
}

wolf_succ = wc_curve25519_import_public_ex( db_relay->relay->ntor_onion_key, H_LENGTH, &ntor_onion_key, EC25519_LITTLE_ENDIAN );
wolf_succ = wc_curve25519_import_public_ex( dl_relay->relay->ntor_onion_key, H_LENGTH, &ntor_onion_key, EC25519_LITTLE_ENDIAN );

if ( wolf_succ < 0 )
{
Expand Down Expand Up @@ -704,10 +712,10 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db

working_secret_input += 32;

memcpy( working_secret_input, db_relay->relay->identity, ID_LENGTH );
memcpy( working_secret_input, dl_relay->relay->identity, ID_LENGTH );
working_secret_input += ID_LENGTH;

memcpy( working_secret_input, db_relay->relay->ntor_onion_key, H_LENGTH );
memcpy( working_secret_input, dl_relay->relay->ntor_onion_key, H_LENGTH );
working_secret_input += H_LENGTH;

idx = 32;
Expand Down Expand Up @@ -735,10 +743,10 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db

working_auth_input += WC_SHA256_DIGEST_SIZE;

memcpy( working_auth_input, db_relay->relay->identity, ID_LENGTH );
memcpy( working_auth_input, dl_relay->relay->identity, ID_LENGTH );
working_auth_input += ID_LENGTH;

memcpy( working_auth_input, db_relay->relay->ntor_onion_key, H_LENGTH );
memcpy( working_auth_input, dl_relay->relay->ntor_onion_key, H_LENGTH );
working_auth_input += H_LENGTH;

memcpy( working_auth_input, handshake_data, G_LENGTH );
Expand Down Expand Up @@ -788,9 +796,9 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db
wc_HmacFree( &reusable_hmac );

// seed the forward sha
wc_ShaUpdate( &db_relay->relay_crypto->running_sha_forward, reusable_hmac_digest, HASH_LEN );
wc_ShaUpdate( &dl_relay->relay_crypto->running_sha_forward, reusable_hmac_digest, HASH_LEN );
// seed the first 16 bytes of backwards sha
wc_ShaUpdate( &db_relay->relay_crypto->running_sha_backward, reusable_hmac_digest + HASH_LEN, WC_SHA256_DIGEST_SIZE - HASH_LEN );
wc_ShaUpdate( &dl_relay->relay_crypto->running_sha_backward, reusable_hmac_digest + HASH_LEN, WC_SHA256_DIGEST_SIZE - HASH_LEN );
// mark how many bytes we've written to the backwards sha and how many remain
bytes_written = WC_SHA256_DIGEST_SIZE - HASH_LEN;
bytes_remaining = HASH_LEN - bytes_written;
Expand All @@ -804,10 +812,10 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db
wc_HmacFree( &reusable_hmac );

// seed the last 8 bytes of backward sha
wc_ShaUpdate( &db_relay->relay_crypto->running_sha_backward, reusable_hmac_digest, bytes_remaining );
wc_ShaUpdate( &dl_relay->relay_crypto->running_sha_backward, reusable_hmac_digest, bytes_remaining );
// set the forward aes key
memcpy( reusable_aes_key, reusable_hmac_digest + bytes_remaining, KEY_LEN );
wc_AesSetKeyDirect( &db_relay->relay_crypto->aes_forward, reusable_aes_key, KEY_LEN, aes_iv, AES_ENCRYPTION );
wc_AesSetKeyDirect( &dl_relay->relay_crypto->aes_forward, reusable_aes_key, KEY_LEN, aes_iv, AES_ENCRYPTION );
// copy the first part of the backward key into the buffer
memcpy( reusable_aes_key, reusable_hmac_digest + bytes_remaining + KEY_LEN, WC_SHA256_DIGEST_SIZE - bytes_remaining - KEY_LEN );
// mark how many bytes we've written to the backwards key and how many remain
Expand All @@ -824,10 +832,10 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db

// copy the last part of the key into the buffer and initialize the key
memcpy( reusable_aes_key + bytes_written, reusable_hmac_digest, bytes_remaining );
wc_AesSetKeyDirect( &db_relay->relay_crypto->aes_backward, reusable_aes_key, KEY_LEN, aes_iv, AES_ENCRYPTION );
wc_AesSetKeyDirect( &dl_relay->relay_crypto->aes_backward, reusable_aes_key, KEY_LEN, aes_iv, AES_ENCRYPTION );

// copy the nonce
memcpy( db_relay->relay_crypto->nonce, reusable_hmac_digest + bytes_remaining, DIGEST_LEN );
memcpy( dl_relay->relay_crypto->nonce, reusable_hmac_digest + bytes_remaining, DIGEST_LEN );

// free all the heap resources
wc_curve25519_free( &responder_handshake_public_key );
Expand All @@ -839,12 +847,12 @@ int d_ntor_handshake_finish( uint8_t* handshake_data, DoublyLinkedOnionRelay* db
return 0;

fail:
wc_ShaFree( &db_relay->relay_crypto->running_sha_forward );
wc_ShaFree( &db_relay->relay_crypto->running_sha_backward );
wc_AesFree( &db_relay->relay_crypto->aes_forward );
wc_AesFree( &db_relay->relay_crypto->aes_backward );
wc_ShaFree( &dl_relay->relay_crypto->running_sha_forward );
wc_ShaFree( &dl_relay->relay_crypto->running_sha_backward );
wc_AesFree( &dl_relay->relay_crypto->aes_forward );
wc_AesFree( &dl_relay->relay_crypto->aes_backward );

free( db_relay->relay_crypto );
free( dl_relay->relay_crypto );

wc_curve25519_free( &responder_handshake_public_key );
wc_curve25519_free( &ntor_onion_key );
Expand Down Expand Up @@ -1737,7 +1745,7 @@ int d_router_begin_dir( OnionCircuit* circuit, DlConnection* or_connection, uint
int ret;
Cell* begin_dir_cell;

begin_dir_cell = malloc( MINITOR_CELL_LEN );
begin_dir_cell = malloc(MINITOR_CELL_LEN);

begin_dir_cell->circ_id = circuit->circ_id;
begin_dir_cell->command = RELAY;
Expand All @@ -1748,17 +1756,19 @@ int d_router_begin_dir( OnionCircuit* circuit, DlConnection* or_connection, uint
begin_dir_cell->payload.relay.length = 0;
begin_dir_cell->length = FIXED_CELL_HEADER_SIZE + RELAY_CELL_HEADER_SIZE + begin_dir_cell->payload.relay.length;

if ( d_send_relay_cell_and_free( or_connection, begin_dir_cell, &circuit->relay_list, NULL ) < 0 )
if (d_send_relay_cell_and_free(or_connection, begin_dir_cell, &circuit->relay_list, NULL) < 0)
{
MINITOR_LOG( MINITOR_TAG, "Failed to send RELAY_EXTEND2 cell" );

return -1;
}

circuit->stream_deliver_windows[stream_id - 1] = STREAM_RELAY_WINDOW_DEFAULT;

return 0;
}

int d_rounter_relay_data_cell( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id, uint8_t* data, uint32_t data_len )
int d_router_relay_data_cell( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id, uint8_t* data, uint32_t data_len )
{
Cell* data_cell;

Expand Down Expand Up @@ -1793,11 +1803,12 @@ int d_rounter_relay_data_cell( OnionCircuit* circuit, DlConnection* or_connectio
return 0;
}

int d_router_relay_end( OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id )
int d_router_relay_end(OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id)
{
Cell* end_cell;

end_cell = malloc( MINITOR_CELL_LEN );
memset(end_cell, 0, MINITOR_CELL_LEN);

end_cell->circ_id = circuit->circ_id;
end_cell->command = RELAY;
Expand All @@ -1818,3 +1829,33 @@ int d_router_relay_end( OnionCircuit* circuit, DlConnection* or_connection, uint

return 0;
}

int d_router_relay_sendme(OnionCircuit* circuit, DlConnection* or_connection, uint16_t stream_id)
{
Cell* sendme_cell;

sendme_cell = malloc( MINITOR_CELL_LEN );
memset(sendme_cell, 0, MINITOR_CELL_LEN);

sendme_cell->circ_id = circuit->circ_id;
sendme_cell->command = RELAY;
sendme_cell->payload.relay.relay_command = RELAY_SENDME;
sendme_cell->payload.relay.recognized = 0;
sendme_cell->payload.relay.stream_id = stream_id;
sendme_cell->payload.relay.digest = 0;
sendme_cell->payload.relay.length = 3;

sendme_cell->payload.relay.sendme.version = 0;
sendme_cell->payload.relay.sendme.data_len = 0;

sendme_cell->length = FIXED_CELL_HEADER_SIZE + RELAY_CELL_HEADER_SIZE + sendme_cell->payload.relay.length;

if ( d_send_relay_cell_and_free( or_connection, sendme_cell, &circuit->relay_list, NULL ) < 0 )
{
MINITOR_LOG( MINITOR_TAG, "Failed to send RELAY_SENDME cell" );

return -1;
}

return 0;
}
1 change: 1 addition & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const char* tor_authorities[] =
// the identity can be found at /tor/status-vote/current/consensus
// the ntor-onion-key can be found at /tor/server/all
#ifdef MINITOR_CHUTNEY
// ip:port:identity:nto_onion_key
MINITOR_CHUTNEY_ADDRESS_STR ":5000:JM022IGoVYCo1n4HRKNmEyRJflI:jq+kM4ZFUbZqYWym4+sCmr9zOUn8DDlPSP0JP1crbBg",
MINITOR_CHUTNEY_ADDRESS_STR ":5001:Ewduz4NDJe1DNGMPLcMZVB/U7oc:z5Yd0lVNE8VLmNjG0Wp3ui9Czbc6E60wKGDb5hQy6B0",
MINITOR_CHUTNEY_ADDRESS_STR ":5002:biV7oePe1m9MXWyQteX44pcEnPI:HMHNA06WJOv/ywNk+6Hw/SUvOse4e12L7Z0/evLS1RI"
Expand Down
Loading

0 comments on commit 0a195e6

Please sign in to comment.