testsock.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "testutil.h"
  17. #include "testsock.h"
  18. #include "fspr_thread_proc.h"
  19. #include "fspr_network_io.h"
  20. #include "fspr_errno.h"
  21. #include "fspr_general.h"
  22. #include "fspr_lib.h"
  23. #include "fspr_strings.h"
  24. #include "fspr_poll.h"
  25. static void launch_child(abts_case *tc, fspr_proc_t *proc, const char *arg1, fspr_pool_t *p)
  26. {
  27. fspr_procattr_t *procattr;
  28. const char *args[3];
  29. fspr_status_t rv;
  30. rv = fspr_procattr_create(&procattr, p);
  31. APR_ASSERT_SUCCESS(tc, "Couldn't create procattr", rv);
  32. rv = fspr_procattr_io_set(procattr, APR_NO_PIPE, APR_NO_PIPE,
  33. APR_NO_PIPE);
  34. APR_ASSERT_SUCCESS(tc, "Couldn't set io in procattr", rv);
  35. rv = fspr_procattr_error_check_set(procattr, 1);
  36. APR_ASSERT_SUCCESS(tc, "Couldn't set error check in procattr", rv);
  37. args[0] = "sockchild" EXTENSION;
  38. args[1] = arg1;
  39. args[2] = NULL;
  40. rv = fspr_proc_create(proc, "./sockchild" EXTENSION, args, NULL,
  41. procattr, p);
  42. APR_ASSERT_SUCCESS(tc, "Couldn't launch program", rv);
  43. }
  44. static int wait_child(abts_case *tc, fspr_proc_t *proc)
  45. {
  46. int exitcode;
  47. fspr_exit_why_e why;
  48. ABTS_ASSERT(tc, "Error waiting for child process",
  49. fspr_proc_wait(proc, &exitcode, &why, APR_WAIT) == APR_CHILD_DONE);
  50. ABTS_ASSERT(tc, "child terminated normally", why == APR_PROC_EXIT);
  51. return exitcode;
  52. }
  53. static void test_addr_info(abts_case *tc, void *data)
  54. {
  55. fspr_status_t rv;
  56. fspr_sockaddr_t *sa;
  57. rv = fspr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 80, 0, p);
  58. APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
  59. rv = fspr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 80, 0, p);
  60. APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
  61. ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname);
  62. }
  63. static fspr_socket_t *setup_socket(abts_case *tc)
  64. {
  65. fspr_status_t rv;
  66. fspr_sockaddr_t *sa;
  67. fspr_socket_t *sock;
  68. rv = fspr_sockaddr_info_get(&sa, "127.0.0.1", APR_INET, 8021, 0, p);
  69. APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
  70. rv = fspr_socket_create(&sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
  71. APR_ASSERT_SUCCESS(tc, "Problem creating socket", rv);
  72. rv = fspr_socket_opt_set(sock, APR_SO_REUSEADDR, 1);
  73. APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv);
  74. rv = fspr_socket_bind(sock, sa);
  75. APR_ASSERT_SUCCESS(tc, "Problem binding to port", rv);
  76. if (rv) return NULL;
  77. rv = fspr_socket_listen(sock, 5);
  78. APR_ASSERT_SUCCESS(tc, "Problem listening on socket", rv);
  79. return sock;
  80. }
  81. static void test_create_bind_listen(abts_case *tc, void *data)
  82. {
  83. fspr_status_t rv;
  84. fspr_socket_t *sock = setup_socket(tc);
  85. if (!sock) return;
  86. rv = fspr_socket_close(sock);
  87. APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
  88. }
  89. static void test_send(abts_case *tc, void *data)
  90. {
  91. fspr_status_t rv;
  92. fspr_socket_t *sock;
  93. fspr_socket_t *sock2;
  94. fspr_proc_t proc;
  95. int protocol;
  96. fspr_size_t length;
  97. sock = setup_socket(tc);
  98. if (!sock) return;
  99. launch_child(tc, &proc, "read", p);
  100. rv = fspr_socket_accept(&sock2, sock, p);
  101. APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
  102. fspr_socket_protocol_get(sock2, &protocol);
  103. ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
  104. length = strlen(DATASTR);
  105. fspr_socket_send(sock2, DATASTR, &length);
  106. /* Make sure that the client received the data we sent */
  107. ABTS_INT_EQUAL(tc, strlen(DATASTR), wait_child(tc, &proc));
  108. rv = fspr_socket_close(sock2);
  109. APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
  110. rv = fspr_socket_close(sock);
  111. APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
  112. }
  113. static void test_recv(abts_case *tc, void *data)
  114. {
  115. fspr_status_t rv;
  116. fspr_socket_t *sock;
  117. fspr_socket_t *sock2;
  118. fspr_proc_t proc;
  119. int protocol;
  120. fspr_size_t length = STRLEN;
  121. char datastr[STRLEN];
  122. sock = setup_socket(tc);
  123. if (!sock) return;
  124. launch_child(tc, &proc, "write", p);
  125. rv = fspr_socket_accept(&sock2, sock, p);
  126. APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
  127. fspr_socket_protocol_get(sock2, &protocol);
  128. ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
  129. memset(datastr, 0, STRLEN);
  130. fspr_socket_recv(sock2, datastr, &length);
  131. /* Make sure that the server received the data we sent */
  132. ABTS_STR_EQUAL(tc, DATASTR, datastr);
  133. ABTS_INT_EQUAL(tc, strlen(datastr), wait_child(tc, &proc));
  134. rv = fspr_socket_close(sock2);
  135. APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
  136. rv = fspr_socket_close(sock);
  137. APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
  138. }
  139. static void test_timeout(abts_case *tc, void *data)
  140. {
  141. fspr_status_t rv;
  142. fspr_socket_t *sock;
  143. fspr_socket_t *sock2;
  144. fspr_proc_t proc;
  145. int protocol;
  146. int exit;
  147. sock = setup_socket(tc);
  148. if (!sock) return;
  149. launch_child(tc, &proc, "read", p);
  150. rv = fspr_socket_accept(&sock2, sock, p);
  151. APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
  152. fspr_socket_protocol_get(sock2, &protocol);
  153. ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
  154. exit = wait_child(tc, &proc);
  155. ABTS_INT_EQUAL(tc, SOCKET_TIMEOUT, exit);
  156. /* We didn't write any data, so make sure the child program returns
  157. * an error.
  158. */
  159. rv = fspr_socket_close(sock2);
  160. APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
  161. rv = fspr_socket_close(sock);
  162. APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
  163. }
  164. static void test_get_addr(abts_case *tc, void *data)
  165. {
  166. fspr_status_t rv;
  167. fspr_socket_t *ld, *sd, *cd;
  168. fspr_sockaddr_t *sa, *ca;
  169. char a[128], b[128];
  170. ld = setup_socket(tc);
  171. APR_ASSERT_SUCCESS(tc,
  172. "get local address of bound socket",
  173. fspr_socket_addr_get(&sa, APR_LOCAL, ld));
  174. rv = fspr_socket_create(&cd, sa->family, SOCK_STREAM,
  175. APR_PROTO_TCP, p);
  176. APR_ASSERT_SUCCESS(tc, "create client socket", rv);
  177. APR_ASSERT_SUCCESS(tc, "enable non-block mode",
  178. fspr_socket_opt_set(cd, APR_SO_NONBLOCK, 1));
  179. /* It is valid for a connect() on a socket with NONBLOCK set to
  180. * succeed (if the connection can be established synchronously),
  181. * but if it does, this test cannot proceed. */
  182. rv = fspr_socket_connect(cd, sa);
  183. if (rv == APR_SUCCESS) {
  184. fspr_socket_close(ld);
  185. fspr_socket_close(cd);
  186. ABTS_NOT_IMPL(tc, "Cannot test if connect completes "
  187. "synchronously");
  188. return;
  189. }
  190. if (!APR_STATUS_IS_EINPROGRESS(rv)) {
  191. fspr_socket_close(ld);
  192. fspr_socket_close(cd);
  193. APR_ASSERT_SUCCESS(tc, "connect to listener", rv);
  194. return;
  195. }
  196. APR_ASSERT_SUCCESS(tc, "accept connection",
  197. fspr_socket_accept(&sd, ld, p));
  198. {
  199. /* wait for writability */
  200. fspr_pollfd_t pfd;
  201. int n;
  202. pfd.p = p;
  203. pfd.desc_type = APR_POLL_SOCKET;
  204. pfd.reqevents = APR_POLLOUT|APR_POLLHUP;
  205. pfd.desc.s = cd;
  206. pfd.client_data = NULL;
  207. APR_ASSERT_SUCCESS(tc, "poll for connect completion",
  208. fspr_poll(&pfd, 1, &n, 5 * APR_USEC_PER_SEC));
  209. }
  210. APR_ASSERT_SUCCESS(tc, "get local address of server socket",
  211. fspr_socket_addr_get(&sa, APR_LOCAL, sd));
  212. APR_ASSERT_SUCCESS(tc, "get remote address of client socket",
  213. fspr_socket_addr_get(&ca, APR_REMOTE, cd));
  214. fspr_snprintf(a, sizeof(a), "%pI", sa);
  215. fspr_snprintf(b, sizeof(b), "%pI", ca);
  216. ABTS_STR_EQUAL(tc, a, b);
  217. fspr_socket_close(cd);
  218. fspr_socket_close(sd);
  219. fspr_socket_close(ld);
  220. }
  221. abts_suite *testsock(abts_suite *suite)
  222. {
  223. suite = ADD_SUITE(suite)
  224. abts_run_test(suite, test_addr_info, NULL);
  225. abts_run_test(suite, test_create_bind_listen, NULL);
  226. abts_run_test(suite, test_send, NULL);
  227. abts_run_test(suite, test_recv, NULL);
  228. abts_run_test(suite, test_timeout, NULL);
  229. abts_run_test(suite, test_get_addr, NULL);
  230. return suite;
  231. }