mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Move unix_time(), id_cpy()/id_eq(), is_timeout() to util.*
unix_time(): - returns local value for current epoch - value is updated explicitly with unix_time_update() called at new_DHT()/doMessenger()/do_DHT() is_timeout(): - uses the local value for current epoch id_cpy()/id_eq() => id_copy()/id_equal(): - centralized duplicate definitions - replaced (most) memcpy()/memcmp() of (*, *, CLIENT_ID_SIZE) with id_copy()/id_equal()
This commit is contained in:
parent
e9d92606d9
commit
0a4c3d7e2e
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
/* DHT boostrap
|
/* DHT boostrap
|
||||||
*
|
*
|
||||||
* A simple DHT boostrap server for tox.
|
* A simple DHT boostrap server for tox.
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +29,8 @@
|
||||||
#include "../toxcore/DHT.h"
|
#include "../toxcore/DHT.h"
|
||||||
#include "../toxcore/LAN_discovery.h"
|
#include "../toxcore/LAN_discovery.h"
|
||||||
#include "../toxcore/friend_requests.h"
|
#include "../toxcore/friend_requests.h"
|
||||||
|
#include "../toxcore/util.h"
|
||||||
|
|
||||||
#include "../testing/misc_tools.c"
|
#include "../testing/misc_tools.c"
|
||||||
|
|
||||||
/* Sleep function (x = milliseconds) */
|
/* Sleep function (x = milliseconds) */
|
||||||
|
@ -147,7 +151,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
do_DHT(dht);
|
do_DHT(dht);
|
||||||
|
|
||||||
if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) {
|
if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
|
||||||
send_LANdiscovery(htons(PORT), dht->c);
|
send_LANdiscovery(htons(PORT), dht->c);
|
||||||
last_LANdiscovery = unix_time();
|
last_LANdiscovery = unix_time();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,25 +115,14 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int id_equal(uint8_t *a, uint8_t *b)
|
|
||||||
{
|
|
||||||
return memcmp(a, b, CLIENT_ID_SIZE) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
|
|
||||||
{
|
|
||||||
return timestamp + timeout <= time_now;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id)
|
static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
/* Dead nodes are considered dead (not in the list)*/
|
/* Dead nodes are considered dead (not in the list)*/
|
||||||
if (!is_timeout(temp_time, list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
|
if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
|
||||||
!is_timeout(temp_time, list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
|
!is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
|
||||||
if (id_equal(list[i].client_id, client_id))
|
if (id_equal(list[i].client_id, client_id))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -272,7 +261,7 @@ static int friend_number(DHT *dht, uint8_t *client_id)
|
||||||
*/
|
*/
|
||||||
static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
|
static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
|
||||||
sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
|
sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
|
||||||
time_t timestamp, int *num_nodes_ptr, uint8_t is_LAN)
|
int *num_nodes_ptr, uint8_t is_LAN)
|
||||||
{
|
{
|
||||||
if ((sa_family != AF_INET) && (sa_family != AF_INET6))
|
if ((sa_family != AF_INET) && (sa_family != AF_INET6))
|
||||||
return;
|
return;
|
||||||
|
@ -295,7 +284,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
|
||||||
ipptp = &client->assoc6;
|
ipptp = &client->assoc6;
|
||||||
|
|
||||||
/* node not in a good condition? */
|
/* node not in a good condition? */
|
||||||
if (is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT))
|
if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
IP *client_ip = &ipptp->ip_port.ip;
|
IP *client_ip = &ipptp->ip_port.ip;
|
||||||
|
@ -366,15 +355,14 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
|
||||||
*/
|
*/
|
||||||
static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN)
|
static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN)
|
||||||
{
|
{
|
||||||
time_t timestamp = unix_time();
|
|
||||||
int num_nodes = 0, i;
|
int num_nodes = 0, i;
|
||||||
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
||||||
dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes, is_LAN);
|
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN);
|
||||||
|
|
||||||
for (i = 0; i < dht->num_friends; ++i)
|
for (i = 0; i < dht->num_friends; ++i)
|
||||||
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
|
||||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||||
timestamp, &num_nodes, is_LAN);
|
&num_nodes, is_LAN);
|
||||||
|
|
||||||
return num_nodes;
|
return num_nodes;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +381,6 @@ static int replace_bad( Client_data *list,
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
/* If node is bad */
|
/* If node is bad */
|
||||||
|
@ -405,10 +392,10 @@ static int replace_bad( Client_data *list,
|
||||||
else
|
else
|
||||||
ipptp = &client->assoc6;
|
ipptp = &client->assoc6;
|
||||||
|
|
||||||
if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) {
|
if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
|
memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
|
||||||
ipptp->ip_port = ip_port;
|
ipptp->ip_port = ip_port;
|
||||||
ipptp->timestamp = temp_time;
|
ipptp->timestamp = unix_time();
|
||||||
|
|
||||||
ip_reset(&ipptp->ret_ip_port.ip);
|
ip_reset(&ipptp->ret_ip_port.ip);
|
||||||
ipptp->ret_ip_port.port = 0;
|
ipptp->ret_ip_port.port = 0;
|
||||||
|
@ -587,10 +574,9 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t pinging;
|
uint8_t pinging;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
|
for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
|
||||||
if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
|
if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
|
||||||
pinging = 0;
|
pinging = 0;
|
||||||
|
|
||||||
if (ping_id != 0 && dht->send_nodes[i].id == ping_id)
|
if (ping_id != 0 && dht->send_nodes[i].id == ping_id)
|
||||||
|
@ -612,12 +598,11 @@ static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < PING_TIMEOUT; ++i ) {
|
for (i = 0; i < PING_TIMEOUT; ++i ) {
|
||||||
for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
|
for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
|
||||||
if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
|
if (is_timeout(dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
|
||||||
dht->send_nodes[j].timestamp = temp_time;
|
dht->send_nodes[j].timestamp = unix_time();
|
||||||
dht->send_nodes[j].ip_port = ip_port;
|
dht->send_nodes[j].ip_port = ip_port;
|
||||||
dht->send_nodes[j].id = ping_id;
|
dht->send_nodes[j].id = ping_id;
|
||||||
return ping_id;
|
return ping_id;
|
||||||
|
@ -937,7 +922,6 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
|
||||||
*/
|
*/
|
||||||
static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
|
static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
|
||||||
{
|
{
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
uint32_t i, num = 0;
|
uint32_t i, num = 0;
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
|
@ -946,7 +930,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
|
||||||
|
|
||||||
for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
|
for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
|
||||||
if (ipport_isset(&(assoc->ip_port)) &&
|
if (ipport_isset(&(assoc->ip_port)) &&
|
||||||
!is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
!is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
getnodes(dht, assoc->ip_port, list[i].client_id, client_id);
|
getnodes(dht, assoc->ip_port, list[i].client_id, client_id);
|
||||||
++num;
|
++num;
|
||||||
|
|
||||||
|
@ -1016,7 +1000,6 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id)
|
||||||
int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
|
int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
ip_reset(&ip_port->ip);
|
ip_reset(&ip_port->ip);
|
||||||
ip_port->port = 0;
|
ip_port->port = 0;
|
||||||
|
@ -1032,7 +1015,7 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
|
||||||
uint32_t a;
|
uint32_t a;
|
||||||
|
|
||||||
for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
|
for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
|
||||||
if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
|
if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
*ip_port = assoc->ip_port;
|
*ip_port = assoc->ip_port;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1063,14 +1046,14 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
|
||||||
uint32_t a;
|
uint32_t a;
|
||||||
|
|
||||||
for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
|
for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
|
||||||
if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) {
|
if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) {
|
||||||
if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) {
|
if (is_timeout(assoc->last_pinged, PING_INTERVAL)) {
|
||||||
send_ping_request(dht->ping, assoc->ip_port, client->client_id );
|
send_ping_request(dht->ping, assoc->ip_port, client->client_id );
|
||||||
assoc->last_pinged = temp_time;
|
assoc->last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If node is good. */
|
/* If node is good. */
|
||||||
if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
|
if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
client_list[num_nodes] = client;
|
client_list[num_nodes] = client;
|
||||||
assoc_list[num_nodes] = assoc;
|
assoc_list[num_nodes] = assoc;
|
||||||
++num_nodes;
|
++num_nodes;
|
||||||
|
@ -1078,8 +1061,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((num_nodes != 0) &&
|
if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) {
|
||||||
is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) {
|
|
||||||
uint32_t rand_node = rand() % num_nodes;
|
uint32_t rand_node = rand() % num_nodes;
|
||||||
getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
|
getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
|
||||||
client_id);
|
client_id);
|
||||||
|
@ -1174,9 +1156,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
|
||||||
*/
|
*/
|
||||||
static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
if (friend_num >= dht->num_friends)
|
if (friend_num >= dht->num_friends)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1187,20 +1166,21 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
|
||||||
IP_Port ipv6s[MAX_FRIEND_CLIENTS];
|
IP_Port ipv6s[MAX_FRIEND_CLIENTS];
|
||||||
int num_ipv6s = 0;
|
int num_ipv6s = 0;
|
||||||
uint8_t connected;
|
uint8_t connected;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
||||||
client = &(friend->client_list[i]);
|
client = &(friend->client_list[i]);
|
||||||
connected = 0;
|
connected = 0;
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
|
ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
|
||||||
++num_ipv4s;
|
++num_ipv4s;
|
||||||
|
|
||||||
connected = 1;
|
connected = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(temp_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
|
ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
|
||||||
++num_ipv6s;
|
++num_ipv6s;
|
||||||
|
|
||||||
|
@ -1260,7 +1240,6 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
if (ip_num < (MAX_FRIEND_CLIENTS / 2))
|
if (ip_num < (MAX_FRIEND_CLIENTS / 2))
|
||||||
return 0; /* Reason for that? */
|
return 0; /* Reason for that? */
|
||||||
|
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
DHT_Friend *friend = &dht->friends_list[num];
|
DHT_Friend *friend = &dht->friends_list[num];
|
||||||
Client_data *client;
|
Client_data *client;
|
||||||
|
|
||||||
|
@ -1283,7 +1262,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (ip_isset(&assoc->ret_ip_port.ip) &&
|
if (ip_isset(&assoc->ret_ip_port.ip) &&
|
||||||
!is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
!is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
|
int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
|
||||||
|
|
||||||
if ((unsigned int)retval == length) {
|
if ((unsigned int)retval == length) {
|
||||||
|
@ -1313,7 +1292,6 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
|
||||||
IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
|
IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
|
||||||
int n = 0;
|
int n = 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
/* extra legwork, because having the outside allocating the space for us
|
/* extra legwork, because having the outside allocating the space for us
|
||||||
* is *usually* good(tm) (bites us in the behind in this case though) */
|
* is *usually* good(tm) (bites us in the behind in this case though) */
|
||||||
|
@ -1330,7 +1308,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
|
||||||
assoc = &client->assoc6;
|
assoc = &client->assoc6;
|
||||||
|
|
||||||
/* If ip is not zero and node is good. */
|
/* If ip is not zero and node is good. */
|
||||||
if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|
||||||
ip_list[n] = assoc->ip_port;
|
ip_list[n] = assoc->ip_port;
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
@ -1556,6 +1534,9 @@ static void do_NAT(DHT *dht)
|
||||||
|
|
||||||
DHT *new_DHT(Net_Crypto *c)
|
DHT *new_DHT(Net_Crypto *c)
|
||||||
{
|
{
|
||||||
|
/* init time */
|
||||||
|
unix_time_update();
|
||||||
|
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -1584,6 +1565,8 @@ DHT *new_DHT(Net_Crypto *c)
|
||||||
|
|
||||||
void do_DHT(DHT *dht)
|
void do_DHT(DHT *dht)
|
||||||
{
|
{
|
||||||
|
unix_time_update();
|
||||||
|
|
||||||
do_Close(dht);
|
do_Close(dht);
|
||||||
do_DHT_friends(dht);
|
do_DHT_friends(dht);
|
||||||
do_NAT(dht);
|
do_NAT(dht);
|
||||||
|
@ -1860,13 +1843,13 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
|
||||||
int DHT_isconnected(DHT *dht)
|
int DHT_isconnected(DHT *dht)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
unix_time_update();
|
||||||
|
|
||||||
for (i = 0; i < LCLIENT_LIST; ++i) {
|
for (i = 0; i < LCLIENT_LIST; ++i) {
|
||||||
Client_data *client = &dht->close_clientlist[i];
|
Client_data *client = &dht->close_clientlist[i];
|
||||||
|
|
||||||
if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
|
if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
|
||||||
!is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT))
|
!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "LAN_discovery.h"
|
#include "LAN_discovery.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define MAX_INTERFACES 16
|
#define MAX_INTERFACES 16
|
||||||
|
|
||||||
|
@ -214,7 +215,7 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
|
||||||
{
|
{
|
||||||
uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
|
uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
|
||||||
data[0] = NET_PACKET_LAN_DISCOVERY;
|
data[0] = NET_PACKET_LAN_DISCOVERY;
|
||||||
memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(data + 1, c->self_public_key);
|
||||||
|
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
|
||||||
|
|
|
@ -92,7 +92,7 @@ int getfriend_id(Messenger *m, uint8_t *client_id)
|
||||||
|
|
||||||
for (i = 0; i < m->numfriends; ++i) {
|
for (i = 0; i < m->numfriends; ++i) {
|
||||||
if (m->friendlist[i].status > 0)
|
if (m->friendlist[i].status > 0)
|
||||||
if (memcmp(client_id, m->friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(client_id, m->friendlist[i].client_id))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
|
||||||
*/
|
*/
|
||||||
void getaddress(Messenger *m, uint8_t *address)
|
void getaddress(Messenger *m, uint8_t *address)
|
||||||
{
|
{
|
||||||
memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(address, m->net_crypto->self_public_key);
|
||||||
uint32_t nospam = get_nospam(&(m->fr));
|
uint32_t nospam = get_nospam(&(m->fr));
|
||||||
memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
|
memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
|
||||||
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
||||||
|
@ -173,7 +173,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
|
||||||
return FAERR_TOOLONG;
|
return FAERR_TOOLONG;
|
||||||
|
|
||||||
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
|
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
|
||||||
memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
|
id_copy(client_id, address);
|
||||||
uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
||||||
memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
|
memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
|
||||||
if (length < 1)
|
if (length < 1)
|
||||||
return FAERR_NOMESSAGE;
|
return FAERR_NOMESSAGE;
|
||||||
|
|
||||||
if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(client_id, m->net_crypto->self_public_key))
|
||||||
return FAERR_OWNKEY;
|
return FAERR_OWNKEY;
|
||||||
|
|
||||||
int friend_id = getfriend_id(m, client_id);
|
int friend_id = getfriend_id(m, client_id);
|
||||||
|
@ -214,7 +214,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
|
||||||
m->friendlist[i].crypt_connection_id = -1;
|
m->friendlist[i].crypt_connection_id = -1;
|
||||||
m->friendlist[i].friendrequest_lastsent = 0;
|
m->friendlist[i].friendrequest_lastsent = 0;
|
||||||
m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT;
|
m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT;
|
||||||
memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
|
id_copy(m->friendlist[i].client_id, client_id);
|
||||||
m->friendlist[i].statusmessage = calloc(1, 1);
|
m->friendlist[i].statusmessage = calloc(1, 1);
|
||||||
m->friendlist[i].statusmessage_length = 1;
|
m->friendlist[i].statusmessage_length = 1;
|
||||||
m->friendlist[i].userstatus = USERSTATUS_NONE;
|
m->friendlist[i].userstatus = USERSTATUS_NONE;
|
||||||
|
@ -243,7 +243,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
|
||||||
if (realloc_friendlist(m, m->numfriends + 1) != 0)
|
if (realloc_friendlist(m, m->numfriends + 1) != 0)
|
||||||
return FAERR_NOMEM;
|
return FAERR_NOMEM;
|
||||||
|
|
||||||
if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(client_id, m->net_crypto->self_public_key))
|
||||||
return FAERR_OWNKEY;
|
return FAERR_OWNKEY;
|
||||||
|
|
||||||
memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
|
memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
|
||||||
|
@ -256,7 +256,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
|
||||||
m->friendlist[i].status = FRIEND_CONFIRMED;
|
m->friendlist[i].status = FRIEND_CONFIRMED;
|
||||||
m->friendlist[i].crypt_connection_id = -1;
|
m->friendlist[i].crypt_connection_id = -1;
|
||||||
m->friendlist[i].friendrequest_lastsent = 0;
|
m->friendlist[i].friendrequest_lastsent = 0;
|
||||||
memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
|
id_copy(m->friendlist[i].client_id, client_id);
|
||||||
m->friendlist[i].statusmessage = calloc(1, 1);
|
m->friendlist[i].statusmessage = calloc(1, 1);
|
||||||
m->friendlist[i].statusmessage_length = 1;
|
m->friendlist[i].statusmessage_length = 1;
|
||||||
m->friendlist[i].userstatus = USERSTATUS_NONE;
|
m->friendlist[i].userstatus = USERSTATUS_NONE;
|
||||||
|
@ -728,7 +728,7 @@ static int group_num(Messenger *m, uint8_t *group_public_key)
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < m->numchats; ++i) {
|
for (i = 0; i < m->numchats; ++i) {
|
||||||
if (memcmp(m->chats[i]->self_public_key, group_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(m->chats[i]->self_public_key, group_public_key))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,8 +917,8 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_
|
||||||
if (groupnum == -1)
|
if (groupnum == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(data, friend_group_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(data, friend_group_public_key);
|
||||||
memcpy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key);
|
||||||
|
|
||||||
if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) {
|
if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) {
|
||||||
chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber),
|
chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber),
|
||||||
|
@ -965,7 +965,7 @@ static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t
|
||||||
if (m->chats[i] == NULL)
|
if (m->chats[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (memcmp(packet + 1, m->chats[i]->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(packet + 1, m->chats[i]->self_public_key))
|
||||||
return handle_groupchatpacket(m->chats[i], source, packet, length);
|
return handle_groupchatpacket(m->chats[i], source, packet, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1769,6 +1769,8 @@ static char *ID2String(uint8_t *client_id)
|
||||||
/* The main loop that needs to be run at least 20 times per second. */
|
/* The main loop that needs to be run at least 20 times per second. */
|
||||||
void doMessenger(Messenger *m)
|
void doMessenger(Messenger *m)
|
||||||
{
|
{
|
||||||
|
unix_time_update();
|
||||||
|
|
||||||
networking_poll(m->net);
|
networking_poll(m->net);
|
||||||
|
|
||||||
do_DHT(m->dht);
|
do_DHT(m->dht);
|
||||||
|
@ -1996,7 +1998,7 @@ static int Messenger_load_old(Messenger *m, uint8_t *data, uint32_t length)
|
||||||
} else if (friend_list[i].status != 0) {
|
} else if (friend_list[i].status != 0) {
|
||||||
/* TODO: This is not a good way to do this. */
|
/* TODO: This is not a good way to do this. */
|
||||||
uint8_t address[FRIEND_ADDRESS_SIZE];
|
uint8_t address[FRIEND_ADDRESS_SIZE];
|
||||||
memcpy(address, friend_list[i].client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(address, friend_list[i].client_id);
|
||||||
memcpy(address + crypto_box_PUBLICKEYBYTES, &(friend_list[i].friendrequest_nospam), sizeof(uint32_t));
|
memcpy(address + crypto_box_PUBLICKEYBYTES, &(friend_list[i].friendrequest_nospam), sizeof(uint32_t));
|
||||||
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
||||||
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
|
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
|
||||||
|
@ -2130,7 +2132,7 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
|
||||||
} else if (friends[i].status != 0) {
|
} else if (friends[i].status != 0) {
|
||||||
/* TODO: This is not a good way to do this. */
|
/* TODO: This is not a good way to do this. */
|
||||||
uint8_t address[FRIEND_ADDRESS_SIZE];
|
uint8_t address[FRIEND_ADDRESS_SIZE];
|
||||||
memcpy(address, friends[i].client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(address, friends[i].client_id);
|
||||||
memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t));
|
memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t));
|
||||||
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
|
||||||
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
|
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "friend_requests.h"
|
#include "friend_requests.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* Try to send a friend request to peer with public_key.
|
/* Try to send a friend request 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.
|
||||||
|
@ -102,7 +103,7 @@ static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id)
|
||||||
if (fr->received_requests_index >= MAX_RECEIVED_STORED)
|
if (fr->received_requests_index >= MAX_RECEIVED_STORED)
|
||||||
fr->received_requests_index = 0;
|
fr->received_requests_index = 0;
|
||||||
|
|
||||||
memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(fr->received_requests[fr->received_requests_index], client_id);
|
||||||
++fr->received_requests_index;
|
++fr->received_requests_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +116,9 @@ static int request_received(Friend_Requests *fr, uint8_t *client_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_RECEIVED_STORED; ++i) {
|
for (i = 0; i < MAX_RECEIVED_STORED; ++i)
|
||||||
if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(fr->received_requests[i], client_id))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "group_chats.h"
|
#include "group_chats.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
|
#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
|
||||||
#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES)
|
#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES)
|
||||||
|
@ -67,16 +67,14 @@ static int peer_in_chat(Group_Chat *chat, uint8_t *client_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < chat->numpeers; ++i) {
|
for (i = 0; i < chat->numpeers; ++i)
|
||||||
/* Equal */
|
if (id_equal(chat->group[i].client_id, client_id))
|
||||||
if (memcmp(chat->group[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0)
|
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BAD_NODE_TIMEOUT 30
|
#define BAD_GROUPNODE_TIMEOUT 30
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if peer is closer to us that the other peers in the list and if the peer is in the list.
|
* Check if peer is closer to us that the other peers in the list and if the peer is in the list.
|
||||||
|
@ -87,19 +85,18 @@ static int peer_in_chat(Group_Chat *chat, uint8_t *client_id)
|
||||||
static int peer_okping(Group_Chat *chat, uint8_t *client_id)
|
static int peer_okping(Group_Chat *chat, uint8_t *client_id)
|
||||||
{
|
{
|
||||||
uint32_t i, j = 0;
|
uint32_t i, j = 0;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
if (memcmp(chat->self_public_key, client_id, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(chat->self_public_key, client_id))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
||||||
if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) {
|
if (is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
|
||||||
++j;
|
++j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equal */
|
/* Equal */
|
||||||
if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(chat->close[i].client_id, client_id))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2)
|
if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2)
|
||||||
|
@ -121,29 +118,28 @@ static int peer_okping(Group_Chat *chat, uint8_t *client_id)
|
||||||
static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
|
static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Check if node is already in list, if it is update its last_recv */
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Check if node is already in list, if it is update its last_recv */
|
||||||
if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) {
|
if (id_equal(chat->close[i].client_id, client_id)) {
|
||||||
chat->close[i].last_recv = temp_time;
|
chat->close[i].last_recv = unix_time();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */
|
||||||
if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) {
|
if (is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
|
||||||
memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(chat->close[i].client_id, client_id);
|
||||||
chat->close[i].ip_port = ip_port;
|
chat->close[i].ip_port = ip_port;
|
||||||
chat->close[i].last_recv = temp_time;
|
chat->close[i].last_recv = unix_time();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Replace nodes if given one is closer. */
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Replace nodes if given one is closer. */
|
||||||
if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2) {
|
if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2) {
|
||||||
memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(chat->close[i].client_id, client_id);
|
||||||
chat->close[i].ip_port = ip_port;
|
chat->close[i].ip_port = ip_port;
|
||||||
chat->close[i].last_recv = temp_time;
|
chat->close[i].last_recv = unix_time();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +150,7 @@ static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
|
||||||
static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *public_key, uint8_t *data, uint32_t length,
|
static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *public_key, uint8_t *data, uint32_t length,
|
||||||
uint8_t request_id)
|
uint8_t request_id)
|
||||||
{
|
{
|
||||||
if (memcmp(chat->self_public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(chat->self_public_key, public_key))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t packet[MAX_DATA_SIZE];
|
uint8_t packet[MAX_DATA_SIZE];
|
||||||
|
@ -180,11 +176,12 @@ static uint8_t sendto_allpeers(Group_Chat *chat, uint8_t *data, uint16_t length,
|
||||||
{
|
{
|
||||||
uint16_t sent = 0;
|
uint16_t sent = 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
||||||
if (ip_isset(&chat->close[i].ip_port.ip) && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) {
|
if (ip_isset(&chat->close[i].ip_port.ip) &&
|
||||||
if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0)
|
!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
|
||||||
|
if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id,
|
||||||
|
data, length, request_id) == 0)
|
||||||
++sent;
|
++sent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +211,7 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
chat->group = temp;
|
chat->group = temp;
|
||||||
memcpy(chat->group[chat->numpeers].client_id, client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(chat->group[chat->numpeers].client_id, client_id);
|
||||||
++chat->numpeers;
|
++chat->numpeers;
|
||||||
return (chat->numpeers - 1);
|
return (chat->numpeers - 1);
|
||||||
}
|
}
|
||||||
|
@ -232,14 +229,11 @@ static int delpeer(Group_Chat *chat, uint8_t *client_id)
|
||||||
|
|
||||||
for (i = 0; i < chat->numpeers; ++i) {
|
for (i = 0; i < chat->numpeers; ++i) {
|
||||||
/* Equal */
|
/* Equal */
|
||||||
if (memcmp(chat->group[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) {
|
if (id_equal(chat->group[i].client_id, client_id)) {
|
||||||
--chat->numpeers;
|
--chat->numpeers;
|
||||||
|
|
||||||
if (chat->numpeers != i) {
|
if (chat->numpeers != i)
|
||||||
memcpy( chat->group[i].client_id,
|
id_copy(chat->group[i].client_id, chat->group[chat->numpeers].client_id);
|
||||||
chat->group[chat->numpeers].client_id,
|
|
||||||
crypto_box_PUBLICKEYBYTES );
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers));
|
temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers));
|
||||||
|
|
||||||
|
@ -276,22 +270,23 @@ int group_peername(Group_Chat *chat, int peernum, uint8_t *name)
|
||||||
|
|
||||||
|
|
||||||
/* min time between pings sent to one peer in seconds */
|
/* min time between pings sent to one peer in seconds */
|
||||||
|
/* TODO: move this to global section */
|
||||||
#define PING_TIMEOUT 5
|
#define PING_TIMEOUT 5
|
||||||
|
|
||||||
static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum)
|
static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum)
|
||||||
{
|
{
|
||||||
if ((uint32_t)peernum >= chat->numpeers)
|
if ((uint32_t)peernum >= chat->numpeers)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint64_t temp_time = unix_time();
|
if (!is_timeout(chat->group[peernum].last_pinged, PING_TIMEOUT))
|
||||||
|
|
||||||
getnodes_data contents;
|
|
||||||
|
|
||||||
if (chat->group[peernum].last_pinged + PING_TIMEOUT > temp_time)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
getnodes_data contents;
|
||||||
contents.pingid = ((uint64_t)random_int() << 32) + random_int();
|
contents.pingid = ((uint64_t)random_int() << 32) + random_int();
|
||||||
chat->group[peernum].last_pinged = temp_time;
|
|
||||||
|
chat->group[peernum].last_pinged = unix_time();
|
||||||
chat->group[peernum].pingid = contents.pingid;
|
chat->group[peernum].pingid = contents.pingid;
|
||||||
|
|
||||||
return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), 48);
|
return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,11 +298,10 @@ static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64
|
||||||
sendnodes_data contents;
|
sendnodes_data contents;
|
||||||
contents.pingid = pingid;
|
contents.pingid = pingid;
|
||||||
uint32_t i, j = 0;
|
uint32_t i, j = 0;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
||||||
if (chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) {
|
if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
|
||||||
memcpy(contents.nodes[j].client_id, chat->close[i].client_id, crypto_box_PUBLICKEYBYTES);
|
id_copy(contents.nodes[j].client_id, chat->close[i].client_id);
|
||||||
contents.nodes[j].ip_port = chat->close[i].ip_port;
|
contents.nodes[j].ip_port = chat->close[i].ip_port;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +340,7 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
|
||||||
if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0)
|
if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (chat->group[peernum].last_pinged + PING_TIMEOUT < unix_time())
|
if (is_timeout(chat->group[peernum].last_pinged, PING_TIMEOUT))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
sendnodes_data contents;
|
sendnodes_data contents;
|
||||||
|
@ -376,7 +370,9 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
|
||||||
add_closepeer(chat, chat->group[peernum].client_id, source);
|
add_closepeer(chat, chat->group[peernum].client_id, source);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1)
|
#define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1)
|
||||||
|
|
||||||
static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
|
static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
|
||||||
{
|
{
|
||||||
if (len < GROUP_DATA_MIN_SIZE)
|
if (len < GROUP_DATA_MIN_SIZE)
|
||||||
|
@ -392,7 +388,6 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
|
||||||
if (peernum == -1)
|
if (peernum == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
/* Spam prevention (1 message per peer per second limit.)
|
/* Spam prevention (1 message per peer per second limit.)
|
||||||
|
|
||||||
if (chat->group[peernum].last_recv == temp_time)
|
if (chat->group[peernum].last_recv == temp_time)
|
||||||
|
@ -421,7 +416,8 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
|
||||||
if (contents_len != 0)
|
if (contents_len != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
chat->group[peernum].last_recv_msgping = temp_time;
|
chat->group[peernum].last_recv_msgping = unix_time();
|
||||||
|
break;
|
||||||
|
|
||||||
case 16: /* If message is new peer */
|
case 16: /* If message is new peer */
|
||||||
if (contents_len != crypto_box_PUBLICKEYBYTES)
|
if (contents_len != crypto_box_PUBLICKEYBYTES)
|
||||||
|
@ -463,7 +459,7 @@ static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t
|
||||||
|
|
||||||
uint32_t message_num = htonl(chat->message_number);
|
uint32_t message_num = htonl(chat->message_number);
|
||||||
//TODO
|
//TODO
|
||||||
memcpy(packet, chat->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(packet, chat->self_public_key);
|
||||||
memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num));
|
memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num));
|
||||||
memcpy(packet + GROUP_DATA_MIN_SIZE, data, len);
|
memcpy(packet + GROUP_DATA_MIN_SIZE, data, len);
|
||||||
packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id;
|
packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id;
|
||||||
|
@ -489,7 +485,7 @@ int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, ui
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (memcmp(chat->self_public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(chat->self_public_key, public_key))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
int peernum = peer_in_chat(chat, public_key);
|
int peernum = peer_in_chat(chat, public_key);
|
||||||
|
@ -548,16 +544,16 @@ Group_Chat *new_groupchat(Networking_Core *net)
|
||||||
static void ping_close(Group_Chat *chat)
|
static void ping_close(Group_Chat *chat)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t temp_time = unix_time();
|
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
|
||||||
if (chat->close[i].last_recv < temp_time + BAD_NODE_TIMEOUT) {
|
/* previous condition was always true, assuming this is the wanted one: */
|
||||||
|
if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
|
||||||
int peernum = peer_in_chat(chat, chat->close[i].client_id);
|
int peernum = peer_in_chat(chat, chat->close[i].client_id);
|
||||||
|
|
||||||
if (peernum == -1)
|
if (peernum == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (chat->group[peernum].last_pinged + NODE_PING_INTERVAL < temp_time)
|
if (is_timeout(chat->group[peernum].last_pinged, NODE_PING_INTERVAL))
|
||||||
send_getnodes(chat, chat->close[i].ip_port, peernum);
|
send_getnodes(chat, chat->close[i].ip_port, peernum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -584,4 +580,3 @@ void chat_bootstrap_nonlazy(Group_Chat *chat, IP_Port ip_port, uint8_t *client_i
|
||||||
send_getnodes(chat, ip_port, addpeer(chat, client_id));
|
send_getnodes(chat, ip_port, addpeer(chat, client_id));
|
||||||
add_closepeer(chat, client_id, ip_port);
|
add_closepeer(chat, client_id, ip_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "net_crypto.h"
|
#include "net_crypto.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define CONN_NO_CONNECTION 0
|
#define CONN_NO_CONNECTION 0
|
||||||
#define CONN_HANDSHAKE_SENT 1
|
#define CONN_HANDSHAKE_SENT 1
|
||||||
|
@ -268,8 +269,8 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
packet[0] = NET_PACKET_CRYPTO;
|
packet[0] = NET_PACKET_CRYPTO;
|
||||||
memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(packet + 1, recv_public_key);
|
||||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key);
|
||||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
|
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
|
||||||
|
|
||||||
return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
|
return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
|
||||||
|
@ -286,8 +287,8 @@ int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *
|
||||||
{
|
{
|
||||||
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
|
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
|
||||||
length <= MAX_DATA_SIZE) {
|
length <= MAX_DATA_SIZE) {
|
||||||
if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
if (id_equal(packet + 1, self_public_key)) {
|
||||||
memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
|
id_copy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES);
|
||||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
uint8_t temp[MAX_DATA_SIZE];
|
uint8_t temp[MAX_DATA_SIZE];
|
||||||
memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
|
memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
|
||||||
|
@ -323,7 +324,7 @@ static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, ui
|
||||||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
|
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
|
if (id_equal(packet + 1, dht->c->self_public_key)) { // Check if request is for us.
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
uint8_t data[MAX_DATA_SIZE];
|
uint8_t data[MAX_DATA_SIZE];
|
||||||
uint8_t number;
|
uint8_t number;
|
||||||
|
@ -361,7 +362,7 @@ static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *publi
|
||||||
|
|
||||||
new_nonce(nonce);
|
new_nonce(nonce);
|
||||||
memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
|
memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
|
||||||
memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(temp + crypto_box_NONCEBYTES, session_key);
|
||||||
|
|
||||||
int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||||
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
|
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
|
||||||
|
@ -370,7 +371,7 @@ static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *publi
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
temp_data[0] = 2;
|
temp_data[0] = 2;
|
||||||
memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(temp_data + 1, c->self_public_key);
|
||||||
memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
|
memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
|
||||||
return write_packet(c->lossless_udp, connection_id, temp_data,
|
return write_packet(c->lossless_udp, connection_id, temp_data,
|
||||||
len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||||
|
@ -396,7 +397,7 @@ static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *s
|
||||||
|
|
||||||
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
|
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
|
||||||
|
|
||||||
memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
|
id_copy(public_key, data + 1);
|
||||||
|
|
||||||
int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
|
int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
|
||||||
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
||||||
|
@ -406,7 +407,7 @@ static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *s
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
|
memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
|
||||||
memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
|
id_copy(session_key, temp + crypto_box_NONCEBYTES);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,11 +420,10 @@ static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < c->crypto_connections_length; ++i) {
|
for (i = 0; i < c->crypto_connections_length; ++i)
|
||||||
if (c->crypto_connections[i].status != CONN_NO_CONNECTION)
|
if (c->crypto_connections[i].status != CONN_NO_CONNECTION)
|
||||||
if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
if (id_equal(public_key, c->crypto_connections[i].public_key))
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port)
|
||||||
c->crypto_connections[i].number = id_new;
|
c->crypto_connections[i].number = id_new;
|
||||||
c->crypto_connections[i].status = CONN_HANDSHAKE_SENT;
|
c->crypto_connections[i].status = CONN_HANDSHAKE_SENT;
|
||||||
random_nonce(c->crypto_connections[i].recv_nonce);
|
random_nonce(c->crypto_connections[i].recv_nonce);
|
||||||
memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(c->crypto_connections[i].public_key, public_key);
|
||||||
crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
|
crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
|
||||||
c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
|
c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
|
||||||
|
|
||||||
|
@ -604,9 +604,9 @@ int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key,
|
||||||
c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
|
c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
|
||||||
random_nonce(c->crypto_connections[i].recv_nonce);
|
random_nonce(c->crypto_connections[i].recv_nonce);
|
||||||
memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
|
memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
|
||||||
memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(c->crypto_connections[i].peersessionpublic_key, session_key);
|
||||||
increment_nonce(c->crypto_connections[i].sent_nonce);
|
increment_nonce(c->crypto_connections[i].sent_nonce);
|
||||||
memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(c->crypto_connections[i].public_key, public_key);
|
||||||
|
|
||||||
crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
|
crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
|
||||||
|
|
||||||
|
@ -658,7 +658,7 @@ void new_keys(Net_Crypto *c)
|
||||||
*/
|
*/
|
||||||
void save_keys(Net_Crypto *c, uint8_t *keys)
|
void save_keys(Net_Crypto *c, uint8_t *keys)
|
||||||
{
|
{
|
||||||
memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(keys, c->self_public_key);
|
||||||
memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
|
memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +667,7 @@ void save_keys(Net_Crypto *c, uint8_t *keys)
|
||||||
*/
|
*/
|
||||||
void load_keys(Net_Crypto *c, uint8_t *keys)
|
void load_keys(Net_Crypto *c, uint8_t *keys)
|
||||||
{
|
{
|
||||||
memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES);
|
id_copy(c->self_public_key, keys);
|
||||||
memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
|
memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,9 +692,9 @@ static void receive_crypto(Net_Crypto *c)
|
||||||
len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data);
|
len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data);
|
||||||
|
|
||||||
if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) {
|
if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) {
|
||||||
if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
|
if (id_equal(public_key, c->crypto_connections[i].public_key)) {
|
||||||
memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
|
memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
|
||||||
memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
|
id_copy(c->crypto_connections[i].peersessionpublic_key, session_key);
|
||||||
increment_nonce(c->crypto_connections[i].sent_nonce);
|
increment_nonce(c->crypto_connections[i].sent_nonce);
|
||||||
uint32_t zero = 0;
|
uint32_t zero = 0;
|
||||||
encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
|
encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
|
||||||
|
|
|
@ -97,9 +97,6 @@ typedef int sock_t;
|
||||||
#define TOX_PORTRANGE_TO 33455
|
#define TOX_PORTRANGE_TO 33455
|
||||||
#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
|
#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
|
||||||
|
|
||||||
/* Current time, unix format */
|
|
||||||
#define unix_time() ((uint64_t)time(NULL))
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t uint8[4];
|
uint8_t uint8[4];
|
||||||
uint16_t uint16[2];
|
uint16_t uint16[2];
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef struct {
|
||||||
|
|
||||||
static bool is_ping_timeout(uint64_t time)
|
static bool is_ping_timeout(uint64_t time)
|
||||||
{
|
{
|
||||||
return (time + PING_TIMEOUT) < now();
|
return is_timeout(time, PING_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_timeouts(PING *ping) // O(n)
|
static void remove_timeouts(PING *ping) // O(n)
|
||||||
|
@ -83,7 +83,7 @@ static uint64_t add_ping(PING *ping, IP_Port ipp) // O(n)
|
||||||
p = (ping->pos_pings + ping->num_pings) % PING_NUM_MAX;
|
p = (ping->pos_pings + ping->num_pings) % PING_NUM_MAX;
|
||||||
|
|
||||||
ping->pings[p].ip_port = ipp;
|
ping->pings[p].ip_port = ipp;
|
||||||
ping->pings[p].timestamp = now();
|
ping->pings[p].timestamp = unix_time();
|
||||||
ping->pings[p].id = random_64b();
|
ping->pings[p].id = random_64b();
|
||||||
|
|
||||||
ping->num_pings++;
|
ping->num_pings++;
|
||||||
|
@ -122,14 +122,14 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
|
||||||
int rc;
|
int rc;
|
||||||
uint64_t ping_id;
|
uint64_t ping_id;
|
||||||
|
|
||||||
if (is_pinging(ping, ipp, 0) || id_eq(client_id, ping->c->self_public_key))
|
if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->c->self_public_key))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Generate random ping_id.
|
// Generate random ping_id.
|
||||||
ping_id = add_ping(ping, ipp);
|
ping_id = add_ping(ping, ipp);
|
||||||
|
|
||||||
pk[0] = NET_PACKET_PING_REQUEST;
|
pk[0] = NET_PACKET_PING_REQUEST;
|
||||||
id_cpy(pk + 1, ping->c->self_public_key); // Our pubkey
|
id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
|
||||||
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
||||||
|
|
||||||
// Encrypt ping_id using recipient privkey
|
// Encrypt ping_id using recipient privkey
|
||||||
|
@ -150,11 +150,11 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
|
||||||
uint8_t pk[DHT_PING_SIZE];
|
uint8_t pk[DHT_PING_SIZE];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (id_eq(client_id, ping->c->self_public_key))
|
if (id_equal(client_id, ping->c->self_public_key))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pk[0] = NET_PACKET_PING_RESPONSE;
|
pk[0] = NET_PACKET_PING_RESPONSE;
|
||||||
id_cpy(pk + 1, ping->c->self_public_key); // Our pubkey
|
id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
|
||||||
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
|
||||||
|
|
||||||
// Encrypt ping_id using recipient privkey
|
// Encrypt ping_id using recipient privkey
|
||||||
|
@ -181,7 +181,7 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
|
||||||
|
|
||||||
PING *ping = dht->ping;
|
PING *ping = dht->ping;
|
||||||
|
|
||||||
if (id_eq(packet + 1, ping->c->self_public_key))
|
if (id_equal(packet + 1, ping->c->self_public_key))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Decrypt ping_id
|
// Decrypt ping_id
|
||||||
|
@ -213,7 +213,7 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
|
||||||
|
|
||||||
PING *ping = dht->ping;
|
PING *ping = dht->ping;
|
||||||
|
|
||||||
if (id_eq(packet + 1, ping->c->self_public_key))
|
if (id_equal(packet + 1, ping->c->self_public_key))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Decrypt ping_id
|
// Decrypt ping_id
|
||||||
|
@ -277,19 +277,12 @@ int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port)
|
||||||
/* Ping all the valid nodes in the toping list every TIME_TOPING seconds.
|
/* Ping all the valid nodes in the toping list every TIME_TOPING seconds.
|
||||||
* This function must be run at least once every TIME_TOPING seconds.
|
* This function must be run at least once every TIME_TOPING seconds.
|
||||||
*/
|
*/
|
||||||
static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
|
|
||||||
{
|
|
||||||
return timestamp + timeout <= time_now;
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_toping(PING *ping)
|
void do_toping(PING *ping)
|
||||||
{
|
{
|
||||||
uint64_t temp_time = unix_time();
|
if (!is_timeout(ping->last_toping, TIME_TOPING))
|
||||||
|
|
||||||
if (!is_timeout(temp_time, ping->last_toping, TIME_TOPING))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ping->last_toping = temp_time;
|
ping->last_toping = unix_time();
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TOPING; ++i) {
|
for (i = 0; i < MAX_TOPING; ++i) {
|
||||||
|
|
|
@ -16,11 +16,6 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
uint64_t now()
|
|
||||||
{
|
|
||||||
return time(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t random_64b()
|
uint64_t random_64b()
|
||||||
{
|
{
|
||||||
uint64_t r;
|
uint64_t r;
|
||||||
|
@ -33,16 +28,39 @@ uint64_t random_64b()
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool id_eq(uint8_t *dest, uint8_t *src)
|
/* don't call into system billions of times for no reason */
|
||||||
|
static uint64_t unix_time_value;
|
||||||
|
|
||||||
|
void unix_time_update()
|
||||||
|
{
|
||||||
|
unix_time_value = (uint64_t)time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t unix_time()
|
||||||
|
{
|
||||||
|
return unix_time_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_timeout(uint64_t timestamp, uint64_t timeout)
|
||||||
|
{
|
||||||
|
return timestamp + timeout <= unix_time_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* id functions */
|
||||||
|
bool id_equal(uint8_t *dest, uint8_t *src)
|
||||||
{
|
{
|
||||||
return memcmp(dest, src, CLIENT_ID_SIZE) == 0;
|
return memcmp(dest, src, CLIENT_ID_SIZE) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void id_cpy(uint8_t *dest, uint8_t *src)
|
uint32_t id_copy(uint8_t *dest, uint8_t *src)
|
||||||
{
|
{
|
||||||
memcpy(dest, src, CLIENT_ID_SIZE);
|
memcpy(dest, src, CLIENT_ID_SIZE);
|
||||||
|
return CLIENT_ID_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* state load/save */
|
||||||
int load_state(load_state_callback_func load_state_callback, void *outer,
|
int load_state(load_state_callback_func load_state_callback, void *outer,
|
||||||
uint8_t *data, uint32_t length, uint16_t cookie_inner)
|
uint8_t *data, uint32_t length, uint16_t cookie_inner)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,11 +11,19 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
uint64_t now();
|
|
||||||
uint64_t random_64b();
|
uint64_t random_64b();
|
||||||
bool id_eq(uint8_t *dest, uint8_t *src);
|
|
||||||
void id_cpy(uint8_t *dest, uint8_t *src);
|
|
||||||
|
|
||||||
|
void unix_time_update();
|
||||||
|
uint64_t unix_time();
|
||||||
|
int is_timeout(uint64_t timestamp, uint64_t timeout);
|
||||||
|
|
||||||
|
|
||||||
|
/* id functions */
|
||||||
|
bool id_equal(uint8_t *dest, uint8_t *src);
|
||||||
|
uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */
|
||||||
|
|
||||||
|
|
||||||
|
/* state load/save */
|
||||||
typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);
|
typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);
|
||||||
int load_state(load_state_callback_func load_state_callback, void *outer,
|
int load_state(load_state_callback_func load_state_callback, void *outer,
|
||||||
uint8_t *data, uint32_t length, uint16_t cookie_inner);
|
uint8_t *data, uint32_t length, uint16_t cookie_inner);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user