mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
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:
parent
db37eca44b
commit
4d50638528
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user