From b034b81ad74f61fc2f188c68df40f89b7900d0aa Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Mon, 7 Sep 2026 13:04:10 -0400 Subject: Add cork() and eagain() to socket Signed-off-by: Andrew Opalach --- src/socket/bsd_common.c | 40 +++++++++++++++++++++++++++++++++++ src/socket/socket.h | 6 ++++-- src/socket/socket_linux.c | 51 ++++++++++++--------------------------------- src/socket/socket_windows.c | 12 +++++++++-- 4 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 src/socket/bsd_common.c (limited to 'src') diff --git a/src/socket/bsd_common.c b/src/socket/bsd_common.c new file mode 100644 index 0000000..af0a9b6 --- /dev/null +++ b/src/socket/bsd_common.c @@ -0,0 +1,40 @@ +#ifndef NAUNET_ON_WINDOWS +#include +#include +#endif + +#include "socket.h" + +void nn_socket_set_nodelay(struct nn_socket *sock, s32 nodelay) +{ + al_assert(sock->type == NNWT_SOCKET_TCP); + setsockopt(sock->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); +} + +u32 nn_socket_get_send_buf(struct nn_socket *sock) +{ + u32 send_queue_size; + socklen_t optlen = sizeof(send_queue_size); + getsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, (char *)&send_queue_size, &optlen); + return send_queue_size; +} + +void nn_socket_set_send_buf(struct nn_socket *sock, u32 sndbuf) +{ + u32 send_queue_size = sndbuf; + setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, (char *)&send_queue_size, sizeof(send_queue_size)); +} + +u32 nn_socket_get_recv_buf(struct nn_socket *sock) +{ + u32 receive_queue_size; + socklen_t optlen = sizeof(receive_queue_size); + getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&receive_queue_size, &optlen); + return receive_queue_size; +} + +void nn_socket_set_recv_buf(struct nn_socket *sock, u32 rcvbuf) +{ + u32 receive_queue_size = rcvbuf; + setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&receive_queue_size, sizeof(receive_queue_size)); +} diff --git a/src/socket/socket.h b/src/socket/socket.h index fde26f4..31f23f3 100644 --- a/src/socket/socket.h +++ b/src/socket/socket.h @@ -8,8 +8,8 @@ #else #include #include -#include #include +#include #endif enum { @@ -50,9 +50,9 @@ struct nn_socket { #endif #ifndef NAUNET_ON_WINDOWS // Posix-only helpers. +#define nn_eventfd eventfd #define nn_pollfd pollfd #define nn_nfds nfds_t -#define nn_eventfd eventfd void nn_fd_set_blocking(s32 fd, bool blocking); s32 nn_poll_fds(struct nn_pollfd *fds, nn_nfds nfds, s64 timeout_ns); #endif @@ -61,6 +61,7 @@ bool nn_socket_init(struct nn_socket *sock, s32 flags); void nn_socket_set_blocking(struct nn_socket *sock, bool blocking); void nn_socket_set_nodelay(struct nn_socket *sock, s32 nodelay); +void nn_socket_set_cork(struct nn_socket *sock, s32 cork); void nn_socket_set_reuse_addr(struct nn_socket *sock, s32 reuse_addr); u32 nn_socket_get_send_buf(struct nn_socket *sock); @@ -81,6 +82,7 @@ ssize_t nn_socket_write(struct nn_socket *sock, void *buf, size_t size); ssize_t nn_socket_sendto(struct nn_socket *sock, void *buf, size_t size); ssize_t nn_socket_recvfrom(struct nn_socket *sock, void *buf, size_t size); +bool nn_socket_eagain(ssize_t ret); bool nn_socket_check_error(ssize_t ret); void nn_socket_shutdown(struct nn_socket *sock); diff --git a/src/socket/socket_linux.c b/src/socket/socket_linux.c index 2634fc2..cfdcab3 100644 --- a/src/socket/socket_linux.c +++ b/src/socket/socket_linux.c @@ -1,9 +1,9 @@ #define AL_LOG_SECTION "socket" #include -#include -#include #include +#include #include +#include #include "../util/error.h" @@ -62,10 +62,10 @@ void nn_socket_set_blocking(struct nn_socket *sock, bool blocking) nn_fd_set_blocking(sock->fd, blocking); } -void nn_socket_set_nodelay(struct nn_socket *sock, s32 nodelay) +void nn_socket_set_cork(struct nn_socket *sock, s32 cork) { al_assert(sock->type == NNWT_SOCKET_TCP); - setsockopt(sock->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + setsockopt(sock->fd, SOL_TCP, TCP_CORK, &cork, sizeof(cork)); } void nn_socket_set_reuse_addr(struct nn_socket *sock, s32 reuse_addr) @@ -74,36 +74,6 @@ void nn_socket_set_reuse_addr(struct nn_socket *sock, s32 reuse_addr) setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr)); } -u32 nn_socket_get_send_buf(struct nn_socket *sock) -{ - u32 send_queue_size; - socklen_t optlen = sizeof(send_queue_size); - getsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &send_queue_size, &optlen); - return send_queue_size / 2; -} - -void nn_socket_set_send_buf(struct nn_socket *sock, u32 sndbuf) -{ - u32 send_queue_size = sndbuf; - setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &send_queue_size, sizeof(send_queue_size)); - al_assert(nn_socket_get_send_buf(sock) == send_queue_size); -} - -u32 nn_socket_get_recv_buf(struct nn_socket *sock) -{ - u32 receive_queue_size; - socklen_t optlen = sizeof(receive_queue_size); - getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, &optlen); - return receive_queue_size / 2; -} - -void nn_socket_set_recv_buf(struct nn_socket *sock, u32 rcvbuf) -{ - u32 receive_queue_size = rcvbuf; - setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, &receive_queue_size, sizeof(receive_queue_size)); - al_assert(nn_socket_get_recv_buf(sock) == receive_queue_size); -} - static bool parse_address(struct nn_socket *sock, str *addr, u16 port) { struct addrinfo hints = { 0 }; @@ -212,18 +182,18 @@ bool nn_socket_accept(struct nn_socket *sock, struct nn_socket *cl, s32 flags) switch (cl->type) { case NNWT_SOCKET_TCP: { - u16 port = 0; + //u16 port = 0; char addr_str[INET6_ADDRSTRLEN] = { 0 }; if (addr.ss_family == AF_INET) { struct sockaddr_in *saddr = (struct sockaddr_in *)&addr; - port = ntohs(saddr->sin_port); + //port = ntohs(saddr->sin_port); inet_ntop(AF_INET, &saddr->sin_addr, addr_str, sizeof(addr_str)); } else if (addr.ss_family == AF_INET6) { struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr; - port = ntohs(saddr->sin6_port); + //port = ntohs(saddr->sin6_port); inet_ntop(AF_INET6, &saddr->sin6_addr, addr_str, sizeof(addr_str)); } - log_debug("Connection from %s:%hu.", addr_str, port); + log_debug("Connection from %s.", addr_str); break; } case NNWT_SOCKET_UNIX: @@ -281,6 +251,11 @@ ssize_t nn_socket_recvfrom(struct nn_socket *sock, void *buf, size_t size) return recvfrom(sock->fd, buf, size, 0, sock->addrinfo->ai_addr, &sock->addrinfo->ai_addrlen); } +bool nn_socket_eagain(ssize_t ret) +{ + return (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)); +} + // This would normally be a log_warn() but we rely on expected errors for control flow. bool nn_socket_check_error(ssize_t ret) { diff --git a/src/socket/socket_windows.c b/src/socket/socket_windows.c index 5e3386c..0671686 100644 --- a/src/socket/socket_windows.c +++ b/src/socket/socket_windows.c @@ -35,10 +35,10 @@ void nn_socket_set_blocking(struct nn_socket *sock, bool blocking) ioctlsocket(sock->fd, FIONBIO, &mode); } -void nn_socket_set_nodelay(struct nn_socket *sock, s32 nodelay) +void nn_socket_set_cork(struct nn_socket *sock, s32 cork) { (void)sock; - (void)nodelay; + (void)cork; } void nn_socket_set_reuse_addr(struct nn_socket *sock, s32 reuse_addr) @@ -152,6 +152,14 @@ ssize_t nn_socket_recvfrom(struct nn_socket *sock, void *buf, size_t size) return 0; } +bool nn_socket_eagain(ssize_t ret) +{ + if (ret == SOCKET_ERROR) { + return WSAGetLastError() == WSAEWOULDBLOCK; + } + return false; +} + bool nn_socket_check_error(ssize_t ret) { if (ret == SOCKET_ERROR) { -- cgit v1.2.3-101-g0448