# HG changeset patch # User Tero Marttila # Date 1241651526 -10800 # Node ID 1a7afcd2dd1a64222ca7d2a530e6617a4b069227 # Parent ea4972e51fa3eef86017e15f9c40af088bf2abe2 implement a separate resolver module diff -r ea4972e51fa3 -r 1a7afcd2dd1a src/resolve.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/resolve.c Thu May 07 02:12:06 2009 +0300 @@ -0,0 +1,89 @@ +#include "resolve.h" + +#include +#include +#include +#include + +err_t resolve_addr (struct resolve_result *res, const char *node, const char *service, int socktype, int ai_flags, error_t *err) +{ + struct addrinfo hints, *ai; + int ret; + + // build hints + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = ai_flags; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = socktype; + + // resolve (blocking) + if ((ret = getaddrinfo(node, service, &hints, &ai))) + RETURN_SET_ERROR_EXTRA(err, ERR_GETADDRINFO, ret); + + // no results? + if (!ai) + RETURN_SET_ERROR(err, ERR_GETADDRINFO_EMPTY); + + // store + res->list = res->item = ai; + + // ok + return SUCCESS; +} + +void resolve_result_init (struct resolve_result *res) +{ + res->list = res->item = NULL; +} + +struct addrinfo* resolve_result_next (struct resolve_result *res) +{ + if (!res->item) { + // no items left + return NULL; + + } else { + // ...remember the current item + struct addrinfo *ai = res->item; + + if (res->item) + // advance item to the next one + res->item = res->item->ai_next; + + // return the current one + return ai; + } +} + +void resolve_result_deinit (struct resolve_result *res) +{ + if (res->list) + // free them all + freeaddrinfo(res->list); + + // invalidate + res->list = res->item = NULL; +} + +const char * resolve_addr_text (const struct addrinfo *addr) +{ + static char text[1024]; + char host[NI_MAXHOST], service[NI_MAXSERV]; + int ret; + + // lookup the reverse nameinfo + if ((ret = getnameinfo( + addr->ai_addr, addr->ai_addrlen, + host, sizeof(host), service, sizeof(service), + AI_NUMERICHOST | AI_NUMERICSERV + ))) { + strcpy(host, "???"); + strcpy(service, "???"); + } + + // format message + snprintf(text, sizeof(text), "[%s]:%s", host, service); + + // return static pointer + return text; +} diff -r ea4972e51fa3 -r 1a7afcd2dd1a src/resolve.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/resolve.h Thu May 07 02:12:06 2009 +0300 @@ -0,0 +1,59 @@ +#ifndef RESOLVE_H +#define RESOLVE_H + +/** + * @file + * + * DNS resolver interface + */ +#include "error.h" +#include + +/** + * Lookup result state + */ +struct resolve_result { + /** Head of the addrinfo list */ + struct addrinfo *list; + + /** Current addrinfo item */ + struct addrinfo *item; +}; + +/** + * Resolve the given node/service tuple as a series of addrinfos for the given socktype. + * + * This will never return an empty result. + * + * XXX: blocking DNS stuff + * + * @param res where to store the result state + * @param node hostname/address to look up + * @param service service/port to look up + * @param socktype a SOCK_* value to return addrinfo's for that socktype + * @param ai_flags optional bitmask of AI_* flags to use + * @param err returned error info + */ +err_t resolve_addr (struct resolve_result *res, const char *node, const char *service, int socktype, int ai_flags, error_t *err); + +/** + * Initialize the given result to zero + */ +void resolve_result_init (struct resolve_result *res); + +/** + * Get the next address from a result, if any left + */ +struct addrinfo* resolve_result_next (struct resolve_result *res); + +/** + * Release the addrinfo resources associated with the given result + */ +void resolve_result_deinit (struct resolve_result *res); + +/** + * Returns a pointer to a static buffer containing a string description of the given addrinfo + */ +const char * resolve_addr_text (const struct addrinfo *addr); + +#endif /* RESOLVE_H */