diff options
author | irungentoo <irungentoo@gmail.com> | 2013-12-06 22:51:17 -0500 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-12-06 22:51:17 -0500 |
commit | 7cd43ecc76cd08c5c2c16b9f9169908ef4674762 (patch) | |
tree | 5b5ba5b61b5591222e2c4682d750c71469f1086c /toxcore/Messenger.c | |
parent | 1473126f9a459f31f4c33262a21987a3bb7dde65 (diff) | |
parent | 4207b73ca9432aeacfa72e5b7610cbb0ba9324c8 (diff) |
Merge branch 'master' into harden
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r-- | toxcore/Messenger.c | 339 |
1 files changed, 270 insertions, 69 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 08e3c70c..32234784 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -26,9 +26,11 @@ | |||
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #include "Messenger.h" | 28 | #include "Messenger.h" |
29 | #include "assoc.h" | ||
29 | #include "network.h" | 30 | #include "network.h" |
30 | #include "util.h" | 31 | #include "util.h" |
31 | 32 | ||
33 | |||
32 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 34 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
33 | 35 | ||
34 | 36 | ||
@@ -435,6 +437,10 @@ int setname(Messenger *m, uint8_t *name, uint16_t length) | |||
435 | for (i = 0; i < m->numfriends; ++i) | 437 | for (i = 0; i < m->numfriends; ++i) |
436 | m->friendlist[i].name_sent = 0; | 438 | m->friendlist[i].name_sent = 0; |
437 | 439 | ||
440 | for (i = 0; i < m->numchats; i++) | ||
441 | if (m->chats[i] != NULL) | ||
442 | set_nick(m->chats[i], name, length); /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
443 | |||
438 | return 0; | 444 | return 0; |
439 | } | 445 | } |
440 | 446 | ||
@@ -701,6 +707,23 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint | |||
701 | 707 | ||
702 | /**********GROUP CHATS************/ | 708 | /**********GROUP CHATS************/ |
703 | 709 | ||
710 | /* return 1 if the groupnumber is not valid. | ||
711 | * return 0 if the groupnumber is valid. | ||
712 | */ | ||
713 | static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber) | ||
714 | { | ||
715 | if ((unsigned int)groupnumber >= m->numchats) | ||
716 | return 1; | ||
717 | |||
718 | if (m->chats == NULL) | ||
719 | return 1; | ||
720 | |||
721 | if (m->chats[groupnumber] == NULL) | ||
722 | return 1; | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | |||
704 | /* returns valid ip port of connected friend on success | 727 | /* returns valid ip port of connected friend on success |
705 | * returns zeroed out IP_Port on failure | 728 | * returns zeroed out IP_Port on failure |
706 | */ | 729 | */ |
@@ -728,8 +751,9 @@ static int group_num(Messenger *m, uint8_t *group_public_key) | |||
728 | uint32_t i; | 751 | uint32_t i; |
729 | 752 | ||
730 | for (i = 0; i < m->numchats; ++i) { | 753 | for (i = 0; i < m->numchats; ++i) { |
731 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) | 754 | if (m->chats[i] != NULL) |
732 | return i; | 755 | if (id_equal(m->chats[i]->self_public_key, group_public_key)) |
756 | return i; | ||
733 | } | 757 | } |
734 | 758 | ||
735 | return -1; | 759 | return -1; |
@@ -755,20 +779,51 @@ void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, | |||
755 | m->group_message = function; | 779 | m->group_message = function; |
756 | m->group_message_userdata = userdata; | 780 | m->group_message_userdata = userdata; |
757 | } | 781 | } |
758 | static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata) | 782 | |
783 | /* Set callback function for peer name list changes. | ||
784 | * | ||
785 | * It gets called every time the name list changes(new peer/name, deleted peer) | ||
786 | * Function(Tox *tox, int groupnumber, void *userdata) | ||
787 | */ | ||
788 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), void *userdata) | ||
759 | { | 789 | { |
760 | Messenger *m = userdata; | 790 | m->group_namelistchange = function; |
761 | uint32_t i; | 791 | m->group_namelistchange_userdata = userdata; |
792 | } | ||
762 | 793 | ||
794 | static int get_chat_num(Messenger *m, Group_Chat *chat) | ||
795 | { | ||
796 | uint32_t i; | ||
763 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this | 797 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this |
764 | if (m->chats[i] == chat) | 798 | if (m->chats[i] == chat) |
765 | break; | 799 | return i; |
766 | } | 800 | } |
801 | return -1; | ||
802 | } | ||
803 | |||
804 | static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata) | ||
805 | { | ||
806 | Messenger *m = userdata; | ||
807 | int i = get_chat_num(m, chat); | ||
808 | if (i == -1) | ||
809 | return; | ||
767 | 810 | ||
768 | if (m->group_message) | 811 | if (m->group_message) |
769 | (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); | 812 | (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); |
770 | } | 813 | } |
771 | 814 | ||
815 | static void group_namelistchange_function(Group_Chat *chat, int peer, uint8_t change, void *userdata) | ||
816 | { | ||
817 | Messenger *m = userdata; | ||
818 | int i = get_chat_num(m, chat); | ||
819 | if (i == -1) | ||
820 | return; | ||
821 | |||
822 | if (m->group_namelistchange) | ||
823 | (*m->group_namelistchange)(m, i, peer, change, m->group_namelistchange_userdata); | ||
824 | } | ||
825 | |||
826 | |||
772 | /* Creates a new groupchat and puts it in the chats array. | 827 | /* Creates a new groupchat and puts it in the chats array. |
773 | * | 828 | * |
774 | * return group number on success. | 829 | * return group number on success. |
@@ -786,6 +841,9 @@ int add_groupchat(Messenger *m) | |||
786 | return -1; | 841 | return -1; |
787 | 842 | ||
788 | callback_groupmessage(newchat, &group_message_function, m); | 843 | callback_groupmessage(newchat, &group_message_function, m); |
844 | callback_namelistchange(newchat, &group_namelistchange_function, m); | ||
845 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
846 | set_nick(newchat, m->name, m->name_length); | ||
789 | m->chats[i] = newchat; | 847 | m->chats[i] = newchat; |
790 | return i; | 848 | return i; |
791 | } | 849 | } |
@@ -804,6 +862,9 @@ int add_groupchat(Messenger *m) | |||
804 | 862 | ||
805 | m->chats = temp; | 863 | m->chats = temp; |
806 | callback_groupmessage(temp[m->numchats], &group_message_function, m); | 864 | callback_groupmessage(temp[m->numchats], &group_message_function, m); |
865 | callback_namelistchange(temp[m->numchats], &group_namelistchange_function, m); | ||
866 | /* TODO: remove this (group nicks should not be tied to the global one) */ | ||
867 | set_nick(temp[m->numchats], m->name, m->name_length); | ||
807 | ++m->numchats; | 868 | ++m->numchats; |
808 | return (m->numchats - 1); | 869 | return (m->numchats - 1); |
809 | } | 870 | } |
@@ -953,6 +1014,7 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_ | |||
953 | return -1; | 1014 | return -1; |
954 | } | 1015 | } |
955 | 1016 | ||
1017 | |||
956 | /* send a group message | 1018 | /* send a group message |
957 | * return 0 on success | 1019 | * return 0 on success |
958 | * return -1 on failure | 1020 | * return -1 on failure |
@@ -960,13 +1022,7 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_ | |||
960 | 1022 | ||
961 | int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length) | 1023 | int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length) |
962 | { | 1024 | { |
963 | if ((unsigned int)groupnumber >= m->numchats) | 1025 | if (groupnumber_not_valid(m, groupnumber)) |
964 | return -1; | ||
965 | |||
966 | if (m->chats == NULL) | ||
967 | return -1; | ||
968 | |||
969 | if (m->chats[groupnumber] == NULL) | ||
970 | return -1; | 1026 | return -1; |
971 | 1027 | ||
972 | if (group_sendmessage(m->chats[groupnumber], message, length) > 0) | 1028 | if (group_sendmessage(m->chats[groupnumber], message, length) > 0) |
@@ -975,6 +1031,33 @@ int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t | |||
975 | return -1; | 1031 | return -1; |
976 | } | 1032 | } |
977 | 1033 | ||
1034 | /* Return the number of peers in the group chat on success. | ||
1035 | * return -1 on failure | ||
1036 | */ | ||
1037 | int group_number_peers(Messenger *m, int groupnumber) | ||
1038 | { | ||
1039 | if (groupnumber_not_valid(m, groupnumber)) | ||
1040 | return -1; | ||
1041 | |||
1042 | return group_numpeers(m->chats[groupnumber]); | ||
1043 | } | ||
1044 | |||
1045 | /* List all the peers in the group chat. | ||
1046 | * | ||
1047 | * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array. | ||
1048 | * | ||
1049 | * returns the number of peers on success. | ||
1050 | * | ||
1051 | * return -1 on failure. | ||
1052 | */ | ||
1053 | int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t length) | ||
1054 | { | ||
1055 | if (groupnumber_not_valid(m, groupnumber)) | ||
1056 | return -1; | ||
1057 | |||
1058 | return group_client_names(m->chats[groupnumber], names, length); | ||
1059 | } | ||
1060 | |||
978 | static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 1061 | static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
979 | { | 1062 | { |
980 | Messenger *m = object; | 1063 | Messenger *m = object; |
@@ -1078,7 +1161,7 @@ int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_ | |||
1078 | int new_filesender(Messenger *m, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) | 1161 | int new_filesender(Messenger *m, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) |
1079 | { | 1162 | { |
1080 | if (friend_not_valid(m, friendnumber)) | 1163 | if (friend_not_valid(m, friendnumber)) |
1081 | return 0; | 1164 | return -1; |
1082 | 1165 | ||
1083 | uint32_t i; | 1166 | uint32_t i; |
1084 | 1167 | ||
@@ -1102,28 +1185,28 @@ int new_filesender(Messenger *m, int friendnumber, uint64_t filesize, uint8_t *f | |||
1102 | /* Send a file control request. | 1185 | /* Send a file control request. |
1103 | * send_receive is 0 if we want the control packet to target a sending file, 1 if it targets a receiving file. | 1186 | * send_receive is 0 if we want the control packet to target a sending file, 1 if it targets a receiving file. |
1104 | * | 1187 | * |
1105 | * return 1 on success | 1188 | * return 0 on success |
1106 | * return 0 on failure | 1189 | * return -1 on failure |
1107 | */ | 1190 | */ |
1108 | int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 1191 | int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, |
1109 | uint8_t *data, uint16_t length) | 1192 | uint8_t *data, uint16_t length) |
1110 | { | 1193 | { |
1111 | if (length > MAX_DATA_SIZE - 3) | 1194 | if (length > MAX_DATA_SIZE - 3) |
1112 | return 0; | 1195 | return -1; |
1113 | 1196 | ||
1114 | if (friend_not_valid(m, friendnumber)) | 1197 | if (friend_not_valid(m, friendnumber)) |
1115 | return 0; | 1198 | return -1; |
1116 | 1199 | ||
1117 | if (send_receive == 1) { | 1200 | if (send_receive == 1) { |
1118 | if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE) | 1201 | if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE) |
1119 | return 0; | 1202 | return -1; |
1120 | } else { | 1203 | } else { |
1121 | if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE) | 1204 | if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE) |
1122 | return 0; | 1205 | return -1; |
1123 | } | 1206 | } |
1124 | 1207 | ||
1125 | if (send_receive > 1) | 1208 | if (send_receive > 1) |
1126 | return 0; | 1209 | return -1; |
1127 | 1210 | ||
1128 | uint8_t packet[MAX_DATA_SIZE]; | 1211 | uint8_t packet[MAX_DATA_SIZE]; |
1129 | packet[0] = send_receive; | 1212 | packet[0] = send_receive; |
@@ -1133,7 +1216,7 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f | |||
1133 | 1216 | ||
1134 | if (message_id == FILECONTROL_RESUME_BROKEN) { | 1217 | if (message_id == FILECONTROL_RESUME_BROKEN) { |
1135 | if (length != sizeof(uint64_t)) | 1218 | if (length != sizeof(uint64_t)) |
1136 | return 0; | 1219 | return -1; |
1137 | 1220 | ||
1138 | uint8_t remaining[sizeof(uint64_t)]; | 1221 | uint8_t remaining[sizeof(uint64_t)]; |
1139 | memcpy(remaining, data, sizeof(uint64_t)); | 1222 | memcpy(remaining, data, sizeof(uint64_t)); |
@@ -1181,32 +1264,32 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f | |||
1181 | break; | 1264 | break; |
1182 | } | 1265 | } |
1183 | 1266 | ||
1184 | return 1; | ||
1185 | } else { | ||
1186 | return 0; | 1267 | return 0; |
1268 | } else { | ||
1269 | return -1; | ||
1187 | } | 1270 | } |
1188 | } | 1271 | } |
1189 | 1272 | ||
1190 | #define MIN_SLOTS_FREE 4 | 1273 | #define MIN_SLOTS_FREE 4 |
1191 | /* Send file data. | 1274 | /* Send file data. |
1192 | * | 1275 | * |
1193 | * return 1 on success | 1276 | * return 0 on success |
1194 | * return 0 on failure | 1277 | * return -1 on failure |
1195 | */ | 1278 | */ |
1196 | int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) | 1279 | int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) |
1197 | { | 1280 | { |
1198 | if (length > MAX_DATA_SIZE - 1) | 1281 | if (length > MAX_DATA_SIZE - 1) |
1199 | return 0; | 1282 | return -1; |
1200 | 1283 | ||
1201 | if (friend_not_valid(m, friendnumber)) | 1284 | if (friend_not_valid(m, friendnumber)) |
1202 | return 0; | 1285 | return -1; |
1203 | 1286 | ||
1204 | if (m->friendlist[friendnumber].file_sending[filenumber].status != FILESTATUS_TRANSFERRING) | 1287 | if (m->friendlist[friendnumber].file_sending[filenumber].status != FILESTATUS_TRANSFERRING) |
1205 | return 0; | 1288 | return -1; |
1206 | 1289 | ||
1207 | /* Prevent file sending from filling up the entire buffer preventing messages from being sent. */ | 1290 | /* Prevent file sending from filling up the entire buffer preventing messages from being sent. */ |
1208 | if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE) | 1291 | if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE) |
1209 | return 0; | 1292 | return -1; |
1210 | 1293 | ||
1211 | uint8_t packet[MAX_DATA_SIZE]; | 1294 | uint8_t packet[MAX_DATA_SIZE]; |
1212 | packet[0] = filenumber; | 1295 | packet[0] = filenumber; |
@@ -1214,10 +1297,10 @@ int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, | |||
1214 | 1297 | ||
1215 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_DATA, packet, length + 1)) { | 1298 | if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_DATA, packet, length + 1)) { |
1216 | m->friendlist[friendnumber].file_sending[filenumber].transferred += length; | 1299 | m->friendlist[friendnumber].file_sending[filenumber].transferred += length; |
1217 | return 1; | 1300 | return 0; |
1218 | } | 1301 | } |
1219 | 1302 | ||
1220 | return 0; | 1303 | return -1; |
1221 | 1304 | ||
1222 | } | 1305 | } |
1223 | 1306 | ||
@@ -1371,6 +1454,17 @@ int m_msi_packet(Messenger *m, int friendnumber, uint8_t *data, uint16_t length) | |||
1371 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); | 1454 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); |
1372 | } | 1455 | } |
1373 | 1456 | ||
1457 | /* Function to filter out some friend requests*/ | ||
1458 | static int friend_already_added(uint8_t *client_id, void *data) | ||
1459 | { | ||
1460 | Messenger *m = data; | ||
1461 | |||
1462 | if (getfriend_id(m, client_id) == -1) | ||
1463 | return 0; | ||
1464 | |||
1465 | return -1; | ||
1466 | } | ||
1467 | |||
1374 | /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ | 1468 | /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ |
1375 | static void LANdiscovery(Messenger *m) | 1469 | static void LANdiscovery(Messenger *m) |
1376 | { | 1470 | { |
@@ -1420,6 +1514,8 @@ Messenger *new_messenger(uint8_t ipv6enabled) | |||
1420 | friendreq_init(&(m->fr), m->net_crypto); | 1514 | friendreq_init(&(m->fr), m->net_crypto); |
1421 | LANdiscovery_init(m->dht); | 1515 | LANdiscovery_init(m->dht); |
1422 | set_nospam(&(m->fr), random_int()); | 1516 | set_nospam(&(m->fr), random_int()); |
1517 | set_filter_function(&(m->fr), &friend_already_added, m); | ||
1518 | |||
1423 | networking_registerhandler(m->net, NET_PACKET_GROUP_CHATS, &handle_group, m); | 1519 | networking_registerhandler(m->net, NET_PACKET_GROUP_CHATS, &handle_group, m); |
1424 | 1520 | ||
1425 | return m; | 1521 | return m; |
@@ -1431,6 +1527,10 @@ void kill_messenger(Messenger *m) | |||
1431 | /* FIXME TODO: ideally cleanupMessenger will mirror initMessenger. | 1527 | /* FIXME TODO: ideally cleanupMessenger will mirror initMessenger. |
1432 | * This requires the other modules to expose cleanup functions. | 1528 | * This requires the other modules to expose cleanup functions. |
1433 | */ | 1529 | */ |
1530 | uint32_t i, numchats = m->numchats; | ||
1531 | for (i = 0; i < numchats; ++i) | ||
1532 | del_groupchat(m, i); | ||
1533 | |||
1434 | kill_DHT(m->dht); | 1534 | kill_DHT(m->dht); |
1435 | kill_net_crypto(m->net_crypto); | 1535 | kill_net_crypto(m->net_crypto); |
1436 | kill_networking(m->net); | 1536 | kill_networking(m->net); |
@@ -1438,6 +1538,24 @@ void kill_messenger(Messenger *m) | |||
1438 | free(m); | 1538 | free(m); |
1439 | } | 1539 | } |
1440 | 1540 | ||
1541 | /* Check for and handle a timed-out friend request. If the request has | ||
1542 | * timed-out then the friend status is set back to FRIEND_ADDED. | ||
1543 | * i: friendlist index of the timed-out friend | ||
1544 | * t: time | ||
1545 | */ | ||
1546 | static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t) | ||
1547 | { | ||
1548 | Friend *f = &m->friendlist[i]; | ||
1549 | |||
1550 | if (f->friendrequest_lastsent + f->friendrequest_timeout < t) { | ||
1551 | set_friend_status(m, i, FRIEND_ADDED); | ||
1552 | /* Double the default timeout everytime if friendrequest is assumed | ||
1553 | * to have been sent unsuccessfully. | ||
1554 | */ | ||
1555 | f->friendrequest_timeout *= 2; | ||
1556 | } | ||
1557 | } | ||
1558 | |||
1441 | /* TODO: Make this function not suck. */ | 1559 | /* TODO: Make this function not suck. */ |
1442 | void do_friends(Messenger *m) | 1560 | void do_friends(Messenger *m) |
1443 | { | 1561 | { |
@@ -1465,13 +1583,7 @@ void do_friends(Messenger *m) | |||
1465 | /* If we didn't connect to friend after successfully sending him a friend request the request is deemed | 1583 | /* If we didn't connect to friend after successfully sending him a friend request the request is deemed |
1466 | * unsuccessful so we set the status back to FRIEND_ADDED and try again. | 1584 | * unsuccessful so we set the status back to FRIEND_ADDED and try again. |
1467 | */ | 1585 | */ |
1468 | if (m->friendlist[i].friendrequest_lastsent + m->friendlist[i].friendrequest_timeout < temp_time) { | 1586 | check_friend_request_timed_out(m, i, temp_time); |
1469 | set_friend_status(m, i, FRIEND_ADDED); | ||
1470 | /* Double the default timeout everytime if friendrequest is assumed to have been | ||
1471 | * sent unsuccessfully. | ||
1472 | */ | ||
1473 | m->friendlist[i].friendrequest_timeout *= 2; | ||
1474 | } | ||
1475 | } | 1587 | } |
1476 | 1588 | ||
1477 | IP_Port friendip; | 1589 | IP_Port friendip; |
@@ -1539,12 +1651,15 @@ void do_friends(Messenger *m) | |||
1539 | if (data_length >= MAX_NAME_LENGTH || data_length == 0) | 1651 | if (data_length >= MAX_NAME_LENGTH || data_length == 0) |
1540 | break; | 1652 | break; |
1541 | 1653 | ||
1542 | memcpy(m->friendlist[i].name, data, data_length); | 1654 | /* Make sure the NULL terminator is present. */ |
1543 | m->friendlist[i].name_length = data_length; | 1655 | data[data_length - 1] = 0; |
1544 | m->friendlist[i].name[data_length - 1] = 0; /* Make sure the NULL terminator is present. */ | ||
1545 | 1656 | ||
1657 | /* inform of namechange before we overwrite the old name */ | ||
1546 | if (m->friend_namechange) | 1658 | if (m->friend_namechange) |
1547 | m->friend_namechange(m, i, m->friendlist[i].name, data_length, m->friend_namechange_userdata); | 1659 | m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata); |
1660 | |||
1661 | memcpy(m->friendlist[i].name, data, data_length); | ||
1662 | m->friendlist[i].name_length = data_length; | ||
1548 | 1663 | ||
1549 | break; | 1664 | break; |
1550 | } | 1665 | } |
@@ -1658,7 +1773,7 @@ void do_friends(Messenger *m) | |||
1658 | break; | 1773 | break; |
1659 | 1774 | ||
1660 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); | 1775 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); |
1661 | 1776 | chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES); | |
1662 | break; | 1777 | break; |
1663 | } | 1778 | } |
1664 | 1779 | ||
@@ -1808,6 +1923,18 @@ void do_messenger(Messenger *m) | |||
1808 | 1923 | ||
1809 | if (unix_time() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { | 1924 | if (unix_time() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) { |
1810 | loglog(" = = = = = = = = \n"); | 1925 | loglog(" = = = = = = = = \n"); |
1926 | Assoc_status(m->dht->assoc); | ||
1927 | |||
1928 | if (m->numchats > 0) { | ||
1929 | size_t c; | ||
1930 | |||
1931 | for (c = 0; c < m->numchats; c++) { | ||
1932 | loglog("---------------- \n"); | ||
1933 | Assoc_status(m->chats[c]->assoc); | ||
1934 | } | ||
1935 | } | ||
1936 | |||
1937 | loglog(" = = = = = = = = \n"); | ||
1811 | 1938 | ||
1812 | lastdump = unix_time(); | 1939 | lastdump = unix_time(); |
1813 | uint32_t client, last_pinged; | 1940 | uint32_t client, last_pinged; |
@@ -1833,7 +1960,30 @@ void do_messenger(Messenger *m) | |||
1833 | 1960 | ||
1834 | loglog(" = = = = = = = = \n"); | 1961 | loglog(" = = = = = = = = \n"); |
1835 | 1962 | ||
1836 | uint32_t num_friends = MIN(m->numfriends, m->dht->num_friends); | 1963 | uint32_t friend, dhtfriend; |
1964 | |||
1965 | /* dht contains additional "friends" (requests) */ | ||
1966 | uint32_t num_dhtfriends = m->dht->num_friends; | ||
1967 | int32_t m2dht[num_dhtfriends]; | ||
1968 | int32_t dht2m[num_dhtfriends]; | ||
1969 | |||
1970 | for (friend = 0; friend < num_dhtfriends; friend++) { | ||
1971 | m2dht[friend] = -1; | ||
1972 | dht2m[friend] = -1; | ||
1973 | |||
1974 | if (friend >= m->numfriends) | ||
1975 | continue; | ||
1976 | |||
1977 | for (dhtfriend = 0; dhtfriend < m->dht->num_friends; dhtfriend++) | ||
1978 | if (id_equal(m->friendlist[friend].client_id, m->dht->friends_list[dhtfriend].client_id)) { | ||
1979 | m2dht[friend] = dhtfriend; | ||
1980 | break; | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | for (friend = 0; friend < num_dhtfriends; friend++) | ||
1985 | if (m2dht[friend] >= 0) | ||
1986 | dht2m[m2dht[friend]] = friend; | ||
1837 | 1987 | ||
1838 | if (m->numfriends != m->dht->num_friends) { | 1988 | if (m->numfriends != m->dht->num_friends) { |
1839 | sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n", | 1989 | sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n", |
@@ -1841,33 +1991,33 @@ void do_messenger(Messenger *m) | |||
1841 | loglog(logbuffer); | 1991 | loglog(logbuffer); |
1842 | } | 1992 | } |
1843 | 1993 | ||
1844 | uint32_t friend, ping_lastrecv; | 1994 | uint32_t ping_lastrecv; |
1845 | 1995 | Friend *msgfptr; | |
1846 | for (friend = 0; friend < num_friends; friend++) { | 1996 | DHT_Friend *dhtfptr; |
1847 | Friend *msgfptr = &m->friendlist[friend]; | ||
1848 | DHT_Friend *dhtfptr = &m->dht->friends_list[friend]; | ||
1849 | 1997 | ||
1850 | if (memcmp(msgfptr->client_id, dhtfptr->client_id, CLIENT_ID_SIZE)) { | 1998 | for (friend = 0; friend < num_dhtfriends; friend++) { |
1851 | if (sizeof(logbuffer) > 2 * CLIENT_ID_SIZE + 64) { | 1999 | if (dht2m[friend] >= 0) |
1852 | sprintf(logbuffer, "F[%2u] ID(m) %s != ID(d) ", friend, | 2000 | msgfptr = &m->friendlist[dht2m[friend]]; |
1853 | ID2String(msgfptr->client_id)); | 2001 | else |
1854 | strcat(logbuffer + strlen(logbuffer), ID2String(dhtfptr->client_id)); | 2002 | msgfptr = NULL; |
1855 | strcat(logbuffer + strlen(logbuffer), "\n"); | ||
1856 | } else | ||
1857 | sprintf(logbuffer, "F[%2u] ID(m) != ID(d) ", friend); | ||
1858 | 2003 | ||
1859 | loglog(logbuffer); | 2004 | dhtfptr = &m->dht->friends_list[friend]; |
1860 | } | ||
1861 | 2005 | ||
1862 | ping_lastrecv = lastdump - msgfptr->ping_lastrecv; | 2006 | if (msgfptr) { |
2007 | ping_lastrecv = lastdump - msgfptr->ping_lastrecv; | ||
1863 | 2008 | ||
1864 | if (ping_lastrecv > 999) | 2009 | if (ping_lastrecv > 999) |
1865 | ping_lastrecv = 999; | 2010 | ping_lastrecv = 999; |
1866 | 2011 | ||
1867 | snprintf(logbuffer, sizeof(logbuffer), "F[%2u] <%s> %02u [%03u] %s\n", | 2012 | snprintf(logbuffer, sizeof(logbuffer), "F[%2u:%2u] <%s> %02i [%03u] %s\n", |
1868 | friend, msgfptr->name, msgfptr->crypt_connection_id, | 2013 | dht2m[friend], friend, msgfptr->name, msgfptr->crypt_connection_id, |
1869 | ping_lastrecv, ID2String(msgfptr->client_id)); | 2014 | ping_lastrecv, ID2String(msgfptr->client_id)); |
1870 | loglog(logbuffer); | 2015 | loglog(logbuffer); |
2016 | } else { | ||
2017 | snprintf(logbuffer, sizeof(logbuffer), "F[--:%2u] %s\n", | ||
2018 | friend, ID2String(dhtfptr->client_id)); | ||
2019 | loglog(logbuffer); | ||
2020 | } | ||
1871 | 2021 | ||
1872 | for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { | 2022 | for (client = 0; client < MAX_FRIEND_CLIENTS; client++) { |
1873 | Client_data *cptr = &dhtfptr->client_list[client]; | 2023 | Client_data *cptr = &dhtfptr->client_list[client]; |
@@ -1995,6 +2145,9 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le | |||
1995 | if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { | 2145 | if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { |
1996 | set_nospam(&(m->fr), *(uint32_t *)data); | 2146 | set_nospam(&(m->fr), *(uint32_t *)data); |
1997 | load_keys(m->net_crypto, &data[sizeof(uint32_t)]); | 2147 | load_keys(m->net_crypto, &data[sizeof(uint32_t)]); |
2148 | |||
2149 | if (m->dht->assoc) | ||
2150 | Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key); | ||
1998 | } else | 2151 | } else |
1999 | return -1; /* critical */ | 2152 | return -1; /* critical */ |
2000 | 2153 | ||
@@ -2100,12 +2253,12 @@ uint32_t copy_friendlist(Messenger *m, int *out_list, uint32_t list_size) | |||
2100 | uint32_t ret = 0; | 2253 | uint32_t ret = 0; |
2101 | 2254 | ||
2102 | for (i = 0; i < m->numfriends; i++) { | 2255 | for (i = 0; i < m->numfriends; i++) { |
2103 | if (i >= list_size) { | 2256 | if (ret >= list_size) { |
2104 | break; /* Abandon ship */ | 2257 | break; /* Abandon ship */ |
2105 | } | 2258 | } |
2106 | 2259 | ||
2107 | if (m->friendlist[i].status > 0) { | 2260 | if (m->friendlist[i].status > 0) { |
2108 | out_list[i] = i; | 2261 | out_list[ret] = i; |
2109 | ret++; | 2262 | ret++; |
2110 | } | 2263 | } |
2111 | } | 2264 | } |
@@ -2146,3 +2299,51 @@ int get_friendlist(Messenger *m, int **out_list, uint32_t *out_list_length) | |||
2146 | return 0; | 2299 | return 0; |
2147 | } | 2300 | } |
2148 | 2301 | ||
2302 | /* Return the number of chats in the instance m. | ||
2303 | * You should use this to determine how much memory to allocate | ||
2304 | * for copy_chatlist. */ | ||
2305 | uint32_t count_chatlist(Messenger *m) | ||
2306 | { | ||
2307 | uint32_t ret = 0; | ||
2308 | uint32_t i; | ||
2309 | |||
2310 | for (i = 0; i < m->numchats; i++) { | ||
2311 | if (m->chats[i]) { | ||
2312 | ret++; | ||
2313 | } | ||
2314 | } | ||
2315 | |||
2316 | return ret; | ||
2317 | } | ||
2318 | |||
2319 | /* Copy a list of valid chat IDs into the array out_list. | ||
2320 | * If out_list is NULL, returns 0. | ||
2321 | * Otherwise, returns the number of elements copied. | ||
2322 | * If the array was too small, the contents | ||
2323 | * of out_list will be truncated to list_size. */ | ||
2324 | uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size) | ||
2325 | { | ||
2326 | if (!out_list) | ||
2327 | return 0; | ||
2328 | |||
2329 | if (m->numchats == 0) { | ||
2330 | return 0; | ||
2331 | } | ||
2332 | |||
2333 | uint32_t i; | ||
2334 | uint32_t ret = 0; | ||
2335 | |||
2336 | for (i = 0; i < m->numchats; i++) { | ||
2337 | if (ret >= list_size) { | ||
2338 | break; /* Abandon ship */ | ||
2339 | } | ||
2340 | |||
2341 | if (m->chats[i]) { | ||
2342 | out_list[ret] = i; | ||
2343 | ret++; | ||
2344 | } | ||
2345 | } | ||
2346 | |||
2347 | return ret; | ||
2348 | } | ||
2349 | |||