Files
waf-platform/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsLocalResolver.m
2026-02-20 17:56:24 +08:00

151 lines
4.6 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HttpdnsLocalResolver.m
// AlicloudHttpDNS
//
// Created by xuyecan on 2025/3/16.
// Copyright © 2025 alibaba-inc.com. All rights reserved.
//
#import "HttpdnsLocalResolver.h"
#import <netdb.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <sys/socket.h>
#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<NSString *> *ipv4Array = [NSMutableArray array];
NSMutableArray<NSString *> *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<HttpdnsIpObject *> *v4IpObjects = [NSMutableArray array];
NSMutableArray<HttpdnsIpObject *> *v6IpObjects = [NSMutableArray array];
if (wantIPv4) {
for (NSString *ipStr in ipv4Array) {
HttpdnsIpObject *ipObj = [[HttpdnsIpObject alloc] init];
[ipObj setIp:ipStr]; // ipObj.ip = ipStr
// connectedRT默认为0
[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为60秒
[hostObject setV4TTL:60];
[hostObject setV6TTL:60];
// 自定义ttl
[HttpdnsUtil processCustomTTL:hostObject forHost:host service:service];
// 当前时间(自1970年以来的秒数)
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