b_sock2.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * Copyright 2016-2021 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_local.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. # ifndef OPENSSL_SYS_WINDOWS
  122. int on = 1;
  123. # endif
  124. if (sock == -1) {
  125. BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
  126. return 0;
  127. }
  128. # ifndef OPENSSL_SYS_WINDOWS
  129. /*
  130. * SO_REUSEADDR has different behavior on Windows than on
  131. * other operating systems, don't set it there.
  132. */
  133. if (options & BIO_SOCK_REUSEADDR) {
  134. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
  135. (const void *)&on, sizeof(on)) != 0) {
  136. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  137. BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
  138. return 0;
  139. }
  140. }
  141. # endif
  142. if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
  143. SYSerr(SYS_F_BIND, get_last_socket_error());
  144. BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
  145. return 0;
  146. }
  147. return 1;
  148. }
  149. /*-
  150. * BIO_listen - Creates a listen socket
  151. * @sock: the socket to listen with
  152. * @addr: local address to bind to
  153. * @options: BIO socket options
  154. *
  155. * Binds to the address using the given socket and options, then
  156. * starts listening for incoming connections.
  157. *
  158. * Options can be a combination of the following:
  159. * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
  160. * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
  161. * - BIO_SOCK_NODELAY: don't delay small messages.
  162. * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
  163. * for a recently closed port.
  164. * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
  165. * for IPv6 addresses and not IPv4 addresses mapped to IPv6.
  166. *
  167. * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
  168. * then check both for new clients that connect to it. You want to set up
  169. * the socket as non-blocking in that case since else it could hang.
  170. *
  171. * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
  172. * others it's an option. If you pass the BIO_LISTEN_V6_ONLY it will try to
  173. * create the IPv6 sockets to only listen for IPv6 connection.
  174. *
  175. * It could be that the first BIO_listen() call will listen to all the IPv6
  176. * and IPv4 addresses and that then trying to bind to the IPv4 address will
  177. * fail. We can't tell the difference between already listening ourself to
  178. * it and someone else listening to it when failing and errno is EADDRINUSE, so
  179. * it's recommended to not give an error in that case if the first call was
  180. * successful.
  181. *
  182. * When restarting the program it could be that the port is still in use. If
  183. * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
  184. * It's recommended that you use this.
  185. */
  186. int BIO_listen(int sock, const BIO_ADDR *addr, int options)
  187. {
  188. int on = 1;
  189. int socktype;
  190. socklen_t socktype_len = sizeof(socktype);
  191. if (sock == -1) {
  192. BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
  193. return 0;
  194. }
  195. if (getsockopt(sock, SOL_SOCKET, SO_TYPE,
  196. (void *)&socktype, &socktype_len) != 0
  197. || socktype_len != sizeof(socktype)) {
  198. SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
  199. BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
  200. return 0;
  201. }
  202. if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
  203. return 0;
  204. if (options & BIO_SOCK_KEEPALIVE) {
  205. if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
  206. (const void *)&on, sizeof(on)) != 0) {
  207. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  208. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
  209. return 0;
  210. }
  211. }
  212. if (options & BIO_SOCK_NODELAY) {
  213. if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
  214. (const void *)&on, sizeof(on)) != 0) {
  215. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  216. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
  217. return 0;
  218. }
  219. }
  220. /* On OpenBSD it is always ipv6 only with ipv6 sockets thus read-only */
  221. # if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
  222. if (BIO_ADDR_family(addr) == AF_INET6) {
  223. /*
  224. * Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF.
  225. * Therefore we always have to use setsockopt here.
  226. */
  227. on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
  228. if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
  229. (const void *)&on, sizeof(on)) != 0) {
  230. SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
  231. BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
  232. return 0;
  233. }
  234. }
  235. # endif
  236. if (!BIO_bind(sock, addr, options))
  237. return 0;
  238. if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
  239. SYSerr(SYS_F_LISTEN, get_last_socket_error());
  240. BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
  241. return 0;
  242. }
  243. return 1;
  244. }
  245. /*-
  246. * BIO_accept_ex - Accept new incoming connections
  247. * @sock: the listening socket
  248. * @addr: the BIO_ADDR to store the peer address in
  249. * @options: BIO socket options, applied on the accepted socket.
  250. *
  251. */
  252. int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
  253. {
  254. socklen_t len;
  255. int accepted_sock;
  256. BIO_ADDR locaddr;
  257. BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
  258. len = sizeof(*addr);
  259. accepted_sock = accept(accept_sock,
  260. BIO_ADDR_sockaddr_noconst(addr), &len);
  261. if (accepted_sock == -1) {
  262. if (!BIO_sock_should_retry(accepted_sock)) {
  263. SYSerr(SYS_F_ACCEPT, get_last_socket_error());
  264. BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
  265. }
  266. return INVALID_SOCKET;
  267. }
  268. if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
  269. closesocket(accepted_sock);
  270. return INVALID_SOCKET;
  271. }
  272. return accepted_sock;
  273. }
  274. /*-
  275. * BIO_closesocket - Close a socket
  276. * @sock: the socket to close
  277. */
  278. int BIO_closesocket(int sock)
  279. {
  280. if (closesocket(sock) < 0)
  281. return 0;
  282. return 1;
  283. }
  284. #endif