Skip to content

Commit d9afa74

Browse files
authored
Avoid memory leak from hostent (#30)
hostent is internally allocated by ares_parse_a_reply when we pass non-null pointer, and it expects the caller to freehostent(hostent).
1 parent 1f5d6f4 commit d9afa74

File tree

1 file changed

+2
-14
lines changed

1 file changed

+2
-14
lines changed

Sources/AsyncDNSResolver/c-ares/DNSResolver_c-ares.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,6 @@ extension Ares {
303303
static let instance = AQueryReplyParser()
304304

305305
func parse(buffer: UnsafeMutablePointer<CUnsignedChar>?, length: CInt) throws -> [ARecord] {
306-
// `hostent` is not needed, but if we don't allocate and pass it as an arg c-ares will allocate one
307-
// and free it automatically, and that might cause TSAN errors in `ares_free_hostent`. If we allocate
308-
// it then we control when it's freed.
309-
let hostentPtrPtr = UnsafeMutablePointer<UnsafeMutablePointer<hostent>?>.allocate(capacity: 1)
310-
defer { hostentPtrPtr.deallocate() }
311-
312306
let addrttlsPointer = UnsafeMutablePointer<ares_addrttl>.allocate(capacity: Ares.maxAddresses)
313307
defer { addrttlsPointer.deallocate() }
314308
let naddrttlsPointer = UnsafeMutablePointer<CInt>.allocate(capacity: 1)
@@ -317,7 +311,7 @@ extension Ares {
317311
// Set a limit or else addrttl array won't be populated
318312
naddrttlsPointer.pointee = CInt(Ares.maxAddresses)
319313

320-
let parseStatus = ares_parse_a_reply(buffer, length, hostentPtrPtr, addrttlsPointer, naddrttlsPointer)
314+
let parseStatus = ares_parse_a_reply(buffer, length, nil, addrttlsPointer, naddrttlsPointer)
321315
guard parseStatus == ARES_SUCCESS else {
322316
throw AsyncDNSResolver.Error(code: parseStatus, "failed to parse A query reply")
323317
}
@@ -332,12 +326,6 @@ extension Ares {
332326
static let instance = AAAAQueryReplyParser()
333327

334328
func parse(buffer: UnsafeMutablePointer<CUnsignedChar>?, length: CInt) throws -> [AAAARecord] {
335-
// `hostent` is not needed, but if we don't allocate and pass it as an arg c-ares will allocate one
336-
// and free it automatically, and that might cause TSAN errors in `ares_free_hostent`. If we allocate
337-
// it then we control when it's freed.
338-
let hostentPtrPtr = UnsafeMutablePointer<UnsafeMutablePointer<hostent>?>.allocate(capacity: 1)
339-
defer { hostentPtrPtr.deallocate() }
340-
341329
let addrttlsPointer = UnsafeMutablePointer<ares_addr6ttl>.allocate(capacity: Ares.maxAddresses)
342330
defer { addrttlsPointer.deallocate() }
343331
let naddrttlsPointer = UnsafeMutablePointer<CInt>.allocate(capacity: 1)
@@ -346,7 +334,7 @@ extension Ares {
346334
// Set a limit or else addrttl array won't be populated
347335
naddrttlsPointer.pointee = CInt(Ares.maxAddresses)
348336

349-
let parseStatus = ares_parse_aaaa_reply(buffer, length, hostentPtrPtr, addrttlsPointer, naddrttlsPointer)
337+
let parseStatus = ares_parse_aaaa_reply(buffer, length, nil, addrttlsPointer, naddrttlsPointer)
350338
guard parseStatus == ARES_SUCCESS else {
351339
throw AsyncDNSResolver.Error(code: parseStatus, "failed to parse AAAA query reply")
352340
}

0 commit comments

Comments
 (0)