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