Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is struct addrinfo **res allocated when getaddrinfo() returns a non-zero value?

Tags:

c

getaddrinfo

I am having some memory leaking troubles in an embedded application and while looking in the code, I see I do not freeaddrinfo() when getaddrinfo() returns non-zero:

s = getaddrinfo(hostname, port, &hints, &result);
if (s != 0) {
  log_error();
} else {
  // do stuff
  freeaddrinfo(result);
}

Could this lead to memory leaks? I have tried to look into the man page, but it doesn't state it explicitly.

like image 648
Bart Friederichs Avatar asked Aug 20 '12 09:08

Bart Friederichs


People also ask

What does getaddrinfo return?

The getaddrinfo() function translates the name of a service location (for example, a host name) and/or service name and returns a set of socket addresses and associated information to be used in creating a socket with which to address the specified service.

What does the function getaddrinfo () do?

The getaddrinfo function can be used to convert a text string representation of an IP address to an addrinfo structure that contains a sockaddr structure for the IP address and other information.

Why is Addrinfo a linked list?

There are several reasons why the linked list may have more than one addrinfo structure, including: the network host is multihomed, accessible over multiple protocols (e.g., both AF_INET and AF_INET6); or the same service is available from multiple socket types (one SOCK_STREAM address and another SOCK_DGRAM address, ...

What is Ai_flags?

ai_flags. Type: int. Flags that indicate options used in the getaddrinfo function. Supported values for the ai_flags member are defined in the Ws2def. h header file on the Windows SDK for Windows 7 and later.


2 Answers

The specification doesn't say that result isn't assigned if it fails, so it appears that a conforming implementation could do so.

Why not free it unconditionally?

result = 0;
s = getaddrinfo(hostname, port, &hints, &result);
if (s) {
    // log error
} else {
    // success
}
if (result) {
    freeaddrinfo(result);
}

Ideally you'd be able to call freeaddrinfo(result) without checking whether result is NULL, but although it's implied by the standard that that's OK I wouldn't count on it.

like image 94
ecatmur Avatar answered Sep 19 '22 17:09

ecatmur


While it's true that the standard is a little bit vague about that, the only interpretation that makes sense is to treat the error as an alternative to a result. This is how other libc functions work and this is how getaddrinfo() is used in the examples even in the standard.

See: http://pubs.opengroup.org/onlinepubs/9699919799/functions/freeaddrinfo.html

I don't think there is a need to invent ways to get around that unless you're dealing with a known broken implementation. POSIX functions don't require you to zero the pointers used for output unless specified otherwise.

From the above link:

Upon successful return of getaddrinfo(), the location to which res points shall refer to a linked list of addrinfo structures, each of which shall specify a socket address and information for use in creating a socket with which to use that socket address.

It's pretty clear that the standard is written with an assumption that in other cases, the res variable is not being touched.

like image 37
Pavel Šimerda Avatar answered Sep 19 '22 17:09

Pavel Šimerda