struct async * gethostbyaddr_async(const void *addr, socklen_t len, int af, struct asr *asr) { struct asr_ctx *ac; struct async *as; ac = asr_use_resolver(asr); as = gethostbyaddr_async_ctx(addr, len, af, ac); asr_ctx_unref(ac); return (as); }
static int getnameinfo_async_run(struct asr_query *as, struct asr_result *ar) { void *addr; socklen_t addrlen; int r; next: switch (as->as_state) { case ASR_STATE_INIT: /* Make sure the parameters are all valid. */ if (as->as.ni.sa.sa.sa_family != AF_INET && as->as.ni.sa.sa.sa_family != AF_INET6) { ar->ar_gai_errno = EAI_FAMILY; async_set_state(as, ASR_STATE_HALT); break; } if ((as->as.ni.sa.sa.sa_family == AF_INET && (SA_LEN(&as->as.ni.sa.sa) != sizeof (as->as.ni.sa.sain))) || (as->as.ni.sa.sa.sa_family == AF_INET6 && (SA_LEN(&as->as.ni.sa.sa) != sizeof (as->as.ni.sa.sain6)))) { ar->ar_gai_errno = EAI_FAIL; async_set_state(as, ASR_STATE_HALT); break; } /* Set the service name first, if needed. */ if (_servname(as) == -1) { ar->ar_gai_errno = EAI_OVERFLOW; async_set_state(as, ASR_STATE_HALT); break; } if (as->as.ni.hostname == NULL || as->as.ni.hostnamelen == 0) { ar->ar_gai_errno = 0; async_set_state(as, ASR_STATE_HALT); break; } if (as->as.ni.flags & NI_NUMERICHOST) { if (_numerichost(as) == -1) { if (errno == ENOMEM) ar->ar_gai_errno = EAI_MEMORY; else if (errno == ENOSPC) ar->ar_gai_errno = EAI_OVERFLOW; else { ar->ar_errno = errno; ar->ar_gai_errno = EAI_SYSTEM; } } else ar->ar_gai_errno = 0; async_set_state(as, ASR_STATE_HALT); break; } if (as->as.ni.sa.sa.sa_family == AF_INET) { addrlen = sizeof(as->as.ni.sa.sain.sin_addr); addr = &as->as.ni.sa.sain.sin_addr; } else { addrlen = sizeof(as->as.ni.sa.sain6.sin6_addr); addr = &as->as.ni.sa.sain6.sin6_addr; } /* * Create a subquery to lookup the address. */ as->as.ni.subq = gethostbyaddr_async_ctx(addr, addrlen, as->as.ni.sa.sa.sa_family, as->as_ctx); if (as->as.ni.subq == NULL) { ar->ar_gai_errno = EAI_MEMORY; async_set_state(as, ASR_STATE_HALT); break; } async_set_state(as, ASR_STATE_SUBQUERY); break; case ASR_STATE_SUBQUERY: if ((r = asr_run(as->as.ni.subq, ar)) == ASYNC_COND) return (ASYNC_COND); /* * Request done. */ as->as.ni.subq = NULL; if (ar->ar_hostent == NULL) { if (as->as.ni.flags & NI_NAMEREQD) { ar->ar_gai_errno = EAI_NONAME; } else if (_numerichost(as) == -1) { if (errno == ENOMEM) ar->ar_gai_errno = EAI_MEMORY; else if (errno == ENOSPC) ar->ar_gai_errno = EAI_OVERFLOW; else { ar->ar_errno = errno; ar->ar_gai_errno = EAI_SYSTEM; } } else ar->ar_gai_errno = 0; } else { if (strlcpy(as->as.ni.hostname, ar->ar_hostent->h_name, as->as.ni.hostnamelen) >= as->as.ni.hostnamelen) ar->ar_gai_errno = EAI_OVERFLOW; else ar->ar_gai_errno = 0; free(ar->ar_hostent); } async_set_state(as, ASR_STATE_HALT); break; case ASR_STATE_HALT: return (ASYNC_DONE); default: ar->ar_errno = EOPNOTSUPP; ar->ar_gai_errno = EAI_SYSTEM; async_set_state(as, ASR_STATE_HALT); break; } goto next; }