/* SPDX-License-Identifier: Unlicense */ #include "proto_io.h" #include #include #include #include #include static unsigned char g_udp_buffer[UINT16_MAX + 1u]; int ReceiveFrame(int fd, struct frame *frame) { frame->type = FT_NONE; struct sockaddr_in source_address; socklen_t source_address_len = sizeof(source_address); int const length = recvfrom( fd, g_udp_buffer, sizeof(g_udp_buffer) - 1, 0, (struct sockaddr*)&source_address, &source_address_len); if (length == 0) { return -EWOULDBLOCK; } if (length < 0) { int const err = errno; if (err != EWOULDBLOCK) { perror("recvfrom failed"); } return -err; } uint32_t const addr = ntohl(source_address.sin_addr.s_addr); uint16_t const port = ntohs(source_address.sin_port); if (length) { *frame = ParseFrame(g_udp_buffer, length); frame->addr = addr; frame->port = port; } if (LOG_TRACE) { uint8_t const a0 = addr >> 24; uint8_t const a1 = addr >> 16; uint8_t const a2 = addr >> 8; uint8_t const a3 = addr; fprintf(stderr, "Received from %u.%u.%u.%u:%u\n", a0, a1, a2, a3, port); } return 0; } int SendFrame(int const fd, struct frame const *const frame) { g_udp_buffer[0] = frame->type; struct sockaddr_in const sockaddr = { .sin_family = AF_INET, .sin_port = htons(frame->port), .sin_addr.s_addr = htonl(frame->addr), }; if (LOG_TRACE) { uint32_t const addr = frame->addr; uint16_t const port = frame->port; uint8_t const a0 = addr >> 24; uint8_t const a1 = addr >> 16; uint8_t const a2 = addr >> 8; uint8_t const a3 = addr; fprintf(stderr, "Sending to %u.%u.%u.%u:%u\n", a0, a1, a2, a3, port); } size_t const size = SerializeFrame(g_udp_buffer, UINT16_MAX + 1u, frame); ssize_t const ret = sendto( fd, g_udp_buffer, size, 0, (struct sockaddr const *)&sockaddr, sizeof(sockaddr)); if (ret < 0) { int const err = errno; perror("sendto failed"); return -err; } return 0; }