15#define native_connection_close_socket closesocket
16#define native_connection_shutdown_socket(fd) shutdown((SOCKET)(fd), SD_BOTH)
17#define native_connection_recv(fd, buffer, len) recv((SOCKET)(fd), (char *)(buffer), (int)(len), 0)
18#define native_connection_send(fd, buffer, len) send((SOCKET)(fd), (const char *)(buffer), (int)(len), 0)
21#include <netinet/in.h>
22#include <sys/socket.h>
26#define native_connection_close_socket close
27#define native_connection_shutdown_socket(fd) shutdown((fd), SHUT_RDWR)
28#define native_connection_recv(fd, buffer, len) recv((fd), (buffer), (len), 0)
29#define native_connection_send(fd, buffer, len) send((fd), (buffer), (len), 0)
32#define NATIVE_CONNECTION_IO_TIMEOUT_SECONDS 15
35#define native_connection_strdup _strdup
37#define native_connection_strdup strdup
45 if (addr->sa_family == AF_INET && addr_len >= (socklen_t)
sizeof(
struct sockaddr_in)) {
46 const struct sockaddr_in *in = (
const struct sockaddr_in *)addr;
47 char ip[INET_ADDRSTRLEN];
48 if (inet_ntop(AF_INET, &in->sin_addr, ip,
sizeof(ip)) == NULL) {
51 snprintf(buffer,
sizeof(buffer),
"%s:%u", ip, (
unsigned int)ntohs(in->sin_port));
55 if (addr->sa_family == AF_UNIX && addr_len >= (socklen_t)
sizeof(
struct sockaddr_un)) {
56 const struct sockaddr_un *un = (
const struct sockaddr_un *)addr;
57 if (un->sun_path[0] !=
'\0') {
67 struct sockaddr_storage addr;
68 socklen_t addr_len = (socklen_t)
sizeof(addr);
69 memset(&addr, 0,
sizeof(addr));
70 if (getsockname(fd, (
struct sockaddr *)&addr, &addr_len) != 0) {
73 if (addr.ss_family == AF_INET) {
77 if (addr.ss_family == AF_UNIX) {
87 setsockopt((SOCKET)fd, SOL_SOCKET, SO_RCVTIMEO, (
const char *)&timeout_ms,
sizeof(timeout_ms));
88 setsockopt((SOCKET)fd, SOL_SOCKET, SO_SNDTIMEO, (
const char *)&timeout_ms,
sizeof(timeout_ms));
90 struct timeval timeout;
93 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout));
94 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout,
sizeof(timeout));
99 struct sockaddr_storage peer_addr;
100 struct sockaddr_storage local_addr;
101 socklen_t peer_len = (socklen_t)
sizeof(peer_addr);
102 socklen_t local_len = (socklen_t)
sizeof(local_addr);
103 if (connection == NULL || connection->
fd < 0) {
106 memset(&peer_addr, 0,
sizeof(peer_addr));
107 memset(&local_addr, 0,
sizeof(local_addr));
112 if (getpeername(connection->
fd, (
struct sockaddr *)&peer_addr, &peer_len) == 0) {
115 if (getsockname(connection->
fd, (
struct sockaddr *)&local_addr, &local_len) == 0) {
127 if (connection == NULL) {
137 if (connection == NULL) {
151 SOCKET socket_value = accept((SOCKET)server_fd, NULL, NULL);
152 if (socket_value == INVALID_SOCKET) {
153 if (shutdown_requested != NULL && *shutdown_requested) {
158 accepted = (int)socket_value;
160 accepted = accept(server_fd, NULL, NULL);
161 if (accepted == -1) {
162 if (shutdown_requested != NULL && *shutdown_requested) {
168 if (connection == NULL) {
174 connection->
fd = accepted;
181 if (connection == NULL || connection->
fd < 0 || buffer == NULL) {
189 if (connection == NULL || connection->
fd < 0 || (buffer == NULL &&
len > 0)) {
197 sent += (size_t)wrote;
209 if (connection == NULL) {
212 if (connection->
fd >= 0) {
220 if (connection == NULL || connection->
fd < 0) {
227 return connection != NULL && connection->
peer_info != NULL ? connection->
peer_info :
"unknown";
231 return connection != NULL && connection->
local_info != NULL ? connection->
local_info :
"unknown";
#define native_connection_strdup
int native_connection_flush(NativeConnection *connection)
Flushes any buffered connection output when the transport requires it.
int native_connection_close(NativeConnection *connection)
Closes a native connection and releases its owned metadata.
int native_connection_accept_next(int server_fd, volatile sig_atomic_t *shutdown_requested, NativeConnection *connection)
Accepts the next client connection and records its transport metadata.
int native_connection_shutdown(NativeConnection *connection)
Shuts down a native connection without discarding the record itself.
int native_connection_write(NativeConnection *connection, const void *buffer, size_t len)
Writes bytes to a native connection.
#define native_connection_shutdown_socket(fd)
static void native_connection_apply_timeouts(int fd)
#define native_connection_close_socket
const char * native_connection_local_info(const NativeConnection *connection)
Returns the printable local endpoint description for a connection.
void native_connection_reset(NativeConnection *connection)
Releases owned transport metadata and resets a connection record.
static char * native_connection_format_sockaddr(const struct sockaddr *addr, socklen_t addr_len)
const char * native_connection_transport_type_name(const NativeConnection *connection)
Returns a human-readable transport type name for a connection.
static void native_connection_populate_endpoint_info(NativeConnection *connection)
void native_connection_init(NativeConnection *connection)
Initializes a native connection record to an empty state.
#define NATIVE_CONNECTION_IO_TIMEOUT_SECONDS
NativeTransportType native_connection_transport_type(const NativeConnection *connection)
Returns the resolved transport type for a connection.
static NativeTransportType native_connection_detect_transport(int fd)
#define native_connection_send(fd, buffer, len)
int native_connection_read(NativeConnection *connection, void *buffer, size_t len)
Reads bytes from a native connection.
const char * native_connection_peer_info(const NativeConnection *connection)
Returns the printable remote endpoint description for a connection.
#define native_connection_recv(fd, buffer, len)
Declares the native connection abstraction and transport metadata helpers.
NativeTransportType
Transport type used by a native connection.
@ NATIVE_TRANSPORT_UNKNOWN
Accepted client connection and its resolved transport metadata.
NativeTransportType transport_type