diff options
Diffstat (limited to 'toxcore/network.c')
-rw-r--r-- | toxcore/network.c | 130 |
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 */ |
256 | static 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 | ||
1119 | static char errmsg_ok[3] = "OK"; | ||
1120 | static 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 | ||