stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
This commit is contained in:
1 parent
a3783b5f55
commit
38c9f229bc
1272 files changed
+968388
-1
No files matched your search
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Socket compatibility layer implementation
|
||||
*/
|
||||
|
||||
#include "socket_compat.h"
|
||||
#include "debug_config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
// ==================== Windows Implementation ====================
|
||||
|
||||
static int wsa_init_count = 0;
|
||||
|
||||
int socket_platform_init(void) {
|
||||
if (wsa_init_count == 0) {
|
||||
WSADATA wsaData;
|
||||
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (result != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "WSAStartup failed: %d", result);
|
||||
return -1;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "Winsock 2.2 initialized");
|
||||
}
|
||||
wsa_init_count++;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "Winsock init count: %d", wsa_init_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void socket_platform_cleanup(void) {
|
||||
if (wsa_init_count > 0) {
|
||||
wsa_init_count--;
|
||||
if (wsa_init_count == 0) {
|
||||
WSACleanup();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "Winsock cleanup completed");
|
||||
} else {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "Winsock init count after cleanup: %d", wsa_init_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_nonblocking(socket_t sock) {
|
||||
u_long mode = 1;
|
||||
if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET,
|
||||
"ioctlsocket(FIONBIO) failed: %d", socket_get_error());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_close_wrapper(socket_t sock) {
|
||||
return closesocket(sock);
|
||||
}
|
||||
|
||||
const char* socket_strerror(int err) {
|
||||
static char buf[256];
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buf, sizeof(buf), NULL);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#else
|
||||
// ==================== POSIX Implementation ====================
|
||||
|
||||
int socket_platform_init(void) {
|
||||
// No initialization needed on POSIX
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "POSIX socket subsystem ready");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void socket_platform_cleanup(void) {
|
||||
// No cleanup needed on POSIX
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "POSIX socket cleanup completed");
|
||||
}
|
||||
|
||||
int socket_set_nonblocking(socket_t sock) {
|
||||
int flags = fcntl(sock, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET,
|
||||
"fcntl(F_GETFL) failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET,
|
||||
"fcntl(F_SETFL) failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_close_wrapper(socket_t sock) {
|
||||
if (sock == 0) return 0; // never close fd 0
|
||||
return close(sock);
|
||||
}
|
||||
|
||||
const char* socket_strerror(int err) {
|
||||
return strerror(err);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ==================== Universal Implementations ====================
|
||||
|
||||
socket_t socket_create_udp(int family) {
|
||||
socket_t sock = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock == SOCKET_INVALID) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET,
|
||||
"socket(SOCK_DGRAM) failed: %s", socket_strerror(socket_get_error()));
|
||||
return SOCKET_INVALID;
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "Created UDP socket: %ld", (long)sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
int socket_set_buffers(socket_t sock, int sndbuf, int rcvbuf) {
|
||||
int err = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows uses char* for optval
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
|
||||
(const char*)&sndbuf, sizeof(sndbuf)) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_SNDBUF failed: %s", socket_strerror(socket_get_error()));
|
||||
err = -1;
|
||||
}
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
|
||||
(const char*)&rcvbuf, sizeof(rcvbuf)) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_RCVBUF failed: %s", socket_strerror(socket_get_error()));
|
||||
err = -1;
|
||||
}
|
||||
#else
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_SNDBUF failed: %s", strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_RCVBUF failed: %s", strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int socket_set_reuseaddr(socket_t sock, int reuse) {
|
||||
#ifdef _WIN32
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char*)&reuse, sizeof(reuse)) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_REUSEADDR failed: %s", socket_strerror(socket_get_error()));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_REUSEADDR failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_bind_to_device(socket_t sock, const char* ifname) {
|
||||
#ifndef _WIN32
|
||||
#ifdef SO_BINDTODEVICE
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_BINDTODEVICE failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
(void)sock;
|
||||
(void)ifname;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "SO_BINDTODEVICE not available");
|
||||
return -1;
|
||||
#endif
|
||||
#else
|
||||
// Windows doesn't support SO_BINDTODEVICE
|
||||
(void)sock;
|
||||
(void)ifname;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "SO_BINDTODEVICE not available on Windows");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int socket_set_mark(socket_t sock, int mark) {
|
||||
#ifndef _WIN32
|
||||
#ifdef SO_MARK
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET,
|
||||
"SO_MARK failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
(void)sock;
|
||||
(void)mark;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "SO_MARK not available");
|
||||
return -1;
|
||||
#endif
|
||||
#else
|
||||
// Windows doesn't support SO_MARK
|
||||
(void)sock;
|
||||
(void)mark;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_SOCKET, "SO_MARK not available on Windows");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t socket_sendto(socket_t sock, const void* buf, size_t len,
|
||||
const struct sockaddr* dest, socklen_t dest_len) {
|
||||
#ifdef _WIN32
|
||||
return sendto(sock, (const char*)buf, (int)len, 0, dest, dest_len);
|
||||
#else
|
||||
return sendto(sock, buf, len, 0, dest, dest_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t socket_recvfrom(socket_t sock, void* buf, size_t len,
|
||||
struct sockaddr* src, socklen_t* src_len) {
|
||||
#ifdef _WIN32
|
||||
int fromlen = src_len ? (int)*src_len : 0;
|
||||
ssize_t ret = recvfrom(sock, (char*)buf, (int)len, 0, src, src_len ? &fromlen : NULL);
|
||||
if (src_len) *src_len = (socklen_t)fromlen;
|
||||
return ret;
|
||||
#else
|
||||
return recvfrom(sock, buf, len, 0, src, src_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t ss_get_port(const struct sockaddr_storage *addr) {
|
||||
if (!addr) return 0;
|
||||
|
||||
if (addr->ss_family == AF_INET) {
|
||||
const struct sockaddr_in *ipv4 = (const struct sockaddr_in *)addr;
|
||||
return ntohs(ipv4->sin_port);
|
||||
}
|
||||
else if (addr->ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *ipv6 = (const struct sockaddr_in6 *)addr;
|
||||
return ntohs(ipv6->sin6_port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user