net_sockets.c 18 KB

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