accept trailing . and empty domain names
[musl] / src / network / lookup_name.c
index 0292093..743aa08 100644 (file)
@@ -1,6 +1,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
+#include <net/if.h>
 #include <arpa/inet.h>
 #include <ctype.h>
 #include <stdlib.h>
@@ -13,7 +14,7 @@
 static int is_valid_hostname(const char *host)
 {
        const unsigned char *s;
-       if (strnlen(host, 256)-1 > 254 || mbstowcs(0, host, 0) > 255) return 0;
+       if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
        for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
        return !*s;
 }
@@ -36,23 +37,9 @@ static int name_from_null(struct address buf[static 2], const char *name, int fa
        return cnt;
 }
 
-int __inet_aton(const char *, struct in_addr *);
-
 static int name_from_numeric(struct address buf[static 1], const char *name, int family)
 {
-       struct in_addr a4;
-       struct in6_addr a6;
-       if (family != AF_INET6 && __inet_aton(name, &a4)>0) {
-               memcpy(&buf[0].addr, &a4, sizeof a4);
-               buf[0].family = AF_INET;
-               return 1;
-       }
-       if (family != AF_INET && inet_pton(AF_INET6, name, &a6)>0) {
-               memcpy(&buf[0].addr, &a6, sizeof a6);
-               buf[0].family = AF_INET6;
-               return 1;
-       }
-       return 0;
+       return __lookup_ipliteral(buf, name, family);
 }
 
 static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
@@ -110,11 +97,13 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const
        case RR_A:
                if (len != 4) return -1;
                ctx->addrs[ctx->cnt].family = AF_INET;
+               ctx->addrs[ctx->cnt].scopeid = 0;
                memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
                break;
        case RR_AAAA:
                if (len != 16) return -1;
                ctx->addrs[ctx->cnt].family = AF_INET6;
+               ctx->addrs[ctx->cnt].scopeid = 0;
                memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
                break;
        case RR_CNAME:
@@ -163,8 +152,9 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c
 
        *canon = 0;
        if (name) {
-               size_t l;
-               if ((l = strnlen(name, 256))-1 > 254)
+               /* reject empty name and check len so it fits into temp bufs */
+               size_t l = strnlen(name, 255);
+               if (l-1 >= 254)
                        return EAI_NONAME;
                memcpy(canon, name, l+1);
        }
@@ -179,10 +169,10 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c
 
        /* Try each backend until there's at least one result. */
        cnt = name_from_null(buf, name, family, flags);
-       if (cnt<=0) cnt = name_from_numeric(buf, name, family);
-       if (cnt<=0 && !(flags & AI_NUMERICHOST)) {
+       if (!cnt) cnt = name_from_numeric(buf, name, family);
+       if (!cnt && !(flags & AI_NUMERICHOST)) {
                cnt = name_from_hosts(buf, canon, name, family);
-               if (cnt<=0) cnt = name_from_dns(buf, canon, name, family);
+               if (!cnt) cnt = name_from_dns(buf, canon, name, family);
        }
        if (cnt<=0) return cnt ? cnt : EAI_NONAME;
 
@@ -204,7 +194,6 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c
                        if (buf[i].family != AF_INET) continue;
                        memcpy(buf[i].addr+12, buf[i].addr, 4);
                        memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
-                       buf[i].scopeid = 0;
                        buf[i].family = AF_INET6;
                }
        }