Merge branch 'master' of https://github.com/KostyaKow/ProjectTox-Core into KostyaKow-master

Conflicts:
	core/DHT.c
This commit is contained in:
irungentoo 2013-07-27 08:26:00 -04:00
commit 1a6446266c
17 changed files with 412 additions and 458 deletions

View File

@ -40,13 +40,13 @@ extern "C" {
client_id must be CLIENT_ID_SIZE bytes long. client_id must be CLIENT_ID_SIZE bytes long.
returns 0 if success returns 0 if success
returns 1 if failure (friends list is full) */ returns 1 if failure (friends list is full) */
int DHT_addfriend(uint8_t * client_id); int DHT_addfriend(uint8_t *client_id);
/* Delete a friend from the friends list /* Delete a friend from the friends list
client_id must be CLIENT_ID_SIZE bytes long. client_id must be CLIENT_ID_SIZE bytes long.
returns 0 if success returns 0 if success
returns 1 if failure (client_id not in friends list) */ returns 1 if failure (client_id not in friends list) */
int DHT_delfriend(uint8_t * client_id); int DHT_delfriend(uint8_t *client_id);
/* Get ip of friend /* Get ip of friend
client_id must be CLIENT_ID_SIZE bytes long. client_id must be CLIENT_ID_SIZE bytes long.
@ -55,7 +55,7 @@ int DHT_delfriend(uint8_t * client_id);
returns ip if success returns ip if success
returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
returns ip of 1 if friend is not in list. */ returns ip of 1 if friend is not in list. */
IP_Port DHT_getfriendip(uint8_t * client_id); IP_Port DHT_getfriendip(uint8_t *client_id);
/* Run this function at least a couple times per second (It's the main loop) */ /* Run this function at least a couple times per second (It's the main loop) */
void doDHT(); void doDHT();
@ -63,21 +63,21 @@ void doDHT();
/* if we receive a DHT packet we call this function so it can be handled. /* if we receive a DHT packet we call this function so it can be handled.
return 0 if packet is handled correctly. return 0 if packet is handled correctly.
return 1 if it didn't handle the packet or if the packet was shit. */ return 1 if it didn't handle the packet or if the packet was shit. */
int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
/* Use this function to bootstrap the client /* Use this function to bootstrap the client
Sends a get nodes request to the given node with ip port and public_key */ Sends a get nodes request to the given node with ip port and public_key */
void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key); void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
/* ROUTING FUNCTIONS */ /* ROUTING FUNCTIONS */
/* send the given packet to node with client_id /* send the given packet to node with client_id
returns -1 if failure */ returns -1 if failure */
int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length); int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length);
/* Send the following packet to everyone who tells us they are connected to friend_id /* Send the following packet to everyone who tells us they are connected to friend_id
returns the number of nodes it sent the packet to */ returns the number of nodes it sent the packet to */
int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length); int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
/* NAT PUNCHING FUNCTIONS */ /* NAT PUNCHING FUNCTIONS */
@ -85,7 +85,7 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length);
ip_portlist must be at least MAX_FRIEND_CLIENTS big ip_portlist must be at least MAX_FRIEND_CLIENTS big
returns the number of ips returned returns the number of ips returned
returns -1 if no such friend*/ returns -1 if no such friend*/
int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id); int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id);
/* SAVE/LOAD functions */ /* SAVE/LOAD functions */
@ -93,12 +93,12 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id);
uint32_t DHT_size(); uint32_t DHT_size();
/* save the DHT in data where data is an array of size DHT_size() */ /* save the DHT in data where data is an array of size DHT_size() */
void DHT_save(uint8_t * data); void DHT_save(uint8_t *data);
/* load the DHT from data of size size; /* load the DHT from data of size size;
return -1 if failure return -1 if failure
return 0 if success */ return 0 if success */
int DHT_load(uint8_t * data, uint32_t size); int DHT_load(uint8_t *data, uint32_t size);
/* returns 0 if we are not connected to the DHT /* returns 0 if we are not connected to the DHT
returns 1 if we are */ returns 1 if we are */

View File

