An alternative interface is defined by <sofia-resolv/sres.h>, <sofia-resolv/sres_record.h>, <sofia-resolv/sres_async.h>, and <sofia-resolv/sres_cache.h>.
The application can either explicitly poll(2) or select(2) on file descriptors used by resolver and call the driver functions, or it can use su root a pointer to a su_root_t object. Third option is to use resolver synchronously with sres_blocking_query().
There is an internal cache used by sresolv. The query functions add records to the cache: using the cache is made similar as if receiving entries directly from DNS server.
Please note that you have to create a separate resolver object for each thread using Sofia resolver. The resolver objects can share the cache, however.
#include <sofia-sip/sresolv.h> sres_resolver_t *sres_resolver_create(su_root_t *root, char const *resolv_conf, tag_type_t, tag_value_t, ...); int sres_resolver_destroy(sres_resolver_t *res);
sres_query_t *sres_query(sres_resolver_t *res, sres_answer_f *callback, sres_context_t *context, int socket, uint16_t type, char const *domain); sres_query_t *sres_query_sockaddr(sres_resolver_t *res, sres_answer_f *callback, sres_context_t *context, int socket, uint16_t type, struct sockaddr const *addr); void sres_query_bind(sres_query_t *q, sres_answer_f *callback, sres_context_t *context);
sres_record_t **sres_cached_answers(sres_resolver_t *res, uint16_t type, char const *domain); sres_record_t **sres_cached_answers_sockaddr(sres_resolver_t *res, uint16_t type, struct sockaddr const *addr); int sres_sort_answers(sres_resolver_t *res, sres_record_t **answers); int sres_filter_answers(sres_resolver_t *sres, sres_record_t **answers, uint16_t type); void sres_free_answers(sres_resolver_t *res, sres_record_t **answers); void sres_free_answer(sres_resolver_t *res, sres_record_t *answer);
#define SRES_CONTEXT_T struct context #include <sofia-sip/sresolv.h> ... struct context { ... su_root_t *root; sres_resolver_t *sres; sres_query_t *query; ... } *context; ... context->sres = sres_resolver_create(context->root, NULL, TAG_END()); ... sres_record_t *results; results = sres_cached_answers(context->sres, sres_type_naptr, domain); if (results) { process_natpr(context, NULL, results); } else { context->query = sres_query(context->sres, process_natpr, context, sres_type_naptr, domain); if (!context->query) process_naptr(context, NULL, NULL); } } ... void process_natpr(sres_context_t *context, sres_query_t *q, sres_record_t *answers[]) { sres_sort_answers(context->sres, answers); ... sres_free_answers(context->sres, answers); }
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sofia-resolv/sres.h> sres_resolver_t *sres_resolver_new(char const *resolv_conf_path); sres_resolver_t *sres_resolver_new_with_cache(char const *conf_file_path, sres_cache_t *cache, char const *options, ...); sres_resolver_t *sres_resolver_ref(sres_resolver_t *res); void sres_resolver_unref(sres_resolver_t *res); sres_resolver_t *sres_resolver_copy(sres_resolver_t *); void *sres_resolver_set_userdata(sres_resolver_t *res, void *userdata); void *sres_resolver_get_userdata(sres_resolver_t const *res);
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sofia-resolv/sres.h> int sres_blocking_query(sres_resolver_t *res, uint16_t type, char const *domain, sres_record_t ***return_records); int sres_blocking_query_sockaddr(sres_resolver_t *res, uint16_t type, struct sockaddr const *addr, sres_record_t ***return_records);
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sofia-resolv/sres_async.h> sres_async_t *sres_resolver_set_async(sres_resolver_t *res, sres_update_f *update, sres_async_t *async, int update_all); sres_async_t *sres_resolver_get_async(sres_resolver_t const *res, sres_update_f *update); int sres_resolver_sockets(sres_resolver_t const *res, int *sockets, int n); void sres_resolver_timer(sres_resolver_t *, int socket); int sres_resolver_receive(sres_resolver_t *res, int socket); int sres_resolver_error(sres_resolver_t *res, int socket);