From db37eca44bca126c08dff4353c9d1dab824f8030 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 8 Jul 2013 20:50:25 -0400 Subject: Some work done on the messenger part. --- core/DHT.c | 4 +- core/Messenger.c | 174 +++++++++++++++++++++++++++++++++++++++++------ core/Messenger.h | 18 +++-- testing/Messenger_test.c | 92 +++++++++++++++++++++++++ 4 files changed, 260 insertions(+), 28 deletions(-) create mode 100644 testing/Messenger_test.c diff --git a/core/DHT.c b/core/DHT.c index 5ca3604f..b8cabd52 100644 --- a/core/DHT.c +++ b/core/DHT.c @@ -756,7 +756,7 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) static uint32_t friend_lastgetnode[MAX_FRIENDS]; -void doFriends() +void doDHTFriends() { uint32_t i, j; uint32_t temp_time = unix_time(); @@ -836,7 +836,7 @@ void doClose()//tested void doDHT() { doClose(); - doFriends(); + doDHTFriends(); } diff --git a/core/Messenger.c b/core/Messenger.c index 7cfbb8ca..1107b60f 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -10,71 +10,203 @@ typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; - + int crypt_connection_id; + int friend_request_id; //id of the friend request corresponding to the current friend request to the current friend. + uint8_t status;//0 if no friend, 1 if added, 2 if friend request successfully sent, 3 if confirmed friend, 4 if online. }Friend; + +uint8_t info[MAX_DATA_SIZE]; //the data that is sent during the friend requests we do + +uint16_t info_size; //length of the info + #define MAX_NUM_FRIENDS 256 Friend friendlist[MAX_NUM_FRIENDS]; + +#define MAX_MESSAGE_LENGTH 256 + +uint32_t numfriends; //add a friend +//client_id is the client i of the friend //returns the friend number if success //return -1 if failure. int m_addfriend(uint8_t * client_id) { - //add friend to the DHT - addfriend(uint8_t * client_id); - - send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length); + DHT_addfriend(client_id); + friendlist[numfriends].status = 1; + 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) +{/* + TODO + DHT_delfriend(friendlist[friendnumber].client_id); +*/ +} + + +//return 4 if friend is online +//return 3 if friend is confirmed +//return 2 if the friend request was sent successfully +//return 1 if the friend was added +//return 0 if there is no friend with that number. +int m_friendstatus(int friendnumber) { - //delete friend from DHT - delfriend(uint8_t * client_id); - + if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) + { + return 0; + } + return friendlist[friendnumber].status; } -//return 1 if friend is online -//return 0 if he is not -int m_friendonline(int friendnumber) +//send a text chat message to an online friend. +//returns 1 if packet was successfully put into the send queue +//return 0 if it was not. +int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length) { - + if(length >= MAX_DATA_SIZE) + //this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. + { + return 0; + } + uint8_t temp[MAX_DATA_SIZE]; + temp[0] = 64; + memcpy(temp + 1, message, length); + return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); } +//set the data that will be sent along with friend requests +//return -1 if failure +//return 0 if success +int m_setinfo(uint8_t * data, uint16_t length) +{ + if(length == 0 || length > MAX_DATA_SIZE - 1 - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES) + { + return -1; + } + memcpy(info, data, length); + info_size = length; + return 0; +} -//send a text chat message to a friend. -int m_sendmessage(int friendnumber) +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)) { - write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); - + friend_request = function; +} + + +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)) +{ + friend_message = function; } #define PORT 33445 //run this at startup -void initMessenger(); +void initMessenger() { new_keys(); + initNetCrypto(); IP ip; ip.i = 0; init_networking(ip, PORT); + memcpy(self_client_id, self_public_key, crypto_box_PUBLICKEYBYTES); } +void doFriends() +{//TODO: add incoming connections and some other stuff. + uint32_t i; + int len; + uint8_t temp[MAX_DATA_SIZE]; + for(i = 0; i < numfriends; i++) + { + if(friendlist[i].status == 1) + { + IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); + int request = check_friendrequest(friendlist[i].friend_request_id); + //printf("\n%u %u %u\n", friendip.ip.i, request, friendlist[i].friend_request_id); + 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) + { + IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); + if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 0 && friendip.ip.i > 1) + { + friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); + } + if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 3)//if connection is established. + { + friendlist[i].status = 4; + } + } + while(friendlist[i].status == 4) + { + len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); + if(len > 0) + { + if(temp[0] == 64) + { + (*friend_message)(i, temp, len); + } + } + else + { + if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 4)//if the connection timed out, kill it + { + crypto_kill(friendlist[i].crypt_connection_id); + friendlist[i].status = 3; + } + break; + } + } + } +} + +void doFriendRequest() +{ + uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t temp[MAX_DATA_SIZE]; + + int len = handle_friendrequest(public_key, temp); + if(len >= 0) + { + (*friend_request)(public_key, temp, len); + + } + +} //the main loop that needs to be run at least 200 times per second. -void doMessenger(); +void doMessenger() { IP_Port ip_port; uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length; - while(recievepacket(&ip_port, data, &length) != -1) + while(receivepacket(&ip_port, data, &length) != -1) { //if(rand() % 3 != 1)//simulate packet loss //{ @@ -92,4 +224,6 @@ void doMessenger(); doDHT(); doLossless_UDP(); doNetCrypto(); -} \ No newline at end of file + doFriendRequest(); + doFriends(); +} diff --git a/core/Messenger.h b/core/Messenger.h index ae8ace16..1032d8d8 100644 --- a/core/Messenger.h +++ b/core/Messenger.h @@ -23,19 +23,25 @@ int m_delfriend(int friendnumber); //return 1 if friend is online //return 0 if he is not -int m_friendonline(int friendnumber); +int m_friendstatus(int friendnumber); //send a text chat message to a friend. -int m_sendmessage(int friendnumber); +int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length); +//set the data that will be sent along with friend requests +//return -1 if failure +//return 0 if success +int m_setinfo(uint8_t * data, uint16_t length); -//set the function that will be executed when a friend request is recieved. -int m_callback_friendrequest(); +//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)); -//set the function that will be executed when a message from a friend is recieved. -int m_callback_friendmessage(); +//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)); //run this at startup diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c new file mode 100644 index 00000000..4290d0fa --- /dev/null +++ b/testing/Messenger_test.c @@ -0,0 +1,92 @@ + + +#include "../core/Messenger.h" + +#ifdef WIN32 + +#define c_sleep(x) Sleep(1*x) + +#else +#include +#include +#define c_sleep(x) usleep(1000*x) + +#endif + +//horrible function from one of my first C programs. +//only here because I was too lazy to write a proper one. +unsigned char * hex_string_to_bin(char hex_string[]) +{ + unsigned char * val = malloc(strlen(hex_string)); + char * pos = hex_string; + int i=0; + while(i < strlen(hex_string)) + { + sscanf(pos,"%2hhx",&val[i]); + pos+=2; + i++; + } + return val; +} + +void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) +{ + printf("Friend request recieved from: \n"); + printf("ClientID: "); + uint32_t j; + for(j = 0; j < 32; j++) + { + if(public_key[j] < 16) + printf("0"); + printf("%hhX", public_key[j]); + } + printf("\nOf length: %u with data: %s \n", length, data); + +} + +void print_message(int friendnumber, uint8_t * string, uint16_t length) +{ + printf("Message with length %u recieved from %u: %s \n", length, friendnumber, string); + +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) { + printf("usage %s ip port (of the DHT bootstrap node)\n", argv[0]); + exit(0); + } + initMessenger(); + m_callback_friendrequest(print_request); + m_callback_friendmessage(print_message); + + m_setinfo("Install Gentoo", sizeof("Install Gentoo"));//The message we send is a message of peace + + printf("OUR ID: "); + uint32_t i; + for(i = 0; i < 32; i++) + { + if(self_public_key[i] < 16) + printf("0"); + printf("%hhX",self_public_key[i]); + } + + char temp_id[128]; + printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); + scanf("%s", temp_id); + int num = m_addfriend(hex_string_to_bin(temp_id)); + + perror("Initialization"); + IP_Port bootstrap_ip_port; + bootstrap_ip_port.port = htons(atoi(argv[2])); + bootstrap_ip_port.ip.i = inet_addr(argv[1]); + DHT_bootstrap(bootstrap_ip_port); + + while(1) + { + m_sendmessage(num, "Test", 5); + doMessenger(); + c_sleep(1); + } + +} -- cgit v1.2.3