@ -37,24 +37,24 @@ IP broadcast_ip()
return -1 if it is not */ return -1 if it is not */
int LAN_ip(IP ip) int LAN_ip(IP ip)
{ {
if(ip.c[0] == 127)/* Loopback */ if (ip.c[0] == 127)/* Loopback */
return 0; return 0;
if(ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */ if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */
return 0; return 0;
if(ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */ if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */
return 0; return 0;
if(ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */ if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */
return 0; return 0;
if(ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */ if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */
return 0; return 0;
return -1; return -1;
} }
int handle_LANdiscovery(uint8_t * packet, uint32_t length, IP_Port source) int handle_LANdiscovery(uint8_t *packet, uint32_t length, IP_Port source)
{ {
if(LAN_ip(source.ip) == -1) if (LAN_ip(source.ip) == -1)
return 1; return 1;
if(length != crypto_box_PUBLICKEYBYTES + 1) if (length != crypto_box_PUBLICKEYBYTES + 1)
return 1; return 1;
DHT_bootstrap(source, packet + 1); DHT_bootstrap(source, packet + 1);
return 0; return 0;
@ -71,9 +71,9 @@ int send_LANdiscovery(uint16_t port)
} }
int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
{ {
if(packet[0] == 32) if (packet[0] == 32)
return handle_LANdiscovery(packet, length, source); return handle_LANdiscovery(packet, length, source);
return 1; return 1;
} }

View File

@ -39,7 +39,7 @@ int send_LANdiscovery(uint16_t port);
/* if we receive a packet we call this function so it can be handled. /* if we receive a packet we call this function so it can be handled.
return 0 if packet is handled correctly. return 0 if packet is handled correctly.
return 1 if it didn't handle the packet or if the packet was shit. */ return 1 if it didn't handle the packet or if the packet was shit. */
int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);

View File

@ -44,14 +44,12 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION
/* initial send rate of data. */ /* initial send rate of data. */
#define DATA_SYNC_RATE 30 #define DATA_SYNC_RATE 30
typedef struct typedef struct {
{
uint8_t data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE];
uint16_t size; uint16_t size;
}Data; }Data;
typedef struct typedef struct {
{
IP_Port ip_port; IP_Port ip_port;
uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, uint8_t status; /* 0 if connection is dead, 1 if attempting handshake,
2 if handshake is done (we start sending SYNC packets) 2 if handshake is done (we start sending SYNC packets)
@ -97,13 +95,13 @@ static Connection connections[MAX_CONNECTIONS];
/* get connection id from IP_Port /* get connection id from IP_Port
return -1 if there are no connections like we are looking for return -1 if there are no connections like we are looking for
return id if it found it */ return id if it found it */
int getconnection_id(IP_Port ip_port) int getconnection_id(IP_Port ip_port) {
{
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CONNECTIONS; ++i) for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].ip_port.ip.i == ip_port.ip.i && if (connections[i].ip_port.ip.i == ip_port.ip.i &&
connections[i].ip_port.port == ip_port.port && connections[i].status > 0) connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
return i; return i;
}
return -1; return -1;
} }
@ -116,12 +114,12 @@ static uint32_t randtable[6][256];
uint32_t handshake_id(IP_Port source) uint32_t handshake_id(IP_Port source)
{ {
uint32_t id = 0, i; uint32_t id = 0, i;
for(i = 0; i < 6; ++i) { for (i = 0; i < 6; ++i) {
if(randtable[i][((uint8_t *)&source)[i]] == 0) if(randtable[i][((uint8_t *)&source)[i]] == 0)
randtable[i][((uint8_t *)&source)[i]] = random_int(); randtable[i][((uint8_t *)&source)[i]] = random_int();
id ^= randtable[i][((uint8_t *)&source)[i]]; id ^= randtable[i][((uint8_t *)&source)[i]];
} }
if(id == 0) /* id can't be zero */ if (id == 0) /* id can't be zero */
id = 1; id = 1;
return id; return id;
} }
@ -141,10 +139,10 @@ void change_handshake(IP_Port source)
int new_connection(IP_Port ip_port) int new_connection(IP_Port ip_port)
{ {
int connect = getconnection_id(ip_port); int connect = getconnection_id(ip_port);
if(connect != -1) if (connect != -1)
return connect; return connect;
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 0) { if(connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection)); memset(&connections[i], 0, sizeof(Connection));
connections[i].ip_port = ip_port; connections[i].ip_port = ip_port;
@ -173,11 +171,11 @@ int new_connection(IP_Port ip_port)
return -1 if it could not initialize the connection. */ return -1 if it could not initialize the connection. */
int new_inconnection(IP_Port ip_port) int new_inconnection(IP_Port ip_port)
{ {
if(getconnection_id(ip_port) != -1) if (getconnection_id(ip_port) != -1)
return -1; return -1;
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 0) { if (connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection)); memset(&connections[i], 0, sizeof(Connection));
connections[i].ip_port = ip_port; connections[i].ip_port = ip_port;
connections[i].status = 2; connections[i].status = 2;
@ -202,11 +200,12 @@ int new_inconnection(IP_Port ip_port)
int incoming_connection() int incoming_connection()
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CONNECTIONS; ++i) for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].inbound == 2) { if (connections[i].inbound == 2) {
connections[i].inbound = 1; connections[i].inbound = 1;
return i; return i;
} }
}
return -1; return -1;
} }
@ -214,12 +213,13 @@ int incoming_connection()
return 0 if killed successfully */ return 0 if killed successfully */
int kill_connection(int connection_id) int kill_connection(int connection_id)
{ {
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
if(connections[connection_id].status > 0) { if (connections[connection_id].status > 0) {
connections[connection_id].status = 0; connections[connection_id].status = 0;
change_handshake(connections[connection_id].ip_port); change_handshake(connections[connection_id].ip_port);
return 0; return 0;
} }
}
return -1; return -1;
} }
@ -228,11 +228,12 @@ int kill_connection(int connection_id)
return 0 if it will kill it */ return 0 if it will kill it */
int kill_connection_in(int connection_id, uint32_t seconds) int kill_connection_in(int connection_id, uint32_t seconds)
{ {
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
if(connections[connection_id].status > 0) { if (connections[connection_id].status > 0) {
connections[connection_id].killat = current_time() + 1000000UL*seconds; connections[connection_id].killat = current_time() + 1000000UL*seconds;
return 0; return 0;
} }
}
return -1; return -1;
} }
@ -244,7 +245,7 @@ int kill_connection_in(int connection_id, uint32_t seconds)
return 4 if timed out and waiting to be killed */ return 4 if timed out and waiting to be killed */
int is_connected(int connection_id) int is_connected(int connection_id)
{ {
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].status; return connections[connection_id].status;
return 0; return 0;
} }
@ -252,7 +253,7 @@ int is_connected(int connection_id)
/* returns the ip_port of the corresponding connection. */ /* returns the ip_port of the corresponding connection. */
IP_Port connection_ip(int connection_id) IP_Port connection_ip(int connection_id)
{ {
if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].ip_port; return connections[connection_id].ip_port;
IP_Port zero = {{{0}}, 0}; IP_Port zero = {{{0}}, 0};
return zero; return zero;
@ -274,7 +275,7 @@ uint32_t recvqueue(int connection_id)
return -1 if no packet in queue */ return -1 if no packet in queue */
char id_packet(int connection_id) char id_packet(int connection_id)
{ {
if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0) if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0)
return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
return -1; return -1;
} }
@ -283,7 +284,7 @@ char id_packet(int connection_id)
return length of received packet if successful */ return length of received packet if successful */
int read_packet(int connection_id, uint8_t * data) int read_packet(int connection_id, uint8_t * data)
{ {
if(recvqueue(connection_id) != 0) { if (recvqueue(connection_id) != 0) {
uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
uint16_t size = connections[connection_id].recvbuffer[index].size; uint16_t size = connections[connection_id].recvbuffer[index].size;
memcpy(data, connections[connection_id].recvbuffer[index].data, size); memcpy(data, connections[connection_id].recvbuffer[index].data, size);
@ -298,11 +299,11 @@ int read_packet(int connection_id, uint8_t * data)
return 1 if data was put into the queue */ return 1 if data was put into the queue */
int write_packet(int connection_id, uint8_t * data, uint32_t length) int write_packet(int connection_id, uint8_t * data, uint32_t length)
{ {
if(length > MAX_DATA_SIZE) if (length > MAX_DATA_SIZE)
return 0; return 0;
if(length == 0) if (length == 0)
return 0; return 0;
if(sendqueue(connection_id) < BUFFER_PACKET_NUM) { if (sendqueue(connection_id) < BUFFER_PACKET_NUM) {
uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
memcpy(connections[connection_id].sendbuffer[index].data, data, length); memcpy(connections[connection_id].sendbuffer[index].data, data, length);
connections[connection_id].sendbuffer[index].size = length; connections[connection_id].sendbuffer[index].size = length;
@ -318,14 +319,15 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
uint32_t number = 0; uint32_t number = 0;
uint32_t i; uint32_t i;
uint32_t temp; uint32_t temp;
if(recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */
return 0; return 0;
for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
temp = htonl(i); temp = htonl(i);
memcpy(requested + number, &temp, 4); memcpy(requested + number, &temp, 4);
++number; ++number;
} }
}
if(number == 0) if(number == 0)
connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
return number; return number;
@ -393,14 +395,14 @@ int send_DATA(uint32_t connection_id)
{ {
int ret; int ret;
uint32_t buffer[BUFFER_PACKET_NUM]; uint32_t buffer[BUFFER_PACKET_NUM];
if(connections[connection_id].num_req_paquets > 0) { if (connections[connection_id].num_req_paquets > 0) {
ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
connections[connection_id].num_req_paquets--; connections[connection_id].num_req_paquets--;
memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4);
memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4);
return ret; return ret;
} }
if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
connections[connection_id].sent_packetnum++; connections[connection_id].sent_packetnum++;
return ret; return ret;
@ -415,7 +417,7 @@ int send_DATA(uint32_t connection_id)
return 0 if handled correctly, 1 if packet is bad. */ return 0 if handled correctly, 1 if packet is bad. */
int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
{ {
if(length != (1 + 4 + 4)) if (length != (1 + 4 + 4))
return 1; return 1;
uint32_t temp; uint32_t temp;
uint32_t handshake_id1, handshake_id2; uint32_t handshake_id1, handshake_id2;
@ -425,13 +427,13 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
memcpy(&temp, packet + 5, 4); memcpy(&temp, packet + 5, 4);
handshake_id2 = ntohl(temp); handshake_id2 = ntohl(temp);
if(handshake_id2 == 0) { if (handshake_id2 == 0) {
send_handshake(source, handshake_id(source), handshake_id1); send_handshake(source, handshake_id(source), handshake_id1);
return 0; return 0;
} }
if(is_connected(connection) != 1) if (is_connected(connection) != 1)
return 1; return 1;
if(handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */ if (handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */
connections[connection].status = 2; connections[connection].status = 2;
/* NOTE: is this necessary? /* NOTE: is this necessary?
connections[connection].handshake_id2 = handshake_id1; */ connections[connection].handshake_id2 = handshake_id1; */
@ -448,9 +450,9 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
0 if not. */ 0 if not. */
int SYNC_valid(uint32_t length) int SYNC_valid(uint32_t length)
{ {
if(length < 4 + 4 + 2) if (length < 4 + 4 + 2)
return 0; return 0;
if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
((length - 4 - 4 - 2) % 4) != 0) ((length - 4 - 4 - 2) % 4) != 0)
return 0; return 0;
return 1; return 1;
@ -459,9 +461,9 @@ int SYNC_valid(uint32_t length)
/* case 1: */ /* case 1: */
int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
{ {
if(handshake_id(source) == recv_packetnum) { if (handshake_id(source) == recv_packetnum) {
int x = new_inconnection(source); int x = new_inconnection(source);
if(x != -1) { if (x != -1) {
connections[x].orecv_packetnum = recv_packetnum; connections[x].orecv_packetnum = recv_packetnum;
connections[x].sent_packetnum = recv_packetnum; connections[x].sent_packetnum = recv_packetnum;
connections[x].sendbuff_packetnum = recv_packetnum; connections[x].sendbuff_packetnum = recv_packetnum;
@ -479,7 +481,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
/* case 2: */ /* case 2: */
int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
{ {
if(recv_packetnum == connections[connection_id].orecv_packetnum) { if (recv_packetnum == connections[connection_id].orecv_packetnum) {
/* && sent_packetnum == connections[connection_id].osent_packetnum) */ /* && sent_packetnum == connections[connection_id].osent_packetnum) */
connections[connection_id].status = 3; connections[connection_id].status = 3;
connections[connection_id].recv_counter = counter; connections[connection_id].recv_counter = counter;
@ -499,14 +501,14 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */
uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum);
uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */ if (comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */
connections[connection_id].orecv_packetnum = recv_packetnum; connections[connection_id].orecv_packetnum = recv_packetnum;
connections[connection_id].osent_packetnum = sent_packetnum; connections[connection_id].osent_packetnum = sent_packetnum;
connections[connection_id].successful_sent = recv_packetnum; connections[connection_id].successful_sent = recv_packetnum;
connections[connection_id].last_recvSYNC = current_time(); connections[connection_id].last_recvSYNC = current_time();
connections[connection_id].recv_counter = counter; connections[connection_id].recv_counter = counter;
++connections[connection_id].send_counter; ++connections[connection_id].send_counter;
for(i = 0; i < number; ++i) { for (i = 0; i < number; ++i) {
temp = ntohl(req_packets[i]); temp = ntohl(req_packets[i]);
memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); memcpy(connections[connection_id].req_packets + i, &temp, 4 * number);
} }
@ -516,10 +518,10 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
return 1; return 1;
} }
int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source) int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
{ {
if(!SYNC_valid(length)) if (!SYNC_valid(length))
return 1; return 1;
int connection = getconnection_id(source); int connection = getconnection_id(source);
uint8_t counter; uint8_t counter;
@ -533,39 +535,39 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source)
recv_packetnum = ntohl(temp); recv_packetnum = ntohl(temp);
memcpy(&temp,packet + 6, 4); memcpy(&temp,packet + 6, 4);
sent_packetnum = ntohl(temp); sent_packetnum = ntohl(temp);
if(number != 0) if (number != 0)
memcpy(req_packets, packet + 10, 4 * number); memcpy(req_packets, packet + 10, 4 * number);
if(connection == -1) if (connection == -1)
return handle_SYNC1(source, recv_packetnum, sent_packetnum); return handle_SYNC1(source, recv_packetnum, sent_packetnum);
if(connections[connection].status == 2) if (connections[connection].status == 2)
return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum);
if(connections[connection].status == 3) if (connections[connection].status == 3)
return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number);
return 0; return 0;
} }
/* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value. /* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value.
return 1 if data was too big, 0 if not. */ return 1 if data was too big, 0 if not. */
int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
{ {
if(size > MAX_DATA_SIZE) if (size > MAX_DATA_SIZE)
return 1; return 1;
uint32_t i; uint32_t i;
uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
if(i == data_num) { if (i == data_num) {
memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
connections[connection_id].last_recvdata = current_time(); connections[connection_id].last_recvdata = current_time();
if(sent_packet < BUFFER_PACKET_NUM) if (sent_packet < BUFFER_PACKET_NUM)
connections[connection_id].osent_packetnum = data_num; connections[connection_id].osent_packetnum = data_num;
break; break;
} }
} }
for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
connections[connection_id].recv_packetnum = i; connections[connection_id].recv_packetnum = i;
else else
break; break;
@ -574,17 +576,17 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size
return 0; return 0;
} }
int handle_data(uint8_t * packet, uint32_t length, IP_Port source) int handle_data(uint8_t *packet, uint32_t length, IP_Port source)
{ {
int connection = getconnection_id(source); int connection = getconnection_id(source);
if(connection == -1) if (connection == -1)
return 1; return 1;
if(connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */
return 1; return 1;
if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
return 1; return 1;
uint32_t temp; uint32_t temp;
uint32_t number; uint32_t number;
@ -597,9 +599,9 @@ int handle_data(uint8_t * packet, uint32_t length, IP_Port source)
/* END of packet handling functions */ /* END of packet handling functions */
int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
{ {
switch (packet[0]) { switch (packet[0]) { //TODO: check if no break statement is correct???
case 16: case 16:
return handle_handshake(packet, length, source); return handle_handshake(packet, length, source);
@ -622,19 +624,19 @@ void doNew()
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for(i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 1) if (connections[i].status == 1)
if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
connections[i].last_sent = temp_time; connections[i].last_sent = temp_time;
} }
/* kill all timed out connections */ /* kill all timed out connections */
if( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
connections[i].status != 4) connections[i].status != 4)
/* kill_connection(i); */ /* kill_connection(i); */
connections[i].status = 4; connections[i].status = 4;
if(connections[i].status > 0 && connections[i].killat < temp_time) if (connections[i].status > 0 && connections[i].killat < temp_time)
kill_connection(i); kill_connection(i);
} }
} }
@ -643,9 +645,9 @@ void doSYNC()
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for(i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 2 || connections[i].status == 3) if (connections[i].status == 2 || connections[i].status == 3)
if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
send_SYNC(i); send_SYNC(i);
connections[i].last_SYNC = temp_time; connections[i].last_SYNC = temp_time;
} }
@ -657,10 +659,10 @@ void doData()
uint32_t i; uint32_t i;
uint64_t j; uint64_t j;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for(i = 0; i < MAX_CONNECTIONS; ++i) for (i = 0; i < MAX_CONNECTIONS; ++i)
if(connections[i].status == 3 && sendqueue(i) != 0) if (connections[i].status == 3 && sendqueue(i) != 0)
if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) { if ((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) {
for(j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) for (j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate))
send_DATA(i); send_DATA(i);
connections[i].last_sent = temp_time; connections[i].last_sent = temp_time;
} }
@ -675,15 +677,15 @@ void adjustRates()
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for(i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 1 || connections[i].status == 2) if (connections[i].status == 1 || connections[i].status == 2)
connections[i].SYNC_rate = MAX_SYNC_RATE; connections[i].SYNC_rate = MAX_SYNC_RATE;
if(connections[i].status == 3) { if (connections[i].status == 3) {
if(sendqueue(i) != 0) { if (sendqueue(i) != 0) {
connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
connections[i].SYNC_rate = MAX_SYNC_RATE; connections[i].SYNC_rate = MAX_SYNC_RATE;
} }
else if(connections[i].last_recvdata + 1000000UL > temp_time) else if (connections[i].last_recvdata + 1000000UL > temp_time)
connections[i].SYNC_rate = MAX_SYNC_RATE; connections[i].SYNC_rate = MAX_SYNC_RATE;
else else
connections[i].SYNC_rate = SYNC_RATE; connections[i].SYNC_rate = SYNC_RATE;

View File

@ -69,11 +69,11 @@ char id_packet(int connection_id);
/* return 0 if there is no received data in the buffer. /* return 0 if there is no received data in the buffer.
return length of received packet if successful */ return length of received packet if successful */
int read_packet(int connection_id, uint8_t * data); int read_packet(int connection_id, uint8_t *data);
/* return 0 if data could not be put in packet queue /* return 0 if data could not be put in packet queue
return 1 if data was put into the queue */ return 1 if data was put into the queue */
int write_packet(int connection_id, uint8_t * data, uint32_t length); int write_packet(int connection_id, uint8_t *data, uint32_t length);
/* returns the number of packets in the queue waiting to be successfully sent. */ /* returns the number of packets in the queue waiting to be successfully sent. */
uint32_t sendqueue(int connection_id); uint32_t sendqueue(int connection_id);
@ -97,7 +97,7 @@ void doLossless_UDP();
/* if we receive a Lossless_UDP packet we call this function so it can be handled. /* if we receive a Lossless_UDP packet we call this function so it can be handled.
return 0 if packet is handled correctly. return 0 if packet is handled correctly.
return 1 if it didn't handle the packet or if the packet was shit. */ return 1 if it didn't handle the packet or if the packet was shit. */
int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,8 +24,7 @@
#include "Messenger.h" #include "Messenger.h"
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
typedef struct typedef struct {
{
uint8_t client_id[CLIENT_ID_SIZE]; uint8_t client_id[CLIENT_ID_SIZE];
int crypt_connection_id; int crypt_connection_id;
int friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ int friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
@ -37,7 +36,7 @@ typedef struct
uint16_t userstatus_length; uint16_t userstatus_length;
uint8_t userstatus_sent; uint8_t userstatus_sent;
uint16_t info_size; /* length of the info */ uint16_t info_size; /* length of the info */
}Friend; } Friend;
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
@ -57,14 +56,15 @@ static uint32_t numfriends;
/* return the friend id associated to that public key. /* return the friend id associated to that public key.
return -1 if no such friend */ return -1 if no such friend */
int getfriend_id(uint8_t * client_id) int getfriend_id(uint8_t *client_id)
{ {
uint32_t i; uint32_t i;
for(i = 0; i < numfriends; ++i) for (i = 0; i < numfriends; ++i) {
if(friendlist[i].status > 0) if (friendlist[i].status > 0)
if(memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0)
return i; return i;
}
return -1; return -1;
} }
@ -73,12 +73,12 @@ int getfriend_id(uint8_t * client_id)
make sure that client_id is of size CLIENT_ID_SIZE. make sure that client_id is of size CLIENT_ID_SIZE.
return 0 if success return 0 if success
return -1 if failure. */ return -1 if failure. */
int getclient_id(int friend_id, uint8_t * client_id) int getclient_id(int friend_id, uint8_t *client_id)
{ {
if(friend_id >= numfriends || friend_id < 0) if (friend_id >= numfriends || friend_id < 0)
return -1; return -1;
if(friendlist[friend_id].status > 0) { if (friendlist[friend_id].status > 0) {
memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE); memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE);
return 0; return 0;
} }
@ -92,20 +92,18 @@ int getclient_id(int friend_id, uint8_t * client_id)
data is the data and length is the length data is the data and length is the length
returns the friend number if success returns the friend number if success
return -1 if failure. */ return -1 if failure. */
int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length) int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
{ {
if(length == 0 || length >= if (length == 0 || length >=
(MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
return -1; return -1;
if(memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
return -1; return -1;
if(getfriend_id(client_id) != -1) if (getfriend_id(client_id) != -1)
return -1; return -1;
uint32_t i; uint32_t i;
for(i = 0; i <= numfriends; ++i) for (i = 0; i <= numfriends; ++i) {
{ if(friendlist[i].status == 0) {
if(friendlist[i].status == 0)
{
DHT_addfriend(client_id); DHT_addfriend(client_id);
friendlist[i].status = 1; friendlist[i].status = 1;
friendlist[i].crypt_connection_id = -1; friendlist[i].crypt_connection_id = -1;
@ -125,13 +123,11 @@ int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length)
int m_addfriend_norequest(uint8_t * client_id) int m_addfriend_norequest(uint8_t * client_id)
{ {
if(getfriend_id(client_id) != -1) if (getfriend_id(client_id) != -1)
return -1; return -1;
uint32_t i; uint32_t i;
for(i = 0; i <= numfriends; ++i) for (i = 0; i <= numfriends; ++i) {
{ if(friendlist[i].status == 0) {
if(friendlist[i].status == 0)
{
DHT_addfriend(client_id); DHT_addfriend(client_id);
friendlist[i].status = 2; friendlist[i].status = 2;
friendlist[i].crypt_connection_id = -1; friendlist[i].crypt_connection_id = -1;
@ -151,7 +147,7 @@ int m_addfriend_norequest(uint8_t * client_id)
return -1 if failure */ return -1 if failure */
int m_delfriend(int friendnumber) int m_delfriend(int friendnumber)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
DHT_delfriend(friendlist[friendnumber].client_id); DHT_delfriend(friendlist[friendnumber].client_id);
@ -159,9 +155,10 @@ int m_delfriend(int friendnumber)
free(friendlist[friendnumber].userstatus); free(friendlist[friendnumber].userstatus);
memset(&friendlist[friendnumber], 0, sizeof(Friend)); memset(&friendlist[friendnumber], 0, sizeof(Friend));
uint32_t i; uint32_t i;
for(i = numfriends; i != 0; --i) for (i = numfriends; i != 0; --i) {
if(friendlist[i].status != 0) if (friendlist[i].status != 0)
break; break;
}
numfriends = i; numfriends = i;
return 0; return 0;
} }
@ -173,7 +170,7 @@ int m_delfriend(int friendnumber)
return 0 if there is no friend with that number */ return 0 if there is no friend with that number */
int m_friendstatus(int friendnumber) int m_friendstatus(int friendnumber)
{ {
if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
return 0; return 0;
return friendlist[friendnumber].status; return friendlist[friendnumber].status;
} }
@ -181,11 +178,11 @@ int m_friendstatus(int friendnumber)
/* send a text chat message to an online friend /* send a text chat message to an online friend
return 1 if packet was successfully put into the send queue return 1 if packet was successfully put into the send queue
return 0 if it was not */ return 0 if it was not */
int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length) int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
{ {
if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
return 0; return 0;
if(length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
/* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
return 0; return 0;
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
@ -208,7 +205,7 @@ static int m_sendname(int friendnumber, uint8_t * name)
return -1 if failure */ return -1 if failure */
static int setfriendname(int friendnumber, uint8_t * name) static int setfriendname(int friendnumber, uint8_t * name)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH); memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
return 0; return 0;
@ -220,11 +217,11 @@ static int setfriendname(int friendnumber, uint8_t * name)
return -1 if failure */ return -1 if failure */
int setname(uint8_t * name, uint16_t length) int setname(uint8_t * name, uint16_t length)
{ {
if(length > MAX_NAME_LENGTH) if (length > MAX_NAME_LENGTH)
return -1; return -1;
memcpy(self_name, name, length); memcpy(self_name, name, length);
uint32_t i; uint32_t i;
for(i = 0; i < numfriends; ++i) for (i = 0; i < numfriends; ++i)
friendlist[i].name_sent = 0; friendlist[i].name_sent = 0;
return 0; return 0;
} }
@ -236,7 +233,7 @@ int setname(uint8_t * name, uint16_t length)
return -1 if failure */ return -1 if failure */
int getname(int friendnumber, uint8_t * name) int getname(int friendnumber, uint8_t * name)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH); memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH);
return 0; return 0;
@ -244,7 +241,7 @@ int getname(int friendnumber, uint8_t * name)
int m_set_userstatus(uint8_t *status, uint16_t length) int m_set_userstatus(uint8_t *status, uint16_t length)
{ {
if(length > MAX_USERSTATUS_LENGTH) if (length > MAX_USERSTATUS_LENGTH)
return -1; return -1;
uint8_t *newstatus = calloc(length, 1); uint8_t *newstatus = calloc(length, 1);
memcpy(newstatus, status, length); memcpy(newstatus, status, length);
@ -253,7 +250,7 @@ int m_set_userstatus(uint8_t *status, uint16_t length)
self_userstatus_len = length; self_userstatus_len = length;
uint32_t i; uint32_t i;
for(i = 0; i < numfriends; ++i) for (i = 0; i < numfriends; ++i)
friendlist[i].userstatus_sent = 0; friendlist[i].userstatus_sent = 0;
return 0; return 0;
} }
@ -262,7 +259,7 @@ int m_set_userstatus(uint8_t *status, uint16_t length)
guaranteed to be at most MAX_USERSTATUS_LENGTH */ guaranteed to be at most MAX_USERSTATUS_LENGTH */
int m_get_userstatus_size(int friendnumber) int m_get_userstatus_size(int friendnumber)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
return friendlist[friendnumber].userstatus_length; return friendlist[friendnumber].userstatus_length;
} }
@ -271,7 +268,7 @@ int m_get_userstatus_size(int friendnumber)
bytes, use m_get_userstatus_size to find out how much you need to allocate */ bytes, use m_get_userstatus_size to find out how much you need to allocate */
int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen) int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
memset(buf, 0, maxlen); memset(buf, 0, maxlen);
memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1); memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1);
@ -290,7 +287,7 @@ static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length)
static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length) static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length)
{ {
if(friendnumber >= numfriends || friendnumber < 0) if (friendnumber >= numfriends || friendnumber < 0)
return -1; return -1;
uint8_t *newstatus = calloc(length, 1); uint8_t *newstatus = calloc(length, 1);
memcpy(newstatus, status, length); memcpy(newstatus, status, length);
@ -350,35 +347,29 @@ int initMessenger()
return 0; return 0;
} }
//TODO: make this function not suck.
static void doFriends() static void doFriends()
{/* TODO: add incoming connections and some other stuff. */ {/* TODO: add incoming connections and some other stuff. */
uint32_t i; uint32_t i;
int len; int len;
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
for(i = 0; i < numfriends; ++i) for (i = 0; i < numfriends; ++i) {
{ if (friendlist[i].status == 1) {
if(friendlist[i].status == 1)
{
int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
if(fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
of packet loss */
friendlist[i].status = 2; friendlist[i].status = 2;
else else if (fr > 0)
if(fr > 0)
friendlist[i].status = 2; friendlist[i].status = 2;
} }
if(friendlist[i].status == 2 || friendlist[i].status == 3) /* friend is not online */ if (friendlist[i].status == 2 || friendlist[i].status == 3) { /* friend is not online */
{ if (friendlist[i].status == 2) {
if(friendlist[i].status == 2) if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
{
if(friendlist[i].friend_request_id + 10 < unix_time()) /*I know this is hackish but it should work.*/
{
send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
friendlist[i].friend_request_id = unix_time(); friendlist[i].friend_request_id = unix_time();
} }
} }
IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
switch(is_cryptoconnected(friendlist[i].crypt_connection_id)) { switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) {
case 0: case 0:
if (friendip.ip.i > 1) if (friendip.ip.i > 1)
friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
@ -394,24 +385,23 @@ static void doFriends()
break; break;
} }
} }
while(friendlist[i].status == 4) /* friend is online */ while (friendlist[i].status == 4) { /* friend is online */
{ if (friendlist[i].name_sent == 0) {
if(friendlist[i].name_sent == 0) if (m_sendname(i, self_name))
if(m_sendname(i, self_name))
friendlist[i].name_sent = 1; friendlist[i].name_sent = 1;
if(friendlist[i].userstatus_sent == 0)
if(send_userstatus(i, self_userstatus, self_userstatus_len))
friendlist[i].userstatus_sent = 1;
len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
if(len > 0)
{
switch(temp[0]) {
case PACKET_ID_NICKNAME: {
if (len != MAX_NAME_LENGTH + 1) break;
if(friend_namechange_isset)
{
friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
} }
if (friendlist[i].userstatus_sent == 0) {
if (send_userstatus(i, self_userstatus, self_userstatus_len))
friendlist[i].userstatus_sent = 1;
}
len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
if (len > 0) {
switch (temp[0]) {
case PACKET_ID_NICKNAME: {
if (len != MAX_NAME_LENGTH + 1)
break;
if(friend_namechange_isset)
friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH); memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */ friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */
break; break;
@ -419,25 +409,21 @@ static void doFriends()
case PACKET_ID_USERSTATUS: { case PACKET_ID_USERSTATUS: {
uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1); uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH)); memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
if(friend_statuschange_isset) if (friend_statuschange_isset)
{
friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
}
set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
free(status); free(status);
break; break;
} }
case PACKET_ID_MESSAGE: { case PACKET_ID_MESSAGE: {
if(friend_message_isset) if (friend_message_isset)
(*friend_message)(i, temp + 1, len - 1); (*friend_message)(i, temp + 1, len - 1);
break; break;
} }
} }
} }
else else {
{ if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) /* if the connection timed out, kill it */
{
crypto_kill(friendlist[i].crypt_connection_id); crypto_kill(friendlist[i].crypt_connection_id);
friendlist[i].crypt_connection_id = -1; friendlist[i].crypt_connection_id = -1;
friendlist[i].status = 3; friendlist[i].status = 3;
@ -454,11 +440,9 @@ static void doInbound()
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES];
int inconnection = crypto_inbound(public_key, secret_nonce, session_key); int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
if(inconnection != -1) if (inconnection != -1) {
{
int friend_id = getfriend_id(public_key); int friend_id = getfriend_id(public_key);
if(friend_id != -1) if (friend_id != -1) {
{
crypto_kill(friendlist[friend_id].crypt_connection_id); crypto_kill(friendlist[friend_id].crypt_connection_id);
friendlist[friend_id].crypt_connection_id = friendlist[friend_id].crypt_connection_id =
accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
@ -476,8 +460,7 @@ static uint32_t last_LANdiscovery;
/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
static void LANdiscovery() static void LANdiscovery()
{ {
if(last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) if (last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
{
send_LANdiscovery(htons(PORT)); send_LANdiscovery(htons(PORT));
last_LANdiscovery = unix_time(); last_LANdiscovery = unix_time();
} }
@ -490,12 +473,11 @@ void doMessenger()
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while(receivepacket(&ip_port, data, &length) != -1) while (receivepacket(&ip_port, data, &length) != -1) {
{
#ifdef DEBUG #ifdef DEBUG
/* if(rand() % 3 != 1) //simulate packet loss */ /* if(rand() % 3 != 1) //simulate packet loss */
/* { */ /* { */
if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) &&
friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port))
/* if packet is discarded */ /* if packet is discarded */
printf("Received unhandled packet with length: %u\n", length); printf("Received unhandled packet with length: %u\n", length);
@ -527,7 +509,7 @@ uint32_t Messenger_size()
} }
/* save the messenger in data of size Messenger_size() */ /* save the messenger in data of size Messenger_size() */
void Messenger_save(uint8_t * data) void Messenger_save(uint8_t *data)
{ {
save_keys(data); save_keys(data);
data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@ -545,9 +527,9 @@ void Messenger_save(uint8_t * data)
/* load the messenger from data of size length. */ /* load the messenger from data of size length. */
int Messenger_load(uint8_t * data, uint32_t length) int Messenger_load(uint8_t * data, uint32_t length)
{ {
if(length == ~0) if (length == ~0)
return -1; return -1;
if(length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2) if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2)
return -1; return -1;
length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2; length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2;
load_keys(data); load_keys(data);
@ -556,15 +538,15 @@ int Messenger_load(uint8_t * data, uint32_t length)
memcpy(&size, data, sizeof(size)); memcpy(&size, data, sizeof(size));
data += sizeof(size); data += sizeof(size);
if(length < size) if (length < size)
return -1; return -1;
length -= size; length -= size;
if(DHT_load(data, size) == -1) if (DHT_load(data, size) == -1)
return -1; return -1;
data += size; data += size;
memcpy(&size, data, sizeof(size)); memcpy(&size, data, sizeof(size));
data += sizeof(size); data += sizeof(size);
if(length != size || length % sizeof(Friend) != 0) if (length != size || length % sizeof(Friend) != 0)
return -1; return -1;
Friend * temp = malloc(size); Friend * temp = malloc(size);
@ -573,10 +555,8 @@ int Messenger_load(uint8_t * data, uint32_t length)
uint16_t num = size / sizeof(Friend); uint16_t num = size / sizeof(Friend);
uint32_t i; uint32_t i;
for(i = 0; i < num; ++i) for (i = 0; i < num; ++i) {
{ if(temp[i].status != 0) {
if(temp[i].status != 0)
{
int fnum = m_addfriend_norequest(temp[i].client_id); int fnum = m_addfriend_norequest(temp[i].client_id);
setfriendname(fnum, temp[i].name); setfriendname(fnum, temp[i].name);
/* set_friend_userstatus(fnum, temp[i].userstatus, temp[i].userstatus_length); */ /* set_friend_userstatus(fnum, temp[i].userstatus, temp[i].userstatus_length); */

View File

@ -51,23 +51,23 @@ extern "C" {
data is the data and length is the length data is the data and length is the length
returns the friend number if success returns the friend number if success
return -1 if failure. */ return -1 if failure. */
int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length); int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
/* add a friend without sending a friendrequest. /* add a friend without sending a friendrequest.
returns the friend number if success returns the friend number if success
return -1 if failure. */ return -1 if failure. */
int m_addfriend_norequest(uint8_t * client_id); int m_addfriend_norequest(uint8_t *client_id);
/* return the friend id associated to that client id. /* return the friend id associated to that client id.
return -1 if no such friend */ return -1 if no such friend */
int getfriend_id(uint8_t * client_id); int getfriend_id(uint8_t *client_id);
/* copies the public key associated to that friend id into client_id buffer. /* copies the public key associated to that friend id into client_id buffer.
make sure that client_id is of size CLIENT_ID_SIZE. make sure that client_id is of size CLIENT_ID_SIZE.
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
int getclient_id(int friend_id, uint8_t * client_id); int getclient_id(int friend_id, uint8_t *client_id);
/* remove a friend */ /* remove a friend */
int m_delfriend(int friendnumber); int m_delfriend(int friendnumber);
@ -82,20 +82,20 @@ int m_friendstatus(int friendnumber);
/* send a text chat message to an online friend /* send a text chat message to an online friend
returns 1 if packet was successfully put into the send queue returns 1 if packet was successfully put into the send queue
return 0 if it was not */ return 0 if it was not */
int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length); int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
/* Set our nickname /* Set our nickname
name must be a string of maximum MAX_NAME_LENGTH length. name must be a string of maximum MAX_NAME_LENGTH length.
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
int setname(uint8_t * name, uint16_t length); int setname(uint8_t *name, uint16_t length);
/* get name of friendnumber /* get name of friendnumber
put it in name put it in name
name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
int getname(int friendnumber, uint8_t * name); int getname(int friendnumber, uint8_t *name);
/* set our user status /* set our user status
you are responsible for freeing status after you are responsible for freeing status after
@ -109,7 +109,7 @@ int m_get_userstatus_size(int friendnumber);
/* copy friendnumber's userstatus into buf, truncating if size is over maxlen /* copy friendnumber's userstatus into buf, truncating if size is over maxlen
get the size you need to allocate from m_get_userstatus_size */ get the size you need to allocate from m_get_userstatus_size */
int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen); int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen);
/* set the function that will be executed when a friend request is received. /* set the function that will be executed when a friend request is received.
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
@ -143,10 +143,10 @@ void doMessenger();
uint32_t Messenger_size(); uint32_t Messenger_size();
/* save the messenger in data (must be allocated memory of size Messenger_size()) */ /* save the messenger in data (must be allocated memory of size Messenger_size()) */
void Messenger_save(uint8_t * data); void Messenger_save(uint8_t *data);
/* load the messenger from data of size length */ /* load the messenger from data of size length */
int Messenger_load(uint8_t * data, uint32_t length); int Messenger_load(uint8_t *data, uint32_t length);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -35,24 +35,23 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
uint8_t packet[MAX_DATA_SIZE]; uint8_t packet[MAX_DATA_SIZE];
int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */
if(len == -1) if (len == -1)
return -1; return -1;
IP_Port ip_port = DHT_getfriendip(public_key); IP_Port ip_port = DHT_getfriendip(public_key);
if(ip_port.ip.i == 1) if (ip_port.ip.i == 1)
return -1; return -1;
if(ip_port.ip.i != 0) if (ip_port.ip.i != 0) {
{ if (sendpacket(ip_port, packet, len) != -1)
if(sendpacket(ip_port, packet, len) != -1)
return 0; return 0;
return -1; return -1;
} }
int num = route_tofriend(public_key, packet, len); int num = route_tofriend(public_key, packet, len);
if(num == 0) if (num == 0)
return -1; return -1;
return num; return num;
@ -62,8 +61,7 @@ static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t);
static uint8_t handle_friendrequest_isset = 0; static uint8_t handle_friendrequest_isset = 0;
/* set the function that will be executed when a friend request is received. */ /* set the function that will be executed when a friend request is received. */
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) {
{
handle_friendrequest = function; handle_friendrequest = function;
handle_friendrequest_isset = 1; handle_friendrequest_isset = 1;
} }
@ -78,9 +76,8 @@ static uint8_t recieved_requests[MAX_RECIEVED_STORED][crypto_box_PUBLICKEYBYTES]
static uint16_t recieved_requests_index; static uint16_t recieved_requests_index;
/*Add to list of recieved friend requests*/ /*Add to list of recieved friend requests*/
static void addto_recievedlist(uint8_t * client_id) static void addto_recievedlist(uint8_t * client_id) {
{ if (recieved_requests_index >= MAX_RECIEVED_STORED)
if(recieved_requests_index >= MAX_RECIEVED_STORED)
recieved_requests_index = 0; recieved_requests_index = 0;
memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES); memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
@ -89,46 +86,43 @@ static void addto_recievedlist(uint8_t * client_id)
/* Check if a friend request was already recieved /* Check if a friend request was already recieved
return 0 if not, 1 if we did */ return 0 if not, 1 if we did */
static int request_recieved(uint8_t * client_id) static int request_recieved(uint8_t * client_id) {
{
uint32_t i; uint32_t i;
for(i = 0; i < MAX_RECIEVED_STORED; ++i) for (i = 0; i < MAX_RECIEVED_STORED; ++i) {
if(memcmp(recieved_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(recieved_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
return 1; return 1;
}
return 0; return 0;
} }
int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) {
{ if (packet[0] == 32) {
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
if(packet[0] == 32)
{
if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
length > MAX_DATA_SIZE + ENCRYPTION_PADDING) length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
return 1; return 1;
if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) /* check if request is for us. */ if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
{ if (handle_friendrequest_isset == 0)
if(handle_friendrequest_isset == 0)
return 1; return 1;
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE];
int len = handle_request(public_key, data, packet, length); int len = handle_request(public_key, data, packet, length);
if(len == -1) if (len == -1)
return 1; return 1;
if(request_recieved(public_key)) if (request_recieved(public_key))
return 1; return 1;
addto_recievedlist(public_key); addto_recievedlist(public_key);
(*handle_friendrequest)(public_key, data, len); (*handle_friendrequest)(public_key, data, len);
} }
else /* if request is not for us, try routing it. */ else {/* if request is not for us, try routing it. */
if(route_packet(packet + 1, packet, length) == length) if(route_packet(packet + 1, packet, length) == length)
return 0; return 0;
} }
}
return 1; return 1;
} }

View File

@ -33,7 +33,7 @@ extern "C" {
/* Try to send a friendrequest to peer with public_key /* Try to send a friendrequest to peer with public_key
data is the data in the request and length is the length. */ data is the data in the request and length is the length. */
int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length); int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length);
/* set the function that will be executed when a friend request for us is received. /* set the function that will be executed when a friend request for us is received.
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
@ -42,7 +42,7 @@ void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
/* if we receive a packet we call this function so it can be handled. /* if we receive a packet we call this function so it can be handled.
return 0 if packet is handled correctly. return 0 if packet is handled correctly.
return 1 if it didn't handle the packet or if the packet was shit. */ return 1 if it didn't handle the packet or if the packet was shit. */
int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -30,8 +30,7 @@
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
typedef struct typedef struct {
{
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */
uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */
@ -43,7 +42,7 @@ typedef struct
4 if the connection is timed out. */ 4 if the connection is timed out. */
uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
}Crypto_Connection; } Crypto_Connection;
#define MAX_CRYPTO_CONNECTIONS 256 #define MAX_CRYPTO_CONNECTIONS 256
@ -58,10 +57,10 @@ static int incoming_connections[MAX_INCOMING];
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
return -1 if there was a problem. return -1 if there was a problem.
return length of encrypted data if everything was fine. */ return length of encrypted data if everything was fine. */
int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t * plain, uint32_t length, uint8_t * encrypted) uint8_t *plain, uint32_t length, uint8_t *encrypted)
{ {
if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
return -1; return -1;
uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
@ -73,7 +72,7 @@ int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key);
/* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */
if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0)
return -1; return -1;
/* unpad the encrypted message */ /* unpad the encrypted message */
@ -85,10 +84,10 @@ int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
return -1 if there was a problem(decryption failed) return -1 if there was a problem(decryption failed)
return length of plain data if everything was fine. */ return length of plain data if everything was fine. */
int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t * encrypted, uint32_t length, uint8_t * plain) uint8_t *encrypted, uint32_t length, uint8_t *plain)
{ {
if(length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
return -1; return -1;
uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES];
@ -97,12 +96,12 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */
if(crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
nonce, public_key, secret_key) == -1) nonce, public_key, secret_key) == -1)
return -1; return -1;
/* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */
if(memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0) if (memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0)
return -1; return -1;
/* unpad the plain message */ /* unpad the plain message */
@ -111,10 +110,10 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
} }
/* increment the given nonce by 1 */ /* increment the given nonce by 1 */
void increment_nonce(uint8_t * nonce) void increment_nonce(uint8_t *nonce)
{ {
uint32_t i; uint32_t i;
for(i = 0; i < crypto_box_NONCEBYTES; ++i) { for (i = 0; i < crypto_box_NONCEBYTES; ++i) {
++nonce[i]; ++nonce[i];
if(nonce[i] != 0) if(nonce[i] != 0)
break; break;
@ -122,7 +121,7 @@ void increment_nonce(uint8_t * nonce)
} }
/* fill the given nonce with random bytes. */ /* fill the given nonce with random bytes. */
void random_nonce(uint8_t * nonce) void random_nonce(uint8_t *nonce)
{ {
uint32_t i, temp; uint32_t i, temp;
for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) { for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
@ -134,22 +133,22 @@ void random_nonce(uint8_t * nonce)
/* return 0 if there is no received data in the buffer /* return 0 if there is no received data in the buffer
return -1 if the packet was discarded. return -1 if the packet was discarded.
return length of received data if successful */ return length of received data if successful */
int read_cryptpacket(int crypt_connection_id, uint8_t * data) int read_cryptpacket(int crypt_connection_id, uint8_t *data)
{ {
if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 0; return 0;
if(crypto_connections[crypt_connection_id].status != 3) if (crypto_connections[crypt_connection_id].status != 3)
return 0; return 0;
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
if(length == 0) if (length == 0)
return 0; return 0;
if(temp_data[0] != 3) if (temp_data[0] != 3)
return -1; return -1;
int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
crypto_connections[crypt_connection_id].sessionsecret_key, crypto_connections[crypt_connection_id].sessionsecret_key,
crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data);
if(len != -1) { if (len != -1) {
increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
return len; return len;
} }
@ -158,22 +157,22 @@ int read_cryptpacket(int crypt_connection_id, uint8_t * data)
/* return 0 if data could not be put in packet queue /* return 0 if data could not be put in packet queue
return 1 if data was put into the queue */ return 1 if data was put into the queue */
int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length) int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
{ {
if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 0; return 0;
if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
return 0; return 0;
if(crypto_connections[crypt_connection_id].status != 3) if (crypto_connections[crypt_connection_id].status != 3)
return 0; return 0;
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
crypto_connections[crypt_connection_id].sessionsecret_key, crypto_connections[crypt_connection_id].sessionsecret_key,
crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1);
if(len == -1) if (len == -1)
return 0; return 0;
temp_data[0] = 3; temp_data[0] = 3;
if(write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
return 0; return 0;
increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
return 1; return 1;
@ -185,15 +184,15 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length)
request_id is the id of the request (32 = friend request, 254 = ping request) request_id is the id of the request (32 = friend request, 254 = ping request)
returns -1 on failure returns -1 on failure
returns the length of the created packet on success */ returns the length of the created packet on success */
int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id) int create_request(uint8_t *packet, uint8_t *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 + ENCRYPTION_PADDING) if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING)
return -1; return -1;
uint8_t nonce[crypto_box_NONCEBYTES]; uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce); random_nonce(nonce);
int len = encrypt_data(public_key, self_secret_key, nonce, data, length, int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
if(len == -1) if (len == -1)
return -1; return -1;
packet[0] = request_id; packet[0] = request_id;
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
@ -207,10 +206,10 @@ int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint3
in data if a friend or ping request was sent to us and returns the length of the data. 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 packet is the request packet and length is its length
return -1 if not valid request. */ return -1 if not valid request. */
int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length) int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length)
{ {
if(length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
{ {
@ -230,7 +229,7 @@ int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint1
/* Send a crypto handshake packet containing an encrypted secret nonce and session public key /* Send a crypto handshake packet containing an encrypted secret nonce and session public key
to peer with connection_id and 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 */ the packet is encrypted with a random nonce which is sent in plain text with the packet */
int send_cryptohandshake(int connection_id, uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key) int send_cryptohandshake(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_data[MAX_DATA_SIZE];
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
@ -242,7 +241,7 @@ int send_cryptohandshake(int connection_id, uint8_t * public_key, uint8_t * secr
int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
if(len == -1) if (len == -1)
return 0; return 0;
temp_data[0] = 2; temp_data[0] = 2;
memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
@ -253,16 +252,16 @@ int send_cryptohandshake(int connection_id, uint8_t * public_key, uint8_t * secr
/* Extract secret nonce, session public key and public_key from a packet(data) with length length /* Extract secret nonce, session public key and public_key from a packet(data) with length length
return 1 if successful return 1 if successful
return 0 if failure */ return 0 if failure */
int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce, int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
uint8_t * session_key, uint8_t * data, uint16_t length) uint8_t *session_key, uint8_t *data, uint16_t length)
{ {
int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
if(length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
+ crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad)
{ {
return 0; return 0;
} }
if(data[0] != 2) if (data[0] != 2)
return 0; return 0;
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
@ -272,7 +271,7 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce,
data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
if(len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES)
return 0; return 0;
memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
@ -283,33 +282,33 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce,
/* get crypto connection id from public key of peer /* get crypto connection id from public key of peer
return -1 if there are no connections like we are looking for return -1 if there are no connections like we are looking for
return id if it found it */ return id if it found it */
int getcryptconnection_id(uint8_t * public_key) int getcryptconnection_id(uint8_t *public_key)
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if(crypto_connections[i].status > 0) if (crypto_connections[i].status > 0)
if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
return i; return i;
}
return -1; return -1;
} }
/* Start a secure connection with other peer who has public_key and ip_port /* Start a secure connection with other peer who has public_key and ip_port
returns -1 if failure returns -1 if failure
returns crypt_connection_id of the initialized connection if everything went well. */ returns crypt_connection_id of the initialized connection if everything went well. */
int crypto_connect(uint8_t * public_key, IP_Port ip_port) int crypto_connect(uint8_t *public_key, IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
int id = getcryptconnection_id(public_key); int id = getcryptconnection_id(public_key);
if(id != -1) { if (id != -1) {
IP_Port c_ip = connection_ip(crypto_connections[id].number); IP_Port c_ip = connection_ip(crypto_connections[id].number);
if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
return -1; return -1;
} }
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
{ if (crypto_connections[i].status == 0) {
if(crypto_connections[i].status == 0) {
int id = new_connection(ip_port); int id = new_connection(ip_port);
if(id == -1) if (id == -1)
return -1; return -1;
crypto_connections[i].number = id; crypto_connections[i].number = id;
crypto_connections[i].status = 1; crypto_connections[i].status = 1;
@ -317,7 +316,7 @@ int crypto_connect(uint8_t * public_key, IP_Port ip_port)
memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
if(send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce,
crypto_connections[i].sessionpublic_key) == 1) crypto_connections[i].sessionpublic_key) == 1)
{ {
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
@ -336,21 +335,20 @@ int crypto_connect(uint8_t * public_key, IP_Port ip_port)
and the session public key for the connection in session_key and the session public key for the connection in session_key
to accept it see: accept_crypto_inbound(...) to accept it see: accept_crypto_inbound(...)
to refuse it just call kill_connection(...) on the connection id */ to refuse it just call kill_connection(...) on the connection id */
int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key) int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_INCOMING; ++i) for (i = 0; i < MAX_INCOMING; ++i) {
{ if (incoming_connections[i] != -1) {
if(incoming_connections[i] != -1) { if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) {
if(is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) {
kill_connection(incoming_connections[i]); kill_connection(incoming_connections[i]);
incoming_connections[i] = -1; incoming_connections[i] = -1;
continue; continue;
} }
if(id_packet(incoming_connections[i]) == 2) { if (id_packet(incoming_connections[i]) == 2) {
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
uint16_t len = read_packet(incoming_connections[i], temp_data); uint16_t len = read_packet(incoming_connections[i], temp_data);
if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
int connection_id = incoming_connections[i]; int connection_id = incoming_connections[i];
incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */
return connection_id; return connection_id;
@ -366,9 +364,9 @@ int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * sessi
return 1 if there was a problem. */ return 1 if there was a problem. */
int crypto_kill(int crypt_connection_id) int crypto_kill(int crypt_connection_id)
{ {
if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 1; return 1;
if(crypto_connections[crypt_connection_id].status != 0) { if (crypto_connections[crypt_connection_id].status != 0) {
crypto_connections[crypt_connection_id].status = 0; crypto_connections[crypt_connection_id].status = 0;
kill_connection(crypto_connections[crypt_connection_id].number); kill_connection(crypto_connections[crypt_connection_id].number);
crypto_connections[crypt_connection_id].number = ~0; crypto_connections[crypt_connection_id].number = ~0;
@ -380,18 +378,17 @@ int crypto_kill(int crypt_connection_id)
/* accept an incoming connection using the parameters provided by crypto_inbound /* accept an incoming connection using the parameters provided by crypto_inbound
return -1 if not successful return -1 if not successful
returns the crypt_connection_id if successful */ returns the crypt_connection_id if successful */
int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key) int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
{ {
uint32_t i; uint32_t i;
if(connection_id == -1) if (connection_id == -1)
return -1; return -1;
/* /*
if(getcryptconnection_id(public_key) != -1) if(getcryptconnection_id(public_key) != -1)
{ {
return -1; return -1;
}*/ }*/
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
{
if(crypto_connections[i].status == 0) { if(crypto_connections[i].status == 0) {
crypto_connections[i].number = connection_id; crypto_connections[i].number = connection_id;
crypto_connections[i].status = 2; crypto_connections[i].status = 2;
@ -403,7 +400,7 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
if(send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce,
crypto_connections[i].sessionpublic_key) == 1) crypto_connections[i].sessionpublic_key) == 1)
{ {
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
@ -424,7 +421,7 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
4 if the connection is timed out and waiting to be killed */ 4 if the connection is timed out and waiting to be killed */
int is_cryptoconnected(int crypt_connection_id) int is_cryptoconnected(int crypt_connection_id)
{ {
if(crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
return crypto_connections[crypt_connection_id].status; return crypto_connections[crypt_connection_id].status;
return 0; return 0;
} }
@ -438,7 +435,7 @@ void new_keys()
/* save the public and private keys to the keys array /* save the public and private keys to the keys array
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
void save_keys(uint8_t * keys) void save_keys(uint8_t *keys)
{ {
memcpy(keys, self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(keys, self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(keys + crypto_box_PUBLICKEYBYTES, self_secret_key, crypto_box_SECRETKEYBYTES); memcpy(keys + crypto_box_PUBLICKEYBYTES, self_secret_key, crypto_box_SECRETKEYBYTES);
@ -446,7 +443,7 @@ void save_keys(uint8_t * keys)
/* load the public and private keys from the keys array /* load the public and private keys from the keys array
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
void load_keys(uint8_t * keys) void load_keys(uint8_t *keys)
{ {
memcpy(self_public_key, keys, crypto_box_PUBLICKEYBYTES); memcpy(self_public_key, keys, crypto_box_PUBLICKEYBYTES);
memcpy(self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); memcpy(self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
@ -459,8 +456,8 @@ void load_keys(uint8_t * keys)
int new_incoming(int id) int new_incoming(int id)
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_INCOMING; ++i) { for (i = 0; i < MAX_INCOMING; ++i) {
if(incoming_connections[i] == -1) { if (incoming_connections[i] == -1) {
incoming_connections[i] = id; incoming_connections[i] = id;
return 0; return 0;
} }
@ -473,7 +470,7 @@ int new_incoming(int id)
static void handle_incomings() static void handle_incomings()
{ {
int income; int income;
while(1) { while (1) {
income = incoming_connection(); income = incoming_connection();
if(income == -1 || new_incoming(income) ) if(income == -1 || new_incoming(income) )
break; break;
@ -484,22 +481,20 @@ static void handle_incomings()
static void receive_crypto() static void receive_crypto()
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
{ if (crypto_connections[i].status == 1) {
if(crypto_connections[i].status == 1)
{
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES];
uint16_t len; uint16_t len;
if(id_packet(crypto_connections[i].number) == 1) if (id_packet(crypto_connections[i].number) == 1)
/* if the packet is a friend request drop it (because we are already friends) */ /* if the packet is a friend request drop it (because we are already friends) */
len = read_packet(crypto_connections[i].number, temp_data); len = read_packet(crypto_connections[i].number, temp_data);
if(id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
len = read_packet(crypto_connections[i].number, temp_data); len = read_packet(crypto_connections[i].number, temp_data);
if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
increment_nonce(crypto_connections[i].sent_nonce); increment_nonce(crypto_connections[i].sent_nonce);
@ -510,15 +505,12 @@ static void receive_crypto()
} }
} }
} }
else if(id_packet(crypto_connections[i].number) != -1) else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
/* This should not happen
kill the connection if it does */
crypto_kill(crypto_connections[i].number); crypto_kill(crypto_connections[i].number);
} }
if(crypto_connections[i].status == 2) if (crypto_connections[i].status == 2) {
{ if (id_packet(crypto_connections[i].number) == 3) {
if(id_packet(crypto_connections[i].number) == 3) {
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
uint8_t data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE];
int length = read_packet(crypto_connections[i].number, temp_data); int length = read_packet(crypto_connections[i].number, temp_data);
@ -526,7 +518,7 @@ static void receive_crypto()
crypto_connections[i].sessionsecret_key, crypto_connections[i].sessionsecret_key,
crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
uint32_t zero = 0; uint32_t zero = 0;
if(len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
crypto_connections[i].status = 3; crypto_connections[i].status = 3;
@ -534,9 +526,7 @@ static void receive_crypto()
kill_connection_in(crypto_connections[i].number, 3000000); kill_connection_in(crypto_connections[i].number, 3000000);
} }
else else
/* This should not happen crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does
kill the connection if it does */
crypto_kill(crypto_connections[i].number);
} }
else if(id_packet(crypto_connections[i].number) != -1) else if(id_packet(crypto_connections[i].number) != -1)
/* This should not happen /* This should not happen
@ -553,17 +543,17 @@ void initNetCrypto()
memset(crypto_connections, 0 ,sizeof(crypto_connections)); memset(crypto_connections, 0 ,sizeof(crypto_connections));
memset(incoming_connections, -1 ,sizeof(incoming_connections)); memset(incoming_connections, -1 ,sizeof(incoming_connections));
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
crypto_connections[i].number = ~0; crypto_connections[i].number = ~0;
} }
static void killTimedout() static void killTimedout()
{ {
uint32_t i; uint32_t i;
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if(crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4) if (crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4)
crypto_connections[i].status = 4; crypto_connections[i].status = 4;
else if(is_connected(crypto_connections[i].number) == 4) { else if (is_connected(crypto_connections[i].number) == 4) {
kill_connection(crypto_connections[i].number); kill_connection(crypto_connections[i].number);
crypto_connections[i].number = ~0; crypto_connections[i].number = ~0;
} }

View File

@ -40,29 +40,29 @@ extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
return -1 if there was a problem. return -1 if there was a problem.
return length of encrypted data if everything was fine. */ return length of encrypted data if everything was fine. */
int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t * plain, uint32_t length, uint8_t * encrypted); uint8_t *plain, uint32_t length, uint8_t *encrypted);
/* decrypts encrypted of length length to plain of length length - 16 using the /* decrypts encrypted of length length to plain of length length - 16 using the
public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
return -1 if there was a problem(decryption failed) return -1 if there was a problem(decryption failed)
return length of plain data if everything was fine. */ return length of plain data if everything was fine. */
int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t * encrypted, uint32_t length, uint8_t * plain); uint8_t *encrypted, uint32_t length, uint8_t *plain);
/* fill the given nonce with random bytes. */ /* fill the given nonce with random bytes. */
void random_nonce(uint8_t * nonce); void random_nonce(uint8_t *nonce);
/* return 0 if there is no received data in the buffer /* return 0 if there is no received data in the buffer
return -1 if the packet was discarded. return -1 if the packet was discarded.
return length of received data if successful */ return length of received data if successful */
int read_cryptpacket(int crypt_connection_id, uint8_t * data); int read_cryptpacket(int crypt_connection_id, uint8_t *data);
/* return 0 if data could not be put in packet queue /* return 0 if data could not be put in packet queue
return 1 if data was put into the queue */ return 1 if data was put into the queue */
int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
/* create a request to peer with public_key. /* create a request to peer with public_key.
packet must be an array of MAX_DATA_SIZE big. packet must be an array of MAX_DATA_SIZE big.
@ -70,18 +70,18 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length);
request_id is the id of the request (32 = friend request, 254 = ping request) request_id is the id of the request (32 = friend request, 254 = ping request)
returns -1 on failure returns -1 on failure
returns the length of the created packet on success */ returns the length of the created packet on success */
int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id); int create_request(uint8_t *packet, uint8_t * 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 /* 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. 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 packet is the request packet and length is its length
return -1 if not valid request. */ return -1 if not valid request. */
int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length); int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length);
/* Start a secure connection with other peer who has public_key and ip_port /* Start a secure connection with other peer who has public_key and ip_port
returns -1 if failure returns -1 if failure
returns crypt_connection_id of the initialized connection if everything went well. */ returns crypt_connection_id of the initialized connection if everything went well. */
int crypto_connect(uint8_t * public_key, IP_Port ip_port); int crypto_connect(uint8_t *public_key, IP_Port ip_port);
/* kill a crypto connection /* kill a crypto connection
return 0 if killed successfully return 0 if killed successfully
@ -95,12 +95,12 @@ int crypto_kill(int crypt_connection_id);
and the session public key for the connection in session_key and the session public key for the connection in session_key
to accept it see: accept_crypto_inbound(...) to accept it see: accept_crypto_inbound(...)
to refuse it just call kill_connection(...) on the connection id */ to refuse it just call kill_connection(...) on the connection id */
int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key); int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
/* accept an incoming connection using the parameters provided by crypto_inbound /* accept an incoming connection using the parameters provided by crypto_inbound
return -1 if not successful return -1 if not successful
returns the crypt_connection_id if successful */ returns the crypt_connection_id if successful */
int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key); int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
(we have received a handshake but no empty data packet), 3 if the connection is established. (we have received a handshake but no empty data packet), 3 if the connection is established.

View File

@ -79,13 +79,10 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
#else #else
uint32_t addrlen = sizeof(addr); uint32_t addrlen = sizeof(addr);
#endif #endif
(*(int32_t *)length) = recvfrom(sock,(char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
if(*(int32_t *)length <= 0) if (*(int32_t*)length <= 0)
{ return -1; /* nothing received or empty packet */
/* nothing received
or empty packet */
return -1;
}
ip_port->ip = addr.ip; ip_port->ip = addr.ip;
ip_port->port = addr.port; ip_port->port = addr.port;
return 0; return 0;
@ -101,7 +98,7 @@ int init_networking(IP ip, uint16_t port)
{ {
#ifdef WIN32 #ifdef WIN32
WSADATA wsaData; WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
return -1; return -1;
#else #else
srandom((uint32_t)current_time()); srandom((uint32_t)current_time());

View File

@ -69,23 +69,20 @@ extern "C" {
#define MAX_UDP_PACKET_SIZE 65507 #define MAX_UDP_PACKET_SIZE 65507
typedef union typedef union {
{
uint8_t c[4]; uint8_t c[4];
uint16_t s[2]; uint16_t s[2];
uint32_t i; uint32_t i;
}IP; } IP;
typedef struct typedef struct {
{
IP ip; IP ip;
uint16_t port; uint16_t port;
/* not used for anything right now */ /* not used for anything right now */
uint16_t padding; uint16_t padding;
}IP_Port; } IP_Port;
typedef struct typedef struct {
{
int16_t family; int16_t family;
uint16_t port; uint16_t port;
IP ip; IP ip;
@ -93,7 +90,7 @@ typedef struct
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
uint8_t zeroes2[12]; uint8_t zeroes2[12];
#endif #endif
}ADDR; } ADDR;
/* returns current time in milleseconds since the epoch. */ /* returns current time in milleseconds since the epoch. */
uint64_t current_time(); uint64_t current_time();
@ -105,12 +102,12 @@ uint32_t random_int();
/* Basic network functions: */ /* Basic network functions: */
/* Function to send packet(data) of length length to ip_port */ /* Function to send packet(data) of length length to ip_port */
int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length); int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length);
/* Function to receive data, ip and port of sender is put into ip_port /* Function to receive data, ip and port of sender is put into ip_port
the packet data into data the packet data into data
the packet length into length. */ the packet length into length. */
int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length); int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length);
/* initialize networking /* initialize networking
bind to ip and port bind to ip and port
@ -118,7 +115,7 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length);
port is in host byte order (this means don't worry about it) port is in host byte order (this means don't worry about it)
returns 0 if no problems returns 0 if no problems
returns -1 if there were problems */ returns -1 if there were problems */
int init_networking(IP ip ,uint16_t port); int init_networking(IP ip, uint16_t port);
/* function to cleanup networking stuff(doesn't do much right now) */ /* function to cleanup networking stuff(doesn't do much right now) */
void shutdown_networking(); void shutdown_networking();

View File

@ -96,79 +96,73 @@ int main(int argc, char *argv[])
uint8_t buffer2[128]; uint8_t buffer2[128];
int read2 = 0; int read2 = 0;
FILE *file1 = fopen(argv[4], "rb"); FILE *file1 = fopen(argv[4], "rb");
if ( file1==NULL ){printf("Error opening file.\n");return 1;} if (file1 == NULL) {
printf("Error opening file.\n");
return 1;
}
FILE *file2 = fopen("received.txt", "wb"); FILE *file2 = fopen("received.txt", "wb");
if ( file2==NULL ){return 1;} if (file2 == NULL)
return 1;
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
while(1) { while (1) {
while (receivepacket(&ip_port, data, &length) != -1) {
while(receivepacket(&ip_port, data, &length) != -1) { if (rand() % 3 != 1) { /* simulate packet loss */
if(rand() % 3 != 1) { /* simulate packet loss */ if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port))
if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) { printf("Received unhandled packet with length: %u\n", length); /* if packet is not recognized */
/* if packet is not recognized */ else
printf("Received unhandled packet with length: %u\n", length);
} else {
printf("Received handled packet with length: %u\n", length); printf("Received handled packet with length: %u\n", length);
} }
} }
}
friend_ip = DHT_getfriendip((uint8_t *)argv[3]); friend_ip = DHT_getfriendip((uint8_t *)argv[3]);
if(friend_ip.ip.i != 0) { if (friend_ip.ip.i != 0) {
if(connection == -1) { if (connection == -1) {
printf("Started connecting to friend:"); printf("Started connecting to friend:");
printip(friend_ip); printip(friend_ip);
connection = new_connection(friend_ip); connection = new_connection(friend_ip);
} }
} }
if(inconnection == -1) { if (inconnection == -1) {
inconnection = incoming_connection(); inconnection = incoming_connection();
if(inconnection != -1) { if (inconnection != -1) {
printf("Someone connected to us:"); printf("Someone connected to us:");
printip(connection_ip(inconnection)); printip(connection_ip(inconnection));
} }
} }
/* if someone connected to us write what he sends to a file */ /* if someone connected to us write what he sends to a file */
/* also send him our file. */ /* also send him our file. */
if(inconnection != -1) { if (inconnection != -1) {
if(write_packet(inconnection, buffer1, read1)) { if (write_packet(inconnection, buffer1, read1)) {
printf("Wrote data.\n"); printf("Wrote data.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_packet(inconnection, buffer2); read2 = read_packet(inconnection, buffer2);
if(read2 != 0) { if (read2 != 0) {
printf("Received data.\n"); printf("Received data.\n");
if(!fwrite(buffer2, read2, 1, file2)) { if (!fwrite(buffer2, read2, 1, file2))
printf("file write error\n"); printf("file write error\n");
} if (read2 < 128) {
if(read2 < 128) {
fclose(file2); fclose(file2);
} }
} }
} }
/* if we are connected to a friend send him data from the file. /* if we are connected to a friend send him data from the file.
* also put what he sends us in a file. */ * also put what he sends us in a file. */
if(is_connected(connection) == 3) if (is_connected(connection) == 3) {
{ if (write_packet(0, buffer1, read1)) {
if(write_packet(0, buffer1, read1))
{
printf("Wrote data.\n"); printf("Wrote data.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_packet(0, buffer2); read2 = read_packet(0, buffer2);
if(read2 != 0) if (read2 != 0) {
{
printf("Received data.\n"); printf("Received data.\n");
if(!fwrite(buffer2, read2, 1, file2)) if(!fwrite(buffer2, read2, 1, file2))
{
printf("file write error\n"); printf("file write error\n");
}
if(read2 < 128) if(read2 < 128)
{
fclose(file2); fclose(file2);
} }
} }
}
doDHT(); doDHT();
doLossless_UDP(); doLossless_UDP();
/* print_clientlist(); /* print_clientlist();

View File

@ -44,13 +44,13 @@
#define PORT 33446 #define PORT 33446
void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n"); printf("--------------------BEGIN-----------------------------\n");
for(i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if(data[i] < 16) if (data[i] < 16)
printf("0"); printf("0");
printf("%hhX",data[i]); printf("%hhX",data[i]);
} }
@ -59,7 +59,7 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
void printip(IP_Port ip_port) void printip(IP_Port ip_port)
{ {
printf("\nIP: %u.%u.%u.%u Port: %u",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("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3], ntohs(ip_port.port));
} }
/* /*
void printpackets(Data test) void printpackets(Data test)
@ -123,16 +123,15 @@ void Lossless_UDP()
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while(receivepacket(&ip_port, data, &length) != -1) { while (receivepacket(&ip_port, data, &length) != -1) {
printf("packet with length: %u\n", length); printf("packet with length: %u\n", length);
/* if(rand() % 3 != 1)//add packet loss /* if(rand() % 3 != 1)//add packet loss
{ */ { */
if(LosslessUDP_handlepacket(data, length, ip_port)) { if (LosslessUDP_handlepacket(data, length, ip_port))
printpacket(data, length, ip_port); printpacket(data, length, ip_port);
} else { else
//printconnection(0); printf("Received handled packet with length: %u\n", length); //printconnection(0);
printf("Received handled packet with length: %u\n", length);
}
/* } */ /* } */
} }
@ -151,7 +150,8 @@ int main(int argc, char *argv[])
int read; int read;
FILE *file = fopen(argv[3], "rb"); FILE *file = fopen(argv[3], "rb");
if ( file==NULL ){return 1;} if (file == NULL)
return 1;
/* initialize networking */ /* initialize networking */
@ -166,14 +166,14 @@ int main(int argc, char *argv[])
printip(serverip); printip(serverip);
int connection = new_connection(serverip); int connection = new_connection(serverip);
uint64_t timer = current_time(); uint64_t timer = current_time();
while(1) { while (1) {
/* printconnection(connection); */ /* printconnection(connection); */
Lossless_UDP(); Lossless_UDP();
if(is_connected(connection) == 3) { if (is_connected(connection) == 3) {
printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
break; break;
} }
if(is_connected(connection) == 0) { if (is_connected(connection) == 0) {
printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
return 1; return 1;
} }
@ -185,19 +185,19 @@ int main(int argc, char *argv[])
/*read first part of file */ /*read first part of file */
read = fread(buffer, 1, 512, file); read = fread(buffer, 1, 512, file);
while(1) { while (1) {
/* printconnection(connection); */ /* printconnection(connection); */
Lossless_UDP(); Lossless_UDP();
if(is_connected(connection) == 3) { if (is_connected(connection) == 3) {
if(write_packet(connection, buffer, read)) { if (write_packet(connection, buffer, read)) {
/* printf("Wrote data.\n"); */ /* printf("Wrote data.\n"); */
read = fread(buffer, 1, 512, file); read = fread(buffer, 1, 512, file);
} }
/* printf("%u\n", sendqueue(connection)); */ /* printf("%u\n", sendqueue(connection)); */
if(sendqueue(connection) == 0) { if (sendqueue(connection) == 0) {
if(read == 0) { if (read == 0) {
printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer));
break; break;
} }

View File

@ -45,12 +45,12 @@
#define PORT 33445 #define PORT 33445
void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n"); printf("--------------------BEGIN-----------------------------\n");
for(i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if(data[i] < 16) if(data[i] < 16)
printf("0"); printf("0");
printf("%hhX",data[i]); printf("%hhX",data[i]);
@ -120,10 +120,10 @@ void Lossless_UDP()
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while(receivepacket(&ip_port, data, &length) != -1) { while (receivepacket(&ip_port, data, &length) != -1) {
//if(rand() % 3 != 1)//add packet loss //if(rand() % 3 != 1)//add packet loss
//{ //{
if(LosslessUDP_handlepacket(data, length, ip_port)) { if (LosslessUDP_handlepacket(data, length, ip_port)) {
printpacket(data, length, ip_port); printpacket(data, length, ip_port);
} else { } else {
//printconnection(0); //printconnection(0);
@ -147,7 +147,8 @@ int main(int argc, char *argv[])
int read; int read;
FILE *file = fopen(argv[1], "wb"); FILE *file = fopen(argv[1], "wb");
if ( file==NULL ){return 1;} if (file == NULL)
return 1;
//initialize networking //initialize networking
@ -161,7 +162,7 @@ int main(int argc, char *argv[])
uint64_t timer = current_time(); uint64_t timer = current_time();
while(1) { while (1) {
Lossless_UDP(); Lossless_UDP();
connection = incoming_connection(); connection = incoming_connection();
if(connection != -1) { if(connection != -1) {
@ -176,19 +177,18 @@ int main(int argc, char *argv[])
timer = current_time(); timer = current_time();
while(1) { while (1) {
//printconnection(0); //printconnection(0);
Lossless_UDP(); Lossless_UDP();
if(is_connected(connection) >= 2) { if (is_connected(connection) >= 2) {
kill_connection_in(connection, 3000000); kill_connection_in(connection, 3000000);
read = read_packet(connection, buffer); read = read_packet(connection, buffer);
if(read != 0) { if (read != 0) {
// printf("Recieved data.\n"); // printf("Recieved data.\n");
if(!fwrite(buffer, read, 1, file)) { if (!fwrite(buffer, read, 1, file))
printf("file write error\n"); printf("file write error\n");
} }
} }
}
if(is_connected(connection) == 4) { if(is_connected(connection) == 4) {
printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
fclose(file); fclose(file);

View File

@ -39,9 +39,9 @@ int nick_before;
void new_lines(char *line) void new_lines(char *line)
{ {
int i; int i;
for (i = HISTORY-1; i > 0; i--) { for (i = HISTORY-1; i > 0; i--)
strcpy(lines[i],lines[i-1]); strcpy(lines[i],lines[i-1]);
}
strcpy(lines[0],line); strcpy(lines[0],line);
do_refresh(); do_refresh();
} }
@ -53,8 +53,7 @@ unsigned char * hex_string_to_bin(char hex_string[])
unsigned char * val = malloc(len); unsigned char * val = malloc(len);
char * pos = hex_string; char * pos = hex_string;
int i=0; int i=0;
while(i < len) while(i < len) {
{
sscanf(pos,"%2hhx",&val[i]); sscanf(pos,"%2hhx",&val[i]);
pos+=2; pos+=2;
i++; i++;
@ -71,17 +70,18 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
if (line[1] == 'f') { // add friend command: /f ID if (line[1] == 'f') { // add friend command: /f ID
int i; int i;
char temp_id[128]; char temp_id[128];
for (i=0; i<128; i++) { for (i=0; i<128; i++)
temp_id[i] = line[i+3]; temp_id[i] = line[i+3];
}
int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] added friend %d", num); sprintf(numstring, "[i] added friend %d", num);
new_lines(numstring); new_lines(numstring);
do_refresh(); do_refresh();
} else if (line[1] == 'd') { }
else if (line[1] == 'd') {
doMessenger(); doMessenger();
} else if (line[1] == 'm') { //message command: /m friendnumber messsage }
else if (line[1] == 'm') { //message command: /m friendnumber messsage
int i; int i;
size_t len = strlen(line); size_t len = strlen(line);
char numstring[len-3]; char numstring[len-3];
@ -91,15 +91,15 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
numstring[i] = line[i+3]; numstring[i] = line[i+3];
} else { } else {
int j; int j;
for (j=i+1; j<len; j++) { for (j=i+1; j<len; j++)
message[j-i-1] = line[j+3]; message[j-i-1] = line[j+3];
}
break; break;
} }
} }
int num = atoi(numstring); int num = atoi(numstring);
m_sendmessage(num, (uint8_t*) message, sizeof(message)); m_sendmessage(num, (uint8_t*) message, sizeof(message));
} else if (line[1] == 'n') { }
else if (line[1] == 'n') {
uint8_t name[MAX_NAME_LENGTH]; uint8_t name[MAX_NAME_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
@ -112,7 +112,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] changed nick to %s", (char*)name); sprintf(numstring, "[i] changed nick to %s", (char*)name);
new_lines(numstring); new_lines(numstring);
} else if (line[1] == 's') { }
else if (line[1] == 's') {
uint8_t status[MAX_USERSTATUS_LENGTH]; uint8_t status[MAX_USERSTATUS_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
@ -125,7 +126,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] changed status to %s", (char*)status); sprintf(numstring, "[i] changed status to %s", (char*)status);
new_lines(numstring); new_lines(numstring);
} else if (line[1] == 'q') { //exit }
else if (line[1] == 'q') { //exit
endwin(); endwin();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -139,7 +141,7 @@ void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
int i = 0; int i = 0;
strcpy(output,input); strcpy(output,input);
size_t len = strlen(output); size_t len = strlen(output);
for (i=line_width; i < len; i = i + line_width) { for (i = line_width; i < len; i = i + line_width) {
while (output[i] != ' ' && i != 0) { while (output[i] != ' ' && i != 0) {
i--; i--;
} }
@ -155,10 +157,9 @@ int count_lines(char *string)
int i; int i;
int count = 1; int count = 1;
for (i=0; i < len; i++) { for (i=0; i < len; i++) {
if (string[i] == '\n') { if (string[i] == '\n')
count++; count++;
} }
}
return count; return count;
} }
@ -196,11 +197,11 @@ void do_refresh()
refresh(); refresh();
} }
void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
{ {
new_lines("[i] received friend request"); new_lines("[i] received friend request");
do_refresh(); do_refresh();
if(memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0 ) if (memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0)
//if the request contained the message of peace the person is obviously a friend so we add him. //if the request contained the message of peace the person is obviously a friend so we add him.
{ {
new_lines("[i] friend request accepted"); new_lines("[i] friend request accepted");
@ -298,15 +299,14 @@ int main(int argc, char *argv[])
uint32_t i; uint32_t i;
for(i = 0; i < 32; i++) for(i = 0; i < 32; i++)
{ {
if(self_public_key[i] < 16) { if(self_public_key[i] < 16)
strcpy(idstring1[i],"0"); strcpy(idstring1[i],"0");
} else { else
strcpy(idstring1[i], ""); strcpy(idstring1[i], "");
}
sprintf(idstring2[i], "%hhX",self_public_key[i]); sprintf(idstring2[i], "%hhX",self_public_key[i]);
} }
strcpy(idstring0,"[i] your ID: "); strcpy(idstring0,"[i] your ID: ");
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
strcat(idstring0,idstring1[i]); strcat(idstring0,idstring1[i]);
strcat(idstring0,idstring2[i]); strcat(idstring0,idstring2[i]);
} }
@ -320,11 +320,11 @@ int main(int argc, char *argv[])
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]); int resolved_address = resolve_addr(argv[1]);
if (resolved_address != -1) { if (resolved_address != -1)
bootstrap_ip_port.ip.i = resolved_address; bootstrap_ip_port.ip.i = resolved_address;
} else { else
exit(1); exit(1);
}
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
nodelay(stdscr, TRUE); nodelay(stdscr, TRUE);
while(true) { while(true) {