Skip to content
  • Philip Withnall's avatar
    gio: Port GThreadedResolver to use res_nquery() to fix thread-safety · 40be86bb
    Philip Withnall authored
    res_query() uses global state in the form of the struct __res_state
    which contains the contents of resolv.conf (and other things). On Linux,
    this state seems to be thread-local, so there is no problem. On OS X,
    however, it is not, and hence multiple res_query() calls from parallel
    threads will compete and return bogus results.
    
    The fix for this is to use res_nquery(), introduced in BIND 8.2, which
    takes an explicit state argument. This allows us to manually store the
    state thread-locally. If res_nquery() isn’t available, we fall back to
    res_query(). It should be available on OS X though. As a data point,
    it’s available on Fedora 27.
    
    There’s a slight complication in the fact that OS X requires the state
    to be freed using res_ndestroy() rather than res_nclose(). Linux uses
    res_nclose().
    
    (See, for example, the NetBSD man page:
    https://www.unix.com/man-page/netbsd/3/res_ninit/. The Linux one is
    incomplete and not so useful:
    http://ma...
    40be86bb