summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2015-02-24 19:39:19 -0500
committerirungentoo <irungentoo@gmail.com>2015-02-24 19:39:19 -0500
commit8fa8e9dcd798540bf539d502d0dbba71184f7489 (patch)
tree7e8b30b39e2bd8a7ccbafe64f949eda1b47c3cab /toxcore
parentca21569a9d0ec4c1a05e7fede61359d158c194f5 (diff)
Remove avatar stuff from Messenger.
The new api sees avatars as a different type of file transfer.
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/Messenger.c486
-rw-r--r--toxcore/Messenger.h213
2 files changed, 0 insertions, 699 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index e5298b31..863259ac 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -39,7 +39,6 @@
39static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); 39static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status);
40static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, 40static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
41 uint32_t length, uint8_t congestion_control); 41 uint32_t length, uint8_t congestion_control);
42static int send_avatar_data_control(const Messenger *m, const uint32_t friendnumber, uint8_t op);
43 42
44// friend_not_valid determines if the friendnumber passed is valid in the Messenger object 43// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
45static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber) 44static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber)
@@ -208,10 +207,6 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta
208 id_copy(m->friendlist[i].real_pk, real_pk); 207 id_copy(m->friendlist[i].real_pk, real_pk);
209 m->friendlist[i].statusmessage_length = 0; 208 m->friendlist[i].statusmessage_length = 0;
210 m->friendlist[i].userstatus = USERSTATUS_NONE; 209 m->friendlist[i].userstatus = USERSTATUS_NONE;
211 m->friendlist[i].avatar_info_sent = 0;
212 m->friendlist[i].avatar_recv_data = NULL;
213 m->friendlist[i].avatar_send_data.bytes_sent = 0;
214 m->friendlist[i].avatar_send_data.last_reset = 0;
215 m->friendlist[i].is_typing = 0; 210 m->friendlist[i].is_typing = 0;
216 m->friendlist[i].message_id = 0; 211 m->friendlist[i].message_id = 0;
217 friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, 212 friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet,
@@ -397,7 +392,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
397 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) 392 if (m->friendlist[friendnumber].status == FRIEND_ONLINE)
398 remove_online_friend(m, friendnumber); 393 remove_online_friend(m, friendnumber);
399 394
400 free(m->friendlist[friendnumber].avatar_recv_data);
401 clear_receipts(m, friendnumber); 395 clear_receipts(m, friendnumber);
402 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); 396 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk);
403 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); 397 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0);
@@ -656,149 +650,6 @@ int m_set_userstatus(Messenger *m, uint8_t status)
656 return 0; 650 return 0;
657} 651}
658 652
659int m_unset_avatar(Messenger *m)
660{
661 if (m->avatar_data != NULL)
662 free(m->avatar_data);
663
664 m->avatar_data = NULL;
665 m->avatar_data_length = 0;
666 m->avatar_format = AVATAR_FORMAT_NONE;
667 memset(m->avatar_hash, 0, AVATAR_HASH_LENGTH);
668
669 uint32_t i;
670
671 for (i = 0; i < m->numfriends; ++i)
672 m->friendlist[i].avatar_info_sent = 0;
673
674 return 0;
675}
676
677int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length)
678{
679 if (format == AVATAR_FORMAT_NONE) {
680 m_unset_avatar(m);
681 return 0;
682 }
683
684 if (length > AVATAR_MAX_DATA_LENGTH || length == 0)
685 return -1;
686
687 if (data == NULL)
688 return -1;
689
690 uint8_t *tmp = realloc(m->avatar_data, length);
691
692 if (tmp == NULL)
693 return -1;
694
695 m->avatar_format = format;
696 m->avatar_data = tmp;
697 m->avatar_data_length = length;
698 memcpy(m->avatar_data, data, length);
699
700 m_avatar_hash(m->avatar_hash, m->avatar_data, m->avatar_data_length);
701
702 uint32_t i;
703
704 for (i = 0; i < m->numfriends; ++i)
705 m->friendlist[i].avatar_info_sent = 0;
706
707 return 0;
708}
709
710int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
711 uint8_t *hash)
712{
713 if (format)
714 *format = m->avatar_format;
715
716 if (length)
717 *length = m->avatar_data_length;
718
719 if (hash)
720 memcpy(hash, m->avatar_hash, AVATAR_HASH_LENGTH);
721
722 if (buf != NULL && maxlen > 0) {
723 if (m->avatar_data_length <= maxlen)
724 memcpy(buf, m->avatar_data, m->avatar_data_length);
725 else
726 return -1;
727 }
728
729 return 0;
730}
731
732int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
733{
734 if (hash == NULL)
735 return -1;
736
737 return crypto_hash_sha256(hash, data, datalen);
738}
739
740int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
741{
742 return m_hash(hash, data, datalen);
743}
744
745int m_request_avatar_info(const Messenger *m, const int32_t friendnumber)
746{
747 if (friend_not_valid(m, friendnumber))
748 return -1;
749
750 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO_REQ, 0, 0, 0))
751 return 0;
752 else
753 return -1;
754}
755
756int m_send_avatar_info(const Messenger *m, const int32_t friendnumber)
757{
758 if (friend_not_valid(m, friendnumber))
759 return -1;
760
761 uint8_t data[sizeof(uint8_t) + AVATAR_HASH_LENGTH];
762 data[0] = m->avatar_format;
763 memcpy(data + 1, m->avatar_hash, AVATAR_HASH_LENGTH);
764
765 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO, data, sizeof(data), 0))
766 return 0;
767 else
768 return -1;
769}
770
771int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
772{
773 if (friend_not_valid(m, friendnumber))
774 return -1;
775
776 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
777
778 if (avrd == NULL) {
779 avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1);
780
781 if (avrd == NULL)
782 return -1;
783
784 avrd->started = 0;
785 m->friendlist[friendnumber].avatar_recv_data = avrd;
786 }
787
788 if (avrd->started) {
789 LOGGER_DEBUG("Resetting already started data request. "
790 "friendnumber == %u", friendnumber);
791 }
792
793 avrd->started = 0;
794 avrd->bytes_received = 0;
795 avrd->total_length = 0;
796 avrd->format = AVATAR_FORMAT_NONE;
797
798 return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ);
799}
800
801
802/* return the size of friendnumber's user status. 653/* return the size of friendnumber's user status.
803 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH. 654 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
804 */ 655 */
@@ -1021,20 +872,6 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
1021 m->friend_connectionstatuschange_internal_userdata = userdata; 872 m->friend_connectionstatuschange_internal_userdata = userdata;
1022} 873}
1023 874
1024void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, void *),
1025 void *userdata)
1026{
1027 m->avatar_info_recv = function;
1028 m->avatar_info_recv_userdata = userdata;
1029}
1030
1031void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *,
1032 uint32_t, void *), void *userdata)
1033{
1034 m->avatar_data_recv = function;
1035 m->avatar_data_recv_userdata = userdata;
1036}
1037
1038static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber) 875static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber)
1039{ 876{
1040 int last_connection_udp_tcp = m->friendlist[friendnumber].last_connection_udp_tcp; 877 int last_connection_udp_tcp = m->friendlist[friendnumber].last_connection_udp_tcp;
@@ -1646,9 +1483,6 @@ Messenger *new_messenger(Messenger_Options *options)
1646 m->net = new_networking(ip, TOX_PORT_DEFAULT); 1483 m->net = new_networking(ip, TOX_PORT_DEFAULT);
1647 } 1484 }
1648 1485
1649 m->avatar_format = AVATAR_FORMAT_NONE;
1650 m->avatar_data = NULL;
1651
1652 if (m->net == NULL) { 1486 if (m->net == NULL) {
1653 free(m); 1487 free(m);
1654 return NULL; 1488 return NULL;
@@ -1714,11 +1548,9 @@ void kill_messenger(Messenger *m)
1714 kill_networking(m->net); 1548 kill_networking(m->net);
1715 1549
1716 for (i = 0; i < m->numfriends; ++i) { 1550 for (i = 0; i < m->numfriends; ++i) {
1717 free(m->friendlist[i].avatar_recv_data);
1718 clear_receipts(m, i); 1551 clear_receipts(m, i);
1719 } 1552 }
1720 1553
1721 free(m->avatar_data);
1722 free(m->friendlist); 1554 free(m->friendlist);
1723 free(m); 1555 free(m);
1724} 1556}
@@ -1752,293 +1584,16 @@ static int handle_status(void *object, int i, uint8_t status)
1752 m->friendlist[i].userstatus_sent = 0; 1584 m->friendlist[i].userstatus_sent = 0;
1753 m->friendlist[i].statusmessage_sent = 0; 1585 m->friendlist[i].statusmessage_sent = 0;
1754 m->friendlist[i].user_istyping_sent = 0; 1586 m->friendlist[i].user_istyping_sent = 0;
1755 m->friendlist[i].avatar_info_sent = 0;
1756 m->friendlist[i].ping_lastrecv = temp_time; 1587 m->friendlist[i].ping_lastrecv = temp_time;
1757 } else { /* Went offline. */ 1588 } else { /* Went offline. */
1758 if (m->friendlist[i].status == FRIEND_ONLINE) { 1589 if (m->friendlist[i].status == FRIEND_ONLINE) {
1759 set_friend_status(m, i, FRIEND_CONFIRMED); 1590 set_friend_status(m, i, FRIEND_CONFIRMED);
1760 } 1591 }
1761
1762 /* Clear avatar transfer state */
1763 if (m->friendlist[i].avatar_recv_data) {
1764 free(m->friendlist[i].avatar_recv_data);
1765 m->friendlist[i].avatar_recv_data = NULL;
1766 }
1767 }
1768
1769 return 0;
1770}
1771
1772
1773/* Sends an avatar data control packet to the peer. Usually to return status
1774 * values or request data.
1775 */
1776static int send_avatar_data_control(const Messenger *m, const uint32_t friendnumber,
1777 uint8_t op)
1778{
1779 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_DATA_CONTROL,
1780 &op, sizeof(op), 0);
1781 LOGGER_DEBUG("friendnumber = %u, op = %u, ret = %d",
1782 friendnumber, op, ret);
1783 return ret ? 0 : -1;
1784}
1785
1786
1787static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
1788 uint8_t *data, uint32_t data_length)
1789{
1790 if (data_length != 1) {
1791 LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad "
1792 "data_length = %u, friendnumber = %u",
1793 data_length, friendnumber);
1794 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
1795 return -1; /* Error */
1796 }
1797
1798 LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
1799
1800 switch (data[0]) {
1801 case AVATAR_DATACONTROL_REQ: {
1802
1803 /* Check data transfer limits for this friend */
1804 AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
1805
1806 if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) {
1807 /* User reached data limit. Check timeout */
1808 uint64_t now = unix_time();
1809
1810 if (avsd->last_reset > 0
1811 && (avsd->last_reset + AVATAR_DATA_TRANSFER_TIMEOUT < now)) {
1812 avsd->bytes_sent = 0;
1813 avsd->last_reset = now;
1814 } else {
1815 /* Friend still rate-limitted. Send an error and stops. */
1816 LOGGER_DEBUG("Avatar data transfer limit reached. "
1817 "friendnumber = %u", friendnumber);
1818 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
1819 return 0;
1820 }
1821 }
1822
1823 /* Start the transmission with a DATA_START message. Format:
1824 * uint8_t format
1825 * uint8_t hash[AVATAR_HASH_LENGTH]
1826 * uint32_t total_length
1827 */
1828 LOGGER_DEBUG("Sending start msg to friend number %u. "
1829 "m->avatar_format = %u, m->avatar_data_length = %u",
1830 friendnumber, m->avatar_format, m->avatar_data_length);
1831 uint8_t start_data[1 + AVATAR_HASH_LENGTH + sizeof(uint32_t)];
1832 uint32_t avatar_len = htonl(m->avatar_data_length);
1833
1834 start_data[0] = m->avatar_format;
1835 memcpy(start_data + 1, m->avatar_hash, AVATAR_HASH_LENGTH);
1836 memcpy(start_data + 1 + AVATAR_HASH_LENGTH, &avatar_len, sizeof(uint32_t));
1837
1838 avsd->bytes_sent += sizeof(start_data); /* For rate limit */
1839
1840 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_DATA_START,
1841 start_data, sizeof(start_data), 0);
1842
1843 if (!ret) {
1844 /* Something went wrong, try to signal the error so the friend
1845 * can clear up the state. */
1846 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
1847 return 0;
1848 }
1849
1850 /* User have no avatar data, nothing more to do. */
1851 if (m->avatar_format == AVATAR_FORMAT_NONE)
1852 return 0;
1853
1854 /* Send the actual avatar data. */
1855 uint32_t offset = 0;
1856
1857 while (offset < m->avatar_data_length) {
1858 uint32_t chunk_len = m->avatar_data_length - offset;
1859
1860 if (chunk_len > AVATAR_DATA_MAX_CHUNK_SIZE)
1861 chunk_len = AVATAR_DATA_MAX_CHUNK_SIZE;
1862
1863 uint8_t chunk[AVATAR_DATA_MAX_CHUNK_SIZE];
1864 memcpy(chunk, m->avatar_data + offset, chunk_len);
1865 offset += chunk_len;
1866 avsd->bytes_sent += chunk_len; /* For rate limit */
1867
1868 int ret = write_cryptpacket_id(m, friendnumber,
1869 PACKET_ID_AVATAR_DATA_PUSH,
1870 chunk, chunk_len, 0);
1871
1872 if (!ret) {
1873 LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, "
1874 "friendnumber = %u, offset = %u",
1875 ret, friendnumber, offset);
1876 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
1877 return -1;
1878 }
1879 }
1880
1881 return 0;
1882 }
1883
1884 case AVATAR_DATACONTROL_ERROR: {
1885 if (m->friendlist[friendnumber].avatar_recv_data) {
1886 /* We were receiving the data, sender detected an error
1887 (eg. changing avatar) and asked us to stop. */
1888 free(m->friendlist[friendnumber].avatar_recv_data);
1889 m->friendlist[friendnumber].avatar_recv_data = NULL;
1890 }
1891
1892 return 0;
1893 }
1894 }
1895
1896 return -1;
1897}
1898
1899
1900static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
1901 uint8_t *data, uint32_t data_length)
1902{
1903 LOGGER_DEBUG("data_length = %u, friendnumber = %u", data_length, friendnumber);
1904
1905 if (data_length != 1 + AVATAR_HASH_LENGTH + sizeof(uint32_t)) {
1906 LOGGER_DEBUG("Invalid msg length = %u, friendnumber = %u",
1907 data_length, friendnumber);
1908 return -1;
1909 } 1592 }
1910 1593
1911 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
1912
1913 if (avrd == NULL) {
1914 LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u",
1915 friendnumber);
1916 return -1;
1917 }
1918
1919 if (avrd->started) {
1920 /* Already receiving data from this friend. Must be an error
1921 * or an malicious request, because we zeroed the started bit
1922 * when we requested the data. */
1923 LOGGER_DEBUG("Received an unrequested duplicated DATA_START, "
1924 "friendnumber = %u", friendnumber);
1925 return -1;
1926 }
1927
1928 /* Copy data from message to our control structure */
1929 avrd->started = 1;
1930 avrd->format = data[0];
1931 memcpy(avrd->hash, data + 1, AVATAR_HASH_LENGTH);
1932 uint32_t tmp_len;
1933 memcpy(&tmp_len, data + 1 + AVATAR_HASH_LENGTH, sizeof(uint32_t));
1934 avrd->total_length = ntohl(tmp_len);
1935 avrd->bytes_received = 0;
1936
1937 LOGGER_DEBUG("friendnumber = %u, avrd->format = %u, "
1938 "avrd->total_length = %u, avrd->bytes_received = %u",
1939 friendnumber, avrd->format, avrd->total_length,
1940 avrd->bytes_received);
1941
1942 if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) {
1943 /* Invalid data length. Stops. */
1944 LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
1945 "friendnumber = %u", friendnumber);
1946 free(avrd);
1947 avrd = NULL;
1948 m->friendlist[friendnumber].avatar_recv_data = NULL;
1949 return 0;
1950 }
1951
1952 if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) {
1953 /* No real data to receive. Run callback function and finish. */
1954 LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber);
1955
1956 if (m->avatar_data_recv) {
1957 memset(avrd->hash, 0, AVATAR_HASH_LENGTH);
1958 (m->avatar_data_recv)(m, friendnumber, avrd->format, avrd->hash,
1959 NULL, 0, m->avatar_data_recv_userdata);
1960 }
1961
1962 free(avrd);
1963 avrd = NULL;
1964 m->friendlist[friendnumber].avatar_recv_data = NULL;
1965 return 0;
1966 }
1967
1968 /* Waits for more data to be received */
1969 return 0;
1970}
1971
1972
1973static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
1974 uint8_t *data, uint32_t data_length)
1975{
1976 LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length);
1977
1978 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
1979
1980 if (avrd == NULL) {
1981 /* No active transfer. It must be an error or a malicious request,
1982 * because we set the avatar_recv_data on the first DATA_START. */
1983 LOGGER_DEBUG("Error: avrd == NULL, friendnumber = %u", friendnumber);
1984 return -1; /* Error */
1985 }
1986
1987 if (avrd->started == 0) {
1988 /* Receiving data for a non-started request. Must be an error
1989 * or an malicious request. */
1990 LOGGER_DEBUG("Received an data push for a yet non started data "
1991 "request. friendnumber = %u", friendnumber);
1992 return -1; /* Error */
1993 }
1994
1995 uint32_t new_length = avrd->bytes_received + data_length;
1996
1997 if (new_length > avrd->total_length
1998 || new_length >= AVATAR_MAX_DATA_LENGTH) {
1999 /* Invalid data length due to error or malice. Stops. */
2000 LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
2001 "new_length = %u, avrd->total_length = %u",
2002 friendnumber, new_length, avrd->total_length);
2003 free(avrd);
2004 m->friendlist[friendnumber].avatar_recv_data = NULL;
2005 return 0;
2006 }
2007
2008 memcpy(avrd->data + avrd->bytes_received, data, data_length);
2009 avrd->bytes_received += data_length;
2010
2011 if (avrd->bytes_received == avrd->total_length) {
2012 LOGGER_DEBUG("All data received. friendnumber = %u", friendnumber);
2013
2014 /* All data was received. Check if the hashes match. It the
2015 * requester's responsability to do this. The sender may have done
2016 * anything with its avatar data between the DATA_START and now.
2017 */
2018 uint8_t cur_hash[AVATAR_HASH_LENGTH];
2019 m_avatar_hash(cur_hash, avrd->data, avrd->bytes_received);
2020
2021 if (memcmp(cur_hash, avrd->hash, AVATAR_HASH_LENGTH) == 0) {
2022 /* Avatar successfuly received! */
2023 if (m->avatar_data_recv) {
2024 (m->avatar_data_recv)(m, friendnumber, avrd->format, cur_hash,
2025 avrd->data, avrd->bytes_received, m->avatar_data_recv_userdata);
2026 }
2027 } else {
2028 LOGGER_DEBUG("Avatar hash error. friendnumber = %u", friendnumber);
2029 }
2030
2031 free(avrd);
2032 m->friendlist[friendnumber].avatar_recv_data = NULL;
2033 return 0;
2034 }
2035
2036 /* Waits for more data to be received */
2037 return 0; 1594 return 0;
2038} 1595}
2039 1596
2040
2041
2042static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) 1597static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2043{ 1598{
2044 if (len == 0) 1599 if (len == 0)
@@ -2178,42 +1733,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2178 break; 1733 break;
2179 } 1734 }
2180 1735
2181 case PACKET_ID_AVATAR_INFO_REQ: {
2182 /* Send our avatar information */
2183 m_send_avatar_info(m, i);
2184 break;
2185 }
2186
2187 case PACKET_ID_AVATAR_INFO: {
2188 if (m->avatar_info_recv) {
2189 /*
2190 * A malicious user may send an incomplete avatar info message.
2191 * Check if it have the correct size for the format:
2192 * [1 uint8_t: avatar format] [32 uint8_t: hash]
2193 */
2194 if (data_length == AVATAR_HASH_LENGTH + 1) {
2195 (m->avatar_info_recv)(m, i, data[0], data + 1, m->avatar_info_recv_userdata);
2196 }
2197 }
2198
2199 break;
2200 }
2201
2202 case PACKET_ID_AVATAR_DATA_CONTROL: {
2203 handle_avatar_data_control(m, i, data, data_length);
2204 break;
2205 }
2206
2207 case PACKET_ID_AVATAR_DATA_START: {
2208 handle_avatar_data_start(m, i, data, data_length);
2209 break;
2210 }
2211
2212 case PACKET_ID_AVATAR_DATA_PUSH: {
2213 handle_avatar_data_push(m, i, data, data_length);
2214 break;
2215 }
2216
2217 case PACKET_ID_INVITE_GROUPCHAT: { 1736 case PACKET_ID_INVITE_GROUPCHAT: {
2218 if (data_length == 0) 1737 if (data_length == 0)
2219 break; 1738 break;
@@ -2362,11 +1881,6 @@ void do_friends(Messenger *m)
2362 m->friendlist[i].userstatus_sent = 1; 1881 m->friendlist[i].userstatus_sent = 1;
2363 } 1882 }
2364 1883
2365 if (m->friendlist[i].avatar_info_sent == 0) {
2366 if (m_send_avatar_info(m, i) == 0)
2367 m->friendlist[i].avatar_info_sent = 1;
2368 }
2369
2370 if (m->friendlist[i].user_istyping_sent == 0) { 1884 if (m->friendlist[i].user_istyping_sent == 0) {
2371 if (send_user_istyping(m, i, m->friendlist[i].user_istyping)) 1885 if (send_user_istyping(m, i, m->friendlist[i].user_istyping))
2372 m->friendlist[i].user_istyping_sent = 1; 1886 m->friendlist[i].user_istyping_sent = 1;
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 4e011a57..48235900 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -33,8 +33,6 @@
33#define MAX_NAME_LENGTH 128 33#define MAX_NAME_LENGTH 128
34/* TODO: this must depend on other variable. */ 34/* TODO: this must depend on other variable. */
35#define MAX_STATUSMESSAGE_LENGTH 1007 35#define MAX_STATUSMESSAGE_LENGTH 1007
36#define AVATAR_MAX_DATA_LENGTH 16384
37#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES
38 36
39 37
40#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) 38#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
@@ -47,11 +45,6 @@
47#define PACKET_ID_STATUSMESSAGE 49 45#define PACKET_ID_STATUSMESSAGE 49
48#define PACKET_ID_USERSTATUS 50 46#define PACKET_ID_USERSTATUS 50
49#define PACKET_ID_TYPING 51 47#define PACKET_ID_TYPING 51
50#define PACKET_ID_AVATAR_INFO_REQ 52
51#define PACKET_ID_AVATAR_INFO 53
52#define PACKET_ID_AVATAR_DATA_CONTROL 54
53#define PACKET_ID_AVATAR_DATA_START 55
54#define PACKET_ID_AVATAR_DATA_PUSH 56
55#define PACKET_ID_MESSAGE 64 48#define PACKET_ID_MESSAGE 64
56#define PACKET_ID_ACTION 65 49#define PACKET_ID_ACTION 65
57#define PACKET_ID_MSI 69 50#define PACKET_ID_MSI 69
@@ -112,14 +105,6 @@ enum {
112/* Interval between the sending of tcp relay information */ 105/* Interval between the sending of tcp relay information */
113#define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60) 106#define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60)
114 107
115/* Must be < MAX_CRYPTO_DATA_SIZE */
116#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1)
117
118/* Per-friend data limit for avatar data requests */
119#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH)
120#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */
121
122
123enum { 108enum {
124 CONNECTION_NONE, 109 CONNECTION_NONE,
125 CONNECTION_TCP, 110 CONNECTION_TCP,
@@ -138,42 +123,6 @@ typedef enum {
138} 123}
139USERSTATUS; 124USERSTATUS;
140 125
141/* AVATAR_FORMAT -
142 * Data formats for user avatar images
143 */
144typedef enum {
145 AVATAR_FORMAT_NONE = 0,
146 AVATAR_FORMAT_PNG
147}
148AVATAR_FORMAT;
149
150/* AVATAR_DATACONTROL
151 * To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
152 */
153typedef enum {
154 AVATAR_DATACONTROL_REQ,
155 AVATAR_DATACONTROL_ERROR
156}
157AVATAR_DATACONTROL;
158
159typedef struct {
160 uint8_t started;
161 AVATAR_FORMAT format;
162 uint8_t hash[AVATAR_HASH_LENGTH];
163 uint32_t total_length;
164 uint32_t bytes_received;
165 uint8_t data[AVATAR_MAX_DATA_LENGTH];
166}
167AVATAR_RECEIVEDATA;
168
169typedef struct {
170 /* Fields only used to limit the network usage from a given friend */
171 uint32_t bytes_sent; /* Total bytes send to this user */
172 uint64_t last_reset; /* Time the data counter was last reset */
173}
174AVATAR_SENDDATA;
175
176
177struct File_Transfers { 126struct File_Transfers {
178 uint64_t size; 127 uint64_t size;
179 uint64_t transferred; 128 uint64_t transferred;
@@ -217,7 +166,6 @@ typedef struct {
217 uint8_t statusmessage_sent; 166 uint8_t statusmessage_sent;
218 USERSTATUS userstatus; 167 USERSTATUS userstatus;
219 uint8_t userstatus_sent; 168 uint8_t userstatus_sent;
220 uint8_t avatar_info_sent;
221 uint8_t user_istyping; 169 uint8_t user_istyping;
222 uint8_t user_istyping_sent; 170 uint8_t user_istyping_sent;
223 uint8_t is_typing; 171 uint8_t is_typing;
@@ -230,9 +178,6 @@ typedef struct {
230 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; 178 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES];
231 struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; 179 struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES];
232 180
233 AVATAR_SENDDATA avatar_send_data;
234 AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
235
236 struct { 181 struct {
237 int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint32_t len, void *object); 182 int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint32_t len, void *object);
238 void *object; 183 void *object;
@@ -269,11 +214,6 @@ struct Messenger {
269 214
270 USERSTATUS userstatus; 215 USERSTATUS userstatus;
271 216
272 AVATAR_FORMAT avatar_format;
273 uint8_t *avatar_data;
274 uint32_t avatar_data_length;
275 uint8_t avatar_hash[AVATAR_HASH_LENGTH];
276
277 Friend *friendlist; 217 Friend *friendlist;
278 uint32_t numfriends; 218 uint32_t numfriends;
279 219
@@ -305,10 +245,6 @@ struct Messenger {
305 void *friend_connectionstatuschange_userdata; 245 void *friend_connectionstatuschange_userdata;
306 void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *); 246 void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *);
307 void *friend_connectionstatuschange_internal_userdata; 247 void *friend_connectionstatuschange_internal_userdata;
308 void *avatar_info_recv_userdata;
309 void (*avatar_info_recv)(struct Messenger *m, uint32_t, uint8_t, uint8_t *, void *);
310 void *avatar_data_recv_userdata;
311 void (*avatar_data_recv)(struct Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, void *);
312 248
313 void *group_chat_object; /* Set by new_groupchats()*/ 249 void *group_chat_object; /* Set by new_groupchats()*/
314 void (*group_invite)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t); 250 void (*group_invite)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t);
@@ -503,113 +439,6 @@ uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber);
503uint8_t m_get_self_userstatus(const Messenger *m); 439uint8_t m_get_self_userstatus(const Messenger *m);
504 440
505 441
506/* Set the user avatar image data.
507 * This should be made before connecting, so we will not announce that the user have no avatar
508 * before setting and announcing a new one, forcing the peers to re-download it.
509 *
510 * Notice that the library treats the image as raw data and does not interpret it by any way.
511 *
512 * Arguments:
513 * format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT);
514 * data - pointer to the avatar data (may be NULL it the format is NONE);
515 * length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH.
516 *
517 * returns 0 on success
518 * returns -1 on failure.
519 */
520int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length);
521
522/* Unsets the user avatar.
523
524 returns 0 on success (currently always returns 0) */
525int m_unset_avatar(Messenger *m);
526
527/* Get avatar data from the current user.
528 * Copies the current user avatar data to the destination buffer and sets the image format
529 * accordingly.
530 *
531 * If the avatar format is NONE, the buffer 'buf' isleft uninitialized, 'hash' is zeroed, and
532 * 'length' is set to zero.
533 *
534 * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
535 *
536 * Arguments:
537 * format - destination pointer to the avatar image format (see AVATAR_FORMAT);
538 * buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
539 * length - destination pointer to the image data length;
540 * maxlen - length of the destination buffer 'buf';
541 * hash - destination pointer to the avatar hash (it must be exactly AVATAR_HASH_LENGTH bytes long).
542 *
543 * returns 0 on success;
544 * returns -1 on failure.
545 *
546 */
547int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
548 uint8_t *hash);
549
550/* Generates a cryptographic hash of the given data.
551 * This function may be used by clients for any purpose, but is provided primarily for
552 * validating cached avatars.
553 * This function is a wrapper to internal message-digest functions.
554 *
555 * Arguments:
556 * hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long.
557 * data - data to be hashed;
558 * datalen - length of the data;
559 *
560 * returns 0 on success
561 * returns -1 on failure.
562 */
563int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
564
565/* Generates a cryptographic hash of the given avatar data.
566 * This function is a wrapper to m_hash and specifically provided
567 * to generate hashes from user avatars that may be memcmp()ed with the values returned by the
568 * other avatar functions. It is specially important to validate cached avatars.
569 *
570 * Arguments:
571 * hash - destination buffer for the hash data, it must be exactly AVATAR_HASH_LENGTH bytes long.
572 * data - avatar image data;
573 * datalen - length of the avatar image data; it must be <= MAX_AVATAR_DATA_LENGTH.
574 *
575 * returns 0 on success
576 * returns -1 on failure.
577 */
578int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
579
580/* Request avatar information from a friend.
581 * Asks a friend to provide their avatar information (image format and hash). The friend may
582 * or may not answer this request and, if answered, the information will be provided through
583 * the callback 'avatar_info'.
584 *
585 * returns 0 on success
586 * returns -1 on failure.
587 */
588int m_request_avatar_info(const Messenger *m, const int32_t friendnumber);
589
590/* Send an unrequested avatar information to a friend.
591 * Sends our avatar format and hash to a friend; he/she can use this information to validate
592 * an avatar from the cache and may (or not) reply with an avatar data request.
593 *
594 * Notice: it is NOT necessary to send these notification after changing the avatar or
595 * connecting. The library already does this.
596 *
597 * returns 0 on success
598 * returns -1 on failure.
599 */
600int m_send_avatar_info(const Messenger *m, const int32_t friendnumber);
601
602
603/* Request the avatar data from a friend.
604 * Ask a friend to send their avatar data. The friend may or may not answer this request and,
605 * if answered, the information will be provided in callback 'avatar_data'.
606 *
607 * returns 0 on sucess
608 * returns -1 on failure.
609 */
610int m_request_avatar_data(const Messenger *m, const int32_t friendnumber);
611
612
613/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. 442/* returns timestamp of last time friendnumber was seen online, or 0 if never seen.
614 * returns -1 on error. 443 * returns -1 on error.
615 */ 444 */
@@ -702,48 +531,6 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
702 void *userdata); 531 void *userdata);
703 532
704 533
705/* Set the callback function for avatar information.
706 * This callback will be called when avatar information are received from friends. These events
707 * can arrive at anytime, but are usually received uppon connection and in reply of avatar
708 * information requests.
709 *
710 * Function format is:
711 * function(Tox *tox, uint32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
712 *
713 * where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of
714 * the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the
715 * image format is NONE, the hash is zeroed.
716 *
717 */
718void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, void *),
719 void *userdata);
720
721
722/* Set the callback function for avatar data.
723 * This callback will be called when the complete avatar data was correctly received from a
724 * friend. This only happens in reply of a avatar data request (see tox_request_avatar_data);
725 *
726 * Function format is:
727 * function(Tox *tox, uint32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
728 *
729 * where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the
730 * locally-calculated cryptographic hash of the avatar data and it is exactly
731 * AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
732 * of such data.
733 *
734 * If format is NONE, 'data' is NULL, 'datalen' is zero, and the hash is zeroed. The hash is
735 * always validated locally with the function tox_avatar_hash and ensured to match the image
736 * data, so this value can be safely used to compare with cached avatars.
737 *
738 * WARNING: users MUST treat all avatar image data received from another peer as untrusted and
739 * potentially malicious. The library only ensures that the data which arrived is the same the
740 * other user sent, and does not interpret or validate any image data.
741 */
742void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *,
743 uint32_t, void *), void *userdata);
744
745
746
747/**********GROUP CHATS************/ 534/**********GROUP CHATS************/
748 535
749/* Set the callback for group invites. 536/* Set the callback for group invites.