summaryrefslogtreecommitdiff
path: root/toxcore/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/network.c')
-rw-r--r--toxcore/network.c86
1 files changed, 54 insertions, 32 deletions
diff --git a/toxcore/network.c b/toxcore/network.c
index a5786801..3e533799 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -25,6 +25,10 @@
25#include "config.h" 25#include "config.h"
26#endif 26#endif
27 27
28#ifndef WIN32
29#include <errno.h>
30#endif
31
28#include "network.h" 32#include "network.h"
29#include "util.h" 33#include "util.h"
30 34
@@ -300,36 +304,53 @@ void networking_poll(Networking_Core *net)
300} 304}
301 305
302/* 306/*
303 * Waits for something to happen on the socket for up to milliseconds milliseconds 307 * function to avoid excessive polling
304 * *** Function MUSTN'T poll. ***
305 * The function mustn't modify anything at all, so it can be called completely
306 * asynchronously without any worry.
307 *
308 * returns 0 if the timeout was reached
309 * returns 1 if there is socket activity (i.e. tox_do() should be called)
310 *
311 */ 308 */
312int networking_wait(Networking_Core *net, uint32_t sendqueue_len, uint16_t milliseconds) 309typedef struct
310{
311 sock_t sock;
312 uint32_t sendqueue_length;
313} select_info;
314
315int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr)
316{
317 if ((data == NULL) || (*lenptr < sizeof(select_info)))
318 {
319 *lenptr = sizeof(select_info);
320 return 0;
321 }
322
323 *lenptr = sizeof(select_info);
324 select_info *s = (select_info *)data;
325 s->sock = net->sock;
326 s->sendqueue_length = sendqueue_length;
327
328 return 1;
329}
330
331int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
313{ 332{
314 sock_t sock = net->sock;
315 /* WIN32: supported since Win2K, but might need some adjustements */ 333 /* WIN32: supported since Win2K, but might need some adjustements */
316 /* UNIX: this should work for any remotely Unix'ish system */ 334 /* UNIX: this should work for any remotely Unix'ish system */
317 int nfds = 1 + sock; 335
336 select_info *s = (select_info *)data;
337
338 int nfds = 1 + s->sock;
318 339
319 /* the FD_ZERO calls might be superfluous */ 340 /* the FD_ZERO calls might be superfluous */
320 fd_set readfds; 341 fd_set readfds;
321 FD_ZERO(&readfds); 342 FD_ZERO(&readfds);
322 FD_SET(sock, &readfds); 343 FD_SET(s->sock, &readfds);
323 344
324 fd_set writefds; 345 fd_set writefds;
325 FD_ZERO(&writefds); 346 FD_ZERO(&writefds);
326 /* add only if we have packets queued, signals that a write won't block */ 347 /* add only if we have packets queued, signals that a write won't block */
327 if (sendqueue_len > 0) 348 if (s->sendqueue_length > 0)
328 FD_SET(sock, &writefds); 349 FD_SET(s->sock, &writefds);
329 350
330 fd_set exceptfds; 351 fd_set exceptfds;
331 FD_ZERO(&exceptfds); 352 FD_ZERO(&exceptfds);
332 FD_SET(sock, &exceptfds); 353 FD_SET(s->sock, &exceptfds);
333 354
334 struct timeval timeout; 355 struct timeval timeout;
335 timeout.tv_sec = 0; 356 timeout.tv_sec = 0;
@@ -342,8 +363,8 @@ int networking_wait(Networking_Core *net, uint32_t sendqueue_len, uint16_t milli
342 int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); 363 int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
343#ifdef LOGGING 364#ifdef LOGGING
344 sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, 365 sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno,
345 strerror(errno), FD_ISSET(sock, &readfds), FD_ISSET(sock, &writefds), 366 strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
346 FD_ISSET(sock, &exceptfds)); 367 FD_ISSET(s->sock, &exceptfds));
347 loglog(logbuffer); 368 loglog(logbuffer);
348#endif 369#endif
349 370
@@ -972,26 +993,27 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
972}; 993};
973 994
974#ifdef LOGGING 995#ifdef LOGGING
996static char errmsg_ok[3] = "OK";
975static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res) 997static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res)
976{ 998{
999 uint16_t port = ntohs(ip_port->port);
1000 uint32_t data[2];
1001 data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0;
1002 data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0;
977 if (res < 0) 1003 if (res < 0)
978 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%d: %s) | %04x%04x\n", 1004 {
979 buffer[0], message, buflen < 999 ? buflen : 999, 'E', 1005 int written = snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n",
980 ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno, 1006 buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E',
981 strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0, 1007 ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]);
982 (buflen > 7) ? ntohl(*(uint32_t *)(&buffer[5])) : 0); 1008 }
983 else if ((res > 0) && ((size_t)res <= buflen)) 1009 else if ((res > 0) && ((size_t)res <= buflen))
984 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%d: %s) | %04x%04x\n", 1010 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x\n",
985 buffer[0], message, res < 999 ? res : 999, (size_t)res < buflen ? '<' : '=', 1011 buffer[0], message, (res < 999 ? (size_t)res : 999), ((size_t)res < buflen ? '<' : '='),
986 ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, 1012 ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
987 "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
988 (buflen > 7) ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
989 else /* empty or overwrite */ 1013 else /* empty or overwrite */
990 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%d: %s) | %04x%04x\n", 1014 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x\n",
991 buffer[0], message, res, !res ? '!' : '>', buflen, 1015 buffer[0], message, (size_t)res, (!res ? '!' : '>'), buflen,
992 ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0, 1016 ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
993 "OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
994 (buflen > 7) ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
995 1017
996 logbuffer[sizeof(logbuffer) - 1] = 0; 1018 logbuffer[sizeof(logbuffer) - 1] = 0;
997 loglog(logbuffer); 1019 loglog(logbuffer);