mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' of https://github.com/plutooo/ProjectTox-Core into plutooo-master
Conflicts: core/ping.c core/util.c
This commit is contained in:
commit
fc5a2f53df
84
core/DHT.c
84
core/DHT.c
|
@ -24,6 +24,7 @@
|
||||||
/*----------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "DHT.h"
|
#include "DHT.h"
|
||||||
|
#include "packets.h"
|
||||||
#include "ping.h"
|
#include "ping.h"
|
||||||
|
|
||||||
/* maximum number of clients stored per friend. */
|
/* maximum number of clients stored per friend. */
|
||||||
|
@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send a ping request, only works if none has been sent to that ip/port
|
|
||||||
* in the last 5 seconds.
|
|
||||||
*/
|
|
||||||
static int pingreq(IP_Port ip_port, uint8_t * public_key)
|
|
||||||
{
|
|
||||||
/* check if packet is gonna be sent to ourself */
|
|
||||||
if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
uint64_t ping_id = add_ping(ip_port);
|
|
||||||
if(ping_id == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
|
|
||||||
uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
|
|
||||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
|
||||||
random_nonce(nonce);
|
|
||||||
|
|
||||||
int len = encrypt_data( public_key,
|
|
||||||
self_secret_key,
|
|
||||||
nonce,
|
|
||||||
(uint8_t *)&ping_id,
|
|
||||||
sizeof(ping_id),
|
|
||||||
encrypt );
|
|
||||||
|
|
||||||
if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
data[0] = 0;
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
if(id_equal(public_key, self_public_key))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
|
|
||||||
uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
|
|
||||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
|
||||||
random_nonce(nonce);
|
|
||||||
|
|
||||||
int len = encrypt_data( public_key,
|
|
||||||
self_secret_key, nonce,
|
|
||||||
(uint8_t *)&ping_id,
|
|
||||||
sizeof(ping_id),
|
|
||||||
encrypt );
|
|
||||||
|
|
||||||
if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
data[0] = 1;
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send a getnodes request */
|
/* send a getnodes request */
|
||||||
static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
|
static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
|
||||||
{
|
{
|
||||||
|
@ -641,8 +577,8 @@ static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
if(len != sizeof(ping_id))
|
if(len != sizeof(ping_id))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pingres(source, packet + 1, ping_id);
|
send_ping_response(source, (clientid_t*) (packet + 1), ping_id);
|
||||||
pingreq(source, packet + 1); /* TODO: make this smarter? */
|
send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -701,7 +637,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
memcpy(&ping_id, plain, sizeof(ping_id));
|
memcpy(&ping_id, plain, sizeof(ping_id));
|
||||||
sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
|
sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
|
||||||
|
|
||||||
pingreq(source, packet + 1); /* TODO: make this smarter? */
|
send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -741,7 +677,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < num_nodes; ++i) {
|
for(i = 0; i < num_nodes; ++i) {
|
||||||
pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
|
send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id);
|
||||||
returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
|
returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,8 +767,8 @@ static void doDHTFriends(void)
|
||||||
/* if node is not dead. */
|
/* if node is not dead. */
|
||||||
if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
|
if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
|
||||||
if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
|
if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
|
||||||
pingreq( friends_list[i].client_list[j].ip_port,
|
send_ping_request( friends_list[i].client_list[j].ip_port,
|
||||||
friends_list[i].client_list[j].client_id );
|
(clientid_t*) &friends_list[i].client_list[j].client_id );
|
||||||
friends_list[i].client_list[j].last_pinged = temp_time;
|
friends_list[i].client_list[j].last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
/* if node is good. */
|
/* if node is good. */
|
||||||
|
@ -869,8 +805,8 @@ static void doClose(void)
|
||||||
/* if node is not dead. */
|
/* if node is not dead. */
|
||||||
if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
|
if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
|
||||||
if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
|
if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
|
||||||
pingreq( close_clientlist[i].ip_port,
|
send_ping_request( close_clientlist[i].ip_port,
|
||||||
close_clientlist[i].client_id );
|
(clientid_t*) &close_clientlist[i].client_id );
|
||||||
close_clientlist[i].last_pinged = temp_time;
|
close_clientlist[i].last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
/* if node is good. */
|
/* if node is good. */
|
||||||
|
@ -1151,7 +1087,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
|
||||||
/*TODO: improve port guessing algorithm*/
|
/*TODO: improve port guessing algorithm*/
|
||||||
uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
|
uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
|
||||||
IP_Port pinging = {ip, htons(port)};
|
IP_Port pinging = {ip, htons(port)};
|
||||||
pingreq(pinging, friends_list[friend_num].client_id);
|
send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id);
|
||||||
}
|
}
|
||||||
friends_list[friend_num].punching_index = i;
|
friends_list[friend_num].punching_index = i;
|
||||||
}
|
}
|
||||||
|
|
37
core/packets.h
Normal file
37
core/packets.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* packet.h -- Packet structure
|
||||||
|
*
|
||||||
|
* This file is donated to the Tox Project.
|
||||||
|
* Copyright 2013 plutooo
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t id[CLIENT_ID_SIZE];
|
||||||
|
|
||||||
|
} __attribute__((packed)) clientid_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PACKET_PING_REQ = 0,
|
||||||
|
PACKET_PING_RES = 1
|
||||||
|
|
||||||
|
} packetid_t;
|
||||||
|
|
||||||
|
// Ping packet
|
||||||
|
typedef struct {
|
||||||
|
uint8_t magic;
|
||||||
|
clientid_t client_id;
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
uint64_t ping_id;
|
||||||
|
uint8_t padding[ENCRYPTION_PADDING];
|
||||||
|
|
||||||
|
} __attribute__((packed)) pingreq_t;
|
||||||
|
|
||||||
|
// Pong packet
|
||||||
|
typedef struct {
|
||||||
|
uint8_t magic;
|
||||||
|
clientid_t client_id;
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
uint64_t ping_id;
|
||||||
|
uint8_t padding[ENCRYPTION_PADDING];
|
||||||
|
|
||||||
|
} __attribute__((packed)) pingres_t;
|
63
core/ping.c
63
core/ping.c
|
@ -8,6 +8,9 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "DHT.h"
|
||||||
|
#include "net_crypto.h"
|
||||||
|
#include "packets.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -23,7 +26,9 @@ typedef struct {
|
||||||
static pinged_t pings[PING_NUM_MAX];
|
static pinged_t pings[PING_NUM_MAX];
|
||||||
static size_t num_pings;
|
static size_t num_pings;
|
||||||
static size_t pos_pings;
|
static size_t pos_pings;
|
||||||
|
static clientid_t* self_id = (clientid_t*) &self_public_key;
|
||||||
|
|
||||||
|
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
|
||||||
|
|
||||||
void init_ping()
|
void init_ping()
|
||||||
{
|
{
|
||||||
|
@ -51,9 +56,10 @@ static void remove_timeouts() // O(n)
|
||||||
new_num--;
|
new_num--;
|
||||||
}
|
}
|
||||||
// Break here because list is sorted.
|
// Break here because list is sorted.
|
||||||
else
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
num_pings = new_num;
|
num_pings = new_num;
|
||||||
pos_pings = new_pos % PING_NUM_MAX;
|
pos_pings = new_pos % PING_NUM_MAX;
|
||||||
|
@ -94,6 +100,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
|
||||||
for (i=0; i<num_pings; i++) {
|
for (i=0; i<num_pings; i++) {
|
||||||
id = (pos_pings + i) % PING_NUM_MAX;
|
id = (pos_pings + i) % PING_NUM_MAX;
|
||||||
|
|
||||||
|
// ping_id = 0 means match any id
|
||||||
if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) {
|
if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -101,3 +108,57 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int send_ping_request(IP_Port ipp, clientid_t* client_id)
|
||||||
|
{
|
||||||
|
pingreq_t pk;
|
||||||
|
int rc;
|
||||||
|
uint64_t ping_id;
|
||||||
|
|
||||||
|
if (is_pinging(ipp, 0) || id_eq(client_id, self_id))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Generate random ping_id
|
||||||
|
ping_id = add_ping(ipp);
|
||||||
|
|
||||||
|
pk.magic = PACKET_PING_REQ;
|
||||||
|
id_cpy(&pk.client_id, self_id); // Our pubkey
|
||||||
|
random_nonce((uint8_t*) &pk.nonce); // Generate random nonce
|
||||||
|
|
||||||
|
// Encrypt ping_id using recipient privkey
|
||||||
|
rc = encrypt_data((uint8_t*) client_id,
|
||||||
|
self_secret_key,
|
||||||
|
(uint8_t*) &pk.nonce,
|
||||||
|
(uint8_t*) &ping_id, sizeof(ping_id),
|
||||||
|
(uint8_t*) &pk.ping_id);
|
||||||
|
|
||||||
|
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk));
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id)
|
||||||
|
{
|
||||||
|
pingres_t pk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (id_eq(client_id, self_id))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
pk.magic = PACKET_PING_RES;
|
||||||
|
id_cpy(&pk.client_id, self_id); // Our pubkey
|
||||||
|
random_nonce((uint8_t*) &pk.nonce); // Generate random nonce
|
||||||
|
|
||||||
|
// Encrypt ping_id using recipient privkey
|
||||||
|
rc = encrypt_data((uint8_t*) client_id,
|
||||||
|
self_secret_key,
|
||||||
|
(uint8_t*) &pk.nonce,
|
||||||
|
(uint8_t*) &ping_id, sizeof(ping_id),
|
||||||
|
(uint8_t*) &pk.ping_id);
|
||||||
|
|
||||||
|
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk));
|
||||||
|
}
|
||||||
|
|
|
@ -10,4 +10,5 @@
|
||||||
void init_ping();
|
void init_ping();
|
||||||
uint64_t add_ping(IP_Port ipp);
|
uint64_t add_ping(IP_Port ipp);
|
||||||
bool is_pinging(IP_Port ipp, uint64_t ping_id);
|
bool is_pinging(IP_Port ipp, uint64_t ping_id);
|
||||||
|
int send_ping_request(IP_Port ipp, clientid_t* client_id);
|
||||||
|
int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id);
|
||||||
|
|
13
core/util.c
13
core/util.c
|
@ -9,7 +9,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "network.h"
|
#include "DHT.h"
|
||||||
|
#include "packets.h"
|
||||||
|
|
||||||
uint64_t now()
|
uint64_t now()
|
||||||
{
|
{
|
||||||
|
@ -32,3 +33,13 @@ bool ipp_eq(IP_Port a, IP_Port b)
|
||||||
{
|
{
|
||||||
return (a.ip.i == b.ip.i) && (a.port == b.port);
|
return (a.ip.i == b.ip.i) && (a.port == b.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool id_eq(clientid_t* dest, clientid_t* src)
|
||||||
|
{
|
||||||
|
return memcmp(dest, src, sizeof(clientid_t)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void id_cpy(clientid_t* dest, clientid_t* src)
|
||||||
|
{
|
||||||
|
memcpy(dest, src, sizeof(clientid_t));
|
||||||
|
}
|
||||||
|
|
|
@ -8,3 +8,6 @@
|
||||||
uint64_t now();
|
uint64_t now();
|
||||||
uint64_t random_64b();
|
uint64_t random_64b();
|
||||||
bool ipp_eq(IP_Port a, IP_Port b);
|
bool ipp_eq(IP_Port a, IP_Port b);
|
||||||
|
bool id_eq(clientid_t* dest, clientid_t* src);
|
||||||
|
void id_cpy(clientid_t* dest, clientid_t* src);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user