diff options
Diffstat (limited to 'toxcore/network.c')
-rw-r--r-- | toxcore/network.c | 77 |
1 files changed, 55 insertions, 22 deletions
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 | */ |
309 | typedef struct | 315 | typedef 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 | ||
315 | int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr) | 323 | int 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 | ||
331 | int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) | 341 | int 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 | ||
400 | void 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 | |||
374 | uint8_t at_startup_ran = 0; | 407 | uint8_t at_startup_ran = 0; |
375 | static int at_startup(void) | 408 | static int at_startup(void) |
376 | { | 409 | { |
@@ -996,10 +1029,10 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra) | |||
996 | static char errmsg_ok[3] = "OK"; | 1029 | static char errmsg_ok[3] = "OK"; |
997 | static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res) | 1030 | static 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", |