From 4d5063852859d44547497f1d3c0b5af9c676b2ba Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 9 Jul 2013 13:20:48 -0400 Subject: Basic IM messenger backend pretty much done (You can start the GUI) And a couple of fixes to the other parts. --- core/Lossless_UDP.c | 13 +++++++-- core/Messenger.c | 70 +++++++++++++++++++++++++++++++++++++++++++----- core/Messenger.h | 10 +++++-- core/net_crypto.c | 49 +++++++++++++++++++++++++++------ testing/Messenger_test.c | 14 ++++++++-- 5 files changed, 136 insertions(+), 20 deletions(-) diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 080dc821..9d31a53b 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c @@ -37,7 +37,7 @@ #define BUFFER_PACKET_NUM (16-1) //Lossless UDP connection timeout. -#define CONNEXION_TIMEOUT 10 +#define CONNEXION_TIMEOUT 5 //initial amount of sync/hanshake packets to send per second. #define SYNC_RATE 10 @@ -133,7 +133,13 @@ uint32_t handshake_id(IP_Port source) } 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 @@ -152,6 +158,7 @@ int new_connection(IP_Port ip_port) { if(connections[i].status == 0) { + memset(&connections[i], 0, sizeof(Connection)); connections[i].ip_port = ip_port; connections[i].status = 1; connections[i].inbound = 0; @@ -184,6 +191,7 @@ int new_inconnection(IP_Port ip_port) { if(connections[i].status == 0) { + memset(&connections[i], 0, sizeof(Connection)); connections[i].ip_port = ip_port; connections[i].status = 2; connections[i].inbound = 2; @@ -223,6 +231,7 @@ int kill_connection(int connection_id) if(connections[connection_id].status > 0) { connections[connection_id].status = 0; + change_handshake(connections[connection_id].ip_port); return 0; } } diff --git a/core/Messenger.c b/core/Messenger.c index 1107b60f..4d484e54 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -45,6 +45,17 @@ int m_addfriend(uint8_t * client_id) 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 int m_delfriend(int friendnumber) {/* @@ -74,7 +85,11 @@ int m_friendstatus(int friendnumber) //return 0 if it was not. 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. { return 0; @@ -103,7 +118,7 @@ int m_setinfo(uint8_t * data, uint16_t length) void (*friend_request)(uint8_t *, uint8_t *, uint16_t); //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; } @@ -112,7 +127,7 @@ int m_callback_friendrequest(void (*function)(uint8_t *, 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. -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; } @@ -146,14 +161,13 @@ void doFriends() if(friendip.ip.i > 1 && request == -1) { friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, friendip, info, info_size); - } - if(request == 1) - { friendlist[i].status = 2; } } 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); if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 0 && friendip.ip.i > 1) { @@ -163,6 +177,10 @@ void doFriends() { 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) { @@ -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. void doMessenger() { @@ -224,6 +281,7 @@ void doMessenger() doDHT(); doLossless_UDP(); doNetCrypto(); + doInbound(); doFriendRequest(); doFriends(); } diff --git a/core/Messenger.h b/core/Messenger.h index 1032d8d8..7e6a0ba0 100644 --- a/core/Messenger.h +++ b/core/Messenger.h @@ -18,6 +18,12 @@ 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 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. //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. //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 diff --git a/core/net_crypto.c b/core/net_crypto.c index bcdb2030..9f9378f6 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c @@ -383,7 +383,8 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data) len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data); 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; return len1; } @@ -396,6 +397,25 @@ int handle_friendrequest(uint8_t * public_key, uint8_t * data) 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 //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) { uint32_t i; - if(getconnection_id(ip_port) != -1) + if(getcryptconnection_id(public_key) != -1) { return -1; } @@ -493,6 +513,10 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec { return -1; } + if(getcryptconnection_id(public_key) != -1) + { + return -1; + } for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) { if(crypto_connections[i].status == 0) @@ -584,13 +608,22 @@ void receive_crypto() { if(crypto_connections[i].status == 1) { + uint8_t temp_data[MAX_DATA_SIZE]; + uint8_t secret_nonce[crypto_box_NONCEBYTES]; + uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t session_key[crypto_box_PUBLICKEYBYTES]; + uint16_t len; + if(id_packet(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. { - uint8_t temp_data[MAX_DATA_SIZE]; - uint8_t secret_nonce[crypto_box_NONCEBYTES]; - uint8_t public_key[crypto_box_PUBLICKEYBYTES]; - uint8_t session_key[crypto_box_PUBLICKEYBYTES]; - uint16_t len = 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(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) @@ -660,7 +693,7 @@ void killTimedout() uint32_t 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; } diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 4290d0fa..3c7c08e9 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -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); + 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) { printf("Message with length %u recieved from %u: %s \n", length, friendnumber, string); - + m_sendmessage(friendnumber, "Test1", 6); } int main(int argc, char *argv[]) @@ -86,7 +96,7 @@ int main(int argc, char *argv[]) { m_sendmessage(num, "Test", 5); doMessenger(); - c_sleep(1); + c_sleep(30); } } -- cgit v1.2.3