]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3531] make check: test-decodenetnum fails
authorJuergen Perlinger <perlinger@ntp.org>
Sat, 4 May 2019 08:13:19 +0000 (10:13 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Sat, 4 May 2019 08:13:19 +0000 (10:13 +0200)
bk: 5ccd499fb66TbGcNIkQ_gdqza2wkqQ

ChangeLog
include/ntp_control.h
libntp/decodenetnum.c
tests/libntp/decodenetnum.c
tests/libntp/sockaddrtest.c
tests/libntp/socktoa.c

index 9ff845c81028eeecbd72fd587d28555bc5f781e5..8966cc54efcc5168f7853f1c6e3eff354c362e4d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+---
+* [Bug 3531] make check: test-decodenetnum fails <perlinger@ntp.org>
+  - try to harden 'decodenetnum()' against 'getaddrinfo()' errors
+  - fix wrong cond-compile tests in unit tests
+
 ---
 (4.2.8p13) 2019/03/07 Released by Harlan Stenn <stenn@ntp.org>
 
index 85f41056c7b174f6688d3fd4c9bfaab404305ba8..2fe0f30bbd78bb9d7eb52e64237d298b61ced3e7 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef NTP_CONTROL_H
+#define NTP_CONTROL_H
 /*
  * ntp_control.h - definitions related to NTP mode 6 control messages
  */
@@ -190,3 +192,5 @@ extern struct ctl_trap ctl_traps[CTL_MAXTRAPS];
 #define        IFSTATS_FIELDS  12
 #define        RESLIST_FIELDS  4
 
+#endif /* NTP_CONTROL_H */
+
index 35b908f3947875a269c2d52a2acff828e474f7af..35e839aafb09bff8cf72bf66a917ceebaf1650f2 100644 (file)
 #include "ntp_stdlib.h"
 #include "ntp_assert.h"
 
+#define PORTSTR(x) _PORTSTR(x)
+#define _PORTSTR(x) #x
+
+static int
+isnumstr(
+       const char *s
+       )
+{
+       while (*s >= '0' && *s <= '9')
+               ++s;
+       return !*s;
+}
+
 /*
  * decodenetnum                convert text IP address and port to sockaddr_u
  *
@@ -26,22 +39,25 @@ decodenetnum(
        sockaddr_u *netnum
        )
 {
+       static const char * const servicename = "ntp";
+       static const char * const serviceport = PORTSTR(NTP_PORT);
+       
        struct addrinfo hints, *ai = NULL;
        int err;
-       u_short port;
-       const char *cp;
+       const char *host_str;
        const char *port_str;
        char *pp;
        char *np;
-       char name[80];
+       char nbuf[80];
 
        REQUIRE(num != NULL);
 
-       if (strlen(num) >= sizeof(name)) {
-               return 0;
+       if (strlen(num) >= sizeof(nbuf)) {
+               printf("length error\n");
+               return FALSE;
        }
 
-       port_str = NULL;
+       port_str = servicename;
        if ('[' != num[0]) {
                /*
                 * to distinguish IPv6 embedded colons from a port
@@ -50,37 +66,53 @@ decodenetnum(
                 */
                pp = strchr(num, ':');
                if (NULL == pp)
-                       cp = num;       /* no colons */
+                       host_str = num; /* no colons */
                else if (NULL != strchr(pp + 1, ':'))
-                       cp = num;       /* two or more colons */
+                       host_str = num; /* two or more colons */
                else {                  /* one colon */
-                       strlcpy(name, num, sizeof(name));
-                       cp = name;
-                       pp = strchr(cp, ':');
+                       strlcpy(nbuf, num, sizeof(nbuf));
+                       host_str = nbuf;
+                       pp = strchr(nbuf, ':');
                        *pp = '\0';
                        port_str = pp + 1;
                }
        } else {
-               cp = num + 1;
-               np = name; 
-               while (*cp && ']' != *cp)
-                       *np++ = *cp++;
+               host_str = np = nbuf; 
+               while (*++num && ']' != *num)
+                       *np++ = *num;
                *np = 0;
-               if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2])
-                       port_str = &cp[2];
-               cp = name; 
+               if (']' == num[0] && ':' == num[1] && '\0' != num[2])
+                       port_str = &num[2];
        }
+       if ( ! *host_str)
+               return FALSE;
+       if ( ! *port_str)
+               port_str = servicename;
+       
        ZERO(hints);
-       hints.ai_flags = Z_AI_NUMERICHOST;
-       err = getaddrinfo(cp, "ntp", &hints, &ai);
+       hints.ai_flags |= Z_AI_NUMERICHOST;
+       if (isnumstr(port_str))
+               hints.ai_flags |= Z_AI_NUMERICSERV;
+       err = getaddrinfo(host_str, port_str, &hints, &ai);
+       /* retry with default service name if the service lookup failed */ 
+       if (err == EAI_SERVICE && strcmp(port_str, servicename)) {
+               hints.ai_flags &= ~Z_AI_NUMERICSERV;
+               port_str = servicename;
+               err = getaddrinfo(host_str, port_str, &hints, &ai);
+       }
+       /* retry another time with default service port if the service lookup failed */ 
+       if (err == EAI_SERVICE && strcmp(port_str, serviceport)) {
+               hints.ai_flags |= Z_AI_NUMERICSERV;
+               port_str = serviceport;
+               err = getaddrinfo(host_str, port_str, &hints, &ai);
+       }
        if (err != 0)
