Alien-cares
view release on metacpan or search on metacpan
libcares/ares_getaddrinfo.c view on Meta::CPAN
return ARES_EFILE;
}
}
status = ares__get_addrinfo(fp, hquery->name, hquery->port, &hquery->hints, &hquery->ai);
fclose(fp);
return status;
}
/* Resolve service name into port number given in host byte order.
* If not resolved, return 0.
*/
static unsigned short lookup_service(const char *service, int flags)
{
const char *proto;
struct servent *sep;
#ifdef HAVE_GETSERVBYNAME_R
struct servent se;
char tmpbuf[4096];
#endif
if (service)
{
if (flags & ARES_NI_UDP)
proto = "udp";
else if (flags & ARES_NI_SCTP)
proto = "sctp";
else if (flags & ARES_NI_DCCP)
proto = "dccp";
else
proto = "tcp";
#ifdef HAVE_GETSERVBYNAME_R
memset(&se, 0, sizeof(se));
sep = &se;
memset(tmpbuf, 0, sizeof(tmpbuf));
#if GETSERVBYNAME_R_ARGS == 6
if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf),
&sep) != 0)
sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
#elif GETSERVBYNAME_R_ARGS == 5
sep = getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
#elif GETSERVBYNAME_R_ARGS == 4
if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0)
sep = NULL;
#else
/* Lets just hope the OS uses TLS! */
sep = getservbyname(service, proto);
#endif
#else
/* Lets just hope the OS uses TLS! */
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
sep = getservbyname(service, (char *)proto);
#else
sep = getservbyname(service, proto);
#endif
#endif
return (sep ? ntohs((unsigned short)sep->s_port) : 0);
}
return 0;
}
/* If the name looks like an IP address, fake up a host entry, end the
* query immediately, and return true. Otherwise return false.
*/
static int fake_addrinfo(const char *name,
unsigned short port,
const struct ares_addrinfo *hints,
ares_addrinfo_callback callback,
void *arg)
{
struct ares_addrinfo *ai;
ares_sockaddr addr;
size_t addrlen;
int result = 0;
int family = hints->ai_family;
if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC)
{
/* It only looks like an IP address if it's all numbers and dots. */
int numdots = 0, valid = 1;
const char *p;
for (p = name; *p; p++)
{
if (!ISDIGIT(*p) && *p != '.')
{
valid = 0;
break;
}
else if (*p == '.')
{
numdots++;
}
}
memset(&addr, 0, sizeof(addr));
/* if we don't have 3 dots, it is illegal
* (although inet_addr doesn't think so).
*/
if (numdots != 3 || !valid)
result = 0;
else
result =
((addr.sa4.sin_addr.s_addr = inet_addr(name))
== INADDR_NONE ? 0 : 1);
if (result)
{
family = addr.sa.sa_family = AF_INET;
addr.sa4.sin_port = htons(port);
addrlen = sizeof(addr.sa4);
}
}
if (family == AF_INET6 || family == AF_UNSPEC)
{
result = (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1);
addr.sa6.sin6_family = AF_INET6;
addr.sa6.sin6_port = htons(port);
addrlen = sizeof(addr.sa6);
}
if (!result)
return 0;
ai = ares__malloc_addrinfo();
if (!ai)
{
callback(arg, ARES_ENOMEM, 0, NULL);
return 1;
}
ai->ai_addr = ares_malloc(addrlen);
if (!ai->ai_addr)
{
ares_free(ai);
callback(arg, ARES_ENOMEM, 0, NULL);
return 1;
}
( run in 1.532 second using v1.01-cache-2.11-cpan-2398b32b56e )