Remove Lossless UDP (This breaks Tox.)

This commit is contained in:
irungentoo 2014-05-02 10:36:48 -04:00
parent deb8bfc350
commit 8e24771fc4
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
11 changed files with 60 additions and 2400 deletions

View File

@ -1,260 +0,0 @@
/* Lossless_UDP testclient
* A program that connects and sends a file using our lossless UDP algorithm.
* NOTE: this program simulates a 33% packet loss.
*
* Best used in combination with Lossless_UDP_testserver
*
* Compile with: gcc -O2 -Wall -lsodium -o testclient ../toxcore/network.c ../toxcore/Lossless_UDP.c ../toxcore/util.c Lossless_UDP_testclient.c
*
* Command line arguments are the ip and port to connect and send the file to.
* EX: ./testclient --ipv4 127.0.0.1 33445 filename.txt
*
* Copyright (C) 2013 Tox project All Rights Reserved.
*
* This file is part of Tox.
*
* Tox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../toxcore/network.h"
#include "../toxcore/Lossless_UDP.h"
#include "../toxcore/util.h"
#include "misc_tools.c"
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
#define c_sleep(x) Sleep(1*x)
#else
#include <unistd.h>
#include <arpa/inet.h>
#define c_sleep(x) usleep(1000*x)
#endif
#define PORT 33446
void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
{
uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) {
if (data[i] < 16)
printf("0");
printf("%hhX", data[i]);
}
printf("\n--------------------END-----------------------------\n\n\n");
}
void printip(IP_Port ip_port)
{
printf("\nIP: %s Port: %u", ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
}
/*
void printpackets(Data test)
{
int i;
if(test.size == 0)
return;
printf("SIZE: %u\n", test.size);
for(i =0; i < test.size; i++)
{
printf("%hhX", test.data[i]);
}
printf("\n");
}
void printconnection(int connection_id)
{
printf("--------------------BEGIN---------------------\n");
IP_Port ip_port = connections[connection_id].ip_port;
printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
connections[connection_id].inbound, connections[connection_id].SYNC_rate);
printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
int i;
for(i =0; i < MAX_QUEUE_NUM; i++)
{
printf(" %u ",i);
printpackets(connections[connection_id].sendbuffer[i]);
}
for(i =0; i < MAX_QUEUE_NUM; i++)
{
printf(" %u ",i);
printpackets(connections[connection_id].recvbuffer[i]);
}
Data sendbuffer[MAX_QUEUE_NUM];
Data recvbuffer[MAX_QUEUE_NUM];
printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
connections[connection_id].recv_packetnum,
connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent,
connections[connection_id].successful_read);
printf("req packets: \n");
for(i = 0; i < BUFFER_PACKET_NUM; i++)
{
printf(" %u ", connections[connection_id].req_packets[i]);
}
printf("\nNumber: %u recv_counter: %u, send_counter: %u\n", connections[connection_id].num_req_paquets,
connections[connection_id].recv_counter, connections[connection_id].send_counter);
printf("--------------------END---------------------\n");
}
*/
/*( receive packets and send them to the packethandler */
/*run doLossless_UDP(); */
//void Lossless_UDP()
//{
/* IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1) {
printf("packet with length: %u\n", length); */
/* if(rand() % 3 != 1)//add packet loss
{ */
/*
if (LosslessUDP_handlepacket(data, length, ip_port))
printpacket(data, length, ip_port);
else
printf("Received handled packet with length: %u\n", length); //printconnection(0); */
/* } */
/* }*/
//networking_poll();
//doLossless_UDP();
//}
int main(int argc, char *argv[])
{
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
if (argc < argvoffset + 4) {
printf("Usage: %s [--ipv4|--ipv6] ip port filename\n", argv[0]);
exit(0);
}
uint8_t buffer[MAX_DATA_SIZE];
int read;
FILE *file = fopen(argv[argvoffset + 3], "rb");
if (file == NULL) {
printf("Failed to open file \"%s\".\n", argv[argvoffset + 3]);
return 1;
}
/* initialize networking */
/* bind to ip 0.0.0.0:PORT */
IP ip;
ip_init(&ip, ipv6enabled);
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
perror("Initialization");
IP_Port serverip;
ip_init(&serverip.ip, ipv6enabled);
if (!addr_resolve(argv[argvoffset + 1], &serverip.ip, NULL)) {
printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]);
return 1;
}
serverip.port = htons(atoi(argv[argvoffset + 2]));
printip(serverip);
int connection = new_connection(ludp, serverip);
uint64_t timer = current_time();
while (1) {
/* printconnection(connection); */
networking_poll(ludp->net);
do_lossless_udp(ludp);
if (is_connected(ludp, connection) == LUDP_ESTABLISHED) {
printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
break;
}
if (is_connected(ludp, connection) == LUDP_NO_CONNECTION) {
printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
return 1;
}
c_sleep(1);
}
timer = current_time();
unsigned long long bytes_sent = 0;
/*read first part of file */
read = fread(buffer, 1, MAX_DATA_SIZE, file);
while (1) {
/* printconnection(connection); */
networking_poll(ludp->net);
do_lossless_udp(ludp);
if (is_connected(ludp, connection) == LUDP_ESTABLISHED) {
while (write_packet(ludp, connection, buffer, read)) {
bytes_sent += read;
/* printf("Wrote data.\n"); */
read = fread(buffer, 1, MAX_DATA_SIZE, file);
}
/* printf("%u\n", sendqueue(connection)); */
if (sendqueue(ludp, connection) == 0) {
if (read == 0) {
unsigned long long us = (unsigned long long)(current_time() - timer);
printf("Sent file successfully in: %llu us = %llu seconds. Average speed: %llu KB/s\n", us, us / 1000000UL,
bytes_sent / (us / 1024UL));
//printf("Total bytes sent: %llu B, Total data sent: %llu B, overhead: %llu B\n", total_bytes_sent, bytes_sent, total_bytes_sent-bytes_sent);
break;
}
}
} else {
printf("%u Client Connecting Lost after: %llu us\n", is_connected(ludp, connection),
(unsigned long long)(current_time() - timer));
return 0;
}
}
c_sleep(25);
return 0;
}

