Skip to content

Commit

Permalink
tcp_transport: Implement connect timeout
Browse files Browse the repository at this point in the history
Merges #3791
Closes #5004
  • Loading branch information
boarchuz authored and david-cermak committed May 5, 2020
1 parent ce2a99d commit 0c7204e
Showing 1 changed file with 52 additions and 6 deletions.
58 changes: 52 additions & 6 deletions components/tcp_transport/transport_tcp.c
Expand Up @@ -81,14 +81,60 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));

ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...",
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) {
close(tcp->sock);
tcp->sock = -1;
return -1;
// Set socket to non-blocking
int flags;
if ((flags = fcntl(tcp->sock, F_GETFL, NULL)) < 0 || fcntl(tcp->sock, F_SETFL, flags |= O_NONBLOCK) < 0) {
ESP_LOGE(TAG, "[sock=%d] set nonblocking error: %s", tcp->sock, strerror(errno));
goto error;
}

ESP_LOGD(TAG, "[sock=%d] Connecting to server. IP: %s, Port: %d",
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);

if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) < 0) {
if (errno == EINPROGRESS) {
fd_set fdset;

esp_transport_utils_ms_to_timeval(timeout_ms, &tv);
FD_ZERO(&fdset);
FD_SET(tcp->sock, &fdset);

int res = select(tcp->sock+1, NULL, &fdset, NULL, &tv);
if (res < 0) {
ESP_LOGE(TAG, "[sock=%d] select() error: %s", tcp->sock, strerror(errno));
goto error;
}
else if (res == 0) {
ESP_LOGE(TAG, "[sock=%d] select() timeout", tcp->sock);
goto error;
} else {
int sockerr;
socklen_t len = (socklen_t)sizeof(int);

if (getsockopt(tcp->sock, SOL_SOCKET, SO_ERROR, (void*)(&sockerr), &len) < 0) {
ESP_LOGE(TAG, "[sock=%d] getsockopt() error: %s", tcp->sock, strerror(errno));
goto error;
}
else if (sockerr) {
ESP_LOGE(TAG, "[sock=%d] delayed connect error: %s", tcp->sock, strerror(sockerr));
goto error;
}
}
} else {
ESP_LOGE(TAG, "[sock=%d] connect() error: %s", tcp->sock, strerror(errno));
goto error;
}
}
// Reset socket to blocking
if ((flags = fcntl(tcp->sock, F_GETFL, NULL)) < 0 || fcntl(tcp->sock, F_SETFL, flags & ~O_NONBLOCK) < 0) {
ESP_LOGE(TAG, "[sock=%d] reset blocking error: %s", tcp->sock, strerror(errno));
goto error;
}
return tcp->sock;
error:
close(tcp->sock);
tcp->sock = -1;
return -1;
}

static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)
Expand Down

0 comments on commit 0c7204e

Please sign in to comment.