Exemplo n.º 1
0
struct asr_query *
gethostbyname2_async(const char *name, int af, void *asr)
{
	struct asr_ctx	 *ac;
	struct asr_query *as;

	/* the original segfaults */
	if (name == NULL) {
		errno = EINVAL;
		return (NULL);
	}

	ac = _asr_use_resolver(asr);
	if ((as = _asr_async_new(ac, ASR_GETHOSTBYNAME)) == NULL)
		goto abort; /* errno set */
	as->as_run = gethostnamadr_async_run;

	as->as.hostnamadr.family = af;
	if (af == AF_INET)
		as->as.hostnamadr.addrlen = INADDRSZ;
	else if (af == AF_INET6)
		as->as.hostnamadr.addrlen = IN6ADDRSZ;
	as->as.hostnamadr.name = strdup(name);
	if (as->as.hostnamadr.name == NULL)
		goto abort; /* errno set */

	_asr_ctx_unref(ac);
	return (as);

    abort:
	if (as)
		_asr_async_free(as);
	_asr_ctx_unref(ac);
	return (NULL);
}
Exemplo n.º 2
0
struct asr_query *
gethostbyaddr_async(const void *addr, socklen_t len, int af, void *asr)
{
	struct asr_ctx	 *ac;
	struct asr_query *as;

	ac = _asr_use_resolver(asr);
	as = _gethostbyaddr_async_ctx(addr, len, af, ac);
	_asr_ctx_unref(ac);

	return (as);
}
Exemplo n.º 3
0
struct asr_query *
getaddrinfo_async(const char *hostname, const char *servname,
	const struct addrinfo *hints, void *asr)
{
	struct asr_ctx		*ac;
	struct asr_query	*as;

	if (hints == NULL || (hints->ai_flags & AI_NUMERICHOST) == 0)
		ac = _asr_use_resolver(asr);
	else
		ac = _asr_no_resolver();
	if ((as = _asr_async_new(ac, ASR_GETADDRINFO)) == NULL)
		goto abort; /* errno set */
	as->as_run = getaddrinfo_async_run;

	if (hostname) {
		if ((as->as.ai.hostname = strdup(hostname)) == NULL)
			goto abort; /* errno set */
	}
	if (servname && (as->as.ai.servname = strdup(servname)) == NULL)
		goto abort; /* errno set */
	if (hints)
		memmove(&as->as.ai.hints, hints, sizeof *hints);
	else {
		memset(&as->as.ai.hints, 0, sizeof as->as.ai.hints);
		as->as.ai.hints.ai_family = PF_UNSPEC;
		as->as.ai.hints.ai_flags = AI_ADDRCONFIG;
	}

	_asr_ctx_unref(ac);
	return (as);
    abort:
	if (as)
		_asr_async_free(as);
	_asr_ctx_unref(ac);
	return (NULL);
}
static int res_search_async_run(struct asr_query *, struct asr_result *);
static size_t domcat(const char *, const char *, char *, size_t);

/*
 * Unlike res_query_async(), this function returns a valid packet only if
 * h_errno is NETDB_SUCCESS.
 */
struct asr_query *
res_search_async(const char *name, int class, int type, void *asr)
{
	struct asr_ctx	 *ac;
	struct asr_query *as;

	DPRINT("asr: res_search_async(\"%s\", %i, %i)\n", name, class, type);

	ac = _asr_use_resolver(asr);
	as = _res_search_async_ctx(name, class, type, ac);
	_asr_ctx_unref(ac);

	return (as);
}
DEF_WEAK(res_search_async);

struct asr_query *
_res_search_async_ctx(const char *name, int class, int type, struct asr_ctx *ac)
{
	struct asr_query	*as;

	DPRINT("asr: res_search_async_ctx(\"%s\", %i, %i)\n", name, class,
	    type);
Exemplo n.º 5
0
int
res_init(void)
{
	static void *resinit_mutex;
	struct asr_ctx	*ac;
	int i;

	ac = _asr_use_resolver(NULL);

	/*
	 * The first thread to call res_init() will setup the global _res
	 * structure from the async context, not overriding fields set early
	 * by the user.
	 */
	_MUTEX_LOCK(&resinit_mutex);
	if (!(_res.options & RES_INIT)) {
		if (_res.retry == 0)
			_res.retry = ac->ac_nsretries;
		if (_res.options == 0)
			_res.options = ac->ac_options;
		if (_res.lookups[0] == '\0')
			strlcpy(_res.lookups, ac->ac_db, sizeof(_res.lookups));

		for (i = 0; i < ac->ac_nscount && i < MAXNS; i++) {
			/*
			 * No need to check for length since we copy to a
			 * struct sockaddr_storage with a size of 256 bytes
			 * and sa_len has only 8 bits.
			 */
			memcpy(&_res_ext.nsaddr_list[i], ac->ac_ns[i],
			    ac->ac_ns[i]->sa_len);
			if (ac->ac_ns[i]->sa_len <= sizeof(_res.nsaddr_list[i]))
				memcpy(&_res.nsaddr_list[i], ac->ac_ns[i],
				    ac->ac_ns[i]->sa_len);
			else
				memset(&_res.nsaddr_list[i], 0,
				    sizeof(_res.nsaddr_list[i]));
		}
		_res.nscount = i;
		_res.options |= RES_INIT;
	}
	_MUTEX_UNLOCK(&resinit_mutex);

	/*
	 * If the program is not threaded, we want to reflect (some) changes
	 * made by the user to the global _res structure.
	 * This is a bit of a hack: if there is already an async query on
	 * this context, it might change things in its back.  It is ok
	 * as long as the user only uses the blocking resolver API.
	 * If needed we could consider cloning the context if there is
	 * a running query.
	 */
	if (!__isthreaded) {
		ac->ac_nsretries = _res.retry;
		ac->ac_options = _res.options;
		strlcpy(ac->ac_db, _res.lookups, sizeof(ac->ac_db));
		ac->ac_dbcount = strlen(ac->ac_db);
	}

	_asr_ctx_unref(ac);

	return (0);
}