View File

@ -1,237 +0,0 @@
/* Lossless_UDP testserver
* A program that waits for a lossless UDP connection and then saves all the data received to a file.
* NOTE: this program simulates a 33% packet loss.
*
* Best used in combination with Lossless_UDP_testclient
*
* Compile with: gcc -O2 -Wall -lsodium -o testserver ../toxcore/network.c ../toxcore/Lossless_UDP.c ../toxcore/util.c Lossless_UDP_testserver.c
*
* Command line argument is the name of the file to save what we receive to.
* EX: ./testserver filename1.txt
*
* Copyright (C) 2013 Tox project All Rights Reserved.
*
* This file is part of Tox.
*
* Tox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../toxcore/network.h"
#include "../toxcore/Lossless_UDP.h"
#include "../toxcore/util.h"
#include "misc_tools.c"
//Sleep function (x = milliseconds)
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
#define c_sleep(x) Sleep(1*x)
#else
#include <unistd.h>
#include <arpa/inet.h>
#define c_sleep(x) usleep(1000*x)
#endif
#define PORT 33445
void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
{
uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) {
if (data[i] < 16)
printf("0");
printf("%hhX", data[i]);
}
printf("\n--------------------END-----------------------------\n\n\n");
}
/*
void printpackets(Data test)
{
int i;
if(test.size == 0)
return;
printf("SIZE: %u\n", test.size);
for(i =0; i < test.size; i++)
{
printf("%hhX", test.data[i]);
}
printf("\n");
}
void printconnection(int connection_id)
{
printf("--------------------BEGIN---------------------\n");
IP_Port ip_port = connections[connection_id].ip_port;
printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
connections[connection_id].inbound, connections[connection_id].SYNC_rate);
printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
int i;
for(i =0; i < MAX_QUEUE_NUM; i++)
{
printf(" %u ",i);
printpackets(connections[connection_id].sendbuffer[i]);
}
for(i =0; i < MAX_QUEUE_NUM; i++)
{
printf(" %u ",i);
printpackets(connections[connection_id].recvbuffer[i]);
}
Data sendbuffer[MAX_QUEUE_NUM];
Data recvbuffer[MAX_QUEUE_NUM];
printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
connections[connection_id].recv_packetnum,
connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent,
connections[connection_id].successful_read);
printf("req packets: \n");
for(i = 0; i < BUFFER_PACKET_NUM; i++)
{
printf(" %u ", connections[connection_id].req_packets[i]);
}
printf("\nNumber: %u recv_counter: %u, send_counter: %u\n", connections[connection_id].num_req_paquets,
connections[connection_id].recv_counter, connections[connection_id].send_counter);
printf("--------------------END---------------------\n");
}
*/
/* receive packets and send them to the packethandler
* run doLossless_UDP(); */
//void Lossless_UDP()
//{
// IP_Port ip_port;
// uint8_t data[MAX_UDP_PACKET_SIZE];
// uint32_t length;
// while (receivepacket(&ip_port, data, &length) != -1) {
//if(rand() % 3 != 1)//add packet loss
//{
// if (LosslessUDP_handlepacket(data, length, ip_port)) {
// printpacket(data, length, ip_port);
// } else {
//printconnection(0);
// printf("Received handled packet with length: %u\n", length);
// }
//}
// }
// networking_poll();
//doLossless_UDP();
//}
int main(int argc, char *argv[])
{
/* let user override default by cmdline */
uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0)
exit(1);
if (argc < argvoffset + 2) {
printf("Usage: %s [--ipv4|--ipv6] filename\n", argv[0]);
exit(0);
}
uint8_t buffer[MAX_DATA_SIZE];
int read;
FILE *file = fopen(argv[argvoffset + 1], "wb");
if (file == NULL) {
printf("Failed to open file \"%s\".\n", argv[argvoffset + 1]);
return 1;
}
//initialize networking
//bind to ip 0.0.0.0:PORT
IP ip;
ip_init(&ip, ipv6enabled);
Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
perror("Initialization");
int connection;
uint64_t timer = current_time();
while (1) {
networking_poll(ludp->net);
do_lossless_udp(ludp);
connection = incoming_connection(ludp, 0);
if (connection != -1) {
if (is_connected(ludp, connection) == LUDP_NOT_CONFIRMED) {
printf("Received the connection.\n");
}
break;
}
c_sleep(1);
}
timer = current_time();
while (1) {
//printconnection(0);
networking_poll(ludp->net);
if (is_connected(ludp, connection) >= LUDP_NOT_CONFIRMED) {
confirm_connection(ludp, connection);
while (1) {
read = read_packet(ludp, connection, buffer);
if (read != 0) {
// printf("Received data.\n");
if (!fwrite(buffer, read, 1, file))
printf("file write error\n");
} else {
break;
}
}
}
do_lossless_udp(ludp);
if (is_connected(ludp, connection) == LUDP_TIMED_OUT) {
printf("Server Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
fclose(file);
return 1;
}
c_sleep(25);
}
return 0;
}

