summaryrefslogtreecommitdiff
path: root/toxcore/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/network.c')
-rw-r--r--toxcore/network.c130
1 files changed, 44 insertions, 86 deletions
diff --git a/toxcore/network.c b/toxcore/network.c
index f1e94996..20332362 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -29,6 +29,8 @@
29#include "config.h" 29#include "config.h"
30#endif 30#endif
31 31
32#include "logger.h"
33
32#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) 34#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
33#include <errno.h> 35#include <errno.h>
34#endif 36#endif
@@ -252,9 +254,29 @@ uint64_t current_time_monotonic(void)
252 return time; 254 return time;
253} 255}
254 256
255#ifdef LOGGING 257/* In case no logging */
256static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res); 258#ifndef LOGGING
257#endif 259#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__)
260#else
261#define data_0(__buflen__, __buffer__) __buflen__ > 4 ? ntohl(*(uint32_t *)&__buffer__[1]) : 0
262#define data_1(__buflen__, __buffer__) __buflen__ > 7 ? ntohl(*(uint32_t *)&__buffer__[5]) : 0
263
264#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__) \
265 (__ip_port__) .ip; \
266 if (__res__ < 0) /* Windows doesn't necessarily know %zu */ \
267 LOGGER_INFO("[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x", \
268 __buffer__[0], __message__, (__buflen__ < 999 ? (uint16_t)__buflen__ : 999), 'E', \
269 ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), errno, strerror(errno), data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
270 else if ((__res__ > 0) && ((size_t)__res__ <= __buflen__)) \
271 LOGGER_INFO("[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x", \
272 __buffer__[0], __message__, (__res__ < 999 ? (size_t)__res__ : 999), ((size_t)__res__ < __buflen__ ? '<' : '='), \
273 ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
274 else /* empty or overwrite */ \
275 LOGGER_INFO("[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x", \
276 __buffer__[0], __message__, (size_t)__res__, (!__res__ ? '!' : '>'), __buflen__, \
277 ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__));
278
279#endif /* LOGGING */
258 280
259/* Basic network functions: 281/* Basic network functions:
260 * Function to send packet(data) of length length to ip_port. 282 * Function to send packet(data) of length length to ip_port.
@@ -313,9 +335,9 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
313 } 335 }
314 336
315 int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); 337 int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
316#ifdef LOGGING 338
317 loglogdata("O=>", data, length, &ip_port, res); 339 loglogdata("O=>", data, length, ip_port, res);
318#endif 340
319 341
320 if ((res >= 0) && ((uint32_t)res == length)) 342 if ((res >= 0) && ((uint32_t)res == length))
321 net->send_fail_eagain = 0; 343 net->send_fail_eagain = 0;
@@ -343,14 +365,10 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
343 int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); 365 int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
344 366
345 if (fail_or_len < 0) { 367 if (fail_or_len < 0) {
346#ifdef LOGGING
347 368
348 if ((fail_or_len < 0) && (errno != EWOULDBLOCK)) { 369 LOGGER_SCOPE( if ((fail_or_len < 0) && (errno != EWOULDBLOCK))
349 sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); 370 LOGGER_ERROR("Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); );
350 loglog(logbuffer);
351 }
352 371
353#endif
354 return -1; /* Nothing received. */ 372 return -1; /* Nothing received. */
355 } 373 }
356 374
@@ -375,9 +393,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
375 } else 393 } else
376 return -1; 394 return -1;
377 395
378#ifdef LOGGING 396 loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, *ip_port, *length);
379 loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length);
380#endif
381 397
382 return 0; 398 return 0;
383} 399}
@@ -400,10 +416,7 @@ void networking_poll(Networking_Core *net)
400 if (length < 1) continue; 416 if (length < 1) continue;
401 417
402 if (!(net->packethandlers[data[0]].function)) { 418 if (!(net->packethandlers[data[0]].function)) {
403#ifdef LOGGING 419 LOGGER_WARNING("[%02u] -- Packet has no handler", data[0]);
404 sprintf(logbuffer, "[%02u] -- Packet has no handler.\n", data[0]);
405 loglog(logbuffer);
406#endif
407 continue; 420 continue;
408 } 421 }
409 422
@@ -506,22 +519,15 @@ int networking_wait_execute(uint8_t *data, long seconds, long microseconds)
506 timeout.tv_usec = microseconds; 519 timeout.tv_usec = microseconds;
507 } 520 }
508 521
509#ifdef LOGGING
510 errno = 0;
511#endif
512 /* returns -1 on error, 0 on timeout, the socket on activity */ 522 /* returns -1 on error, 0 on timeout, the socket on activity */
513 int res = select(nfds, &readfds, &writefds, &exceptfds, timeout_ptr); 523 int res = select(nfds, &readfds, &writefds, &exceptfds, timeout_ptr);
514#ifdef LOGGING
515 524
516 /* only dump if not timeout */ 525 LOGGER_SCOPE(
517 if (res) {
518 sprintf(logbuffer, "select(%d, %d): %d (%d, %s) - %d %d %d\n", microseconds, seconds, res, errno,
519 strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
520 FD_ISSET(s->sock, &exceptfds));
521 loglog(logbuffer);
522 }
523 526
524#endif 527 if (res) LOGGER_INFO("select(%d, %d): %d (%d, %s) - %d %d %d\n", microseconds, seconds, res, errno,
528 strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
529 FD_ISSET(s->sock, &exceptfds));
530 );
525 531
526 if (FD_ISSET(s->sock, &writefds)) { 532 if (FD_ISSET(s->sock, &writefds)) {
527 s->send_fail_reset = 1; 533 s->send_fail_reset = 1;
@@ -681,18 +687,10 @@ Networking_Core *new_networking(IP ip, uint16_t port)
681 if (ip.family == AF_INET6) { 687 if (ip.family == AF_INET6) {
682#ifdef LOGGING 688#ifdef LOGGING
683 int is_dualstack = 689 int is_dualstack =
684#endif 690#endif /* LOGGING */
685 set_socket_dualstack(temp->sock); 691 set_socket_dualstack(temp->sock);
686#ifdef LOGGING 692 LOGGER_DEBUG( "Dual-stack socket: %s",
687 693 is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses" );
688 if (is_dualstack) {
689 loglog("Dual-stack socket: enabled.\n");
690 } else {
691 loglog("Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses.\n");
692 }
693
694#endif
695
696 /* multicast local nodes */ 694 /* multicast local nodes */
697 struct ipv6_mreq mreq; 695 struct ipv6_mreq mreq;
698 memset(&mreq, 0, sizeof(mreq)); 696 memset(&mreq, 0, sizeof(mreq));
@@ -701,20 +699,12 @@ Networking_Core *new_networking(IP ip, uint16_t port)
701 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; 699 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
702 mreq.ipv6mr_interface = 0; 700 mreq.ipv6mr_interface = 0;
703#ifdef LOGGING 701#ifdef LOGGING
704 errno = 0;
705 int res = 702 int res =
706#endif 703#endif /* LOGGING */
707 setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); 704 setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
708#ifdef LOGGING
709 705
710 if (res < 0) { 706 LOGGER_DEBUG(res < 0 ? "Failed to activate local multicast membership. (%u, %s)" :
711 sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n", 707 "Local multicast group FF02::1 joined successfully", errno, strerror(errno) );
712 errno, strerror(errno));
713 loglog(logbuffer);
714 } else
715 loglog("Local multicast group FF02::1 joined successfully.\n");
716
717#endif
718 } 708 }
719 709
720 /* a hanging program or a different user might block the standard port; 710 /* a hanging program or a different user might block the standard port;
@@ -742,12 +732,8 @@ Networking_Core *new_networking(IP ip, uint16_t port)
742 732
743 if (!res) { 733 if (!res) {
744 temp->port = *portptr; 734 temp->port = *portptr;
745#ifdef LOGGING
746 loginit(temp->port);
747 735
748 sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port)); 736 LOGGER_DEBUG("Bound successfully to %s:%u", ip_ntoa(&ip), ntohs(temp->port));
749 loglog(logbuffer);
750#endif
751 737
752 /* errno isn't reset on success, only set on failure, the failed 738 /* errno isn't reset on success, only set on failure, the failed
753 * binds with parallel clients yield a -EPERM to the outside if 739 * binds with parallel clients yield a -EPERM to the outside if
@@ -1114,31 +1100,3 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
1114 1100
1115 return 1; 1101 return 1;
1116}; 1102};
1117
1118#ifdef LOGGING
1119static char errmsg_ok[3] = "OK";
1120static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res)
1121{
1122 uint16_t port = ntohs(ip_port->port);
1123 uint32_t data[2];
1124 data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0;
1125 data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0;
1126
1127 /* Windows doesn't necessarily know %zu */
1128 if (res < 0) {
1129 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n",
1130 buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E',
1131 ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]);
1132 } else if ((res > 0) && ((size_t)res <= buflen))
1133 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x\n",
1134 buffer[0], message, (res < 999 ? (size_t)res : 999), ((size_t)res < buflen ? '<' : '='),
1135 ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
1136 else /* empty or overwrite */
1137 snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x\n",
1138 buffer[0], message, (size_t)res, (!res ? '!' : '>'), buflen,
1139 ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
1140
1141 logbuffer[sizeof(logbuffer) - 1] = 0;
1142 loglog(logbuffer);
1143}
1144#endif