diff options
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r-- | toxcore/Messenger.c | 719 |
1 files changed, 42 insertions, 677 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 99b95f67..c3f85beb 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -153,20 +153,9 @@ void getaddress(const Messenger *m, uint8_t *address) | |||
153 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); | 153 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); |
154 | } | 154 | } |
155 | 155 | ||
156 | /* callback for recv TCP relay nodes. */ | 156 | static int handle_status(void *object, int i, uint8_t status); |
157 | static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) | 157 | static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len); |
158 | { | 158 | static int handle_custom_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length); |
159 | Messenger *m = object; | ||
160 | |||
161 | if (friend_not_valid(m, number)) | ||
162 | return -1; | ||
163 | |||
164 | if (m->friendlist[number].crypt_connection_id != -1) { | ||
165 | return add_tcp_relay_peer(m->net_crypto, m->friendlist[number].crypt_connection_id, ip_port, public_key); | ||
166 | } else { | ||
167 | return add_tcp_relay(m->net_crypto, ip_port, public_key); | ||
168 | } | ||
169 | } | ||
170 | 159 | ||
171 | /* | 160 | /* |
172 | * Add a friend. | 161 | * Add a friend. |
@@ -230,18 +219,17 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
230 | 219 | ||
231 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); | 220 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); |
232 | 221 | ||
233 | int32_t onion_friendnum = onion_addfriend(m->onion_c, client_id); | 222 | int friendcon_id = new_friend_connection(m->fr_c, client_id); |
234 | 223 | ||
235 | if (onion_friendnum == -1) | 224 | if (friendcon_id == -1) |
236 | return FAERR_UNKNOWN; | 225 | return -1; |
237 | 226 | ||
238 | uint32_t i; | 227 | uint32_t i; |
239 | 228 | ||
240 | for (i = 0; i <= m->numfriends; ++i) { | 229 | for (i = 0; i <= m->numfriends; ++i) { |
241 | if (m->friendlist[i].status == NOFRIEND) { | 230 | if (m->friendlist[i].status == NOFRIEND) { |
242 | m->friendlist[i].onion_friendnum = onion_friendnum; | ||
243 | m->friendlist[i].status = FRIEND_ADDED; | 231 | m->friendlist[i].status = FRIEND_ADDED; |
244 | m->friendlist[i].crypt_connection_id = -1; | 232 | m->friendlist[i].friendcon_id = friendcon_id; |
245 | m->friendlist[i].friendrequest_lastsent = 0; | 233 | m->friendlist[i].friendrequest_lastsent = 0; |
246 | m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; | 234 | m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; |
247 | id_copy(m->friendlist[i].client_id, client_id); | 235 | id_copy(m->friendlist[i].client_id, client_id); |
@@ -258,7 +246,9 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u | |||
258 | m->friendlist[i].message_id = 0; | 246 | m->friendlist[i].message_id = 0; |
259 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | 247 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ |
260 | memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); | 248 | memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); |
261 | recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); | 249 | friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, |
250 | &handle_custom_lossy_packet, m, i); | ||
251 | |||
262 | 252 | ||
263 | if (m->numfriends == i) | 253 | if (m->numfriends == i) |
264 | ++m->numfriends; | 254 | ++m->numfriends; |
@@ -287,18 +277,17 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id) | |||
287 | 277 | ||
288 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); | 278 | memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); |
289 | 279 | ||
290 | int32_t onion_friendnum = onion_addfriend(m->onion_c, client_id); | 280 | int friendcon_id = new_friend_connection(m->fr_c, client_id); |
291 | 281 | ||
292 | if (onion_friendnum == -1) | 282 | if (friendcon_id == -1) |
293 | return -1; | 283 | return -1; |
294 | 284 | ||
295 | uint32_t i; | 285 | uint32_t i; |
296 | 286 | ||
297 | for (i = 0; i <= m->numfriends; ++i) { | 287 | for (i = 0; i <= m->numfriends; ++i) { |
298 | if (m->friendlist[i].status == NOFRIEND) { | 288 | if (m->friendlist[i].status == NOFRIEND) { |
299 | m->friendlist[i].onion_friendnum = onion_friendnum; | ||
300 | m->friendlist[i].status = FRIEND_CONFIRMED; | 289 | m->friendlist[i].status = FRIEND_CONFIRMED; |
301 | m->friendlist[i].crypt_connection_id = -1; | 290 | m->friendlist[i].friendcon_id = friendcon_id; |
302 | m->friendlist[i].friendrequest_lastsent = 0; | 291 | m->friendlist[i].friendrequest_lastsent = 0; |
303 | id_copy(m->friendlist[i].client_id, client_id); | 292 | id_copy(m->friendlist[i].client_id, client_id); |
304 | m->friendlist[i].statusmessage = calloc(1, 1); | 293 | m->friendlist[i].statusmessage = calloc(1, 1); |
@@ -311,7 +300,8 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id) | |||
311 | m->friendlist[i].is_typing = 0; | 300 | m->friendlist[i].is_typing = 0; |
312 | m->friendlist[i].message_id = 0; | 301 | m->friendlist[i].message_id = 0; |
313 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | 302 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ |
314 | recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); | 303 | friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, |
304 | &handle_custom_lossy_packet, m, i); | ||
315 | 305 | ||
316 | if (m->numfriends == i) | 306 | if (m->numfriends == i) |
317 | ++m->numfriends; | 307 | ++m->numfriends; |
@@ -336,11 +326,11 @@ int m_delfriend(Messenger *m, int32_t friendnumber) | |||
336 | if (m->friendlist[friendnumber].status == FRIEND_ONLINE) | 326 | if (m->friendlist[friendnumber].status == FRIEND_ONLINE) |
337 | remove_online_friend(m, friendnumber); | 327 | remove_online_friend(m, friendnumber); |
338 | 328 | ||
339 | onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); | ||
340 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); | ||
341 | free(m->friendlist[friendnumber].statusmessage); | 329 | free(m->friendlist[friendnumber].statusmessage); |
342 | free(m->friendlist[friendnumber].avatar_recv_data); | 330 | free(m->friendlist[friendnumber].avatar_recv_data); |
343 | remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id); | 331 | remove_request_received(&(m->fr), m->friendlist[friendnumber].client_id); |
332 | friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); | ||
333 | kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id); | ||
344 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); | 334 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); |
345 | uint32_t i; | 335 | uint32_t i; |
346 | 336 | ||
@@ -492,10 +482,6 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length) | |||
492 | for (i = 0; i < m->numfriends; ++i) | 482 | for (i = 0; i < m->numfriends; ++i) |
493 | m->friendlist[i].name_sent = 0; | 483 | m->friendlist[i].name_sent = 0; |
494 | 484 | ||
495 | for (i = 0; i < m->numchats; i++) | ||
496 | if (m->chats[i] != NULL) | ||
497 | set_nick(m->chats[i], name, length); /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
498 | |||
499 | return 0; | 485 | return 0; |
500 | } | 486 | } |
501 | 487 | ||
@@ -811,16 +797,6 @@ static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t | |||
811 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); | 797 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); |
812 | } | 798 | } |
813 | 799 | ||
814 | static int send_ping(const Messenger *m, int32_t friendnumber) | ||
815 | { | ||
816 | int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_ALIVE, 0, 0, 0); | ||
817 | |||
818 | if (ret == 1) | ||
819 | m->friendlist[friendnumber].ping_lastsent = unix_time(); | ||
820 | |||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | static int send_relays(const Messenger *m, int32_t friendnumber) | 800 | static int send_relays(const Messenger *m, int32_t friendnumber) |
825 | { | 801 | { |
826 | Node_format nodes[MAX_SHARED_RELAYS]; | 802 | Node_format nodes[MAX_SHARED_RELAYS]; |
@@ -967,8 +943,6 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui | |||
967 | const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE; | 943 | const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE; |
968 | const uint8_t is_online = status == FRIEND_ONLINE; | 944 | const uint8_t is_online = status == FRIEND_ONLINE; |
969 | 945 | ||
970 | onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online); | ||
971 | |||
972 | if (is_online != was_online) { | 946 | if (is_online != was_online) { |
973 | if (was_online) { | 947 | if (was_online) { |
974 | break_files(m, friendnumber); | 948 | break_files(m, friendnumber); |
@@ -1009,464 +983,31 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_ | |||
1009 | if (length != 0) | 983 | if (length != 0) |
1010 | memcpy(packet + 1, data, length); | 984 | memcpy(packet + 1, data, length); |
1011 | 985 | ||
1012 | return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1, | 986 | return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, |
1013 | congestion_control) != -1; | 987 | m->friendlist[friendnumber].friendcon_id), packet, length + 1, congestion_control) != -1; |
1014 | } | 988 | } |
1015 | 989 | ||
1016 | /**********GROUP CHATS************/ | 990 | /**********GROUP CHATS************/ |
1017 | 991 | ||
1018 | /* return 1 if the groupnumber is not valid. | ||
1019 | * return 0 if the groupnumber is valid. | ||
1020 | */ | ||
1021 | static uint8_t groupnumber_not_valid(const Messenger *m, int groupnumber) | ||
1022 | { | ||
1023 | if ((unsigned int)groupnumber >= m->numchats) | ||
1024 | return 1; | ||
1025 | |||
1026 | if (m->chats == NULL) | ||
1027 | return 1; | ||
1028 | |||
1029 | if (m->chats[groupnumber] == NULL) | ||
1030 | return 1; | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | /* returns valid ip port of connected friend on success | ||
1037 | * returns zeroed out IP_Port on failure | ||
1038 | */ | ||
1039 | static IP_Port get_friend_ipport(const Messenger *m, int32_t friendnumber) | ||
1040 | { | ||
1041 | IP_Port zero; | ||
1042 | memset(&zero, 0, sizeof(zero)); | ||
1043 | |||
1044 | if (friend_not_valid(m, friendnumber)) | ||
1045 | return zero; | ||
1046 | |||
1047 | int crypt_id = m->friendlist[friendnumber].crypt_connection_id; | ||
1048 | |||
1049 | uint8_t direct_connected; | ||
1050 | |||
1051 | if (crypto_connection_status(m->net_crypto, crypt_id, &direct_connected) != CRYPTO_CONN_ESTABLISHED) | ||
1052 | return zero; | ||
1053 | |||
1054 | if (direct_connected == 0) | ||
1055 | return zero; | ||
1056 | |||
1057 | return m->net_crypto->crypto_connections[crypt_id].ip_port; | ||
1058 | } | ||
1059 | |||
1060 | /* returns the group number of the chat with public key group_public_key. | ||
1061 | * returns -1 on failure. | ||
1062 | */ | ||
1063 | static int group_num(const Messenger *m, const uint8_t *group_public_key) | ||
1064 | { | ||
1065 | uint32_t i; | ||
1066 | |||
1067 | for (i = 0; i < m->numchats; ++i) { | ||
1068 | if (m->chats[i] != NULL) | ||
1069 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) | ||
1070 | return i; | ||
1071 | } | ||
1072 | |||
1073 | return -1; | ||
1074 | } | ||
1075 | 992 | ||
1076 | /* Set the callback for group invites. | 993 | /* Set the callback for group invites. |
1077 | * | 994 | * |
1078 | * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata) | 995 | * Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length) |
1079 | */ | 996 | */ |
1080 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, void *), | 997 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t)) |
1081 | void *userdata) | ||
1082 | { | 998 | { |
1083 | m->group_invite = function; | 999 | m->group_invite = function; |
1084 | m->group_invite_userdata = userdata; | ||
1085 | } | 1000 | } |
1086 | 1001 | ||
1087 | /* Set the callback for group messages. | ||
1088 | * | ||
1089 | * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) | ||
1090 | */ | ||
1091 | void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *), | ||
1092 | void *userdata) | ||
1093 | { | ||
1094 | m->group_message = function; | ||
1095 | m->group_message_userdata = userdata; | ||
1096 | } | ||
1097 | 1002 | ||
1098 | /* Set the callback for group actions. | 1003 | /* Send a group invite packet. |
1099 | * | 1004 | * |
1100 | * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) | 1005 | * return 1 on success |
1101 | */ | 1006 | * return 0 on failure |
1102 | void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *), | ||
1103 | void *userdata) | ||
1104 | { | ||
1105 | m->group_action = function; | ||
1106 | m->group_action_userdata = userdata; | ||
1107 | } | ||
1108 | |||
1109 | /* Set callback function for peer name list changes. | ||
1110 | * | ||
1111 | * It gets called every time the name list changes(new peer/name, deleted peer) | ||
1112 | * Function(Tox *tox, int groupnumber, void *userdata) | ||
1113 | */ | ||
1114 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), | ||
1115 | void *userdata) | ||
1116 | { | ||
1117 | m->group_namelistchange = function; | ||
1118 | m->group_namelistchange_userdata = userdata; | ||
1119 | } | ||
1120 | |||
1121 | static int get_chat_num(const Messenger *m, const Group_Chat *chat) | ||
1122 | { | ||
1123 | uint32_t i; | ||
1124 | |||
1125 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this | ||
1126 | if (m->chats[i] == chat) | ||
1127 | return i; | ||
1128 | } | ||
1129 | |||
1130 | return -1; | ||
1131 | } | ||
1132 | |||
1133 | static void group_message_function(Group_Chat *chat, int peer_number, const uint8_t *message, uint16_t length, | ||
1134 | void *userdata) | ||
1135 | { | ||
1136 | Messenger *m = userdata; | ||
1137 | int i = get_chat_num(m, chat); | ||
1138 | |||
1139 | if (i == -1) | ||
1140 | return; | ||
1141 | |||
1142 | uint8_t message_terminated[length + 1]; | ||
1143 | memcpy(message_terminated, message, length); | ||
1144 | message_terminated[length] = 0; /* Force NULL terminator */ | ||
1145 | |||
1146 | if (m->group_message) | ||
1147 | (*m->group_message)(m, i, peer_number, message_terminated, length, m->group_message_userdata); | ||
1148 | } | ||
1149 | |||
1150 | static void group_action_function(Group_Chat *chat, int peer_number, const uint8_t *action, uint16_t length, | ||
1151 | void *userdata) | ||
1152 | { | ||
1153 | Messenger *m = userdata; | ||
1154 | int i = get_chat_num(m, chat); | ||
1155 | |||
1156 | if (i == -1) | ||
1157 | return; | ||
1158 | |||
1159 | uint8_t action_terminated[length + 1]; | ||
1160 | memcpy(action_terminated, action, length); | ||
1161 | action_terminated[length] = 0; /* Force NULL terminator */ | ||
1162 | |||
1163 | if (m->group_action) | ||
1164 | (*m->group_action)(m, i, peer_number, action_terminated, length, m->group_action_userdata); | ||
1165 | } | ||
1166 | |||
1167 | static void group_namelistchange_function(Group_Chat *chat, int peer, uint8_t change, void *userdata) | ||
1168 | { | ||
1169 | Messenger *m = userdata; | ||
1170 | int i = get_chat_num(m, chat); | ||
1171 | |||
1172 | if (i == -1) | ||
1173 | return; | ||
1174 | |||
1175 | if (m->group_namelistchange) | ||
1176 | (*m->group_namelistchange)(m, i, peer, change, m->group_namelistchange_userdata); | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | /* Creates a new groupchat and puts it in the chats array. | ||
1181 | * | ||
1182 | * return group number on success. | ||
1183 | * return -1 on failure. | ||
1184 | */ | ||
1185 | int add_groupchat(Messenger *m) | ||
1186 | { | ||
1187 | uint32_t i; | ||
1188 | |||
1189 | for (i = 0; i < m->numchats; ++i) { | ||
1190 | if (m->chats[i] == NULL) { | ||
1191 | Group_Chat *newchat = new_groupchat(m->net); | ||
1192 | |||
1193 | if (newchat == NULL) | ||
1194 | return -1; | ||
1195 | |||
1196 | callback_groupmessage(newchat, &group_message_function, m); | ||
1197 | callback_groupaction(newchat, &group_action_function, m); | ||
1198 | callback_namelistchange(newchat, &group_namelistchange_function, m); | ||
1199 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
1200 | set_nick(newchat, m->name, m->name_length); | ||
1201 | m->chats[i] = newchat; | ||
1202 | return i; | ||
1203 | } | ||
1204 | } | ||
1205 | |||
1206 | Group_Chat **temp; | ||
1207 | temp = realloc(m->chats, sizeof(Group_Chat *) * (m->numchats + 1)); | ||
1208 | |||
1209 | if (temp == NULL) | ||
1210 | return -1; | ||
1211 | |||
1212 | m->chats = temp; | ||
1213 | temp[m->numchats] = new_groupchat(m->net); | ||
1214 | |||
1215 | if (temp[m->numchats] == NULL) | ||
1216 | return -1; | ||
1217 | |||
1218 | callback_groupmessage(temp[m->numchats], &group_message_function, m); | ||
1219 | callback_groupaction(temp[m->numchats], &group_action_function, m); | ||
1220 | callback_namelistchange(temp[m->numchats], &group_namelistchange_function, m); | ||
1221 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
1222 | set_nick(temp[m->numchats], m->name, m->name_length); | ||
1223 | ++m->numchats; | ||
1224 | return (m->numchats - 1); | ||
1225 | } | ||
1226 | |||
1227 | /* Delete a groupchat from the chats array. | ||
1228 | * | ||
1229 | * return 0 on success. | ||
1230 | * return -1 if failure. | ||
1231 | */ | ||
1232 | int del_groupchat(Messenger *m, int groupnumber) | ||
1233 | { | ||
1234 | if ((unsigned int)groupnumber >= m->numchats) | ||
1235 | return -1; | ||
1236 | |||
1237 | if (m->chats == NULL) | ||
1238 | return -1; | ||
1239 | |||
1240 | if (m->chats[groupnumber] == NULL) | ||
1241 | return -1; | ||
1242 | |||
1243 | kill_groupchat(m->chats[groupnumber]); | ||
1244 | m->chats[groupnumber] = NULL; | ||
1245 | |||
1246 | uint32_t i; | ||
1247 | |||
1248 | for (i = m->numchats; i != 0; --i) { | ||
1249 | if (m->chats[i - 1] != NULL) | ||
1250 | break; | ||
1251 | } | ||
1252 | |||
1253 | m->numchats = i; | ||
1254 | |||
1255 | if (i == 0) { | ||
1256 | free(m->chats); | ||
1257 | m->chats = NULL; | ||
1258 | } else { | ||
1259 | Group_Chat **temp = realloc(m->chats, sizeof(Group_Chat *) * i); | ||
1260 | |||
1261 | if (temp != NULL) | ||
1262 | m->chats = temp; | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | /* Copy the name of peernumber who is in groupnumber to name. | ||
1269 | * name must be at least MAX_NICK_BYTES long. | ||
1270 | * | ||
1271 | * return length of name if success | ||
1272 | * return -1 if failure | ||
1273 | */ | ||
1274 | int m_group_peername(const Messenger *m, int groupnumber, int peernumber, uint8_t *name) | ||
1275 | { | ||
1276 | if ((unsigned int)groupnumber >= m->numchats) | ||
1277 | return -1; | ||
1278 | |||
1279 | if (m->chats == NULL) | ||
1280 | return -1; | ||
1281 | |||
1282 | if (m->chats[groupnumber] == NULL) | ||
1283 | return -1; | ||
1284 | |||
1285 | return group_peername(m->chats[groupnumber], peernumber, name); | ||
1286 | } | ||
1287 | |||
1288 | /* Store the fact that we invited a specific friend. | ||
1289 | */ | ||
1290 | static void group_store_friendinvite(Messenger *m, int32_t friendnumber, int groupnumber) | ||
1291 | { | ||
1292 | /* Add 1 to the groupchat number because 0 (default value in invited_groups) is a valid groupchat number */ | ||
1293 | m->friendlist[friendnumber].invited_groups[m->friendlist[friendnumber].invited_groups_num % MAX_INVITED_GROUPS] = | ||
1294 | groupnumber + 1; | ||
1295 | ++m->friendlist[friendnumber].invited_groups_num; | ||
1296 | } | ||
1297 | |||
1298 | /* return 1 if that friend was invited to the group | ||
1299 | * return 0 if the friend was not or error. | ||
1300 | */ | ||
1301 | static uint8_t group_invited(const Messenger *m, int32_t friendnumber, int groupnumber) | ||
1302 | { | ||
1303 | |||
1304 | uint32_t i; | ||
1305 | uint16_t num = MAX_INVITED_GROUPS; | ||
1306 | |||
1307 | if (MAX_INVITED_GROUPS > m->friendlist[friendnumber].invited_groups_num) | ||
1308 | num = m->friendlist[friendnumber].invited_groups_num; | ||
1309 | |||
1310 | for (i = 0; i < num; ++i) { | ||
1311 | if (m->friendlist[friendnumber].invited_groups[i] == groupnumber + 1) { | ||
1312 | return 1; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | /* invite friendnumber to groupnumber | ||
1320 | * return 0 on success | ||
1321 | * return -1 on failure | ||
1322 | */ | ||
1323 | int invite_friend(Messenger *m, int32_t friendnumber, int groupnumber) | ||
1324 | { | ||
1325 | if (friend_not_valid(m, friendnumber) || (unsigned int)groupnumber >= m->numchats) | ||
1326 | return -1; | ||
1327 | |||
1328 | if (m->chats == NULL) | ||
1329 | return -1; | ||
1330 | |||
1331 | if (m->friendlist[friendnumber].status == NOFRIEND || m->chats[groupnumber] == NULL) | ||
1332 | return -1; | ||
1333 | |||
1334 | group_store_friendinvite(m, friendnumber, groupnumber); | ||
1335 | |||
1336 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, m->chats[groupnumber]->self_public_key, | ||
1337 | crypto_box_PUBLICKEYBYTES, 0) == 0) | ||
1338 | return -1; | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | |||
1344 | /* Join a group (you need to have been invited first.) | ||
1345 | * | ||
1346 | * returns group number on success | ||
1347 | * returns -1 on failure. | ||
1348 | */ | ||
1349 | int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_group_public_key) | ||
1350 | { | ||
1351 | if (friend_not_valid(m, friendnumber)) | ||
1352 | return -1; | ||
1353 | |||
1354 | uint8_t data[crypto_box_PUBLICKEYBYTES * 2]; | ||
1355 | int groupnum = add_groupchat(m); | ||
1356 | |||
1357 | if (groupnum == -1) | ||
1358 | return -1; | ||
1359 | |||
1360 | IP_Port friend_ip = get_friend_ipport(m, friendnumber); | ||
1361 | |||
1362 | if (friend_ip.ip.family == 0) { | ||
1363 | del_groupchat(m, groupnum); | ||
1364 | return -1; | ||
1365 | } | ||
1366 | |||
1367 | id_copy(data, friend_group_public_key); | ||
1368 | id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key); | ||
1369 | |||
1370 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data), 0)) { | ||
1371 | chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber), | ||
1372 | friend_group_public_key); //TODO: check if ip returned is zero? | ||
1373 | return groupnum; | ||
1374 | } | ||
1375 | |||
1376 | del_groupchat(m, groupnum); | ||
1377 | return -1; | ||
1378 | } | ||
1379 | |||
1380 | |||
1381 | /* send a group message | ||
1382 | * return 0 on success | ||
1383 | * return -1 on failure | ||
1384 | */ | ||
1385 | int group_message_send(const Messenger *m, int groupnumber, const uint8_t *message, uint32_t length) | ||
1386 | { | ||
1387 | if (groupnumber_not_valid(m, groupnumber)) | ||
1388 | return -1; | ||
1389 | |||
1390 | if (group_sendmessage(m->chats[groupnumber], message, length) > 0) | ||
1391 | return 0; | ||
1392 | |||
1393 | return -1; | ||
1394 | } | ||
1395 | |||
1396 | /* send a group action | ||
1397 | * return 0 on success | ||
1398 | * return -1 on failure | ||
1399 | */ | ||
1400 | int group_action_send(const Messenger *m, int groupnumber, const uint8_t *action, uint32_t length) | ||
1401 | { | ||
1402 | if (groupnumber_not_valid(m, groupnumber)) | ||
1403 | return -1; | ||
1404 | |||
1405 | if (group_sendaction(m->chats[groupnumber], action, length) > 0) | ||
1406 | return 0; | ||
1407 | |||
1408 | return -1; | ||
1409 | } | ||
1410 | |||
1411 | /* Return the number of peers in the group chat on success. | ||
1412 | * return -1 on failure | ||
1413 | */ | ||
1414 | int group_number_peers(const Messenger *m, int groupnumber) | ||
1415 | { | ||
1416 | if (groupnumber_not_valid(m, groupnumber)) | ||
1417 | return -1; | ||
1418 | |||
1419 | return group_numpeers(m->chats[groupnumber]); | ||
1420 | } | ||
1421 | |||
1422 | /* List all the peers in the group chat. | ||
1423 | * | ||
1424 | * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array. | ||
1425 | * | ||
1426 | * Copies the lengths of the names to lengths[length] | ||
1427 | * | ||
1428 | * returns the number of peers on success. | ||
1429 | * | ||
1430 | * return -1 on failure. | ||
1431 | */ | 1007 | */ |
1432 | int group_names(const Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], | 1008 | int send_group_invite_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) |
1433 | uint16_t length) | ||
1434 | { | 1009 | { |
1435 | if (groupnumber_not_valid(m, groupnumber)) | 1010 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, data, length, 0); |
1436 | return -1; | ||
1437 | |||
1438 | return group_client_names(m->chats[groupnumber], names, lengths, length); | ||
1439 | } | ||
1440 | |||
1441 | static int handle_group(void *object, IP_Port source, const uint8_t *packet, uint32_t length) | ||
1442 | { | ||
1443 | Messenger *m = object; | ||
1444 | |||
1445 | if (length < crypto_box_PUBLICKEYBYTES + 1) { | ||
1446 | return 1; | ||
1447 | } | ||
1448 | |||
1449 | uint32_t i; | ||
1450 | |||
1451 | for (i = 0; i < m->numchats; ++i) { | ||
1452 | if (m->chats[i] == NULL) | ||
1453 | continue; | ||
1454 | |||
1455 | if (id_equal(packet + 1, m->chats[i]->self_public_key)) | ||
1456 | return handle_groupchatpacket(m->chats[i], source, packet, length); | ||
1457 | } | ||
1458 | |||
1459 | return 1; | ||
1460 | } | ||
1461 | |||
1462 | static void do_allgroupchats(Messenger *m) | ||
1463 | { | ||
1464 | uint32_t i; | ||
1465 | |||
1466 | for (i = 0; i < m->numchats; ++i) { | ||
1467 | if (m->chats[i] != NULL) | ||
1468 | do_groupchat(m->chats[i]); | ||
1469 | } | ||
1470 | } | 1011 | } |
1471 | 1012 | ||
1472 | /****************FILE SENDING*****************/ | 1013 | /****************FILE SENDING*****************/ |
@@ -1669,8 +1210,9 @@ int file_data(const Messenger *m, int32_t friendnumber, uint8_t filenumber, cons | |||
1669 | if (m->friendlist[friendnumber].file_sending[filenumber].status != FILESTATUS_TRANSFERRING) | 1210 | if (m->friendlist[friendnumber].file_sending[filenumber].status != FILESTATUS_TRANSFERRING) |
1670 | return -1; | 1211 | return -1; |
1671 | 1212 | ||
1672 | /* Prevent file sending from filling up the entire buffer preventing messages from being sent. */ | 1213 | /* Prevent file sending from filling up the entire buffer preventing messages from being sent. TODO: remove */ |
1673 | if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE) | 1214 | if (crypto_num_free_sendqueue_slots(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, |
1215 | m->friendlist[friendnumber].friendcon_id)) < MIN_SLOTS_FREE) | ||
1674 | return -1; | 1216 | return -1; |
1675 | 1217 | ||
1676 | uint8_t packet[MAX_CRYPTO_DATA_SIZE]; | 1218 | uint8_t packet[MAX_CRYPTO_DATA_SIZE]; |
@@ -1876,10 +1418,8 @@ int send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uin | |||
1876 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) | 1418 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) |
1877 | return -1; | 1419 | return -1; |
1878 | 1420 | ||
1879 | if (m->friendlist[friendnumber].crypt_connection_id == -1) | 1421 | return send_lossy_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, |
1880 | return -1; | 1422 | m->friendlist[friendnumber].friendcon_id), data, length); |
1881 | |||
1882 | return send_lossy_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, data, length); | ||
1883 | } | 1423 | } |
1884 | 1424 | ||
1885 | static int handle_custom_lossless_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length) | 1425 | static int handle_custom_lossless_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length) |
@@ -1937,10 +1477,8 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const | |||
1937 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) | 1477 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) |
1938 | return -1; | 1478 | return -1; |
1939 | 1479 | ||
1940 | if (m->friendlist[friendnumber].crypt_connection_id == -1) | 1480 | if (write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, |
1941 | return -1; | 1481 | m->friendlist[friendnumber].friendcon_id), data, length, 1) == -1) { |
1942 | |||
1943 | if (write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, data, length, 1) == -1) { | ||
1944 | return -1; | 1482 | return -1; |
1945 | } else { | 1483 | } else { |
1946 | return 0; | 1484 | return 0; |
@@ -1967,31 +1505,6 @@ static void LANdiscovery(Messenger *m) | |||
1967 | } | 1505 | } |
1968 | } | 1506 | } |
1969 | 1507 | ||
1970 | static int handle_status(void *object, int i, uint8_t status); | ||
1971 | static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len); | ||
1972 | |||
1973 | static int handle_new_connections(void *object, New_Connection *n_c) | ||
1974 | { | ||
1975 | Messenger *m = object; | ||
1976 | int friend_id = getfriend_id(m, n_c->public_key); | ||
1977 | |||
1978 | if (friend_id != -1) { | ||
1979 | if (m->friendlist[friend_id].crypt_connection_id != -1) | ||
1980 | return -1; | ||
1981 | |||
1982 | int id = accept_crypto_connection(m->net_crypto, n_c); | ||
1983 | connection_status_handler(m->net_crypto, id, &handle_status, m, friend_id); | ||
1984 | connection_data_handler(m->net_crypto, id, &handle_packet, m, friend_id); | ||
1985 | connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friend_id); | ||
1986 | m->friendlist[friend_id].crypt_connection_id = id; | ||
1987 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); | ||
1988 | return 0; | ||
1989 | } | ||
1990 | |||
1991 | return -1; | ||
1992 | } | ||
1993 | |||
1994 | |||
1995 | /* Run this at startup. */ | 1508 | /* Run this at startup. */ |
1996 | Messenger *new_messenger(Messenger_Options *options) | 1509 | Messenger *new_messenger(Messenger_Options *options) |
1997 | { | 1510 | { |
@@ -2038,13 +1551,13 @@ Messenger *new_messenger(Messenger_Options *options) | |||
2038 | return NULL; | 1551 | return NULL; |
2039 | } | 1552 | } |
2040 | 1553 | ||
2041 | new_connection_handler(m->net_crypto, &handle_new_connections, m); | ||
2042 | |||
2043 | m->onion = new_onion(m->dht); | 1554 | m->onion = new_onion(m->dht); |
2044 | m->onion_a = new_onion_announce(m->dht); | 1555 | m->onion_a = new_onion_announce(m->dht); |
2045 | m->onion_c = new_onion_client(m->net_crypto); | 1556 | m->onion_c = new_onion_client(m->net_crypto); |
1557 | m->fr_c = new_friend_connections(m->onion_c); | ||
2046 | 1558 | ||
2047 | if (!(m->onion && m->onion_a && m->onion_c)) { | 1559 | if (!(m->onion && m->onion_a && m->onion_c)) { |
1560 | kill_friend_connections(m->fr_c); | ||
2048 | kill_onion(m->onion); | 1561 | kill_onion(m->onion); |
2049 | kill_onion_announce(m->onion_a); | 1562 | kill_onion_announce(m->onion_a); |
2050 | kill_onion_client(m->onion_c); | 1563 | kill_onion_client(m->onion_c); |
@@ -2061,22 +1574,15 @@ Messenger *new_messenger(Messenger_Options *options) | |||
2061 | set_nospam(&(m->fr), random_int()); | 1574 | set_nospam(&(m->fr), random_int()); |
2062 | set_filter_function(&(m->fr), &friend_already_added, m); | 1575 | set_filter_function(&(m->fr), &friend_already_added, m); |
2063 | 1576 | ||
2064 | networking_registerhandler(m->net, NET_PACKET_GROUP_CHATS, &handle_group, m); | ||
2065 | |||
2066 | return m; | 1577 | return m; |
2067 | } | 1578 | } |
2068 | 1579 | ||
2069 | /* Run this before closing shop. */ | 1580 | /* Run this before closing shop. */ |
2070 | void kill_messenger(Messenger *m) | 1581 | void kill_messenger(Messenger *m) |
2071 | { | 1582 | { |
2072 | /* FIXME TODO: ideally cleanupMessenger will mirror initMessenger. | 1583 | uint32_t i; |
2073 | * This requires the other modules to expose cleanup functions. | ||
2074 | */ | ||
2075 | uint32_t i, numchats = m->numchats; | ||
2076 | |||
2077 | for (i = 0; i < numchats; ++i) | ||
2078 | del_groupchat(m, i); | ||
2079 | 1584 | ||
1585 | kill_friend_connections(m->fr_c); | ||
2080 | kill_onion(m->onion); | 1586 | kill_onion(m->onion); |
2081 | kill_onion_announce(m->onion_a); | 1587 | kill_onion_announce(m->onion_a); |
2082 | kill_onion_client(m->onion_c); | 1588 | kill_onion_client(m->onion_c); |
@@ -2124,8 +1630,6 @@ static int handle_status(void *object, int i, uint8_t status) | |||
2124 | m->friendlist[i].statusmessage_sent = 0; | 1630 | m->friendlist[i].statusmessage_sent = 0; |
2125 | m->friendlist[i].ping_lastrecv = temp_time; | 1631 | m->friendlist[i].ping_lastrecv = temp_time; |
2126 | } else { /* Went offline. */ | 1632 | } else { /* Went offline. */ |
2127 | m->friendlist[i].crypt_connection_id = -1; | ||
2128 | |||
2129 | if (m->friendlist[i].status == FRIEND_ONLINE) { | 1633 | if (m->friendlist[i].status == FRIEND_ONLINE) { |
2130 | set_friend_status(m, i, FRIEND_CONFIRMED); | 1634 | set_friend_status(m, i, FRIEND_CONFIRMED); |
2131 | } | 1635 | } |
@@ -2425,11 +1929,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2425 | return -1; | 1929 | return -1; |
2426 | 1930 | ||
2427 | switch (packet_id) { | 1931 | switch (packet_id) { |
2428 | case PACKET_ID_ALIVE: { | ||
2429 | m->friendlist[i].ping_lastrecv = temp_time; | ||
2430 | break; | ||
2431 | } | ||
2432 | |||
2433 | case PACKET_ID_NICKNAME: { | 1932 | case PACKET_ID_NICKNAME: { |
2434 | if (data_length > MAX_NAME_LENGTH || data_length == 0) | 1933 | if (data_length > MAX_NAME_LENGTH || data_length == 0) |
2435 | break; | 1934 | break; |
@@ -2599,33 +2098,15 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2599 | } | 2098 | } |
2600 | 2099 | ||
2601 | case PACKET_ID_INVITE_GROUPCHAT: { | 2100 | case PACKET_ID_INVITE_GROUPCHAT: { |
2602 | if (data_length != crypto_box_PUBLICKEYBYTES) | 2101 | if (data_length == 0) |
2603 | break; | 2102 | break; |
2604 | 2103 | ||
2605 | if (m->group_invite) | 2104 | if (m->group_invite) |
2606 | (*m->group_invite)(m, i, data, m->group_invite_userdata); | 2105 | (*m->group_invite)(m, i, data, data_length); |
2607 | 2106 | ||
2608 | break; | 2107 | break; |
2609 | } | 2108 | } |
2610 | 2109 | ||
2611 | case PACKET_ID_JOIN_GROUPCHAT: { | ||
2612 | if (data_length != crypto_box_PUBLICKEYBYTES * 2) | ||
2613 | break; | ||
2614 | |||
2615 | int groupnum = group_num(m, data); | ||
2616 | |||
2617 | if (groupnum == -1) | ||
2618 | break; | ||
2619 | |||
2620 | if (!group_invited(m, i, groupnum)) | ||
2621 | break; | ||
2622 | |||
2623 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); | ||
2624 | /* This is just there to speedup joining. */ | ||
2625 | chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES); | ||
2626 | break; | ||
2627 | } | ||
2628 | |||
2629 | case PACKET_ID_FILE_SENDREQUEST: { | 2110 | case PACKET_ID_FILE_SENDREQUEST: { |
2630 | if (data_length < 1 + sizeof(uint64_t) + 1) | 2111 | if (data_length < 1 + sizeof(uint64_t) + 1) |
2631 | break; | 2112 | break; |
@@ -2720,27 +2201,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2720 | return 0; | 2201 | return 0; |
2721 | } | 2202 | } |
2722 | 2203 | ||
2723 | static int friend_new_connection(Messenger *m, int32_t friendnumber, const uint8_t *real_public_key) | ||
2724 | { | ||
2725 | if (friend_not_valid(m, friendnumber)) | ||
2726 | return -1; | ||
2727 | |||
2728 | if (m->friendlist[friendnumber].crypt_connection_id != -1) { | ||
2729 | return -1; | ||
2730 | } | ||
2731 | |||
2732 | int id = new_crypto_connection(m->net_crypto, real_public_key); | ||
2733 | |||
2734 | if (id == -1) | ||
2735 | return -1; | ||
2736 | |||
2737 | m->friendlist[friendnumber].crypt_connection_id = id; | ||
2738 | connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber); | ||
2739 | connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber); | ||
2740 | connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friendnumber); | ||
2741 | return 0; | ||
2742 | } | ||
2743 | |||
2744 | /* TODO: Make this function not suck. */ | 2204 | /* TODO: Make this function not suck. */ |
2745 | void do_friends(Messenger *m) | 2205 | void do_friends(Messenger *m) |
2746 | { | 2206 | { |
@@ -2767,32 +2227,6 @@ void do_friends(Messenger *m) | |||
2767 | */ | 2227 | */ |
2768 | check_friend_request_timed_out(m, i, temp_time); | 2228 | check_friend_request_timed_out(m, i, temp_time); |
2769 | } | 2229 | } |
2770 | |||
2771 | friend_new_connection(m, i, m->friendlist[i].client_id); | ||
2772 | } | ||
2773 | |||
2774 | if (m->friendlist[i].crypt_connection_id != -1) { | ||
2775 | uint8_t dht_public_key1[crypto_box_PUBLICKEYBYTES]; | ||
2776 | uint64_t timestamp1 = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key1); | ||
2777 | uint8_t dht_public_key2[crypto_box_PUBLICKEYBYTES]; | ||
2778 | uint64_t timestamp2 = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key2); | ||
2779 | |||
2780 | if (timestamp1 > timestamp2) { | ||
2781 | set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key1, timestamp1); | ||
2782 | } else if (timestamp1 < timestamp2) { | ||
2783 | onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key2, timestamp2); | ||
2784 | } | ||
2785 | |||
2786 | uint8_t direct_connected; | ||
2787 | unsigned int status = crypto_connection_status(m->net_crypto, m->friendlist[i].crypt_connection_id, &direct_connected); | ||
2788 | |||
2789 | if (direct_connected == 0 || status == CRYPTO_CONN_COOKIE_REQUESTING) { | ||
2790 | IP_Port friendip; | ||
2791 | |||
2792 | if (onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip) == 1) { | ||
2793 | set_direct_ip_port(m->net_crypto, m->friendlist[i].crypt_connection_id, friendip); | ||
2794 | } | ||
2795 | } | ||
2796 | } | 2230 | } |
2797 | 2231 | ||
2798 | if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ | 2232 | if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ |
@@ -2821,17 +2255,6 @@ void do_friends(Messenger *m) | |||
2821 | m->friendlist[i].user_istyping_sent = 1; | 2255 | m->friendlist[i].user_istyping_sent = 1; |
2822 | } | 2256 | } |
2823 | 2257 | ||
2824 | if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { | ||
2825 | send_ping(m, i); | ||
2826 | } | ||
2827 | |||
2828 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | ||
2829 | /* If we stopped receiving ping packets, kill it. */ | ||
2830 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | ||
2831 | m->friendlist[i].crypt_connection_id = -1; | ||
2832 | set_friend_status(m, i, FRIEND_CONFIRMED); | ||
2833 | } | ||
2834 | |||
2835 | if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) { | 2258 | if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) { |
2836 | send_relays(m, i); | 2259 | send_relays(m, i); |
2837 | } | 2260 | } |
@@ -2901,8 +2324,8 @@ void do_messenger(Messenger *m) | |||
2901 | 2324 | ||
2902 | do_net_crypto(m->net_crypto); | 2325 | do_net_crypto(m->net_crypto); |
2903 | do_onion_client(m->onion_c); | 2326 | do_onion_client(m->onion_c); |
2327 | do_friend_connections(m->fr_c); | ||
2904 | do_friends(m); | 2328 | do_friends(m); |
2905 | do_allgroupchats(m); | ||
2906 | LANdiscovery(m); | 2329 | LANdiscovery(m); |
2907 | 2330 | ||
2908 | #ifdef LOGGING | 2331 | #ifdef LOGGING |
@@ -2913,16 +2336,6 @@ void do_messenger(Messenger *m) | |||
2913 | Assoc_status(m->dht->assoc); | 2336 | Assoc_status(m->dht->assoc); |
2914 | #endif | 2337 | #endif |
2915 | 2338 | ||
2916 | if (m->numchats > 0) { | ||
2917 | size_t c; | ||
2918 | |||
2919 | for (c = 0; c < m->numchats; c++) { | ||
2920 | if (m->chats[c]) | ||
2921 | Assoc_status(m->chats[c]->assoc); | ||
2922 | } | ||
2923 | } | ||
2924 | |||
2925 | |||
2926 | lastdump = unix_time(); | 2339 | lastdump = unix_time(); |
2927 | uint32_t client, last_pinged; | 2340 | uint32_t client, last_pinged; |
2928 | 2341 | ||
@@ -2992,8 +2405,8 @@ void do_messenger(Messenger *m) | |||
2992 | if (ping_lastrecv > 999) | 2405 | if (ping_lastrecv > 999) |
2993 | ping_lastrecv = 999; | 2406 | ping_lastrecv = 999; |
2994 | 2407 | ||
2995 | LOGGER_INFO("F[%2u:%2u] <%s> %02i [%03u] %s", | 2408 | LOGGER_INFO("F[%2u:%2u] <%s> [%03u] %s", |
2996 | dht2m[friend], friend, msgfptr->name, msgfptr->crypt_connection_id, | 2409 | dht2m[friend], friend, msgfptr->name, |
2997 | ping_lastrecv, ID2String(msgfptr->client_id)); | 2410 | ping_lastrecv, ID2String(msgfptr->client_id)); |
2998 | } else { | 2411 | } else { |
2999 | LOGGER_INFO("F[--:%2u] %s", friend, ID2String(dhtfptr->client_id)); | 2412 | LOGGER_INFO("F[--:%2u] %s", friend, ID2String(dhtfptr->client_id)); |
@@ -3429,51 +2842,3 @@ int get_friendlist(const Messenger *m, int32_t **out_list, uint32_t *out_list_le | |||
3429 | 2842 | ||
3430 | return 0; | 2843 | return 0; |
3431 | } | 2844 | } |
3432 | |||
3433 | /* Return the number of chats in the instance m. | ||
3434 | * You should use this to determine how much memory to allocate | ||
3435 | * for copy_chatlist. */ | ||
3436 | uint32_t count_chatlist(const Messenger *m) | ||
3437 | { | ||
3438 | uint32_t ret = 0; | ||
3439 | uint32_t i; | ||
3440 | |||
3441 | for (i = 0; i < m->numchats; i++) { | ||
3442 | if (m->chats[i]) { | ||
3443 | ret++; | ||
3444 | } | ||
3445 | } | ||
3446 | |||
3447 | return ret; | ||
3448 | } | ||
3449 | |||
3450 | /* Copy a list of valid chat IDs into the array out_list. | ||
3451 | * If out_list is NULL, returns 0. | ||
3452 | * Otherwise, returns the number of elements copied. | ||
3453 | * If the array was too small, the contents | ||
3454 | * of out_list will be truncated to list_size. */ | ||
3455 | uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size) | ||
3456 | { | ||
3457 | if (!out_list) | ||
3458 | return 0; | ||
3459 | |||
3460 | if (m->numchats == 0) { | ||
3461 | return 0; | ||
3462 | } | ||
3463 | |||
3464 | uint32_t i; | ||
3465 | uint32_t ret = 0; | ||
3466 | |||
3467 | for (i = 0; i < m->numchats; i++) { | ||
3468 | if (ret >= list_size) { | ||
3469 | break; /* Abandon ship */ | ||
3470 | } | ||
3471 | |||
3472 | if (m->chats[i]) { | ||
3473 | out_list[ret] = i; | ||
3474 | ret++; | ||
3475 | } | ||
3476 | } | ||
3477 | |||
3478 | return ret; | ||
3479 | } | ||