auto_socket: Windows-скан + список сокетов в Network Settings (add/remove, чистый rewrite конфига)
This commit is contained in:
1 parent
d5119ac7c6
commit
f82dca3185
8 files changed
+545
-160
No files matched your search
@@ -698,19 +698,91 @@ static void auto_socket_scan_all(struct AUTO_SOCKET* as) {
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
/* Собирает IfIndex всех UP не-loopback адаптеров. Возвращает число найденных (до max_count). */
|
||||
static int win_collect_up_ifaces(uint32_t* out_ifindex, int max_count) {
|
||||
PIP_ADAPTER_ADDRESSES adapters = NULL;
|
||||
ULONG size = 0;
|
||||
ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
DWORD rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &size);
|
||||
if (rv != ERROR_BUFFER_OVERFLOW) return 0;
|
||||
adapters = (PIP_ADAPTER_ADDRESSES)u_malloc(size);
|
||||
if (!adapters) return 0;
|
||||
rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &size);
|
||||
if (rv != NO_ERROR) { u_free(adapters); return 0; }
|
||||
|
||||
int count = 0;
|
||||
for (PIP_ADAPTER_ADDRESSES a = adapters; a && count < max_count; a = a->Next) {
|
||||
if (a->OperStatus != IfOperStatusUp) continue;
|
||||
if (a->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
|
||||
out_ifindex[count++] = a->IfIndex;
|
||||
}
|
||||
u_free(adapters);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int scan_and_classify_iface(uint32_t ifindex, const char* ifname,
|
||||
int* out_has_v4, int* out_has_v6,
|
||||
uint8_t* out_v4_type, uint8_t* out_v6_type) {
|
||||
(void)ifindex; (void)ifname;
|
||||
(void)ifname;
|
||||
*out_has_v4 = 0; *out_has_v6 = 0;
|
||||
*out_v4_type = CFG_SERVER_TYPE_NAT;
|
||||
*out_v6_type = CFG_SERVER_TYPE_NAT;
|
||||
|
||||
PIP_ADAPTER_ADDRESSES adapters = NULL;
|
||||
ULONG size = 0;
|
||||
ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
DWORD rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &size);
|
||||
if (rv != ERROR_BUFFER_OVERFLOW) return -1;
|
||||
adapters = (PIP_ADAPTER_ADDRESSES)u_malloc(size);
|
||||
if (!adapters) return -1;
|
||||
rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &size);
|
||||
if (rv != NO_ERROR) { u_free(adapters); return -1; }
|
||||
|
||||
PIP_ADAPTER_ADDRESSES a = adapters;
|
||||
while (a && a->IfIndex != ifindex) a = a->Next;
|
||||
if (!a || a->OperStatus != IfOperStatusUp || a->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
|
||||
u_free(adapters);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (PIP_ADAPTER_UNICAST_ADDRESS u = a->FirstUnicastAddress; u; u = u->Next) {
|
||||
if (!u->Address.lpSockaddr) continue;
|
||||
if (u->Address.lpSockaddr->sa_family == AF_INET) {
|
||||
const struct sockaddr_in* sin = (const struct sockaddr_in*)u->Address.lpSockaddr;
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY) continue;
|
||||
*out_has_v4 = 1;
|
||||
if (is_ipv4_public(sin->sin_addr.s_addr)) *out_v4_type = CFG_SERVER_TYPE_PUBLIC;
|
||||
} else if (u->Address.lpSockaddr->sa_family == AF_INET6) {
|
||||
const struct sockaddr_in6* sin6 = (const struct sockaddr_in6*)u->Address.lpSockaddr;
|
||||
int cls = v6_classify(sin6->sin6_addr.s6_addr);
|
||||
if (cls == AS_V6_OTH || cls == AS_V6_LL) continue;
|
||||
*out_has_v6 = 1;
|
||||
if (cls == AS_V6_DIR) *out_v6_type = CFG_SERVER_TYPE_PUBLIC;
|
||||
}
|
||||
}
|
||||
u_free(adapters);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void auto_socket_scan_all(struct AUTO_SOCKET* as) {
|
||||
(void)as;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_AS, "[as] Windows: auto_socket_scan_all not yet implemented");
|
||||
uint32_t up[64];
|
||||
int up_count = win_collect_up_ifaces(up, 64);
|
||||
|
||||
for (int i = 0; i < up_count; i++) {
|
||||
char ifname[IF_NAMESIZE];
|
||||
if (!if_indextoname(up[i], ifname)) snprintf(ifname, sizeof(ifname), "if%u", up[i]);
|
||||
reconcile_iface(as, up[i], ifname);
|
||||
}
|
||||
|
||||
/* prune: удаляем сокеты адаптеров, которых больше нет в UP-списке (или они DOWN) */
|
||||
struct auto_sock_iface** pp = &as->ifaces;
|
||||
while (*pp) {
|
||||
struct auto_sock_iface* ifa = *pp;
|
||||
int found = 0;
|
||||
for (int i = 0; i < up_count; i++) if (up[i] == ifa->netif_index) { found = 1; break; }
|
||||
if (!found) { remove_iface_sockets(as, ifa->netif_index); continue; }
|
||||
pp = &ifa->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Reference in new issue
Block a user