Other Alias
asr_run, asr_run_sync, asr_abort, res_send_async, res_query_async, res_search_async, getrrsetbyname_async, gethostbyname_async, gethostbyname2_async, getnetbyname_async, getnetbyaddr_async, getaddrinfo_async, getnameinfo_asyncSYNOPSIS
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <asr.h>int
asr_run(struct asr_query *aq, struct asr_result *ar);
int
asr_run_sync(struct asr_query *aq, struct asr_result *ar);
void
asr_abort(struct asr_query *aq);
struct asr_query *
res_send_async(const unsigned char *pkt, int pktlen, void *asr);
struct asr_query *
res_query_async(const char *name, int class, int type, void *asr);
struct asr_query *
res_search_async(const char *name, int class, int type, void *asr);
struct asr_query *
getrrsetbyname_async(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, void *asr);
struct asr_query *
gethostbyname_async(const char *name, void *asr);
struct asr_query *
gethostbyname2_async(const char *name, int af, void *asr);
struct asr_query *
gethostbyaddr_async(const void *addr, socklen_t len, int af, void *asr);
struct asr_query *
getnetbyname_async(const char *name, void *asr);
struct asr_query *
getnetbyaddr_async(in_addr_t net, int type, void *asr);
struct asr_query *
getaddrinfo_async(const char *hostname, const char *servname, const struct addrinfo *hints, void *asr);
struct asr_query *
getnameinfo_async(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags, void *asr);
DESCRIPTION
The asr functions provide a simple interface for asynchronous address resolution and nameserver querying. They should be used in place of the classical resolver functions of libc when blocking is not desirable.The principle of operation is as follows: All async requests are made against an asr context which basically defines a list of sources to query and a strategy to do so. The user creates a query through one of the dedicated functions, and gets a handle representing the internal query. A query is a state-machine that can be run to try to fulfill a particular request. This is done by calling in a generic API that performs the state transitions until it needs to give the control back to the user, either because a result is available, or because the next transition implies a blocking call (a file descriptor needs to be read from or written to). The user is responsible for dealing with the situation: either get the result, or wait until the fd conditions are met, and then call back into the resolving machinery when it is ready to proceed.
The asr_run() function drives the resolving process. It runs the asynchronous query represented by the handle until a result is available, or until it cannot continue without blocking. The results are returned to the user through the parameter, which must be a valid pointer to user allocated memory. is defined as:
-
struct asr_result { /* Fields set if the query is not done yet (asr_run returns 0) */ int ar_cond; /* ASR_WANT_READ or ASR_WANT_WRITE */ int ar_fd; /* the fd waiting for io condition */ int ar_timeout; /* time to wait for in milliseconds */ /* Error fields. Depends on the query type. */ int ar_errno; int ar_h_errno; int ar_gai_errno; int ar_rrset_errno; /* Result for res_*_async() calls */ int ar_count; /* number of answers in the dns reply */ int ar_rcode; /* response code in the dns reply */ void *ar_data; /* raw reply packet (must be freed) */ int ar_datalen; /* reply packet length */ struct sockaddr_storage ar_ns; /* nameserver that responded */ /* Result for other calls. Must be freed properly. */ struct addrinfo *ar_addrinfo; struct rrsetinfo *ar_rrsetinfo; struct hostent *ar_hostent; struct netent *ar_netent; };
- 0
- The query cannot be processed further until a specific condition on a file descriptor becomes true. The following members of the structure are filled:
- one of ASR_WANT_READ or ASR_WANT_WRITE,
- the file descriptor waiting for an IO operation,
- the amount of time to wait for in milliseconds.
- 1
- The query is completed. The members relevant to the actual async query type are set accordingly, including error conditions. In any case, the query is cleared and its handle is invalidated.
WORKING WITH THREADS
This implementation of the asynchronous resolver interface is thread-safe and lock-free internally, but the following restriction applies: Two different threads must not create queries on the same context or run queries originating from the same context at the same time. If they want to do that, all calls must be protected by a mutex around that context.It is generally not a problem since the main point of the asynchronous resolver is to multiplex queries within a single thread of control, so sharing a resolver among threads is not useful.
CAVEATS
This DNS resolver implementation doesn't support the EDNS0 protocol extension yet.