From Fedora Project Wiki
Line 1: Line 1:
The standard C library provides a number of functions related to host and service name resolution and DNS information retrieval. The former are mainly intended to support applications when connecting to services while the latter gives them access to additional DNS  
+
The standard C library provides a number of functions related to host and service name resolution and DNS information retrieval. The former are mainly intended to support applications when connecting to services while the latter gives them access to additional DNS information.
  
 
== Name resolution for libraries ==
 
== Name resolution for libraries ==
Line 20: Line 20:
 
For example, [http://sourceware.org/git/?p=netresolve.git;a=blob;f=README;hb=HEAD netresolve] provides a context object and allows for all sorts of name resolution backends including DNS.
 
For example, [http://sourceware.org/git/?p=netresolve.git;a=blob;f=README;hb=HEAD netresolve] provides a context object and allows for all sorts of name resolution backends including DNS.
  
Example: Classic <code>getaddrinfo()</code> implemented using <code>netresolve_query_getaddrinfo()</code> using a brand new object for the query. This is not necessarily very practical but it shows the concept.
+
Examples:
  
<pre>
+
* [https://sourceware.org/git/?p=netresolve.git;a=blob;f=tests/test-sync.c;h=6befcb5ef3395edb6f5ffc5f4c875a0ddbd9a7f1;hb=HEAD Test program to check a blocking call to <code>netresolve_query()</code>.]
int
+
* [https://sourceware.org/git/?p=netresolve.git;a=blob;f=compat/libc.c;h=83410a5c8fc6c6f488819a941dcfd4d6b971127c;hb=HEAD#l39 Classic <code>getaddrinfo()</code> implemented using <code>netresolve_query_getaddrinfo()</code> using a brand new object for the query.]
getaddrinfo(const char *nodename, const char *servname,
 
        const struct addrinfo *hints, struct addrinfo **res)
 
{
 
    netresolve_t channel;
 
    netresolve_query_t query;
 
    int status = EAI_SYSTEM;
 
  
    if (!(channel = netresolve_open()))
+
=== Notes ===
        return status;
+
 
 +
A global context could still be available and the classic <code>getaddrinfo()</code> function could call the new function with the global context.
 +
 
 +
The application and the libraries can be single-threaded as well as multi-threaded. Any solutions using thread local storage are therefore not generally suitable.
 +
 
 +
== File descriptor based non-blocking API ==
 +
 
 +
=== Problem statement ===
 +
 
 +
The libc socket API allows for both blocking and non-blocking usage, thus being useful in all sorts of single threaded and multi-threaded applications and libraries. This doesn't apply to the libc name resolution API which
 +
is strictly blocking from top to bottom. Unfortunately this also applies to the nsswitch backend API.
 +
 
 +
=== Solutions ===
 +
 
 +
Add a new non-blocking API for applications and a new non-blocking API for nsswitch backends.
  
    if ((query = netresolve_query_getaddrinfo(channel, nodename, servname, hints)))
+
=== Open questions ===
        status = netresolve_query_getaddrinfo_done(query, res);
 
  
    netresolve_close(channel);
+
What to do with nsswitch backends that don't support the new API, yet?
    return status;
 
}
 
</pre>
 
  
Note: While the getaddrinfo functionality is split into two functions, this code doesn't use the non-blocking functionality and thus can just call the two functions in row.
+
=== Existing solutions ===
  
=== Notes ===
+
For example, [http://sourceware.org/git/?p=netresolve.git;a=blob;f=README;hb=HEAD netresolve] provides a file descriptor based non-blocking API.
 +
 
 +
Examples:
  
A global context could still be available and the classic <code>getaddrinfo()</code> function could call the new function with the global context.
+
* [https://sourceware.org/git/?p=netresolve.git;a=blob;f=tests/test-async.c;hb=HEAD Test program to check a non-blocking call to <code>netresolve_query()</code>]

Revision as of 09:43, 15 July 2014

The standard C library provides a number of functions related to host and service name resolution and DNS information retrieval. The former are mainly intended to support applications when connecting to services while the latter gives them access to additional DNS information.

Name resolution for libraries

Problem statement

Current versions of glibc offer the getaddrinfo() function, res_*() functions and _res.options. The former two are used for host and service name resolution and for DNS record retrieval, respectively. While this works well for applications, libraries may need to tweak the configuration without affecting the application. Basically, the configuration needs to be specific to the caller and the caller needs to be able to provide the configuration when performing host/service name resolution and DNS record retrieval.

Example use case

A cryptographic library may want to configure the resolver so that it only receives records secured by DNSSEC. The same library may also want to perform ordinary name resolution where records not secured by DNSSEC are returned as well. None of the configuration should ever affect the running application, therefore three different configuration contexts are needed.

Possible solution

For each libc library function that uses the shared context, provide a new function that would accept an opaque pointer to a specific context object. We also need to provide a set of functions to create and configure the context object.

Existing solutions

For example, netresolve provides a context object and allows for all sorts of name resolution backends including DNS.

Examples:

Notes

A global context could still be available and the classic getaddrinfo() function could call the new function with the global context.

The application and the libraries can be single-threaded as well as multi-threaded. Any solutions using thread local storage are therefore not generally suitable.

File descriptor based non-blocking API

Problem statement

The libc socket API allows for both blocking and non-blocking usage, thus being useful in all sorts of single threaded and multi-threaded applications and libraries. This doesn't apply to the libc name resolution API which is strictly blocking from top to bottom. Unfortunately this also applies to the nsswitch backend API.

Solutions

Add a new non-blocking API for applications and a new non-blocking API for nsswitch backends.

Open questions

What to do with nsswitch backends that don't support the new API, yet?

Existing solutions

For example, netresolve provides a file descriptor based non-blocking API.

Examples: