Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with getaddrinfo and thread-safety?

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

In scenarios where thread-safety is required, how to handle it? I also checked UNP but seems no concrete answer provided. Thanks a lot.

like image 311
user180574 Avatar asked Sep 04 '13 00:09

user180574


2 Answers

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

Functions getaddrinfo() and freeaddrinfo() must be thread-safe.

On some platforms, gethostbyname() is thread-safe, but on others it is not. What gethostbyname() is not on all platforms is re-entrant. If you call gethostbyname() and then call gethostbyname() again in the same thread, the data from the first call is overwritten with data from the second call. This is because gethostbyname() usually uses a static buffer internally, that is why you have to copy the data before calling gethostbyname() again. getaddrinfo() does not suffer from that problem, as it allocates a new addrinfo struct every time it is called.

like image 115
Remy Lebeau Avatar answered Sep 29 '22 17:09

Remy Lebeau


Well, getaddrinfo is not quite thread safe on some platforms, Linux for example: 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()  │               │                    │
   └────────────────┴───────────────┴────────────────────┘

Note env and locale attibutes:

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.

So you will get random segfaults if not take it into account. See this old glibc bug discussion for details: https://sourceware.org/bugzilla/show_bug.cgi?id=13271

like image 30
Andrew Selivanov Avatar answered Sep 29 '22 18:09

Andrew Selivanov