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)
//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;
}
}

View File

@ -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();
}

View File

@ -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

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);
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;
}

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);
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);
}
}