Esempio 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);
}
Esempio n. 2
0
/*
 * Resume the "as" async query resolution.  Return one of ASYNC_COND,
 * or ASYNC_DONE and put query-specific return values in the user-allocated
 * memory at "ar".
 */
int
asr_run(struct asr_query *as, struct asr_result *ar)
{
	int	r, saved_errno = errno;

	DPRINT("asr: asr_run(%p, %p) %s ctx=[%p]\n", as, ar,
	    _asr_querystr(as->as_type), as->as_ctx);
	r = as->as_run(as, ar);

	DPRINT("asr: asr_run(%p, %p) -> %s", as, ar, _asr_transitionstr(r));
#ifdef DEBUG
	if (r == ASYNC_COND)
#endif
		DPRINT(" fd=%i timeout=%i", ar->ar_fd, ar->ar_timeout);
	DPRINT("\n");
	if (r == ASYNC_DONE)
		_asr_async_free(as);

	errno = saved_errno;

	return (r);
}
Esempio n. 3
0
struct asr_query *
_gethostbyaddr_async_ctx(const void *addr, socklen_t len, int af,
    struct asr_ctx *ac)
{
	struct asr_query *as;

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

	as->as.hostnamadr.family = af;
	as->as.hostnamadr.addrlen = len;
	if (len > 0)
		memmove(as->as.hostnamadr.addr, addr, (len > 16) ? 16 : len);

	return (as);

    abort:
	if (as)
		_asr_async_free(as);
	return (NULL);
}
Esempio n. 4
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);
}
Esempio n. 5
0
/*
 * Free an async query and unref the associated context.
 */
void
_asr_async_free(struct asr_query *as)
{
	DPRINT("asr: asr_async_free(%p)\n", as);
	switch (as->as_type) {
	case ASR_SEND:
		if (as->as_fd != -1)
			close(as->as_fd);
		if (as->as.dns.obuf && !(as->as.dns.flags & ASYNC_EXTOBUF))
			free(as->as.dns.obuf);
		if (as->as.dns.ibuf)
			free(as->as.dns.ibuf);
		if (as->as.dns.dname)
			free(as->as.dns.dname);
		break;

	case ASR_SEARCH:
		if (as->as.search.subq)
			_asr_async_free(as->as.search.subq);
		if (as->as.search.name)
			free(as->as.search.name);
		break;

	case ASR_GETRRSETBYNAME:
		if (as->as.rrset.subq)
			_asr_async_free(as->as.rrset.subq);
		if (as->as.rrset.name)
			free(as->as.rrset.name);
		break;

	case ASR_GETHOSTBYNAME:
	case ASR_GETHOSTBYADDR:
		if (as->as.hostnamadr.subq)
			_asr_async_free(as->as.hostnamadr.subq);
		if (as->as.hostnamadr.name)
			free(as->as.hostnamadr.name);
		break;

	case ASR_GETNETBYNAME:
	case ASR_GETNETBYADDR:
		if (as->as.netnamadr.subq)
			_asr_async_free(as->as.netnamadr.subq);
		if (as->as.netnamadr.name)
			free(as->as.netnamadr.name);
		break;

	case ASR_GETADDRINFO:
		if (as->as.ai.subq)
			_asr_async_free(as->as.ai.subq);
		if (as->as.ai.aifirst)
			freeaddrinfo(as->as.ai.aifirst);
		if (as->as.ai.hostname)
			free(as->as.ai.hostname);
		if (as->as.ai.servname)
			free(as->as.ai.servname);
		if (as->as.ai.fqdn)
			free(as->as.ai.fqdn);
		break;

	case ASR_GETNAMEINFO:
		if (as->as.ni.subq)
			_asr_async_free(as->as.ni.subq);
		break;
	}

	_asr_ctx_unref(as->as_ctx);
	free(as);
}
Esempio n. 6
0
/*
 * Cancel an async query.
 */
void
asr_abort(struct asr_query *as)
{
	_asr_async_free(as);
}