summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index ae13e9d6..656b384b 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -637,6 +637,181 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
637 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 637 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1);
638} 638}
639 639
640/**********GROUP CHATS************/
641
642/* returns valid ip port of connected friend on success
643 * returns zeroed out IP_Port on failure
644 */
645static IP_Port get_friend_ipport(Messenger *m, int friendnumber)
646{
647 IP_Port zero;
648 memset(&zero, 0, sizeof(zero));
649
650 if (friend_not_valid(m, friendnumber))
651 return zero;
652
653 int crypt_id = m->friendlist[friendnumber].crypt_connection_id;
654
655 if (is_cryptoconnected(m->net_crypto, crypt_id) != 3)
656 return zero;
657
658 return connection_ip(m->net_crypto->lossless_udp, m->net_crypto->crypto_connections[crypt_id].number);
659}
660
661/* returns the group number of the chat with public key group_public_key.
662 * returns -1 on failure.
663 */
664static int group_num(Messenger *m, uint8_t *group_public_key)
665{
666 uint32_t i;
667
668 for (i = 0; i < m->numchats; ++i) {
669 if (memcmp(m->chats[i]->self_public_key, group_public_key, crypto_box_PUBLICKEYBYTES) == 0)
670 return i;
671 }
672
673 return -1;
674}
675
676/* Creates a new groupchat and puts it in the chats array.
677 *
678 * return group number on success.
679 * return -1 on failure.
680 */
681int add_groupchat(Messenger *m)
682{
683 uint32_t i;
684
685 for (i = 0; i < m->numchats; ++i) {
686 if (m->chats[i] == NULL) {
687 Group_Chat *newchat = new_groupchat(m->net);
688
689 if (newchat == NULL)
690 return -1;
691
692 m->chats[i] = newchat;
693 return i;
694 }
695 }
696
697 Group_Chat **temp;
698 temp = realloc(m->chats, sizeof(Group_Chat *) * (m->numchats + 1));
699
700 if (temp == NULL)
701 return -1;
702
703 temp[m->numchats] = new_groupchat(m->net);
704
705 if (temp[m->numchats] == NULL)
706 return -1;
707
708 ++m->numchats;
709 return (m->numchats - 1);
710}
711
712/* Delete a groupchat from the chats array.
713 *
714 * return 0 on success.
715 * return -1 if failure.
716 */
717static int del_groupchat(Messenger *m, int groupnumber)
718{
719 if ((unsigned int)groupnumber >= m->numchats)
720 return -1;
721
722 if (m->chats == NULL)
723 return -1;
724
725 if (m->chats[groupnumber] == NULL)
726 return -1;
727
728 kill_groupchat(m->chats[groupnumber]);
729 m->chats[groupnumber] = NULL;
730
731 uint32_t i;
732
733 for (i = m->numchats; i != 0; --i) {
734 if (m->chats[i - 1] != NULL)
735 break;
736 }
737
738 if (i == 0) {
739 free(m->chats);
740 m->chats = NULL;
741 } else {
742 Group_Chat **temp = realloc(m->chats, sizeof(Group_Chat *) * i);
743
744 if (temp != NULL)
745 m->chats = temp;
746 }
747
748 return 0;
749}
750
751/* Join a group (you need to have been invited first.)
752 *
753 * returns 0 on success
754 * returns -1 on failure.
755 */
756int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_key)
757{
758 if (friend_not_valid(m, friendnumber))
759 return -1;
760
761 uint8_t data[crypto_box_PUBLICKEYBYTES * 2];
762 int groupnum = add_groupchat(m);
763
764 if (groupnum == -1)
765 return -1;
766
767 memcpy(data, friend_group_public_key, crypto_box_PUBLICKEYBYTES);
768 memcpy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key, crypto_box_PUBLICKEYBYTES);
769
770 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) {
771 chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber),
772 friend_group_public_key); //TODO: check if ip returned is zero?
773 return 0;
774 }
775
776 return -1;
777}
778
779static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t length)
780{
781 Messenger *m = object;
782
783 if (length < crypto_box_PUBLICKEYBYTES + 1) {
784 return 1;
785 }
786
787 uint32_t i;
788
789 for (i = 0; i < m->numchats; ++i) {
790 if (m->chats[i] == NULL)
791 continue;
792
793 if (memcmp(packet + 1, m->chats[i]->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
794 return handle_groupchatpacket(m->chats[i], source, packet, length);
795 }
796
797 return 1;
798}
799
800static void do_allgroupchats(Messenger *m)
801{
802 uint32_t i;
803
804 for (i = 0; i < m->numchats; ++i) {
805 if (m->chats[i] != NULL)
806 do_groupchat(m->chats[i]);
807 }
808}
809
810/*********************************/
811
812/* Interval in seconds between LAN discovery packet sending. */
813#define LAN_DISCOVERY_INTERVAL 60
814
640/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ 815/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
641static void LANdiscovery(Messenger *m) 816static void LANdiscovery(Messenger *m)
642{ 817{
@@ -686,6 +861,7 @@ Messenger *initMessenger(uint8_t ipv6enabled)
686 friendreq_init(&(m->fr), m->net_crypto); 861 friendreq_init(&(m->fr), m->net_crypto);
687 LANdiscovery_init(m->dht); 862 LANdiscovery_init(m->dht);
688 set_nospam(&(m->fr), random_int()); 863 set_nospam(&(m->fr), random_int());
864 networking_registerhandler(m->net, NET_PACKET_GROUP_CHATS, &handle_group, m);
689 865
690 return m; 866 return m;
691} 867}
@@ -939,6 +1115,7 @@ void doMessenger(Messenger *m)
939 do_net_crypto(m->net_crypto); 1115 do_net_crypto(m->net_crypto);
940 doInbound(m); 1116 doInbound(m);
941 doFriends(m); 1117 doFriends(m);
1118 do_allgroupchats(m);
942 LANdiscovery(m); 1119 LANdiscovery(m);
943} 1120}
944 1121