diff options
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r-- | toxcore/Messenger.c | 540 |
1 files changed, 287 insertions, 253 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 7fdae8f0..9889d666 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -1857,347 +1857,381 @@ static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t) | |||
1857 | } | 1857 | } |
1858 | } | 1858 | } |
1859 | 1859 | ||
1860 | /* TODO: Make this function not suck. */ | 1860 | static int handle_status(void *object, int i, uint8_t status) |
1861 | void do_friends(Messenger *m) | ||
1862 | { | 1861 | { |
1863 | uint32_t i; | ||
1864 | int len; | ||
1865 | uint8_t temp[MAX_CRYPTO_DATA_SIZE]; | ||
1866 | uint64_t temp_time = unix_time(); | 1862 | uint64_t temp_time = unix_time(); |
1863 | Messenger *m = object; | ||
1867 | 1864 | ||
1868 | for (i = 0; i < m->numfriends; ++i) { | 1865 | if (status) { /* Went online. */ |
1869 | if (m->friendlist[i].status == FRIEND_ADDED) { | 1866 | set_friend_status(m, i, FRIEND_ONLINE); |
1870 | int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, | 1867 | m->friendlist[i].name_sent = 0; |
1871 | m->friendlist[i].info, | 1868 | m->friendlist[i].userstatus_sent = 0; |
1872 | m->friendlist[i].info_size); | 1869 | m->friendlist[i].statusmessage_sent = 0; |
1870 | m->friendlist[i].ping_lastrecv = temp_time; | ||
1871 | } else { /* Went offline. */ | ||
1872 | m->friendlist[i].crypt_connection_id = -1; | ||
1873 | 1873 | ||
1874 | if (fr >= 0) { | 1874 | if (m->friendlist[i].status == FRIEND_ONLINE) { |
1875 | set_friend_status(m, i, FRIEND_REQUESTED); | 1875 | set_friend_status(m, i, FRIEND_CONFIRMED); |
1876 | m->friendlist[i].friendrequest_lastsent = temp_time; | ||
1877 | } | ||
1878 | } | 1876 | } |
1877 | } | ||
1879 | 1878 | ||
1880 | if (m->friendlist[i].status == FRIEND_REQUESTED | 1879 | return 0; |
1881 | || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online. */ | 1880 | } |
1882 | if (m->friendlist[i].status == FRIEND_REQUESTED) { | ||
1883 | /* If we didn't connect to friend after successfully sending him a friend request the request is deemed | ||
1884 | * unsuccessful so we set the status back to FRIEND_ADDED and try again. | ||
1885 | */ | ||
1886 | check_friend_request_timed_out(m, i, temp_time); | ||
1887 | } | ||
1888 | 1881 | ||
1889 | IP_Port friendip; | 1882 | static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) |
1890 | int friendok = onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip); | 1883 | { |
1884 | if (len == 0) | ||
1885 | return -1; | ||
1891 | 1886 | ||
1892 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { | 1887 | Messenger *m = object; |
1893 | case CRYPTO_CONN_NO_CONNECTION: | 1888 | uint64_t temp_time = unix_time(); |
1894 | if (friendok == 1) | 1889 | uint8_t packet_id = temp[0]; |
1895 | m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); | 1890 | uint8_t *data = temp + 1; |
1891 | uint32_t data_length = len - 1; | ||
1896 | 1892 | ||
1897 | break; | 1893 | if (m->friendlist[i].status != FRIEND_ONLINE) |
1894 | return -1; | ||
1898 | 1895 | ||
1899 | case CRYPTO_CONN_ESTABLISHED: /* Connection is established. */ | 1896 | switch (packet_id) { |
1900 | set_friend_status(m, i, FRIEND_ONLINE); | 1897 | case PACKET_ID_ALIVE: { |
1901 | m->friendlist[i].name_sent = 0; | 1898 | m->friendlist[i].ping_lastrecv = temp_time; |
1902 | m->friendlist[i].userstatus_sent = 0; | 1899 | break; |
1903 | m->friendlist[i].statusmessage_sent = 0; | 1900 | } |
1904 | m->friendlist[i].ping_lastrecv = temp_time; | ||
1905 | break; | ||
1906 | 1901 | ||
1907 | case CRYPTO_CONN_TIMED_OUT: | 1902 | case PACKET_ID_NICKNAME: { |
1908 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | 1903 | if (data_length > MAX_NAME_LENGTH || data_length == 0) |
1909 | m->friendlist[i].crypt_connection_id = -1; | 1904 | break; |
1910 | break; | ||
1911 | 1905 | ||
1912 | default: | 1906 | /* Make sure the NULL terminator is present. */ |
1913 | break; | 1907 | uint8_t data_terminated[data_length + 1]; |
1914 | } | 1908 | memcpy(data_terminated, data, data_length); |
1909 | data_terminated[data_length] = 0; | ||
1910 | |||
1911 | /* inform of namechange before we overwrite the old name */ | ||
1912 | if (m->friend_namechange) | ||
1913 | m->friend_namechange(m, i, data_terminated, data_length, m->friend_namechange_userdata); | ||
1914 | |||
1915 | memcpy(m->friendlist[i].name, data_terminated, data_length); | ||
1916 | m->friendlist[i].name_length = data_length; | ||
1917 | |||
1918 | break; | ||
1915 | } | 1919 | } |
1916 | 1920 | ||
1917 | while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ | 1921 | case PACKET_ID_STATUSMESSAGE: { |
1918 | if (m->friendlist[i].name_sent == 0) { | 1922 | if (data_length == 0 || data_length > MAX_STATUSMESSAGE_LENGTH) |
1919 | if (m_sendname(m, i, m->name, m->name_length)) | 1923 | break; |
1920 | m->friendlist[i].name_sent = 1; | ||
1921 | } | ||
1922 | 1924 | ||
1923 | if (m->friendlist[i].statusmessage_sent == 0) { | 1925 | /* Make sure the NULL terminator is present. */ |
1924 | if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) | 1926 | uint8_t data_terminated[data_length + 1]; |
1925 | m->friendlist[i].statusmessage_sent = 1; | 1927 | memcpy(data_terminated, data, data_length); |
1926 | } | 1928 | data_terminated[data_length] = 0; |
1927 | 1929 | ||
1928 | if (m->friendlist[i].userstatus_sent == 0) { | 1930 | if (m->friend_statusmessagechange) |
1929 | if (send_userstatus(m, i, m->userstatus)) | 1931 | m->friend_statusmessagechange(m, i, data_terminated, data_length, |
1930 | m->friendlist[i].userstatus_sent = 1; | 1932 | m->friend_statuschange_userdata); |
1931 | } | ||
1932 | 1933 | ||
1933 | if (m->friendlist[i].user_istyping_sent == 0) { | 1934 | set_friend_statusmessage(m, i, data_terminated, data_length); |
1934 | if (send_user_istyping(m, i, m->friendlist[i].user_istyping)) | 1935 | break; |
1935 | m->friendlist[i].user_istyping_sent = 1; | 1936 | } |
1936 | } | ||
1937 | 1937 | ||
1938 | if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { | 1938 | case PACKET_ID_USERSTATUS: { |
1939 | send_ping(m, i); | 1939 | if (data_length != 1) |
1940 | } | 1940 | break; |
1941 | |||
1942 | USERSTATUS status = data[0]; | ||
1941 | 1943 | ||
1942 | len = read_cryptpacket(m->net_crypto, m->friendlist[i].crypt_connection_id, temp); | 1944 | if (status >= USERSTATUS_INVALID) |
1945 | break; | ||
1943 | 1946 | ||
1944 | if (len > 0) { | 1947 | if (m->friend_userstatuschange) |
1945 | uint8_t packet_id = temp[0]; | 1948 | m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata); |
1946 | uint8_t *data = temp + 1; | ||
1947 | uint32_t data_length = len - 1; | ||
1948 | 1949 | ||
1949 | switch (packet_id) { | 1950 | set_friend_userstatus(m, i, status); |
1950 | case PACKET_ID_ALIVE: { | 1951 | break; |
1951 | m->friendlist[i].ping_lastrecv = temp_time; | 1952 | } |
1952 | break; | ||
1953 | } | ||
1954 | 1953 | ||
1955 | case PACKET_ID_NICKNAME: { | 1954 | case PACKET_ID_TYPING: { |
1956 | if (data_length > MAX_NAME_LENGTH || data_length == 0) | 1955 | if (data_length != 1) |
1957 | break; | 1956 | break; |
1958 | 1957 | ||
1959 | /* Make sure the NULL terminator is present. */ | 1958 | uint8_t typing = data[0]; |
1960 | uint8_t data_terminated[data_length + 1]; | ||
1961 | memcpy(data_terminated, data, data_length); | ||
1962 | data_terminated[data_length] = 0; | ||
1963 | 1959 | ||
1964 | /* inform of namechange before we overwrite the old name */ | 1960 | set_friend_typing(m, i, typing); |
1965 | if (m->friend_namechange) | ||
1966 | m->friend_namechange(m, i, data_terminated, data_length, m->friend_namechange_userdata); | ||
1967 | 1961 | ||
1968 | memcpy(m->friendlist[i].name, data_terminated, data_length); | 1962 | if (m->friend_typingchange) |
1969 | m->friendlist[i].name_length = data_length; | 1963 | m->friend_typingchange(m, i, typing, m->friend_typingchange_userdata); |
1970 | 1964 | ||
1971 | break; | 1965 | break; |
1972 | } | 1966 | } |
1973 | 1967 | ||
1974 | case PACKET_ID_STATUSMESSAGE: { | 1968 | case PACKET_ID_MESSAGE: { |
1975 | if (data_length == 0 || data_length > MAX_STATUSMESSAGE_LENGTH) | 1969 | uint8_t *message_id = data; |
1976 | break; | 1970 | uint8_t message_id_length = 4; |
1977 | 1971 | ||
1978 | /* Make sure the NULL terminator is present. */ | 1972 | if (data_length <= message_id_length) |
1979 | uint8_t data_terminated[data_length + 1]; | 1973 | break; |
1980 | memcpy(data_terminated, data, data_length); | ||
1981 | data_terminated[data_length] = 0; | ||
1982 | 1974 | ||
1983 | if (m->friend_statusmessagechange) | 1975 | uint8_t *message = data + message_id_length; |
1984 | m->friend_statusmessagechange(m, i, data_terminated, data_length, | 1976 | uint16_t message_length = data_length - message_id_length; |
1985 | m->friend_statuschange_userdata); | ||
1986 | 1977 | ||
1987 | set_friend_statusmessage(m, i, data_terminated, data_length); | 1978 | /* Make sure the NULL terminator is present. */ |
1988 | break; | 1979 | uint8_t message_terminated[message_length + 1]; |
1989 | } | 1980 | memcpy(message_terminated, message, message_length); |
1981 | message_terminated[message_length] = 0; | ||
1990 | 1982 | ||
1991 | case PACKET_ID_USERSTATUS: { | 1983 | if (m->friendlist[i].receives_read_receipts) { |
1992 | if (data_length != 1) | 1984 | write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); |
1993 | break; | 1985 | } |
1994 | 1986 | ||
1995 | USERSTATUS status = data[0]; | 1987 | if (m->friend_message) |
1988 | (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata); | ||
1996 | 1989 | ||
1997 | if (status >= USERSTATUS_INVALID) | 1990 | break; |
1998 | break; | 1991 | } |
1999 | 1992 | ||
2000 | if (m->friend_userstatuschange) | 1993 | case PACKET_ID_ACTION: { |
2001 | m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata); | 1994 | uint8_t *message_id = data; |
1995 | uint8_t message_id_length = 4; | ||
2002 | 1996 | ||
2003 | set_friend_userstatus(m, i, status); | 1997 | if (data_length <= message_id_length) |
2004 | break; | 1998 | break; |
2005 | } | ||
2006 | 1999 | ||
2007 | case PACKET_ID_TYPING: { | 2000 | uint8_t *action = data + message_id_length; |
2008 | if (data_length != 1) | 2001 | uint16_t action_length = data_length - message_id_length; |
2009 | break; | ||
2010 | 2002 | ||
2011 | uint8_t typing = data[0]; | 2003 | /* Make sure the NULL terminator is present. */ |
2004 | uint8_t action_terminated[action_length + 1]; | ||
2005 | memcpy(action_terminated, action, action_length); | ||
2006 | action_terminated[action_length] = 0; | ||
2012 | 2007 | ||
2013 | set_friend_typing(m, i, typing); | 2008 | if (m->friendlist[i].receives_read_receipts) { |
2009 | write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); | ||
2010 | } | ||
2014 | 2011 | ||
2015 | if (m->friend_typingchange) | 2012 | if (m->friend_action) |
2016 | m->friend_typingchange(m, i, typing, m->friend_typingchange_userdata); | 2013 | (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata); |
2017 | 2014 | ||
2018 | break; | 2015 | break; |
2019 | } | 2016 | } |
2017 | |||
2018 | case PACKET_ID_RECEIPT: { | ||
2019 | uint32_t msgid; | ||
2020 | 2020 | ||
2021 | case PACKET_ID_MESSAGE: { | 2021 | if (data_length < sizeof(msgid)) |
2022 | uint8_t *message_id = data; | 2022 | break; |
2023 | uint8_t message_id_length = 4; | ||
2024 | 2023 | ||
2025 | if (data_length <= message_id_length) | 2024 | memcpy(&msgid, data, sizeof(msgid)); |
2026 | break; | 2025 | msgid = ntohl(msgid); |
2027 | 2026 | ||
2028 | uint8_t *message = data + message_id_length; | 2027 | if (m->read_receipt) |
2029 | uint16_t message_length = data_length - message_id_length; | 2028 | (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); |
2030 | 2029 | ||
2031 | /* Make sure the NULL terminator is present. */ | 2030 | break; |
2032 | uint8_t message_terminated[message_length + 1]; | 2031 | } |
2033 | memcpy(message_terminated, message, message_length); | ||
2034 | message_terminated[message_length] = 0; | ||
2035 | 2032 | ||
2036 | if (m->friendlist[i].receives_read_receipts) { | 2033 | case PACKET_ID_INVITE_GROUPCHAT: { |
2037 | write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); | 2034 | if (data_length != crypto_box_PUBLICKEYBYTES) |
2038 | } | 2035 | break; |
2039 | 2036 | ||
2040 | if (m->friend_message) | 2037 | if (m->group_invite) |
2041 | (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata); | 2038 | (*m->group_invite)(m, i, data, m->group_invite_userdata); |
2042 | 2039 | ||
2043 | break; | 2040 | break; |
2044 | } | 2041 | } |
2045 | 2042 | ||
2046 | case PACKET_ID_ACTION: { | 2043 | case PACKET_ID_JOIN_GROUPCHAT: { |
2047 | uint8_t *message_id = data; | 2044 | if (data_length != crypto_box_PUBLICKEYBYTES * 2) |
2048 | uint8_t message_id_length = 4; | 2045 | break; |
2049 | 2046 | ||
2050 | if (data_length <= message_id_length) | 2047 | int groupnum = group_num(m, data); |
2051 | break; | ||
2052 | 2048 | ||
2053 | uint8_t *action = data + message_id_length; | 2049 | if (groupnum == -1) |
2054 | uint16_t action_length = data_length - message_id_length; | 2050 | break; |
2055 | 2051 | ||
2056 | /* Make sure the NULL terminator is present. */ | 2052 | if (!group_invited(m, i, groupnum)) |
2057 | uint8_t action_terminated[action_length + 1]; | 2053 | break; |
2058 | memcpy(action_terminated, action, action_length); | ||
2059 | action_terminated[action_length] = 0; | ||
2060 | 2054 | ||
2061 | if (m->friendlist[i].receives_read_receipts) { | 2055 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); |
2062 | write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); | 2056 | /* This is just there to speedup joining. */ |
2063 | } | 2057 | chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES); |
2058 | break; | ||
2059 | } | ||
2064 | 2060 | ||
2065 | if (m->friend_action) | 2061 | case PACKET_ID_FILE_SENDREQUEST: { |
2066 | (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata); | 2062 | if (data_length < 1 + sizeof(uint64_t) + 1) |
2063 | break; | ||
2067 | 2064 | ||
2068 | break; | 2065 | uint8_t filenumber = data[0]; |
2069 | } | 2066 | uint64_t filesize; |
2067 | net_to_host(data + 1, sizeof(filesize)); | ||
2068 | memcpy(&filesize, data + 1, sizeof(filesize)); | ||
2069 | m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED; | ||
2070 | m->friendlist[i].file_receiving[filenumber].size = filesize; | ||
2071 | m->friendlist[i].file_receiving[filenumber].transferred = 0; | ||
2070 | 2072 | ||
2071 | case PACKET_ID_RECEIPT: { | 2073 | /* Force NULL terminate file name. */ |
2072 | uint32_t msgid; | 2074 | uint8_t filename_terminated[data_length - 1 - sizeof(uint64_t) + 1]; |
2075 | memcpy(filename_terminated, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t)); | ||
2076 | filename_terminated[data_length - 1 - sizeof(uint64_t)] = 0; | ||
2073 | 2077 | ||
2074 | if (data_length < sizeof(msgid)) | 2078 | if (m->file_sendrequest) |
2075 | break; | 2079 | (*m->file_sendrequest)(m, i, filenumber, filesize, filename_terminated, data_length - 1 - sizeof(uint64_t), |
2080 | m->file_sendrequest_userdata); | ||
2076 | 2081 | ||
2077 | memcpy(&msgid, data, sizeof(msgid)); | 2082 | break; |
2078 | msgid = ntohl(msgid); | 2083 | } |
2079 | 2084 | ||
2080 | if (m->read_receipt) | 2085 | case PACKET_ID_FILE_CONTROL: { |
2081 | (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); | 2086 | if (data_length < 3) |
2087 | break; | ||
2082 | 2088 | ||
2083 | break; | 2089 | uint8_t send_receive = data[0]; |
2084 | } | 2090 | uint8_t filenumber = data[1]; |
2091 | uint8_t control_type = data[2]; | ||
2085 | 2092 | ||
2086 | case PACKET_ID_INVITE_GROUPCHAT: { | 2093 | if (handle_filecontrol(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3) == -1) |
2087 | if (data_length != crypto_box_PUBLICKEYBYTES) | 2094 | break; |
2088 | break; | ||
2089 | 2095 | ||
2090 | if (m->group_invite) | 2096 | if (m->file_filecontrol) |
2091 | (*m->group_invite)(m, i, data, m->group_invite_userdata); | 2097 | (*m->file_filecontrol)(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3, |
2098 | m->file_filecontrol_userdata); | ||
2092 | 2099 | ||
2093 | break; | 2100 | break; |
2094 | } | 2101 | } |
2095 | 2102 | ||
2096 | case PACKET_ID_JOIN_GROUPCHAT: { | 2103 | case PACKET_ID_FILE_DATA: { |
2097 | if (data_length != crypto_box_PUBLICKEYBYTES * 2) | 2104 | if (data_length < 2) |
2098 | break; | 2105 | break; |
2099 | 2106 | ||
2100 | int groupnum = group_num(m, data); | 2107 | uint8_t filenumber = data[0]; |
2101 | 2108 | ||
2102 | if (groupnum == -1) | 2109 | if (m->friendlist[i].file_receiving[filenumber].status == FILESTATUS_NONE) |
2103 | break; | 2110 | break; |
2104 | 2111 | ||
2105 | if (!group_invited(m, i, groupnum)) | 2112 | m->friendlist[i].file_receiving[filenumber].transferred += (data_length - 1); |
2106 | break; | ||
2107 | 2113 | ||
2108 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); | 2114 | if (m->file_filedata) |
2109 | /* This is just there to speedup joining. */ | 2115 | (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata); |
2110 | chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES); | ||
2111 | break; | ||
2112 | } | ||
2113 | 2116 | ||
2114 | case PACKET_ID_FILE_SENDREQUEST: { | 2117 | break; |
2115 | if (data_length < 1 + sizeof(uint64_t) + 1) | 2118 | } |
2116 | break; | ||
2117 | 2119 | ||
2118 | uint8_t filenumber = data[0]; | 2120 | case PACKET_ID_MSI: { |
2119 | uint64_t filesize; | 2121 | if (data_length == 0) |
2120 | net_to_host(data + 1, sizeof(filesize)); | 2122 | break; |
2121 | memcpy(&filesize, data + 1, sizeof(filesize)); | ||
2122 | m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED; | ||
2123 | m->friendlist[i].file_receiving[filenumber].size = filesize; | ||
2124 | m->friendlist[i].file_receiving[filenumber].transferred = 0; | ||
2125 | 2123 | ||
2126 | /* Force NULL terminate file name. */ | 2124 | if (m->msi_packet) |
2127 | uint8_t filename_terminated[data_length - 1 - sizeof(uint64_t) + 1]; | 2125 | (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata); |
2128 | memcpy(filename_terminated, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t)); | 2126 | } |
2129 | filename_terminated[data_length - 1 - sizeof(uint64_t)] = 0; | ||
2130 | 2127 | ||
2131 | if (m->file_sendrequest) | 2128 | default: { |
2132 | (*m->file_sendrequest)(m, i, filenumber, filesize, filename_terminated, data_length - 1 - sizeof(uint64_t), | 2129 | break; |
2133 | m->file_sendrequest_userdata); | 2130 | } |
2131 | } | ||
2134 | 2132 | ||
2135 | break; | 2133 | return 0; |
2136 | } | 2134 | } |
2137 | 2135 | ||
2138 | case PACKET_ID_FILE_CONTROL: { | 2136 | static int friend_new_connection(Messenger *m, int32_t friendnumber, uint8_t *real_public_key) |
2139 | if (data_length < 3) | 2137 | { |
2140 | break; | 2138 | if (friend_not_valid(m, friendnumber)) |
2139 | return -1; | ||
2141 | 2140 | ||
2142 | uint8_t send_receive = data[0]; | 2141 | if (m->friendlist[friendnumber].crypt_connection_id != -1) { |
2143 | uint8_t filenumber = data[1]; | 2142 | return -1; |
2144 | uint8_t control_type = data[2]; | 2143 | } |
2145 | 2144 | ||
2146 | if (handle_filecontrol(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3) == -1) | 2145 | int id = new_crypto_connection(m->net_crypto, real_public_key); |
2147 | break; | ||
2148 | 2146 | ||
2149 | if (m->file_filecontrol) | 2147 | if (id == -1) |
2150 | (*m->file_filecontrol)(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3, | 2148 | return -1; |
2151 | m->file_filecontrol_userdata); | ||
2152 | 2149 | ||
2153 | break; | 2150 | m->friendlist[friendnumber].crypt_connection_id = id; |
2154 | } | 2151 | connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber); |
2152 | connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber); | ||
2153 | return 0; | ||
2155 | 2154 | ||
2156 | case PACKET_ID_FILE_DATA: { | 2155 | } |
2157 | if (data_length < 2) | ||
2158 | break; | ||
2159 | 2156 | ||
2160 | uint8_t filenumber = data[0]; | 2157 | /* TODO: Make this function not suck. */ |
2158 | void do_friends(Messenger *m) | ||
2159 | { | ||
2160 | uint32_t i; | ||
2161 | uint64_t temp_time = unix_time(); | ||
2161 | 2162 | ||
2162 | if (m->friendlist[i].file_receiving[filenumber].status == FILESTATUS_NONE) | 2163 | for (i = 0; i < m->numfriends; ++i) { |
2163 | break; | 2164 | if (m->friendlist[i].status == FRIEND_ADDED) { |
2165 | int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, | ||
2166 | m->friendlist[i].info, | ||
2167 | m->friendlist[i].info_size); | ||
2164 | 2168 | ||
2165 | m->friendlist[i].file_receiving[filenumber].transferred += (data_length - 1); | 2169 | if (fr >= 0) { |
2170 | set_friend_status(m, i, FRIEND_REQUESTED); | ||
2171 | m->friendlist[i].friendrequest_lastsent = temp_time; | ||
2172 | } | ||
2173 | } | ||
2166 | 2174 | ||
2167 | if (m->file_filedata) | 2175 | if (m->friendlist[i].status == FRIEND_REQUESTED |
2168 | (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata); | 2176 | || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online. */ |
2177 | if (m->friendlist[i].status == FRIEND_REQUESTED) { | ||
2178 | /* If we didn't connect to friend after successfully sending him a friend request the request is deemed | ||
2179 | * unsuccessful so we set the status back to FRIEND_ADDED and try again. | ||
2180 | */ | ||
2181 | check_friend_request_timed_out(m, i, temp_time); | ||
2182 | } | ||
2169 | 2183 | ||
2170 | break; | 2184 | friend_new_connection(m, i, m->friendlist[i].client_id); |
2171 | } | 2185 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; |
2172 | 2186 | ||
2173 | case PACKET_ID_MSI: { | 2187 | if (onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key) == 0) { |
2174 | if (data_length == 0) | 2188 | set_conection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key); |
2175 | break; | 2189 | } |
2176 | 2190 | ||
2177 | if (m->msi_packet) | 2191 | IP_Port friendip; |
2178 | (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata); | ||
2179 | } | ||
2180 | 2192 | ||
2181 | default: { | 2193 | if (onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip) == 1) { |
2182 | break; | 2194 | set_direct_ip_port(m->net_crypto, m->friendlist[i].crypt_connection_id, friendip); |
2183 | } | 2195 | } |
2184 | } | 2196 | } |
2185 | } else { | ||
2186 | if (is_cryptoconnected(m->net_crypto, | ||
2187 | m->friendlist[i].crypt_connection_id) == CRYPTO_CONN_TIMED_OUT) { /* If the connection timed out, kill it. */ | ||
2188 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | ||
2189 | m->friendlist[i].crypt_connection_id = -1; | ||
2190 | set_friend_status(m, i, FRIEND_CONFIRMED); | ||
2191 | } | ||
2192 | 2197 | ||
2193 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | 2198 | if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ |
2194 | /* If we stopped recieving ping packets, kill it. */ | 2199 | if (m->friendlist[i].name_sent == 0) { |
2195 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | 2200 | if (m_sendname(m, i, m->name, m->name_length)) |
2196 | m->friendlist[i].crypt_connection_id = -1; | 2201 | m->friendlist[i].name_sent = 1; |
2197 | set_friend_status(m, i, FRIEND_CONFIRMED); | 2202 | } |
2198 | } | ||
2199 | 2203 | ||
2200 | break; | 2204 | if (m->friendlist[i].statusmessage_sent == 0) { |
2205 | if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) | ||
2206 | m->friendlist[i].statusmessage_sent = 1; | ||
2207 | } | ||
2208 | |||
2209 | if (m->friendlist[i].userstatus_sent == 0) { | ||
2210 | if (send_userstatus(m, i, m->userstatus)) | ||
2211 | m->friendlist[i].userstatus_sent = 1; | ||
2212 | } | ||
2213 | |||
2214 | if (m->friendlist[i].user_istyping_sent == 0) { | ||
2215 | if (send_user_istyping(m, i, m->friendlist[i].user_istyping)) | ||
2216 | m->friendlist[i].user_istyping_sent = 1; | ||
2217 | } | ||
2218 | |||
2219 | if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { | ||
2220 | send_ping(m, i); | ||
2221 | } | ||
2222 | |||
2223 | if (is_cryptoconnected(m->net_crypto, | ||
2224 | m->friendlist[i].crypt_connection_id) == CRYPTO_CONN_TIMED_OUT) { /* If the connection timed out, kill it. */ | ||
2225 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | ||
2226 | m->friendlist[i].crypt_connection_id = -1; | ||
2227 | set_friend_status(m, i, FRIEND_CONFIRMED); | ||
2228 | } | ||
2229 | |||
2230 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | ||
2231 | /* If we stopped recieving ping packets, kill it. */ | ||
2232 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | ||
2233 | m->friendlist[i].crypt_connection_id = -1; | ||
2234 | set_friend_status(m, i, FRIEND_CONFIRMED); | ||
2201 | } | 2235 | } |
2202 | } | 2236 | } |
2203 | } | 2237 | } |