View File

@ -22,8 +22,6 @@ endif
if BUILD_TESTING
noinst_PROGRAMS += DHT_test \
Lossless_UDP_testclient \
Lossless_UDP_testserver \
Messenger_test \
crypto_speed_test
@ -41,40 +39,6 @@ DHT_test_LDADD = $(LIBSODIUM_LDFLAGS) \
$(WINSOCK2_LIBS)
Lossless_UDP_testclient_SOURCES = \
../testing/Lossless_UDP_testclient.c
Lossless_UDP_testclient_CFLAGS = \
$(LIBSODIUM_CFLAGS) \
$(NACL_CFLAGS)
Lossless_UDP_testclient_LDADD = \
$(LIBSODIUM_LDFLAGS) \
$(NACL_LDFLAGS) \
libtoxcore.la \
$(LIBSODIUM_LIBS) \
$(NACL_OBJECTS) \
$(NACL_LIBS) \
$(WINSOCK2_LIBS)
Lossless_UDP_testserver_SOURCES = \
../testing/Lossless_UDP_testserver.c
Lossless_UDP_testserver_CFLAGS = \
$(LIBSODIUM_CFLAGS) \
$(NACL_CFLAGS)
Lossless_UDP_testserver_LDADD = \
$(LIBSODIUM_LDFLAGS) \
$(NACL_LDFLAGS) \
libtoxcore.la \
$(LIBSODIUM_LIBS) \
$(NACL_OBJECTS) \
$(NACL_LIBS) \
$(WINSOCK2_LIBS)
Messenger_test_SOURCES = \
../testing/Messenger_test.c

File diff suppressed because it is too large Load Diff

View File

