[LOCALSPL_WINETEST] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / dll / 3rdparty / mbedtls / net_sockets.c
1 /*
2 * TCP/IP or UDP/IP networking functions
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29
30 #if defined(MBEDTLS_NET_C)
31
32 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
33 !defined(__APPLE__) && !defined(_WIN32)
34 #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
35 #endif
36
37 #if defined(MBEDTLS_PLATFORM_C)
38 #include "mbedtls/platform.h"
39 #else
40 #include <stdlib.h>
41 #endif
42
43 #include "mbedtls/net_sockets.h"
44
45 #include <string.h>
46
47 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
48 !defined(EFI32)
49
50 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
51 #undef _WIN32_WINNT
52 /* Enables getaddrinfo() & Co */
53 #define _WIN32_WINNT 0x0501
54 #endif
55
56 #include <ws2tcpip.h>
57
58 #include <winsock2.h>
59 #include <windows.h>
60
61 #if defined(_MSC_VER)
62 #if defined(_WIN32_WCE)
63 #pragma comment( lib, "ws2.lib" )
64 #else
65 #pragma comment( lib, "ws2_32.lib" )
66 #endif
67 #endif /* _MSC_VER */
68
69 #define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 )
70 #define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 )
71 #define close(fd) closesocket(fd)
72
73 static int wsa_init_done = 0;
74
75 #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
76
77 #include <sys/types.h>
78 #include <sys/socket.h>
79 #include <netinet/in.h>
80 #include <arpa/inet.h>
81 #include <sys/time.h>
82 #include <unistd.h>
83 #include <signal.h>
84 #include <fcntl.h>
85 #include <netdb.h>
86 #include <errno.h>
87
88 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
89
90 /* Some MS functions want int and MSVC warns if we pass size_t,
91 * but the standard functions use socklen_t, so cast only for MSVC */
92 #if defined(_MSC_VER)
93 #define MSVC_INT_CAST (int)
94 #else
95 #define MSVC_INT_CAST
96 #endif
97
98 #include <stdio.h>
99
100 #include <time.h>
101
102 #include <stdint.h>
103
104 /*
105 * Prepare for using the sockets interface
106 */
107 static int net_prepare( void )
108 {
109 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
110 !defined(EFI32)
111 WSADATA wsaData;
112
113 if( wsa_init_done == 0 )
114 {
115 if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
116 return( MBEDTLS_ERR_NET_SOCKET_FAILED );
117
118 wsa_init_done = 1;
119 }
120 #else
121 #if !defined(EFIX64) && !defined(EFI32)
122 signal( SIGPIPE, SIG_IGN );
123 #endif
124 #endif
125 return( 0 );
126 }
127
128 /*
129 * Initialize a context
130 */
131 void mbedtls_net_init( mbedtls_net_context *ctx )
132 {
133 ctx->fd = -1;
134 }
135
136 /*
137 * Initiate a TCP connection with host:port and the given protocol
138 */
139 int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
140 const char *port, int proto )
141 {
142 int ret;
143 struct addrinfo hints, *addr_list, *cur;
144
145 if( ( ret = net_prepare() ) != 0 )
146 return( ret );
147
148 /* Do name resolution with both IPv6 and IPv4 */
149 memset( &hints, 0, sizeof( hints ) );
150 hints.ai_family = AF_UNSPEC;
151 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
152 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
153
154 if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
155 return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
156
157 /* Try the sockaddrs until a connection succeeds */
158 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
159 for( cur = addr_list; cur != NULL; cur = cur->ai_next )
160 {
161 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
162 cur->ai_protocol );
163 if( ctx->fd < 0 )
164 {
165 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
166 continue;
167 }
168
169 if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
170 {
171 ret = 0;
172 break;
173 }
174
175 close( ctx->fd );
176 ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
177 }
178
179 freeaddrinfo( addr_list );
180
181 return( ret );
182 }
183
184 /*
185 * Create a listening socket on bind_ip:port
186 */
187 int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
188 {
189 int n, ret;
190 struct addrinfo hints, *addr_list, *cur;
191
192 if( ( ret = net_prepare() ) != 0 )
193 return( ret );
194
195 /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
196 memset( &hints, 0, sizeof( hints ) );
197 hints.ai_family = AF_UNSPEC;
198 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
199 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
200 if( bind_ip == NULL )
201 hints.ai_flags = AI_PASSIVE;
202
203 if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
204 return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
205
206 /* Try the sockaddrs until a binding succeeds */
207 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
208 for( cur = addr_list; cur != NULL; cur = cur->ai_next )
209 {
210 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
211 cur->ai_protocol );
212 if( ctx->fd < 0 )
213 {
214 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
215 continue;
216 }
217
218 n = 1;
219 if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
220 (const char *) &n, sizeof( n ) ) != 0 )
221 {
222 close( ctx->fd );
223 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
224 continue;
225 }
226
227 if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
228 {
229 close( ctx->fd );
230 ret = MBEDTLS_ERR_NET_BIND_FAILED;
231 continue;
232 }
233
234 /* Listen only makes sense for TCP */
235 if( proto == MBEDTLS_NET_PROTO_TCP )
236 {
237 if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
238 {
239 close( ctx->fd );
240 ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
241 continue;
242 }
243 }
244
245 /* Bind was successful */
246 ret = 0;
247 break;
248 }
249
250 freeaddrinfo( addr_list );
251
252 return( ret );
253
254 }
255
256 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
257 !defined(EFI32)
258 /*
259 * Check if the requested operation would be blocking on a non-blocking socket
260 * and thus 'failed' with a negative return value.
261 */
262 static int net_would_block( const mbedtls_net_context *ctx )
263 {
264 ((void) ctx);
265 return( WSAGetLastError() == WSAEWOULDBLOCK );
266 }
267 #else
268 /*
269 * Check if the requested operation would be blocking on a non-blocking socket
270 * and thus 'failed' with a negative return value.
271 *
272 * Note: on a blocking socket this function always returns 0!
273 */
274 static int net_would_block( const mbedtls_net_context *ctx )
275 {
276 int err = errno;
277
278 /*
279 * Never return 'WOULD BLOCK' on a blocking socket
280 */
281 if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
282 {
283 errno = err;
284 return( 0 );
285 }
286
287 switch( errno = err )
288 {
289 #if defined EAGAIN
290 case EAGAIN:
291 #endif
292 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
293 case EWOULDBLOCK:
294 #endif
295 return( 1 );
296 }
297 return( 0 );
298 }
299 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
300
301 /*
302 * Accept a connection from a remote client
303 */
304 int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
305 mbedtls_net_context *client_ctx,
306 void *client_ip, size_t buf_size, size_t *ip_len )
307 {
308 int ret;
309 int type;
310
311 struct sockaddr_storage client_addr;
312
313 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
314 defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
315 socklen_t n = (socklen_t) sizeof( client_addr );
316 socklen_t type_len = (socklen_t) sizeof( type );
317 #else
318 int n = (int) sizeof( client_addr );
319 int type_len = (int) sizeof( type );
320 #endif
321
322 /* Is this a TCP or UDP socket? */
323 if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
324 (void *) &type, &type_len ) != 0 ||
325 ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
326 {
327 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
328 }
329
330 if( type == SOCK_STREAM )
331 {
332 /* TCP: actual accept() */
333 ret = client_ctx->fd = (int) accept( bind_ctx->fd,
334 (struct sockaddr *) &client_addr, &n );
335 }
336 else
337 {
338 /* UDP: wait for a message, but keep it in the queue */
339 char buf[1] = { 0 };
340
341 ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
342 (struct sockaddr *) &client_addr, &n );
343
344 #if defined(_WIN32)
345 if( ret == SOCKET_ERROR &&
346 WSAGetLastError() == WSAEMSGSIZE )
347 {
348 /* We know buf is too small, thanks, just peeking here */
349 ret = 0;
350 }
351 #endif
352 }
353
354 if( ret < 0 )
355 {
356 if( net_would_block( bind_ctx ) != 0 )
357 return( MBEDTLS_ERR_SSL_WANT_READ );
358
359 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
360 }
361
362 /* UDP: hijack the listening socket to communicate with the client,
363 * then bind a new socket to accept new connections */
364 if( type != SOCK_STREAM )
365 {
366 struct sockaddr_storage local_addr;
367 int one = 1;
368
369 if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
370 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
371
372 client_ctx->fd = bind_ctx->fd;
373 bind_ctx->fd = -1; /* In case we exit early */
374
375 n = sizeof( struct sockaddr_storage );
376 if( getsockname( client_ctx->fd,
377 (struct sockaddr *) &local_addr, &n ) != 0 ||
378 ( bind_ctx->fd = (int) socket( local_addr.ss_family,
379 SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
380 setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
381 (const char *) &one, sizeof( one ) ) != 0 )
382 {
383 return( MBEDTLS_ERR_NET_SOCKET_FAILED );
384 }
385
386 if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
387 {
388 return( MBEDTLS_ERR_NET_BIND_FAILED );
389 }
390 }
391
392 if( client_ip != NULL )
393 {
394 if( client_addr.ss_family == AF_INET )
395 {
396 struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
397 *ip_len = sizeof( addr4->sin_addr.s_addr );
398
399 if( buf_size < *ip_len )
400 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
401
402 memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
403 }
404 else
405 {
406 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
407 *ip_len = sizeof( addr6->sin6_addr.s6_addr );
408
409 if( buf_size < *ip_len )
410 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
411
412 memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
413 }
414 }
415
416 return( 0 );
417 }
418
419 /*
420 * Set the socket blocking or non-blocking
421 */
422 int mbedtls_net_set_block( mbedtls_net_context *ctx )
423 {
424 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
425 !defined(EFI32)
426 u_long n = 0;
427 return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
428 #else
429 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
430 #endif
431 }
432
433 int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
434 {
435 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
436 !defined(EFI32)
437 u_long n = 1;
438 return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
439 #else
440 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
441 #endif
442 }
443
444 /*
445 * Portable usleep helper
446 */
447 void mbedtls_net_usleep( unsigned long usec )
448 {
449 #if defined(_WIN32)
450 Sleep( ( usec + 999 ) / 1000 );
451 #else
452 struct timeval tv;
453 tv.tv_sec = usec / 1000000;
454 #if defined(__unix__) || defined(__unix) || \
455 ( defined(__APPLE__) && defined(__MACH__) )
456 tv.tv_usec = (suseconds_t) usec % 1000000;
457 #else
458 tv.tv_usec = usec % 1000000;
459 #endif
460 select( 0, NULL, NULL, NULL, &tv );
461 #endif
462 }
463
464 /*
465 * Read at most 'len' characters
466 */
467 int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
468 {
469 int ret;
470 int fd = ((mbedtls_net_context *) ctx)->fd;
471
472 if( fd < 0 )
473 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
474
475 ret = (int) read( fd, buf, len );
476
477 if( ret < 0 )
478 {
479 if( net_would_block( ctx ) != 0 )
480 return( MBEDTLS_ERR_SSL_WANT_READ );
481
482 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
483 !defined(EFI32)
484 if( WSAGetLastError() == WSAECONNRESET )
485 return( MBEDTLS_ERR_NET_CONN_RESET );
486 #else
487 if( errno == EPIPE || errno == ECONNRESET )
488 return( MBEDTLS_ERR_NET_CONN_RESET );
489
490 if( errno == EINTR )
491 return( MBEDTLS_ERR_SSL_WANT_READ );
492 #endif
493
494 return( MBEDTLS_ERR_NET_RECV_FAILED );
495 }
496
497 return( ret );
498 }
499
500 /*
501 * Read at most 'len' characters, blocking for at most 'timeout' ms
502 */
503 int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
504 uint32_t timeout )
505 {
506 int ret;
507 struct timeval tv;
508 fd_set read_fds;
509 int fd = ((mbedtls_net_context *) ctx)->fd;
510
511 if( fd < 0 )
512 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
513
514 FD_ZERO( &read_fds );
515 FD_SET( fd, &read_fds );
516
517 tv.tv_sec = timeout / 1000;
518 tv.tv_usec = ( timeout % 1000 ) * 1000;
519
520 ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
521
522 /* Zero fds ready means we timed out */
523 if( ret == 0 )
524 return( MBEDTLS_ERR_SSL_TIMEOUT );
525
526 if( ret < 0 )
527 {
528 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
529 !defined(EFI32)
530 if( WSAGetLastError() == WSAEINTR )
531 return( MBEDTLS_ERR_SSL_WANT_READ );
532 #else
533 if( errno == EINTR )
534 return( MBEDTLS_ERR_SSL_WANT_READ );
535 #endif
536
537 return( MBEDTLS_ERR_NET_RECV_FAILED );
538 }
539
540 /* This call will not block */
541 return( mbedtls_net_recv( ctx, buf, len ) );
542 }
543
544 /*
545 * Write at most 'len' characters
546 */
547 int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
548 {
549 int ret;
550 int fd = ((mbedtls_net_context *) ctx)->fd;
551
552 if( fd < 0 )
553 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
554
555 ret = (int) write( fd, buf, len );
556
557 if( ret < 0 )
558 {
559 if( net_would_block( ctx ) != 0 )
560 return( MBEDTLS_ERR_SSL_WANT_WRITE );
561
562 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
563 !defined(EFI32)
564 if( WSAGetLastError() == WSAECONNRESET )
565 return( MBEDTLS_ERR_NET_CONN_RESET );
566 #else
567 if( errno == EPIPE || errno == ECONNRESET )
568 return( MBEDTLS_ERR_NET_CONN_RESET );
569
570 if( errno == EINTR )
571 return( MBEDTLS_ERR_SSL_WANT_WRITE );
572 #endif
573
574 return( MBEDTLS_ERR_NET_SEND_FAILED );
575 }
576
577 return( ret );
578 }
579
580 /*
581 * Gracefully close the connection
582 */
583 void mbedtls_net_free( mbedtls_net_context *ctx )
584 {
585 if( ctx->fd == -1 )
586 return;
587
588 shutdown( ctx->fd, 2 );
589 close( ctx->fd );
590
591 ctx->fd = -1;
592 }
593
594 #endif /* MBEDTLS_NET_C */