apple / swift-async-dns-resolver

A Swift library for asynchronous DNS requests, wrapping c-ares with Swift-friendly APIs and data structures.
Apache License 2.0
82 stars 12 forks source link

Possible memory leaks in Ares.query and AQueryReplyParser / AAAAQueryReplyParser #29

Closed dieb closed 4 months ago

dieb commented 4 months ago

Hi there,

I'm using the Xcode Leaks to inspect my app and leaks are showing up when using the lib (v0.3.0). Same leaks were showing up before I upgraded (v0.1.3).

I noticed two potential sources of leaks: 1) Continuation leaking in Ares.query: https://github.com/apple/swift-async-dns-resolver/blob/main/Sources/AsyncDNSResolver/c-ares/DNSResolver_c-ares.swift#L148 2) Hostent is leaking in AQueryReplyParser and AAAAQueryReplyParser and maybe others but I'm only doing A/AAAA

Possible explanation for 1): see PR #31

Possible explanation for 2) : ares_parse_a_reply will create hostent and fill it out here which then allocates stuff in addrinfo2hostent. It looks like it has the expectation the caller will call freehostent(hostent). Looks like we can pass host=null and and it won't allocate for *host (this worked and leaks are gone PR - #30 ). We aren't using hostent anyways.

Screenshots below.

Screenshot 2024-02-20 at 9 47 03 PM

Screenshot 2024-02-20 at 9 46 54 PM

Screenshot 2024-02-20 at 9 46 44 PM

How my app uses the lib (note: I don't reuse AsyncDNSResolver, it gets collected):

var options = CAresDNSResolver.Options.default
options.timeoutMillis = 200
options.servers = Constants.DNSServers
options.rotate = true
resolver = try AsyncDNSResolver(options: options)

Querying

let aRecords = try? await resolver.queryA(name: hostname)
let aaaaRecords = try? await resolver.queryAAAA(name: hostname)

let a = aRecords?.map { aRecord in
    Record(address: aRecord.address.description, ttl: aRecord.ttl.map { Int($0) } ?? DNSResolver.defaultTTL)
}

let aaaa = aaaaRecords?.map { aaaaRecord in
    Record(address: aaaaRecord.address.description, ttl: aaaaRecord.ttl.map { Int($0) } ?? DNSResolver.defaultTTL)
}
yim-lee commented 4 months ago

Patch release that includes the fixes: https://github.com/apple/swift-async-dns-resolver/releases/tag/0.3.1