IPv6: STCP dual-stack + Android config + invite fixes

- stcp_server: dual-stack (AF_INET6 + IPV6_V6ONLY=0) instead of IPv4-only
- stcp_client: getaddrinfo(AF_UNSPEC) instead of inet_pton(AF_INET)
- stcp_link: detect address family from remote_addr->ss_family
- platform_compat.h: add <netdb.h> for getaddrinfo on POSIX
- ConfigProvider.kt: add [server:main6] addr=[::]:PORT for Android
- invite_link_c.c: invite_serialize_addrs handles IPv6 (was IPv4-only)
This commit is contained in:
evgeny committed 2026-08-01 20:19:00 +03:00
1 parent f5e18891bc
commit 6719a1e23c
7 files changed
+48 -21

No files matched your search

+4 -1
View File
@@ -19,7 +19,10 @@ struct TOPO_GROUP;
* @file conn_mgr.h
* @brief Подключение к узлам P2P-сети. Handle-based API.
*
* === Архитектура ===
* Подключает к удалегному узлу либо напрямую, либо через посредника с прямыми адресами.
* При открытии выдаёт handle. и держит подключение открытым пока не закроешь handle.
* Отправлять можно обычным send через роутер - он сам разберётся как отправить,
* либо send этого моделя - он точно отправит через этот мост.
*
* Один CONN_MGR = одна TOPO_GROUP. Создаётся conn_mgr_init(group), живёт пока
* существует группа. Внутри: кеш entries (по одной на целевой узел), список
+16 -9
View File
@@ -258,16 +258,23 @@ struct stcp_client *stcp_client_connect(struct UASYNC *ua, const char *addr, uin
c->on_close = close_cb; c->close_arg = close_arg;
c->tx_cb = client_tx_queue_cb;
c->sock = socket(AF_INET, SOCK_STREAM, 0);
if (c->sock == SOCKET_INVALID) { u_free(cli); return NULL; }
socket_set_nonblocking(c->sock);
struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET; saddr.sin_port = htons(port);
if (inet_pton(AF_INET, addr, &saddr.sin_addr) != 1) { socket_close_wrapper(c->sock); u_free(cli); return NULL; }
if (connect(c->sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0 && socket_get_error() != EINPROGRESS) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "stcp_client connect to %s:%u failed err=%d", addr, port, socket_get_error());
socket_close_wrapper(c->sock); u_free(cli); return NULL;
struct addrinfo hints = {0};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
char port_str[16]; snprintf(port_str, sizeof(port_str), "%u", port);
struct addrinfo *res;
if (getaddrinfo(addr, port_str, &hints, &res) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "stcp_client getaddrinfo %s:%u failed", addr, port);
u_free(cli); return NULL;
}
c->sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (c->sock == SOCKET_INVALID) { freeaddrinfo(res); u_free(cli); return NULL; }
socket_set_nonblocking(c->sock);
if (connect(c->sock, res->ai_addr, res->ai_addrlen) < 0 && socket_get_error() != EINPROGRESS) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "stcp_client connect to %s:%u failed err=%d", addr, port, socket_get_error());
socket_close_wrapper(c->sock); freeaddrinfo(res); u_free(cli); return NULL;
}
freeaddrinfo(res);
c->socket_id = uasync_add_socket_t(ua, c->sock, NULL, client_connect_write_cb, NULL, cli);
if (!c->socket_id) { socket_close_wrapper(c->sock); u_free(cli); return NULL; }
return cli;
+14 -3
View File
@@ -133,10 +133,21 @@ struct stcp_link *stcp_link_connect(struct stcp_link_config *cfg) {
if (!cfg || !cfg->ua || !cfg->my_keys || !cfg->peer_pubkey || !cfg->remote_addr)
return NULL;
int family = cfg->remote_addr->ss_family;
char addr_str[64];
struct sockaddr_in *sa = (struct sockaddr_in *)cfg->remote_addr;
inet_ntop(AF_INET, &sa->sin_addr, addr_str, sizeof(addr_str));
uint16_t port = cfg->remote_port ? cfg->remote_port : ntohs(sa->sin_port);
uint16_t port;
if (family == AF_INET) {
struct sockaddr_in *sa = (struct sockaddr_in *)cfg->remote_addr;
inet_ntop(AF_INET, &sa->sin_addr, addr_str, sizeof(addr_str));
port = cfg->remote_port ? cfg->remote_port : ntohs(sa->sin_port);
} else if (family == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)cfg->remote_addr;
inet_ntop(AF_INET6, &sa6->sin6_addr, addr_str, sizeof(addr_str));
port = cfg->remote_port ? cfg->remote_port : ntohs(sa6->sin6_port);
} else {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "stcp_link: unsupported address family %d", family);
return NULL;
}
struct stcp_link *link = u_calloc(1, sizeof(struct stcp_link));
if (!link) return NULL;
+7 -5
View File
@@ -355,16 +355,18 @@ struct stcp_server *stcp_server_create(struct UASYNC *ua, uint16_t port,
srv->close_cb = close_cb;
srv->close_arg = close_arg;
srv->listen_sock = socket(AF_INET, SOCK_STREAM, 0);
srv->listen_sock = socket(AF_INET6, SOCK_STREAM, 0);
if (srv->listen_sock == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "socket failed"); u_free(srv); return NULL; }
socket_set_nonblocking(srv->listen_sock);
int reuse = 1;
setsockopt(srv->listen_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse, sizeof(reuse));
struct sockaddr_in addr;
int v6only = 0;
setsockopt(srv->listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&v6only, sizeof(v6only));
struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any;
addr.sin6_port = htons(port);
if (bind(srv->listen_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "bind port=%u failed err=%d", port, socket_get_error());
socket_close_wrapper(srv->listen_sock); u_free(srv); return NULL;