Basic IM messenger backend pretty much done (You can start the GUI)

And a couple of fixes to the other parts.
This commit is contained in:
irungentoo 2013-07-09 13:20:48 -04:00
parent db37eca44b
commit 4d50638528
5 changed files with 136 additions and 20 deletions

View File

@ -37,7 +37,7 @@
#define BUFFER_PACKET_NUM (16-1) #define BUFFER_PACKET_NUM (16-1)
//Lossless UDP connection timeout. //Lossless UDP connection timeout.
#define CONNEXION_TIMEOUT 10 #define CONNEXION_TIMEOUT 5
//initial amount of sync/hanshake packets to send per second. //initial amount of sync/hanshake packets to send per second.
#define SYNC_RATE 10 #define SYNC_RATE 10
@ -133,7 +133,13 @@ uint32_t handshake_id(IP_Port source)
} }
return id; return id;
} }
//change the hnshake id associated with that ip_port
//TODO: make this better
void change_handshake(IP_Port source)
{
uint8_t rand = random_int() % 4;
randtable[rand][((uint8_t *)&source)[rand]] = random_int();
}
//initialize a new connection to ip_port //initialize a new connection to ip_port
@ -152,6 +158,7 @@ int new_connection(IP_Port ip_port)
{ {
if(connections[i].status == 0) if(connections[i].status == 0)
{ {
memset(&connections[i], 0, sizeof(Connection));
connections[i].ip_port = ip_port; connections[i].ip_port = ip_port;
connections[i].status = 1; connections[i].status = 1;
connections[i].inbound = 0; connections[i].inbound = 0;
@ -184,6 +191,7 @@ int new_inconnection(IP_Port ip_port)
{ {
if(connections[i].status == 0) if(connections[i].status == 0)
{ {
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;
connections[i].inbound = 2; connections[i].inbound = 2;
@ -223,6 +231,7 @@ int kill_connection(int connection_id)
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);
return 0; return 0;
} }
} }

View File

@ -45,6 +45,17 @@ int m_addfriend(uint8_t * client_id)
return numfriends - 1; return numfriends - 1;
} }
int m_addfriend_norequest(uint8_t * client_id)
{
DHT_addfriend(client_id);
friendlist[numfriends].status = 2;
friendlist[numfriends].friend_request_id = -1;
memcpy(friendlist[numfriends].client_id, client_id, CLIENT_ID_SIZE);
numfriends++;
return numfriends - 1;
}
//remove a friend //remove a friend
int m_delfriend(int friendnumber) int m_delfriend(int friendnumber)
{/* {/*
@ -74,7 +85,11 @@ int m_friendstatus(int friendnumber)
//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(length >= MAX_DATA_SIZE) if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
{
return 0;
}
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;
@ -103,7 +118,7 @@ int m_setinfo(uint8_t * data, uint16_t length)
void (*friend_request)(uint8_t *, uint8_t *, uint16_t); void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
//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.
int m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
{ {
friend_request = function; friend_request = function;
} }
@ -112,7 +127,7 @@ int m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
void (*friend_message)(int, uint8_t *, uint16_t); void (*friend_message)(int, uint8_t *, uint16_t);
//set the function that will be executed when a message from a friend is received. //set the function that will be executed when a message from a friend is received.
int m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
{ {
friend_message = function; friend_message = function;
} }
@ -146,14 +161,13 @@ void doFriends()
if(friendip.ip.i > 1 && request == -1) if(friendip.ip.i > 1 && request == -1)
{ {
friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, friendip, info, info_size); friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, friendip, info, info_size);
}
if(request == 1)
{
friendlist[i].status = 2; friendlist[i].status = 2;
} }
} }
if(friendlist[i].status == 2 || friendlist[i].status == 3) if(friendlist[i].status == 2 || friendlist[i].status == 3)
{ {
check_friendrequest(friendlist[i].friend_request_id);//for now this is used to kill the friend request
IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 0 && friendip.ip.i > 1) if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 0 && friendip.ip.i > 1)
{ {
@ -163,6 +177,10 @@ void doFriends()
{ {
friendlist[i].status = 4; friendlist[i].status = 4;
} }
if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 4)
{
crypto_kill(friendlist[i].crypt_connection_id);
}
} }
while(friendlist[i].status == 4) while(friendlist[i].status == 4)
{ {
@ -200,6 +218,45 @@ void doFriendRequest()
} }
} }
//return the friend id associated to that public key.
//return -1 if no such friend
int getfriend_id(uint8_t * public_key)
{
uint32_t i;
for(i = 0; i < numfriends; i++)
{
if(friendlist[i].status > 0)
{
if(memcmp(public_key, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0)
{
return i;
}
}
}
return -1;
}
void doInbound()
{
uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
if(inconnection != -1)
{
int friend_id = getfriend_id(public_key);
if(friend_id != -1)
{
friendlist[friend_id].crypt_connection_id =
accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
friendlist[friend_id].status = 3;
}
}
}
//the main loop that needs to be run at least 200 times per second. //the main loop that needs to be run at least 200 times per second.
void doMessenger() void doMessenger()
{ {
@ -224,6 +281,7 @@ void doMessenger()
doDHT(); doDHT();
doLossless_UDP(); doLossless_UDP();
doNetCrypto(); doNetCrypto();
doInbound();
doFriendRequest(); doFriendRequest();
doFriends(); doFriends();
} }

View File

@ -18,6 +18,12 @@
int m_addfriend(uint8_t * client_id); int m_addfriend(uint8_t * client_id);
//add a friend without sending a friendrequest.
//returns the friend number if success
//return -1 if failure.
int m_addfriend_norequest(uint8_t * client_id);
//remove a friend //remove a friend
int m_delfriend(int friendnumber); int m_delfriend(int friendnumber);
@ -36,12 +42,12 @@ int m_setinfo(uint8_t * data, uint16_t length);
//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)
int m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
//set the function that will be executed when a message from a friend is received. //set the function that will be executed when a message from a friend is received.
//function format is: function(int friendnumber, uint8_t * message, uint32_t length) //function format is: function(int friendnumber, uint8_t * message, uint32_t length)
int m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
//run this at startup //run this at startup

View File

@ -383,7 +383,8 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data)
len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data); len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data);
if(len1 != -1) if(len1 != -1)
{ {
kill_connection_in(incoming_connections[i], 1); //conection is useless now, kill it in 1 seconds kill_connection(incoming_connections[i]);
//kill_connection_in(incoming_connections[i], 1); //conection is useless now, kill it in 1 seconds
incoming_connections[i] = -1; incoming_connections[i] = -1;
return len1; return len1;
} }
@ -396,6 +397,25 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data)
return -1; return -1;
} }
//get crypto connection id from public key of peer
//return -1 if there are no connections like we are looking for
//return id if it found it
int getcryptconnection_id(uint8_t * public_key)
{
uint32_t i;
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++)
{
if(crypto_connections[i].status > 0)
{
if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
{
return i;
}
}
}
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
@ -403,7 +423,7 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data)
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;
if(getconnection_id(ip_port) != -1) if(getcryptconnection_id(public_key) != -1)
{ {
return -1; return -1;
} }
@ -493,6 +513,10 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
{ {
return -1; return -1;
} }
if(getcryptconnection_id(public_key) != -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)
@ -583,14 +607,23 @@ void receive_crypto()
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)
{
if(id_packet(crypto_connections[i].number) == 2)//handle handshake packet.
{ {
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 = read_packet(crypto_connections[i].number, temp_data); uint16_t len;
if(id_packet(crypto_connections[i].number) == 1)
//if the packet is a friend request drop it (because we are already friends)
{
len = read_packet(crypto_connections[i].number, temp_data);
printf("REQUEST DROPPED\n");
}
if(id_packet(crypto_connections[i].number) == 2)//handle handshake packet.
{
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)
@ -660,7 +693,7 @@ 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(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;
} }

View File

@ -42,12 +42,22 @@ void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
} }
printf("\nOf length: %u with data: %s \n", length, data); printf("\nOf length: %u with data: %s \n", length, data);
if(length != sizeof("Install Gentoo"))
{
return;
}
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.
{
printf("Friend request accepted.\n");
m_addfriend_norequest(public_key);
}
} }
void print_message(int friendnumber, uint8_t * string, uint16_t length) void print_message(int friendnumber, uint8_t * string, uint16_t length)
{ {
printf("Message with length %u recieved from %u: %s \n", length, friendnumber, string); printf("Message with length %u recieved from %u: %s \n", length, friendnumber, string);
m_sendmessage(friendnumber, "Test1", 6);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -86,7 +96,7 @@ int main(int argc, char *argv[])
{ {
m_sendmessage(num, "Test", 5); m_sendmessage(num, "Test", 5);
doMessenger(); doMessenger();
c_sleep(1); c_sleep(30);
} }
} }