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