// // HttpdnsLocalResolver.m // NewHttpDNS // // Created by xuyecan on 2025/3/16. // Copyright © 2025 trustapp.com. All rights reserved. // #import "HttpdnsLocalResolver.h" #import #import #import #import #import "HttpdnsService.h" #import "HttpdnsUtil.h" #import "HttpdnsHostObject.h" @implementation HttpdnsLocalResolver - (HttpdnsHostObject *)resolve:(HttpdnsRequest *)request { // 1. 验证输入参数 NSString *host = request.host; if (host.length == 0) { return nil; // 没有主机名可解析 } HttpDnsService *service = [HttpDnsService getInstanceByAccountId:request.accountId]; if (!service) { service = [HttpDnsService sharedInstance]; } // 2. 准备DNS解析配置 struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // 同时支持IPv4和IPv6 hints.ai_socktype = SOCK_STREAM; // TCP (对DNS解析来说通常不重? // 3. 执行getaddrinfo解析 struct addrinfo *res = NULL; int ret = getaddrinfo([host UTF8String], NULL, &hints, &res); if (ret != 0 || res == NULL) { // DNS解析失败 if (res) { freeaddrinfo(res); } return nil; } // 4. 收集所有IPv4和IPv6地址 NSMutableArray *ipv4Array = [NSMutableArray array]; NSMutableArray *ipv6Array = [NSMutableArray array]; for (struct addrinfo *p = res; p != NULL; p = p->ai_next) { if (p->ai_family == AF_INET || p->ai_family == AF_INET6) { char hostBuffer[NI_MAXHOST]; memset(hostBuffer, 0, sizeof(hostBuffer)); if (getnameinfo(p->ai_addr, (socklen_t)p->ai_addrlen, hostBuffer, sizeof(hostBuffer), NULL, 0, NI_NUMERICHOST) == 0) { NSString *ipString = [NSString stringWithUTF8String:hostBuffer]; if (p->ai_family == AF_INET) { [ipv4Array addObject:ipString]; } else { [ipv6Array addObject:ipString]; } } } } freeaddrinfo(res); // 5. 根据queryIpType确定保留哪些IP类型 BOOL wantIPv4 = NO; BOOL wantIPv6 = NO; switch (request.queryIpType) { case HttpdnsQueryIPTypeAuto: // Auto模式:如果有IPv4则始终返回,如果有IPv6则也包含 // 无条件设置wantIPv4为YES wantIPv4 = YES; // 如果DNS返回了IPv6地址,则也包含IPv6 wantIPv6 = (ipv6Array.count > 0); break; case HttpdnsQueryIPTypeIpv4: wantIPv4 = YES; break; case HttpdnsQueryIPTypeIpv6: wantIPv6 = YES; break; case HttpdnsQueryIPTypeBoth: wantIPv4 = YES; wantIPv6 = YES; break; } // 6. 构建最终的HttpdnsIpObject数组 NSMutableArray *v4IpObjects = [NSMutableArray array]; NSMutableArray *v6IpObjects = [NSMutableArray array]; if (wantIPv4) { for (NSString *ipStr in ipv4Array) { HttpdnsIpObject *ipObj = [[HttpdnsIpObject alloc] init]; [ipObj setIp:ipStr]; // ipObj.ip = ipStr // connectedRT默认? [v4IpObjects addObject:ipObj]; } } if (wantIPv6) { for (NSString *ipStr in ipv6Array) { HttpdnsIpObject *ipObj = [[HttpdnsIpObject alloc] init]; [ipObj setIp:ipStr]; [v6IpObjects addObject:ipObj]; } } // 7. 创建并填充HttpdnsHostObject HttpdnsHostObject *hostObject = [[HttpdnsHostObject alloc] init]; [hostObject setHostName:host]; // hostName = request.host [hostObject setV4Ips:v4IpObjects]; [hostObject setV6Ips:v6IpObjects]; // IPv4和IPv6的默认TTL?0? [hostObject setV4TTL:60]; [hostObject setV6TTL:60]; // 自定义ttl [HttpdnsUtil processCustomTTL:hostObject forHost:host service:service]; // 当前时间(?970年以来的秒数) int64_t now = (int64_t)[[NSDate date] timeIntervalSince1970]; // 更新最后查询时? [hostObject setLastIPv4LookupTime:now]; [hostObject setLastIPv6LookupTime:now]; // 标记是否没有IPv4或IPv6记录 [hostObject setHasNoIpv4Record:(v4IpObjects.count == 0)]; [hostObject setHasNoIpv6Record:(v6IpObjects.count == 0)]; // 如果需要,可以在这里设置clientIp或额外字? // 现在保留为默认?? return hostObject; } @end