The query cannot be processed further until a specific condition on a
file descriptor becomes true.
The following members of the
structure are filled:
|ar_cond||one of ASR_WANT_READ or ASR_WANT_WRITE,|
|ar_fd||the file descriptor waiting for an IO operation,|
|ar_timeout||the amount of time to wait for in milliseconds.|
The caller is expected to call asr_run again once the condition holds or the timeout expires.
|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.|
Note that although the query itself may fail (the error being properly reported in the ar structure), the asr_run function itself cannot fail and it always preserves errno.
The asr_run_sync function is a wrapper around asr_run that handles the read/write conditions, thus falling back to a blocking interface. It only returns 1. It also preserves errno.
The asr_abort function clears a running query. It can be called when the query is waiting on a file descriptor. Note that a completed query is already cleared when asr_run returns, so asr_abort must not be called in this case.
The remaining functions are used to initiate different kinds of query on the asr resolver context. The specific operational details for each of them are described below. All functions return a handle to an internal query, or NULL if they could not allocate the necessary resources to initiate the query. All other errors (especially invalid parameters) are reported when calling asr_run. They usually have the same interface as an existing resolver function, with an additional asr argument, which specifies the context to use for this request. For now, the argument must always be NULL, which will use the default context for the current thread.
The res_send_async, res_query_async and res_search_async functions are asynchronous versions of the standard libc resolver routines. Their interface is very similar, except that the response buffer is always allocated internally. The return value is found upon completion in the ar_datalen member of the response structure. In addition, the ar_ns structure contains the address of the DNS server that sent the response, ar_rcode contains the code returned by the server in the DNS response packet, and ar_count contains the number of answers in the packet. If a response is received it is placed in a newly allocated buffer and returned as ar_data member. This buffer must be freed by the caller. On error, the ar_errno and ar_h_errno members are set accordingly.
The getrrsetbyname_async function is an asynchronous version of getrrsetbyname(3). Upon completion, the return code is found in ar_rrset_errno and the address to the newly allocated result set is set in ar_rrsetinfo. As for the blocking function, it must be freed by calling freerrset(3).
The gethostbyname_async, gethostbyname2_async and gethostbyaddr_async functions provide an asynchronous version of the network host entry functions. Upon completion, ar_h_errno is set and the resulting hostent address, if found, is set in the ar_hostent field. Note that unlike their blocking counterparts, these functions always return a pointer to newly allocated memory, which must be released by the caller using free(3).
Similarly, the getnetbyname_async and getnetbyaddr_async functions provide an asynchronous version of the network entry functions. Upon completion, ar_h_errno is set and the resulting netent address, if found, is set in the ar_netent field. The memory there is also allocated for the request, and it must be freed by free(3).
The getaddrinfo_async function is an asynchronous version of the getaddrinfo(3) call. It provides a chain of addrinfo structures with all valid combinations of socket address for the given hostname, servname and hints. Those three parameters have the same meaning as for the blocking counterpart. Upon completion the return code is set in ar_gai_errno. The ar_errno member may also be set. On success, the ar_addrinfo member points to a newly allocated list of addrinfo. This list must be freed with freeaddrinfo(3).
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.
getaddrinfo(3), gethostbyname(3), getnameinfo(3), getnetbyname(3), getrrsetbyname(3), res_send(3), resolv.conf(5)
This DNS resolver implementation doesnt support the EDNS0 protocol extension yet.