From 02cc56af509452479d13280872b1d36fabc5c0a1 Mon Sep 17 00:00:00 2001 From: dongheng Date: Mon, 3 Jun 2019 19:47:25 +0800 Subject: [PATCH] fix(aws): fix AWS read timeout error The behave that set socket timeout is error, it will lead to a socket I/O error to mbedTLS. --- .../aws_iot/port/network_mbedtls_wrapper.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/components/aws_iot/port/network_mbedtls_wrapper.c b/components/aws_iot/port/network_mbedtls_wrapper.c index 332749d6..be33fdb7 100644 --- a/components/aws_iot/port/network_mbedtls_wrapper.c +++ b/components/aws_iot/port/network_mbedtls_wrapper.c @@ -165,18 +165,32 @@ IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Tim } while (len > 0) { - /* Make sure we never block on read for longer than timer has left, - but also that we don't block indefinitely (ie read_timeout > 0) */ - read_timeout = MAX(1, MIN(read_timeout, left_ms(timer))); - timeout.tv_sec = read_timeout / 1000; - timeout.tv_usec = (read_timeout % 1000) * 1000; + if (esp_tls_get_bytes_avail(tls) <= 0) { + fd_set read_fs, error_fs; + + /* Make sure we never block on read for longer than timer has left, + but also that we don't block indefinitely (ie read_timeout > 0) */ + read_timeout = MAX(1, MIN(read_timeout, left_ms(timer))); + timeout.tv_sec = read_timeout / 1000; + timeout.tv_usec = (read_timeout % 1000) * 1000; + + FD_CLR(tls->sockfd, &read_fs); + FD_CLR(tls->sockfd, &error_fs); + + FD_SET(tls->sockfd, &read_fs); + FD_SET(tls->sockfd, &error_fs); + + ret = select(tls->sockfd + 1, &read_fs, NULL, &error_fs, &timeout); + if (!ret) + goto check_time; + else if (ret < 0) + return NETWORK_SSL_READ_ERROR; + + if (FD_ISSET(tls->sockfd, &error_fs)) + return NETWORK_SSL_READ_ERROR; + } - ret = setsockopt(tls->sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); ret = esp_tls_conn_read(tls, pMsg, len); - - /* Restore the old timeout */ - tlsDataParams->timeout = read_timeout; - if (ret > 0) { rxLen += ret; pMsg += ret; @@ -185,6 +199,7 @@ IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Tim return NETWORK_SSL_READ_ERROR; } +check_time: // Evaluate timeout after the read to make sure read is done at least once if (has_timer_expired(timer)) { break;