@ -1,262 +0,0 @@
/* Lossless_UDP.h
*
* An implementation of the Lossless_UDP protocol as seen in http://wiki.tox.im/index.php/Lossless_UDP
*
* Copyright (C) 2013 Tox project All Rights Reserved.
*
* This file is part of Tox.
*
* Tox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef LOSSLESS_UDP_H
#define LOSSLESS_UDP_H
#include "network.h"
#include "crypto_core.h"
#include "misc_tools.h"
/* Maximum length of the data in the data packets. */
#define MAX_DATA_SIZE 1024
/* Maximum data packets in sent and receive queues. */
#define MAX_QUEUE_NUM 1024
#define DEFAULT_QUEUE_NUM 4
/* Maximum number of data packets in the buffer. */
#define MAX_REQUESTED_PACKETS 256
/* Timeout per connection is randomly set between CONNECTION_TIMEOUT and 2*CONNECTION_TIMEOUT. */
#define CONNECTION_TIMEOUT 5
/* Initial amount of sync/handshake packets to send per second. */
#define SYNC_RATE 2
/* Initial send rate of data. */
#define DATA_SYNC_RATE 30
typedef struct {
uint8_t data[MAX_DATA_SIZE];
uint16_t size;
} Data;
#define LUDP_NO_CONNECTION 0
#define LUDP_HANDSHAKE_SENDING 1
#define LUDP_NOT_CONFIRMED 2
#define LUDP_ESTABLISHED 3
#define LUDP_TIMED_OUT 4
typedef struct {
IP_Port ip_port;
/*
* return LUDP_NO_CONNECTION if connection is dead.
* return LUDP_HANDSHAKE_SENDING if attempting handshake.
* return LUDP_NOT_CONFIRMED if handshake is done (we start sending SYNC packets).
* return LUDP_ESTABLISHED if we are sending SYNC packets and can send data.
* return LUDP_TIMED_OUT if the connection has timed out.
*/
uint8_t status;
/*
* return 0 if connection was not initiated by someone else.
* return 1 if incoming_connection() has returned.
* return 2 if it has not.
*/
uint8_t inbound;
uint16_t SYNC_rate; /* Current SYNC packet send rate packets per second. */
uint32_t data_rate; /* Current data packet send rate packets per second. */
uint64_t last_SYNC; /* Time our last SYNC packet was sent. */
uint64_t last_sent; /* Time our last data or handshake packet was sent. */
uint64_t last_recvSYNC; /* Time we last received a SYNC packet from the other. */
uint64_t last_recvdata; /* Time we last received a DATA packet from the other. */
uint64_t killat; /* Time to kill the connection. */
Data *sendbuffer; /* packet send buffer. */
uint32_t sendbuffer_length;
Data *recvbuffer; /* packet receive buffer. */
uint32_t recvbuffer_length;
uint32_t handshake_id1;
uint32_t handshake_id2;
/* Number of data packets received (also used as handshake_id1). */
uint32_t recv_packetnum;
/* Number of packets received by the other peer. */
uint32_t orecv_packetnum;
/* Number of data packets sent. */
uint32_t sent_packetnum;
/* Number of packets sent by the other peer. */
uint32_t osent_packetnum;
/* Number of latest packet written onto the sendbuffer. */
uint32_t sendbuff_packetnum;
/* We know all packets before that number were successfully sent. */
uint32_t successful_sent;
/* Packet number of last packet read with the read_packet function. */
uint32_t successful_read;
/* List of currently requested packet numbers(by the other person). */
uint32_t req_packets[MAX_REQUESTED_PACKETS];
/* Total number of currently requested packets(by the other person). */
uint16_t num_req_paquets;
uint8_t recv_counter;
uint8_t send_counter;
uint8_t timeout; /* connection timeout in seconds. */
/* Is the connection confirmed or not? 1 if yes, 0 if no */
uint8_t confirmed;
} Connection;
typedef struct {
Networking_Core *net;
tox_array connections;
/* Table of random numbers used in handshake_id. */
/* IPv6 (16) + port (2)*/
uint32_t randtable[18][256];
} Lossless_UDP;
/*
* Initialize a new connection to ip_port.
*
* return an integer corresponding to the connection id.
* return -1 if it could not initialize the connection.
* return number if there already was an existing connection to that ip_port.
*/
int new_connection(Lossless_UDP *ludp, IP_Port ip_port);
/*
* Get connection id from IP_Port.
*
* return -1 if there are no connections like we are looking for.
* return id if it found it .
*/
int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port);
/*
* return an integer corresponding to the next connection in our incoming connection list with at least numpackets in the recieve queue.
* return -1 if there are no new incoming connections in the list.
*/
int incoming_connection(Lossless_UDP *ludp, uint32_t numpackets);
/* return -1 if it could not kill the connection.
* return 0 if killed successfully.
*/
int kill_connection(Lossless_UDP *ludp, int connection_id);
/*
* timeout connection in seconds seconds.
*
* return -1 if it can not kill the connection.
* return 0 if it will kill it.
*/
int timeout_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds);
/* Check if connection is confirmed.
*
* returns 1 if yes.
* returns 0 if no.
*/
int connection_confirmed(Lossless_UDP *ludp, int connection_id);
/* Confirm an incoming connection.
* Also disables the auto kill timeout on incomming connections.
*
* return 0 on success
* return -1 on failure.
*/
int confirm_connection(Lossless_UDP *ludp, int connection_id);
/* returns the ip_port of the corresponding connection.
* return 0 if there is no such connection.
*/
IP_Port connection_ip(Lossless_UDP *ludp, int connection_id);
/* returns the id of the next packet in the queue.
* return -1 if no packet in queue.
*/
uint8_t id_packet(Lossless_UDP *ludp, int connection_id);
/* return 0 if there is no received data in the buffer.
* return length of received packet if successful.
*/
int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data);
/* Like read_packet() but does leaves the queue as is.
* return 0 if there is no received data in the buffer.
* return length of received packet if successful.
*/
int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data);
/* Discard the next packet to be read from the queue
* return 0 if success.
* return -1 if failure.
*/
int discard_packet(Lossless_UDP *ludp, int connection_id);
/* returns the number of packet slots left in the sendbuffer.
* return 0 if failure.
*/
uint32_t num_free_sendqueue_slots(Lossless_UDP *ludp, int connection_id);
/* return 0 if data could not be put in packet queue.
* return 1 if data was put into the queue.
*/
int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t length);
/* return number of packets in the queue waiting to be successfully sent. */
uint32_t sendqueue(Lossless_UDP *ludp, int connection_id);
/* return number of packets in all queues waiting to be successfully sent. */
uint32_t sendqueue_total(Lossless_UDP *ludp);
/*
* return number of packets in the queue waiting to be successfully
* read with read_packet(...).
*/
uint32_t recvqueue(Lossless_UDP *ludp, int connection_id);
/* Check if connection is connected:
*
* return LUDP_NO_CONNECTION if not.
* return LUDP_HANDSHAKE_SENDING if attempting handshake.
* return LUDP_NOT_CONFIRMED if handshake is done.
* return LUDP_ESTABLISHED if fully connected.
* return LUDP_TIMED_OUT if timed out and wating to be killed.
*/
int is_connected(Lossless_UDP *ludp, int connection_id);
/* Call this function a couple times per second. It is the main loop. */
void do_lossless_udp(Lossless_UDP *ludp);
/* This function sets up LosslessUDP packet handling. */
Lossless_UDP *new_lossless_udp(Networking_Core *net);
void kill_lossless_udp(Lossless_UDP *ludp);
#endif

