tst-udp-garbage.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* Test that garbage packets do not affect timeout handling.
  2. Copyright (C) 2017-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <netinet/in.h>
  16. #include <rpc/clnt.h>
  17. #include <rpc/svc.h>
  18. #include <stdbool.h>
  19. #include <support/check.h>
  20. #include <support/namespace.h>
  21. #include <support/xsocket.h>
  22. #include <support/xthread.h>
  23. #include <sys/socket.h>
  24. #include <unistd.h>
  25. /* Descriptor for the server UDP socket. */
  26. static int server_fd;
  27. static void *
  28. garbage_sender_thread (void *unused)
  29. {
  30. while (true)
  31. {
  32. struct sockaddr_storage sa;
  33. socklen_t salen = sizeof (sa);
  34. char buf[1];
  35. if (recvfrom (server_fd, buf, sizeof (buf), 0,
  36. (struct sockaddr *) &sa, &salen) < 0)
  37. FAIL_EXIT1 ("recvfrom: %m");
  38. /* Send garbage packets indefinitely. */
  39. buf[0] = 0;
  40. while (true)
  41. {
  42. /* sendto can fail if the client closed the socket. */
  43. if (sendto (server_fd, buf, sizeof (buf), 0,
  44. (struct sockaddr *) &sa, salen) < 0)
  45. break;
  46. /* Wait a bit, to avoid burning too many CPU cycles in a
  47. tight loop. The wait period must be much shorter than
  48. the client timeouts configured below. */
  49. usleep (50 * 1000);
  50. }
  51. }
  52. }
  53. static int
  54. do_test (void)
  55. {
  56. support_become_root ();
  57. support_enter_network_namespace ();
  58. server_fd = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
  59. struct sockaddr_in server_address =
  60. {
  61. .sin_family = AF_INET,
  62. .sin_addr.s_addr = htonl (INADDR_LOOPBACK),
  63. };
  64. xbind (server_fd,
  65. (struct sockaddr *) &server_address, sizeof (server_address));
  66. {
  67. socklen_t sinlen = sizeof (server_address);
  68. xgetsockname (server_fd, (struct sockaddr *) &server_address, &sinlen);
  69. TEST_VERIFY (sizeof (server_address) == sinlen);
  70. }
  71. /* Garbage packet source. */
  72. xpthread_detach (xpthread_create (NULL, garbage_sender_thread, NULL));
  73. /* Test client. Use an arbitrary timeout of one second, which is
  74. much longer than the garbage packet interval, but still
  75. reasonably short, so that the test completes quickly. */
  76. int client_fd = RPC_ANYSOCK;
  77. CLIENT *clnt = clntudp_create (&server_address,
  78. 1, 2, /* Arbitrary RPC endpoint numbers. */
  79. (struct timeval) { 1, 0 },
  80. &client_fd);
  81. if (clnt == NULL)
  82. FAIL_EXIT1 ("clntudp_create: %m");
  83. TEST_VERIFY (clnt_call (clnt, 3, /* Arbitrary RPC procedure number. */
  84. (xdrproc_t) xdr_void, NULL,
  85. (xdrproc_t) xdr_void, NULL,
  86. ((struct timeval) { 1, 0 })));
  87. return 0;
  88. }
  89. #include <support/test-driver.c>