net_sockets.c 18 KB

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