diff options
author | irungentoo <irungentoo@gmail.com> | 2014-08-27 15:13:44 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-08-27 15:13:44 -0400 |
commit | 30524bf41513a334f0e32117b85aad2f661eed2b (patch) | |
tree | 44c0acbaf2daf6b41330f5ead3838be9f1e85ec6 /toxcore/Messenger.c | |
parent | ff02d5a607362df1382eeb4d7ef146eaab1c8dd1 (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.c | 202 |
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 @@ | |||
42 | static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); | 42 | static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); |
43 | static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, | 43 | static 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); |
45 | static 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 |
47 | static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber) | 48 | static 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. | 366 | static 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 | */ | ||
371 | uint32_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 | ||
388 | uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message, | 384 | static 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. | 408 | static 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 | */ | ||
406 | uint32_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 | ||
423 | uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action, | 435 | static 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 | */ | ||
471 | uint32_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 | */ | ||
481 | uint32_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. */ | ||
729 | void 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. */ |
742 | void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, uint16_t, | 780 | void 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 | ||
845 | int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, | 884 | static 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 | } |