mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Ran the code through: astyle --style=linux
This commit is contained in:
parent
1a6446266c
commit
14b43651c1
331
core/DHT.c
331
core/DHT.c
|
@ -1,5 +1,5 @@
|
|||
/* DHT.c
|
||||
*
|
||||
*
|
||||
* An implementation of the DHT as seen in docs/DHT.txt
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
|
@ -18,52 +18,48 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "DHT.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
IP_Port ip_port;
|
||||
uint32_t timestamp;
|
||||
uint32_t last_pinged;
|
||||
IP_Port ret_ip_port;/* The ip_port returned by this node for the friend
|
||||
IP_Port ret_ip_port;/* The ip_port returned by this node for the friend
|
||||
(for nodes in friends_list) or us (for nodes in close_clientlist) */
|
||||
uint32_t ret_timestamp;
|
||||
}Client_data;
|
||||
uint32_t ret_timestamp;
|
||||
} Client_data;
|
||||
|
||||
/* maximum number of clients stored per friend. */
|
||||
#define MAX_FRIEND_CLIENTS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
Client_data client_list[MAX_FRIEND_CLIENTS];
|
||||
uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */
|
||||
|
||||
|
||||
/*Symetric NAT hole punching stuff*/
|
||||
uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */
|
||||
uint32_t punching_index;
|
||||
uint32_t punching_timestamp;
|
||||
uint64_t NATping_id;
|
||||
uint32_t NATping_timestamp;
|
||||
}Friend;
|
||||
} Friend;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
IP_Port ip_port;
|
||||
}Node_format;
|
||||
} Node_format;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
IP_Port ip_port;
|
||||
uint64_t ping_id;
|
||||
uint32_t timestamp;
|
||||
|
||||
}Pinged;
|
||||
|
||||
} Pinged;
|
||||
|
||||
/* Our client id/public key */
|
||||
uint8_t self_public_key[CLIENT_ID_SIZE];
|
||||
|
@ -115,7 +111,7 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
|
|||
for(i = 0; i < length; ++i) {
|
||||
/*If ip_port is assigned to a different client_id replace it*/
|
||||
if(list[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
list[i].ip_port.port == ip_port.port) {
|
||||
list[i].ip_port.port == ip_port.port) {
|
||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
}
|
||||
|
||||
|
@ -167,39 +163,38 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
|
|||
int num_nodes=0;
|
||||
uint32_t temp_time = unix_time();
|
||||
for(i = 0; i < LCLIENT_LIST; ++i)
|
||||
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
|
||||
!client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
|
||||
/* if node is good and not already in list. */
|
||||
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
|
||||
!client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
|
||||
/* if node is good and not already in list. */
|
||||
if(num_nodes < MAX_SENT_NODES) {
|
||||
memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
|
||||
num_nodes++;
|
||||
}
|
||||
else for(j = 0; j < MAX_SENT_NODES; ++j)
|
||||
if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
|
||||
memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[j].ip_port = close_clientlist[i].ip_port;
|
||||
break;
|
||||
}
|
||||
memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
|
||||
num_nodes++;
|
||||
} else for(j = 0; j < MAX_SENT_NODES; ++j)
|
||||
if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
|
||||
memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[j].ip_port = close_clientlist[i].ip_port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
|
||||
!client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
|
||||
/* if node is good and not already in list. */
|
||||
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
|
||||
!client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
|
||||
/* if node is good and not already in list. */
|
||||
if(num_nodes < MAX_SENT_NODES) {
|
||||
memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
|
||||
num_nodes++;
|
||||
memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
|
||||
num_nodes++;
|
||||
} else for(k = 0; k < MAX_SENT_NODES; ++k)
|
||||
if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
|
||||
memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
|
||||
break;
|
||||
}
|
||||
if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
|
||||
memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
|
||||
nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num_nodes;
|
||||
return num_nodes;
|
||||
}
|
||||
|
||||
/* replace first bad (or empty) node with this one
|
||||
|
@ -210,7 +205,7 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
|
|||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
for(i = 0; i < length; ++i)
|
||||
if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ {
|
||||
if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */
|
||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
list[i].ip_port = ip_port;
|
||||
list[i].timestamp = temp_time;
|
||||
|
@ -228,7 +223,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
|
|||
{
|
||||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
|
||||
|
||||
for(i = 0; i < length; ++i)
|
||||
if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
|
||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
|
@ -247,7 +242,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
|
|||
void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
||||
/* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
|
||||
if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port))
|
||||
if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
|
||||
|
@ -261,7 +256,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
|||
replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
|
||||
}
|
||||
|
||||
/* If client_id is a friend or us, update ret_ip_port
|
||||
/* If client_id is a friend or us, update ret_ip_port
|
||||
nodeclient_id is the id of the node that sent us this info */
|
||||
void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
|
||||
{
|
||||
|
@ -275,14 +270,14 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
|
|||
return;
|
||||
}
|
||||
} else
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0)
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
|
||||
friends_list[i].client_list[j].ret_ip_port = ip_port;
|
||||
friends_list[i].client_list[j].ret_timestamp = temp_time;
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0)
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
|
||||
friends_list[i].client_list[j].ret_ip_port = ip_port;
|
||||
friends_list[i].client_list[j].ret_timestamp = temp_time;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ping timeout in seconds */
|
||||
|
@ -304,13 +299,13 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
|
|||
pinging = 0;
|
||||
if(ip_port.ip.i != 0)
|
||||
if(pings[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
pings[i].ip_port.port == ip_port.port)
|
||||
++pinging;
|
||||
pings[i].ip_port.port == ip_port.port)
|
||||
++pinging;
|
||||
if(ping_id != 0)
|
||||
if(pings[i].ping_id == ping_id)
|
||||
++pinging;
|
||||
++pinging;
|
||||
if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -328,14 +323,14 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
|
|||
pinging = 0;
|
||||
if(ip_port.ip.i != 0)
|
||||
if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
send_nodes[i].ip_port.port == ip_port.port)
|
||||
++pinging;
|
||||
send_nodes[i].ip_port.port == ip_port.port)
|
||||
++pinging;
|
||||
if(ping_id != 0)
|
||||
if(send_nodes[i].ping_id == ping_id)
|
||||
++pinging;
|
||||
if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -354,10 +349,10 @@ uint64_t add_pinging(IP_Port ip_port)
|
|||
for(i = 0; i < PING_TIMEOUT; ++i )
|
||||
for(j = 0; j < LPING_ARRAY; ++j )
|
||||
if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
|
||||
pings[j].timestamp = temp_time;
|
||||
pings[j].ip_port = ip_port;
|
||||
pings[j].ping_id = ping_id;
|
||||
return ping_id;
|
||||
pings[j].timestamp = temp_time;
|
||||
pings[j].ip_port = ip_port;
|
||||
pings[j].ping_id = ping_id;
|
||||
return ping_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -373,10 +368,10 @@ uint64_t add_gettingnodes(IP_Port ip_port)
|
|||
for(i = 0; i < PING_TIMEOUT; ++i )
|
||||
for(j = 0; j < LSEND_NODES_ARRAY; ++j )
|
||||
if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
|
||||
send_nodes[j].timestamp = temp_time;
|
||||
send_nodes[j].ip_port = ip_port;
|
||||
send_nodes[j].ping_id = ping_id;
|
||||
return ping_id;
|
||||
send_nodes[j].timestamp = temp_time;
|
||||
send_nodes[j].ip_port = ip_port;
|
||||
send_nodes[j].ping_id = ping_id;
|
||||
return ping_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -415,7 +410,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
|
|||
/* send a ping response */
|
||||
static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
|
||||
{
|
||||
/* check if packet is gonna be sent to ourself */
|
||||
/* check if packet is gonna be sent to ourself */
|
||||
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
|
||||
return 1;
|
||||
|
||||
|
@ -431,7 +426,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
|
|||
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||
|
||||
|
||||
return sendpacket(ip_port, data, sizeof(data));
|
||||
}
|
||||
|
||||
|
@ -441,26 +436,26 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
|
|||
/* check if packet is gonna be sent to ourself */
|
||||
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
if(is_gettingnodes(ip_port, 0))
|
||||
return 1;
|
||||
|
||||
|
||||
uint64_t ping_id = add_gettingnodes(ip_port);
|
||||
|
||||
|
||||
if(ping_id == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
|
||||
uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
|
||||
uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
random_nonce(nonce);
|
||||
|
||||
|
||||
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||
memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
|
||||
|
||||
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
|
||||
|
||||
|
||||
if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
|
||||
return -1;
|
||||
data[0] = 2;
|
||||
|
@ -476,8 +471,8 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
|
|||
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */
|
||||
return 1;
|
||||
|
||||
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
int num_nodes = get_close_nodes(client_id, nodes_list);
|
||||
|
@ -489,16 +484,16 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
|
|||
uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
random_nonce(nonce);
|
||||
|
||||
|
||||
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
|
||||
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, plain,
|
||||
sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
|
||||
|
||||
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, plain,
|
||||
sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
|
||||
|
||||
if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
|
||||
return -1;
|
||||
|
||||
|
||||
data[0] = 3;
|
||||
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||
|
@ -515,13 +510,13 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
uint64_t ping_id;
|
||||
if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||
return 1;
|
||||
/* check if packet is from ourself. */
|
||||
/* check if packet is from ourself. */
|
||||
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
|
||||
return 1;
|
||||
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||
if(len != sizeof(ping_id))
|
||||
return 1;
|
||||
|
||||
|
@ -540,18 +535,18 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */
|
||||
return 1;
|
||||
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||
if(len != sizeof(ping_id))
|
||||
return 1;
|
||||
|
||||
|
||||
if(is_pinging(source, ping_id)) {
|
||||
addto_lists(source, packet + 1);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
|
@ -559,15 +554,15 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
uint64_t ping_id;
|
||||
if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
|
||||
return 1;
|
||||
/* check if packet is from ourself. */
|
||||
/* check if packet is from ourself. */
|
||||
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
|
||||
return 1;
|
||||
|
||||
uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
|
||||
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
|
||||
|
||||
if(len != sizeof(ping_id) + CLIENT_ID_SIZE)
|
||||
return 1;
|
||||
|
@ -578,7 +573,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
pingreq(source, packet + 1); /* TODO: make this smarter? */
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
|
@ -586,21 +581,21 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
uint64_t ping_id;
|
||||
/* TODO: make this more readable */
|
||||
if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) ||
|
||||
(length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
|
||||
length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ sizeof(Node_format) + ENCRYPTION_PADDING) {
|
||||
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) ||
|
||||
(length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
|
||||
length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||
+ sizeof(Node_format) + ENCRYPTION_PADDING) {
|
||||
return 1;
|
||||
}
|
||||
uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
|
||||
+ sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
|
||||
uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
|
||||
+ sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
|
||||
|
||||
uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
|
||||
uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
|
||||
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
|
||||
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||
sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
|
||||
|
||||
if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
|
||||
return 1;
|
||||
|
@ -648,7 +643,7 @@ int DHT_delfriend(uint8_t * client_id)
|
|||
uint32_t i;
|
||||
Friend * temp;
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
/* Equal */
|
||||
/* Equal */
|
||||
if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
|
||||
--num_friends;
|
||||
if(num_friends != i)
|
||||
|
@ -669,18 +664,18 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
|
|||
IP_Port empty = {{{0}}, 0};
|
||||
uint32_t temp_time = unix_time();
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
/* Equal */
|
||||
/* Equal */
|
||||
if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
|
||||
friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
|
||||
if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
|
||||
friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
|
||||
return friends_list[i].client_list[j].ip_port;
|
||||
|
||||
return empty;
|
||||
}
|
||||
empty.ip.i = 1;
|
||||
return empty;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* The timeout after which a node is discarded completely. */
|
||||
|
@ -700,24 +695,24 @@ void doDHTFriends()
|
|||
uint32_t temp_time = unix_time();
|
||||
uint32_t rand_node;
|
||||
uint32_t index[MAX_FRIEND_CLIENTS];
|
||||
|
||||
|
||||
for(i = 0; i < num_friends; ++i) {
|
||||
uint32_t num_nodes = 0;
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ {
|
||||
if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */
|
||||
if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
|
||||
pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
|
||||
friends_list[i].client_list[j].last_pinged = temp_time;
|
||||
}
|
||||
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ {
|
||||
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */
|
||||
index[num_nodes] = j;
|
||||
++num_nodes;
|
||||
}
|
||||
}
|
||||
if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
|
||||
rand_node = rand() % num_nodes;
|
||||
getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
|
||||
friends_list[i].client_list[index[rand_node]].client_id,
|
||||
getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
|
||||
friends_list[i].client_list[index[rand_node]].client_id,
|
||||
friends_list[i].client_id);
|
||||
friends_list[i].lastgetnode = temp_time;
|
||||
}
|
||||
|
@ -735,25 +730,25 @@ void doClose() /* tested */
|
|||
uint32_t num_nodes = 0;
|
||||
uint32_t rand_node;
|
||||
uint32_t index[LCLIENT_LIST];
|
||||
|
||||
|
||||
for(i = 0; i < LCLIENT_LIST; ++i)
|
||||
/* if node is not dead. */
|
||||
/* if node is not dead. */
|
||||
if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
|
||||
if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
|
||||
pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
|
||||
close_clientlist[i].last_pinged = temp_time;
|
||||
}
|
||||
/* if node is good. */
|
||||
/* if node is good. */
|
||||
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
|
||||
index[num_nodes] = i;
|
||||
++num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
|
||||
rand_node = rand() % num_nodes;
|
||||
getnodes(close_clientlist[index[rand_node]].ip_port,
|
||||
close_clientlist[index[rand_node]].client_id,
|
||||
getnodes(close_clientlist[index[rand_node]].ip_port,
|
||||
close_clientlist[index[rand_node]].client_id,
|
||||
self_public_key);
|
||||
close_lastgetnodes = temp_time;
|
||||
}
|
||||
|
@ -761,7 +756,7 @@ void doClose() /* tested */
|
|||
|
||||
void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
|
||||
{
|
||||
getnodes(ip_port, public_key, self_public_key);
|
||||
getnodes(ip_port, public_key, self_public_key);
|
||||
}
|
||||
|
||||
/* send the given packet to node with client_id
|
||||
|
@ -775,7 +770,7 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
|
||||
/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
|
||||
ip_portlist must be at least MAX_FRIEND_CLIENTS big
|
||||
returns the number of ips returned
|
||||
return 0 if we are connected to friend or if no ips were found.
|
||||
|
@ -788,9 +783,9 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
|
|||
if(friend_num >= num_friends)
|
||||
return -1;
|
||||
for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
|
||||
friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
|
||||
friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
|
||||
if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 )
|
||||
return 0;
|
||||
ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
|
||||
|
@ -807,11 +802,11 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
|
|||
uint32_t sent = 0;
|
||||
uint32_t temp_time = unix_time();
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
/* Equal */
|
||||
/* Equal */
|
||||
if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
|
||||
friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time)
|
||||
if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
|
||||
++sent;
|
||||
|
@ -827,15 +822,15 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
|
|||
int num = friend_number(friend_id);
|
||||
if(num == -1)
|
||||
return 0;
|
||||
|
||||
|
||||
IP_Port ip_list[MAX_FRIEND_CLIENTS];
|
||||
int n = 0;
|
||||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
|
||||
friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
|
||||
/*If ip is not zero and node is good */
|
||||
if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
|
||||
friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
|
||||
ip_list[n] = friends_list[num].client_list[i].ip_port;
|
||||
++n;
|
||||
}
|
||||
|
@ -846,7 +841,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
|
||||
/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
|
||||
ip_portlist must be at least MAX_FRIEND_CLIENTS big
|
||||
returns the number of ips returned
|
||||
return 0 if we are connected to friend or if no ips were found.
|
||||
|
@ -856,7 +851,7 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
|
|||
|
||||
uint32_t i;
|
||||
for(i = 0; i < num_friends; ++i)
|
||||
/* Equal */
|
||||
/* Equal */
|
||||
if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0)
|
||||
return friend_iplist(ip_portlist, i);
|
||||
return -1;
|
||||
|
@ -869,7 +864,7 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
|
|||
uint8_t data[sizeof(uint64_t) + 1];
|
||||
data[0] = type;
|
||||
memcpy(data + 1, &ping_id, sizeof(uint64_t));
|
||||
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
|
||||
if(len == -1)
|
||||
|
@ -890,9 +885,9 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
|
|||
int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
{
|
||||
if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
|
||||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
|
||||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
|
||||
return 1;
|
||||
/* check if request is for us. */
|
||||
/* check if request is for us. */
|
||||
if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
|
@ -901,11 +896,11 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
return 1;
|
||||
uint64_t ping_id;
|
||||
memcpy(&ping_id, data + 1, sizeof(uint64_t));
|
||||
|
||||
|
||||
int friendnumber = friend_number(public_key);
|
||||
if(friendnumber == -1)
|
||||
return 1;
|
||||
|
||||
|
||||
if(data[0] == 0) {
|
||||
send_NATping(public_key, ping_id, 1); /*1 is reply*/
|
||||
return 0;
|
||||
|
@ -917,10 +912,9 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
/* if request is not for us, try routing it. */
|
||||
else
|
||||
if(route_packet(packet + 1, packet, length) == length)
|
||||
return 0;
|
||||
/* if request is not for us, try routing it. */
|
||||
else if(route_packet(packet + 1, packet, length) == length)
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -933,7 +927,7 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
|
|||
IP zero = {{0}};
|
||||
if(len > MAX_FRIEND_CLIENTS)
|
||||
return zero;
|
||||
|
||||
|
||||
uint32_t i, j;
|
||||
uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
|
||||
for(i = 0; i < len; ++i) {
|
||||
|
@ -998,8 +992,7 @@ static void doNAT()
|
|||
send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
|
||||
friends_list[i].NATping_timestamp = temp_time;
|
||||
}
|
||||
}
|
||||
else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
|
||||
} else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
|
||||
IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
|
||||
if(ip.i == 0)
|
||||
continue;
|
||||
|
@ -1020,23 +1013,23 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
{
|
||||
switch (packet[0]) {
|
||||
case 0:
|
||||
return handle_pingreq(packet, length, source);
|
||||
|
||||
return handle_pingreq(packet, length, source);
|
||||
|
||||
case 1:
|
||||
return handle_pingres(packet, length, source);
|
||||
|
||||
return handle_pingres(packet, length, source);
|
||||
|
||||
case 2:
|
||||
return handle_getnodes(packet, length, source);
|
||||
|
||||
return handle_getnodes(packet, length, source);
|
||||
|
||||
case 3:
|
||||
return handle_sendnodes(packet, length, source);
|
||||
|
||||
|
||||
case 254:
|
||||
return handle_NATping(packet, length, source);
|
||||
|
||||
default:
|
||||
|
||||
default:
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1074,17 +1067,17 @@ int DHT_load(uint8_t * data, uint32_t size)
|
|||
uint32_t i, j;
|
||||
/* uint32_t temp_time = unix_time(); */
|
||||
uint16_t temp;
|
||||
|
||||
|
||||
temp = (size - sizeof(close_clientlist))/sizeof(Friend);
|
||||
|
||||
|
||||
if(temp != 0) {
|
||||
Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
|
||||
|
||||
for(i = 0; i < temp; ++i) {
|
||||
DHT_addfriend(tempfriends_list[i].client_id);
|
||||
for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
|
||||
if(tempfriends_list[i].client_list[j].timestamp != 0) {
|
||||
getnodes(tempfriends_list[i].client_list[j].ip_port,
|
||||
if(tempfriends_list[i].client_list[j].timestamp != 0) {
|
||||
getnodes(tempfriends_list[i].client_list[j].ip_port,
|
||||
tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
|
||||
}
|
||||
}
|
||||
|
|
118
core/DHT.h
118
core/DHT.h
|
@ -1,7 +1,7 @@
|
|||
/* DHT.h
|
||||
*
|
||||
*
|
||||
* An implementation of the DHT as seen in docs/DHT.txt
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,11 +18,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DHT_H
|
||||
#define DHT_H
|
||||
#ifndef DHT_H
|
||||
#define DHT_H
|
||||
|
||||
#include "net_crypto.h"
|
||||
|
||||
|
@ -30,79 +30,79 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Current time, unix format */
|
||||
/* Current time, unix format */
|
||||
#define unix_time() ((uint32_t)time(NULL))
|
||||
|
||||
/* size of the client_id in bytes */
|
||||
/* size of the client_id in bytes */
|
||||
#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
|
||||
|
||||
/* Add a new friend to the friends list
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
returns 0 if success
|
||||
returns 1 if failure (friends list is full) */
|
||||
int DHT_addfriend(uint8_t *client_id);
|
||||
/* Add a new friend to the friends list
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
returns 0 if success
|
||||
returns 1 if failure (friends list is full) */
|
||||
int DHT_addfriend(uint8_t *client_id);
|
||||
|
||||
/* Delete a friend from the friends list
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
returns 0 if success
|
||||
returns 1 if failure (client_id not in friends list) */
|
||||
int DHT_delfriend(uint8_t *client_id);
|
||||
/* Delete a friend from the friends list
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
returns 0 if success
|
||||
returns 1 if failure (client_id not in friends list) */
|
||||
int DHT_delfriend(uint8_t *client_id);
|
||||
|
||||
/* Get ip of friend
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
ip must be 4 bytes long.
|
||||
port must be 2 bytes long.
|
||||
returns ip if success
|
||||
returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
|
||||
returns ip of 1 if friend is not in list. */
|
||||
IP_Port DHT_getfriendip(uint8_t *client_id);
|
||||
/* Get ip of friend
|
||||
client_id must be CLIENT_ID_SIZE bytes long.
|
||||
ip must be 4 bytes long.
|
||||
port must be 2 bytes long.
|
||||
returns ip if success
|
||||
returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
|
||||
returns ip of 1 if friend is not in list. */
|
||||
IP_Port DHT_getfriendip(uint8_t *client_id);
|
||||
|
||||
/* Run this function at least a couple times per second (It's the main loop) */
|
||||
void doDHT();
|
||||
/* Run this function at least a couple times per second (It's the main loop) */
|
||||
void doDHT();
|
||||
|
||||
/* if we receive a DHT packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
/* if we receive a DHT packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
|
||||
/* Use this function to bootstrap the client
|
||||
Sends a get nodes request to the given node with ip port and public_key */
|
||||
void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
|
||||
/* Use this function to bootstrap the client
|
||||
Sends a get nodes request to the given node with ip port and public_key */
|
||||
void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
|
||||
|
||||
/* ROUTING FUNCTIONS */
|
||||
/* ROUTING FUNCTIONS */
|
||||
|
||||
/* send the given packet to node with client_id
|
||||
returns -1 if failure */
|
||||
int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length);
|
||||
/* send the given packet to node with client_id
|
||||
returns -1 if failure */
|
||||
int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length);
|
||||
|
||||
/* Send the following packet to everyone who tells us they are connected to friend_id
|
||||
returns the number of nodes it sent the packet to */
|
||||
int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
|
||||
/* Send the following packet to everyone who tells us they are connected to friend_id
|
||||
returns the number of nodes it sent the packet to */
|
||||
int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
|
||||
|
||||
/* NAT PUNCHING FUNCTIONS */
|
||||
/* NAT PUNCHING FUNCTIONS */
|
||||
|
||||
/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
|
||||
ip_portlist must be at least MAX_FRIEND_CLIENTS big
|
||||
returns the number of ips returned
|
||||
returns -1 if no such friend*/
|
||||
int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id);
|
||||
/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
|
||||
ip_portlist must be at least MAX_FRIEND_CLIENTS big
|
||||
returns the number of ips returned
|
||||
returns -1 if no such friend*/
|
||||
int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id);
|
||||
|
||||
/* SAVE/LOAD functions */
|
||||
/* SAVE/LOAD functions */
|
||||
|
||||
/* get the size of the DHT (for saving) */
|
||||
uint32_t DHT_size();
|
||||
/* get the size of the DHT (for saving) */
|
||||
uint32_t DHT_size();
|
||||
|
||||
/* save the DHT in data where data is an array of size DHT_size() */
|
||||
void DHT_save(uint8_t *data);
|
||||
/* save the DHT in data where data is an array of size DHT_size() */
|
||||
void DHT_save(uint8_t *data);
|
||||
|
||||
/* load the DHT from data of size size;
|
||||
return -1 if failure
|
||||
return 0 if success */
|
||||
int DHT_load(uint8_t *data, uint32_t size);
|
||||
/* load the DHT from data of size size;
|
||||
return -1 if failure
|
||||
return 0 if success */
|
||||
int DHT_load(uint8_t *data, uint32_t size);
|
||||
|
||||
/* returns 0 if we are not connected to the DHT
|
||||
returns 1 if we are */
|
||||
int DHT_isconnected();
|
||||
/* returns 0 if we are not connected to the DHT
|
||||
returns 1 if we are */
|
||||
int DHT_isconnected();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* LAN_discovery.c
|
||||
*
|
||||
*
|
||||
* LAN discovery implementation.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LAN_discovery.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* LAN_discovery.h
|
||||
*
|
||||
*
|
||||
* LAN discovery implementation.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,12 +18,12 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LAN_DISCOVERY_H
|
||||
#define LAN_DISCOVERY_H
|
||||
#ifndef LAN_DISCOVERY_H
|
||||
#define LAN_DISCOVERY_H
|
||||
|
||||
|
||||
#include "DHT.h"
|
||||
|
@ -32,14 +32,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*Send a LAN discovery pcaket to the broadcast address with port port*/
|
||||
int send_LANdiscovery(uint16_t port);
|
||||
/*Send a LAN discovery pcaket to the broadcast address with port port*/
|
||||
int send_LANdiscovery(uint16_t port);
|
||||
|
||||
|
||||
/* if we receive a packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
/* if we receive a packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Lossless_UDP.c
|
||||
*
|
||||
/* Lossless_UDP.c
|
||||
*
|
||||
* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: clean this file a bit.
|
||||
|
@ -47,18 +47,18 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION
|
|||
typedef struct {
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint16_t size;
|
||||
}Data;
|
||||
} Data;
|
||||
|
||||
typedef struct {
|
||||
IP_Port ip_port;
|
||||
uint8_t status; /* 0 if connection is dead, 1 if attempting handshake,
|
||||
uint8_t status; /* 0 if connection is dead, 1 if attempting handshake,
|
||||
2 if handshake is done (we start sending SYNC packets)
|
||||
3 if we are sending SYNC packets and can send data
|
||||
4 if the connection has timed out. */
|
||||
|
||||
uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not.
|
||||
|
||||
uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not.
|
||||
2 if incoming_connection() has not returned it yet, 1 if it has. */
|
||||
|
||||
|
||||
uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
|
||||
uint16_t data_rate; /* current data packet send rate packets per second. */
|
||||
uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */
|
||||
|
@ -82,7 +82,7 @@ typedef struct {
|
|||
uint8_t recv_counter;
|
||||
uint8_t send_counter;
|
||||
uint8_t timeout; /* connection timeout in seconds. */
|
||||
}Connection;
|
||||
} Connection;
|
||||
|
||||
#define MAX_CONNECTIONS 256
|
||||
|
||||
|
@ -95,10 +95,11 @@ static Connection connections[MAX_CONNECTIONS];
|
|||
/* get connection id from IP_Port
|
||||
return -1 if there are no connections like we are looking for
|
||||
return id if it found it */
|
||||
int getconnection_id(IP_Port ip_port) {
|
||||
int getconnection_id(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if (connections[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
if (connections[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
|
||||
return i;
|
||||
}
|
||||
|
@ -384,10 +385,10 @@ int send_data_packet(uint32_t connection_id, uint32_t packet_num)
|
|||
packet[0] = 18;
|
||||
temp = htonl(packet_num);
|
||||
memcpy(packet + 1, &temp, 4);
|
||||
memcpy(packet + 5, connections[connection_id].sendbuffer[index].data,
|
||||
connections[connection_id].sendbuffer[index].size);
|
||||
memcpy(packet + 5, connections[connection_id].sendbuffer[index].data,
|
||||
connections[connection_id].sendbuffer[index].size);
|
||||
return sendpacket(connections[connection_id].ip_port, packet,
|
||||
1 + 4 + connections[connection_id].sendbuffer[index].size);
|
||||
1 + 4 + connections[connection_id].sendbuffer[index].size);
|
||||
}
|
||||
|
||||
/* sends 1 data packet */
|
||||
|
@ -395,7 +396,7 @@ int send_DATA(uint32_t connection_id)
|
|||
{
|
||||
int ret;
|
||||
uint32_t buffer[BUFFER_PACKET_NUM];
|
||||
if (connections[connection_id].num_req_paquets > 0) {
|
||||
if (connections[connection_id].num_req_paquets > 0) {
|
||||
ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
|
||||
connections[connection_id].num_req_paquets--;
|
||||
memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4);
|
||||
|
@ -416,9 +417,9 @@ int send_DATA(uint32_t connection_id)
|
|||
One to handle each type of packets we receive
|
||||
return 0 if handled correctly, 1 if packet is bad. */
|
||||
int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
{
|
||||
{
|
||||
if (length != (1 + 4 + 4))
|
||||
return 1;
|
||||
return 1;
|
||||
uint32_t temp;
|
||||
uint32_t handshake_id1, handshake_id2;
|
||||
int connection = getconnection_id(source);
|
||||
|
@ -426,7 +427,7 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
|
|||
handshake_id1 = ntohl(temp);
|
||||
memcpy(&temp, packet + 5, 4);
|
||||
handshake_id2 = ntohl(temp);
|
||||
|
||||
|
||||
if (handshake_id2 == 0) {
|
||||
send_handshake(source, handshake_id(source), handshake_id1);
|
||||
return 0;
|
||||
|
@ -452,7 +453,7 @@ int SYNC_valid(uint32_t length)
|
|||
{
|
||||
if (length < 4 + 4 + 2)
|
||||
return 0;
|
||||
if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
|
||||
if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
|
||||
((length - 4 - 4 - 2) % 4) != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -482,7 +483,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
|
|||
int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
|
||||
{
|
||||
if (recv_packetnum == connections[connection_id].orecv_packetnum) {
|
||||
/* && sent_packetnum == connections[connection_id].osent_packetnum) */
|
||||
/* && sent_packetnum == connections[connection_id].osent_packetnum) */
|
||||
connections[connection_id].status = 3;
|
||||
connections[connection_id].recv_counter = counter;
|
||||
++connections[connection_id].send_counter;
|
||||
|
@ -522,14 +523,14 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
|
|||
{
|
||||
|
||||
if (!SYNC_valid(length))
|
||||
return 1;
|
||||
return 1;
|
||||
int connection = getconnection_id(source);
|
||||
uint8_t counter;
|
||||
uint32_t temp;
|
||||
uint32_t recv_packetnum, sent_packetnum;
|
||||
uint32_t req_packets[BUFFER_PACKET_NUM];
|
||||
uint16_t number = (length - 4 - 4 - 2)/ 4;
|
||||
|
||||
|
||||
memcpy(&counter, packet + 1, 1);
|
||||
memcpy(&temp, packet + 2, 4);
|
||||
recv_packetnum = ntohl(temp);
|
||||
|
@ -556,7 +557,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
|
|||
uint32_t i;
|
||||
uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
|
||||
uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
|
||||
for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
|
||||
for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
|
||||
if (i == data_num) {
|
||||
memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
|
||||
connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
|
||||
|
@ -568,7 +569,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
|
|||
}
|
||||
for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
|
||||
if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
|
||||
connections[connection_id].recv_packetnum = i;
|
||||
connections[connection_id].recv_packetnum = i;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -603,15 +604,15 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
|
|||
{
|
||||
switch (packet[0]) { //TODO: check if no break statement is correct???
|
||||
case 16:
|
||||
return handle_handshake(packet, length, source);
|
||||
return handle_handshake(packet, length, source);
|
||||
|
||||
case 17:
|
||||
return handle_SYNC(packet, length, source);
|
||||
return handle_SYNC(packet, length, source);
|
||||
|
||||
case 18:
|
||||
return handle_data(packet, length, source);
|
||||
return handle_data(packet, length, source);
|
||||
|
||||
default:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -627,13 +628,13 @@ void doNew()
|
|||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if (connections[i].status == 1)
|
||||
if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
|
||||
send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
|
||||
connections[i].last_sent = temp_time;
|
||||
send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
|
||||
connections[i].last_sent = temp_time;
|
||||
}
|
||||
|
||||
/* kill all timed out connections */
|
||||
if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
|
||||
connections[i].status != 4)
|
||||
if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
|
||||
connections[i].status != 4)
|
||||
/* kill_connection(i); */
|
||||
connections[i].status = 4;
|
||||
if (connections[i].status > 0 && connections[i].killat < temp_time)
|
||||
|
@ -648,8 +649,8 @@ void doSYNC()
|
|||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if (connections[i].status == 2 || connections[i].status == 3)
|
||||
if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
|
||||
send_SYNC(i);
|
||||
connections[i].last_SYNC = temp_time;
|
||||
send_SYNC(i);
|
||||
connections[i].last_SYNC = temp_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -682,10 +683,9 @@ void adjustRates()
|
|||
connections[i].SYNC_rate = MAX_SYNC_RATE;
|
||||
if (connections[i].status == 3) {
|
||||
if (sendqueue(i) != 0) {
|
||||
connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
|
||||
connections[i].SYNC_rate = MAX_SYNC_RATE;
|
||||
}
|
||||
else if (connections[i].last_recvdata + 1000000UL > temp_time)
|
||||
connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
|
||||
connections[i].SYNC_rate = MAX_SYNC_RATE;
|
||||
} else if (connections[i].last_recvdata + 1000000UL > temp_time)
|
||||
connections[i].SYNC_rate = MAX_SYNC_RATE;
|
||||
else
|
||||
connections[i].SYNC_rate = SYNC_RATE;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Lossless_UDP.h
|
||||
*
|
||||
*
|
||||
* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,11 +18,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LOSSLESS_UDP_H
|
||||
#define LOSSLESS_UDP_H
|
||||
#ifndef LOSSLESS_UDP_H
|
||||
#define LOSSLESS_UDP_H
|
||||
|
||||
#include "network.h"
|
||||
|
||||
|
@ -30,74 +30,74 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* maximum length of the data in the data packets */
|
||||
/* maximum length of the data in the data packets */
|
||||
#define MAX_DATA_SIZE 1024
|
||||
|
||||
/* Functions */
|
||||
/* Functions */
|
||||
|
||||
/* initialize a new connection to ip_port
|
||||
returns an integer corresponding to the connection id.
|
||||
return -1 if it could not initialize the connection.
|
||||
if there already was an existing connection to that ip_port return its number. */
|
||||
int new_connection(IP_Port ip_port);
|
||||
/* initialize a new connection to ip_port
|
||||
returns an integer corresponding to the connection id.
|
||||
return -1 if it could not initialize the connection.
|
||||
if there already was an existing connection to that ip_port return its number. */
|
||||
int new_connection(IP_Port ip_port);
|
||||
|
||||
/* get connection id from IP_Port
|
||||
return -1 if there are no connections like we are looking for
|
||||
return id if it found it */
|
||||
int getconnection_id(IP_Port ip_port);
|
||||
/* get connection id from IP_Port
|
||||
return -1 if there are no connections like we are looking for
|
||||
return id if it found it */
|
||||
int getconnection_id(IP_Port ip_port);
|
||||
|
||||
/* returns an integer corresponding to the next connection in our imcoming connection list
|
||||
return -1 if there are no new incoming connections in the list. */
|
||||
int incoming_connection();
|
||||
/* returns an integer corresponding to the next connection in our imcoming connection list
|
||||
return -1 if there are no new incoming connections in the list. */
|
||||
int incoming_connection();
|
||||
|
||||
/* return -1 if it could not kill the connection.
|
||||
return 0 if killed successfully */
|
||||
int kill_connection(int connection_id);
|
||||
/* return -1 if it could not kill the connection.
|
||||
return 0 if killed successfully */
|
||||
int kill_connection(int connection_id);
|
||||
|
||||
/* kill connection in seconds seconds.
|
||||
return -1 if it can not kill the connection.
|
||||
return 0 if it will kill it */
|
||||
int kill_connection_in(int connection_id, uint32_t seconds);
|
||||
/* kill connection in seconds seconds.
|
||||
return -1 if it can not kill the connection.
|
||||
return 0 if it will kill it */
|
||||
int kill_connection_in(int connection_id, uint32_t seconds);
|
||||
|
||||
/* returns the ip_port of the corresponding connection.
|
||||
return 0 if there is no such connection. */
|
||||
IP_Port connection_ip(int connection_id);
|
||||
/* returns the ip_port of the corresponding connection.
|
||||
return 0 if there is no such connection. */
|
||||
IP_Port connection_ip(int connection_id);
|
||||
|
||||
/* returns the id of the next packet in the queue
|
||||
return -1 if no packet in queue */
|
||||
char id_packet(int connection_id);
|
||||
/* returns the id of the next packet in the queue
|
||||
return -1 if no packet in queue */
|
||||
char id_packet(int connection_id);
|
||||
|
||||
/* return 0 if there is no received data in the buffer.
|
||||
return length of received packet if successful */
|
||||
int read_packet(int connection_id, uint8_t *data);
|
||||
/* return 0 if there is no received data in the buffer.
|
||||
return length of received packet if successful */
|
||||
int read_packet(int connection_id, uint8_t *data);
|
||||
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
int write_packet(int connection_id, uint8_t *data, uint32_t length);
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
int write_packet(int connection_id, uint8_t *data, uint32_t length);
|
||||
|
||||
/* returns the number of packets in the queue waiting to be successfully sent. */
|
||||
uint32_t sendqueue(int connection_id);
|
||||
/* returns the number of packets in the queue waiting to be successfully sent. */
|
||||
uint32_t sendqueue(int connection_id);
|
||||
|
||||
/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
|
||||
uint32_t recvqueue(int connection_id);
|
||||
/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
|
||||
uint32_t recvqueue(int connection_id);
|
||||
|
||||
/* check if connection is connected
|
||||
return 0 no.
|
||||
return 1 if attempting handshake
|
||||
return 2 if handshake is done
|
||||
return 3 if fully connected
|
||||
return 4 if timed out and wating to be killed */
|
||||
int is_connected(int connection_id);
|
||||
/* check if connection is connected
|
||||
return 0 no.
|
||||
return 1 if attempting handshake
|
||||
return 2 if handshake is done
|
||||
return 3 if fully connected
|
||||
return 4 if timed out and wating to be killed */
|
||||
int is_connected(int connection_id);
|
||||
|
||||
/* Call this function a couple times per second
|
||||
It's the main loop. */
|
||||
void doLossless_UDP();
|
||||
/* Call this function a couple times per second
|
||||
It's the main loop. */
|
||||
void doLossless_UDP();
|
||||
|
||||
|
||||
/* if we receive a Lossless_UDP packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
/* if we receive a Lossless_UDP packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
124
core/Messenger.c
124
core/Messenger.c
|
@ -18,12 +18,12 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Messenger.h"
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
int crypt_connection_id;
|
||||
|
@ -49,7 +49,7 @@ static uint16_t self_userstatus_len;
|
|||
static Friend friendlist[MAX_NUM_FRIENDS];
|
||||
|
||||
static uint32_t numfriends;
|
||||
|
||||
|
||||
/* 1 if we are online
|
||||
0 if we are offline
|
||||
static uint8_t online; */
|
||||
|
@ -95,7 +95,7 @@ int getclient_id(int friend_id, uint8_t *client_id)
|
|||
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length == 0 || length >=
|
||||
(MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
|
||||
(MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
|
||||
return -1;
|
||||
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||
return -1;
|
||||
|
@ -113,7 +113,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
|
|||
friendlist[i].userstatus_length = 1;
|
||||
memcpy(friendlist[i].info, data, length);
|
||||
friendlist[i].info_size = length;
|
||||
|
||||
|
||||
++numfriends;
|
||||
return i;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
|
|||
if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
|
||||
return 0;
|
||||
if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
|
||||
/* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
|
||||
/* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
|
||||
return 0;
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
temp[0] = PACKET_ID_MESSAGE;
|
||||
|
@ -349,7 +349,8 @@ int initMessenger()
|
|||
|
||||
//TODO: make this function not suck.
|
||||
static void doFriends()
|
||||
{/* TODO: add incoming connections and some other stuff. */
|
||||
{
|
||||
/* TODO: add incoming connections and some other stuff. */
|
||||
uint32_t i;
|
||||
int len;
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
|
@ -370,19 +371,19 @@ static void doFriends()
|
|||
}
|
||||
IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
|
||||
switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) {
|
||||
case 0:
|
||||
if (friendip.ip.i > 1)
|
||||
friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
|
||||
break;
|
||||
case 3: /* Connection is established */
|
||||
friendlist[i].status = 4;
|
||||
break;
|
||||
case 4:
|
||||
crypto_kill(friendlist[i].crypt_connection_id);
|
||||
friendlist[i].crypt_connection_id = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
if (friendip.ip.i > 1)
|
||||
friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
|
||||
break;
|
||||
case 3: /* Connection is established */
|
||||
friendlist[i].status = 4;
|
||||
break;
|
||||
case 4:
|
||||
crypto_kill(friendlist[i].crypt_connection_id);
|
||||
friendlist[i].crypt_connection_id = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (friendlist[i].status == 4) { /* friend is online */
|
||||
|
@ -397,38 +398,37 @@ static void doFriends()
|
|||
len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
|
||||
if (len > 0) {
|
||||
switch (temp[0]) {
|
||||
case PACKET_ID_NICKNAME: {
|
||||
if (len != MAX_NAME_LENGTH + 1)
|
||||
break;
|
||||
if(friend_namechange_isset)
|
||||
friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
|
||||
memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
|
||||
friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */
|
||||
case PACKET_ID_NICKNAME: {
|
||||
if (len != MAX_NAME_LENGTH + 1)
|
||||
break;
|
||||
}
|
||||
case PACKET_ID_USERSTATUS: {
|
||||
uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
|
||||
memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
if (friend_statuschange_isset)
|
||||
friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
free(status);
|
||||
break;
|
||||
}
|
||||
case PACKET_ID_MESSAGE: {
|
||||
if (friend_message_isset)
|
||||
(*friend_message)(i, temp + 1, len - 1);
|
||||
break;
|
||||
}
|
||||
if(friend_namechange_isset)
|
||||
friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
|
||||
memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
|
||||
friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
|
||||
crypto_kill(friendlist[i].crypt_connection_id);
|
||||
friendlist[i].crypt_connection_id = -1;
|
||||
friendlist[i].status = 3;
|
||||
}
|
||||
break;
|
||||
case PACKET_ID_USERSTATUS: {
|
||||
uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
|
||||
memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
if (friend_statuschange_isset)
|
||||
friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
|
||||
free(status);
|
||||
break;
|
||||
}
|
||||
case PACKET_ID_MESSAGE: {
|
||||
if (friend_message_isset)
|
||||
(*friend_message)(i, temp + 1, len - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
|
||||
crypto_kill(friendlist[i].crypt_connection_id);
|
||||
friendlist[i].crypt_connection_id = -1;
|
||||
friendlist[i].status = 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,11 +443,11 @@ static void doInbound()
|
|||
if (inconnection != -1) {
|
||||
int friend_id = getfriend_id(public_key);
|
||||
if (friend_id != -1) {
|
||||
crypto_kill(friendlist[friend_id].crypt_connection_id);
|
||||
friendlist[friend_id].crypt_connection_id =
|
||||
accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
|
||||
|
||||
friendlist[friend_id].status = 3;
|
||||
crypto_kill(friendlist[friend_id].crypt_connection_id);
|
||||
friendlist[friend_id].crypt_connection_id =
|
||||
accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
|
||||
|
||||
friendlist[friend_id].status = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,8 +477,8 @@ void doMessenger()
|
|||
#ifdef DEBUG
|
||||
/* if(rand() % 3 != 1) //simulate packet loss */
|
||||
/* { */
|
||||
if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) &&
|
||||
friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port))
|
||||
if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) &&
|
||||
friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port))
|
||||
/* if packet is discarded */
|
||||
printf("Received unhandled packet with length: %u\n", length);
|
||||
else
|
||||
|
@ -505,7 +505,7 @@ void doMessenger()
|
|||
uint32_t Messenger_size()
|
||||
{
|
||||
return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
|
||||
+ sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends;
|
||||
+ sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends;
|
||||
}
|
||||
|
||||
/* save the messenger in data of size Messenger_size() */
|
||||
|
@ -537,7 +537,7 @@ int Messenger_load(uint8_t * data, uint32_t length)
|
|||
uint32_t size;
|
||||
memcpy(&size, data, sizeof(size));
|
||||
data += sizeof(size);
|
||||
|
||||
|
||||
if (length < size)
|
||||
return -1;
|
||||
length -= size;
|
||||
|
@ -548,12 +548,12 @@ int Messenger_load(uint8_t * data, uint32_t length)
|
|||
data += sizeof(size);
|
||||
if (length != size || length % sizeof(Friend) != 0)
|
||||
return -1;
|
||||
|
||||
|
||||
Friend * temp = malloc(size);
|
||||
memcpy(temp, data, size);
|
||||
|
||||
|
||||
uint16_t num = size / sizeof(Friend);
|
||||
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < num; ++i) {
|
||||
if(temp[i].status != 0) {
|
||||
|
|
170
core/Messenger.h
170
core/Messenger.h
|
@ -3,7 +3,7 @@
|
|||
* An implementation of a simple text chat only messenger on the tox network core.
|
||||
*
|
||||
* NOTE: All the text in the messages must be encoded using UTF-8
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -20,8 +20,8 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MESSENGER_H
|
||||
#define MESSENGER_H
|
||||
|
@ -42,111 +42,111 @@ extern "C" {
|
|||
#define PACKET_ID_USERSTATUS 49
|
||||
#define PACKET_ID_MESSAGE 64
|
||||
|
||||
/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased
|
||||
to an absurdly large number later */
|
||||
/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased
|
||||
to an absurdly large number later */
|
||||
|
||||
/* add a friend
|
||||
set the data that will be sent along with friend request
|
||||
client_id is the client id of the friend
|
||||
data is the data and length is the length
|
||||
returns the friend number if success
|
||||
return -1 if failure. */
|
||||
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
|
||||
/* add a friend
|
||||
set the data that will be sent along with friend request
|
||||
client_id is the client id of the friend
|
||||
data is the data and length is the length
|
||||
returns the friend number if success
|
||||
return -1 if failure. */
|
||||
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
/* add a friend without sending a friendrequest.
|
||||
returns the friend number if success
|
||||
return -1 if failure. */
|
||||
int m_addfriend_norequest(uint8_t *client_id);
|
||||
/* add a friend without sending a friendrequest.
|
||||
returns the friend number if success
|
||||
return -1 if failure. */
|
||||
int m_addfriend_norequest(uint8_t *client_id);
|
||||
|
||||
/* return the friend id associated to that client id.
|
||||
return -1 if no such friend */
|
||||
int getfriend_id(uint8_t *client_id);
|
||||
/* return the friend id associated to that client id.
|
||||
return -1 if no such friend */
|
||||
int getfriend_id(uint8_t *client_id);
|
||||
|
||||
/* copies the public key associated to that friend id into client_id buffer.
|
||||
make sure that client_id is of size CLIENT_ID_SIZE.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int getclient_id(int friend_id, uint8_t *client_id);
|
||||
/* copies the public key associated to that friend id into client_id buffer.
|
||||
make sure that client_id is of size CLIENT_ID_SIZE.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int getclient_id(int friend_id, uint8_t *client_id);
|
||||
|
||||
/* remove a friend */
|
||||
int m_delfriend(int friendnumber);
|
||||
/* remove a friend */
|
||||
int m_delfriend(int friendnumber);
|
||||
|
||||
/* return 4 if friend is online
|
||||
return 3 if friend is confirmed
|
||||
return 2 if the friend request was sent
|
||||
return 1 if the friend was added
|
||||
return 0 if there is no friend with that number */
|
||||
int m_friendstatus(int friendnumber);
|
||||
/* return 4 if friend is online
|
||||
return 3 if friend is confirmed
|
||||
return 2 if the friend request was sent
|
||||
return 1 if the friend was added
|
||||
return 0 if there is no friend with that number */
|
||||
int m_friendstatus(int friendnumber);
|
||||
|
||||
/* send a text chat message to an online friend
|
||||
returns 1 if packet was successfully put into the send queue
|
||||
return 0 if it was not */
|
||||
int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
|
||||
/* send a text chat message to an online friend
|
||||
returns 1 if packet was successfully put into the send queue
|
||||
return 0 if it was not */
|
||||
int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
|
||||
|
||||
/* Set our nickname
|
||||
name must be a string of maximum MAX_NAME_LENGTH length.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int setname(uint8_t *name, uint16_t length);
|
||||
/* Set our nickname
|
||||
name must be a string of maximum MAX_NAME_LENGTH length.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int setname(uint8_t *name, uint16_t length);
|
||||
|
||||
/* get name of friendnumber
|
||||
put it in name
|
||||
name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int getname(int friendnumber, uint8_t *name);
|
||||
/* get name of friendnumber
|
||||
put it in name
|
||||
name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
|
||||
return 0 if success
|
||||
return -1 if failure */
|
||||
int getname(int friendnumber, uint8_t *name);
|
||||
|
||||
/* set our user status
|
||||
you are responsible for freeing status after
|
||||
returns 0 on success, -1 on failure */
|
||||
int m_set_userstatus(uint8_t *status, uint16_t length);
|
||||
/* set our user status
|
||||
you are responsible for freeing status after
|
||||
returns 0 on success, -1 on failure */
|
||||
int m_set_userstatus(uint8_t *status, uint16_t length);
|
||||
|
||||
/* return the length of friendnumber's user status,
|
||||
including null
|
||||
pass it into malloc */
|
||||
int m_get_userstatus_size(int friendnumber);
|
||||
/* return the length of friendnumber's user status,
|
||||
including null
|
||||
pass it into malloc */
|
||||
int m_get_userstatus_size(int friendnumber);
|
||||
|
||||
/* copy friendnumber's userstatus into buf, truncating if size is over maxlen
|
||||
get the size you need to allocate from m_get_userstatus_size */
|
||||
int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen);
|
||||
/* copy friendnumber's userstatus into buf, truncating if size is over maxlen
|
||||
get the size you need to allocate from m_get_userstatus_size */
|
||||
int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen);
|
||||
|
||||
/* set the function that will be executed when a friend request is received.
|
||||
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
|
||||
void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
|
||||
/* set the function that will be executed when a friend request is received.
|
||||
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
|
||||
void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
|
||||
|
||||
/* set the function that will be executed when a message from a friend is received.
|
||||
function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
|
||||
void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
|
||||
/* set the function that will be executed when a message from a friend is received.
|
||||
function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
|
||||
void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
|
||||
|
||||
/* set the callback for name changes
|
||||
function(int friendnumber, uint8_t *newname, uint16_t length)
|
||||
you are not responsible for freeing newname */
|
||||
void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
|
||||
/* set the callback for name changes
|
||||
function(int friendnumber, uint8_t *newname, uint16_t length)
|
||||
you are not responsible for freeing newname */
|
||||
void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
|
||||
|
||||
/* set the callback for user status changes
|
||||
function(int friendnumber, uint8_t *newstatus, uint16_t length)
|
||||
you are not responsible for freeing newstatus */
|
||||
void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t));
|
||||
/* set the callback for user status changes
|
||||
function(int friendnumber, uint8_t *newstatus, uint16_t length)
|
||||
you are not responsible for freeing newstatus */
|
||||
void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t));
|
||||
|
||||
/* run this at startup
|
||||
returns 0 if no connection problems
|
||||
returns -1 if there are problems */
|
||||
int initMessenger();
|
||||
/* run this at startup
|
||||
returns 0 if no connection problems
|
||||
returns -1 if there are problems */
|
||||
int initMessenger();
|
||||
|
||||
/* the main loop that needs to be run at least 200 times per second */
|
||||
void doMessenger();
|
||||
/* the main loop that needs to be run at least 200 times per second */
|
||||
void doMessenger();
|
||||
|
||||
/* SAVING AND LOADING FUNCTIONS: */
|
||||
/* SAVING AND LOADING FUNCTIONS: */
|
||||
|
||||
/* returns the size of the messenger data (for saving) */
|
||||
uint32_t Messenger_size();
|
||||
/* returns the size of the messenger data (for saving) */
|
||||
uint32_t Messenger_size();
|
||||
|
||||
/* save the messenger in data (must be allocated memory of size Messenger_size()) */
|
||||
void Messenger_save(uint8_t *data);
|
||||
/* save the messenger in data (must be allocated memory of size Messenger_size()) */
|
||||
void Messenger_save(uint8_t *data);
|
||||
|
||||
/* load the messenger from data of size length */
|
||||
int Messenger_load(uint8_t *data, uint32_t length);
|
||||
/* load the messenger from data of size length */
|
||||
int Messenger_load(uint8_t *data, uint32_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* friend_requests.c
|
||||
*
|
||||
*
|
||||
* Handle friend requests.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "friend_requests.h"
|
||||
|
@ -26,7 +26,7 @@
|
|||
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
|
||||
/* Try to send a friendrequest to peer with public_key
|
||||
data is the data in the request and length is the length.
|
||||
data is the data in the request and length is the length.
|
||||
return -1 if failure.
|
||||
return 0 if it sent the friend request directly to the friend.
|
||||
return the number of peers it was routed through if it did not send it directly.*/
|
||||
|
@ -34,7 +34,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
|
|||
{
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */
|
||||
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -48,7 +48,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
|
|||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int num = route_tofriend(public_key, packet, len);
|
||||
|
||||
if (num == 0)
|
||||
|
@ -61,7 +61,8 @@ static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t);
|
|||
static uint8_t handle_friendrequest_isset = 0;
|
||||
|
||||
/* set the function that will be executed when a friend request is received. */
|
||||
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) {
|
||||
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
|
||||
{
|
||||
handle_friendrequest = function;
|
||||
handle_friendrequest_isset = 1;
|
||||
}
|
||||
|
@ -76,17 +77,19 @@ static uint8_t recieved_requests[MAX_RECIEVED_STORED][crypto_box_PUBLICKEYBYTES]
|
|||
static uint16_t recieved_requests_index;
|
||||
|
||||
/*Add to list of recieved friend requests*/
|
||||
static void addto_recievedlist(uint8_t * client_id) {
|
||||
static void addto_recievedlist(uint8_t * client_id)
|
||||
{
|
||||
if (recieved_requests_index >= MAX_RECIEVED_STORED)
|
||||
recieved_requests_index = 0;
|
||||
|
||||
|
||||
memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
|
||||
++recieved_requests_index;
|
||||
}
|
||||
|
||||
/* Check if a friend request was already recieved
|
||||
/* Check if a friend request was already recieved
|
||||
return 0 if not, 1 if we did */
|
||||
static int request_recieved(uint8_t * client_id) {
|
||||
static int request_recieved(uint8_t * client_id)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < MAX_RECIEVED_STORED; ++i) {
|
||||
|
@ -98,7 +101,8 @@ static int request_recieved(uint8_t * client_id) {
|
|||
}
|
||||
|
||||
|
||||
int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) {
|
||||
int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
{
|
||||
if (packet[0] == 32) {
|
||||
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
|
||||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
|
||||
|
@ -118,11 +122,10 @@ int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) {
|
|||
|
||||
addto_recievedlist(public_key);
|
||||
(*handle_friendrequest)(public_key, data, len);
|
||||
}
|
||||
else {/* if request is not for us, try routing it. */
|
||||
} else { /* if request is not for us, try routing it. */
|
||||
if(route_packet(packet + 1, packet, length) == length)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* friend_requests.h
|
||||
*
|
||||
*
|
||||
* Handle friend requests.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,11 +18,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FRIEND_REQUESTS_H
|
||||
#define FRIEND_REQUESTS_H
|
||||
#ifndef FRIEND_REQUESTS_H
|
||||
#define FRIEND_REQUESTS_H
|
||||
|
||||
#include "DHT.h"
|
||||
#include "net_crypto.h"
|
||||
|
@ -31,18 +31,18 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Try to send a friendrequest to peer with public_key
|
||||
data is the data in the request and length is the length. */
|
||||
int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length);
|
||||
/* Try to send a friendrequest to peer with public_key
|
||||
data is the data in the request and length is the length. */
|
||||
int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length);
|
||||
|
||||
/* set the function that will be executed when a friend request for us is received.
|
||||
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
|
||||
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
|
||||
/* set the function that will be executed when a friend request for us is received.
|
||||
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
|
||||
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
|
||||
|
||||
/* if we receive a packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
/* if we receive a packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* net_crypto.c
|
||||
*
|
||||
*
|
||||
* Functions for the core network crypto.
|
||||
* See also: docs/Crypto.txt
|
||||
*
|
||||
*
|
||||
* NOTE: This code has to be perfect. We don't mess around with encryption.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -21,7 +21,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "net_crypto.h"
|
||||
|
@ -37,11 +37,11 @@ typedef struct {
|
|||
uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */
|
||||
uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */
|
||||
uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
|
||||
uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
|
||||
uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
|
||||
(we have received a handshake but no empty data packet), 3 if the connection is established.
|
||||
4 if the connection is timed out. */
|
||||
uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
|
||||
|
||||
|
||||
} Crypto_Connection;
|
||||
|
||||
#define MAX_CRYPTO_CONNECTIONS 256
|
||||
|
@ -53,24 +53,24 @@ static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
|
|||
/* keeps track of the connection numbers for friends request so we can check later if they were sent */
|
||||
static int incoming_connections[MAX_INCOMING];
|
||||
|
||||
/* encrypts plain of length length to encrypted of length + 16 using the
|
||||
/* encrypts plain of length length to encrypted of length + 16 using the
|
||||
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
||||
return -1 if there was a problem.
|
||||
return length of encrypted data if everything was fine. */
|
||||
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *plain, uint32_t length, uint8_t *encrypted)
|
||||
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *plain, uint32_t length, uint8_t *encrypted)
|
||||
{
|
||||
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
|
||||
return -1;
|
||||
|
||||
|
||||
uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
|
||||
uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES];
|
||||
uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0};
|
||||
|
||||
|
||||
memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */
|
||||
|
||||
|
||||
crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key);
|
||||
|
||||
|
||||
/* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */
|
||||
if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0)
|
||||
return -1;
|
||||
|
@ -84,8 +84,8 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
|||
public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
|
||||
return -1 if there was a problem(decryption failed)
|
||||
return length of plain data if everything was fine. */
|
||||
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *encrypted, uint32_t length, uint8_t *plain)
|
||||
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *encrypted, uint32_t length, uint8_t *plain)
|
||||
{
|
||||
if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
|
||||
return -1;
|
||||
|
@ -93,11 +93,11 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
|||
uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES];
|
||||
uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
|
||||
uint8_t zeroes[crypto_box_ZEROBYTES] = {0};
|
||||
|
||||
|
||||
memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */
|
||||
|
||||
if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
|
||||
nonce, public_key, secret_key) == -1)
|
||||
|
||||
if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
|
||||
nonce, public_key, secret_key) == -1)
|
||||
return -1;
|
||||
|
||||
/* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */
|
||||
|
@ -130,13 +130,13 @@ void random_nonce(uint8_t *nonce)
|
|||
}
|
||||
}
|
||||
|
||||
/* return 0 if there is no received data in the buffer
|
||||
/* return 0 if there is no received data in the buffer
|
||||
return -1 if the packet was discarded.
|
||||
return length of received data if successful */
|
||||
int read_cryptpacket(int crypt_connection_id, uint8_t *data)
|
||||
{
|
||||
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
|
||||
return 0;
|
||||
return 0;
|
||||
if (crypto_connections[crypt_connection_id].status != 3)
|
||||
return 0;
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
|
@ -145,7 +145,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
|
|||
return 0;
|
||||
if (temp_data[0] != 3)
|
||||
return -1;
|
||||
int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
|
||||
int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
|
||||
crypto_connections[crypt_connection_id].sessionsecret_key,
|
||||
crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data);
|
||||
if (len != -1) {
|
||||
|
@ -160,13 +160,13 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
|
|||
int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
|
||||
return 0;
|
||||
return 0;
|
||||
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
|
||||
return 0;
|
||||
if (crypto_connections[crypt_connection_id].status != 3)
|
||||
return 0;
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
|
||||
int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
|
||||
crypto_connections[crypt_connection_id].sessionsecret_key,
|
||||
crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1);
|
||||
if (len == -1)
|
||||
|
@ -190,7 +190,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
|
|||
return -1;
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
random_nonce(nonce);
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
|
||||
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
@ -198,11 +198,11 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
|
|||
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
|
||||
|
||||
|
||||
return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
|
||||
}
|
||||
|
||||
/* puts the senders public key in the request in public_key, the data from the request
|
||||
/* puts the senders public key in the request in public_key, the data from the request
|
||||
in data if a friend or ping request was sent to us and returns the length of the data.
|
||||
packet is the request packet and length is its length
|
||||
return -1 if not valid request. */
|
||||
|
@ -210,19 +210,17 @@ int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t
|
|||
{
|
||||
|
||||
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
|
||||
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
|
||||
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||
{
|
||||
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
|
||||
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
||||
memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
|
||||
int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
|
||||
length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data);
|
||||
int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
|
||||
length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data);
|
||||
if(len1 == -1)
|
||||
return -1;
|
||||
return len1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -234,13 +232,13 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret
|
|||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
|
||||
|
||||
random_nonce(nonce);
|
||||
memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
|
||||
|
||||
int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
|
||||
if (len == -1)
|
||||
return 0;
|
||||
temp_data[0] = 2;
|
||||
|
@ -252,28 +250,27 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret
|
|||
/* Extract secret nonce, session public key and public_key from a packet(data) with length length
|
||||
return 1 if successful
|
||||
return 0 if failure */
|
||||
int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
|
||||
int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
|
||||
uint8_t *session_key, uint8_t *data, uint16_t length)
|
||||
{
|
||||
int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
|
||||
if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
|
||||
+ crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad)
|
||||
{
|
||||
if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
|
||||
+ crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) {
|
||||
return 0;
|
||||
}
|
||||
if (data[0] != 2)
|
||||
return 0;
|
||||
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
|
||||
|
||||
|
||||
memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
|
||||
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
||||
crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
|
||||
|
||||
|
||||
int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
|
||||
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
||||
crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
|
||||
|
||||
if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES)
|
||||
return 0;
|
||||
|
||||
|
||||
memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
|
||||
memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
|
||||
return 1;
|
||||
|
@ -316,9 +313,8 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
|
|||
memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
||||
crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
|
||||
|
||||
if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce,
|
||||
crypto_connections[i].sessionpublic_key) == 1)
|
||||
{
|
||||
if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce,
|
||||
crypto_connections[i].sessionpublic_key) == 1) {
|
||||
increment_nonce(crypto_connections[i].recv_nonce);
|
||||
return i;
|
||||
}
|
||||
|
@ -363,9 +359,9 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
|
|||
return 0 if killed successfully
|
||||
return 1 if there was a problem. */
|
||||
int crypto_kill(int crypt_connection_id)
|
||||
{
|
||||
{
|
||||
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
|
||||
return 1;
|
||||
return 1;
|
||||
if (crypto_connections[crypt_connection_id].status != 0) {
|
||||
crypto_connections[crypt_connection_id].status = 0;
|
||||
kill_connection(crypto_connections[crypt_connection_id].number);
|
||||
|
@ -400,9 +396,8 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
|
|||
|
||||
crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
|
||||
|
||||
if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce,
|
||||
crypto_connections[i].sessionpublic_key) == 1)
|
||||
{
|
||||
if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce,
|
||||
crypto_connections[i].sessionpublic_key) == 1) {
|
||||
increment_nonce(crypto_connections[i].recv_nonce);
|
||||
uint32_t zero = 0;
|
||||
crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */
|
||||
|
@ -413,10 +408,10 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
|
|||
return -1; /* this should never happen. */
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet
|
||||
/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet
|
||||
(we have received a handshake but no empty data packet), 3 if the connection is established.
|
||||
4 if the connection is timed out and waiting to be killed */
|
||||
int is_cryptoconnected(int crypt_connection_id)
|
||||
|
@ -471,9 +466,9 @@ static void handle_incomings()
|
|||
{
|
||||
int income;
|
||||
while (1) {
|
||||
income = incoming_connection();
|
||||
if(income == -1 || new_incoming(income) )
|
||||
break;
|
||||
income = incoming_connection();
|
||||
if(income == -1 || new_incoming(income) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,8 +483,8 @@ static void receive_crypto()
|
|||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint16_t len;
|
||||
if (id_packet(crypto_connections[i].number) == 1)
|
||||
/* if the packet is a friend request drop it (because we are already friends) */
|
||||
if (id_packet(crypto_connections[i].number) == 1)
|
||||
/* if the packet is a friend request drop it (because we are already friends) */
|
||||
len = read_packet(crypto_connections[i].number, temp_data);
|
||||
if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
|
||||
len = read_packet(crypto_connections[i].number, temp_data);
|
||||
|
@ -504,31 +499,28 @@ static void receive_crypto()
|
|||
crypto_connections[i].status = 2; /* set it to its proper value right after. */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
|
||||
} else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
|
||||
crypto_kill(crypto_connections[i].number);
|
||||
|
||||
|
||||
}
|
||||
if (crypto_connections[i].status == 2) {
|
||||
if (id_packet(crypto_connections[i].number) == 3) {
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
int length = read_packet(crypto_connections[i].number, temp_data);
|
||||
int len = decrypt_data(crypto_connections[i].peersessionpublic_key,
|
||||
int len = decrypt_data(crypto_connections[i].peersessionpublic_key,
|
||||
crypto_connections[i].sessionsecret_key,
|
||||
crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
|
||||
uint32_t zero = 0;
|
||||
if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
|
||||
increment_nonce(crypto_connections[i].recv_nonce);
|
||||
crypto_connections[i].status = 3;
|
||||
|
||||
|
||||
/* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */
|
||||
kill_connection_in(crypto_connections[i].number, 3000000);
|
||||
}
|
||||
else
|
||||
} else
|
||||
crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does
|
||||
}
|
||||
else if(id_packet(crypto_connections[i].number) != -1)
|
||||
} else if(id_packet(crypto_connections[i].number) != -1)
|
||||
/* This should not happen
|
||||
kill the connection if it does */
|
||||
crypto_kill(crypto_connections[i].number);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* net_crypto.h
|
||||
*
|
||||
*
|
||||
* Functions for the core network crypto.
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
|
@ -18,11 +18,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NET_CRYPTO_H
|
||||
#define NET_CRYPTO_H
|
||||
#ifndef NET_CRYPTO_H
|
||||
#define NET_CRYPTO_H
|
||||
|
||||
#include "Lossless_UDP.h"
|
||||
|
||||
|
@ -30,102 +30,102 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Our public key. */
|
||||
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
|
||||
/* Our public key. */
|
||||
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
|
||||
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
|
||||
|
||||
#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
||||
|
||||
/* encrypts plain of length length to encrypted of length + 16 using the
|
||||
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
||||
return -1 if there was a problem.
|
||||
return length of encrypted data if everything was fine. */
|
||||
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *plain, uint32_t length, uint8_t *encrypted);
|
||||
/* encrypts plain of length length to encrypted of length + 16 using the
|
||||
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
||||
return -1 if there was a problem.
|
||||
return length of encrypted data if everything was fine. */
|
||||
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *plain, uint32_t length, uint8_t *encrypted);
|
||||
|
||||
|
||||
/* decrypts encrypted of length length to plain of length length - 16 using the
|
||||
public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
|
||||
return -1 if there was a problem(decryption failed)
|
||||
return length of plain data if everything was fine. */
|
||||
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *encrypted, uint32_t length, uint8_t *plain);
|
||||
/* decrypts encrypted of length length to plain of length length - 16 using the
|
||||
public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
|
||||
return -1 if there was a problem(decryption failed)
|
||||
return length of plain data if everything was fine. */
|
||||
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint8_t *encrypted, uint32_t length, uint8_t *plain);
|
||||
|
||||
|
||||
/* fill the given nonce with random bytes. */
|
||||
void random_nonce(uint8_t *nonce);
|
||||
/* fill the given nonce with random bytes. */
|
||||
void random_nonce(uint8_t *nonce);
|
||||
|
||||
/* return 0 if there is no received data in the buffer
|
||||
return -1 if the packet was discarded.
|
||||
return length of received data if successful */
|
||||
int read_cryptpacket(int crypt_connection_id, uint8_t *data);
|
||||
/* return 0 if there is no received data in the buffer
|
||||
return -1 if the packet was discarded.
|
||||
return length of received data if successful */
|
||||
int read_cryptpacket(int crypt_connection_id, uint8_t *data);
|
||||
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
|
||||
|
||||
/* create a request to peer with public_key.
|
||||
packet must be an array of MAX_DATA_SIZE big.
|
||||
Data represents the data we send with the request with length being the length of the data.
|
||||
request_id is the id of the request (32 = friend request, 254 = ping request)
|
||||
returns -1 on failure
|
||||
returns the length of the created packet on success */
|
||||
int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id);
|
||||
/* create a request to peer with public_key.
|
||||
packet must be an array of MAX_DATA_SIZE big.
|
||||
Data represents the data we send with the request with length being the length of the data.
|
||||
request_id is the id of the request (32 = friend request, 254 = ping request)
|
||||
returns -1 on failure
|
||||
returns the length of the created packet on success */
|
||||
int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id);
|
||||
|
||||
/* puts the senders public key in the request in public_key, the data from the request
|
||||
in data if a friend or ping request was sent to us and returns the length of the data.
|
||||
packet is the request packet and length is its length
|
||||
return -1 if not valid request. */
|
||||
int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length);
|
||||
/* puts the senders public key in the request in public_key, the data from the request
|
||||
in data if a friend or ping request was sent to us and returns the length of the data.
|
||||
packet is the request packet and length is its length
|
||||
return -1 if not valid request. */
|
||||
int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length);
|
||||
|
||||
/* Start a secure connection with other peer who has public_key and ip_port
|
||||
returns -1 if failure
|
||||
returns crypt_connection_id of the initialized connection if everything went well. */
|
||||
int crypto_connect(uint8_t *public_key, IP_Port ip_port);
|
||||
/* Start a secure connection with other peer who has public_key and ip_port
|
||||
returns -1 if failure
|
||||
returns crypt_connection_id of the initialized connection if everything went well. */
|
||||
int crypto_connect(uint8_t *public_key, IP_Port ip_port);
|
||||
|
||||
/* kill a crypto connection
|
||||
return 0 if killed successfully
|
||||
return 1 if there was a problem. */
|
||||
int crypto_kill(int crypt_connection_id);
|
||||
/* kill a crypto connection
|
||||
return 0 if killed successfully
|
||||
return 1 if there was a problem. */
|
||||
int crypto_kill(int crypt_connection_id);
|
||||
|
||||
/* handle an incoming connection
|
||||
return -1 if no crypto inbound connection
|
||||
return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection
|
||||
Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
|
||||
and the session public key for the connection in session_key
|
||||
to accept it see: accept_crypto_inbound(...)
|
||||
to refuse it just call kill_connection(...) on the connection id */
|
||||
int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
|
||||
/* handle an incoming connection
|
||||
return -1 if no crypto inbound connection
|
||||
return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection
|
||||
Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
|
||||
and the session public key for the connection in session_key
|
||||
to accept it see: accept_crypto_inbound(...)
|
||||
to refuse it just call kill_connection(...) on the connection id */
|
||||
int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
|
||||
|
||||
/* accept an incoming connection using the parameters provided by crypto_inbound
|
||||
return -1 if not successful
|
||||
returns the crypt_connection_id if successful */
|
||||
int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
|
||||
/* accept an incoming connection using the parameters provided by crypto_inbound
|
||||
return -1 if not successful
|
||||
returns the crypt_connection_id if successful */
|
||||
int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
|
||||
|
||||
/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
|
||||
(we have received a handshake but no empty data packet), 3 if the connection is established.
|
||||
4 if the connection is timed out and waiting to be killed */
|
||||
int is_cryptoconnected(int crypt_connection_id);
|
||||
/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
|
||||
(we have received a handshake but no empty data packet), 3 if the connection is established.
|
||||
4 if the connection is timed out and waiting to be killed */
|
||||
int is_cryptoconnected(int crypt_connection_id);
|
||||
|
||||
|
||||
/* Generate our public and private keys
|
||||
Only call this function the first time the program starts. */
|
||||
void new_keys();
|
||||
/* Generate our public and private keys
|
||||
Only call this function the first time the program starts. */
|
||||
void new_keys();
|
||||
|
||||
/* save the public and private keys to the keys array
|
||||
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
|
||||
void save_keys(uint8_t * keys);
|
||||
/* save the public and private keys to the keys array
|
||||
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
|
||||
void save_keys(uint8_t * keys);
|
||||
|
||||
/* load the public and private keys from the keys array
|
||||
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
|
||||
void load_keys(uint8_t * keys);
|
||||
/* load the public and private keys from the keys array
|
||||
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
|
||||
void load_keys(uint8_t * keys);
|
||||
|
||||
/* run this to (re)initialize net_crypto
|
||||
sets all the global connection variables to their default values. */
|
||||
void initNetCrypto();
|
||||
/* run this to (re)initialize net_crypto
|
||||
sets all the global connection variables to their default values. */
|
||||
void initNetCrypto();
|
||||
|
||||
/* main loop */
|
||||
void doNetCrypto();
|
||||
/* main loop */
|
||||
void doNetCrypto();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* network.h
|
||||
*
|
||||
*
|
||||
* Functions for the core networking.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "network.h"
|
||||
|
@ -27,7 +27,7 @@
|
|||
uint64_t current_time()
|
||||
{
|
||||
uint64_t time;
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
/* This probably works fine */
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
@ -36,24 +36,24 @@ uint64_t current_time()
|
|||
time |= ft.dwLowDateTime;
|
||||
time -= 116444736000000000UL;
|
||||
return time/10;
|
||||
#else
|
||||
#else
|
||||
struct timeval a;
|
||||
gettimeofday(&a, NULL);
|
||||
time = 1000000UL*a.tv_sec + a.tv_usec;
|
||||
return time;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return a random number
|
||||
NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */
|
||||
uint32_t random_int()
|
||||
{
|
||||
#ifndef VANILLA_NACL
|
||||
#ifndef VANILLA_NACL
|
||||
//NOTE: this function comes from libsodium
|
||||
return randombytes_random();
|
||||
#else
|
||||
#else
|
||||
return random();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* our UDP socket, a global variable. */
|
||||
|
@ -63,7 +63,7 @@ static int sock;
|
|||
Function to send packet(data) of length length to ip_port */
|
||||
int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length)
|
||||
{
|
||||
ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
|
||||
ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
|
||||
return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
|
||||
}
|
||||
|
||||
|
@ -74,15 +74,15 @@ int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length)
|
|||
int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
|
||||
{
|
||||
ADDR addr;
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
int addrlen = sizeof(addr);
|
||||
#else
|
||||
#else
|
||||
uint32_t addrlen = sizeof(addr);
|
||||
#endif
|
||||
#endif
|
||||
(*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
|
||||
if (*(int32_t*)length <= 0)
|
||||
return -1; /* nothing received or empty packet */
|
||||
|
||||
|
||||
ip_port->ip = addr.ip;
|
||||
ip_port->port = addr.port;
|
||||
return 0;
|
||||
|
@ -92,30 +92,30 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
|
|||
bind to ip and port
|
||||
ip must be in network order EX: 127.0.0.1 = (7F000001)
|
||||
port is in host byte order (this means don't worry about it)
|
||||
returns 0 if no problems
|
||||
returns 0 if no problems
|
||||
returns -1 if there are problems */
|
||||
int init_networking(IP ip, uint16_t port)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
|
||||
return -1;
|
||||
#else
|
||||
#else
|
||||
srandom((uint32_t)current_time());
|
||||
#endif
|
||||
#endif
|
||||
srand((uint32_t)current_time());
|
||||
|
||||
/* initialize our socket */
|
||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
/* Check for socket error */
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
if (sock == INVALID_SOCKET) /* MSDN recommends this */
|
||||
return -1;
|
||||
#else
|
||||
#else
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Functions to increase the size of the send and receive UDP buffers
|
||||
NOTE: uncomment if necessary */
|
||||
|
@ -129,23 +129,23 @@ int init_networking(IP ip, uint16_t port)
|
|||
if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1)
|
||||
return -1;
|
||||
*/
|
||||
|
||||
|
||||
/* Enable broadcast on socket */
|
||||
int broadcast = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast));
|
||||
|
||||
/* Set socket nonblocking */
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
/* I think this works for windows */
|
||||
u_long mode = 1;
|
||||
/* ioctl(sock, FIONBIO, &mode); */
|
||||
ioctlsocket(sock, FIONBIO, &mode);
|
||||
#else
|
||||
ioctlsocket(sock, FIONBIO, &mode);
|
||||
#else
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK, 1);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Bind our socket to port PORT and address 0.0.0.0 */
|
||||
ADDR addr = {AF_INET, htons(port), ip};
|
||||
ADDR addr = {AF_INET, htons(port), ip};
|
||||
bind(sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
|
||||
return 0;
|
||||
|
@ -155,12 +155,12 @@ int init_networking(IP ip, uint16_t port)
|
|||
/* function to cleanup networking stuff */
|
||||
void shutdown_networking()
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#else
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
104
core/network.h
104
core/network.h
|
@ -1,5 +1,5 @@
|
|||
/* network.h
|
||||
*
|
||||
*
|
||||
* Datatypes, functions and includes for the core networking.
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
|
@ -18,11 +18,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -46,7 +46,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -69,63 +69,63 @@ extern "C" {
|
|||
|
||||
#define MAX_UDP_PACKET_SIZE 65507
|
||||
|
||||
typedef union {
|
||||
uint8_t c[4];
|
||||
uint16_t s[2];
|
||||
uint32_t i;
|
||||
} IP;
|
||||
typedef union {
|
||||
uint8_t c[4];
|
||||
uint16_t s[2];
|
||||
uint32_t i;
|
||||
} IP;
|
||||
|
||||
typedef struct {
|
||||
IP ip;
|
||||
uint16_t port;
|
||||
/* not used for anything right now */
|
||||
uint16_t padding;
|
||||
} IP_Port;
|
||||
typedef struct {
|
||||
IP ip;
|
||||
uint16_t port;
|
||||
/* not used for anything right now */
|
||||
uint16_t padding;
|
||||
} IP_Port;
|
||||
|
||||
typedef struct {
|
||||
int16_t family;
|
||||
uint16_t port;
|
||||
IP ip;
|
||||
uint8_t zeroes[8];
|
||||
#ifdef ENABLE_IPV6
|
||||
uint8_t zeroes2[12];
|
||||
#endif
|
||||
} ADDR;
|
||||
typedef struct {
|
||||
int16_t family;
|
||||
uint16_t port;
|
||||
IP ip;
|
||||
uint8_t zeroes[8];
|
||||
#ifdef ENABLE_IPV6
|
||||
uint8_t zeroes2[12];
|
||||
#endif
|
||||
} ADDR;
|
||||
|
||||
/* returns current time in milleseconds since the epoch. */
|
||||
uint64_t current_time();
|
||||
/* returns current time in milleseconds since the epoch. */
|
||||
uint64_t current_time();
|
||||
|
||||
/* return a random number
|
||||
NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */
|
||||
uint32_t random_int();
|
||||
/* return a random number
|
||||
NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */
|
||||
uint32_t random_int();
|
||||
|
||||
/* Basic network functions: */
|
||||
/* Basic network functions: */
|
||||
|
||||
/* Function to send packet(data) of length length to ip_port */
|
||||
int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length);
|
||||
/* Function to send packet(data) of length length to ip_port */
|
||||
int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length);
|
||||
|
||||
/* Function to receive data, ip and port of sender is put into ip_port
|
||||
the packet data into data
|
||||
the packet length into length. */
|
||||
int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length);
|
||||
/* Function to receive data, ip and port of sender is put into ip_port
|
||||
the packet data into data
|
||||
the packet length into length. */
|
||||
int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length);
|
||||
|
||||
/* initialize networking
|
||||
bind to ip and port
|
||||
ip must be in network order EX: 127.0.0.1 = (7F000001)
|
||||
port is in host byte order (this means don't worry about it)
|
||||
returns 0 if no problems
|
||||
returns -1 if there were problems */
|
||||
int init_networking(IP ip, uint16_t port);
|
||||
/* initialize networking
|
||||
bind to ip and port
|
||||
ip must be in network order EX: 127.0.0.1 = (7F000001)
|
||||
port is in host byte order (this means don't worry about it)
|
||||
returns 0 if no problems
|
||||
returns -1 if there were problems */
|
||||
int init_networking(IP ip, uint16_t port);
|
||||
|
||||
/* function to cleanup networking stuff(doesn't do much right now) */
|
||||
void shutdown_networking();
|
||||
/* function to cleanup networking stuff(doesn't do much right now) */
|
||||
void shutdown_networking();
|
||||
|
||||
/* resolves provided address to a binary data in network byte order
|
||||
address is ASCII null terminated string
|
||||
address should represent IPv4, IPv6 or a hostname
|
||||
on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i
|
||||
on failure returns -1 */
|
||||
int resolve_addr(char *address);
|
||||
/* resolves provided address to a binary data in network byte order
|
||||
address is ASCII null terminated string
|
||||
address should represent IPv4, IPv6 or a hostname
|
||||
on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i
|
||||
on failure returns -1 */
|
||||
int resolve_addr(char *address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user