Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
net_sockets.c
00001 /* 00002 * TCP/IP or UDP/IP networking functions 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 /* Enable definition of getaddrinfo() even when compiling with -std=c99. Must 00023 * be set before config.h, which pulls in glibc's features.h indirectly. 00024 * Harmless on other platforms. */ 00025 #define _POSIX_C_SOURCE 200112L 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_NET_C) 00034 00035 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ 00036 !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ 00037 !defined(__HAIKU__) 00038 #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" 00039 #endif 00040 00041 #if defined(MBEDTLS_PLATFORM_C) 00042 #include "mbedtls/platform.h" 00043 #else 00044 #include <stdlib.h> 00045 #endif 00046 00047 #include "mbedtls/net_sockets.h" 00048 00049 #include <string.h> 00050 00051 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ 00052 !defined(EFI32) 00053 00054 #define IS_EINTR( ret ) ( ( ret ) == WSAEINTR ) 00055 00056 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) 00057 #undef _WIN32_WINNT 00058 /* Enables getaddrinfo() & Co */ 00059 #define _WIN32_WINNT 0x0501 00060 #endif 00061 00062 #include <ws2tcpip.h> 00063 00064 #include <winsock2.h> 00065 #include <windows.h> 00066 00067 #if defined(_MSC_VER) 00068 #if defined(_WIN32_WCE) 00069 #pragma comment( lib, "ws2.lib" ) 00070 #else 00071 #pragma comment( lib, "ws2_32.lib" ) 00072 #endif 00073 #endif /* _MSC_VER */ 00074 00075 #define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 ) 00076 #define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 ) 00077 #define close(fd) closesocket(fd) 00078 00079 static int wsa_init_done = 0; 00080 00081 #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ 00082 00083 #include <sys/types.h> 00084 #include <sys/socket.h> 00085 #include <netinet/in.h> 00086 #include <arpa/inet.h> 00087 #include <sys/time.h> 00088 #include <unistd.h> 00089 #include <signal.h> 00090 #include <fcntl.h> 00091 #include <netdb.h> 00092 #include <errno.h> 00093 00094 #define IS_EINTR( ret ) ( ( ret ) == EINTR ) 00095 00096 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ 00097 00098 /* Some MS functions want int and MSVC warns if we pass size_t, 00099 * but the standard functions use socklen_t, so cast only for MSVC */ 00100 #if defined(_MSC_VER) 00101 #define MSVC_INT_CAST (int) 00102 #else 00103 #define MSVC_INT_CAST 00104 #endif 00105 00106 #include <stdio.h> 00107 00108 #include <time.h> 00109 00110 #include <stdint.h> 00111 00112 /* 00113 * Prepare for using the sockets interface 00114 */ 00115 static int net_prepare( void ) 00116 { 00117 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00118 !defined(EFI32) 00119 WSADATA wsaData; 00120 00121 if( wsa_init_done == 0 ) 00122 { 00123 if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) 00124 return( MBEDTLS_ERR_NET_SOCKET_FAILED ); 00125 00126 wsa_init_done = 1; 00127 } 00128 #else 00129 #if !defined(EFIX64) && !defined(EFI32) 00130 signal( SIGPIPE, SIG_IGN ); 00131 #endif 00132 #endif 00133 return( 0 ); 00134 } 00135 00136 /* 00137 * Initialize a context 00138 */ 00139 void mbedtls_net_init( mbedtls_net_context *ctx ) 00140 { 00141 ctx->fd = -1; 00142 } 00143 00144 /* 00145 * Initiate a TCP connection with host:port and the given protocol 00146 */ 00147 int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, 00148 const char *port, int proto ) 00149 { 00150 int ret; 00151 struct addrinfo hints, *addr_list, *cur; 00152 00153 if( ( ret = net_prepare() ) != 0 ) 00154 return( ret ); 00155 00156 /* Do name resolution with both IPv6 and IPv4 */ 00157 memset( &hints, 0, sizeof( hints ) ); 00158 hints.ai_family = AF_UNSPEC; 00159 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; 00160 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; 00161 00162 if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) 00163 return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); 00164 00165 /* Try the sockaddrs until a connection succeeds */ 00166 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; 00167 for( cur = addr_list; cur != NULL; cur = cur->ai_next ) 00168 { 00169 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, 00170 cur->ai_protocol ); 00171 if( ctx->fd < 0 ) 00172 { 00173 ret = MBEDTLS_ERR_NET_SOCKET_FAILED; 00174 continue; 00175 } 00176 00177 if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 ) 00178 { 00179 ret = 0; 00180 break; 00181 } 00182 00183 close( ctx->fd ); 00184 ret = MBEDTLS_ERR_NET_CONNECT_FAILED; 00185 } 00186 00187 freeaddrinfo( addr_list ); 00188 00189 return( ret ); 00190 } 00191 00192 /* 00193 * Create a listening socket on bind_ip:port 00194 */ 00195 int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ) 00196 { 00197 int n, ret; 00198 struct addrinfo hints, *addr_list, *cur; 00199 00200 if( ( ret = net_prepare() ) != 0 ) 00201 return( ret ); 00202 00203 /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ 00204 memset( &hints, 0, sizeof( hints ) ); 00205 hints.ai_family = AF_UNSPEC; 00206 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; 00207 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; 00208 if( bind_ip == NULL ) 00209 hints.ai_flags = AI_PASSIVE; 00210 00211 if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) 00212 return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); 00213 00214 /* Try the sockaddrs until a binding succeeds */ 00215 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; 00216 for( cur = addr_list; cur != NULL; cur = cur->ai_next ) 00217 { 00218 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, 00219 cur->ai_protocol ); 00220 if( ctx->fd < 0 ) 00221 { 00222 ret = MBEDTLS_ERR_NET_SOCKET_FAILED; 00223 continue; 00224 } 00225 00226 n = 1; 00227 if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR, 00228 (const char *) &n, sizeof( n ) ) != 0 ) 00229 { 00230 close( ctx->fd ); 00231 ret = MBEDTLS_ERR_NET_SOCKET_FAILED; 00232 continue; 00233 } 00234 00235 if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 ) 00236 { 00237 close( ctx->fd ); 00238 ret = MBEDTLS_ERR_NET_BIND_FAILED; 00239 continue; 00240 } 00241 00242 /* Listen only makes sense for TCP */ 00243 if( proto == MBEDTLS_NET_PROTO_TCP ) 00244 { 00245 if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) 00246 { 00247 close( ctx->fd ); 00248 ret = MBEDTLS_ERR_NET_LISTEN_FAILED; 00249 continue; 00250 } 00251 } 00252 00253 /* Bind was successful */ 00254 ret = 0; 00255 break; 00256 } 00257 00258 freeaddrinfo( addr_list ); 00259 00260 return( ret ); 00261 00262 } 00263 00264 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00265 !defined(EFI32) 00266 /* 00267 * Check if the requested operation would be blocking on a non-blocking socket 00268 * and thus 'failed' with a negative return value. 00269 */ 00270 static int net_would_block( const mbedtls_net_context *ctx ) 00271 { 00272 ((void) ctx); 00273 return( WSAGetLastError() == WSAEWOULDBLOCK ); 00274 } 00275 #else 00276 /* 00277 * Check if the requested operation would be blocking on a non-blocking socket 00278 * and thus 'failed' with a negative return value. 00279 * 00280 * Note: on a blocking socket this function always returns 0! 00281 */ 00282 static int net_would_block( const mbedtls_net_context *ctx ) 00283 { 00284 int err = errno; 00285 00286 /* 00287 * Never return 'WOULD BLOCK' on a blocking socket 00288 */ 00289 if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) 00290 { 00291 errno = err; 00292 return( 0 ); 00293 } 00294 00295 switch( errno = err ) 00296 { 00297 #if defined EAGAIN 00298 case EAGAIN: 00299 #endif 00300 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN 00301 case EWOULDBLOCK: 00302 #endif 00303 return( 1 ); 00304 } 00305 return( 0 ); 00306 } 00307 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ 00308 00309 /* 00310 * Accept a connection from a remote client 00311 */ 00312 int mbedtls_net_accept( mbedtls_net_context *bind_ctx, 00313 mbedtls_net_context *client_ctx, 00314 void *client_ip, size_t buf_size, size_t *ip_len ) 00315 { 00316 int ret; 00317 int type; 00318 00319 struct sockaddr_storage client_addr; 00320 00321 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ 00322 defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) 00323 socklen_t n = (socklen_t) sizeof( client_addr ); 00324 socklen_t type_len = (socklen_t) sizeof( type ); 00325 #else 00326 int n = (int) sizeof( client_addr ); 00327 int type_len = (int) sizeof( type ); 00328 #endif 00329 00330 /* Is this a TCP or UDP socket? */ 00331 if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, 00332 (void *) &type, &type_len ) != 0 || 00333 ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) 00334 { 00335 return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); 00336 } 00337 00338 if( type == SOCK_STREAM ) 00339 { 00340 /* TCP: actual accept() */ 00341 ret = client_ctx->fd = (int) accept( bind_ctx->fd, 00342 (struct sockaddr *) &client_addr, &n ); 00343 } 00344 else 00345 { 00346 /* UDP: wait for a message, but keep it in the queue */ 00347 char buf[1] = { 0 }; 00348 00349 ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, 00350 (struct sockaddr *) &client_addr, &n ); 00351 00352 #if defined(_WIN32) 00353 if( ret == SOCKET_ERROR && 00354 WSAGetLastError() == WSAEMSGSIZE ) 00355 { 00356 /* We know buf is too small, thanks, just peeking here */ 00357 ret = 0; 00358 } 00359 #endif 00360 } 00361 00362 if( ret < 0 ) 00363 { 00364 if( net_would_block( bind_ctx ) != 0 ) 00365 return( MBEDTLS_ERR_SSL_WANT_READ ); 00366 00367 return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); 00368 } 00369 00370 /* UDP: hijack the listening socket to communicate with the client, 00371 * then bind a new socket to accept new connections */ 00372 if( type != SOCK_STREAM ) 00373 { 00374 struct sockaddr_storage local_addr; 00375 int one = 1; 00376 00377 if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) 00378 return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); 00379 00380 client_ctx->fd = bind_ctx->fd; 00381 bind_ctx->fd = -1; /* In case we exit early */ 00382 00383 n = sizeof( struct sockaddr_storage ); 00384 if( getsockname( client_ctx->fd, 00385 (struct sockaddr *) &local_addr, &n ) != 0 || 00386 ( bind_ctx->fd = (int) socket( local_addr.ss_family, 00387 SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || 00388 setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, 00389 (const char *) &one, sizeof( one ) ) != 0 ) 00390 { 00391 return( MBEDTLS_ERR_NET_SOCKET_FAILED ); 00392 } 00393 00394 if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) 00395 { 00396 return( MBEDTLS_ERR_NET_BIND_FAILED ); 00397 } 00398 } 00399 00400 if( client_ip != NULL ) 00401 { 00402 if( client_addr.ss_family == AF_INET ) 00403 { 00404 struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; 00405 *ip_len = sizeof( addr4->sin_addr.s_addr ); 00406 00407 if( buf_size < *ip_len ) 00408 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); 00409 00410 memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); 00411 } 00412 else 00413 { 00414 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; 00415 *ip_len = sizeof( addr6->sin6_addr.s6_addr ); 00416 00417 if( buf_size < *ip_len ) 00418 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); 00419 00420 memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); 00421 } 00422 } 00423 00424 return( 0 ); 00425 } 00426 00427 /* 00428 * Set the socket blocking or non-blocking 00429 */ 00430 int mbedtls_net_set_block( mbedtls_net_context *ctx ) 00431 { 00432 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00433 !defined(EFI32) 00434 u_long n = 0; 00435 return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); 00436 #else 00437 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) ); 00438 #endif 00439 } 00440 00441 int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ) 00442 { 00443 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00444 !defined(EFI32) 00445 u_long n = 1; 00446 return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); 00447 #else 00448 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) ); 00449 #endif 00450 } 00451 00452 /* 00453 * Check if data is available on the socket 00454 */ 00455 00456 int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout ) 00457 { 00458 int ret; 00459 struct timeval tv; 00460 00461 fd_set read_fds; 00462 fd_set write_fds; 00463 00464 int fd = ctx->fd; 00465 00466 if( fd < 0 ) 00467 return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 00468 00469 #if defined(__has_feature) 00470 #if __has_feature(memory_sanitizer) 00471 /* Ensure that memory sanitizers consider read_fds and write_fds as 00472 * initialized even on platforms such as Glibc/x86_64 where FD_ZERO 00473 * is implemented in assembly. */ 00474 memset( &read_fds, 0, sizeof( read_fds ) ); 00475 memset( &write_fds, 0, sizeof( write_fds ) ); 00476 #endif 00477 #endif 00478 00479 FD_ZERO( &read_fds ); 00480 if( rw & MBEDTLS_NET_POLL_READ ) 00481 { 00482 rw &= ~MBEDTLS_NET_POLL_READ; 00483 FD_SET( fd, &read_fds ); 00484 } 00485 00486 FD_ZERO( &write_fds ); 00487 if( rw & MBEDTLS_NET_POLL_WRITE ) 00488 { 00489 rw &= ~MBEDTLS_NET_POLL_WRITE; 00490 FD_SET( fd, &write_fds ); 00491 } 00492 00493 if( rw != 0 ) 00494 return( MBEDTLS_ERR_NET_BAD_INPUT_DATA ); 00495 00496 tv.tv_sec = timeout / 1000; 00497 tv.tv_usec = ( timeout % 1000 ) * 1000; 00498 00499 do 00500 { 00501 ret = select( fd + 1, &read_fds, &write_fds, NULL, 00502 timeout == (uint32_t) -1 ? NULL : &tv ); 00503 } 00504 while( IS_EINTR( ret ) ); 00505 00506 if( ret < 0 ) 00507 return( MBEDTLS_ERR_NET_POLL_FAILED ); 00508 00509 ret = 0; 00510 if( FD_ISSET( fd, &read_fds ) ) 00511 ret |= MBEDTLS_NET_POLL_READ; 00512 if( FD_ISSET( fd, &write_fds ) ) 00513 ret |= MBEDTLS_NET_POLL_WRITE; 00514 00515 return( ret ); 00516 } 00517 00518 /* 00519 * Portable usleep helper 00520 */ 00521 void mbedtls_net_usleep( unsigned long usec ) 00522 { 00523 #if defined(_WIN32) 00524 Sleep( ( usec + 999 ) / 1000 ); 00525 #else 00526 struct timeval tv; 00527 tv.tv_sec = usec / 1000000; 00528 #if defined(__unix__) || defined(__unix) || \ 00529 ( defined(__APPLE__) && defined(__MACH__) ) 00530 tv.tv_usec = (suseconds_t) usec % 1000000; 00531 #else 00532 tv.tv_usec = usec % 1000000; 00533 #endif 00534 select( 0, NULL, NULL, NULL, &tv ); 00535 #endif 00536 } 00537 00538 /* 00539 * Read at most 'len' characters 00540 */ 00541 int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) 00542 { 00543 int ret; 00544 int fd = ((mbedtls_net_context *) ctx)->fd; 00545 00546 if( fd < 0 ) 00547 return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 00548 00549 ret = (int) read( fd, buf, len ); 00550 00551 if( ret < 0 ) 00552 { 00553 if( net_would_block( ctx ) != 0 ) 00554 return( MBEDTLS_ERR_SSL_WANT_READ ); 00555 00556 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00557 !defined(EFI32) 00558 if( WSAGetLastError() == WSAECONNRESET ) 00559 return( MBEDTLS_ERR_NET_CONN_RESET ); 00560 #else 00561 if( errno == EPIPE || errno == ECONNRESET ) 00562 return( MBEDTLS_ERR_NET_CONN_RESET ); 00563 00564 if( errno == EINTR ) 00565 return( MBEDTLS_ERR_SSL_WANT_READ ); 00566 #endif 00567 00568 return( MBEDTLS_ERR_NET_RECV_FAILED ); 00569 } 00570 00571 return( ret ); 00572 } 00573 00574 /* 00575 * Read at most 'len' characters, blocking for at most 'timeout' ms 00576 */ 00577 int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, 00578 size_t len, uint32_t timeout ) 00579 { 00580 int ret; 00581 struct timeval tv; 00582 fd_set read_fds; 00583 int fd = ((mbedtls_net_context *) ctx)->fd; 00584 00585 if( fd < 0 ) 00586 return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 00587 00588 FD_ZERO( &read_fds ); 00589 FD_SET( fd, &read_fds ); 00590 00591 tv.tv_sec = timeout / 1000; 00592 tv.tv_usec = ( timeout % 1000 ) * 1000; 00593 00594 ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); 00595 00596 /* Zero fds ready means we timed out */ 00597 if( ret == 0 ) 00598 return( MBEDTLS_ERR_SSL_TIMEOUT ); 00599 00600 if( ret < 0 ) 00601 { 00602 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00603 !defined(EFI32) 00604 if( WSAGetLastError() == WSAEINTR ) 00605 return( MBEDTLS_ERR_SSL_WANT_READ ); 00606 #else 00607 if( errno == EINTR ) 00608 return( MBEDTLS_ERR_SSL_WANT_READ ); 00609 #endif 00610 00611 return( MBEDTLS_ERR_NET_RECV_FAILED ); 00612 } 00613 00614 /* This call will not block */ 00615 return( mbedtls_net_recv( ctx, buf, len ) ); 00616 } 00617 00618 /* 00619 * Write at most 'len' characters 00620 */ 00621 int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) 00622 { 00623 int ret; 00624 int fd = ((mbedtls_net_context *) ctx)->fd; 00625 00626 if( fd < 0 ) 00627 return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 00628 00629 ret = (int) write( fd, buf, len ); 00630 00631 if( ret < 0 ) 00632 { 00633 if( net_would_block( ctx ) != 0 ) 00634 return( MBEDTLS_ERR_SSL_WANT_WRITE ); 00635 00636 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 00637 !defined(EFI32) 00638 if( WSAGetLastError() == WSAECONNRESET ) 00639 return( MBEDTLS_ERR_NET_CONN_RESET ); 00640 #else 00641 if( errno == EPIPE || errno == ECONNRESET ) 00642 return( MBEDTLS_ERR_NET_CONN_RESET ); 00643 00644 if( errno == EINTR ) 00645 return( MBEDTLS_ERR_SSL_WANT_WRITE ); 00646 #endif 00647 00648 return( MBEDTLS_ERR_NET_SEND_FAILED ); 00649 } 00650 00651 return( ret ); 00652 } 00653 00654 /* 00655 * Close the connection 00656 */ 00657 void mbedtls_net_close( mbedtls_net_context *ctx ) 00658 { 00659 if( ctx->fd == -1 ) 00660 return; 00661 00662 close( ctx->fd ); 00663 00664 ctx->fd = -1; 00665 } 00666 00667 /* 00668 * Gracefully close the connection 00669 */ 00670 void mbedtls_net_free( mbedtls_net_context *ctx ) 00671 { 00672 if( ctx->fd == -1 ) 00673 return; 00674 00675 shutdown( ctx->fd, 2 ); 00676 close( ctx->fd ); 00677 00678 ctx->fd = -1; 00679 } 00680 00681 #endif /* MBEDTLS_NET_C */
Generated on Tue Jul 12 2022 13:54:37 by