-               return 0;
+               return FALSE;
+
        INSIST(ai->ai_addrlen <= sizeof(*netnum));
        ZERO(*netnum);
        memcpy(netnum, ai->ai_addr, ai->ai_addrlen);
        freeaddrinfo(ai);
-       if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port))
-               port = NTP_PORT;
-       SET_PORT(netnum, port);
-       return 1;
+
+       return TRUE;
 }
index 64980fc3d5865fbe41a50300b6ae588dc579b9d7..85463e868d0bd7d887542181ceb19614ed37e05c 100644 (file)
@@ -62,7 +62,7 @@ test_IPv4AddressWithPort(void)
 void
 test_IPv6AddressOnly(void)
 {
-#ifdef ISC_PLATFORM_WANTIPV6
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
 
        const struct in6_addr address = {
                0x20, 0x01, 0x0d, 0xb8,
@@ -84,16 +84,16 @@ test_IPv6AddressOnly(void)
 
 #else
        
-       TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping.");
+       TEST_IGNORE_MESSAGE("IPV6 disabled in build");
        
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif
 }
 
 
 void
 test_IPv6AddressWithPort(void)
 {
-#ifdef ISC_PLATFORM_WANTIPV6
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
 
        const struct in6_addr address = {
                0x20, 0x01, 0x0d, 0xb8,
@@ -115,9 +115,9 @@ test_IPv6AddressWithPort(void)
 
 #else
        
-       TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping.");
+       TEST_IGNORE_MESSAGE("IPV6 disabled in build");
        
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif
 }
 
 
index bd893bd429a2f169f3db41ed7b96328d376e2202..bbf669c784871468043835dae52f8a42f4d9872a 100644 (file)
@@ -31,7 +31,13 @@ IsEqual(const sockaddr_u expected, const sockaddr_u actual) {
                                   sizeof( in )) == 0) {
                        return TRUE;
                } else {
-                       printf("IPv4 comparision failed, expected: %s(%s) but was: %s(%s)",inet_ntoa(expected.sa4.sin_addr), socktoa(&expected), inet_ntoa(actual.sa4.sin_addr),socktoa(&actual));
+                       char buf[4][32];
+                       strlcpy(buf[0], inet_ntoa(expected.sa4.sin_addr), sizeof(buf[0]));
+                       strlcpy(buf[1], socktoa(&expected)              , sizeof(buf[1]));
+                       strlcpy(buf[2], inet_ntoa(actual.sa4.sin_addr)  , sizeof(buf[2]));
+                       strlcpy(buf[3], socktoa(&actual)                , sizeof(buf[3]));
+                       printf("IPv4 comparision failed, expected: %s(%s) but was: %s(%s)",
+                              buf[0], buf[1], buf[2], buf[3]);
                        return FALSE;
                }
        } else if (actual.sa.sa_family == AF_INET6) { //IPv6
index e9be1829fc6cb28ccedae26c9204d2651e5afd84..c8a9157d9bfa611cc8130de972b6078d40fd2bc4 100644 (file)
@@ -36,7 +36,7 @@ test_IPv4AddressWithPort(void)
 void 
 test_IPv6AddressWithPort(void)
 {
-#ifdef ISC_PLATFORM_WANTIPV6
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
 
        const struct in6_addr address = {
                0x20, 0x01, 0x0d, 0xb8,
@@ -61,16 +61,16 @@ test_IPv6AddressWithPort(void)
 
 #else
 
-       TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping.");
+       TEST_IGNORE_MESSAGE("IPV6 disabled in build");
 
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif
 }
 
 
 void 
 test_ScopedIPv6AddressWithPort(void)
 {
-#ifdef ISC_PLATFORM_HAVESCOPEID
+#if defined(ISC_PLATFORM_HAVESCOPEID) && defined(WANT_IPV6)
     
        const struct in6_addr address = { { {
                0xfe, 0x80, 0x00, 0x00,
@@ -95,7 +95,7 @@ test_ScopedIPv6AddressWithPort(void)
        TEST_ASSERT_EQUAL_STRING(expected_port, sockporttoa(&input));
 #else
        
-       TEST_IGNORE_MESSAGE("Skipping because ISC_PLATFORM does not have Scope ID");
+       TEST_IGNORE_MESSAGE("IPV6 scopes unavailable or IPV6 disabled in build");
        
 #endif
 }
@@ -127,7 +127,7 @@ test_HashNotEqual(void)
 void 
 test_IgnoreIPv6Fields(void)
 {
-#ifdef ISC_PLATFORM_WANTIPV6
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
 
        const struct in6_addr address = {
                0x20, 0x01, 0x0d, 0xb8,
@@ -152,7 +152,7 @@ test_IgnoreIPv6Fields(void)
 
 #else
 
-       TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping.");
+       TEST_IGNORE_MESSAGE("IPV6 disabled in build");
 
-#endif /* ISC_PLATFORM_HAVEIPV6 */
+#endif
 }