summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxcore/Messenger.c540
-rw-r--r--toxcore/net_crypto.c141
-rw-r--r--toxcore/net_crypto.h74
-rw-r--r--toxcore/onion_client.c31
-rw-r--r--toxcore/onion_client.h7
5 files changed, 493 insertions, 300 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. */ 1860static int handle_status(void *object, int i, uint8_t status)
1861void 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; 1882static 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: { 2136static 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. */
2158void 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 }
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index a0a913d2..9425afba 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -379,6 +379,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *dat
379 return -1; 379 return -1;
380 380
381 increment_nonce(conn->sent_nonce); 381 increment_nonce(conn->sent_nonce);
382 conn->last_data_packet_sent = current_time(); //TODO remove this.
382 return send_packet_to(c, crypt_connection_id, packet, sizeof(packet)); 383 return send_packet_to(c, crypt_connection_id, packet, sizeof(packet));
383} 384}
384 385
@@ -459,6 +460,7 @@ static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *pack
459 conn->temp_packet = temp_packet; 460 conn->temp_packet = temp_packet;
460 conn->temp_packet_length = length; 461 conn->temp_packet_length = length;
461 conn->temp_packet_sent_time = 0; 462 conn->temp_packet_sent_time = 0;
463 conn->temp_packet_num_sent = 0;
462 return 0; 464 return 0;
463} 465}
464 466
@@ -480,6 +482,7 @@ static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id)
480 conn->temp_packet = 0; 482 conn->temp_packet = 0;
481 conn->temp_packet_length = 0; 483 conn->temp_packet_length = 0;
482 conn->temp_packet_sent_time = 0; 484 conn->temp_packet_sent_time = 0;
485 conn->temp_packet_num_sent = 0;
483 return 0; 486 return 0;
484} 487}
485 488
@@ -503,6 +506,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
503 return -1; 506 return -1;
504 507
505 conn->temp_packet_sent_time = current_time(); 508 conn->temp_packet_sent_time = current_time();
509 ++conn->temp_packet_num_sent;
506 return 0; 510 return 0;
507} 511}
508 512
@@ -594,7 +598,24 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
594 598
595 case NET_PACKET_CRYPTO_DATA: { 599 case NET_PACKET_CRYPTO_DATA: {
596 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) { 600 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) {
597 //TODO 601 uint8_t data[MAX_DATA_DATA_PACKET_SIZE];
602 int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
603
604 if (len == -1)
605 return -1;
606
607 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
608 if (conn->connection_status_callback)
609 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
610
611 clear_temp_packet(c, crypt_connection_id);
612 conn->status = CRYPTO_CONN_ESTABLISHED;
613 }
614
615 if (conn->connection_data_callback)
616 conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, data, len);
617
618 //TODO add buffers and packet requesting.
598 } else { 619 } else {
599 return -1; 620 return -1;
600 } 621 }
@@ -870,6 +891,9 @@ int set_conection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t
870 if (conn == 0) 891 if (conn == 0)
871 return -1; 892 return -1;
872 893
894 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
895 return -1;
896
873 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 897 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
874 conn->dht_public_key_set = 1; 898 conn->dht_public_key_set = 1;
875 899
@@ -908,6 +932,52 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
908 return 0; 932 return 0;
909} 933}
910 934
935/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
936 *
937 * The set function should return -1 on failure and 0 on success.
938 * Note that if this function is set, the connection will clear itself on disconnect.
939 * Object and id will be passed to this function untouched.
940 * status is 1 if the connection is going online, 0 if it is going offline.
941 *
942 * return -1 on failure.
943 * return 0 on success.
944 */
945int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object,
946 int id, uint8_t status), void *object, int id)
947{
948 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
949
950 if (conn == 0)
951 return -1;
952
953 conn->connection_status_callback = connection_status_callback;
954 conn->connection_status_callback_object = object;
955 conn->connection_status_callback_id = id;
956 return 0;
957}
958
959/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
960 *
961 * The set function should return -1 on failure and 0 on success.
962 * Object and id will be passed to this function untouched.
963 *
964 * return -1 on failure.
965 * return 0 on success.
966 */
967int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
968 int id, uint8_t *data, uint16_t length), void *object, int id)
969{
970 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
971
972 if (conn == 0)
973 return -1;
974
975 conn->connection_data_callback = connection_data_callback;
976 conn->connection_data_callback_object = object;
977 conn->connection_data_callback_id = id;
978 return 0;
979}
980
911/* Get the crypto connection id from the ip_port. 981/* Get the crypto connection id from the ip_port.
912 * 982 *
913 * return -1 on failure. 983 * return -1 on failure.
@@ -977,27 +1047,26 @@ static void send_crypto_packets(Net_Crypto *c)
977 if (conn == 0) 1047 if (conn == 0)
978 return; 1048 return;
979 1049
980 if ((CRYPTO_SEND_PACKET_INTERVAL * 1000UL) + conn->temp_packet_sent_time < temp_time) { 1050 if ((CRYPTO_SEND_PACKET_INTERVAL * 1000ULL) + conn->temp_packet_sent_time < temp_time) {
981 send_temp_packet(c, i); 1051 send_temp_packet(c, i);
982 } 1052 }
1053
1054 if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED
1055 && (500ULL * 1000ULL) + conn->last_data_packet_sent < temp_time) {//TODO remove this.
1056 uint8_t data[4] = {};
1057 send_data_packet(c, i, data, 4);
1058 }
983 } 1059 }
984} 1060}
985 1061
986/* return 0 if there is no received data in the buffer.
987 * return -1 if the packet was discarded.
988 * return length of received data if successful.
989 */
990int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
991{
992
993}
994 1062
995/* returns the number of packet slots left in the sendbuffer. 1063/* returns the number of packet slots left in the sendbuffer.
996 * return 0 if failure. 1064 * return 0 if failure.
997 */ 1065 */
998uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) 1066uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
999{ 1067{
1000 1068 //TODO
1069 return 0;
1001} 1070}
1002 1071
1003/* return 0 if data could not be put in packet queue. 1072/* return 0 if data could not be put in packet queue.
@@ -1005,28 +1074,22 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
1005 */ 1074 */
1006int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 1075int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
1007{ 1076{
1077 //TODO
1078 if (send_data_packet(c, crypt_connection_id, data, length) == 0)
1079 return 1;
1008 1080
1009} 1081 return 0;
1010
1011
1012/* Start a secure connection with other peer who has public_key and ip_port.
1013 *
1014 * return -1 if failure.
1015 * return crypt_connection_id of the initialized connection if everything went well.
1016 */
1017int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port)
1018{
1019
1020} 1082}
1021 1083
1022/* Kill a crypto connection. 1084/* Kill a crypto connection.
1023 * 1085 *
1024 * return 0 if killed successfully. 1086 * return -1 on failure.
1025 * return 1 if there was a problem. 1087 * return 0 on success.
1026 */ 1088 */
1027int crypto_kill(Net_Crypto *c, int crypt_connection_id) 1089int crypto_kill(Net_Crypto *c, int crypt_connection_id)
1028{ 1090{
1029 1091 //TODO
1092 return wipe_crypto_connection(c, crypt_connection_id);
1030} 1093}
1031 1094
1032/* return 0 if no connection. 1095/* return 0 if no connection.
@@ -1096,9 +1159,35 @@ Net_Crypto *new_net_crypto(DHT *dht)
1096static void kill_timedout(Net_Crypto *c) 1159static void kill_timedout(Net_Crypto *c)
1097{ 1160{
1098 uint32_t i; 1161 uint32_t i;
1162 uint64_t temp_time = current_time();
1099 1163
1100 for (i = 0; i < c->crypto_connections_length; ++i) { 1164 for (i = 0; i < c->crypto_connections_length; ++i) {
1101//TODO 1165 Crypto_Connection *conn = get_crypto_connection(c, i);
1166
1167 if (conn == 0)
1168 return;
1169
1170 if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT)
1171 continue;
1172
1173 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
1174 || conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
1175 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
1176 continue;
1177
1178 if (conn->connection_status_callback) {
1179 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
1180 crypto_kill(c, i);
1181 continue;
1182 }
1183
1184 conn->status = CRYPTO_CONN_TIMED_OUT;
1185 continue;
1186 }
1187
1188 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
1189 //TODO: add a timeout here?
1190 }
1102 } 1191 }
1103} 1192}
1104 1193
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 3d58e5c1..5d4ff35b 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -44,6 +44,9 @@
44 44
45/* Interval in ms between sending cookie request/handshake packets. */ 45/* Interval in ms between sending cookie request/handshake packets. */
46#define CRYPTO_SEND_PACKET_INTERVAL 500 46#define CRYPTO_SEND_PACKET_INTERVAL 500
47/* The maximum number of times we try to send the cookie request and handshake
48 before giving up. */
49#define MAX_NUM_SENDPACKET_TRIES 10
47 50
48typedef struct { 51typedef struct {
49 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 52 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
@@ -59,8 +62,6 @@ typedef struct {
59 * 4 if the connection is established. 62 * 4 if the connection is established.
60 * 5 if the connection is timed out. 63 * 5 if the connection is timed out.
61 */ 64 */
62 uint64_t timeout;
63
64 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 65 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
65 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ 66 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
66 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */ 67 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
@@ -68,9 +69,20 @@ typedef struct {
68 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 69 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
69 uint16_t temp_packet_length; 70 uint16_t temp_packet_length;
70 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */ 71 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */
72 uint32_t temp_packet_num_sent;
71 73
72 IP_Port ip_port; /* The ip and port to contact this guy directly.*/ 74 IP_Port ip_port; /* The ip and port to contact this guy directly.*/
73 uint64_t direct_lastrecv_time; /* The Time at which we last receive a direct packet. */ 75 uint64_t direct_lastrecv_time; /* The Time at which we last receive a direct packet. */
76
77 int (*connection_status_callback)(void *object, int id, uint8_t status);
78 void *connection_status_callback_object;
79 int connection_status_callback_id;
80
81 int (*connection_data_callback)(void *object, int id, uint8_t *data, uint16_t length);
82 void *connection_data_callback_object;
83 int connection_data_callback_id;
84
85 uint64_t last_data_packet_sent;
74} Crypto_Connection; 86} Crypto_Connection;
75 87
76typedef struct { 88typedef struct {
@@ -117,12 +129,52 @@ void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *
117 */ 129 */
118int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c); 130int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
119 131
132/* Create a crypto connection.
133 * If one to that real public key already exists, return it.
134 *
135 * return -1 on failure.
136 * return connection id on success.
137 */
138int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key);
139
140/* Set the DHT public key of the crypto connection.
141 *
142 * return -1 on failure.
143 * return 0 on success.
144 */
145int set_conection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
146
147/* Set the direct ip of the crypto connection.
148 *
149 * return -1 on failure.
150 * return 0 on success.
151 */
152int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port);
153
154/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
155 *
156 * The set function should return -1 on failure and 0 on success.
157 * Note that if this function is set, the connection will clear itself on disconnect.
158 * Object and id will be passed to this function untouched.
159 * status is 1 if the connection is going online, 0 if it is going offline.
160 *
161 * return -1 on failure.
162 * return 0 on success.
163 */
164int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object,
165 int id, uint8_t status), void *object, int id);
120 166
121/* return 0 if there is no received data in the buffer. 167/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
122 * return -1 if the packet was discarded. 168 *
123 * return length of received data if successful. 169 * The set function should return -1 on failure and 0 on success.
170 * Object and id will be passed to this function untouched.
171 *
172 * return -1 on failure.
173 * return 0 on success.
124 */ 174 */
125int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); 175int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
176 int id, uint8_t *data, uint16_t length), void *object, int id);
177
126 178
127/* returns the number of packet slots left in the sendbuffer. 179/* returns the number of packet slots left in the sendbuffer.
128 * return 0 if failure. 180 * return 0 if failure.
@@ -134,17 +186,11 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
134 */ 186 */
135int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 187int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
136 188
137/* Start a secure connection with other peer who has public_key and ip_port.
138 *
139 * return -1 if failure.
140 * return crypt_connection_id of the initialized connection if everything went well.
141 */
142int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port);
143 189
144/* Kill a crypto connection. 190/* Kill a crypto connection.
145 * 191 *
146 * return 0 if killed successfully. 192 * return -1 on failure.
147 * return 1 if there was a problem. 193 * return 0 on success.
148 */ 194 */
149int crypto_kill(Net_Crypto *c, int crypt_connection_id); 195int crypto_kill(Net_Crypto *c, int crypt_connection_id);
150 196
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index c7ebcd15..ca92ee42 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -796,14 +796,12 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
796 return friend_num; 796 return friend_num;
797} 797}
798 798
799/* Get the ip of friend friendnum and put it in ip_port 799/* Copy friends DHT public key into dht_key.
800 *
801 * return -1, -- if client_id does NOT refer to a friend
802 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
803 * return 1, ip if client_id refers to a friend and we found him
804 * 800 *
801 * return -1 on failure (no key copied).
802 * return 0 on success (key copied).
805 */ 803 */
806int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) 804int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
807{ 805{
808 if ((uint32_t)friend_num >= onion_c->num_friends) 806 if ((uint32_t)friend_num >= onion_c->num_friends)
809 return -1; 807 return -1;
@@ -814,9 +812,28 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
814 if (!onion_c->friends_list[friend_num].is_fake_clientid) 812 if (!onion_c->friends_list[friend_num].is_fake_clientid)
815 return -1; 813 return -1;
816 814
817 return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port); 815 memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES);
816 return 0;
817}
818
819/* Get the ip of friend friendnum and put it in ip_port
820 *
821 * return -1, -- if client_id does NOT refer to a friend
822 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
823 * return 1, ip if client_id refers to a friend and we found him
824 *
825 */
826int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
827{
828 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
829
830 if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) != 0)
831 return -1;
832
833 return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port);
818} 834}
819 835
836
820/* Set if friend is online or not. 837/* Set if friend is online or not.
821 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online. 838 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
822 * 839 *
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index 6b960e40..4affcc6a 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -172,6 +172,13 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
172 */ 172 */
173int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 173int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
174 174
175/* Copy friends DHT public key into dht_key.
176 *
177 * return -1 on failure (no key copied).
178 * return 0 on success (key copied).
179 */
180int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
181
175#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 182#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
176#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) 183#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
177 184