无法初始化CAresDNSResolver.Options,如何配置AsyncDNSResolver的DNS服务器和超时?
问题
我正在使用Apple的AsyncDNSResolver,希望在创建AsyncDNSResolver(options:)实例时指定CAresDNSResolver.Options(包括查询超时时间与要使用的域名服务器)。但初始化var options: CAresDNSResolver.Options = CAresDNSResolver.Options()时,Xcode报错:'CAresDNSResolver.Options' initializer is inaccessible due to 'internal' protection level。
我需要一种初始化该Options结构体的方法,以便传递给AsyncDNSResolver;如果无法实现,也可以提供设置AsyncDNSResolver查询所用域名服务器的替代方案。
相关函数代码(仅设置Options部分无法正常工作):
func getDmarcTxtWithDomainName(domainName: String, altDnsServer: String = "") async throws -> String { var dmarcString: String var resolver: AsyncDNSResolver do { if altDnsServer.isEmpty { resolver = try AsyncDNSResolver() } else { // TODO: set the resolver to use altDnsServer and timeout var options: CAresDNSResolver.Options = CAresDNSResolver.Options() // (1) options.servers = [altDnsServer] // (2) options.timeoutMillis = 2000. // (3) resolver = try AsyncDNSResolver(options: options) } let txtRecords = try await resolver.queryTXT(name: domainName) if txtRecords.count > 0 { dmarcString = subStringInTxtRecords(subString: "v=DMARC", txtRecords: txtRecords) if dmarcString.count == 0 { dmarcString = "None found" } } else { dmarcString = "None found" } } catch { debugLog(object: error.localizedDescription) throw error } return dmarcString }
解决方案
1. 初始化CAresDNSResolver.Options的可行方法
CAresDNSResolver.Options的默认初始化器是internal权限,外部无法直接调用,你可以通过扩展该结构体,添加公开初始化器来解决:
extension CAresDNSResolver.Options { public init(servers: [String] = [], timeoutMillis: UInt32 = 5000) { self.servers = servers self.timeoutMillis = timeoutMillis // 补充结构体其他属性的默认值,参考库内部逻辑 self.tries = 2 self.ndots = 1 self.rotate = false // 若有其他属性,按库源码默认值补充初始化 } }
添加扩展后,即可正常初始化并配置参数:
var options = CAresDNSResolver.Options(servers: [altDnsServer], timeoutMillis: 2000) resolver = try AsyncDNSResolver(options: options)
注意:需确保所有结构体属性都被正确初始化,可查看库源码中CAresDNSResolver.Options的默认值保持逻辑一致。
2. 替代方案:手动指定DNS服务器的自定义解析
如果不想修改库的访问权限,可手动实现基于指定DNS服务器的解析逻辑(需处理DNS协议细节):
func queryTXT(domain: String, dnsServer: String) async throws -> [String] { let dnsPort = NWEndpoint.Port(rawValue: 53)! let serverEndpoint = NWEndpoint.hostPort(host: .init(dnsServer), port: dnsPort) // 这里需要构建DNS TXT查询报文、发送到指定服务器并解析响应 // 以下为简化示例,需完善DNS协议解析逻辑 let connection = NWConnection(to: serverEndpoint, using: .udp) // 实现DNS查询的异步逻辑... // 解析响应后返回TXT记录数组 }
这种方式需要处理DNS协议的编码和解码,复杂度较高,仅推荐在无法扩展库的情况下使用。
内容的提问来源于stack exchange,提问作者Kent
相关产品推荐
相关产品推荐

