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