mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Major cleanups.
Fixed circular dependency between DHT and net_crypto: DHT no longer depends on net_crypto. Moved the crypto request packets functions to crypto core and DHT. Cleaned up/added some defines that can be used to get the true maximum length of things like the friends request message. MAX_DATA_SIZE has been replaced in most places by more appropriate defines.
This commit is contained in:
parent
1bfe15ee88
commit
384750af8c
|
@ -1685,7 +1685,7 @@ int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id)
|
|||
static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type)
|
||||
{
|
||||
uint8_t data[sizeof(uint64_t) + 1];
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
|
||||
int num = 0;
|
||||
|
||||
|
@ -1896,7 +1896,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
|
|||
if (length > HARDREQ_DATA_SIZE - 1)
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t data[HARDREQ_DATA_SIZE] = {0};
|
||||
data[0] = type;
|
||||
memcpy(data + 1, contents, length);
|
||||
|
@ -1925,7 +1925,7 @@ static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *qu
|
|||
if (!ip_isset(&sendto->ip_port.ip))
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t data[1 + CLIENT_ID_SIZE + nodes_data_length];
|
||||
data[0] = CHECK_TYPE_GETNODE_RES;
|
||||
memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
|
||||
|
@ -2242,12 +2242,54 @@ void do_hardening(DHT *dht)
|
|||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
DHT *new_DHT(Net_Crypto *c)
|
||||
void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object)
|
||||
{
|
||||
dht->cryptopackethandlers[byte].function = cb;
|
||||
dht->cryptopackethandlers[byte].object = object;
|
||||
}
|
||||
|
||||
static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
DHT *dht = object;
|
||||
|
||||
if (packet[0] == NET_PACKET_CRYPTO) {
|
||||
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
|
||||
length > MAX_CRYPTO_REQUEST_SIZE + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t number;
|
||||
int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
|
||||
|
||||
if (len == -1 || len == 0)
|
||||
return 1;
|
||||
|
||||
if (!dht->cryptopackethandlers[number].function) return 1;
|
||||
|
||||
return dht->cryptopackethandlers[number].function(dht->cryptopackethandlers[number].object, source, public_key,
|
||||
data, len);
|
||||
|
||||
} else { /* If request is not for us, try routing it. */
|
||||
int retval = route_packet(dht, packet + 1, packet, length);
|
||||
|
||||
if ((unsigned int)retval == length)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
DHT *new_DHT(Networking_Core *net)
|
||||
{
|
||||
/* init time */
|
||||
unix_time_update();
|
||||
|
||||
if (c == NULL)
|
||||
if (net == NULL)
|
||||
return NULL;
|
||||
|
||||
DHT *dht = calloc(1, sizeof(DHT));
|
||||
|
@ -2255,8 +2297,7 @@ DHT *new_DHT(Net_Crypto *c)
|
|||
if (dht == NULL)
|
||||
return NULL;
|
||||
|
||||
dht->c = c;
|
||||
dht->net = c->lossless_udp->net;
|
||||
dht->net = net;
|
||||
dht->ping = new_ping(dht);
|
||||
|
||||
if (dht->ping == NULL) {
|
||||
|
@ -2266,9 +2307,9 @@ DHT *new_DHT(Net_Crypto *c)
|
|||
|
||||
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
|
||||
init_cryptopackets(dht);
|
||||
cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
|
||||
|
||||
new_symmetric_key(dht->secret_symmetric_key);
|
||||
crypto_box_keypair(dht->self_public_key, dht->self_secret_key);
|
||||
|
@ -2283,7 +2324,6 @@ DHT *new_DHT(Net_Crypto *c)
|
|||
DHT_addfriend(dht, random_key_bytes);
|
||||
}
|
||||
|
||||
c->dht = dht;
|
||||
return dht;
|
||||
}
|
||||
|
||||
|
@ -2316,9 +2356,8 @@ void kill_DHT(DHT *dht)
|
|||
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL);
|
||||
cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_NAT_PING, NULL, NULL);
|
||||
cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_HARDENING, NULL, NULL);
|
||||
dht->c->dht = 0;
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL);
|
||||
kill_ping(dht->ping);
|
||||
free(dht->friends_list);
|
||||
free(dht);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef DHT_H
|
||||
#define DHT_H
|
||||
|
||||
#include "net_crypto.h"
|
||||
#include "crypto_core.h"
|
||||
|
||||
/* Size of the client_id in bytes. */
|
||||
#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
|
||||
|
@ -168,8 +168,15 @@ typedef struct {
|
|||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
typedef struct {
|
||||
cryptopacket_handler_callback function;
|
||||
void *object;
|
||||
} Cryptopacket_Handles;
|
||||
|
||||
typedef struct {
|
||||
Net_Crypto *c;
|
||||
Networking_Core *net;
|
||||
|
||||
Client_data close_clientlist[LCLIENT_LIST];
|
||||
|
@ -193,6 +200,8 @@ typedef struct {
|
|||
struct Assoc *assoc;
|
||||
#endif
|
||||
uint64_t last_run;
|
||||
|
||||
Cryptopacket_Handles cryptopackethandlers[256];
|
||||
} DHT;
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -354,7 +363,7 @@ void DHT_save(DHT *dht, uint8_t *data);
|
|||
int DHT_load(DHT *dht, uint8_t *data, uint32_t length);
|
||||
|
||||
/* Initialize DHT. */
|
||||
DHT *new_DHT(Net_Crypto *c);
|
||||
DHT *new_DHT(Networking_Core *net);
|
||||
|
||||
void kill_DHT(DHT *dht);
|
||||
|
||||
|
|
|
@ -214,9 +214,7 @@ void getaddress(Messenger *m, uint8_t *address)
|
|||
*/
|
||||
int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
|
||||
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
|
||||
+ crypto_box_ZEROBYTES))
|
||||
if (length > MAX_FRIEND_REQUEST_DATA_SIZE)
|
||||
return FAERR_TOOLONG;
|
||||
|
||||
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
|
||||
|
@ -1757,26 +1755,26 @@ Messenger *new_messenger(uint8_t ipv6enabled)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
m->net_crypto = new_net_crypto(m->net);
|
||||
m->dht = new_DHT(m->net);
|
||||
|
||||
if (m->net_crypto == NULL) {
|
||||
if (m->dht == NULL) {
|
||||
kill_networking(m->net);
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m->dht = new_DHT(m->net_crypto);
|
||||
m->net_crypto = new_net_crypto(m->dht);
|
||||
|
||||
if (m->dht == NULL) {
|
||||
kill_net_crypto(m->net_crypto);
|
||||
if (m->net_crypto == NULL) {
|
||||
kill_networking(m->net);
|
||||
kill_DHT(m->dht);
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m->onion = new_onion(m->dht);
|
||||
m->onion_a = new_onion_announce(m->dht);
|
||||
m->onion_c = new_onion_client(m->dht);
|
||||
m->onion_c = new_onion_client(m->net_crypto);
|
||||
|
||||
if (!(m->onion && m->onion_a && m->onion_c)) {
|
||||
kill_onion(m->onion);
|
||||
|
@ -2409,10 +2407,12 @@ int wait_cleanup_messenger(Messenger *m, uint8_t *data)
|
|||
#define MESSENGER_STATE_TYPE_STATUSMESSAGE 5
|
||||
#define MESSENGER_STATE_TYPE_STATUS 6
|
||||
|
||||
#define SAVED_FRIEND_REQUEST_SIZE 1024
|
||||
|
||||
struct SAVED_FRIEND {
|
||||
uint8_t status;
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do.
|
||||
uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do.
|
||||
uint16_t info_size; // Length of the info.
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
uint16_t name_length;
|
||||
|
@ -2428,7 +2428,7 @@ struct SAVED_FRIEND {
|
|||
struct SAVED_FRIEND_OLD {
|
||||
uint8_t status;
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
uint8_t info[MAX_DATA_SIZE];
|
||||
uint8_t info[1024];
|
||||
uint16_t info_size;
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
uint16_t name_length;
|
||||
|
@ -2456,7 +2456,12 @@ static uint32_t friends_list_save(Messenger *m, uint8_t *data)
|
|||
memcpy(temp.client_id, m->friendlist[i].client_id, CLIENT_ID_SIZE);
|
||||
|
||||
if (temp.status < 3) {
|
||||
if (m->friendlist[i].info_size > SAVED_FRIEND_REQUEST_SIZE) {
|
||||
memcpy(temp.info, m->friendlist[i].info, SAVED_FRIEND_REQUEST_SIZE);
|
||||
} else {
|
||||
memcpy(temp.info, m->friendlist[i].info, m->friendlist[i].info_size);
|
||||
}
|
||||
|
||||
temp.info_size = htons(m->friendlist[i].info_size);
|
||||
temp.friendrequest_nospam = m->friendlist[i].friendrequest_nospam;
|
||||
} else {
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
#define PACKET_ID_STATUSMESSAGE 49
|
||||
#define PACKET_ID_USERSTATUS 50
|
||||
#define PACKET_ID_TYPING 51
|
||||
#define PACKET_ID_RECEIPT 65
|
||||
#define PACKET_ID_RECEIPT 63
|
||||
#define PACKET_ID_MESSAGE 64
|
||||
#define PACKET_ID_ACTION 63
|
||||
#define PACKET_ID_ACTION 65
|
||||
#define PACKET_ID_MSI 69
|
||||
#define PACKET_ID_FILE_SENDREQUEST 80
|
||||
#define PACKET_ID_FILE_CONTROL 81
|
||||
|
@ -134,7 +134,7 @@ typedef struct {
|
|||
uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
|
||||
uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
|
||||
uint8_t status; // 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online.
|
||||
uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do.
|
||||
uint8_t info[MAX_FRIEND_REQUEST_DATA_SIZE]; // the data that is sent during the friend requests we do.
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
uint16_t name_length;
|
||||
uint8_t name_sent; // 0 if we didn't send our name to this friend 1 if we have.
|
||||
|
|
|
@ -167,3 +167,72 @@ void new_nonce(uint8_t *nonce)
|
|||
increment_nonce(base_nonce);
|
||||
memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
|
||||
}
|
||||
|
||||
/* Create a request to peer.
|
||||
* send_public_key and send_secret_key are the pub/secret keys of the sender.
|
||||
* recv_public_key is public key of reciever.
|
||||
* packet must be an array of MAX_CRYPTO_REQUEST_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).
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
|
||||
uint8_t *data, uint32_t length, uint8_t request_id)
|
||||
{
|
||||
if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 +
|
||||
crypto_box_MACBYTES)
|
||||
return -1;
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
|
||||
memcpy(temp + 1, data, length);
|
||||
temp[0] = request_id;
|
||||
new_nonce(nonce);
|
||||
int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
|
||||
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
packet[0] = NET_PACKET_CRYPTO;
|
||||
memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_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
|
||||
* 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 *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, uint8_t *packet, uint16_t length)
|
||||
{
|
||||
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
|
||||
length <= MAX_CRYPTO_REQUEST_SIZE) {
|
||||
if (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];
|
||||
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
|
||||
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), temp);
|
||||
|
||||
if (len1 == -1 || len1 == 0)
|
||||
return -1;
|
||||
|
||||
request_id[0] = temp[0];
|
||||
--len1;
|
||||
memcpy(data, temp + 1, len1);
|
||||
return len1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "network.h"
|
||||
|
||||
|
||||
/* return zero if the buffer contains only zeros. */
|
||||
uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
|
||||
|
||||
|
@ -83,4 +84,34 @@ void new_symmetric_key(uint8_t *key);
|
|||
/*Gives a nonce guaranteed to be different from previous ones.*/
|
||||
void new_nonce(uint8_t *nonce);
|
||||
|
||||
#define MAX_CRYPTO_REQUEST_SIZE 1024
|
||||
|
||||
#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
|
||||
#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
|
||||
#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */
|
||||
|
||||
/* Create a request to peer.
|
||||
* send_public_key and send_secret_key are the pub/secret keys of the sender.
|
||||
* recv_public_key is public key of reciever.
|
||||
* packet must be an array of MAX_CRYPTO_REQUEST_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).
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_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 *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, uint8_t *packet, uint16_t length);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,10 +37,10 @@
|
|||
*/
|
||||
int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (length + sizeof(nospam_num) >= MAX_DATA_SIZE)
|
||||
if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0)
|
||||
return -1;
|
||||
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
uint8_t temp[1 + sizeof(nospam_num) + length];
|
||||
temp[0] = CRYPTO_PACKET_FRIEND_REQ;
|
||||
memcpy(temp + 1, &nospam_num, sizeof(nospam_num));
|
||||
memcpy(temp + 1 + sizeof(nospam_num), data, length);
|
||||
|
@ -50,7 +50,7 @@ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nosp
|
|||
if (friend_num == -1)
|
||||
return -1;
|
||||
|
||||
int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length);
|
||||
int num = send_onion_data(onion_c, friend_num, temp, sizeof(temp));
|
||||
|
||||
if (num <= 0)
|
||||
return -1;
|
||||
|
@ -137,7 +137,7 @@ static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t
|
|||
{
|
||||
Friend_Requests *fr = object;
|
||||
|
||||
if (length <= 1 + sizeof(fr->nospam) || length > MAX_DATA_SIZE)
|
||||
if (length <= 1 + sizeof(fr->nospam) || length > ONION_CLIENT_MAX_DATA_SIZE)
|
||||
return 1;
|
||||
|
||||
++packet;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "onion_client.h"
|
||||
|
||||
#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t)))
|
||||
|
||||
typedef struct {
|
||||
uint32_t nospam;
|
||||
void (*handle_friendrequest)(void *, uint8_t *, uint8_t *, uint16_t, void *);
|
||||
|
@ -47,6 +49,7 @@ typedef struct {
|
|||
|
||||
/* Try to send a friendrequest to peer with public_key.
|
||||
* data is the data in the request and length is the length.
|
||||
* Maximum length of data is MAX_FRIEND_REQUEST_DATA_SIZE.
|
||||
*/
|
||||
int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
|
||||
/* Set and get the nospam variable used to prevent one type of friend request spam. */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "LAN_discovery.h"
|
||||
#include "util.h"
|
||||
|
||||
#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
|
||||
#define GROUPCHAT_MAXDATA_LENGTH (MAX_CRYPTO_REQUEST_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
|
||||
#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES)
|
||||
|
||||
#define GROUP_MAX_SENDNODES (GROUP_CLOSE_CONNECTIONS * 2)
|
||||
|
@ -181,7 +181,7 @@ static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *publ
|
|||
if (id_equal(chat->self_public_key, public_key))
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
int len = create_request(chat->self_public_key, chat->self_secret_key, packet, public_key, data, length, request_id);
|
||||
packet[0] = NET_PACKET_GROUP_CHATS;
|
||||
|
||||
|
@ -587,10 +587,10 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
|
|||
|
||||
static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id)
|
||||
{
|
||||
if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/
|
||||
if (len + GROUP_DATA_MIN_SIZE > MAX_CRYPTO_REQUEST_SIZE) /*NOTE: not the real maximum len.*/
|
||||
return 1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
++chat->message_number;
|
||||
|
||||
if (chat->message_number == 0)
|
||||
|
@ -616,11 +616,11 @@ static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t
|
|||
|
||||
int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
if (length > MAX_DATA_SIZE)
|
||||
if (length > MAX_CRYPTO_REQUEST_SIZE)
|
||||
return 1;
|
||||
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
uint8_t number;
|
||||
int len = handle_request(chat->self_public_key, chat->self_secret_key, public_key, data, &number, packet, length);
|
||||
|
||||
|
|
|
@ -249,113 +249,6 @@ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uin
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Create a request to peer.
|
||||
* send_public_key and send_secret_key are the pub/secret keys of the sender.
|
||||
* recv_public_key is public key of reciever.
|
||||
* 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).
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
|
||||
uint8_t *data, uint32_t length, uint8_t request_id)
|
||||
{
|
||||
if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES)
|
||||
return -1;
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
memcpy(temp + 1, data, length);
|
||||
temp[0] = request_id;
|
||||
new_nonce(nonce);
|
||||
int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
|
||||
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
|
||||
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
packet[0] = NET_PACKET_CRYPTO;
|
||||
memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_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
|
||||
* 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 *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, uint8_t *packet, uint16_t length)
|
||||
{
|
||||
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
|
||||
length <= MAX_DATA_SIZE) {
|
||||
if (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];
|
||||
uint8_t temp[MAX_DATA_SIZE];
|
||||
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), temp);
|
||||
|
||||
if (len1 == -1 || len1 == 0)
|
||||
return -1;
|
||||
|
||||
request_id[0] = temp[0];
|
||||
--len1;
|
||||
memcpy(data, temp + 1, len1);
|
||||
return len1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object)
|
||||
{
|
||||
c->cryptopackethandlers[byte].function = cb;
|
||||
c->cryptopackethandlers[byte].object = object;
|
||||
}
|
||||
|
||||
static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
DHT *dht = object;
|
||||
|
||||
if (packet[0] == NET_PACKET_CRYPTO) {
|
||||
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
|
||||
length > MAX_DATA_SIZE + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint8_t number;
|
||||
int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
|
||||
|
||||
if (len == -1 || len == 0)
|
||||
return 1;
|
||||
|
||||
if (!dht->c->cryptopackethandlers[number].function) return 1;
|
||||
|
||||
return dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key,
|
||||
data, len);
|
||||
|
||||
} else { /* If request is not for us, try routing it. */
|
||||
int retval = route_packet(dht, packet + 1, packet, length);
|
||||
|
||||
if ((unsigned int)retval == length)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
|
||||
* to peer with connection_id and public_key.
|
||||
|
@ -774,11 +667,11 @@ static void receive_crypto(Net_Crypto *c)
|
|||
/* Run this to (re)initialize net_crypto.
|
||||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
Net_Crypto *new_net_crypto(Networking_Core *net)
|
||||
Net_Crypto *new_net_crypto(DHT *dht)
|
||||
{
|
||||
unix_time_update();
|
||||
|
||||
if (net == NULL)
|
||||
if (dht == NULL)
|
||||
return NULL;
|
||||
|
||||
Net_Crypto *temp = calloc(1, sizeof(Net_Crypto));
|
||||
|
@ -786,7 +679,8 @@ Net_Crypto *new_net_crypto(Networking_Core *net)
|
|||
if (temp == NULL)
|
||||
return NULL;
|
||||
|
||||
temp->lossless_udp = new_lossless_udp(net);
|
||||
temp->dht = dht;
|
||||
temp->lossless_udp = new_lossless_udp(dht->net);
|
||||
|
||||
if (temp->lossless_udp == NULL) {
|
||||
free(temp);
|
||||
|
@ -798,12 +692,6 @@ Net_Crypto *new_net_crypto(Networking_Core *net)
|
|||
return temp;
|
||||
}
|
||||
|
||||
void init_cryptopackets(void *dht)
|
||||
{
|
||||
DHT *s_dht = dht;
|
||||
networking_registerhandler(s_dht->c->lossless_udp->net, NET_PACKET_CRYPTO, &cryptopacket_handle, s_dht);
|
||||
}
|
||||
|
||||
static void kill_timedout(Net_Crypto *c)
|
||||
{
|
||||
uint32_t i;
|
||||
|
|
|
@ -27,12 +27,6 @@
|
|||
#include "Lossless_UDP.h"
|
||||
#include "DHT.h"
|
||||
|
||||
#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
|
||||
#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
|
||||
#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */
|
||||
#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */
|
||||
#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
|
||||
|
||||
#define CRYPTO_CONN_NO_CONNECTION 0
|
||||
|
@ -58,13 +52,6 @@ typedef struct {
|
|||
|
||||
} Crypto_Connection;
|
||||
|
||||
typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
typedef struct {
|
||||
cryptopacket_handler_callback function;
|
||||
void *object;
|
||||
} Cryptopacket_Handles;
|
||||
|
||||
typedef struct {
|
||||
Lossless_UDP *lossless_udp;
|
||||
|
@ -79,9 +66,7 @@ typedef struct {
|
|||
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
|
||||
|
||||
/* The secret key used for cookies */
|
||||
uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
|
||||
|
||||
Cryptopacket_Handles cryptopackethandlers[256];
|
||||
uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
|
||||
} Net_Crypto;
|
||||
|
||||
#include "DHT.h"
|
||||
|
@ -102,26 +87,6 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
|
|||
*/
|
||||
int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
|
||||
|
||||
/* Create a request to peer.
|
||||
* send_public_key and send_secret_key are the pub/secret keys of the sender.
|
||||
* recv_public_key is public key of reciever.
|
||||
* 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).
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_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 *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, uint8_t *packet, uint16_t length);
|
||||
|
||||
/* Function to call when request beginning with byte is received. */
|
||||
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object);
|
||||
|
||||
|
@ -186,15 +151,13 @@ void load_keys(Net_Crypto *c, uint8_t *keys);
|
|||
/* Create new instance of Net_Crypto.
|
||||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
Net_Crypto *new_net_crypto(Networking_Core *net);
|
||||
Net_Crypto *new_net_crypto(DHT *dht);
|
||||
|
||||
/* Main loop. */
|
||||
void do_net_crypto(Net_Crypto *c);
|
||||
|
||||
void kill_net_crypto(Net_Crypto *c);
|
||||
|
||||
/* Initialize the cryptopacket handling. */
|
||||
void init_cryptopackets(void *dht);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "onion.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAX_ONION_SIZE MAX_DATA_SIZE
|
||||
|
||||
#define RETURN_1 ONION_RETURN_1
|
||||
#define RETURN_2 ONION_RETURN_2
|
||||
#define RETURN_3 ONION_RETURN_3
|
||||
|
@ -89,13 +87,14 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes)
|
|||
/* Create and send a onion packet.
|
||||
*
|
||||
* Use Onion_Path path to send data of length to dest.
|
||||
* Maximum length of data is ONION_MAX_DATA_SIZE.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (1 + length + SEND_1 > MAX_ONION_SIZE || length == 0)
|
||||
if (1 + length + SEND_1 > ONION_MAX_PACKET_SIZE || length == 0)
|
||||
return -1;
|
||||
|
||||
to_net_family(&dest.ip);
|
||||
|
@ -142,13 +141,18 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create and send a onion response sent initially to dest with.
|
||||
* Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret)
|
||||
{
|
||||
if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0)
|
||||
return -1;
|
||||
|
||||
uint8_t packet[1 + RETURN_3 + length];
|
||||
packet[0] = NET_PACKET_ONION_RECV_3;
|
||||
memcpy(packet + 1, ret, RETURN_3);
|
||||
|
@ -164,7 +168,7 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + SEND_1)
|
||||
|
@ -172,7 +176,7 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
|
|||
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[MAX_ONION_SIZE];
|
||||
uint8_t plain[ONION_MAX_PACKET_SIZE];
|
||||
uint8_t shared_key[crypto_box_BEFORENMBYTES];
|
||||
get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
|
||||
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
|
@ -190,7 +194,7 @@ int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, uin
|
|||
memcpy(&send_to, plain, sizeof(IP_Port));
|
||||
to_host_family(&send_to.ip);
|
||||
|
||||
uint8_t data[MAX_ONION_SIZE];
|
||||
uint8_t data[ONION_MAX_PACKET_SIZE];
|
||||
data[0] = NET_PACKET_ONION_SEND_1;
|
||||
memcpy(data + 1, nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port));
|
||||
|
@ -215,7 +219,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + SEND_2)
|
||||
|
@ -223,7 +227,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[MAX_ONION_SIZE];
|
||||
uint8_t plain[ONION_MAX_PACKET_SIZE];
|
||||
uint8_t shared_key[crypto_box_BEFORENMBYTES];
|
||||
get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
|
||||
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
|
@ -236,7 +240,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
memcpy(&send_to, plain, sizeof(IP_Port));
|
||||
to_host_family(&send_to.ip);
|
||||
|
||||
uint8_t data[MAX_ONION_SIZE];
|
||||
uint8_t data[ONION_MAX_PACKET_SIZE];
|
||||
data[0] = NET_PACKET_ONION_SEND_2;
|
||||
memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES);
|
||||
memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port));
|
||||
|
@ -264,7 +268,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + SEND_3)
|
||||
|
@ -272,7 +276,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
|
||||
change_symmetric_key(onion);
|
||||
|
||||
uint8_t plain[MAX_ONION_SIZE];
|
||||
uint8_t plain[ONION_MAX_PACKET_SIZE];
|
||||
uint8_t shared_key[crypto_box_BEFORENMBYTES];
|
||||
get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
|
||||
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
|
@ -285,7 +289,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
memcpy(&send_to, plain, sizeof(IP_Port));
|
||||
to_host_family(&send_to.ip);
|
||||
|
||||
uint8_t data[MAX_ONION_SIZE];
|
||||
uint8_t data[ONION_MAX_PACKET_SIZE];
|
||||
memcpy(data, plain + sizeof(IP_Port), len - sizeof(IP_Port));
|
||||
uint32_t data_len = (len - sizeof(IP_Port));
|
||||
uint8_t *ret_part = data + (len - sizeof(IP_Port));
|
||||
|
@ -312,7 +316,7 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + RETURN_3)
|
||||
|
@ -330,7 +334,7 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
IP_Port send_to;
|
||||
memcpy(&send_to, plain, sizeof(IP_Port));
|
||||
|
||||
uint8_t data[MAX_ONION_SIZE];
|
||||
uint8_t data[ONION_MAX_PACKET_SIZE];
|
||||
data[0] = NET_PACKET_ONION_RECV_2;
|
||||
memcpy(data + 1, plain + sizeof(IP_Port), RETURN_2);
|
||||
memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3));
|
||||
|
@ -346,7 +350,7 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + RETURN_2)
|
||||
|
@ -364,7 +368,7 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
IP_Port send_to;
|
||||
memcpy(&send_to, plain, sizeof(IP_Port));
|
||||
|
||||
uint8_t data[MAX_ONION_SIZE];
|
||||
uint8_t data[ONION_MAX_PACKET_SIZE];
|
||||
data[0] = NET_PACKET_ONION_RECV_1;
|
||||
memcpy(data + 1, plain + sizeof(IP_Port), RETURN_1);
|
||||
memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2));
|
||||
|
@ -380,7 +384,7 @@ static int handle_recv_1(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length > MAX_ONION_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
if (length <= 1 + RETURN_1)
|
||||
|
@ -424,7 +428,7 @@ Onion *new_onion(DHT *dht)
|
|||
return NULL;
|
||||
|
||||
onion->dht = dht;
|
||||
onion->net = dht->c->lossless_udp->net;
|
||||
onion->net = dht->net;
|
||||
new_symmetric_key(onion->secret_symmetric_key);
|
||||
onion->timestamp = unix_time();
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ typedef struct {
|
|||
void *callback_object;
|
||||
} Onion;
|
||||
|
||||
#define ONION_MAX_PACKET_SIZE 1400
|
||||
|
||||
#define ONION_RETURN_1 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES)
|
||||
#define ONION_RETURN_2 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES + ONION_RETURN_1)
|
||||
#define ONION_RETURN_3 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES + ONION_RETURN_2)
|
||||
|
@ -48,6 +50,9 @@ typedef struct {
|
|||
#define ONION_SEND_2 (crypto_box_NONCEBYTES + ONION_SEND_BASE*2 + ONION_RETURN_1)
|
||||
#define ONION_SEND_1 (crypto_box_NONCEBYTES + ONION_SEND_BASE*3)
|
||||
|
||||
#define ONION_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1))
|
||||
#define ONION_RESPONSE_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (1 + ONION_RETURN_3))
|
||||
|
||||
typedef struct {
|
||||
uint8_t shared_key1[crypto_box_BEFORENMBYTES];
|
||||
uint8_t shared_key2[crypto_box_BEFORENMBYTES];
|
||||
|
@ -76,6 +81,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
|
|||
/* Create and send a onion packet.
|
||||
*
|
||||
* Use Onion_Path path to send data of length to dest.
|
||||
* Maximum length of data is ONION_MAX_DATA_SIZE.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
|
@ -83,6 +89,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
|
|||
int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length);
|
||||
|
||||
/* Create and send a onion response sent initially to dest with.
|
||||
* Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
|
||||
#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
|
||||
|
||||
#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
|
||||
#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)
|
||||
|
||||
/* Create and send an onion announce request packet.
|
||||
|
@ -90,6 +90,9 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
|
|||
int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key,
|
||||
uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE)
|
||||
return -1;
|
||||
|
||||
uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
|
||||
packet[0] = NET_PACKET_ONION_DATA_REQUEST;
|
||||
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
|
||||
|
@ -304,7 +307,7 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui
|
|||
if (length <= DATA_REQUEST_MIN_SIZE_RECV)
|
||||
return 1;
|
||||
|
||||
if (length >= MAX_DATA_SIZE)
|
||||
if (length > ONION_MAX_PACKET_SIZE)
|
||||
return 1;
|
||||
|
||||
int index = in_entries(onion_a, packet + 1);
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES
|
||||
#endif
|
||||
|
||||
#define ONION_DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
#define MAX_DATA_REQUEST_SIZE (ONION_MAX_DATA_SIZE - ONION_DATA_REQUEST_MIN_SIZE)
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
IP_Port ret_ip_port;
|
||||
|
@ -86,6 +89,8 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
|
|||
*
|
||||
* nonce is the nonce to encrypt this packet with
|
||||
*
|
||||
* The maximum length of data is MAX_DATA_REQUEST_SIZE.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
|
|
|
@ -183,9 +183,9 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
|
|||
if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1)
|
||||
return -1;
|
||||
|
||||
return send_announce_request(onion_c->net, &path, dest_node, onion_c->dht->c->self_public_key,
|
||||
onion_c->dht->c->self_secret_key, ping_id,
|
||||
onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback);
|
||||
return send_announce_request(onion_c->net, &path, dest_node, onion_c->c->self_public_key,
|
||||
onion_c->c->self_secret_key, ping_id,
|
||||
onion_c->c->self_public_key, onion_c->temp_public_key, sendback);
|
||||
} else {
|
||||
if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1)
|
||||
return -1;
|
||||
|
@ -236,7 +236,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
|
|||
|
||||
if (num == 0) {
|
||||
list_nodes = onion_c->clients_announce_list;
|
||||
reference_id = onion_c->dht->c->self_public_key;
|
||||
reference_id = onion_c->c->self_public_key;
|
||||
|
||||
if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
|
||||
is_stored = 0;
|
||||
|
@ -325,7 +325,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
|
|||
|
||||
if (num == 0) {
|
||||
list_nodes = onion_c->clients_announce_list;
|
||||
reference_id = onion_c->dht->c->self_public_key;
|
||||
reference_id = onion_c->c->self_public_key;
|
||||
ping_nodes_sent_second = &onion_c->ping_nodes_sent_second;
|
||||
last_pinged = onion_c->last_pinged;
|
||||
last_pinged_index = &onion_c->last_pinged_index;
|
||||
|
@ -388,7 +388,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
|||
int len = -1;
|
||||
|
||||
if (num == 0) {
|
||||
len = decrypt_data(public_key, onion_c->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
||||
len = decrypt_data(public_key, onion_c->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
|
||||
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
|
||||
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain);
|
||||
} else {
|
||||
|
@ -421,7 +421,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE
|
||||
|
||||
static int handle_data_response(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||
{
|
||||
|
@ -430,7 +430,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
|
|||
if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE))
|
||||
return 1;
|
||||
|
||||
if (length > MAX_DATA_SIZE)
|
||||
if (length > MAX_DATA_REQUEST_SIZE)
|
||||
return 1;
|
||||
|
||||
uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE];
|
||||
|
@ -442,7 +442,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
|
|||
return 1;
|
||||
|
||||
uint8_t plain[sizeof(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE];
|
||||
len = decrypt_data(temp_plain, onion_c->dht->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES,
|
||||
len = decrypt_data(temp_plain, onion_c->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES,
|
||||
sizeof(temp_plain) - crypto_box_PUBLICKEYBYTES, plain);
|
||||
|
||||
if ((uint32_t)len != sizeof(plain))
|
||||
|
@ -527,7 +527,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
|
|||
if ((uint32_t)friend_num >= onion_c->num_friends)
|
||||
return -1;
|
||||
|
||||
if (length + DATA_IN_RESPONSE_MIN_SIZE + ONION_DATA_RESPONSE_MIN_SIZE + ONION_SEND_1 > MAX_DATA_SIZE)
|
||||
if (length + DATA_IN_RESPONSE_MIN_SIZE > MAX_DATA_REQUEST_SIZE)
|
||||
return -1;
|
||||
|
||||
if (length == 0)
|
||||
|
@ -537,8 +537,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
|
|||
random_nonce(nonce);
|
||||
|
||||
uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length];
|
||||
memcpy(packet, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
|
||||
memcpy(packet, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data,
|
||||
length, packet + crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet))
|
||||
|
@ -597,15 +597,15 @@ static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data,
|
|||
new_nonce(nonce);
|
||||
|
||||
uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
|
||||
memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(temp, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
|
||||
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data,
|
||||
length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||
|
||||
if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
|
||||
return -1;
|
||||
|
||||
uint8_t packet[MAX_DATA_SIZE];
|
||||
uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
|
||||
len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
|
||||
onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
|
||||
|
||||
|
@ -626,7 +626,7 @@ static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubke
|
|||
return 1;
|
||||
|
||||
uint8_t plain[FAKEID_DATA_MAX_LENGTH];
|
||||
int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
|
||||
int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
|
||||
packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
|
||||
length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
|
||||
|
||||
|
@ -960,7 +960,7 @@ static void do_announce(Onion_Client *onion_c)
|
|||
if (count != MAX_ONION_CLIENTS) {
|
||||
if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list,
|
||||
uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list,
|
||||
rand() % 2 ? AF_INET : AF_INET6, 1, 0);
|
||||
|
||||
for (i = 0; i < num_nodes; ++i) {
|
||||
|
@ -989,9 +989,9 @@ void do_onion_client(Onion_Client *onion_c)
|
|||
onion_c->last_run = unix_time();
|
||||
}
|
||||
|
||||
Onion_Client *new_onion_client(DHT *dht)
|
||||
Onion_Client *new_onion_client(Net_Crypto *c)
|
||||
{
|
||||
if (dht == NULL)
|
||||
if (c == NULL)
|
||||
return NULL;
|
||||
|
||||
Onion_Client *onion_c = calloc(1, sizeof(Onion_Client));
|
||||
|
@ -999,14 +999,15 @@ Onion_Client *new_onion_client(DHT *dht)
|
|||
if (onion_c == NULL)
|
||||
return NULL;
|
||||
|
||||
onion_c->dht = dht;
|
||||
onion_c->net = dht->c->lossless_udp->net;
|
||||
onion_c->dht = c->dht;
|
||||
onion_c->net = c->dht->net;
|
||||
onion_c->c = c;
|
||||
new_symmetric_key(onion_c->secret_symmetric_key);
|
||||
crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
|
||||
oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
|
||||
cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
|
||||
cryptopacket_registerhandler(onion_c->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
|
||||
|
||||
return onion_c;
|
||||
}
|
||||
|
@ -1020,7 +1021,7 @@ void kill_onion_client(Onion_Client *onion_c)
|
|||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
|
||||
oniondata_registerhandler(onion_c, FAKEID_DATA_ID, NULL, NULL);
|
||||
cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, NULL, NULL);
|
||||
cryptopacket_registerhandler(onion_c->c, FAKEID_DATA_ID, NULL, NULL);
|
||||
memset(onion_c, 0, sizeof(Onion_Client));
|
||||
free(onion_c);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define ONION_CLIENT_H
|
||||
|
||||
#include "onion_announce.h"
|
||||
#include "net_crypto.h"
|
||||
|
||||
#define MAX_ONION_CLIENTS 8
|
||||
#define ONION_NODE_PING_INTERVAL 30
|
||||
|
@ -105,6 +106,7 @@ typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey,
|
|||
|
||||
typedef struct {
|
||||
DHT *dht;
|
||||
Net_Crypto *c;
|
||||
Networking_Core *net;
|
||||
Onion_Friend *friends_list;
|
||||
uint16_t num_friends;
|
||||
|
@ -170,8 +172,11 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
|
|||
*/
|
||||
int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
|
||||
|
||||
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
|
||||
|
||||
/* Send data of length length to friendnum.
|
||||
* Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
|
||||
* This data will be recieved by the friend using the Onion_Data_Handlers callbacks.
|
||||
*
|
||||
* Even if this function succeeds, the friend might not recieve any data.
|
||||
|
@ -186,7 +191,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
|
|||
|
||||
void do_onion_client(Onion_Client *onion_c);
|
||||
|
||||
Onion_Client *new_onion_client(DHT *dht);
|
||||
Onion_Client *new_onion_client(Net_Crypto *c);
|
||||
|
||||
void kill_onion_client(Onion_Client *onion_c);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user