mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Updated Lossless UDP.
This commit is contained in:
parent
6bd24212ee
commit
4ad22addf4
|
@ -21,7 +21,8 @@
|
|||
along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
//TODO: clean this file a bit.
|
||||
//There are a couple of useless variables to get rid of.
|
||||
#include "Lossless_UDP.h"
|
||||
|
||||
|
||||
|
@ -89,11 +90,61 @@ Connection connections[MAX_CONNECTIONS];
|
|||
|
||||
//Functions
|
||||
|
||||
//get connection id from IP_Port
|
||||
//return -1 if there are no connections like we are looking for
|
||||
//return id if it found it
|
||||
int getconnection_id(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(connections[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//table of random numbers used below.
|
||||
static uint32_t randtable[6][256];
|
||||
|
||||
|
||||
//generate a handshake_id which depends on the ip_port.
|
||||
//this function will always give one unique handshake_id per ip_port.
|
||||
//TODO: make this better
|
||||
uint32_t handshake_id(IP_Port source)
|
||||
{
|
||||
uint32_t id = 0, i;
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
if(randtable[i][((uint8_t *)&source)[i]] == 0)
|
||||
{
|
||||
randtable[i][((uint8_t *)&source)[i]] = random_int();
|
||||
}
|
||||
id ^= randtable[i][((uint8_t *)&source)[i]];
|
||||
}
|
||||
if(id == 0)//id can't be zero
|
||||
{
|
||||
id = 1;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//initialize a new connection to ip_port
|
||||
//returns an integer corresponding to the connection id.
|
||||
//return -1 if it could not initialize the connection.
|
||||
//if there already was an existing connection to that ip_port return its number.
|
||||
int new_connection(IP_Port ip_port)
|
||||
{
|
||||
int connect = getconnection_id(ip_port);
|
||||
if(connect != -1)
|
||||
{
|
||||
return connect;
|
||||
}
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_CONNECTIONS; i++)
|
||||
{
|
||||
|
@ -102,7 +153,7 @@ int new_connection(IP_Port ip_port)
|
|||
connections[i].ip_port = ip_port;
|
||||
connections[i].status = 1;
|
||||
connections[i].inbound = 0;
|
||||
connections[i].handshake_id1 = random_int();
|
||||
connections[i].handshake_id1 = handshake_id(ip_port);
|
||||
connections[i].sent_packetnum = connections[i].handshake_id1;
|
||||
connections[i].sendbuff_packetnum = connections[i].handshake_id1;
|
||||
connections[i].successful_sent = connections[i].handshake_id1;
|
||||
|
@ -121,6 +172,10 @@ int new_connection(IP_Port ip_port)
|
|||
//return -1 if it could not initialize the connection.
|
||||
int new_inconnection(IP_Port ip_port)
|
||||
{
|
||||
if(getconnection_id(ip_port) != -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_CONNECTIONS; i++)
|
||||
{
|
||||
|
@ -159,10 +214,13 @@ int incoming_connection()
|
|||
//return 0 if killed successfully
|
||||
int kill_connection(int connection_id)
|
||||
{
|
||||
if(connections[connection_id].status > 0)
|
||||
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
|
||||
{
|
||||
connections[connection_id].status = 0;
|
||||
return 0;
|
||||
if(connections[connection_id].status > 0)
|
||||
{
|
||||
connections[connection_id].status = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -174,7 +232,22 @@ int kill_connection(int connection_id)
|
|||
//return 3 if fully connected
|
||||
int is_connected(int connection_id)
|
||||
{
|
||||
return connections[connection_id].status;
|
||||
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
|
||||
{
|
||||
return connections[connection_id].status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//returns the ip_port of the corresponding connection.
|
||||
IP_Port connection_ip(int connection_id)
|
||||
{
|
||||
if(connection_id > 0 && connection_id < MAX_CONNECTIONS)
|
||||
{
|
||||
return connections[connection_id].ip_port;
|
||||
}
|
||||
IP_Port zero = {{{0}}, 0};
|
||||
return zero;
|
||||
}
|
||||
|
||||
//returns the number of packets in the queue waiting to be successfully sent.
|
||||
|
@ -331,47 +404,7 @@ int send_DATA(uint32_t connection_id)
|
|||
|
||||
//END of packet sending functions
|
||||
|
||||
//get connection id from IP_Port
|
||||
//return -1 if there are no connections like we are looking for
|
||||
//return id if it found it
|
||||
int getconnection_id(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(connections[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//table of random numbers used below.
|
||||
static uint32_t randtable[6][256];
|
||||
|
||||
|
||||
//generate a handshake_id which depends on the ip_port.
|
||||
//this function will always give one unique handshake_id per ip_port.
|
||||
//TODO: make this better
|
||||
uint32_t handshake_id(IP_Port source)
|
||||
{
|
||||
uint32_t id = 0, i;
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
if(randtable[i][((uint8_t *)&source)[i]] == 0)
|
||||
{
|
||||
randtable[i][((uint8_t *)&source)[i]] = random_int();
|
||||
}
|
||||
id ^= randtable[i][((uint8_t *)&source)[i]];
|
||||
}
|
||||
if(id == 0)//id can't be zero
|
||||
{
|
||||
id = 1;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
//Packet handling functions
|
||||
//One to handle each type of packets we recieve
|
||||
|
@ -383,27 +416,29 @@ int handle_handshake(char * packet, uint32_t length, IP_Port source)
|
|||
return 1;
|
||||
}
|
||||
uint32_t handshake_id1, handshake_id2;
|
||||
int connection = getconnection_id(source);
|
||||
memcpy(&handshake_id1, packet + 1, 4);
|
||||
memcpy(&handshake_id2, packet + 5, 4);
|
||||
|
||||
|
||||
if(handshake_id2 == 0)
|
||||
{
|
||||
send_handshake(source, handshake_id1, handshake_id(source));
|
||||
send_handshake(source, handshake_id(source), handshake_id1);
|
||||
return 0;
|
||||
}
|
||||
int connection = getconnection_id(source);
|
||||
if(is_connected(connection) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if(handshake_id1 == connections[connection].handshake_id1)//if handshake_id1 is what we sent previously.
|
||||
if(handshake_id2 == connections[connection].handshake_id1)//if handshake_id2 is what we sent previously as handshake_id1
|
||||
{
|
||||
connections[connection].status = 2;
|
||||
//NOTE:is this necessary?
|
||||
//connections[connection].handshake_id2 = handshake_id2;
|
||||
connections[connection].orecv_packetnum = handshake_id1;
|
||||
connections[connection].osent_packetnum = handshake_id2;
|
||||
connections[connection].recv_packetnum = handshake_id2;
|
||||
connections[connection].successful_read = handshake_id2;
|
||||
//connections[connection].handshake_id2 = handshake_id1;
|
||||
connections[connection].orecv_packetnum = handshake_id2;
|
||||
connections[connection].osent_packetnum = handshake_id1;
|
||||
connections[connection].recv_packetnum = handshake_id1;
|
||||
connections[connection].successful_read = handshake_id1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -33,40 +33,56 @@
|
|||
//initialize a new connection to ip_port
|
||||
//returns an integer corresponding to the connection id.
|
||||
//return -1 if it could not initialize the connection.
|
||||
//if there already was an existing connection to that ip_port return its number.
|
||||
int new_connection(IP_Port ip_port);
|
||||
|
||||
|
||||
//returns an integer corresponding to the next connection in our imcoming connection list
|
||||
//return -1 if there are no new incoming connections in the list.
|
||||
int incoming_connection();
|
||||
|
||||
|
||||
//return -1 if it could not kill the connection.
|
||||
//return 0 if killed successfully
|
||||
int kill_connection(int connection_id);
|
||||
|
||||
|
||||
//returns the ip_port of the corresponding connection.
|
||||
//return 0 if there is no such connection.
|
||||
IP_Port connection_ip(int connection_id);
|
||||
|
||||
|
||||
//return 0 if there is no received data in the buffer.
|
||||
//return length of recieved packet if successful
|
||||
int read_packet(int connection_id, char * data);
|
||||
|
||||
|
||||
//return 0 if data could not be put in packet queue
|
||||
//return 1 if data was put into the queue
|
||||
int write_packet(int connection_id, char * data, uint32_t length);
|
||||
|
||||
|
||||
//returns the number of packets in the queue waiting to be successfully sent.
|
||||
uint32_t sendqueue(int connection_id);
|
||||
|
||||
|
||||
//returns the number of packets in the queue waiting to be successfully read with read_packet(...)
|
||||
uint32_t recvqueue(int connection_id);
|
||||
|
||||
|
||||
//check if connection is connected
|
||||
//return 0 no.
|
||||
//return 1 if yes
|
||||
//return 2 if the initial attempt isn't over yet.
|
||||
//return 1 if attempting handshake
|
||||
//return 2 if handshake is done
|
||||
//return 3 if fully connected
|
||||
int is_connected(int connection_id);
|
||||
|
||||
|
||||
//Call this function a couple times per second
|
||||
//It's the main loop.
|
||||
void doLossless_UDP();
|
||||
|
||||
|
||||
//if we receive a Lossless_UDP packet we call this function so it can be handled.
|
||||
//Return 0 if packet is handled correctly.
|
||||
//return 1 if it didn't handle the packet or if the packet was shit.
|
||||
|
|
|
@ -63,7 +63,10 @@ Lossless UDP:
|
|||
|
||||
The client receives a Connection handshake packet(not initiating connection):
|
||||
If handshake_id2 is zero:
|
||||
add our random handshake_id2 to it and send it back
|
||||
use the handshake_id1 in the packet as the handshake_id2 of the response.
|
||||
use our random handshake_id1 as handshake_id1.
|
||||
send the response packet.
|
||||
|
||||
|
||||
|
||||
The client receives a Connection handshake packet(initiating connection):
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*
|
||||
* Compile with: gcc -O2 -Wall -o testclient ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testclient.c
|
||||
*
|
||||
* Command line arguments are the ip and port to cennect and send the file to.
|
||||
* EX: ./test 127.0.0.1 33445 filename.txt
|
||||
* Command line arguments are the ip and port to connect and send the file to.
|
||||
* EX: ./testclient 127.0.0.1 33445 filename.txt
|
||||
*/
|
||||
|
||||
#include "../core/network.h"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Compile with: gcc -O2 -Wall -o testserver ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testserver.c
|
||||
*
|
||||
* Command line argument is the name of the file to save what we recieve to.
|
||||
* EX: ./test filename1.txt
|
||||
* EX: ./testserver filename1.txt
|
||||
*/
|
||||
|
||||
#include "../core/network.h"
|
||||
|
|
Loading…
Reference in New Issue
Block a user