s_socket.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* socket-related functions used by s_client and s_server */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. #include <signal.h>
  15. #include <openssl/opensslconf.h>
  16. /*
  17. * With IPv6, it looks like Digital has mixed up the proper order of
  18. * recursive header file inclusion, resulting in the compiler complaining
  19. * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
  20. * needed to have fileno() declared correctly... So let's define u_int
  21. */
  22. #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
  23. # define __U_INT
  24. typedef unsigned int u_int;
  25. #endif
  26. #ifndef OPENSSL_NO_SOCK
  27. # define USE_SOCKETS
  28. # include "apps.h"
  29. # undef USE_SOCKETS
  30. # include "s_apps.h"
  31. # include <openssl/bio.h>
  32. # include <openssl/err.h>
  33. /*
  34. * init_client - helper routine to set up socket communication
  35. * @sock: pointer to storage of resulting socket.
  36. * @host: the host name or path (for AF_UNIX) to connect to.
  37. * @port: the port to connect to (ignored for AF_UNIX).
  38. * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
  39. * AF_UNSPEC
  40. * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
  41. *
  42. * This will create a socket and use it to connect to a host:port, or if
  43. * family == AF_UNIX, to the path found in host.
  44. *
  45. * If the host has more than one address, it will try them one by one until
  46. * a successful connection is established. The resulting socket will be
  47. * found in *sock on success, it will be given INVALID_SOCKET otherwise.
  48. *
  49. * Returns 1 on success, 0 on failure.
  50. */
  51. int init_client(int *sock, const char *host, const char *port,
  52. int family, int type)
  53. {
  54. BIO_ADDRINFO *res = NULL;
  55. const BIO_ADDRINFO *ai = NULL;
  56. int ret;
  57. if (!BIO_sock_init())
  58. return 0;
  59. ret = BIO_lookup(host, port, BIO_LOOKUP_CLIENT, family, type, &res);
  60. if (ret == 0) {
  61. ERR_print_errors(bio_err);
  62. return 0;
  63. }
  64. ret = 0;
  65. for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
  66. /* Admittedly, these checks are quite paranoid, we should not get
  67. * anything in the BIO_ADDRINFO chain that we haven't
  68. * asked for. */
  69. OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
  70. && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
  71. *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
  72. BIO_ADDRINFO_protocol(res), 0);
  73. if (*sock == INVALID_SOCKET) {
  74. /* Maybe the kernel doesn't support the socket family, even if
  75. * BIO_lookup() added it in the returned result...
  76. */
  77. continue;
  78. }
  79. if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) {
  80. BIO_closesocket(*sock);
  81. *sock = INVALID_SOCKET;
  82. continue;
  83. }
  84. /* Success, don't try any more addresses */
  85. break;
  86. }
  87. if (*sock == INVALID_SOCKET) {
  88. ERR_print_errors(bio_err);
  89. } else {
  90. /* Remove any stale errors from previous connection attempts */
  91. ERR_clear_error();
  92. ret = 1;
  93. }
  94. BIO_ADDRINFO_free(res);
  95. return ret;
  96. }
  97. /*
  98. * do_server - helper routine to perform a server operation
  99. * @accept_sock: pointer to storage of resulting socket.
  100. * @host: the host name or path (for AF_UNIX) to connect to.
  101. * @port: the port to connect to (ignored for AF_UNIX).
  102. * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
  103. * AF_UNSPEC
  104. * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
  105. * @cb: pointer to a function that receives the accepted socket and
  106. * should perform the communication with the connecting client.
  107. * @context: pointer to memory that's passed verbatim to the cb function.
  108. * @naccept: number of times an incoming connect should be accepted. If -1,
  109. * unlimited number.
  110. *
  111. * This will create a socket and use it to listen to a host:port, or if
  112. * family == AF_UNIX, to the path found in host, then start accepting
  113. * incoming connections and run cb on the resulting socket.
  114. *
  115. * 0 on failure, something other on success.
  116. */
  117. int do_server(int *accept_sock, const char *host, const char *port,
  118. int family, int type, do_server_cb cb,
  119. unsigned char *context, int naccept)
  120. {
  121. int asock = 0;
  122. int sock;
  123. int i;
  124. BIO_ADDRINFO *res = NULL;
  125. int ret = 0;
  126. if (!BIO_sock_init())
  127. return 0;
  128. if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
  129. ERR_print_errors(bio_err);
  130. return 0;
  131. }
  132. /* Admittedly, these checks are quite paranoid, we should not get
  133. * anything in the BIO_ADDRINFO chain that we haven't asked for */
  134. OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
  135. && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
  136. asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
  137. BIO_ADDRINFO_protocol(res), 0);
  138. if (asock == INVALID_SOCKET
  139. || !BIO_listen(asock, BIO_ADDRINFO_address(res), BIO_SOCK_REUSEADDR)) {
  140. BIO_ADDRINFO_free(res);
  141. ERR_print_errors(bio_err);
  142. if (asock != INVALID_SOCKET)
  143. BIO_closesocket(asock);
  144. goto end;
  145. }
  146. BIO_ADDRINFO_free(res);
  147. res = NULL;
  148. if (accept_sock != NULL)
  149. *accept_sock = asock;
  150. for (;;) {
  151. if (type == SOCK_STREAM) {
  152. do {
  153. sock = BIO_accept_ex(asock, NULL, 0);
  154. } while (sock < 0 && BIO_sock_should_retry(ret));
  155. if (sock < 0) {
  156. ERR_print_errors(bio_err);
  157. BIO_closesocket(asock);
  158. break;
  159. }
  160. i = (*cb)(sock, type, context);
  161. BIO_closesocket(sock);
  162. } else {
  163. i = (*cb)(asock, type, context);
  164. }
  165. if (naccept != -1)
  166. naccept--;
  167. if (i < 0 || naccept == 0) {
  168. BIO_closesocket(asock);
  169. ret = i;
  170. break;
  171. }
  172. }
  173. end:
  174. # ifdef AF_UNIX
  175. if (family == AF_UNIX)
  176. unlink(host);
  177. # endif
  178. return ret;
  179. }
  180. #endif /* OPENSSL_NO_SOCK */