View File

@ -11,8 +11,6 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
../toxcore/network.c \
../toxcore/crypto_core.h \
../toxcore/crypto_core.c \
../toxcore/Lossless_UDP.h \
../toxcore/Lossless_UDP.c \
../toxcore/net_crypto.h \
../toxcore/net_crypto.c \
../toxcore/friend_requests.h \

View File

@ -406,10 +406,10 @@ uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, uint8_t *message, uin
uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
{
if (length >= (MAX_DATA_SIZE - sizeof(theid)))
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)))
return 0;
uint8_t temp[MAX_DATA_SIZE];
uint8_t temp[MAX_CRYPTO_DATA_SIZE];
theid = htonl(theid);
memcpy(temp, &theid, sizeof(theid));
memcpy(temp + sizeof(theid), message, length);
@ -440,10 +440,10 @@ uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint3
uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length)
{
if (length >= (MAX_DATA_SIZE - sizeof(theid)))
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)))
return 0;
uint8_t temp[MAX_DATA_SIZE];
uint8_t temp[MAX_CRYPTO_DATA_SIZE];
theid = htonl(theid);
memcpy(temp, &theid, sizeof(theid));
memcpy(temp + sizeof(theid), action, length);
@ -840,7 +840,7 @@ int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id,
if (friend_not_valid(m, friendnumber))
return 0;
if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
if (length >= MAX_CRYPTO_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
return 0;
uint8_t packet[length + 1];
@ -888,7 +888,7 @@ static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber)
if (is_cryptoconnected(m->net_crypto, crypt_id) != CRYPTO_CONN_ESTABLISHED)
return zero;
return connection_ip(m->net_crypto->lossless_udp, m->net_crypto->crypto_connections[crypt_id].number);
return m->net_crypto->crypto_connections[crypt_id].ip_port;
}
/* returns the group number of the chat with public key group_public_key.
@ -1395,7 +1395,7 @@ int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_
int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
uint8_t *data, uint16_t length)
{
if (length > MAX_DATA_SIZE - 3)
if (length > MAX_CRYPTO_DATA_SIZE - 3)
return -1;
if (friend_not_valid(m, friendnumber))
@ -1412,7 +1412,7 @@ int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8
if (send_receive > 1)
return -1;
uint8_t packet[MAX_DATA_SIZE];
uint8_t packet[MAX_CRYPTO_DATA_SIZE];
packet[0] = send_receive;
packet[1] = filenumber;
packet[2] = message_id;
@ -1482,7 +1482,7 @@ int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8
*/
int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length)
{
if (length > MAX_DATA_SIZE - 1)
if (length > MAX_CRYPTO_DATA_SIZE - 1)
return -1;
if (friend_not_valid(m, friendnumber))
@ -1495,7 +1495,7 @@ int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *d
if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE)
return -1;
uint8_t packet[MAX_DATA_SIZE];
uint8_t packet[MAX_CRYPTO_DATA_SIZE];
packet[0] = filenumber;
memcpy(packet + 1, data, length);
@ -1738,6 +1738,23 @@ static void LANdiscovery(Messenger *m)
}
}
int handle_new_connections(void *object, New_Connection *n_c)
{
Messenger *m = object;
int friend_id = getfriend_id(m, n_c->public_key);
if (friend_id != -1) {
if (m->friendlist[friend_id].crypt_connection_id != -1)
return -1;
m->friendlist[friend_id].crypt_connection_id = accept_crypto_connection(m->net_crypto, n_c);
set_friend_status(m, friend_id, FRIEND_CONFIRMED);
}
return -1;
}
/* Run this at startup. */
Messenger *new_messenger(uint8_t ipv6enabled)
{
@ -1772,6 +1789,8 @@ Messenger *new_messenger(uint8_t ipv6enabled)
return NULL;
}
new_connection_handler(m->net_crypto, &handle_new_connections, m);
m->onion = new_onion(m->dht);
m->onion_a = new_onion_announce(m->dht);
m->onion_c = new_onion_client(m->net_crypto);
@ -1843,7 +1862,7 @@ void do_friends(Messenger *m)
{
uint32_t i;
int len;
uint8_t temp[MAX_DATA_SIZE];
uint8_t temp[MAX_CRYPTO_DATA_SIZE];
uint64_t temp_time = unix_time();
for (i = 0; i < m->numfriends; ++i) {
@ -2184,32 +2203,8 @@ void do_friends(Messenger *m)
}
}
void do_inbound(Messenger *m)
{
uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
int inconnection = crypto_inbound(m->net_crypto, public_key, secret_nonce, session_key);
if (inconnection != -1) {
int friend_id = getfriend_id(m, public_key);
if (friend_id != -1) {
if (m_get_friend_connectionstatus(m, friend_id) == 1) {
kill_connection(m->net_crypto->lossless_udp, inconnection);
return;
}
crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id);
m->friendlist[friend_id].crypt_connection_id =
accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key);
set_friend_status(m, friend_id, FRIEND_CONFIRMED);
} else {
kill_connection(m->net_crypto->lossless_udp, inconnection);
}
}
}
#ifdef LOGGING
#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL
@ -2238,7 +2233,6 @@ void do_messenger(Messenger *m)
do_net_crypto(m->net_crypto);
do_onion_client(m->onion_c);
do_friends(m);
do_inbound(m);
do_allgroupchats(m);
LANdiscovery(m);
@ -2381,7 +2375,9 @@ size_t wait_data_size()
int wait_prepare_messenger(Messenger *m, uint8_t *data)
{
return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data);
//TODO
//return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data);
return networking_wait_prepare(m->net, 1024, data);
}
int wait_execute_messenger(uint8_t *data, long seconds, long microseconds)

