From 5555f01e279a1e514584a62e709c4ef1b8d57ecd Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 4 Oct 2014 16:49:17 -0400 Subject: Send friend request with connection if for some reason (groupchats) we are already connected to the friend but they have not added us yet. --- toxcore/Messenger.c | 8 +++---- toxcore/friend_connection.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ toxcore/friend_connection.h | 19 ++++++++++++++++ toxcore/friend_requests.c | 35 ++--------------------------- toxcore/friend_requests.h | 10 ++------- toxcore/group.c | 2 +- 6 files changed, 82 insertions(+), 46 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index db5a3141..04d1a2f7 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1625,7 +1625,7 @@ Messenger *new_messenger(Messenger_Options *options) } m->options = *options; - friendreq_init(&(m->fr), m->onion_c); + friendreq_init(&(m->fr), m->fr_c); LANdiscovery_init(m->dht); set_nospam(&(m->fr), random_int()); set_filter_function(&(m->fr), &friend_already_added, m); @@ -2286,9 +2286,9 @@ void do_friends(Messenger *m) for (i = 0; i < m->numfriends; ++i) { if (m->friendlist[i].status == FRIEND_ADDED) { - int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, - m->friendlist[i].info, - m->friendlist[i].info_size); + int fr = send_friend_request_packet(m->fr_c, m->friendlist[i].friendcon_id, m->friendlist[i].friendrequest_nospam, + m->friendlist[i].info, + m->friendlist[i].info_size); if (fr >= 0) { set_friend_status(m, i, FRIEND_REQUESTED); diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 7be4251a..7eb8e8c0 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -253,6 +253,13 @@ static int handle_packet(void *object, int number, uint8_t *data, uint16_t lengt Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); + if (data[0] == PACKET_ID_FRIEND_REQUESTS) { + if (fr_c->fr_request_callback) + fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); + + return 0; + } + if (!friend_con) return -1; @@ -538,6 +545,53 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id) } +/* Set friend request callback. + * + * This function will be called every time a friend request packet is received. + */ +void set_friend_request_callback(Friend_Connections *fr_c, int (*fr_request_callback)(void *, const uint8_t *, + const uint8_t *, uint32_t), void *object) +{ + fr_c->fr_request_callback = fr_request_callback; + fr_c->fr_request_object = object; + oniondata_registerhandler(fr_c->onion_c, CRYPTO_PACKET_FRIEND_REQ, fr_request_callback, object); +} + +/* Send a Friend request packet. + * + * return -1 if failure. + * return 0 if it sent the friend request directly to the friend. + * return the number of peers it was routed through if it did not send it directly. + */ +int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, + uint16_t length) +{ + if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) + return -1; + + Friend_Conn *friend_con = get_conn(fr_c, friendcon_id); + + if (!friend_con) + return -1; + + uint8_t packet[1 + sizeof(nospam_num) + length]; + memcpy(packet + 1, &nospam_num, sizeof(nospam_num)); + memcpy(packet + 1 + sizeof(nospam_num), data, length); + + if (friend_con->status == FRIENDCONN_STATUS_CONNECTED) { + packet[0] = PACKET_ID_FRIEND_REQUESTS; + return write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, packet, sizeof(packet), 0) != -1; + } else { + packet[0] = CRYPTO_PACKET_FRIEND_REQ; + int num = send_onion_data(fr_c->onion_c, friend_con->onion_friendnum, packet, sizeof(packet)); + + if (num <= 0) + return -1; + + return num; + } +} + /* Create new friend_connections instance. */ Friend_Connections *new_friend_connections(Onion_Client *onion_c) { diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index 64280acb..4f8cbf41 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h @@ -36,6 +36,7 @@ #define GROUPCHAT_CALLBACK_INDEX 1 #define PACKET_ID_ALIVE 16 +#define PACKET_ID_FRIEND_REQUESTS 18 /* Interval between the sending of ping packets. */ #define FRIEND_PING_INTERVAL 6 @@ -93,6 +94,8 @@ typedef struct { Friend_Conn *conns; uint32_t num_cons; + int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint32_t len); + void *fr_request_object; } Friend_Connections; /* return friendcon_id corresponding to the real public key on success. @@ -157,6 +160,22 @@ int new_friend_connection(Friend_Connections *fr_c, const uint8_t *real_public_k */ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id); +/* Send a Friend request packet. + * + * return -1 if failure. + * return 0 if it sent the friend request directly to the friend. + * return the number of peers it was routed through if it did not send it directly. + */ +int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, + uint16_t length); + +/* Set friend request callback. + * + * This function will be called every time a friend request is received. + */ +void set_friend_request_callback(Friend_Connections *fr_c, int (*fr_request_callback)(void *, const uint8_t *, + const uint8_t *, uint32_t), void *object); + /* Create new friend_connections instance. */ Friend_Connections *new_friend_connections(Onion_Client *onion_c); diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index a662b629..a7a1bcba 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -28,37 +28,6 @@ #include "friend_requests.h" #include "util.h" -/* Try to send a friend request to peer with public_key. - * data is the data in the request and length is the length. - * - * return -1 if failure. - * return 0 if it sent the friend request directly to the friend. - * return the number of peers it was routed through if it did not send it directly. - */ -int send_friendrequest(const Onion_Client *onion_c, const uint8_t *public_key, uint32_t nospam_num, const uint8_t *data, - uint32_t length) -{ - if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) - return -1; - - uint8_t temp[1 + sizeof(nospam_num) + length]; - temp[0] = CRYPTO_PACKET_FRIEND_REQ; - memcpy(temp + 1, &nospam_num, sizeof(nospam_num)); - memcpy(temp + 1 + sizeof(nospam_num), data, length); - - int friend_num = onion_friend_num(onion_c, public_key); - - if (friend_num == -1) - return -1; - - int num = send_onion_data(onion_c, friend_num, temp, sizeof(temp)); - - if (num <= 0) - return -1; - - return num; -} - /* Set and get the nospam variable used to prevent one type of friend request spam. */ void set_nospam(Friend_Requests *fr, uint32_t num) @@ -169,7 +138,7 @@ static int friendreq_handlepacket(void *object, const uint8_t *source_pubkey, co return 0; } -void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c) +void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c) { - oniondata_registerhandler(onion_c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr); + set_friend_request_callback(fr_c, &friendreq_handlepacket, fr); } diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h index c3e31f36..b7e07af4 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h @@ -24,7 +24,7 @@ #ifndef FRIEND_REQUESTS_H #define FRIEND_REQUESTS_H -#include "onion_client.h" +#include "friend_connection.h" #define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) @@ -47,12 +47,6 @@ typedef struct { uint16_t received_requests_index; } Friend_Requests; -/* Try to send a friendrequest to peer with public_key. - * data is the data in the request and length is the length. - * Maximum length of data is MAX_FRIEND_REQUEST_DATA_SIZE. - */ -int send_friendrequest(const Onion_Client *onion_c, const uint8_t *public_key, uint32_t nospam_num, const uint8_t *data, - uint32_t length); /* Set and get the nospam variable used to prevent one type of friend request spam. */ void set_nospam(Friend_Requests *fr, uint32_t num); uint32_t get_nospam(const Friend_Requests *fr); @@ -77,7 +71,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(void *, const void set_filter_function(Friend_Requests *fr, int (*function)(const uint8_t *, void *), void *userdata); /* Sets up friendreq packet handlers. */ -void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c); +void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c); #endif diff --git a/toxcore/group.c b/toxcore/group.c index f83cd5a2..352c40f5 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -979,7 +979,7 @@ static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, cons return; uint16_t peer_number = rand(); /* TODO: what if two people enter the group at the same time and - are given the same peer_number by different nodes? */ + are given the same peer_number by different nodes? */ unsigned int tries = 0; while (get_peer_index(g, peer_number) != -1) { -- cgit v1.2.3