e876e07f1bf27024094f428bcdf6924296d13700
[openssl.git] / crypto / bio / b_sock2.c
1 /* ====================================================================
2  * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This product includes cryptographic software written by Eric Young
50  * (eay@cryptsoft.com).  This product includes software written by Tim
51  * Hudson (tjh@cryptsoft.com).
52  *
53  */
54
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <errno.h>
58
59 #include "bio_lcl.h"
60
61 #include <openssl/err.h>
62
63 #ifndef OPENSSL_NO_SOCK
64 # ifdef SO_MAXCONN
65 #  define MAX_LISTEN  SO_MAXCONN
66 # elif defined(SOMAXCONN)
67 #  define MAX_LISTEN  SOMAXCONN
68 # else
69 #  define MAX_LISTEN  32
70 # endif
71
72 /*-
73  * BIO_socket - create a socket
74  * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
75  * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
76  * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
77  * @options: BIO socket options (currently unused)
78  *
79  * Creates a socket.  This should be called before calling any
80  * of BIO_connect and BIO_listen.
81  *
82  * Returns the file descriptor on success or INVALID_SOCKET on failure.  On
83  * failure errno is set, and a status is added to the OpenSSL error stack.
84  */
85 int BIO_socket(int domain, int socktype, int protocol, int options)
86 {
87     int sock = -1;
88
89     if (BIO_sock_init() != 1)
90         return INVALID_SOCKET;
91
92     sock = socket(domain, socktype, protocol);
93     if (sock == -1) {
94         SYSerr(SYS_F_SOCKET, get_last_socket_error());
95         BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
96         return INVALID_SOCKET;
97     }
98
99     return sock;
100 }
101
102 /*-
103  * BIO_connect - connect to an address
104  * @sock: the socket to connect with
105  * @addr: the address to connect to
106  * @options: BIO socket options
107  *
108  * Connects to the address using the given socket and options.
109  *
110  * Options can be a combination of the following:
111  * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
112  * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
113  * - BIO_SOCK_NODELAY: don't delay small messages.
114  *
115  * options holds BIO socket options that can be used
116  * You should call this for every address returned by BIO_lookup
117  * until the connection is succesful.
118  *
119  * Returns 1 on success or 0 on failure.  On failure errno is set
120  * and an error status is added to the OpenSSL error stack.
121  */
122 int BIO_connect(int sock, const BIO_ADDR *addr, int options)
123 {
124     int on = 1;
125
126     if (sock == -1) {
127         BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
128         return 0;
129     }
130
131     if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
132         return 0;
133
134     if (options & BIO_SOCK_KEEPALIVE) {
135         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
136             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
137             BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
138             return 0;
139         }
140     }
141
142     if (options & BIO_SOCK_NODELAY) {
143         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
144             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
145             BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
146             return 0;
147         }
148     }
149
150     if (connect(sock, BIO_ADDR_sockaddr(addr),
151                 BIO_ADDR_sockaddr_size(addr)) == -1) {
152         if (!BIO_sock_should_retry(-1)) {
153             SYSerr(SYS_F_CONNECT, get_last_socket_error());
154             BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
155         }
156         return 0;
157     }
158     return 1;
159 }
160
161 /*-
162  * BIO_listen - Creates a listen socket
163  * @sock: the socket to listen with
164  * @addr: local address to bind to
165  * @options: BIO socket options
166  *
167  * Binds to the address using the given socket and options, then
168  * starts listening for incoming connections.
169  *
170  * Options can be a combination of the following:
171  * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
172  * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
173  * - BIO_SOCK_NODELAY: don't delay small messages.
174  * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
175  *   for a recently closed port.
176  * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
177  *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
178  *
179  * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
180  * then check both for new clients that connect to it.  You want to set up
181  * the socket as non-blocking in that case since else it could hang.
182  *
183  * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
184  * others it's an option.  If you pass the BIO_LISTEN_V6_ONLY it will try to
185  * create the IPv6 sockets to only listen for IPv6 connection.
186  *
187  * It could be that the first BIO_listen() call will listen to all the IPv6
188  * and IPv4 addresses and that then trying to bind to the IPv4 address will
189  * fail.  We can't tell the difference between already listening ourself to
190  * it and someone else listening to it when failing and errno is EADDRINUSE, so
191  * it's recommended to not give an error in that case if the first call was
192  * succesful.
193  *
194  * When restarting the program it could be that the port is still in use.  If
195  * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
196  * It's recommended that you use this.
197  */
198 int BIO_listen(int sock, const BIO_ADDR *addr, int options)
199 {
200     int on = 1;
201     int socktype;
202     socklen_t socktype_len = sizeof(socktype);
203
204     if (sock == -1) {
205         BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
206         return 0;
207     }
208
209     if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &socktype_len) != 0
210         || socktype_len != sizeof(socktype)) {
211         SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
212         BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
213         return 0;
214     }
215
216     if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
217         return 0;
218
219 # ifndef OPENSSL_SYS_WINDOWS
220     /* SO_REUSEADDR has different behavior on Windows than on
221      * other operating systems, don't set it there. */
222     if (options & BIO_SOCK_REUSEADDR) {
223         if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
224             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
225             BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_REUSEADDR);
226             return 0;
227         }
228     }
229 # endif
230
231     if (options & BIO_SOCK_KEEPALIVE) {
232         if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
233             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
234             BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
235             return 0;
236         }
237     }
238
239     if (options & BIO_SOCK_NODELAY) {
240         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
241             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
242             BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
243             return 0;
244         }
245     }
246
247 # ifdef IPV6_V6ONLY
248     if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) {
249         if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) != 0) {
250             SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
251             BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
252             return 0;
253         }
254     }
255 # endif
256
257     if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
258         SYSerr(SYS_F_BIND, get_last_socket_error());
259         BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_BIND_SOCKET);
260         return 0;
261     }
262
263     if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
264         SYSerr(SYS_F_LISTEN, get_last_socket_error());
265         BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
266         return 0;
267     }
268
269     return 1;
270 }
271
272 /*-
273  * BIO_accept_ex - Accept new incoming connections
274  * @sock: the listening socket
275  * @addr: the BIO_ADDR to store the peer address in
276  * @options: BIO socket options, applied on the accepted socket.
277  *
278  */
279 int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
280 {
281     socklen_t len;
282     int accepted_sock;
283     BIO_ADDR locaddr;
284     BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
285
286     len = sizeof(*addr);
287     accepted_sock = accept(accept_sock,
288                            BIO_ADDR_sockaddr_noconst(addr), &len);
289     if (accepted_sock == -1) {
290         if (!BIO_sock_should_retry(accepted_sock)) {
291             SYSerr(SYS_F_ACCEPT, get_last_socket_error());
292             BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
293         }
294         return INVALID_SOCKET;
295     }
296
297     if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
298         closesocket(accepted_sock);
299         return INVALID_SOCKET;
300     }
301
302     return accepted_sock;
303 }
304
305 /*-
306  * BIO_closesocket - Close a socket
307  * @sock: the socket to close
308  */
309 int BIO_closesocket(int sock)
310 {
311     if (closesocket(sock) < 0)
312         return 0;
313     return 1;
314 }
315 #endif