b_sock2.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. * Copyright 2016-2018 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. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <errno.h>
  12. #include "bio_lcl.h"
  13. #include <openssl/err.h>
  14. #ifndef OPENSSL_NO_SOCK
  15. # ifdef SO_MAXCONN
  16. # define MAX_LISTEN SO_MAXCONN
  17. # elif defined(SOMAXCONN)
  18. # define MAX_LISTEN SOMAXCONN
  19. # else
  20. # define MAX_LISTEN 32
  21. # endif
  22. /*-
  23. * BIO_socket - create a socket
  24. * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
  25. * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
  26. * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
  27. * @options: BIO socket options (currently unused)
  28. *
  29. * Creates a socket. This should be called before calling any
  30. * of BIO_connect and BIO_listen.
  31. *
  32. * Returns the file descriptor on success or INVALID_SOCKET on failure. On
  33. * failure errno is set, and a status is added to the OpenSSL error stack.
  34. */
  35. int BIO_socket(int domain, int socktype, int protocol, int options)
  36. {
  37. int sock = -1;
  38. if (BIO_sock_init() != 1)
  39. return INVALID_SOCKET;
  40. sock = socket(domain, socktype, protocol);
  41. if (sock == -1) {
  42. SYSerr(SYS_F_SOCKET, get_last_socket_error());
  43. BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
  44. return INVALID_SOCKET;
  45. }
  46. return sock;
  47. }
  48. /*-
  49. * BIO_connect - connect to an address
  50. * @sock: the socket to connect with
  51. * @addr: the address to connect to
  52. * @options: BIO socket options
  53. *
  54. * Connects to the address using the given socket and options.
  55. *
  56. * Options can be a combination of the following:
  57. * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
  58. * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
  59. * - BIO_SOCK_NODELAY: don't delay small messages.
  60. *
  61. * options holds BIO socket options that can be used
  62. * You should call this for every address returned by BIO_lookup
  63. * until the connection is successful.
  64. *
  65. * Returns 1 on success or 0 on failure. On failure errno is set
  66. * and an error status is added to the OpenSSL error stack.
  67. */
  68. int BIO_connect(int sock, const BIO_ADDR *addr, int options)
  69. {
  70. const int on = 1;
  71. if (sock == -1) {
  72. BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
  73. return 0;
  74. }
  75. if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
  76. return 0;
  77. if (options & BIO_SOCK_KEEPALIVE) {
  78. if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
  79. (const void *)&on, sizeof(on)) != 0) {
  80. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  81. BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
  82. return 0;
  83. }
  84. }
  85. if (options & BIO_SOCK_NODELAY) {
  86. if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
  87. (const void *)&on, sizeof(on)) != 0) {
  88. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  89. BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
  90. return 0;
  91. }
  92. }
  93. if (connect(sock, BIO_ADDR_sockaddr(addr),
  94. BIO_ADDR_sockaddr_size(addr)) == -1) {
  95. if (!BIO_sock_should_retry(-1)) {
  96. SYSerr(SYS_F_CONNECT, get_last_socket_error());
  97. BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
  98. }
  99. return 0;
  100. }
  101. return 1;
  102. }
  103. /*-
  104. * BIO_bind - bind socket to address
  105. * @sock: the socket to set
  106. * @addr: local address to bind to
  107. * @options: BIO socket options
  108. *
  109. * Binds to the address using the given socket and options.
  110. *
  111. * Options can be a combination of the following:
  112. * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
  113. * for a recently closed port.
  114. *
  115. * When restarting the program it could be that the port is still in use. If
  116. * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
  117. * It's recommended that you use this.
  118. */
  119. int BIO_bind(int sock, const BIO_ADDR *addr, int options)
  120. {
  121. int on = 1;
  122. if (sock == -1) {
  123. BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
  124. return 0;
  125. }
  126. # ifndef OPENSSL_SYS_WINDOWS
  127. /*
  128. * SO_REUSEADDR has different behavior on Windows than on
  129. * other operating systems, don't set it there.
  130. */
  131. if (options & BIO_SOCK_REUSEADDR) {
  132. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
  133. (const void *)&on, sizeof(on)) != 0) {
  134. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  135. BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
  136. return 0;
  137. }
  138. }
  139. # endif
  140. if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
  141. SYSerr(SYS_F_BIND, get_last_socket_error());
  142. BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
  143. return 0;
  144. }
  145. return 1;
  146. }
  147. /*-
  148. * BIO_listen - Creates a listen socket
  149. * @sock: the socket to listen with
  150. * @addr: local address to bind to
  151. * @options: BIO socket options
  152. *
  153. * Binds to the address using the given socket and options, then
  154. * starts listening for incoming connections.
  155. *
  156. * Options can be a combination of the following:
  157. * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
  158. * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
  159. * - BIO_SOCK_NODELAY: don't delay small messages.
  160. * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
  161. * for a recently closed port.
  162. * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
  163. * for IPv6 addresses and not IPv4 addresses mapped to IPv6.
  164. *
  165. * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
  166. * then check both for new clients that connect to it. You want to set up
  167. * the socket as non-blocking in that case since else it could hang.
  168. *
  169. * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
  170. * others it's an option. If you pass the BIO_LISTEN_V6_ONLY it will try to
  171. * create the IPv6 sockets to only listen for IPv6 connection.
  172. *
  173. * It could be that the first BIO_listen() call will listen to all the IPv6
  174. * and IPv4 addresses and that then trying to bind to the IPv4 address will
  175. * fail. We can't tell the difference between already listening ourself to
  176. * it and someone else listening to it when failing and errno is EADDRINUSE, so
  177. * it's recommended to not give an error in that case if the first call was
  178. * successful.
  179. *
  180. * When restarting the program it could be that the port is still in use. If
  181. * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
  182. * It's recommended that you use this.
  183. */
  184. int BIO_listen(int sock, const BIO_ADDR *addr, int options)
  185. {
  186. int on = 1;
  187. int socktype;
  188. socklen_t socktype_len = sizeof(socktype);
  189. if (sock == -1) {
  190. BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
  191. return 0;
  192. }
  193. if (getsockopt(sock, SOL_SOCKET, SO_TYPE,
  194. (void *)&socktype, &socktype_len) != 0
  195. || socktype_len != sizeof(socktype)) {
  196. SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
  197. BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
  198. return 0;
  199. }
  200. if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
  201. return 0;
  202. if (options & BIO_SOCK_KEEPALIVE) {
  203. if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
  204. (const void *)&on, sizeof(on)) != 0) {
  205. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  206. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
  207. return 0;
  208. }
  209. }
  210. if (options & BIO_SOCK_NODELAY) {
  211. if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
  212. (const void *)&on, sizeof(on)) != 0) {
  213. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  214. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
  215. return 0;
  216. }
  217. }
  218. # ifdef IPV6_V6ONLY
  219. if (BIO_ADDR_family(addr) == AF_INET6) {
  220. /*
  221. * Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF.
  222. * Therefore we always have to use setsockopt here.
  223. */
  224. on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
  225. if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
  226. (const void *)&on, sizeof(on)) != 0) {
  227. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  228. BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
  229. return 0;
  230. }
  231. }
  232. # endif
  233. if (!BIO_bind(sock, addr, options))
  234. return 0;
  235. if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
  236. SYSerr(SYS_F_LISTEN, get_last_socket_error());
  237. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
  238. return 0;
  239. }
  240. return 1;
  241. }
  242. /*-
  243. * BIO_accept_ex - Accept new incoming connections
  244. * @sock: the listening socket
  245. * @addr: the BIO_ADDR to store the peer address in
  246. * @options: BIO socket options, applied on the accepted socket.
  247. *
  248. */
  249. int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
  250. {
  251. socklen_t len;
  252. int accepted_sock;
  253. BIO_ADDR locaddr;
  254. BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
  255. len = sizeof(*addr);
  256. accepted_sock = accept(accept_sock,
  257. BIO_ADDR_sockaddr_noconst(addr), &len);
  258. if (accepted_sock == -1) {
  259. if (!BIO_sock_should_retry(accepted_sock)) {
  260. SYSerr(SYS_F_ACCEPT, get_last_socket_error());
  261. BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
  262. }
  263. return INVALID_SOCKET;
  264. }
  265. if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
  266. closesocket(accepted_sock);
  267. return INVALID_SOCKET;
  268. }
  269. return accepted_sock;
  270. }
  271. /*-
  272. * BIO_closesocket - Close a socket
  273. * @sock: the socket to close
  274. */
  275. int BIO_closesocket(int sock)
  276. {
  277. if (closesocket(sock) < 0)
  278. return 0;
  279. return 1;
  280. }
  281. #endif