net_sockets.c 18 KB

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