summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxcore/Messenger.c9
-rw-r--r--toxcore/Messenger.h1
-rw-r--r--toxcore/network.c77
-rw-r--r--toxcore/network.h2
-rw-r--r--toxcore/tox.c6
-rw-r--r--toxcore/tox.h9
-rw-r--r--toxcore/util.h1
7 files changed, 81 insertions, 24 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index e4387fcb..dfd32d40 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -1394,14 +1394,19 @@ void doMessenger(Messenger *m)
1394 */ 1394 */
1395int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr) 1395int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr)
1396{ 1396{
1397 return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data, lenptr); 1397 return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data, lenptr);
1398} 1398}
1399 1399
1400int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds) 1400int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds)
1401{ 1401{
1402 return networking_wait_execute(data, len, milliseconds); 1402 return networking_wait_execute(data, len, milliseconds);
1403}; 1403};
1404 1404
1405void waitcleanupMessenger(Messenger *m, uint8_t *data, uint16_t len)
1406{
1407 networking_wait_cleanup(m->net, data, len);
1408}
1409
1405/* return size of the messenger data (for saving) */ 1410/* return size of the messenger data (for saving) */
1406uint32_t Messenger_size_old(Messenger *m) 1411uint32_t Messenger_size_old(Messenger *m)
1407{ 1412{
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 80450b1a..a59cec29 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -460,6 +460,7 @@ void doMessenger(Messenger *m);
460 */ 460 */
461int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr); 461int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr);
462int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds); 462int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds);
463void waitcleanupMessenger(Messenger *m, uint8_t *data, uint16_t len);
463 464
464/* SAVING AND LOADING FUNCTIONS: */ 465/* SAVING AND LOADING FUNCTIONS: */
465 466
diff --git a/toxcore/network.c b/toxcore/network.c
index 3e533799..51f064e7 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -209,6 +209,12 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
209#ifdef LOGGING 209#ifdef LOGGING
210 loglogdata("O=>", data, length, &ip_port, res); 210 loglogdata("O=>", data, length, &ip_port, res);
211#endif 211#endif
212
213 if (res == length)
214 net->send_fail_eagain = 0;
215 else if ((res < 0) && (errno == EAGAIN))
216 net->send_fail_eagain = current_time();
217
212 return res; 218 return res;
213} 219}
214 220
@@ -308,24 +314,28 @@ void networking_poll(Networking_Core *net)
308 */ 314 */
309typedef struct 315typedef struct
310{ 316{
311 sock_t sock; 317 sock_t sock;
312 uint32_t sendqueue_length; 318 uint32_t sendqueue_length;
319 uint16_t send_fail_reset;
320 uint64_t send_fail_eagain;
313} select_info; 321} select_info;
314 322
315int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr) 323int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr)
316{ 324{
317 if ((data == NULL) || (*lenptr < sizeof(select_info))) 325 if ((data == NULL) || (*lenptr < sizeof(select_info)))
318 { 326 {
319 *lenptr = sizeof(select_info); 327 *lenptr = sizeof(select_info);
320 return 0; 328 return 0;
321 } 329 }
322 330
323 *lenptr = sizeof(select_info); 331 *lenptr = sizeof(select_info);
324 select_info *s = (select_info *)data; 332 select_info *s = (select_info *)data;
325 s->sock = net->sock; 333 s->sock = net->sock;
326 s->sendqueue_length = sendqueue_length; 334 s->sendqueue_length = sendqueue_length;
327 335 s->send_fail_reset = 0;
328 return 1; 336 s->send_fail_eagain = net->send_fail_eagain;
337
338 return 1;
329} 339}
330 340
331int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) 341int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
@@ -333,9 +343,23 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
333 /* WIN32: supported since Win2K, but might need some adjustements */ 343 /* WIN32: supported since Win2K, but might need some adjustements */
334 /* UNIX: this should work for any remotely Unix'ish system */ 344 /* UNIX: this should work for any remotely Unix'ish system */
335 345
336 select_info *s = (select_info *)data; 346 select_info *s = (select_info *)data;
337 347
338 int nfds = 1 + s->sock; 348 /* add only if we had a failed write */
349 int writefds_add = 0;
350 if (s->send_fail_eagain != 0)
351 {
352 // current_time(): microseconds
353 uint64_t now = current_time();
354
355 /* s->sendqueue_length: might be used to guess how long we keep checking */
356 /* for now, threshold is hardcoded to 500ms, too long for a really really
357 * fast link, but too short for a sloooooow link... */
358 if (now - s->send_fail_eagain < 500000)
359 writefds_add = 1;
360 }
361
362 int nfds = 1 + s->sock;
339 363
340 /* the FD_ZERO calls might be superfluous */ 364 /* the FD_ZERO calls might be superfluous */
341 fd_set readfds; 365 fd_set readfds;
@@ -344,8 +368,7 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
344 368
345 fd_set writefds; 369 fd_set writefds;
346 FD_ZERO(&writefds); 370 FD_ZERO(&writefds);
347 /* add only if we have packets queued, signals that a write won't block */ 371 if (writefds_add)
348 if (s->sendqueue_length > 0)
349 FD_SET(s->sock, &writefds); 372 FD_SET(s->sock, &writefds);
350 373
351 fd_set exceptfds; 374 fd_set exceptfds;
@@ -368,9 +391,19 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
368 loglog(logbuffer); 391 loglog(logbuffer);
369#endif 392#endif
370 393
394 if (FD_ISSET(s->sock, &writefds))
395 s->send_fail_reset = 1;
396
371 return res > 0 ? 1 : 0; 397 return res > 0 ? 1 : 0;
372}; 398};
373 399
400void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len)
401{
402 select_info *s = (select_info *)data;
403 if (s->send_fail_reset)
404 net->send_fail_eagain = 0;
405}
406
374uint8_t at_startup_ran = 0; 407uint8_t at_startup_ran = 0;
375static int at_startup(void) 408static int at_startup(void)
376{ 409{
@@ -996,10 +1029,10 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
996static char errmsg_ok[3] = "OK"; 1029static char errmsg_ok[3] = "OK";
997static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res) 1030static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res)
998{ 1031{
999 uint16_t port = ntohs(ip_port->port); 1032 uint16_t port = ntohs(ip_port->port);
1000 uint32_t data[2]; 1033 uint32_t data[2];
1001 data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0; 1034 data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0;
1002 data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0; 1035 data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0;
1003 if (res < 0) 1036 if (res < 0)
1004 { 1037 {
1005 int written = snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n", 1038 int written = snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n",
diff --git a/toxcore/network.h b/toxcore/network.h
index 54df7d2e..8a0e20dc 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -244,6 +244,7 @@ typedef struct {
244 sa_family_t family; 244 sa_family_t family;
245 uint16_t port; 245 uint16_t port;
246 sock_t sock; 246 sock_t sock;
247 uint64_t send_fail_eagain;
247} Networking_Core; 248} Networking_Core;
248 249
249/* return current time in milleseconds since the epoch. */ 250/* return current time in milleseconds since the epoch. */
@@ -269,6 +270,7 @@ void networking_poll(Networking_Core *net);
269 */ 270 */
270int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr); 271int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr);
271int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds); 272int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds);
273void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len);
272 274
273/* Initialize networking. 275/* Initialize networking.
274 * bind to ip and port. 276 * bind to ip and port.
diff --git a/toxcore/tox.c b/toxcore/tox.c
index b2107389..5868a8e1 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -551,6 +551,12 @@ int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t millisecond
551 waitexecuteMessenger(m, data, len, milliseconds); 551 waitexecuteMessenger(m, data, len, milliseconds);
552} 552}
553 553
554void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len)
555{
556 Messenger *m = tox;
557 waitcleanupMessenger(m, data, len);
558}
559
554/* SAVING AND LOADING FUNCTIONS: */ 560/* SAVING AND LOADING FUNCTIONS: */
555 561
556/* return size of the messenger data (for saving). */ 562/* return size of the messenger data (for saving). */
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 3278a9d3..7b8af15e 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -491,6 +491,7 @@ void tox_do(Tox *tox);
491 * returns 1 on success 491 * returns 1 on success
492 * returns 0 on failure (length is insufficient) 492 * returns 0 on failure (length is insufficient)
493 * 493 *
494 *
494 * tox_wait_execute(): function can be called asynchronously 495 * tox_wait_execute(): function can be called asynchronously
495 * Waits for something to happen on the socket for up to milliseconds milliseconds. 496 * Waits for something to happen on the socket for up to milliseconds milliseconds.
496 * *** Function MUSTN'T poll. *** 497 * *** Function MUSTN'T poll. ***
@@ -501,9 +502,17 @@ void tox_do(Tox *tox);
501 * returns 0 if the timeout was reached 502 * returns 0 if the timeout was reached
502 * returns -1 if data was NULL or len too short 503 * returns -1 if data was NULL or len too short
503 * 504 *
505 *
506 * tox_wait_cleanup(): function should be called under lock
507 * Stores results from tox_wait_execute().
508 *
509 * data[]/len shall be the exact same as given to tox_wait_execute()
510 *
504 */ 511 */
505int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr); 512int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr);
506int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds); 513int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds);
514void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len);
515
507 516
508/* SAVING AND LOADING FUNCTIONS: */ 517/* SAVING AND LOADING FUNCTIONS: */
509 518
diff --git a/toxcore/util.h b/toxcore/util.h
index 13ab4792..1c1898a0 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -20,6 +20,7 @@ typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len
20int load_state(load_state_callback_func load_state_callback, void *outer, 20int load_state(load_state_callback_func load_state_callback, void *outer,
21 uint8_t *data, uint32_t length, uint16_t cookie_inner); 21 uint8_t *data, uint32_t length, uint16_t cookie_inner);
22 22
23#define LOGGING
23#ifdef LOGGING 24#ifdef LOGGING
24extern char logbuffer[512]; 25extern char logbuffer[512];
25void loginit(uint16_t port); 26void loginit(uint16_t port);