How to deal with getaddrinfo and thread safety?

I am using getaddrinfo for an IPv6-related C project. "Man getaddrinfo" on my computer (uname -a: 3.5.0-23) only indicates that it is "reentrant." Therefore, I think it is not thread safe.

In scenarios where thread safety is required, how to handle it? I also checked UNP, but didn't seem to find a specific answer. Many thanks.

+5
source share
4 answers

getaddrinfo() really thread safe. This is required by RFC 3493 Section 6.1 :

The functions getaddrinfo () and freeaddrinfo () must be thread safe.

On some platforms, gethostbyname() is thread safe, while on others it is not. That gethostbyname() not on all platforms is repetitive. If you call gethostbyname() and then call gethostbyname() again in the same stream, the data of the first call is overwritten by the data of the second call. This is because gethostbyname() usually uses a static buffer inside, so you need to copy the data before calling gethostbyname() again. getaddrinfo() does not suffer from this problem, because every time it is called, it allocates a new addrinfo structure.

+11
source

Well, getaddrinfo is not completely safe for streams on some platforms, for example, on Linux: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚Interface β”‚ Attribute β”‚ Value β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚getaddrinfo() β”‚ Thread safety β”‚ MT-Safe env locale β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚freeaddrinfo(), β”‚ Thread safety β”‚ MT-Safe β”‚ β”‚gai_strerror() β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 

Pay attention to env and regional settings:

 Other safety remarks Additional keywords may be attached to functions, indicating features that do not make a function unsafe to call, but that may need to be taken into account in certain classes of programs: locale Functions annotated with locale as an MT-Safety issue read from the locale object without any form of synchronization. Functions annotated with locale called concurrently with locale changes may behave in ways that do not correspond to any of the locales active during their execution, but an unpredictable mix thereof. We do not mark these functions as MT-Unsafe, however, because functions that modify the locale object are marked with const:locale and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the locale can be considered effectively constant in these contexts, which makes the former safe. env Functions marked with env as an MT-Safety issue access the environment with getenv(3) or similar, without any guards to ensure safety in the presence of concurrent modifications. We do not mark these functions as MT-Unsafe, however, because functions that modify the environment are all marked with const:env and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the environment can be considered effectively constant in these contexts, which makes the former safe. 

This way you will get random errors if you do not take this into account. See the discussion of the old glibc error for details: https://sourceware.org/bugzilla/show_bug.cgi?id=13271.

+1
source

getaddrinfo() is part of the POSIX standard, and the POSIX standard requires:

The functions freeaddrinfo () and getaddrinfo () must be thread-oriented.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html

The OS may not claim POSIX compliance if it is not.

Operating systems officially comply with POSIX, which you may have heard about:
AIX, BSD, IRIX, macOS, (Open) Solaris, QNX, as well as several others.
On these platforms, you can rely on getaddrinfo() be thread-oriented.

Well-known operating systems that do not officially comply with POSIX, but always try to get as close as possible to the POSIX standard to ensure software compatibility:
BeOS, FreeBSD, GNU, iOS, Linux, NetBSD, OpenBSD, as well as several others.
On these platforms, you cannot rely on getaddrinfo() completely thread safe, but you can of course expect it to be thread safe enough that you can use it from multiple threads in your application without having to wrap it around it.

Please note that getaddrinfo() also thread-oriented on Linux, as it will become thread-safe only if your code ever changes the locale or environment while several threads work and do it, considering thread-safe unsafe in itself. Thus, you can make getaddrinfo() thread-safe only if you do something that is forbidden in any case (well, actually it is not forbidden, but you do it at your own peril and risk, so how unsafe it is).

Also note that even if this is not said on the man page (some POSIX man pages say nothing about thread safety), the POSIX standard actually requires:

3.407 thread safe

A thread-safe function can safely be called simultaneously with other calls to the same function or with calls to any other thread-safe functions by multiple threads. Each function defined in the POSIX.1-2017 system interface volume is thread-oriented, unless otherwise specified. Examples are any β€œclean” function, a function that keeps the mutex locked while accessing static storage, or objects shared by threads.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html

0
source

getaddrinfo () is thread safe. All (or almost all) of the function manual pages contain thread safety information. Reentrant means thread safety.

0
source

Source: https://habr.com/ru/post/1500409/


All Articles