(root)/
glibc-2.38/
resolv/
resolv_context.h
       1  /* Temporary, thread-local resolver state.
       2     Copyright (C) 2017-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  /* struct resolv_context objects are allocated on the heap,
      20     initialized by __resolv_context_get (and its variants), and
      21     destroyed by __resolv_context_put.
      22  
      23     A nested call to __resolv_context_get (after another call to
      24     __resolv_context_get without a matching __resolv_context_put call,
      25     on the same thread) returns the original pointer, instead of
      26     allocating a new context.  This prevents unexpected reloading of
      27     the resolver configuration.  Care is taken to keep the context in
      28     sync with the thread-local _res object.  (This does not happen with
      29     __resolv_context_get_override.)
      30  
      31     In contrast to struct __res_state, struct resolv_context is not
      32     affected by ABI compatibility concerns.
      33  
      34     For the benefit of the res_n* functions, a struct __res_state
      35     pointer is included in the context object, and a separate
      36     initialization function is provided.  */
      37  
      38  #ifndef _RESOLV_CONTEXT_H
      39  #define _RESOLV_CONTEXT_H
      40  
      41  #include <bits/types/res_state.h>
      42  #include <resolv/resolv_conf.h>
      43  #include <stdbool.h>
      44  #include <stddef.h>
      45  
      46  /* Temporary resolver state.  */
      47  struct resolv_context
      48  {
      49    struct __res_state *resp;     /* Backing resolver state.   */
      50  
      51    /* Extended resolver state.  This is set to NULL if the
      52       __resolv_context_get functions are unable to locate an associated
      53       extended state.  In this case, the configuration data in *resp
      54       has to be used; otherwise, the data from *conf should be
      55       preferred (because it is a superset).  */
      56    struct resolv_conf *conf;
      57  
      58    /* The following fields are for internal use within the
      59       resolv_context module.  */
      60    size_t __refcount;            /* Count of reusages by the get functions.  */
      61    bool __from_res;              /* True if created from _res.  */
      62  
      63    /* Single-linked list of resolver contexts.  Used for memory
      64       deallocation on thread cancellation.  */
      65    struct resolv_context *__next;
      66  };
      67  
      68  /* Return the current temporary resolver context, or NULL if there was
      69     an error (indicated by errno).  A call to this function must be
      70     paired with a call to __resolv_context_put.  */
      71  struct resolv_context *__resolv_context_get (void)
      72    __attribute__ ((warn_unused_result));
      73  libc_hidden_proto (__resolv_context_get)
      74  
      75  /* Deallocate the temporary resolver context.  Converse of
      76     __resolv_context_get.  Do nothing if CTX is NULL.  */
      77  void __resolv_context_put (struct resolv_context *ctx);
      78  libc_hidden_proto (__resolv_context_put)
      79  
      80  /* Like __resolv_context_get, but the _res structure can be partially
      81     initialized and those changes will not be overwritten.  */
      82  struct resolv_context *__resolv_context_get_preinit (void)
      83    __attribute__ ((warn_unused_result));
      84  libc_hidden_proto (__resolv_context_get_preinit)
      85  
      86  /* Wrap a struct __res_state object in a struct resolv_context object.
      87     A call to this function must be paired with a call to
      88     __resolv_context_put.  */
      89  struct resolv_context *__resolv_context_get_override (struct __res_state *)
      90    __attribute__ ((nonnull (1), warn_unused_result));
      91  libc_hidden_proto (__resolv_context_get_override)
      92  
      93  /* Return the search path entry at INDEX, or NULL if there are fewer
      94     than INDEX entries.  */
      95  static __attribute__ ((nonnull (1), unused)) const char *
      96  __resolv_context_search_list (const struct resolv_context *ctx, size_t index)
      97  {
      98    if (ctx->conf != NULL)
      99      {
     100        if (index < ctx->conf->search_list_size)
     101          return ctx->conf->search_list[index];
     102        else
     103          return NULL;
     104      }
     105    /* Fallback.  ctx->resp->dnsrch is a NULL-terminated array.  */
     106    for (size_t i = 0; ctx->resp->dnsrch[i] != NULL && i < MAXDNSRCH; ++i)
     107      if (i == index)
     108        return ctx->resp->dnsrch[i];
     109    return NULL;
     110  }
     111  
     112  /* Return the number of name servers.  */
     113  static __attribute__ ((nonnull (1), unused)) size_t
     114  __resolv_context_nameserver_count (const struct resolv_context *ctx)
     115  {
     116    if (ctx->conf != NULL)
     117      return ctx->conf->nameserver_list_size;
     118    else
     119      return ctx->resp->nscount;
     120  }
     121  
     122  /* Return a pointer to the socket address of the name server INDEX, or
     123     NULL if the index is out of bounds.  */
     124  static __attribute__ ((nonnull (1), unused)) const struct sockaddr *
     125  __resolv_context_nameserver (const struct resolv_context *ctx, size_t index)
     126  {
     127    if (ctx->conf != NULL)
     128      {
     129        if (index < ctx->conf->nameserver_list_size)
     130          return ctx->conf->nameserver_list[index];
     131      }
     132    else
     133      if (index < ctx->resp->nscount)
     134        {
     135          if (ctx->resp->nsaddr_list[index].sin_family != 0)
     136            return (const struct sockaddr *) &ctx->resp->nsaddr_list[index];
     137          else
     138            return (const struct sockaddr *) &ctx->resp->_u._ext.nsaddrs[index];
     139        }
     140    return NULL;
     141  }
     142  
     143  /* Return the number of sort list entries.  */
     144  static __attribute__ ((nonnull (1), unused)) size_t
     145  __resolv_context_sort_count (const struct resolv_context *ctx)
     146  {
     147    if (ctx->conf != NULL)
     148      return ctx->conf->sort_list_size;
     149    else
     150      return ctx->resp->nsort;
     151  }
     152  
     153  /* Return the sort list entry at INDEX.  */
     154  static __attribute__ ((nonnull (1), unused)) struct resolv_sortlist_entry
     155  __resolv_context_sort_entry (const struct resolv_context *ctx, size_t index)
     156  {
     157    if (ctx->conf != NULL)
     158      {
     159        if (index < ctx->conf->sort_list_size)
     160          return ctx->conf->sort_list[index];
     161        /* Fall through.  */
     162      }
     163    else if (index < ctx->resp->nsort)
     164      return (struct resolv_sortlist_entry)
     165        {
     166          .addr = ctx->resp->sort_list[index].addr,
     167          .mask = ctx->resp->sort_list[index].mask,
     168        };
     169  
     170    return (struct resolv_sortlist_entry) { .mask = 0, };
     171  }
     172  
     173  /* Called during thread shutdown to free the associated resolver
     174     context (mostly in response to cancellation, otherwise the
     175     __resolv_context_get/__resolv_context_put pairing will already have
     176     deallocated the context object).  */
     177  void __resolv_context_freeres (void) attribute_hidden;
     178  
     179  #endif /* _RESOLV_CONTEXT_H */