summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-08-27 15:13:44 -0400
committerirungentoo <irungentoo@gmail.com>2014-08-27 15:13:44 -0400
commit30524bf41513a334f0e32117b85aad2f661eed2b (patch)
tree44c0acbaf2daf6b41330f5ead3838be9f1e85ec6 /toxcore/Messenger.c
parentff02d5a607362df1382eeb4d7ef146eaab1c8dd1 (diff)
Changed how receipts work.
Messages now have a maximum length of 1372. Receipt packets have been removed, instead net_crypto tells us if the other peer has received the packets or not.
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c202
1 files changed, 107 insertions, 95 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index fd7527e4..eff845cf 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -42,6 +42,7 @@
42static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); 42static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status);
43static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, 43static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
44 uint32_t length); 44 uint32_t length);
45static int clear_receipts(Messenger *m, int32_t friendnumber);
45 46
46// friend_not_valid determines if the friendnumber passed is valid in the Messenger object 47// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
47static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber) 48static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber)
@@ -251,7 +252,6 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u
251 memcpy(m->friendlist[i].info, data, length); 252 memcpy(m->friendlist[i].info, data, length);
252 m->friendlist[i].info_size = length; 253 m->friendlist[i].info_size = length;
253 m->friendlist[i].message_id = 0; 254 m->friendlist[i].message_id = 0;
254 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
255 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); 255 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
256 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); 256 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
257 257
@@ -301,7 +301,6 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id)
301 m->friendlist[i].userstatus = USERSTATUS_NONE; 301 m->friendlist[i].userstatus = USERSTATUS_NONE;
302 m->friendlist[i].is_typing = 0; 302 m->friendlist[i].is_typing = 0;
303 m->friendlist[i].message_id = 0; 303 m->friendlist[i].message_id = 0;
304 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
305 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); 304 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
306 305
307 if (m->numfriends == i) 306 if (m->numfriends == i)
@@ -330,6 +329,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
330 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); 329 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
331 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 330 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
332 free(m->friendlist[friendnumber].statusmessage); 331 free(m->friendlist[friendnumber].statusmessage);
332 clear_receipts(m, friendnumber);
333 remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id); 333 remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id);
334 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 334 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
335 uint32_t i; 335 uint32_t i;
@@ -363,74 +363,124 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
363 return m->friendlist[friendnumber].status > NOFRIEND; 363 return m->friendlist[friendnumber].status > NOFRIEND;
364} 364}
365 365
366/* Send a text chat message to an online friend. 366static int clear_receipts(Messenger *m, int32_t friendnumber)
367 *
368 * return the message id if packet was successfully put into the send queue.
369 * return 0 if it was not.
370 */
371uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length)
372{ 367{
373 if (friend_not_valid(m, friendnumber)) 368 if (friend_not_valid(m, friendnumber))
374 return 0; 369 return -1;
375
376 uint32_t msgid = ++m->friendlist[friendnumber].message_id;
377 370
378 if (msgid == 0) 371 struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
379 msgid = 1; // Otherwise, false error
380 372
381 if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) { 373 while (receipts) {
382 return msgid; 374 struct Receipts *temp_r = receipts->next;
375 free(receipts);
376 receipts = temp_r;
383 } 377 }
384 378
379 m->friendlist[friendnumber].receipts_start = NULL;
380 m->friendlist[friendnumber].receipts_end = NULL;
385 return 0; 381 return 0;
386} 382}
387 383
388uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message, 384static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num, uint32_t msg_id)
389 uint32_t length)
390{ 385{
391 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0) 386 if (friend_not_valid(m, friendnumber))
392 return 0; 387 return -1;
393 388
394 uint8_t temp[sizeof(theid) + length]; 389 struct Receipts *new = calloc(1, sizeof(struct Receipts));
395 theid = htonl(theid); 390
396 memcpy(temp, &theid, sizeof(theid)); 391 if (!new)
397 memcpy(temp + sizeof(theid), message, length); 392 return -1;
398 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE, temp, sizeof(temp)); 393
394 new->packet_num = packet_num;
395 new->msg_id = msg_id;
396
397 if (!m->friendlist[friendnumber].receipts_start) {
398 m->friendlist[friendnumber].receipts_start = new;
399 } else {
400 m->friendlist[friendnumber].receipts_end->next = new;
401 }
402
403 m->friendlist[friendnumber].receipts_end = new;
404 new->next = NULL;
405 return 0;
399} 406}
400 407
401/* Send an action to an online friend. 408static int do_receipts(Messenger *m, int32_t friendnumber)
402 *
403 * return the message id if packet was successfully put into the send queue.
404 * return 0 if it was not.
405 */
406uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length)
407{ 409{
408 if (friend_not_valid(m, friendnumber)) 410 if (friend_not_valid(m, friendnumber))
409 return 0; 411 return -1;
412
413 struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
410 414
411 uint32_t msgid = ++m->friendlist[friendnumber].message_id; 415 while (receipts) {
416 struct Receipts *temp_r = receipts->next;
412 417
413 if (msgid == 0) 418 if (cryptpacket_received(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, receipts->packet_num) == -1)
414 msgid = 1; // Otherwise, false error 419 break;
420
421 if (m->read_receipt)
422 (*m->read_receipt)(m, friendnumber, receipts->msg_id, m->read_receipt_userdata);
415 423
416 if (m_sendaction_withid(m, friendnumber, msgid, action, length)) { 424 free(receipts);
417 return msgid; 425 m->friendlist[friendnumber].receipts_start = temp_r;
426 receipts = temp_r;
418 } 427 }
419 428
429 if (!m->friendlist[friendnumber].receipts_start)
430 m->friendlist[friendnumber].receipts_end = NULL;
431
420 return 0; 432 return 0;
421} 433}
422 434
423uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action, 435static uint32_t send_message_generic(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length,
424 uint32_t length) 436 uint8_t packet_id)
425{ 437{
426 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0) 438 if (friend_not_valid(m, friendnumber))
427 return 0; 439 return 0;
428 440
429 uint8_t temp[sizeof(theid) + length]; 441 if (length >= MAX_CRYPTO_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
430 theid = htonl(theid); 442 return 0;
431 memcpy(temp, &theid, sizeof(theid)); 443
432 memcpy(temp + sizeof(theid), action, length); 444 uint8_t packet[length + 1];
433 return write_cryptpacket_id(m, friendnumber, PACKET_ID_ACTION, temp, sizeof(temp)); 445 packet[0] = packet_id;
446
447 if (length != 0)
448 memcpy(packet + 1, message, length);
449
450 int64_t packet_num = write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet,
451 length + 1);
452
453 if (packet_num == -1)
454 return 0;
455
456 uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
457
458 if (msg_id == 0) {
459 msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
460 }
461
462 add_receipt(m, friendnumber, packet_num, msg_id);
463 return msg_id;
464}
465
466/* Send a text chat message to an online friend.
467 *
468 * return the message id if packet was successfully put into the send queue.
469 * return 0 if it was not.
470 */
471uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length)
472{
473 return send_message_generic(m, friendnumber, message, length, PACKET_ID_MESSAGE);
474}
475
476/* Send an action to an online friend.
477 *
478 * return the message id if packet was successfully put into the send queue.
479 * return 0 if it was not.
480 */
481uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length)
482{
483 return send_message_generic(m, friendnumber, action, length, PACKET_ID_ACTION);
434} 484}
435 485
436/* Send a name packet to friendnumber. 486/* Send a name packet to friendnumber.
@@ -725,18 +775,6 @@ static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t
725 m->friendlist[friendnumber].is_typing = is_typing; 775 m->friendlist[friendnumber].is_typing = is_typing;
726} 776}
727 777
728/* Sets whether we send read receipts for friendnumber. */
729void m_set_sends_receipts(Messenger *m, int32_t friendnumber, int yesno)
730{
731 if (yesno != 0 && yesno != 1)
732 return;
733
734 if (friend_not_valid(m, friendnumber))
735 return;
736
737 m->friendlist[friendnumber].receives_read_receipts = yesno;
738}
739
740/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */ 778/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
741/* Set the function that will be executed when a friend request is received. */ 779/* Set the function that will be executed when a friend request is received. */
742void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, uint16_t, 780void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, uint16_t,
@@ -821,6 +859,7 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
821 if (was_online) { 859 if (was_online) {
822 break_files(m, friendnumber); 860 break_files(m, friendnumber);
823 remove_online_friend(m, friendnumber); 861 remove_online_friend(m, friendnumber);
862 clear_receipts(m, friendnumber);
824 } else { 863 } else {
825 add_online_friend(m, friendnumber); 864 add_online_friend(m, friendnumber);
826 } 865 }
@@ -842,8 +881,8 @@ void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status)
842 m->friendlist[friendnumber].status = status; 881 m->friendlist[friendnumber].status = status;
843} 882}
844 883
845int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, 884static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
846 uint32_t length) 885 uint32_t length)
847{ 886{
848 if (friend_not_valid(m, friendnumber)) 887 if (friend_not_valid(m, friendnumber))
849 return 0; 888 return 0;
@@ -1916,8 +1955,8 @@ void kill_messenger(Messenger *m)
1916 kill_networking(m->net); 1955 kill_networking(m->net);
1917 1956
1918 for (i = 0; i < m->numfriends; ++i) { 1957 for (i = 0; i < m->numfriends; ++i) {
1919 if (m->friendlist[i].statusmessage) 1958 clear_receipts(m, i);
1920 free(m->friendlist[i].statusmessage); 1959 free(m->friendlist[i].statusmessage);
1921 } 1960 }
1922 1961
1923 free(m->friendlist); 1962 free(m->friendlist);
@@ -2051,24 +2090,17 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2051 } 2090 }
2052 2091
2053 case PACKET_ID_MESSAGE: { 2092 case PACKET_ID_MESSAGE: {
2054 const uint8_t *message_id = data; 2093 if (data_length == 0)
2055 uint8_t message_id_length = 4;
2056
2057 if (data_length <= message_id_length)
2058 break; 2094 break;
2059 2095
2060 const uint8_t *message = data + message_id_length; 2096 const uint8_t *message = data;
2061 uint16_t message_length = data_length - message_id_length; 2097 uint16_t message_length = data_length;
2062 2098
2063 /* Make sure the NULL terminator is present. */ 2099 /* Make sure the NULL terminator is present. */
2064 uint8_t message_terminated[message_length + 1]; 2100 uint8_t message_terminated[message_length + 1];
2065 memcpy(message_terminated, message, message_length); 2101 memcpy(message_terminated, message, message_length);
2066 message_terminated[message_length] = 0; 2102 message_terminated[message_length] = 0;
2067 2103
2068 if (m->friendlist[i].receives_read_receipts) {
2069 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
2070 }
2071
2072 if (m->friend_message) 2104 if (m->friend_message)
2073 (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata); 2105 (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata);
2074 2106
@@ -2076,24 +2108,17 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2076 } 2108 }
2077 2109
2078 case PACKET_ID_ACTION: { 2110 case PACKET_ID_ACTION: {
2079 const uint8_t *message_id = data; 2111 if (data_length == 0)
2080 uint8_t message_id_length = 4;
2081
2082 if (data_length <= message_id_length)
2083 break; 2112 break;
2084 2113
2085 const uint8_t *action = data + message_id_length; 2114 const uint8_t *action = data;
2086 uint16_t action_length = data_length - message_id_length; 2115 uint16_t action_length = data_length;
2087 2116
2088 /* Make sure the NULL terminator is present. */ 2117 /* Make sure the NULL terminator is present. */
2089 uint8_t action_terminated[action_length + 1]; 2118 uint8_t action_terminated[action_length + 1];
2090 memcpy(action_terminated, action, action_length); 2119 memcpy(action_terminated, action, action_length);
2091 action_terminated[action_length] = 0; 2120 action_terminated[action_length] = 0;
2092 2121
2093 if (m->friendlist[i].receives_read_receipts) {
2094 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
2095 }
2096
2097 if (m->friend_action) 2122 if (m->friend_action)
2098 (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata); 2123 (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata);
2099 2124
@@ -2101,21 +2126,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2101 break; 2126 break;
2102 } 2127 }
2103 2128
2104 case PACKET_ID_RECEIPT: {
2105 uint32_t msgid;
2106
2107 if (data_length < sizeof(msgid))
2108 break;
2109
2110 memcpy(&msgid, data, sizeof(msgid));
2111 msgid = ntohl(msgid);
2112
2113 if (m->read_receipt)
2114 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
2115
2116 break;
2117 }
2118
2119 case PACKET_ID_INVITE_GROUPCHAT: { 2129 case PACKET_ID_INVITE_GROUPCHAT: {
2120 if (data_length != crypto_box_PUBLICKEYBYTES) 2130 if (data_length != crypto_box_PUBLICKEYBYTES)
2121 break; 2131 break;
@@ -2348,6 +2358,8 @@ void do_friends(Messenger *m)
2348 if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) { 2358 if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) {
2349 send_relays(m, i); 2359 send_relays(m, i);
2350 } 2360 }
2361
2362 do_receipts(m, i);
2351 } 2363 }
2352 } 2364 }
2353} 2365}