test_nat.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009, 2011 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * Testcase for port redirection and public IP address retrieval.
  18. * This test never fails, because there need to be a NAT box set up for that.
  19. * So we only get IP address and open the 2086 port using any NAT traversal
  20. * method available, wait for 30s, close ports and return.
  21. * Have a look at the logs and use NMAP to check that it works with your box.
  22. *
  23. * @file nat/test_nat.c
  24. * @brief Testcase for NAT library
  25. * @author Milan Bouchet-Valat
  26. * @author Christian Grothoff
  27. *
  28. * TODO: actually use ARM to start resolver service to make DNS work!
  29. */
  30. #include "platform.h"
  31. #include "gnunet_util_lib.h"
  32. #include "gnunet_program_lib.h"
  33. #include "gnunet_scheduler_lib.h"
  34. #include "gnunet_nat_lib.h"
  35. /**
  36. * Time to wait before stopping NAT, in seconds
  37. */
  38. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
  39. /**
  40. * Function called on each address that the NAT service
  41. * believes to be valid for the transport.
  42. */
  43. static void
  44. addr_callback (void *cls, int add_remove, const struct sockaddr *addr,
  45. socklen_t addrlen)
  46. {
  47. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  48. "Address changed: %s `%s' (%u bytes)\n",
  49. add_remove == GNUNET_YES ? "added" : "removed",
  50. GNUNET_a2s (addr,
  51. addrlen),
  52. (unsigned int) addrlen);
  53. }
  54. /**
  55. * Function that terminates the test.
  56. */
  57. static void
  58. stop (void *cls)
  59. {
  60. struct GNUNET_NAT_Handle *nat = cls;
  61. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  62. "Stopping NAT and quitting...\n");
  63. GNUNET_NAT_unregister (nat);
  64. }
  65. struct addr_cls
  66. {
  67. struct sockaddr *addr;
  68. socklen_t addrlen;
  69. };
  70. /**
  71. * Return the address of the default interface,
  72. * or any interface with a valid address if the default is not valid
  73. *
  74. * @param cls the 'struct addr_cls'
  75. * @param name name of the interface
  76. * @param isDefault do we think this may be our default interface
  77. * @param addr address of the interface
  78. * @param addrlen number of bytes in @a addr
  79. * @return #GNUNET_OK to continue iterating
  80. */
  81. static int
  82. process_if (void *cls,
  83. const char *name,
  84. int isDefault,
  85. const struct sockaddr *addr,
  86. const struct sockaddr *broadcast_addr,
  87. const struct sockaddr *netmask,
  88. socklen_t addrlen)
  89. {
  90. struct addr_cls *data = cls;
  91. if (addr == NULL)
  92. return GNUNET_OK;
  93. GNUNET_free_non_null (data->addr);
  94. data->addr = GNUNET_malloc (addrlen);
  95. GNUNET_memcpy (data->addr, addr, addrlen);
  96. data->addrlen = addrlen;
  97. if (isDefault)
  98. return GNUNET_SYSERR;
  99. return GNUNET_OK;
  100. }
  101. /**
  102. * Main function run with scheduler.
  103. */
  104. static void
  105. run (void *cls,
  106. char *const *args,
  107. const char *cfgfile,
  108. const struct GNUNET_CONFIGURATION_Handle *cfg)
  109. {
  110. struct GNUNET_NAT_Handle *nat;
  111. struct addr_cls data;
  112. struct sockaddr *addr;
  113. data.addr = NULL;
  114. GNUNET_OS_network_interfaces_list (process_if, &data);
  115. if (NULL == data.addr)
  116. {
  117. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  118. "Could not find a valid interface address!\n");
  119. exit (77); /* marks test as skipped */
  120. }
  121. addr = data.addr;
  122. GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
  123. if (addr->sa_family == AF_INET)
  124. ((struct sockaddr_in *) addr)->sin_port = htons (2086);
  125. else
  126. ((struct sockaddr_in6 *) addr)->sin6_port = htons (2086);
  127. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  128. "Requesting NAT redirection from address %s...\n",
  129. GNUNET_a2s (addr, data.addrlen));
  130. nat = GNUNET_NAT_register (cfg, GNUNET_YES /* tcp */ ,
  131. 2086, 1, (const struct sockaddr **) &addr,
  132. &data.addrlen, &addr_callback, NULL, NULL, NULL);
  133. GNUNET_free (addr);
  134. GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat);
  135. }
  136. int
  137. main (int argc, char *const argv[])
  138. {
  139. struct GNUNET_GETOPT_CommandLineOption options[] = {
  140. GNUNET_GETOPT_OPTION_END
  141. };
  142. char *const argv_prog[] = {
  143. "test-nat",
  144. "-c",
  145. "test_nat_data.conf",
  146. NULL
  147. };
  148. GNUNET_log_setup ("test-nat",
  149. "WARNING",
  150. NULL);
  151. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  152. "Testing NAT library, timeout set to %s\n",
  153. GNUNET_STRINGS_relative_time_to_string (TIMEOUT,
  154. GNUNET_YES));
  155. GNUNET_PROGRAM_run (3,
  156. argv_prog,
  157. "test-nat",
  158. "nohelp",
  159. options,
  160. &run, NULL);
  161. return 0;
  162. }
  163. /* end of test_nat.c */