net_sockets.c 19 KB

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