summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2014-07-21 04:10:05 +0200
committermannol <eniz_vukovic@hotmail.com>2014-07-21 04:10:05 +0200
commit79115259a81dc958041f18573f34299c083cebea (patch)
tree594fbf60dc01e2aa78c775c4e2d9977c5b18752f /toxcore
parent2ca2baf120c5dd4dcdd9c450ef35560b0726136f (diff)
parentb63e4ad88fb93820fb740372f36d74c65b8b7b81 (diff)
Fixed conflicts
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/LAN_discovery.c75
-rw-r--r--toxcore/Messenger.c9
-rw-r--r--toxcore/TCP_client.c178
-rw-r--r--toxcore/TCP_client.h5
-rw-r--r--toxcore/TCP_server.c125
-rw-r--r--toxcore/TCP_server.h10
-rw-r--r--toxcore/group_chats.c11
-rw-r--r--toxcore/net_crypto.c70
-rw-r--r--toxcore/net_crypto.h4
-rw-r--r--toxcore/network.c26
-rw-r--r--toxcore/network.h15
-rw-r--r--toxcore/onion_client.c2
-rw-r--r--toxcore/ping_array.c2
-rw-r--r--toxcore/tox.h14
14 files changed, 422 insertions, 124 deletions
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index e1b8534c..420c490d 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -30,11 +30,72 @@
30 30
31#define MAX_INTERFACES 16 31#define MAX_INTERFACES 16
32 32
33#ifdef __linux
34 33
35static int broadcast_count = -1; 34static int broadcast_count = -1;
36static IP_Port broadcast_ip_port[MAX_INTERFACES]; 35static IP_Port broadcast_ip_port[MAX_INTERFACES];
37 36
37#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
38
39#include <iphlpapi.h>
40
41static void fetch_broadcast_info(uint16_t port)
42{
43 broadcast_count = 0;
44
45 IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(pAdapterInfo));
46 unsigned long ulOutBufLen = sizeof(pAdapterInfo);
47
48 if (pAdapterInfo == NULL) {
49 printf("Error allocating memory for pAdapterInfo\n");
50 return;
51 }
52
53 if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
54 free(pAdapterInfo);
55 pAdapterInfo = malloc(ulOutBufLen);
56
57 if (pAdapterInfo == NULL) {
58 printf("Error allocating memory needed to call GetAdaptersinfo\n");
59 return;
60 }
61 }
62
63 int ret;
64
65 if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
66 IP_ADAPTER_INFO *pAdapter = pAdapterInfo;
67
68 while (pAdapter) {
69 IP gateway = {0}, subnet_mask = {0};
70
71 if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask)
72 && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) {
73 if (gateway.family == AF_INET && subnet_mask.family == AF_INET) {
74 IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
75 ip_port->ip.family = AF_INET;
76 uint32_t gateway_ip = ntohl(gateway.ip4.uint32), subnet_ip = ntohl(subnet_mask.ip4.uint32);
77 uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1;
78 ip_port->ip.ip4.uint32 = htonl(broadcast_ip);
79 ip_port->port = port;
80 broadcast_count++;
81 printf("broadcast ip: %s\n", ip_ntoa(&ip_port->ip));
82
83 if (broadcast_count >= MAX_INTERFACES) {
84 return;
85 }
86 }
87 }
88
89 pAdapter = pAdapter->Next;
90 }
91 } else {
92 printf("Fetching adapter info failed %i\n", ret);
93 }
94
95}
96
97#elif defined(__linux__)
98
38static void fetch_broadcast_info(uint16_t port) 99static void fetch_broadcast_info(uint16_t port)
39{ 100{
40 /* Not sure how many platforms this will run on, 101 /* Not sure how many platforms this will run on,
@@ -93,6 +154,14 @@ static void fetch_broadcast_info(uint16_t port)
93 close(sock); 154 close(sock);
94} 155}
95 156
157#else //TODO: Other platforms?
158
159static void fetch_broadcast_info(uint16_t port)
160{
161 broadcast_count = 0;
162}
163
164#endif
96/* Send packet to all IPv4 broadcast addresses 165/* Send packet to all IPv4 broadcast addresses
97 * 166 *
98 * return 1 if sent to at least one broadcast target. 167 * return 1 if sent to at least one broadcast target.
@@ -115,7 +184,6 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8
115 184
116 return 1; 185 return 1;
117} 186}
118#endif /* __linux */
119 187
120/* Return the broadcast ip. */ 188/* Return the broadcast ip. */
121static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) 189static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
@@ -228,9 +296,8 @@ int send_LANdiscovery(uint16_t port, DHT *dht)
228 data[0] = NET_PACKET_LAN_DISCOVERY; 296 data[0] = NET_PACKET_LAN_DISCOVERY;
229 id_copy(data + 1, dht->self_public_key); 297 id_copy(data + 1, dht->self_public_key);
230 298
231#ifdef __linux
232 send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); 299 send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
233#endif 300
234 int res = -1; 301 int res = -1;
235 IP_Port ip_port; 302 IP_Port ip_port;
236 ip_port.port = port; 303 ip_port.port = port;
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 4344fdcb..b65f09ae 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -1206,8 +1206,10 @@ int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_gro
1206 1206
1207 IP_Port friend_ip = get_friend_ipport(m, friendnumber); 1207 IP_Port friend_ip = get_friend_ipport(m, friendnumber);
1208 1208
1209 if (friend_ip.ip.family == 0) 1209 if (friend_ip.ip.family == 0) {
1210 del_groupchat(m, groupnum);
1210 return -1; 1211 return -1;
1212 }
1211 1213
1212 id_copy(data, friend_group_public_key); 1214 id_copy(data, friend_group_public_key);
1213 id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key); 1215 id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key);
@@ -1218,6 +1220,7 @@ int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_gro
1218 return groupnum; 1220 return groupnum;
1219 } 1221 }
1220 1222
1223 del_groupchat(m, groupnum);
1221 return -1; 1224 return -1;
1222} 1225}
1223 1226
@@ -2598,6 +2601,10 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
2598 2601
2599 if (temp.status >= 3) { 2602 if (temp.status >= 3) {
2600 int fnum = m_addfriend_norequest(m, temp.client_id); 2603 int fnum = m_addfriend_norequest(m, temp.client_id);
2604
2605 if (fnum < 0)
2606 continue;
2607
2601 setfriendname(m, fnum, temp.name, ntohs(temp.name_length)); 2608 setfriendname(m, fnum, temp.name, ntohs(temp.name_length));
2602 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length)); 2609 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length));
2603 set_friend_userstatus(m, fnum, temp.userstatus); 2610 set_friend_userstatus(m, fnum, temp.userstatus);
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 087188f7..45220538 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -109,7 +109,7 @@ static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data
109/* return 0 if pending data was sent completely 109/* return 0 if pending data was sent completely
110 * return -1 if it wasn't 110 * return -1 if it wasn't
111 */ 111 */
112static int send_pending_data(TCP_Client_Connection *con) 112static int send_pending_data_nonpriority(TCP_Client_Connection *con)
113{ 113{
114 if (con->last_packet_length == 0) { 114 if (con->last_packet_length == 0) {
115 return 0; 115 return 0;
@@ -127,24 +127,95 @@ static int send_pending_data(TCP_Client_Connection *con)
127 return 0; 127 return 0;
128 } 128 }
129 129
130 if (len > left) 130 con->last_packet_sent += len;
131 return -1;
132}
133
134/* return 0 if pending data was sent completely
135 * return -1 if it wasn't
136 */
137static int send_pending_data(TCP_Client_Connection *con)
138{
139 /* finish sending current non-priority packet */
140 if (send_pending_data_nonpriority(con) == -1) {
131 return -1; 141 return -1;
142 }
143
144 TCP_Priority_List *p = con->priority_queue_start;
145
146 while (p) {
147 uint16_t left = p->size - p->sent;
148 int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL);
149
150 if (len != left) {
151 if (len > 0) {
152 p->sent += len;
153 }
154
155 break;
156 }
157
158 TCP_Priority_List *pp = p;
159 p = p->next;
160 free(pp);
161 }
162
163 con->priority_queue_start = p;
164
165 if (!p) {
166 con->priority_queue_end = NULL;
167 return 0;
168 }
132 169
133 con->last_packet_sent += len;
134 return -1; 170 return -1;
135} 171}
136 172
173/* return 0 on failure (only if malloc fails)
174 * return 1 on success
175 */
176static _Bool add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
177{
178 TCP_Priority_List *p = con->priority_queue_end, *new;
179 new = malloc(sizeof(TCP_Priority_List) + size);
180
181 if (!new) {
182 return 0;
183 }
184
185 new->next = NULL;
186 new->size = size;
187 new->sent = sent;
188 memcpy(new->data, packet, size);
189
190 if (p) {
191 p->next = new;
192 } else {
193 con->priority_queue_start = new;
194 }
195
196 con->priority_queue_end = new;
197 return 1;
198}
199
137/* return 1 on success. 200/* return 1 on success.
138 * return 0 if could not send packet. 201 * return 0 if could not send packet.
139 * return -1 on failure (connection must be killed). 202 * return -1 on failure (connection must be killed).
140 */ 203 */
141static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length) 204static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length,
205 _Bool priority)
142{ 206{
143 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 207 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
144 return -1; 208 return -1;
145 209
146 if (send_pending_data(con) == -1) 210 _Bool sendpriority = 1;
147 return 0; 211
212 if (send_pending_data(con) == -1) {
213 if (priority) {
214 sendpriority = 0;
215 } else {
216 return 0;
217 }
218 }
148 219
149 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; 220 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
150 221
@@ -155,17 +226,33 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const
155 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) 226 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
156 return -1; 227 return -1;
157 228
158 increment_nonce(con->sent_nonce); 229 if (priority) {
230 len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0;
159 231
160 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); 232 if (len <= 0) {
233 len = 0;
234 }
161 235
162 if ((unsigned int)len == sizeof(packet)) 236 increment_nonce(con->sent_nonce);
163 return 1; 237
238 if (len == sizeof(packet)) {
239 return 1;
240 }
241
242 return add_priority(con, packet, sizeof(packet), len);
243 }
244
245 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
164 246
165 if (len <= 0) 247 if (len <= 0)
166 return 0; 248 return 0;
167 249
168 memcpy(con->last_packet, packet, length); 250 increment_nonce(con->sent_nonce);
251
252 if ((unsigned int)len == sizeof(packet))
253 return 1;
254
255 memcpy(con->last_packet, packet, sizeof(packet));
169 con->last_packet_length = sizeof(packet); 256 con->last_packet_length = sizeof(packet);
170 con->last_packet_sent = len; 257 con->last_packet_sent = len;
171 return 1; 258 return 1;
@@ -180,7 +267,7 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
180 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES]; 267 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES];
181 packet[0] = TCP_PACKET_ROUTING_REQUEST; 268 packet[0] = TCP_PACKET_ROUTING_REQUEST;
182 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 269 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
183 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 270 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
184} 271}
185 272
186void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 273void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
@@ -197,6 +284,9 @@ void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(v
197 con->status_callback_object = object; 284 con->status_callback_object = object;
198} 285}
199 286
287static int send_ping_response(TCP_Client_Connection *con);
288static int send_ping_request(TCP_Client_Connection *con);
289
200/* return 1 on success. 290/* return 1 on success.
201 * return 0 if could not send packet. 291 * return 0 if could not send packet.
202 * return -1 on failure. 292 * return -1 on failure.
@@ -209,10 +299,13 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u
209 if (con->connections[con_id].status != 2) 299 if (con->connections[con_id].status != 2)
210 return -1; 300 return -1;
211 301
302 if (send_ping_response(con) == 0 || send_ping_request(con) == 0)
303 return 0;
304
212 uint8_t packet[1 + length]; 305 uint8_t packet[1 + length];
213 packet[0] = con_id + NUM_RESERVED_PORTS; 306 packet[0] = con_id + NUM_RESERVED_PORTS;
214 memcpy(packet + 1, data, length); 307 memcpy(packet + 1, data, length);
215 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 308 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
216} 309}
217 310
218/* return 1 on success. 311/* return 1 on success.
@@ -228,7 +321,7 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const
228 packet[0] = TCP_PACKET_OOB_SEND; 321 packet[0] = TCP_PACKET_OOB_SEND;
229 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 322 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
230 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); 323 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
231 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 324 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
232} 325}
233 326
234 327
@@ -274,31 +367,49 @@ static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
274 uint8_t packet[1 + 1]; 367 uint8_t packet[1 + 1];
275 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION; 368 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
276 packet[1] = id; 369 packet[1] = id;
277 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 370 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
278} 371}
279 372
280/* return 1 on success. 373/* return 1 on success.
281 * return 0 if could not send packet. 374 * return 0 if could not send packet.
282 * return -1 on failure (connection must be killed). 375 * return -1 on failure (connection must be killed).
283 */ 376 */
284static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id) 377static int send_ping_request(TCP_Client_Connection *con)
285{ 378{
379 if (!con->ping_request_id)
380 return 1;
381
286 uint8_t packet[1 + sizeof(uint64_t)]; 382 uint8_t packet[1 + sizeof(uint64_t)];
287 packet[0] = TCP_PACKET_PING; 383 packet[0] = TCP_PACKET_PING;
288 memcpy(packet + 1, &ping_id, sizeof(uint64_t)); 384 memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
289 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 385 int ret;
386
387 if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
388 con->ping_request_id = 0;
389 }
390
391 return ret;
290} 392}
291 393
292/* return 1 on success. 394/* return 1 on success.
293 * return 0 if could not send packet. 395 * return 0 if could not send packet.
294 * return -1 on failure (connection must be killed). 396 * return -1 on failure (connection must be killed).
295 */ 397 */
296static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id) 398static int send_ping_response(TCP_Client_Connection *con)
297{ 399{
400 if (!con->ping_response_id)
401 return 1;
402
298 uint8_t packet[1 + sizeof(uint64_t)]; 403 uint8_t packet[1 + sizeof(uint64_t)];
299 packet[0] = TCP_PACKET_PONG; 404 packet[0] = TCP_PACKET_PONG;
300 memcpy(packet + 1, &ping_id, sizeof(uint64_t)); 405 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
301 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 406 int ret;
407
408 if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
409 con->ping_response_id = 0;
410 }
411
412 return ret;
302} 413}
303 414
304/* return 1 on success. 415/* return 1 on success.
@@ -324,7 +435,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t
324 uint8_t packet[1 + length]; 435 uint8_t packet[1 + length];
325 packet[0] = TCP_PACKET_ONION_REQUEST; 436 packet[0] = TCP_PACKET_ONION_REQUEST;
326 memcpy(packet + 1, data, length); 437 memcpy(packet + 1, data, length);
327 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 438 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
328} 439}
329 440
330void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, 441void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data,
@@ -427,7 +538,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
427 uint8_t con_id = data[1] - NUM_RESERVED_PORTS; 538 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
428 539
429 if (conn->connections[con_id].status != 1) 540 if (conn->connections[con_id].status != 1)
430 return -1; 541 return 0;
431 542
432 conn->connections[con_id].status = 2; 543 conn->connections[con_id].status = 2;
433 544
@@ -451,7 +562,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
451 return 0; 562 return 0;
452 563
453 if (conn->connections[con_id].status != 2) 564 if (conn->connections[con_id].status != 2)
454 return -1; 565 return 0;
455 566
456 conn->connections[con_id].status = 1; 567 conn->connections[con_id].status = 1;
457 568
@@ -468,7 +579,8 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
468 579
469 uint64_t ping_id; 580 uint64_t ping_id;
470 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 581 memcpy(&ping_id, data + 1, sizeof(uint64_t));
471 send_ping_response(conn, ping_id); 582 conn->ping_response_id = ping_id;
583 send_ping_response(conn);
472 return 0; 584 return 0;
473 } 585 }
474 586
@@ -523,6 +635,9 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
523static int do_confirmed_TCP(TCP_Client_Connection *conn) 635static int do_confirmed_TCP(TCP_Client_Connection *conn)
524{ 636{
525 send_pending_data(conn); 637 send_pending_data(conn);
638 send_ping_response(conn);
639 send_ping_request(conn);
640
526 uint8_t packet[MAX_PACKET_SIZE]; 641 uint8_t packet[MAX_PACKET_SIZE];
527 int len; 642 int len;
528 643
@@ -532,16 +647,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn)
532 if (!ping_id) 647 if (!ping_id)
533 ++ping_id; 648 ++ping_id;
534 649
535 int ret = send_ping_request(conn, ping_id); 650 conn->ping_request_id = conn->ping_id = ping_id;
536 651 send_ping_request(conn);
537 if (ret == 1) { 652 conn->last_pinged = unix_time();
538 conn->last_pinged = unix_time();
539 conn->ping_id = ping_id;
540 } else {
541 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
542 conn->status = TCP_CLIENT_DISCONNECTED;
543 }
544 }
545 } 653 }
546 654
547 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { 655 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index 2622b4f7..9998d20c 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -52,11 +52,16 @@ typedef struct {
52 uint16_t last_packet_length; 52 uint16_t last_packet_length;
53 uint16_t last_packet_sent; 53 uint16_t last_packet_sent;
54 54
55 TCP_Priority_List *priority_queue_start, *priority_queue_end;
56
55 uint64_t kill_at; 57 uint64_t kill_at;
56 58
57 uint64_t last_pinged; 59 uint64_t last_pinged;
58 uint64_t ping_id; 60 uint64_t ping_id;
59 61
62 uint64_t ping_response_id;
63 uint64_t ping_request_id;
64
60 void *net_crypto_pointer; 65 void *net_crypto_pointer;
61 uint32_t net_crypto_location; 66 uint32_t net_crypto_location;
62 struct { 67 struct {
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 7487ad4f..47e2ff27 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -288,7 +288,7 @@ int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length,
288/* return 0 if pending data was sent completely 288/* return 0 if pending data was sent completely
289 * return -1 if it wasn't 289 * return -1 if it wasn't
290 */ 290 */
291static int send_pending_data(TCP_Secure_Connection *con) 291static int send_pending_data_nonpriority(TCP_Secure_Connection *con)
292{ 292{
293 if (con->last_packet_length == 0) { 293 if (con->last_packet_length == 0) {
294 return 0; 294 return 0;
@@ -306,25 +306,96 @@ static int send_pending_data(TCP_Secure_Connection *con)
306 return 0; 306 return 0;
307 } 307 }
308 308
309 if (len > left) 309 con->last_packet_sent += len;
310 return -1;
311
312}
313
314/* return 0 if pending data was sent completely
315 * return -1 if it wasn't
316 */
317static int send_pending_data(TCP_Secure_Connection *con)
318{
319 /* finish sending current non-priority packet */
320 if (send_pending_data_nonpriority(con) == -1) {
310 return -1; 321 return -1;
322 }
323
324 TCP_Priority_List *p = con->priority_queue_start;
325
326 while (p) {
327 uint16_t left = p->size - p->sent;
328 int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL);
329
330 if (len != left) {
331 if (len > 0) {
332 p->sent += len;
333 }
334
335 break;
336 }
337
338 TCP_Priority_List *pp = p;
339 p = p->next;
340 free(pp);
341 }
342
343 con->priority_queue_start = p;
344
345 if (!p) {
346 con->priority_queue_end = NULL;
347 return 0;
348 }
311 349
312 con->last_packet_sent += len;
313 return -1; 350 return -1;
351}
352
353/* return 0 on failure (only if malloc fails)
354 * return 1 on success
355 */
356static _Bool add_priority(TCP_Secure_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
357{
358 TCP_Priority_List *p = con->priority_queue_end, *new;
359 new = malloc(sizeof(TCP_Priority_List) + size);
314 360
361 if (!new) {
362 return 0;
363 }
364
365 new->next = NULL;
366 new->size = size;
367 new->sent = sent;
368 memcpy(new->data, packet, size);
369
370 if (p) {
371 p->next = new;
372 } else {
373 con->priority_queue_start = new;
374 }
375
376 con->priority_queue_end = new;
377 return 1;
315} 378}
316 379
317/* return 1 on success. 380/* return 1 on success.
318 * return 0 if could not send packet. 381 * return 0 if could not send packet.
319 * return -1 on failure (connection must be killed). 382 * return -1 on failure (connection must be killed).
320 */ 383 */
321static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length) 384static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
385 _Bool priority)
322{ 386{
323 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 387 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
324 return -1; 388 return -1;
325 389
326 if (send_pending_data(con) == -1) 390 _Bool sendpriority = 1;
327 return 0; 391
392 if (send_pending_data(con) == -1) {
393 if (priority) {
394 sendpriority = 0;
395 } else {
396 return 0;
397 }
398 }
328 399
329 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; 400 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
330 401
@@ -335,17 +406,33 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const
335 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) 406 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
336 return -1; 407 return -1;
337 408
338 increment_nonce(con->sent_nonce); 409 if (priority) {
410 len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0;
339 411
340 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); 412 if (len <= 0) {
413 len = 0;
414 }
341 415
342 if ((unsigned int)len == sizeof(packet)) 416 increment_nonce(con->sent_nonce);
343 return 1; 417
418 if (len == sizeof(packet)) {
419 return 1;
420 }
421
422 return add_priority(con, packet, sizeof(packet), len);
423 }
424
425 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
344 426
345 if (len <= 0) 427 if (len <= 0)
346 return 0; 428 return 0;
347 429
348 memcpy(con->last_packet, packet, length); 430 increment_nonce(con->sent_nonce);
431
432 if ((unsigned int)len == sizeof(packet))
433 return 1;
434
435 memcpy(con->last_packet, packet, sizeof(packet));
349 con->last_packet_length = sizeof(packet); 436 con->last_packet_length = sizeof(packet);
350 con->last_packet_sent = len; 437 con->last_packet_sent = len;
351 return 1; 438 return 1;
@@ -459,7 +546,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const
459 data[1] = rpid; 546 data[1] = rpid;
460 memcpy(data + 2, public_key, crypto_box_PUBLICKEYBYTES); 547 memcpy(data + 2, public_key, crypto_box_PUBLICKEYBYTES);
461 548
462 return write_packet_TCP_secure_connection(con, data, sizeof(data)); 549 return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
463} 550}
464 551
465/* return 1 on success. 552/* return 1 on success.
@@ -469,7 +556,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const
469static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id) 556static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
470{ 557{
471 uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS}; 558 uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS};
472 return write_packet_TCP_secure_connection(con, data, sizeof(data)); 559 return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
473} 560}
474 561
475/* return 1 on success. 562/* return 1 on success.
@@ -479,7 +566,7 @@ static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
479static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) 566static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
480{ 567{
481 uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS}; 568 uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS};
482 return write_packet_TCP_secure_connection(con, data, sizeof(data)); 569 return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
483} 570}
484 571
485/* return 0 on success. 572/* return 0 on success.
@@ -579,7 +666,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui
579 memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES); 666 memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES);
580 memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); 667 memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
581 write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, 668 write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet,
582 sizeof(resp_packet)); 669 sizeof(resp_packet), 0);
583 } 670 }
584 671
585 return 0; 672 return 0;
@@ -637,7 +724,7 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
637 memcpy(packet + 1, data, length); 724 memcpy(packet + 1, data, length);
638 packet[0] = TCP_PACKET_ONION_RESPONSE; 725 packet[0] = TCP_PACKET_ONION_RESPONSE;
639 726
640 if (write_packet_TCP_secure_connection(con, packet, sizeof(packet)) != 1) 727 if (write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0) != 1)
641 return 1; 728 return 1;
642 729
643 return 0; 730 return 0;
@@ -682,7 +769,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
682 uint8_t response[1 + sizeof(uint64_t)]; 769 uint8_t response[1 + sizeof(uint64_t)];
683 response[0] = TCP_PACKET_PONG; 770 response[0] = TCP_PACKET_PONG;
684 memcpy(response + 1, data + 1, sizeof(uint64_t)); 771 memcpy(response + 1, data + 1, sizeof(uint64_t));
685 write_packet_TCP_secure_connection(con, response, sizeof(response)); 772 write_packet_TCP_secure_connection(con, response, sizeof(response), 1);
686 return 0; 773 return 0;
687 } 774 }
688 775
@@ -752,7 +839,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
752 uint8_t new_data[length]; 839 uint8_t new_data[length];
753 memcpy(new_data, data, length); 840 memcpy(new_data, data, length);
754 new_data[0] = other_c_id; 841 new_data[0] = other_c_id;
755 int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length); 842 int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0);
756 843
757 if (ret == -1) 844 if (ret == -1)
758 return -1; 845 return -1;
@@ -1058,7 +1145,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
1058 ++ping_id; 1145 ++ping_id;
1059 1146
1060 memcpy(ping + 1, &ping_id, sizeof(uint64_t)); 1147 memcpy(ping + 1, &ping_id, sizeof(uint64_t));
1061 int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping)); 1148 int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping), 1);
1062 1149
1063 if (ret == 1) { 1150 if (ret == 1) {
1064 conn->last_pinged = unix_time(); 1151 conn->last_pinged = unix_time();
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index def0a978..81507acb 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -80,6 +80,14 @@ enum {
80 TCP_STATUS_CONFIRMED, 80 TCP_STATUS_CONFIRMED,
81}; 81};
82 82
83typedef struct TCP_Priority_List TCP_Priority_List;
84
85struct TCP_Priority_List {
86 TCP_Priority_List *next;
87 uint16_t size, sent;
88 uint8_t data[0];
89};
90
83typedef struct TCP_Secure_Connection { 91typedef struct TCP_Secure_Connection {
84 uint8_t status; 92 uint8_t status;
85 sock_t sock; 93 sock_t sock;
@@ -98,6 +106,8 @@ typedef struct TCP_Secure_Connection {
98 uint16_t last_packet_length; 106 uint16_t last_packet_length;
99 uint16_t last_packet_sent; 107 uint16_t last_packet_sent;
100 108
109 TCP_Priority_List *priority_queue_start, *priority_queue_end;
110
101 uint64_t identifier; 111 uint64_t identifier;
102 112
103 uint64_t last_pinged; 113 uint64_t last_pinged;
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c
index 1f76878b..77fa6acd 100644
--- a/toxcore/group_chats.c
+++ b/toxcore/group_chats.c
@@ -471,16 +471,6 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, const
471 471
472 int ok = add_closepeer(chat, chat->group[peernum].client_id, source); 472 int ok = add_closepeer(chat, chat->group[peernum].client_id, source);
473 473
474 if (chat->assoc) {
475 ippts_send.ip_port = chat->group[peernum].ping_via;
476 ippts_send.timestamp = chat->group[peernum].last_pinged;
477
478 IP_Port ipp_recv;
479 ipp_recv = source;
480
481 Assoc_add_entry(chat->assoc, contents.nodes[i].client_id, &ippts_send, &ipp_recv, ok == 0 ? 1 : 0);
482 }
483
484 return 0; 474 return 0;
485} 475}
486 476
@@ -830,6 +820,7 @@ void do_groupchat(Group_Chat *chat)
830void kill_groupchat(Group_Chat *chat) 820void kill_groupchat(Group_Chat *chat)
831{ 821{
832 send_data(chat, 0, 0, GROUP_CHAT_QUIT); 822 send_data(chat, 0, 0, GROUP_CHAT_QUIT);
823 kill_Assoc(chat->assoc);
833 free(chat->group); 824 free(chat->group);
834 free(chat); 825 free(chat);
835} 826}
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index e0319f34..ac2359ee 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -37,21 +37,6 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn
37 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 37 return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
38} 38}
39 39
40/* return 0 if connection is dead.
41 * return 1 if connection is alive.
42 */
43static int is_alive(uint8_t status)
44{
45 if (status == CRYPTO_CONN_COOKIE_REQUESTING ||
46 status == CRYPTO_CONN_HANDSHAKE_SENT ||
47 status == CRYPTO_CONN_NOT_CONFIRMED ||
48 status == CRYPTO_CONN_ESTABLISHED) {
49 return 1;
50 }
51
52 return 0;
53}
54
55/* cookie timeout in seconds */ 40/* cookie timeout in seconds */
56#define COOKIE_TIMEOUT 10 41#define COOKIE_TIMEOUT 10
57#define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2) 42#define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2)
@@ -426,19 +411,22 @@ static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const ui
426 411
427 } 412 }
428 413
429 //TODO: spread packets over many relays, detect and kill bad relays. 414 //TODO: detect and kill bad relays.
430 uint32_t i; 415 uint32_t i;
431 416
417 unsigned int r = rand();
418
432 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 419 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
433 if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ 420 if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
434 if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) 421 if (send_data(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->con_number_tcp[(i + r) % MAX_TCP_CONNECTIONS],
422 data, length) == 1)
435 return 0; 423 return 0;
436 } 424 }
437 } 425 }
438 426
439 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 427 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
440 if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) { 428 if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_INVISIBLE) {
441 if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1) 429 if (send_oob_packet(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->dht_public_key, data, length) == 1)
442 return 0; 430 return 0;
443 } 431 }
444 } 432 }
@@ -1106,6 +1094,14 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
1106 return -1; 1094 return -1;
1107 } 1095 }
1108 1096
1097 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
1098 clear_temp_packet(c, crypt_connection_id);
1099 conn->status = CRYPTO_CONN_ESTABLISHED;
1100
1101 if (conn->connection_status_callback)
1102 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
1103 }
1104
1109 if (real_data[0] == PACKET_ID_REQUEST) { 1105 if (real_data[0] == PACKET_ID_REQUEST) {
1110 int requested = handle_request_packet(&conn->send_array, real_data, real_length); 1106 int requested = handle_request_packet(&conn->send_array, real_data, real_length);
1111 1107
@@ -1148,14 +1144,6 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
1148 return -1; 1144 return -1;
1149 } 1145 }
1150 1146
1151 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
1152 if (conn->connection_status_callback)
1153 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
1154
1155 clear_temp_packet(c, crypt_connection_id);
1156 conn->status = CRYPTO_CONN_ESTABLISHED;
1157 }
1158
1159 return 0; 1147 return 0;
1160} 1148}
1161 1149
@@ -1485,6 +1473,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1485 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1473 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1486 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic()); 1474 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
1487 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1475 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1476 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1488 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1477 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
1489 return crypt_connection_id; 1478 return crypt_connection_id;
1490} 1479}
@@ -1517,6 +1506,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1517 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1506 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1518 conn->status = CRYPTO_CONN_COOKIE_REQUESTING; 1507 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1519 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1508 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1509 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1520 return crypt_connection_id; 1510 return crypt_connection_id;
1521} 1511}
1522 1512
@@ -2250,6 +2240,15 @@ static void send_crypto_packets(Net_Crypto *c)
2250 notes: needs improvement but seems to work fine for packet loss <1% 2240 notes: needs improvement but seems to work fine for packet loss <1%
2251 */ 2241 */
2252 2242
2243 /* additional step: adjust the send rate based on the size change of the send queue */
2244 uint32_t queue_size = num_packets_array(&conn->send_array);
2245
2246 if (queue_size > conn->packet_send_rate && queue_size > conn->last_queue_size) {
2247 conn->rate_increase = 0;
2248 conn->packets_resent = conn->packets_sent;
2249 }
2250
2251
2253 //hack to prevent 1 packet lost from affecting calculations at low send rates 2252 //hack to prevent 1 packet lost from affecting calculations at low send rates
2254 if (conn->packets_resent == 1) { 2253 if (conn->packets_resent == 1) {
2255 conn->packets_resent = 0; 2254 conn->packets_resent = 0;
@@ -2300,18 +2299,27 @@ static void send_crypto_packets(Net_Crypto *c)
2300 double linear_increase = realrate * 0.0025 + 1.0; 2299 double linear_increase = realrate * 0.0025 + 1.0;
2301 2300
2302 //final send rate: average of "real" and previous send rates + increases 2301 //final send rate: average of "real" and previous send rates + increases
2303 conn->packet_send_rate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase; 2302 double newrate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase;
2303 conn->last_send_rate = conn->packet_send_rate;
2304 conn->packet_send_rate = newrate;
2304 2305
2305 2306
2306 conn->dropped = dropped; 2307 conn->dropped = dropped;
2307 conn->drop_ignore = drop_ignore_new; 2308 conn->drop_ignore = drop_ignore_new;
2308 conn->packets_resent = 0; 2309 conn->packets_resent = 0;
2310 conn->last_queue_size = queue_size;
2309 2311
2310 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) { 2312 if (!conn->sending || !conn->packets_sent) {
2311 conn->rate_increase = 0; 2313 conn->rate_increase = 0;
2314 conn->packet_send_rate /= 2;
2315 }
2316
2317 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) {
2312 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 2318 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
2313 } 2319 }
2314 2320
2321 conn->packets_sent = 0;
2322
2315 if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH / 2) { 2323 if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH / 2) {
2316 --conn->sending; 2324 --conn->sending;
2317 } 2325 }
@@ -2342,6 +2350,7 @@ static void send_crypto_packets(Net_Crypto *c)
2342 2350
2343 conn->packets_resent += ret; 2351 conn->packets_resent += ret;
2344 conn->packets_left -= ret; 2352 conn->packets_left -= ret;
2353 conn->packets_sent += ret;
2345 } 2354 }
2346 2355
2347 if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) { 2356 if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) {
@@ -2421,6 +2430,7 @@ int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const ui
2421 return -1; 2430 return -1;
2422 2431
2423 --conn->packets_left; 2432 --conn->packets_left;
2433 conn->packets_sent++;
2424 conn->sending = CONN_SENDING_VALUE; 2434 conn->sending = CONN_SENDING_VALUE;
2425 return ret; 2435 return ret;
2426} 2436}
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 4fed0000..2bc9a716 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -143,9 +143,9 @@ typedef struct {
143 uint32_t packets_left; 143 uint32_t packets_left;
144 uint64_t last_packets_left_set; 144 uint64_t last_packets_left_set;
145 145
146 double dropped, drop_ignore, rate_increase; 146 double dropped, drop_ignore, rate_increase, last_send_rate;
147 uint64_t drop_ignore_start, rate_increase_stop_start; 147 uint64_t drop_ignore_start, rate_increase_stop_start;
148 uint32_t packets_resent; 148 uint32_t packets_resent, last_queue_size, packets_sent, last_packets_sent;
149 149
150 uint8_t sending; /* indicates if data is being sent or not. */ 150 uint8_t sending; /* indicates if data is being sent or not. */
151 151
diff --git a/toxcore/network.c b/toxcore/network.c
index 0009a558..373fef9e 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -671,7 +671,7 @@ int ip_equal(const IP *a, const IP *b)
671 } 671 }
672 672
673 return 0; 673 return 0;
674}; 674}
675 675
676/* ipport_equal 676/* ipport_equal
677 * compares two IPAny_Port structures 677 * compares two IPAny_Port structures
@@ -688,7 +688,7 @@ int ipport_equal(const IP_Port *a, const IP_Port *b)
688 return 0; 688 return 0;
689 689
690 return ip_equal(&a->ip, &b->ip); 690 return ip_equal(&a->ip, &b->ip);
691}; 691}
692 692
693/* nulls out ip */ 693/* nulls out ip */
694void ip_reset(IP *ip) 694void ip_reset(IP *ip)
@@ -697,7 +697,7 @@ void ip_reset(IP *ip)
697 return; 697 return;
698 698
699 memset(ip, 0, sizeof(IP)); 699 memset(ip, 0, sizeof(IP));
700}; 700}
701 701
702/* nulls out ip, sets family according to flag */ 702/* nulls out ip, sets family according to flag */
703void ip_init(IP *ip, uint8_t ipv6enabled) 703void ip_init(IP *ip, uint8_t ipv6enabled)
@@ -707,7 +707,7 @@ void ip_init(IP *ip, uint8_t ipv6enabled)
707 707
708 memset(ip, 0, sizeof(IP)); 708 memset(ip, 0, sizeof(IP));
709 ip->family = ipv6enabled ? AF_INET6 : AF_INET; 709 ip->family = ipv6enabled ? AF_INET6 : AF_INET;
710}; 710}
711 711
712/* checks if ip is valid */ 712/* checks if ip is valid */
713int ip_isset(const IP *ip) 713int ip_isset(const IP *ip)
@@ -716,7 +716,7 @@ int ip_isset(const IP *ip)
716 return 0; 716 return 0;
717 717
718 return (ip->family != 0); 718 return (ip->family != 0);
719}; 719}
720 720
721/* checks if ip is valid */ 721/* checks if ip is valid */
722int ipport_isset(const IP_Port *ipport) 722int ipport_isset(const IP_Port *ipport)
@@ -728,7 +728,7 @@ int ipport_isset(const IP_Port *ipport)
728 return 0; 728 return 0;
729 729
730 return ip_isset(&ipport->ip); 730 return ip_isset(&ipport->ip);
731}; 731}
732 732
733/* copies an ip structure (careful about direction!) */ 733/* copies an ip structure (careful about direction!) */
734void ip_copy(IP *target, const IP *source) 734void ip_copy(IP *target, const IP *source)
@@ -737,7 +737,7 @@ void ip_copy(IP *target, const IP *source)
737 return; 737 return;
738 738
739 memcpy(target, source, sizeof(IP)); 739 memcpy(target, source, sizeof(IP));
740}; 740}
741 741
742/* copies an ip_port structure (careful about direction!) */ 742/* copies an ip_port structure (careful about direction!) */
743void ipport_copy(IP_Port *target, const IP_Port *source) 743void ipport_copy(IP_Port *target, const IP_Port *source)
@@ -805,7 +805,7 @@ const char *ip_ntoa(const IP *ip)
805 /* brute force protection against lacking termination */ 805 /* brute force protection against lacking termination */
806 addresstext[sizeof(addresstext) - 1] = 0; 806 addresstext[sizeof(addresstext) - 1] = 0;
807 return addresstext; 807 return addresstext;
808}; 808}
809 809
810/* 810/*
811 * addr_parse_ip 811 * addr_parse_ip
@@ -820,7 +820,6 @@ const char *ip_ntoa(const IP *ip)
820 * 820 *
821 * returns 1 on success, 0 on failure 821 * returns 1 on success, 0 on failure
822 */ 822 */
823
824int addr_parse_ip(const char *address, IP *to) 823int addr_parse_ip(const char *address, IP *to)
825{ 824{
826 if (!address || !to) 825 if (!address || !to)
@@ -832,7 +831,7 @@ int addr_parse_ip(const char *address, IP *to)
832 to->family = AF_INET; 831 to->family = AF_INET;
833 to->ip4.in_addr = addr4; 832 to->ip4.in_addr = addr4;
834 return 1; 833 return 1;
835 }; 834 }
836 835
837 struct in6_addr addr6; 836 struct in6_addr addr6;
838 837
@@ -840,10 +839,10 @@ int addr_parse_ip(const char *address, IP *to)
840 to->family = AF_INET6; 839 to->family = AF_INET6;
841 to->ip6.in6_addr = addr6; 840 to->ip6.in6_addr = addr6;
842 return 1; 841 return 1;
843 }; 842 }
844 843
845 return 0; 844 return 0;
846}; 845}
847 846
848/* 847/*
849 * addr_resolve(): 848 * addr_resolve():
@@ -862,7 +861,6 @@ int addr_parse_ip(const char *address, IP *to)
862 * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6 861 * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
863 * returns 0 on failure 862 * returns 0 on failure
864 */ 863 */
865
866int addr_resolve(const char *address, IP *to, IP *extra) 864int addr_resolve(const char *address, IP *to, IP *extra)
867{ 865{
868 if (!address || !to) 866 if (!address || !to)
@@ -970,4 +968,4 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
970 return 0; 968 return 0;
971 969
972 return 1; 970 return 1;
973}; 971}
diff --git a/toxcore/network.h b/toxcore/network.h
index 359d26c8..b902a487 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -191,6 +191,21 @@ IP_Port;
191 */ 191 */
192const char *ip_ntoa(const IP *ip); 192const char *ip_ntoa(const IP *ip);
193 193
194/*
195 * addr_parse_ip
196 * directly parses the input into an IP structure
197 * tries IPv4 first, then IPv6
198 *
199 * input
200 * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
201 *
202 * output
203 * IP: family and the value is set on success
204 *
205 * returns 1 on success, 0 on failure
206 */
207int addr_parse_ip(const char *address, IP *to);
208
194/* ip_equal 209/* ip_equal
195 * compares two IPAny structures 210 * compares two IPAny structures
196 * unset means unequal 211 * unset means unequal
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 7d0efc79..42982ea8 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -831,7 +831,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
831 uint32_t i; 831 uint32_t i;
832 832
833 for (i = onion_c->num_friends; i != 0; --i) { 833 for (i = onion_c->num_friends; i != 0; --i) {
834 if (onion_c->friends_list[i].status != 0) 834 if (onion_c->friends_list[i - 1].status != 0)
835 break; 835 break;
836 } 836 }
837 837
diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c
index 5c92527e..93dade05 100644
--- a/toxcore/ping_array.c
+++ b/toxcore/ping_array.c
@@ -135,7 +135,7 @@ int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout)
135 if (size == 0 || timeout == 0 || empty_array == NULL) 135 if (size == 0 || timeout == 0 || empty_array == NULL)
136 return -1; 136 return -1;
137 137
138 empty_array->entries = calloc(size * sizeof(Ping_Array_Entry), 1); 138 empty_array->entries = calloc(size, sizeof(Ping_Array_Entry));
139 139
140 if (empty_array->entries == NULL) 140 if (empty_array->entries == NULL)
141 return -1; 141 return -1;
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 5418b03e..14426f31 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -90,7 +90,7 @@ void tox_get_address(const Tox *tox, uint8_t *address);
90 * data is the data and length is the length. 90 * data is the data and length is the length.
91 * 91 *
92 * return the friend number if success. 92 * return the friend number if success.
93 * return TOX_FA_TOOLONG if message length is too long. 93 * return TOX_FAERR_TOOLONG if message length is too long.
94 * return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte). 94 * return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte).
95 * return TOX_FAERR_OWNKEY if user's own key. 95 * return TOX_FAERR_OWNKEY if user's own key.
96 * return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend. 96 * return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend.
@@ -294,13 +294,13 @@ void tox_callback_friend_request(Tox *tox, void (*function)(Tox *tox, const uint
294 void *), void *userdata); 294 void *), void *userdata);
295 295
296/* Set the function that will be executed when a message from a friend is received. 296/* Set the function that will be executed when a message from a friend is received.
297 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint32_t length, void *userdata) 297 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint16_t length, void *userdata)
298 */ 298 */
299void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), 299void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
300 void *userdata); 300 void *userdata);
301 301
302/* Set the function that will be executed when an action from a friend is received. 302/* Set the function that will be executed when an action from a friend is received.
303 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint32_t length, void *userdata) 303 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint16_t length, void *userdata)
304 */ 304 */
305void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), 305void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
306 void *userdata); 306 void *userdata);
@@ -495,20 +495,20 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
495 * tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive. 495 * tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive.
496 * 496 *
497 * If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back) 497 * If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back)
498 * the receiver must send a control packet with receive_send == 0 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being 498 * the receiver must send a control packet with send_receive == 1 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being
499 * a uint64_t (in host byte order) containing the number of bytes received. 499 * a uint64_t (in host byte order) containing the number of bytes received.
500 * 500 *
501 * If the sender receives this packet, he must send a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT 501 * If the sender receives this packet, he must send a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT
502 * then he must start sending file data from the position (data , uint64_t in host byte order) received in the TOX_FILECONTROL_RESUME_BROKEN packet. 502 * then he must start sending file data from the position (data , uint64_t in host byte order) received in the TOX_FILECONTROL_RESUME_BROKEN packet.
503 * 503 *
504 * To pause a file transfer send a control packet with control_type == TOX_FILECONTROL_PAUSE. 504 * To pause a file transfer send a control packet with control_type == TOX_FILECONTROL_PAUSE.
505 * To unpause a file transfer send a control packet with control_type == TOX_FILECONTROL_ACCEPT. 505 * To unpause a file transfer send a control packet with control_type == TOX_FILECONTROL_ACCEPT.
506 * 506 *
507 * If you receive a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_PAUSE, you must stop sending filenumber until the other 507 * If you receive a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_PAUSE, you must stop sending filenumber until the other
508 * person sends a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT with the filenumber being a paused filenumber. 508 * person sends a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT with the filenumber being a paused filenumber.
509 * 509 *
510 * If you receive a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_PAUSE, it means the sender of filenumber has paused the 510 * If you receive a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_PAUSE, it means the sender of filenumber has paused the
511 * transfer and will resume it later with a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_ACCEPT for that file number. 511 * transfer and will resume it later with a control packet with send_receive == 1 and control_type == TOX_FILECONTROL_ACCEPT for that file number.
512 * 512 *
513 * More to come... 513 * More to come...
514 */ 514 */