View File

@ -34,6 +34,7 @@
#include "onion_client.h"
#define MAX_NAME_LENGTH 128
/* TODO: this must depend on other variable. */
#define MAX_STATUSMESSAGE_LENGTH 1007
#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))

View File

@ -705,7 +705,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
*
* The set function should return -1 on failure and 0 on success.
*
* n_c is only valid for the duration of this function.
* n_c is only valid for the duration of the function call.
*/
void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
void *object)
@ -968,31 +968,7 @@ static void send_crypto_packets(Net_Crypto *c)
*/
int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
{
if (crypt_connection_id_not_valid(c, crypt_connection_id))
return 0;
if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED)
return 0;
uint8_t temp_data[MAX_DATA_SIZE];
int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data);
if (length == 0)
return 0;
if (temp_data[0] != 3)
return -1;
int len = decrypt_data_symmetric(c->crypto_connections[crypt_connection_id].shared_key,
c->crypto_connections[crypt_connection_id].recv_nonce,
temp_data + 1, length - 1, data);
if (len != -1) {
increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce);
return len;
}
return -1;
}
/* returns the number of packet slots left in the sendbuffer.
@ -1000,10 +976,7 @@ int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
*/
uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
{
if (crypt_connection_id_not_valid(c, crypt_connection_id))
return 0;
return num_free_sendqueue_slots(c->lossless_udp, c->crypto_connections[crypt_connection_id].number);
}
/* return 0 if data could not be put in packet queue.
@ -1011,93 +984,7 @@ 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)
{
if (crypt_connection_id_not_valid(c, crypt_connection_id))
return 0;
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
return 0;
if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED)
return 0;
uint8_t temp_data[MAX_DATA_SIZE];
int len = encrypt_data_symmetric(c->crypto_connections[crypt_connection_id].shared_key,
c->crypto_connections[crypt_connection_id].sent_nonce,
data, length, temp_data + 1);
if (len == -1)
return 0;
temp_data[0] = 3;
if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
return 0;
increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce);
return 1;
}
/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
* to peer with connection_id and public_key.
* The packet is encrypted with a random nonce which is sent in plain text with the packet.
*/
static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce,
uint8_t *session_key)
{
uint8_t temp_data[MAX_DATA_SIZE];
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
uint8_t nonce[crypto_box_NONCEBYTES];
new_nonce(nonce);
memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
if (len == -1)
return 0;
temp_data[0] = 2;
memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
return write_packet(c->lossless_udp, connection_id, temp_data,
len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
}
/* Extract secret nonce, session public key and public_key from a packet(data) with length length.
*
* return 1 if successful.
* return 0 if failure.
*/
static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce,
uint8_t *session_key, uint8_t *data, uint16_t length)
{
int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
+ crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) {
return 0;
}
if (data[0] != 2)
return 0;
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES)
return 0;
memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
return 1;
}
@ -1108,92 +995,7 @@ static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *s
*/
int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port)
{
uint32_t i;
int id_existing = getcryptconnection_id(c, public_key);
if (id_existing != -1) {
IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id_existing].number);
if (ipport_equal(&c_ip, &ip_port))
return -1;
}
if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1
|| c->crypto_connections == NULL)
return -1;
memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
c->crypto_connections[c->crypto_connections_length].number = ~0;
for (i = 0; i <= c->crypto_connections_length; ++i) {
if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) {
int id_new = new_connection(c->lossless_udp, ip_port);
if (id_new == -1)
return -1;
c->crypto_connections[i].number = id_new;
c->crypto_connections[i].status = CRYPTO_CONN_HANDSHAKE_SENT;
random_nonce(c->crypto_connections[i].recv_nonce);
memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
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;
if (c->crypto_connections_length == i)
++c->crypto_connections_length;
if (send_cryptohandshake(c, id_new, public_key, c->crypto_connections[i].recv_nonce,
c->crypto_connections[i].sessionpublic_key) == 1) {
increment_nonce(c->crypto_connections[i].recv_nonce);
return i;
}
return -1; /* This should never happen. */
}
}
return -1;
}
/* Handle an incoming connection.
*
* return -1 if no crypto inbound connection.
* return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection.
*
* Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
* and the session public key for the connection in session_key.
* to accept it see: accept_crypto_inbound(...).
* to refuse it just call kill_connection(...) on the connection id.
*/
int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
{
while (1) {
int incoming_con = incoming_connection(c->lossless_udp, 1);
if (incoming_con != -1) {
if (is_connected(c->lossless_udp, incoming_con) == LUDP_TIMED_OUT) {
kill_connection(c->lossless_udp, incoming_con);
continue;
}
if (id_packet(c->lossless_udp, incoming_con) == 2) {
uint8_t temp_data[MAX_DATA_SIZE];
uint16_t len = read_packet_silent(c->lossless_udp, incoming_con, temp_data);
if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) {
return incoming_con;
} else {
kill_connection(c->lossless_udp, incoming_con);
}
} else {
kill_connection(c->lossless_udp, incoming_con);
}
} else {
break;
}
}
return -1;
}
/* Kill a crypto connection.
@ -1203,94 +1005,7 @@ int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, ui
*/
int crypto_kill(Net_Crypto *c, int crypt_connection_id)
{
if (crypt_connection_id_not_valid(c, crypt_connection_id))
return 1;
if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_NO_CONNECTION) {
c->crypto_connections[crypt_connection_id].status = CRYPTO_CONN_NO_CONNECTION;
kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number);
memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
c->crypto_connections[crypt_connection_id].number = ~0;
uint32_t i;
for (i = c->crypto_connections_length; i != 0; --i) {
if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION)
break;
}
if (c->crypto_connections_length != i) {
c->crypto_connections_length = i;
realloc_cryptoconnection(c, c->crypto_connections_length);
}
return 0;
}
return 1;
}
/* Accept an incoming connection using the parameters provided by crypto_inbound.
*
* return -1 if not successful.
* return the crypt_connection_id if successful.
*/
int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce,
uint8_t *session_key)
{
uint32_t i;
if (discard_packet(c->lossless_udp, connection_id) == -1)
return -1;
/*
* if(getcryptconnection_id(public_key) != -1)
* {
* return -1;
* }
*/
if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1
|| c->crypto_connections == NULL)
return -1;
memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
c->crypto_connections[c->crypto_connections_length].number = ~0;
for (i = 0; i <= c->crypto_connections_length; ++i) {
if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) {
c->crypto_connections[i].number = connection_id;
c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED;
c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
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].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
increment_nonce(c->crypto_connections[i].sent_nonce);
memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
if (c->crypto_connections_length == i)
++c->crypto_connections_length;
if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce,
c->crypto_connections[i].sessionpublic_key) == 1) {
increment_nonce(c->crypto_connections[i].recv_nonce);
uint32_t zero = 0;
encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
c->crypto_connections[i].sessionsecret_key,
c->crypto_connections[i].shared_key);
c->crypto_connections[i].status =
CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */
write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero));
c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */
return i;
}
return -1; /* This should never happen. */
}
}
return -1;
}
/* return 0 if no connection.
@ -1333,84 +1048,7 @@ void load_keys(Net_Crypto *c, uint8_t *keys)
/* Handle received packets for not yet established crypto connections. */
static void receive_crypto(Net_Crypto *c)
{
uint32_t i;
uint64_t temp_time = unix_time();
for (i = 0; i < c->crypto_connections_length; ++i) {
if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION)
continue;
if (c->crypto_connections[i].status == CRYPTO_CONN_HANDSHAKE_SENT) {
uint8_t temp_data[MAX_DATA_SIZE];
uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
uint16_t len;
if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */
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 (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
increment_nonce(c->crypto_connections[i].sent_nonce);
uint32_t zero = 0;
encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
c->crypto_connections[i].sessionsecret_key,
c->crypto_connections[i].shared_key);
c->crypto_connections[i].status =
CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */
write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero));
c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */
} else {
/* This should not happen, timeout the connection if it does. */
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
} else {
/* This should not happen, timeout the connection if it does. */
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
} else if (id_packet(c->lossless_udp,
c->crypto_connections[i].number) != (uint8_t)~0) {
/* This should not happen, timeout the connection if it does. */
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
}
if (c->crypto_connections[i].status == CRYPTO_CONN_NOT_CONFIRMED) {
if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) {
uint8_t temp_data[MAX_DATA_SIZE];
uint8_t data[MAX_DATA_SIZE];
int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data);
int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key,
c->crypto_connections[i].sessionsecret_key,
c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
uint32_t zero = 0;
if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
increment_nonce(c->crypto_connections[i].recv_nonce);
encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
c->crypto_connections[i].sessionsecret_key,
c->crypto_connections[i].shared_key);
c->crypto_connections[i].status = CRYPTO_CONN_ESTABLISHED;
c->crypto_connections[i].timeout = ~0;
/* Connection is accepted. */
confirm_connection(c->lossless_udp, c->crypto_connections[i].number);
} else {
/* This should not happen, timeout the connection if it does. */
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
} else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != (uint8_t)~0) {
/* This should not happen, timeout the connection if it does. */
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
}
if (temp_time > c->crypto_connections[i].timeout) {
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
}
}
}
/* Run this to (re)initialize net_crypto.
@ -1429,12 +1067,6 @@ Net_Crypto *new_net_crypto(DHT *dht)
return NULL;
temp->dht = dht;
temp->lossless_udp = new_lossless_udp(dht->net);
if (temp->lossless_udp == NULL) {
free(temp);
return NULL;
}
new_keys(temp);
new_symmetric_key(temp->secret_symmetric_key);
@ -1451,9 +1083,7 @@ static void kill_timedout(Net_Crypto *c)
uint32_t i;
for (i = 0; i < c->crypto_connections_length; ++i) {
if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION
&& is_connected(c->lossless_udp, c->crypto_connections[i].number) == LUDP_TIMED_OUT)
c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
//TODO
}
}
@ -1461,9 +1091,9 @@ static void kill_timedout(Net_Crypto *c)
void do_net_crypto(Net_Crypto *c)
{
unix_time_update();
do_lossless_udp(c->lossless_udp);
kill_timedout(c);
receive_crypto(c);
send_crypto_packets(c);
}
void kill_net_crypto(Net_Crypto *c)
@ -1474,7 +1104,10 @@ void kill_net_crypto(Net_Crypto *c)
crypto_kill(c, i);
}
kill_lossless_udp(c->lossless_udp);
networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL);
networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_DATA, NULL, NULL);
memset(c, 0, sizeof(Net_Crypto));
free(c);
}

View File

@ -24,7 +24,6 @@
#ifndef NET_CRYPTO_H
#define NET_CRYPTO_H
#include "Lossless_UDP.h"
#include "DHT.h"
#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
@ -39,6 +38,8 @@
#define CRYPTO_PACKET_BUFFER_SIZE 64
#define MAX_CRYPTO_PACKET_SIZE 1400
/* Max size of data in packets TODO*/
#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
/* Interval in ms between sending cookie request/handshake packets. */
@ -58,7 +59,6 @@ typedef struct {
* 4 if the connection is established.
* 5 if the connection is timed out.
*/
uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
uint64_t timeout;
uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
@ -71,7 +71,6 @@ typedef struct {
IP_Port ip_port; /* The ip and port to contact this guy directly.*/
uint64_t direct_lastrecv_time; /* The Time at which we last receive a direct packet. */
} Crypto_Connection;
typedef struct {
@ -84,7 +83,6 @@ typedef struct {
} New_Connection;
typedef struct {
Lossless_UDP *lossless_udp;
DHT *dht;
Crypto_Connection *crypto_connections;
@ -103,6 +101,22 @@ typedef struct {
} Net_Crypto;
/* Set function to be called when someone requests a new connection to us.
*
* The set function should return -1 on failure and 0 on success.
*
* n_c is only valid for the duration of the function call.
*/
void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
void *object);
/* Accept a crypto connection.
*
* return -1 on failure.
* return connection id on success.
*/
int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
/* return 0 if there is no received data in the buffer.
* return -1 if the packet was discarded.
@ -134,25 +148,6 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port);
*/
int crypto_kill(Net_Crypto *c, int crypt_connection_id);
/* Handle an incoming connection.
*
* return -1 if no crypto inbound connection.
* return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection.
*
* Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
* and the session public key for the connection in session_key.
* to accept it see: accept_crypto_inbound(...).
* to refuse it just call kill_connection(...) on the connection id.
*/
int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
/* Accept an incoming connection using the parameters provided by crypto_inbound.
*
* return -1 if not successful.
* return crypt_connection_id if successful.
*/
int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce,
uint8_t *session_key);
/* return 0 if no connection.
* return 1 we have sent a handshake

View File

@ -721,7 +721,7 @@ int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8
*/
int tox_file_data_size(Tox *tox, int32_t friendnumber)
{
return MAX_DATA_SIZE - crypto_box_MACBYTES - 3;
return MAX_CRYPTO_DATA_SIZE - 3;
}
/* Give the number of bytes left to be sent/received.