X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=blobdiff_plain;f=src%2Fnetwork%2Fgetaddrinfo.c;h=4c1fe27717329d0d591130762b25a803fa384464;hp=c0f135f31442591435fcdd5f70159f4cef537465;hb=f5dfb45f78872b2574b911af2e0a372c1dac1590;hpb=e2cc0bee118d7a282bdce0b71db433def3022fb6 diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c index c0f135f3..4c1fe277 100644 --- a/src/network/getaddrinfo.c +++ b/src/network/getaddrinfo.c @@ -47,7 +47,7 @@ struct aibuf { /* Extra slots needed for storing canonical name */ #define EXTRA ((256+sizeof(struct aibuf)-1)/sizeof(struct aibuf)) -int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, struct addrinfo **res) +int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res) { int flags = hint ? hint->ai_flags : 0; int family = hint ? hint->ai_family : AF_UNSPEC; @@ -58,10 +58,9 @@ int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, union sa sa = {{0}}; unsigned char reply[1024]; int i, j; - //char hostbuf[256]; char line[512]; FILE *f, _f; - unsigned char _buf[64]; + unsigned char _buf[1024]; char *z; int result; int cnt; @@ -75,38 +74,63 @@ int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, type = proto==IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; if (serv) { - port = strtoul(serv, &z, 0); - if (!*z && port > 65535) return EAI_SERVICE; - if (!port) { + if (!*serv) return EAI_SERVICE; + port = strtoul(serv, &z, 10); + if (*z) { + size_t servlen = strlen(serv); + char *end = line; + if (flags & AI_NUMERICSERV) return EAI_SERVICE; - //f = fopen("/etc/services", "rb"); - return EAI_SERVICE; + f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf); + if (!f) return EAI_SERVICE; + while (fgets(line, sizeof line, f)) { + if (strncmp(line, serv, servlen) || !isspace(line[servlen])) + continue; + port = strtoul(line+servlen, &end, 10); + if (strncmp(end, proto==IPPROTO_UDP ? "/udp" : "/tcp", 4)) + continue; + break; + } + __fclose_ca(f); + if (feof(f)) return EAI_SERVICE; } + if (port > 65535) return EAI_SERVICE; port = htons(port); } if (!host) { - if (family == AF_UNSPEC) family = AF_INET; - buf = calloc(sizeof *buf, 1+EXTRA); + if (family == AF_UNSPEC) { + cnt = 2; family = AF_INET; + } else { + cnt = 1; + } + buf = calloc(sizeof *buf, cnt); if (!buf) return EAI_MEMORY; - buf->ai.ai_protocol = proto; - buf->ai.ai_socktype = type; - buf->ai.ai_addr = (void *)&buf->sa; - buf->ai.ai_addrlen = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin; - buf->ai.ai_family = family; - buf->sa.sin.sin_family = family; - buf->sa.sin.sin_port = port; - if (!(flags & AI_PASSIVE)) { - if (family == AF_INET) { - 0[(uint8_t*)&buf->sa.sin.sin_addr.s_addr]=127; - 3[(uint8_t*)&buf->sa.sin.sin_addr.s_addr]=1; - } else buf[0].sa.sin6.sin6_addr.s6_addr[15] = 1; + for (i=0; iai; return 0; } + if (!*host) return EAI_NONAME; + /* Try as a numeric address */ if (__ipparse(&sa, family, host) >= 0) { buf = calloc(sizeof *buf, 1+EXTRA); @@ -204,7 +228,7 @@ int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, while (j--) buf[i++].sa.sin.sin_family = AF_INET6; } - if (__dns_get_rr((void *)&buf[cnt], 0, 256, 1, reply, RR_CNAME, 1) < 0) + if (__dns_get_rr((void *)&buf[cnt], 0, 256, 1, reply, RR_CNAME, 1) <= 0) strcpy((void *)&buf[cnt], host); for (i=0; i