GH601: Various spelling fixes.
[openssl.git] / crypto / bio / b_sock.c
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <errno.h>
61 #include "bio_lcl.h"
62 #if defined(NETWARE_CLIB)
63 # include <sys/ioctl.h>
64 NETDB_DEFINE_CONTEXT
65 #endif
66 #ifndef OPENSSL_NO_SOCK
67 # include <openssl/dso.h>
68 # define SOCKET_PROTOCOL IPPROTO_TCP
69 # ifdef SO_MAXCONN
70 #  define MAX_LISTEN  SO_MAXCONN
71 # elif defined(SOMAXCONN)
72 #  define MAX_LISTEN  SOMAXCONN
73 # else
74 #  define MAX_LISTEN  32
75 # endif
76 # if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
77 static int wsa_init_done = 0;
78 # endif
79
80 /*
81  * WSAAPI specifier is required to make indirect calls to run-time
82  * linked WinSock 2 functions used in this module, to be specific
83  * [get|free]addrinfo and getnameinfo. This is because WinSock uses
84  * uses non-C calling convention, __stdcall vs. __cdecl, on x86
85  * Windows. On non-WinSock platforms WSAAPI needs to be void.
86  */
87 # ifndef WSAAPI
88 #  define WSAAPI
89 # endif
90
91 # if OPENSSL_API_COMPAT < 0x10100000L
92 int BIO_get_host_ip(const char *str, unsigned char *ip)
93 {
94     BIO_ADDRINFO *res = NULL;
95     int ret = 0;
96
97     if (BIO_sock_init() != 1)
98         return 0;               /* don't generate another error code here */
99
100     if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
101         size_t l;
102
103         if (BIO_ADDRINFO_family(res) != AF_INET) {
104             BIOerr(BIO_F_BIO_GET_HOST_IP,
105                    BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
106         } else {
107             BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l);
108             /* Because only AF_INET addresses will reach this far,
109                we can assert that l should be 4 */
110             OPENSSL_assert(l == 4);
111
112             BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
113             ret = 1;
114         }
115         BIO_ADDRINFO_free(res);
116     } else {
117         ERR_add_error_data(2, "host=", str);
118     }
119
120     return ret;
121 }
122
123 int BIO_get_port(const char *str, unsigned short *port_ptr)
124 {
125     BIO_ADDRINFO *res = NULL;
126     int ret = 0;
127
128     if (str == NULL) {
129         BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
130         return (0);
131     }
132
133     if (BIO_sock_init() != 1)
134         return 0;               /* don't generate another error code here */
135
136     if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
137         if (BIO_ADDRINFO_family(res) != AF_INET) {
138             BIOerr(BIO_F_BIO_GET_PORT,
139                    BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
140         } else {
141             *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
142             ret = 1;
143         }
144         BIO_ADDRINFO_free(res);
145     } else {
146         ERR_add_error_data(2, "host=", str);
147     }
148
149     return ret;
150 }
151 # endif
152
153 int BIO_sock_error(int sock)
154 {
155     int j = 0, i;
156     socklen_t size = 0;
157
158     /*
159      * Note: under Windows the third parameter is of type (char *) whereas
160      * under other systems it is (void *) if you don't have a cast it will
161      * choke the compiler: if you do have a cast then you can either go for
162      * (char *) or (void *).
163      */
164     i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
165     if (i < 0)
166         return (1);
167     else
168         return (j);
169 }
170
171 # if OPENSSL_API_COMPAT < 0x10100000L
172 struct hostent *BIO_gethostbyname(const char *name)
173 {
174     /*
175      * Caching gethostbyname() results forever is wrong, so we have to let
176      * the true gethostbyname() worry about this
177      */
178 #  if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
179     return gethostbyname((char *)name);
180 #  else
181     return gethostbyname(name);
182 #  endif
183 }
184 # endif
185
186 int BIO_sock_init(void)
187 {
188 # ifdef OPENSSL_SYS_WINDOWS
189     static struct WSAData wsa_state;
190
191     if (!wsa_init_done) {
192         int err;
193
194         wsa_init_done = 1;
195         memset(&wsa_state, 0, sizeof(wsa_state));
196         /*
197          * Not making wsa_state available to the rest of the code is formally
198          * wrong. But the structures we use are [believed to be] invariable
199          * among Winsock DLLs, while API availability is [expected to be]
200          * probed at run-time with DSO_global_lookup.
201          */
202         if (WSAStartup(0x0202, &wsa_state) != 0) {
203             err = WSAGetLastError();
204             SYSerr(SYS_F_WSASTARTUP, err);
205             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
206             return (-1);
207         }
208     }
209 # endif                         /* OPENSSL_SYS_WINDOWS */
210 # ifdef WATT32
211     extern int _watt_do_exit;
212     _watt_do_exit = 0;          /* don't make sock_init() call exit() */
213     if (sock_init())
214         return (-1);
215 # endif
216
217 # if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
218     WORD wVerReq;
219     WSADATA wsaData;
220     int err;
221
222     if (!wsa_init_done) {
223         wsa_init_done = 1;
224         wVerReq = MAKEWORD(2, 0);
225         err = WSAStartup(wVerReq, &wsaData);
226         if (err != 0) {
227             SYSerr(SYS_F_WSASTARTUP, err);
228             BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
229             return (-1);
230         }
231     }
232 # endif
233
234     return (1);
235 }
236
237 void BIO_sock_cleanup(void)
238 {
239 # ifdef OPENSSL_SYS_WINDOWS
240     if (wsa_init_done) {
241         wsa_init_done = 0;
242         WSACleanup();
243     }
244 # elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
245     if (wsa_init_done) {
246         wsa_init_done = 0;
247         WSACleanup();
248     }
249 # endif
250 }
251
252 # if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
253
254 int BIO_socket_ioctl(int fd, long type, void *arg)
255 {
256     int i;
257
258 #  ifdef __DJGPP__
259     i = ioctlsocket(fd, type, (char *)arg);
260 #  else
261 #   if defined(OPENSSL_SYS_VMS)
262     /*-
263      * 2011-02-18 SMS.
264      * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
265      * observe that all the consumers pass in an "unsigned long *",
266      * so we arrange a local copy with a short pointer, and use
267      * that, instead.
268      */
269 #    if __INITIAL_POINTER_SIZE == 64
270 #     define ARG arg_32p
271 #     pragma pointer_size save
272 #     pragma pointer_size 32
273     unsigned long arg_32;
274     unsigned long *arg_32p;
275 #     pragma pointer_size restore
276     arg_32p = &arg_32;
277     arg_32 = *((unsigned long *)arg);
278 #    else                       /* __INITIAL_POINTER_SIZE == 64 */
279 #     define ARG arg
280 #    endif                      /* __INITIAL_POINTER_SIZE == 64 [else] */
281 #   else                        /* defined(OPENSSL_SYS_VMS) */
282 #    define ARG arg
283 #   endif                       /* defined(OPENSSL_SYS_VMS) [else] */
284
285     i = ioctlsocket(fd, type, ARG);
286 #  endif                        /* __DJGPP__ */
287     if (i < 0)
288         SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
289     return (i);
290 }
291 # endif                         /* __VMS_VER */
292
293 # if OPENSSL_API_COMPAT < 0x10100000L
294 int BIO_get_accept_socket(char *host, int bind_mode)
295 {
296     int s = INVALID_SOCKET;
297     char *h = NULL, *p = NULL;
298     BIO_ADDRINFO *res = NULL;
299
300     if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
301         return INVALID_SOCKET;
302
303     if (BIO_sock_init() != 1)
304         return INVALID_SOCKET;
305
306     if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
307         goto err;
308
309     if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
310                         BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
311         s = INVALID_SOCKET;
312         goto err;
313     }
314
315     if (!BIO_listen(s, BIO_ADDRINFO_address(res),
316                     bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
317         BIO_closesocket(s);
318         s = INVALID_SOCKET;
319     }
320
321  err:
322     BIO_ADDRINFO_free(res);
323     OPENSSL_free(h);
324     OPENSSL_free(p);
325
326     return s;
327 }
328
329 int BIO_accept(int sock, char **ip_port)
330 {
331     BIO_ADDR *res = BIO_ADDR_new();
332     int ret = -1;
333
334     if (res == NULL) {
335         BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
336         return ret;
337     }
338
339     ret = BIO_accept_ex(sock, res, 0);
340
341     if (ret == (int)INVALID_SOCKET) {
342         if (BIO_sock_should_retry(ret)) {
343             ret = -2;
344             goto end;
345         }
346         SYSerr(SYS_F_ACCEPT, get_last_socket_error());
347         BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
348         goto end;
349     }
350
351     if (ip_port != NULL) {
352         char *host = BIO_ADDR_hostname_string(res, 1);
353         char *port = BIO_ADDR_service_string(res, 1);
354         *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
355         strcpy(*ip_port, host);
356         strcat(*ip_port, ":");
357         strcat(*ip_port, port);
358         OPENSSL_free(host);
359         OPENSSL_free(port);
360     }
361
362  end:
363     BIO_ADDR_free(res);
364     return ret;
365 }
366 # endif
367
368 int BIO_set_tcp_ndelay(int s, int on)
369 {
370     int ret = 0;
371 # if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
372     int opt;
373
374 #  ifdef SOL_TCP
375     opt = SOL_TCP;
376 #  else
377 #   ifdef IPPROTO_TCP
378     opt = IPPROTO_TCP;
379 #   endif
380 #  endif
381
382     ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
383 # endif
384     return (ret == 0);
385 }
386
387 int BIO_socket_nbio(int s, int mode)
388 {
389     int ret = -1;
390     int l;
391
392     l = mode;
393 # ifdef FIONBIO
394     ret = BIO_socket_ioctl(s, FIONBIO, &l);
395 # endif
396     return (ret == 0);
397 }
398
399 int BIO_sock_info(int sock,
400                   enum BIO_sock_info_type type, union BIO_sock_info_u *info)
401 {
402     switch (type) {
403     case BIO_SOCK_INFO_ADDRESS:
404         {
405             socklen_t addr_len;
406             int ret = 0;
407             addr_len = sizeof(*info->addr);
408             ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
409                               &addr_len);
410             if (ret == -1) {
411                 SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
412                 BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
413                 return 0;
414             }
415             if (addr_len > sizeof(*info->addr)) {
416                 BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
417                 return 0;
418             }
419         }
420         break;
421     default:
422         BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
423         return 0;
424     }
425     return 1;
426 }
427
428 #endif