Commit b296ed5f authored by xpetrak2's avatar xpetrak2
Browse files

A few changes for the P2P overlay implementation

README renamed to README.md
Peer functions renaming
	nonces_get_first to nonces_get_oldest
	nonces_get_last to nonces_get_newest
Inversed conditions, swapped branches
More effective parity check
Initial value of identity's nonce halved
Route stale time increased
parent 044e1174
......@@ -3,10 +3,14 @@
## Terminology
- Host: A device that is possibly connected to the Coincer network
- Identifier: The public key of a cryptographic keypair
- Identity: A peer representation that we own (identifier + its corresponding secret key)
- Message trace: A tuple of a peer-to-peer message's nonce and a pointer to a neighbour from which we've received the message. The message traces are being used for routing loop detection
- Identity: A peer representation that we own (identifier + its corresponding
secret key)
- Message trace: A tuple of a peer-to-peer message's nonce and a pointer to a
neighbour from which we've received the message. The message traces are
being used for routing loop detection
- n2n: neighbour-to-neighbour
- Neighbour: A host that we are interconnected with
- Nonce: Ever-increasing integer tied to every message sent for message repetiton or replay attack detection
- Nonce: Ever-increasing integer tied to every message sent for message
repetiton or replay attack detection
- p2p: peer-to-peer
- Peer: The Coincer network participant
......@@ -234,8 +234,8 @@ static enum process_message_result process_message(
/* nonce parity check; the message must have:
* sender ID > our ID => odd nonce; sender ID < our ID => even nonce */
if ((cmp_val > 0 && nonce_value % 2 == 0) ||
(cmp_val < 0 && nonce_value % 2 == 1)) {
if ((cmp_val > 0 && !(nonce_value & 0x01)) ||
(cmp_val < 0 && (nonce_value & 0x01))) {
log_debug("process_mesage - wrong nonce parity");
return PMR_ERR_SEMANTIC;
}
......@@ -279,8 +279,8 @@ static enum process_message_result process_message(
}
/* if the message smells like replay attack */
if (!linkedlist_empty(&sender_peer->nonces) &&
nonce_value <
(nonces_get_first(&sender_peer->nonces))->value) {
nonce_value <
(nonces_get_oldest(&sender_peer->nonces))->value) {
log_warn("Potential replay attack detected");
return PMR_ERR_SEMANTIC;
}
......@@ -648,29 +648,30 @@ static int process_p2p_route_sol(const message_t *message,
identity_t *identity;
p2p_route_sol_t *route_sol;
route_sol = (p2p_route_sol_t *) message->body.data;
route_sol = (p2p_route_sol_t *) message->body.data;
identity = identity_find(&global_state->identities, route_sol->target);
/* if we wouldn't rebroadcast the p2p.route.sol, and just sent
* a p2p.route.adv, it could be obvious the 'target' is us */
if (!message_forward(message, sender, global_state)) {
/* if someone's looking for us */
if (identity) {
if (difftime(identity->last_adv,
time(NULL)) > ADV_GAP_TIME) {
/* broadcast the identity */
return send_p2p_route_adv(
&global_state->neighbours,
identity);
}
/* returning 1 means not storing the message's nonce,
* and so if we receive this message again, we can
* re-check the p2p.route.adv gap time */
return 1;
if (message_forward(message,
sender,
global_state)) {
return 1;
}
/* if someone's looking for us */
if (identity) {
if (difftime(time(NULL),
identity->last_adv) > ADV_GAP_TIME) {
/* broadcast the identity */
return send_p2p_route_adv(
&global_state->neighbours,
identity);
}
return 0;
/* returning 1 means not storing the message's nonce,
* and so if we receive this message again, we can
* re-check the p2p.route.adv gap time */
return 1;
}
return 1;
return 0;
}
......@@ -71,7 +71,7 @@ neighbour_t *add_new_neighbour(linkedlist_t *neighbours,
new_neighbour->host = NULL;
/* create our pseudonym */
generate_keypair(&new_neighbour->my_pseudonym.keypair);
new_neighbour->my_pseudonym.nonce_value = get_random_uint64_t();
new_neighbour->my_pseudonym.nonce_value = get_random_uint64_t() >> 1;
/* initialize neighbour's pseudonym */
memset(new_neighbour->pseudonym.identifier,
0x0,
......
......@@ -161,6 +161,7 @@ int nonce_store(linkedlist_t *nonces, uint64_t value)
}
nonce->value = value;
nonce->creation = time(NULL);
/* place the nonce into appropriate position */
cur_node = linkedlist_get_last(nonces);
......@@ -168,9 +169,7 @@ int nonce_store(linkedlist_t *nonces, uint64_t value)
cur_nonce = (nonce_t *) cur_node->data;
/* appropriate position found */
if (value > cur_nonce->value) {
if (cur_node == linkedlist_get_last(nonces)) {
nonce->creation = time(NULL);
} else {
if (cur_node != linkedlist_get_last(nonces)) {
nonce->creation = cur_nonce->creation;
}
......@@ -188,20 +187,14 @@ int nonce_store(linkedlist_t *nonces, uint64_t value)
/* at this point we know the nonce should be placed at the beginning
* of the container; do that only if the container is empty */
if (linkedlist_empty(nonces)) {
nonce->creation = time(NULL);
if (!linkedlist_insert_after(nonces, &nonces->first, nonce)) {
log_error("Storing a nonce");
free(nonce);
return 1;
}
return 0;
if (!linkedlist_empty(nonces) ||
!linkedlist_insert_after(nonces, &nonces->first, nonce)) {
log_error("Storing a nonce");
free(nonce);
return 1;
}
free(nonce);
return 1;
return 0;
}
/**
......@@ -234,34 +227,35 @@ nonce_t *nonces_find(const linkedlist_t *nonces, uint64_t value)
}
/**
* Get the first nonce (the nonce with the lowest value) from a list of nonces.
* Get the newest nonce (the nonce with the highest value) from a list
* of nonces.
*
* @param nonces Use these nonces.
*
* @return nonce_t The first nonce.
* @return nonce_t The last nonce.
* @return NULL The nonces are empty.
*/
nonce_t *nonces_get_first(const linkedlist_t *nonces)
nonce_t *nonces_get_newest(const linkedlist_t *nonces)
{
linkedlist_node_t *node;
if ((node = linkedlist_get_first(nonces))) {
if ((node = linkedlist_get_last(nonces))) {
return node->data;
}
return NULL;
}
/**
* Get the last nonce (the nonce with the highest value) from a list of nonces.
* Get the oldest nonce (the nonce with the lowest value) from a list of nonces.
*
* @param nonces Use these nonces.
*
* @return nonce_t The last nonce.
* @return nonce_t The first nonce.
* @return NULL The nonces are empty.
*/
nonce_t *nonces_get_last(const linkedlist_t *nonces)
nonce_t *nonces_get_oldest(const linkedlist_t *nonces)
{
linkedlist_node_t *node;
if ((node = linkedlist_get_last(nonces))) {
if ((node = linkedlist_get_first(nonces))) {
return node->data;
}
return NULL;
......
......@@ -76,8 +76,8 @@ int nonce_is_stale(const nonce_t *nonce, const time_t current_time);
int nonce_store(linkedlist_t *nonces, uint64_t value);
nonce_t *nonces_find(const linkedlist_t *nonces, uint64_t value);
nonce_t *nonces_get_first(const linkedlist_t *nonces);
nonce_t *nonces_get_last(const linkedlist_t *nonces);
nonce_t *nonces_get_newest(const linkedlist_t *nonces);
nonce_t *nonces_get_oldest(const linkedlist_t *nonces);
void nonces_remove_stale(linkedlist_t *nonces);
void peer_clear(peer_t *peer);
......
......@@ -180,20 +180,20 @@ static int message_finalize(message_t *message,
message->body.to,
crypto_box_PUBLICKEYBYTES);
/* from ID > to ID => odd nonce; from ID < to ID => even nonce */
if ((cmp_val > 0 && nonce_value % 2 == 0) ||
(cmp_val < 0 && nonce_value % 2 == 1)) {
if ((cmp_val > 0 && !(nonce_value & 0x01)) ||
(cmp_val < 0 && (nonce_value & 0x01))) {
nonce_value++;
}
message->body.nonce = from->nonce_value = nonce_value;
if (!encode_message_body(&message->body, &json_body)) {
sign_message(json_body, from->keypair.secret_key, message->sig);
free(json_body);
return 0;
if (encode_message_body(&message->body, &json_body)) {
return 1;
}
return 1;
sign_message(json_body, from->keypair.secret_key, message->sig);
free(json_body);
return 0;
}
/**
......@@ -240,14 +240,14 @@ int message_forward(const message_t *message,
*/
static int message_send_n2n(message_t *message, neighbour_t *dest)
{
if (!message_finalize(message,
&dest->my_pseudonym,
dest->pseudonym.identifier,
DV_HIDDEN)) {
return message_send_to_neighbour(message, dest);
if (message_finalize(message,
&dest->my_pseudonym,
dest->pseudonym.identifier,
DV_HIDDEN)) {
return 1;
}
return 1;
return message_send_to_neighbour(message, dest);
}
/**
......@@ -632,22 +632,21 @@ int send_p2p_bye(linkedlist_t *neighbours, identity_t *identity)
message_t p2p_bye_msg;
int ret;
if (!create_p2p_bye(&p2p_bye_msg)) {
if (!(ret = message_finalize(&p2p_bye_msg,
identity,
NULL,
DV_HIDDEN))) {
/* route as P2P (don't use our neighbour pseudonym) */
ret = message_broadcast_p2p(&p2p_bye_msg,
neighbours,
NULL);
}
message_delete(&p2p_bye_msg);
return ret;
if (create_p2p_bye(&p2p_bye_msg)) {
return 1;
}
if (!(ret = message_finalize(&p2p_bye_msg,
identity,
NULL,
DV_HIDDEN))) {
/* route as P2P (don't use our neighbour pseudonym) */
ret = message_broadcast_p2p(&p2p_bye_msg,
neighbours,
NULL);
}
return 1;
message_delete(&p2p_bye_msg);
return ret;
}
/**
......@@ -664,14 +663,13 @@ int send_p2p_hello(neighbour_t *dest, unsigned short port)
message_t p2p_hello_msg;
int ret;
if (!create_p2p_hello(&p2p_hello_msg, port)) {
ret = message_send_n2n(&p2p_hello_msg, dest);
message_delete(&p2p_hello_msg);
return ret;
if (create_p2p_hello(&p2p_hello_msg, port)) {
return 1;
}
ret = message_send_n2n(&p2p_hello_msg, dest);
return 1;
message_delete(&p2p_hello_msg);
return ret;
}
/**
......@@ -688,14 +686,13 @@ int send_p2p_peers_adv(neighbour_t *dest, const linkedlist_t *hosts)
message_t p2p_peers_adv_msg;
int ret;
if (!create_p2p_peers_adv(&p2p_peers_adv_msg, hosts)) {
ret = message_send_n2n(&p2p_peers_adv_msg, dest);
message_delete(&p2p_peers_adv_msg);
return ret;
if (create_p2p_peers_adv(&p2p_peers_adv_msg, hosts)) {
return 1;
}
ret = message_send_n2n(&p2p_peers_adv_msg, dest);
return 1;
message_delete(&p2p_peers_adv_msg);
return ret;
}
/**
......@@ -711,16 +708,15 @@ int send_p2p_peers_sol(neighbour_t *dest)
message_t p2p_peers_sol_msg;
int ret;
if (!create_p2p_peers_sol(&p2p_peers_sol_msg)) {
if (!(ret = message_send_n2n(&p2p_peers_sol_msg, dest))) {
set_neighbour_flags(dest, NEIGHBOUR_ADDRS_REQ);
}
message_delete(&p2p_peers_sol_msg);
return ret;
if (create_p2p_peers_sol(&p2p_peers_sol_msg)) {
return 1;
}
if (!(ret = message_send_n2n(&p2p_peers_sol_msg, dest))) {
set_neighbour_flags(dest, NEIGHBOUR_ADDRS_REQ);
}
return 1;
message_delete(&p2p_peers_sol_msg);
return ret;
}
/**
......@@ -736,14 +732,13 @@ int send_p2p_ping(neighbour_t *dest)
message_t p2p_ping_msg;
int ret;
if (!create_p2p_ping(&p2p_ping_msg)) {
ret = message_send_n2n(&p2p_ping_msg, dest);
message_delete(&p2p_ping_msg);
return ret;
if (create_p2p_ping(&p2p_ping_msg)) {
return 1;
}
ret = message_send_n2n(&p2p_ping_msg, dest);
return 1;
message_delete(&p2p_ping_msg);
return ret;
}
/**
......@@ -759,14 +754,13 @@ int send_p2p_pong(neighbour_t *dest)
message_t p2p_pong_msg;
int ret;
if (!create_p2p_pong(&p2p_pong_msg)) {
ret = message_send_n2n(&p2p_pong_msg, dest);
message_delete(&p2p_pong_msg);
return ret;
if (create_p2p_pong(&p2p_pong_msg)) {
return 1;
}
ret = message_send_n2n(&p2p_pong_msg, dest);
return 1;
message_delete(&p2p_pong_msg);
return ret;
}
/**
......@@ -783,27 +777,26 @@ int send_p2p_route_adv(linkedlist_t *neighbours, identity_t *identity)
message_t p2p_route_adv_msg;
int ret;
if (!create_p2p_route_adv(&p2p_route_adv_msg)) {
if (!(ret = message_finalize(&p2p_route_adv_msg,
identity,
NULL,
DV_HIDDEN))) {
/* timing attack protection */
execution_pause_random(250, 2000);
/* route as P2P (don't use our neighbour pseudonym) */
if (!(ret = message_broadcast_p2p(&p2p_route_adv_msg,
neighbours,
NULL))) {
identity->last_adv = time(NULL);
}
if (create_p2p_route_adv(&p2p_route_adv_msg)) {
return 1;
}
if (!(ret = message_finalize(&p2p_route_adv_msg,
identity,
NULL,
DV_HIDDEN))) {
/* timing attack protection */
execution_pause_random(250, 2000);
/* route as P2P (don't use our neighbour pseudonym) */
if (!(ret = message_broadcast_p2p(&p2p_route_adv_msg,
neighbours,
NULL))) {
identity->last_adv = time(NULL);
}
message_delete(&p2p_route_adv_msg);
return ret;
}
return 1;
message_delete(&p2p_route_adv_msg);
return ret;
}
/**
......@@ -823,22 +816,21 @@ int send_p2p_route_sol(linkedlist_t *neighbours,
message_t p2p_route_sol_msg;
int ret;
if (!create_p2p_route_sol(&p2p_route_sol_msg, target)) {
if (!(ret = message_finalize(&p2p_route_sol_msg,
identity,
NULL,
DV_HIDDEN))) {
/* route as P2P (don't use our neighbour pseudonym) */
ret = message_broadcast_p2p(&p2p_route_sol_msg,
neighbours,
NULL);
}
message_delete(&p2p_route_sol_msg);
return ret;
if (create_p2p_route_sol(&p2p_route_sol_msg, target)) {
return 1;
}
if (!(ret = message_finalize(&p2p_route_sol_msg,
identity,
NULL,
DV_HIDDEN))) {
/* route as P2P (don't use our neighbour pseudonym) */
ret = message_broadcast_p2p(&p2p_route_sol_msg,
neighbours,
NULL);
}
return 1;
message_delete(&p2p_route_sol_msg);
return ret;
}
/**
......
......@@ -32,7 +32,7 @@
/** After this many seconds we consider a message trace to be stale. */
#define MESSAGE_TRACE_STALE_TIME 60
/** After this many seconds we consider a route to be stale. */
#define ROUTE_STALE_TIME 60
#define ROUTE_STALE_TIME 180
/** A message trace representation. */
typedef struct s_message_trace {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment