summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 67f7b34f..8229c270 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -168,6 +168,56 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
168 } 168 }
169} 169}
170 170
171static int friend_new_connection(Messenger *m, int32_t friendnumber, const uint8_t *real_public_key);
172/* Callback for DHT ip_port changes. */
173static void dht_ip_callback(void *data, int32_t number, IP_Port ip_port)
174{
175 Messenger *m = data;
176
177 if (friend_not_valid(m, number))
178 return;
179
180 if (m->friendlist[number].crypt_connection_id == -1) {
181 friend_new_connection(m, number, m->friendlist[number].client_id);
182 }
183
184 set_direct_ip_port(m->net_crypto, m->friendlist[number].crypt_connection_id, ip_port);
185 m->friendlist[number].dht_ip_port = ip_port;
186}
187
188/* Callback for dht public key changes. */
189static void dht_pk_callback(void *data, int32_t number, const uint8_t *dht_public_key)
190{
191 Messenger *m = data;
192
193 if (friend_not_valid(m, number))
194 return;
195
196 if (memcmp(m->friendlist[number].dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
197 return;
198
199 if (m->friendlist[number].dht_lock) {
200 if (DHT_delfriend(m->dht, m->friendlist[number].dht_temp_pk, m->friendlist[number].dht_lock) != 0) {
201 printf("a. Could not delete dht peer. Please report this.\n");
202 return;
203 }
204
205 m->friendlist[number].dht_lock = 0;
206 }
207
208 DHT_addfriend(m->dht, dht_public_key, dht_ip_callback, data, number, &m->friendlist[number].dht_lock);
209
210 if (m->friendlist[number].crypt_connection_id == -1) {
211 friend_new_connection(m, number, m->friendlist[number].client_id);
212 }
213
214 set_connection_dht_public_key(m->net_crypto, m->friendlist[number].crypt_connection_id, dht_public_key, current_time_monotonic());
215 onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[number].onion_friendnum, dht_public_key, current_time_monotonic());
216
217 memcpy(m->friendlist[number].dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
218}
219
220
171/* 221/*
172 * Add a friend. 222 * Add a friend.
173 * Set the data that will be sent along with friend request. 223 * Set the data that will be sent along with friend request.
@@ -259,6 +309,7 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u
259 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 309 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
260 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); 310 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
261 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); 311 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
312 onion_dht_pk_callback(m->onion_c, onion_friendnum, &dht_pk_callback, m, i);
262 313
263 if (m->numfriends == i) 314 if (m->numfriends == i)
264 ++m->numfriends; 315 ++m->numfriends;
@@ -312,6 +363,7 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id)
312 m->friendlist[i].message_id = 0; 363 m->friendlist[i].message_id = 0;
313 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 364 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
314 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); 365 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
366 onion_dht_pk_callback(m->onion_c, onion_friendnum, &dht_pk_callback, m, i);
315 367
316 if (m->numfriends == i) 368 if (m->numfriends == i)
317 ++m->numfriends; 369 ++m->numfriends;
@@ -337,6 +389,10 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
337 remove_online_friend(m, friendnumber); 389 remove_online_friend(m, friendnumber);
338 390
339 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); 391 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
392 if (m->friendlist[friendnumber].dht_lock) {
393 DHT_delfriend(m->dht, m->friendlist[friendnumber].dht_temp_pk, m->friendlist[friendnumber].dht_lock);
394 }
395
340 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 396 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
341 free(m->friendlist[friendnumber].statusmessage); 397 free(m->friendlist[friendnumber].statusmessage);
342 free(m->friendlist[friendnumber].avatar_recv_data); 398 free(m->friendlist[friendnumber].avatar_recv_data);
@@ -1567,6 +1623,13 @@ static int handle_new_connections(void *object, New_Connection *n_c)
1567 connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friend_id); 1623 connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friend_id);
1568 m->friendlist[friend_id].crypt_connection_id = id; 1624 m->friendlist[friend_id].crypt_connection_id = id;
1569 set_friend_status(m, friend_id, FRIEND_CONFIRMED); 1625 set_friend_status(m, friend_id, FRIEND_CONFIRMED);
1626
1627 if (n_c->source.ip.family != AF_INET && n_c->source.ip.family != AF_INET6) {
1628 set_direct_ip_port(m->net_crypto, m->friendlist[friend_id].crypt_connection_id, m->friendlist[friend_id].dht_ip_port);
1629 }
1630
1631 dht_pk_callback(m, friend_id, n_c->dht_public_key);
1632
1570 return 0; 1633 return 0;
1571 } 1634 }
1572 1635
@@ -2304,6 +2367,8 @@ static int friend_new_connection(Messenger *m, int32_t friendnumber, const uint8
2304 connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber); 2367 connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber);
2305 connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber); 2368 connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber);
2306 connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friendnumber); 2369 connection_lossy_data_handler(m->net_crypto, id, &handle_custom_lossy_packet, m, friendnumber);
2370 nc_dht_pk_callback(m->net_crypto, id, &dht_pk_callback, m, friendnumber);
2371
2307 return 0; 2372 return 0;
2308} 2373}
2309 2374
@@ -2332,33 +2397,15 @@ void do_friends(Messenger *m)
2332 * unsuccessful so we set the status back to FRIEND_ADDED and try again. 2397 * unsuccessful so we set the status back to FRIEND_ADDED and try again.
2333 */ 2398 */
2334 check_friend_request_timed_out(m, i, temp_time); 2399 check_friend_request_timed_out(m, i, temp_time);
2335 }
2336 2400
2337 friend_new_connection(m, i, m->friendlist[i].client_id); 2401 if (m->friendlist[i].dht_lock)
2338 } 2402 set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, m->friendlist[i].dht_temp_pk, current_time_monotonic());
2339 2403
2340 if (m->friendlist[i].crypt_connection_id != -1) { 2404 set_direct_ip_port(m->net_crypto, m->friendlist[i].crypt_connection_id, m->friendlist[i].dht_ip_port);
2341 uint8_t dht_public_key1[crypto_box_PUBLICKEYBYTES];
2342 uint64_t timestamp1 = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key1);
2343 uint8_t dht_public_key2[crypto_box_PUBLICKEYBYTES];
2344 uint64_t timestamp2 = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key2);
2345 2405
2346 if (timestamp1 > timestamp2) {
2347 set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key1, timestamp1);
2348 } else if (timestamp1 < timestamp2) {
2349 onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key2, timestamp2);
2350 } 2406 }
2351 2407
2352 uint8_t direct_connected; 2408 friend_new_connection(m, i, m->friendlist[i].client_id);
2353 unsigned int status = crypto_connection_status(m->net_crypto, m->friendlist[i].crypt_connection_id, &direct_connected);
2354
2355 if (direct_connected == 0 || status == CRYPTO_CONN_COOKIE_REQUESTING) {
2356 IP_Port friendip;
2357
2358 if (onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip) == 1) {
2359 set_direct_ip_port(m->net_crypto, m->friendlist[i].crypt_connection_id, friendip);
2360 }
2361 }
2362 } 2409 }
2363 2410
2364 if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ 2411 if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */