mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
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.
This commit is contained in:
parent
ff02d5a607
commit
30524bf415
|
@ -42,6 +42,7 @@
|
|||
static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status);
|
||||
static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
|
||||
uint32_t length);
|
||||
static int clear_receipts(Messenger *m, int32_t friendnumber);
|
||||
|
||||
// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
|
||||
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
|
|||
memcpy(m->friendlist[i].info, data, length);
|
||||
m->friendlist[i].info_size = length;
|
||||
m->friendlist[i].message_id = 0;
|
||||
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
|
||||
memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
|
||||
recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
|
||||
|
||||
|
@ -301,7 +301,6 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id)
|
|||
m->friendlist[i].userstatus = USERSTATUS_NONE;
|
||||
m->friendlist[i].is_typing = 0;
|
||||
m->friendlist[i].message_id = 0;
|
||||
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
|
||||
recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
|
||||
|
||||
if (m->numfriends == i)
|
||||
|
@ -330,6 +329,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
|
|||
onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
|
||||
crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
|
||||
free(m->friendlist[friendnumber].statusmessage);
|
||||
clear_receipts(m, friendnumber);
|
||||
remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id);
|
||||
memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
|
||||
uint32_t i;
|
||||
|
@ -363,6 +363,106 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
|
|||
return m->friendlist[friendnumber].status > NOFRIEND;
|
||||
}
|
||||
|
||||
static int clear_receipts(Messenger *m, int32_t friendnumber)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
|
||||
|
||||
while (receipts) {
|
||||
struct Receipts *temp_r = receipts->next;
|
||||
free(receipts);
|
||||
receipts = temp_r;
|
||||
}
|
||||
|
||||
m->friendlist[friendnumber].receipts_start = NULL;
|
||||
m->friendlist[friendnumber].receipts_end = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num, uint32_t msg_id)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *new = calloc(1, sizeof(struct Receipts));
|
||||
|
||||
if (!new)
|
||||
return -1;
|
||||
|
||||
new->packet_num = packet_num;
|
||||
new->msg_id = msg_id;
|
||||
|
||||
if (!m->friendlist[friendnumber].receipts_start) {
|
||||
m->friendlist[friendnumber].receipts_start = new;
|
||||
} else {
|
||||
m->friendlist[friendnumber].receipts_end->next = new;
|
||||
}
|
||||
|
||||
m->friendlist[friendnumber].receipts_end = new;
|
||||
new->next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_receipts(Messenger *m, int32_t friendnumber)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
|
||||
|
||||
while (receipts) {
|
||||
struct Receipts *temp_r = receipts->next;
|
||||
|
||||
if (cryptpacket_received(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, receipts->packet_num) == -1)
|
||||
break;
|
||||
|
||||
if (m->read_receipt)
|
||||
(*m->read_receipt)(m, friendnumber, receipts->msg_id, m->read_receipt_userdata);
|
||||
|
||||
free(receipts);
|
||||
m->friendlist[friendnumber].receipts_start = temp_r;
|
||||
receipts = temp_r;
|
||||
}
|
||||
|
||||
if (!m->friendlist[friendnumber].receipts_start)
|
||||
m->friendlist[friendnumber].receipts_end = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t send_message_generic(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length,
|
||||
uint8_t packet_id)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
if (length >= MAX_CRYPTO_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
|
||||
return 0;
|
||||
|
||||
uint8_t packet[length + 1];
|
||||
packet[0] = packet_id;
|
||||
|
||||
if (length != 0)
|
||||
memcpy(packet + 1, message, length);
|
||||
|
||||
int64_t packet_num = write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet,
|
||||
length + 1);
|
||||
|
||||
if (packet_num == -1)
|
||||
return 0;
|
||||
|
||||
uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msg_id == 0) {
|
||||
msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
|
||||
}
|
||||
|
||||
add_receipt(m, friendnumber, packet_num, msg_id);
|
||||
return msg_id;
|
||||
}
|
||||
|
||||
/* Send a text chat message to an online friend.
|
||||
*
|
||||
* return the message id if packet was successfully put into the send queue.
|
||||
|
@ -370,32 +470,7 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
|
|||
*/
|
||||
uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
uint32_t msgid = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msgid == 0)
|
||||
msgid = 1; // Otherwise, false error
|
||||
|
||||
if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
|
||||
return msgid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message,
|
||||
uint32_t length)
|
||||
{
|
||||
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t temp[sizeof(theid) + length];
|
||||
theid = htonl(theid);
|
||||
memcpy(temp, &theid, sizeof(theid));
|
||||
memcpy(temp + sizeof(theid), message, length);
|
||||
return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE, temp, sizeof(temp));
|
||||
return send_message_generic(m, friendnumber, message, length, PACKET_ID_MESSAGE);
|
||||
}
|
||||
|
||||
/* Send an action to an online friend.
|
||||
|
@ -405,32 +480,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
|
|||
*/
|
||||
uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
uint32_t msgid = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msgid == 0)
|
||||
msgid = 1; // Otherwise, false error
|
||||
|
||||
if (m_sendaction_withid(m, friendnumber, msgid, action, length)) {
|
||||
return msgid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
|
||||
uint32_t length)
|
||||
{
|
||||
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t temp[sizeof(theid) + length];
|
||||
theid = htonl(theid);
|
||||
memcpy(temp, &theid, sizeof(theid));
|
||||
memcpy(temp + sizeof(theid), action, length);
|
||||
return write_cryptpacket_id(m, friendnumber, PACKET_ID_ACTION, temp, sizeof(temp));
|
||||
return send_message_generic(m, friendnumber, action, length, PACKET_ID_ACTION);
|
||||
}
|
||||
|
||||
/* Send a name packet to friendnumber.
|
||||
|
@ -725,18 +775,6 @@ static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t
|
|||
m->friendlist[friendnumber].is_typing = is_typing;
|
||||
}
|
||||
|
||||
/* Sets whether we send read receipts for friendnumber. */
|
||||
void m_set_sends_receipts(Messenger *m, int32_t friendnumber, int yesno)
|
||||
{
|
||||
if (yesno != 0 && yesno != 1)
|
||||
return;
|
||||
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return;
|
||||
|
||||
m->friendlist[friendnumber].receives_read_receipts = yesno;
|
||||
}
|
||||
|
||||
/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
|
||||
/* Set the function that will be executed when a friend request is received. */
|
||||
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
|
|||
if (was_online) {
|
||||
break_files(m, friendnumber);
|
||||
remove_online_friend(m, friendnumber);
|
||||
clear_receipts(m, friendnumber);
|
||||
} else {
|
||||
add_online_friend(m, friendnumber);
|
||||
}
|
||||
|
@ -842,8 +881,8 @@ void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status)
|
|||
m->friendlist[friendnumber].status = status;
|
||||
}
|
||||
|
||||
int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
|
||||
uint32_t length)
|
||||
static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
|
||||
uint32_t length)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
@ -1916,8 +1955,8 @@ void kill_messenger(Messenger *m)
|
|||
kill_networking(m->net);
|
||||
|
||||
for (i = 0; i < m->numfriends; ++i) {
|
||||
if (m->friendlist[i].statusmessage)
|
||||
free(m->friendlist[i].statusmessage);
|
||||
clear_receipts(m, i);
|
||||
free(m->friendlist[i].statusmessage);
|
||||
}
|
||||
|
||||
free(m->friendlist);
|
||||
|
@ -2051,24 +2090,17 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
}
|
||||
|
||||
case PACKET_ID_MESSAGE: {
|
||||
const uint8_t *message_id = data;
|
||||
uint8_t message_id_length = 4;
|
||||
|
||||
if (data_length <= message_id_length)
|
||||
if (data_length == 0)
|
||||
break;
|
||||
|
||||
const uint8_t *message = data + message_id_length;
|
||||
uint16_t message_length = data_length - message_id_length;
|
||||
const uint8_t *message = data;
|
||||
uint16_t message_length = data_length;
|
||||
|
||||
/* Make sure the NULL terminator is present. */
|
||||
uint8_t message_terminated[message_length + 1];
|
||||
memcpy(message_terminated, message, message_length);
|
||||
message_terminated[message_length] = 0;
|
||||
|
||||
if (m->friendlist[i].receives_read_receipts) {
|
||||
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
|
||||
}
|
||||
|
||||
if (m->friend_message)
|
||||
(*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata);
|
||||
|
||||
|
@ -2076,24 +2108,17 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
}
|
||||
|
||||
case PACKET_ID_ACTION: {
|
||||
const uint8_t *message_id = data;
|
||||
uint8_t message_id_length = 4;
|
||||
|
||||
if (data_length <= message_id_length)
|
||||
if (data_length == 0)
|
||||
break;
|
||||
|
||||
const uint8_t *action = data + message_id_length;
|
||||
uint16_t action_length = data_length - message_id_length;
|
||||
const uint8_t *action = data;
|
||||
uint16_t action_length = data_length;
|
||||
|
||||
/* Make sure the NULL terminator is present. */
|
||||
uint8_t action_terminated[action_length + 1];
|
||||
memcpy(action_terminated, action, action_length);
|
||||
action_terminated[action_length] = 0;
|
||||
|
||||
if (m->friendlist[i].receives_read_receipts) {
|
||||
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
|
||||
}
|
||||
|
||||
if (m->friend_action)
|
||||
(*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata);
|
||||
|
||||
|
@ -2101,21 +2126,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
break;
|
||||
}
|
||||
|
||||
case PACKET_ID_RECEIPT: {
|
||||
uint32_t msgid;
|
||||
|
||||
if (data_length < sizeof(msgid))
|
||||
break;
|
||||
|
||||
memcpy(&msgid, data, sizeof(msgid));
|
||||
msgid = ntohl(msgid);
|
||||
|
||||
if (m->read_receipt)
|
||||
(*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_ID_INVITE_GROUPCHAT: {
|
||||
if (data_length != crypto_box_PUBLICKEYBYTES)
|
||||
break;
|
||||
|
@ -2348,6 +2358,8 @@ void do_friends(Messenger *m)
|
|||
if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) {
|
||||
send_relays(m, i);
|
||||
}
|
||||
|
||||
do_receipts(m, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#define PACKET_ID_STATUSMESSAGE 49
|
||||
#define PACKET_ID_USERSTATUS 50
|
||||
#define PACKET_ID_TYPING 51
|
||||
#define PACKET_ID_RECEIPT 63
|
||||
#define PACKET_ID_MESSAGE 64
|
||||
#define PACKET_ID_ACTION 65
|
||||
#define PACKET_ID_MSI 69
|
||||
|
@ -74,6 +73,13 @@ typedef struct {
|
|||
TCP_Proxy_Info proxy_info;
|
||||
} Messenger_Options;
|
||||
|
||||
|
||||
struct Receipts {
|
||||
uint32_t packet_num;
|
||||
uint32_t msg_id;
|
||||
struct Receipts *next;
|
||||
};
|
||||
|
||||
/* Status definitions. */
|
||||
enum {
|
||||
NOFRIEND,
|
||||
|
@ -168,7 +174,6 @@ typedef struct {
|
|||
uint8_t is_typing;
|
||||
uint16_t info_size; // Length of the info.
|
||||
uint32_t message_id; // a semi-unique id used in read receipts.
|
||||
uint8_t receives_read_receipts; // shall we send read receipts to this person?
|
||||
uint32_t friendrequest_nospam; // The nospam number used in the friend request.
|
||||
uint64_t ping_lastrecv;
|
||||
uint64_t ping_lastsent;
|
||||
|
@ -187,6 +192,9 @@ typedef struct {
|
|||
int (*function)(void *object, const uint8_t *data, uint32_t len);
|
||||
void *object;
|
||||
} lossless_packethandlers[PACKET_ID_LOSSLESS_RANGE_SIZE];
|
||||
|
||||
struct Receipts *receipts_start;
|
||||
struct Receipts *receipts_end;
|
||||
} Friend;
|
||||
|
||||
|
||||
|
@ -335,12 +343,8 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber);
|
|||
*
|
||||
* You will want to retain the return value, it will be passed to your read_receipt callback
|
||||
* if one is received.
|
||||
* m_sendmessage_withid will send a message with the id of your choosing,
|
||||
* however we can generate an id for you by calling plain m_sendmessage.
|
||||
*/
|
||||
uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length);
|
||||
uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message,
|
||||
uint32_t length);
|
||||
|
||||
/* Send an action to an online friend.
|
||||
*
|
||||
|
@ -349,12 +353,8 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
|
|||
*
|
||||
* You will want to retain the return value, it will be passed to your read_receipt callback
|
||||
* if one is received.
|
||||
* m_sendaction_withid will send an action message with the id of your choosing,
|
||||
* however we can generate an id for you by calling plain m_sendaction.
|
||||
*/
|
||||
uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length);
|
||||
uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
|
||||
uint32_t length);
|
||||
|
||||
/* Set the name and name_length of a friend.
|
||||
* name must be a string of maximum MAX_NAME_LENGTH length.
|
||||
|
@ -453,11 +453,6 @@ int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing);
|
|||
*/
|
||||
uint8_t m_get_istyping(const Messenger *m, int32_t friendnumber);
|
||||
|
||||
/* Sets whether we send read receipts for friendnumber.
|
||||
* This function is not lazy, and it will fail if yesno is not (0 or 1).
|
||||
*/
|
||||
void m_set_sends_receipts(Messenger *m, int32_t friendnumber, int yesno);
|
||||
|
||||
/* 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)
|
||||
*/
|
||||
|
|
|
@ -34,7 +34,7 @@ extern "C" {
|
|||
#define TOX_MAX_NAME_LENGTH 128
|
||||
|
||||
/* Maximum length of single messages after which they should be split. */
|
||||
#define TOX_MAX_MESSAGE_LENGTH 1368
|
||||
#define TOX_MAX_MESSAGE_LENGTH 1372
|
||||
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
|
||||
#define TOX_CLIENT_ID_SIZE 32
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user