]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
test: extend socket unit test
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 2 Dec 2024 13:43:29 +0000 (14:43 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 4 Dec 2024 11:06:29 +0000 (12:06 +0100)
test/unit/socket.c

index c4edea0fc47c7286271fb7497df4625617aad4e7..097bda2f8ba4aeaf81a4253af0d657d4cd1a1772 100644 (file)
@@ -54,8 +54,199 @@ test_preinitialise(void)
 #endif
 }
 
+static void
+send_and_recv(int type, int is_stream, int is_client_bound, int server_fd, int client_fd)
+{
+  SCK_Message *msg1, msg2;
+  char buf1[16], buf2[16];
+
+  TEST_CHECK(!SCK_IsReusable(server_fd));
+  TEST_CHECK(!SCK_IsReusable(client_fd));
+
+  if (random() % 2 && !SCK_EnableKernelRxTimestamping(client_fd))
+    ;
+
+  UTI_GetRandomBytes(buf1, sizeof (buf1));
+
+  TEST_CHECK(SCK_Send(client_fd, buf1, sizeof (buf1), 0) == sizeof (buf1));
+  msg1 = SCK_ReceiveMessage(server_fd, 0);
+
+  TEST_CHECK(msg1);
+  TEST_CHECK(msg1->data);
+  TEST_CHECK(msg1->length == sizeof (buf1));
+  if (is_stream) {
+    TEST_CHECK(msg1->addr_type == type || msg1->addr_type == SCK_ADDR_UNSPEC);
+  } else if (is_client_bound) {
+    TEST_CHECK(msg1->addr_type == type);
+    TEST_CHECK(msg1->remote_addr.ip.ip_addr.family != IPADDR_UNSPEC);
+  } else {
+    TEST_CHECK(msg1->addr_type == SCK_ADDR_UNSPEC);
+  }
+
+  TEST_CHECK(memcmp(buf1, msg1->data, sizeof (buf1)) == 0);
+
+  UTI_GetRandomBytes(buf2, sizeof (buf2));
+  SCK_InitMessage(&msg2, is_stream ? SCK_ADDR_UNSPEC : type);
+  if (!is_stream)
+    msg2.remote_addr = msg1->remote_addr;
+  msg2.data = buf2;
+  msg2.length = sizeof (buf1);
+
+  TEST_CHECK(SCK_SendMessage(server_fd, &msg2, 0));
+  TEST_CHECK(SCK_Receive(client_fd, buf1, sizeof (buf1), 0) == sizeof (buf1));
+  TEST_CHECK(memcmp(buf1, buf2, sizeof (buf1)) == 0);
+}
+
 void
 test_unit(void)
 {
+  int i, family, s1, s2, s3;
+  IPSockAddr sa1, sa2;
+  IPAddr ip1, ip2;
+
   test_preinitialise();
+
+  SCK_PreInitialise();
+
+  SCK_Initialise(IPADDR_INET4);
+  TEST_CHECK(SCK_IsIpFamilyEnabled(IPADDR_INET4));
+  TEST_CHECK(!SCK_IsIpFamilyEnabled(IPADDR_INET6));
+  SCK_Finalise();
+
+  SCK_Initialise(IPADDR_INET6);
+  TEST_CHECK(!SCK_IsIpFamilyEnabled(IPADDR_INET4));
+#ifdef FEAT_IPV6
+  TEST_CHECK(SCK_IsIpFamilyEnabled(IPADDR_INET6));
+#else
+  TEST_CHECK(!SCK_IsIpFamilyEnabled(IPADDR_INET6));
+#endif
+  SCK_Finalise();
+
+  SCK_Initialise(IPADDR_UNSPEC);
+  TEST_CHECK(SCK_IsIpFamilyEnabled(IPADDR_INET4));
+#ifdef FEAT_IPV6
+  TEST_CHECK(SCK_IsIpFamilyEnabled(IPADDR_INET6));
+#else
+  TEST_CHECK(!SCK_IsIpFamilyEnabled(IPADDR_INET6));
+#endif
+
+  SCK_GetAnyLocalIPAddress(IPADDR_INET4, &ip1);
+  if (UTI_StringToIP("0.0.0.0", &ip2))
+    TEST_CHECK(UTI_CompareIPs(&ip1, &ip2, NULL) == 0);
+  SCK_GetAnyLocalIPAddress(IPADDR_INET6, &ip1);
+  if (UTI_StringToIP("::", &ip2))
+    TEST_CHECK(UTI_CompareIPs(&ip1, &ip2, NULL) == 0);
+
+  SCK_GetLoopbackIPAddress(IPADDR_INET4, &ip1);
+  if (UTI_StringToIP("127.0.0.1", &ip2))
+    TEST_CHECK(UTI_CompareIPs(&ip1, &ip2, NULL) == 0);
+  SCK_GetLoopbackIPAddress(IPADDR_INET6, &ip1);
+  if (UTI_StringToIP("::1", &ip2))
+    TEST_CHECK(UTI_CompareIPs(&ip1, &ip2, NULL) == 0);
+
+  if (UTI_StringToIP("169.254.100.100", &ip1))
+    TEST_CHECK(SCK_IsLinkLocalIPAddress(&ip1));
+  if (UTI_StringToIP("169.255.100.100", &ip1))
+    TEST_CHECK(!SCK_IsLinkLocalIPAddress(&ip2));
+  if (UTI_StringToIP("fe80::", &ip1))
+    TEST_CHECK(SCK_IsLinkLocalIPAddress(&ip1));
+  if (UTI_StringToIP("fe81::", &ip1))
+    TEST_CHECK(!SCK_IsLinkLocalIPAddress(&ip2));
+
+  for (family = IPADDR_INET4; family <= IPADDR_INET6; family++) {
+    SCK_GetLoopbackIPAddress(family, &sa1.ip_addr);
+
+    for (i = 0; i < 16; i++) {
+      sa1.port = 1024 + random() % 60000;
+      s1 = SCK_OpenUdpSocket(NULL, &sa1, NULL, SCK_FLAG_BLOCK);
+      if (s1 >= 0) {
+        s2 = SCK_OpenUdpSocket(&sa1, NULL, NULL, SCK_FLAG_BLOCK);
+        TEST_CHECK(s2 >= 0);
+
+        send_and_recv(SCK_ADDR_IP, 0, 1, s1, s2);
+
+        SCK_CloseSocket(s1);
+        SCK_CloseSocket(s2);
+      }
+    }
+
+    for (i = 0; i < 16; i++) {
+      sa1.port = 1024 + random() % 60000;
+      s1 = SCK_OpenTcpSocket(NULL, &sa1, NULL, SCK_FLAG_BLOCK);
+      if (s1 >= 0) {
+        TEST_CHECK(SCK_ListenOnSocket(s1, 1));
+        if (i % 2) {
+          sa2 = sa1;
+          sa2.port = 1024 + random() % 60000;
+          s2 = SCK_OpenTcpSocket(&sa1, &sa2, NULL, SCK_FLAG_BLOCK);
+          if (s2 < 0) {
+            SCK_CloseSocket(s1);
+            continue;
+          }
+        } else {
+          s2 = SCK_OpenTcpSocket(&sa1, NULL, NULL, SCK_FLAG_BLOCK);
+        }
+        TEST_CHECK(s2 >= 0);
+        s3 = SCK_AcceptConnection(s1, &sa2);
+        TEST_CHECK(UTI_CompareIPs(&sa1.ip_addr, &sa2.ip_addr, NULL) == 0);
+
+        send_and_recv(SCK_ADDR_IP, 1, 1, s3, s2);
+
+        SCK_ShutdownConnection(s2);
+        SCK_ShutdownConnection(s3);
+        SCK_CloseSocket(s1);
+        SCK_CloseSocket(s2);
+        SCK_CloseSocket(s3);
+      }
+    }
+  }
+
+  for (i = 0; i < 16; i++) {
+    s1 = SCK_OpenUnixDatagramSocket(NULL, "testsocket1", SCK_FLAG_BLOCK);
+    TEST_CHECK(s1 >= 0);
+    s2 = SCK_OpenUnixDatagramSocket("testsocket1", "testsocket2", SCK_FLAG_BLOCK);
+    TEST_CHECK(s2 >= 0);
+
+    send_and_recv(SCK_ADDR_UNIX, 0, 1, s1, s2);
+
+    if (i % 2)
+      TEST_CHECK(SCK_RemoveSocket(s1));
+    if (i % 2)
+      TEST_CHECK(SCK_RemoveSocket(s2));
+    SCK_CloseSocket(s1);
+    SCK_CloseSocket(s2);
+  }
+
+  for (i = 0; i < 16; i++) {
+    s1 = SCK_OpenUnixStreamSocket(NULL, "testsocket1", SCK_FLAG_BLOCK);
+    TEST_CHECK(s1 >= 0);
+    TEST_CHECK(SCK_ListenOnSocket(s1, 1));
+    s2 = SCK_OpenUnixStreamSocket("testsocket1", i % 2 ? "testsocket2" : NULL, SCK_FLAG_BLOCK);
+    TEST_CHECK(s2 >= 0);
+    s3 = SCK_AcceptConnection(s1, &sa2);
+    TEST_CHECK(sa2.ip_addr.family == IPADDR_UNSPEC);
+
+    send_and_recv(SCK_ADDR_UNIX, 1, i % 2, s3, s2);
+
+    if (i % 4)
+      TEST_CHECK(SCK_RemoveSocket(s1));
+    SCK_ShutdownConnection(s2);
+    SCK_ShutdownConnection(s3);
+    SCK_CloseSocket(s1);
+    SCK_CloseSocket(s2);
+    SCK_CloseSocket(s3);
+  }
+
+  for (i = 0; i < 16; i++) {
+    s1 = SCK_OpenUnixSocketPair(SCK_FLAG_BLOCK, &s2);
+    TEST_CHECK(s1 >= 0);
+    TEST_CHECK(s2 >= 0);
+
+    send_and_recv(SCK_ADDR_UNIX, 1, 0, s1, s2);
+
+    SCK_CloseSocket(s1);
+    SCK_CloseSocket(s2);
+  }
+
+  SCK_Finalise();
 }