summaryrefslogtreecommitdiff
path: root/toxcore/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/network.c')
-rw-r--r--toxcore/network.c77
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 */
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",