chatgui: IPv4+IPv6 dual-stack listen by default
- Default config creates [server:lan] (0.0.0.0) + [server:lan6] ([::]) - Network settings save also writes [server:lan6] section - Sets IPV6_V6ONLY=1 on IPv6 sockets to avoid conflict with IPv4 - interface_addr for [::] bind prefers permanent IPv6 over temporary
This commit is contained in:
1 parent
7799d54c0c
commit
af3e2ee869
3 files changed
+37
-10
No files matched your search
@@ -556,6 +556,13 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
|
||||
if (socket_set_nonblocking(e_sock->fd) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set non-blocking mode");
|
||||
}
|
||||
|
||||
if (family == AF_INET6) {
|
||||
int v6only = 1;
|
||||
if (setsockopt(e_sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set IPV6_V6ONLY: %s", socket_strerror(socket_get_error()));
|
||||
}
|
||||
}
|
||||
|
||||
// Set socket mark if specified (Linux only)
|
||||
if (so_mark > 0) {
|
||||
@@ -637,15 +644,28 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
|
||||
} else if (ip->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)ip;
|
||||
if (memcmp(&sin6->sin6_addr, &in6addr_any, sizeof(struct in6_addr)) == 0) {
|
||||
// :: — определяем через default route
|
||||
struct sockaddr_storage remote;
|
||||
memset(&remote, 0, sizeof(remote));
|
||||
struct sockaddr_in6* rem_sin6 = (struct sockaddr_in6*)&remote;
|
||||
rem_sin6->sin6_family = AF_INET6;
|
||||
rem_sin6->sin6_port = htons(53);
|
||||
inet_pton(AF_INET6, "2001:4860:4860::8888", &rem_sin6->sin6_addr);
|
||||
if (get_outgoing_local_ip(ip, &remote, &e_sock->interface_addr) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to detect outgoing local IPv6 for socket %s", e_sock->name);
|
||||
// :: — приоритет: permanent > temporary > get_outgoing_local_ip
|
||||
uint16_t v6if = (netif_index > 0) ? netif_index : get_default_route_netif_index(AF_INET6);
|
||||
if (v6if > 0) {
|
||||
uint8_t v6addr[16];
|
||||
int got = get_interface_ipv6_by_index(v6if, 0, v6addr);
|
||||
if (got != 0) got = get_interface_ipv6_by_index(v6if, 1, v6addr);
|
||||
if (got == 0) {
|
||||
struct sockaddr_in6* if6 = (struct sockaddr_in6*)&e_sock->interface_addr;
|
||||
if6->sin6_family = AF_INET6;
|
||||
memcpy(&if6->sin6_addr, v6addr, 16);
|
||||
}
|
||||
}
|
||||
if (e_sock->interface_addr.ss_family == 0) {
|
||||
struct sockaddr_storage remote;
|
||||
memset(&remote, 0, sizeof(remote));
|
||||
struct sockaddr_in6* rem_sin6 = (struct sockaddr_in6*)&remote;
|
||||
rem_sin6->sin6_family = AF_INET6;
|
||||
rem_sin6->sin6_port = htons(53);
|
||||
inet_pton(AF_INET6, "2001:4860:4860::8888", &rem_sin6->sin6_addr);
|
||||
if (get_outgoing_local_ip(ip, &remote, &e_sock->interface_addr) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to detect outgoing local IPv6 for socket %s", e_sock->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user