run.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <ccan/net/net.h>
  2. #include <ccan/net/net.c>
  3. #include <ccan/tap/tap.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #include <stdio.h>
  7. #include <err.h>
  8. static unsigned int server(int protocol, int type)
  9. {
  10. int sock;
  11. union {
  12. struct sockaddr addr;
  13. struct sockaddr_in ipv4;
  14. struct sockaddr_in6 ipv6;
  15. } addr;
  16. socklen_t addlen = sizeof(addr);
  17. sock = socket(protocol, type, 0);
  18. /* Bind to free port. */
  19. listen(sock, 0);
  20. /* Figure out what port it gave us. */
  21. getsockname(sock, &addr.addr, &addlen);
  22. fflush(stdout);
  23. if (fork() == 0) {
  24. int ret, fd;
  25. alarm(3);
  26. fd = accept(sock, NULL, 0);
  27. if (fd < 0)
  28. err(1, "Accepting from socket %i", sock);
  29. ret = write(fd, "Yay!", strlen("Yay!"));
  30. if (ret != strlen("Yay!"))
  31. err(1, "Write returned %i", ret);
  32. exit(0);
  33. }
  34. close(sock);
  35. return ntohs(protocol == AF_INET
  36. ? addr.ipv4.sin_port : addr.ipv6.sin6_port);
  37. }
  38. int main(void)
  39. {
  40. struct addrinfo *addr, *addr2;
  41. int fd, status;
  42. struct sockaddr saddr;
  43. socklen_t slen = sizeof(saddr);
  44. char buf[20];
  45. unsigned int port;
  46. plan_tests(16);
  47. port = server(AF_INET, SOCK_STREAM);
  48. sprintf(buf, "%u", port);
  49. addr = net_client_lookup("localhost", buf, AF_UNSPEC, SOCK_STREAM);
  50. addr2 = net_client_lookup("ip6-localhost", buf,
  51. AF_UNSPEC, SOCK_STREAM);
  52. ok1(addr);
  53. ok1(addr2);
  54. /* Join them as if they were from one lookup. */
  55. addr->ai_next = addr2;
  56. fd = net_connect(addr);
  57. ok1(fd >= 0);
  58. ok1(getsockname(fd, &saddr, &slen) == 0);
  59. ok1(saddr.sa_family == AF_INET);
  60. status = read(fd, buf, sizeof(buf));
  61. ok(status == strlen("Yay!"),
  62. "Read returned %i (%s)", status, strerror(errno));
  63. ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0);
  64. close(fd);
  65. addr->ai_next = NULL;
  66. freeaddrinfo(addr);
  67. freeaddrinfo(addr2);
  68. port = server(AF_INET6, SOCK_STREAM);
  69. sprintf(buf, "%u", port);
  70. addr = net_client_lookup("localhost", buf, AF_UNSPEC, SOCK_STREAM);
  71. addr2 = net_client_lookup("ip6-localhost", buf,
  72. AF_UNSPEC, SOCK_STREAM);
  73. ok1(addr);
  74. ok1(addr2);
  75. /* Join them as if they were from one lookup. */
  76. addr->ai_next = addr2;
  77. fd = net_connect(addr);
  78. ok1(fd >= 0);
  79. ok1(getsockname(fd, &saddr, &slen) == 0);
  80. ok1(saddr.sa_family == AF_INET6);
  81. status = read(fd, buf, sizeof(buf));
  82. ok(status == strlen("Yay!"),
  83. "Read returned %i (%s)", status, strerror(errno));
  84. ok1(strncmp(buf, "Yay!", strlen("Yay!")) == 0);
  85. close(fd);
  86. addr->ai_next = NULL;
  87. freeaddrinfo(addr);
  88. freeaddrinfo(addr2);
  89. wait(&status);
  90. ok1(WIFEXITED(status));
  91. ok1(WEXITSTATUS(status) == 0);
  92. /* This exits depending on whether all tests passed */
  93. return exit_status();
  94. }