From 5bce13c1fd5dafafb383883f016cfa3762b730f5 Mon Sep 17 00:00:00 2001 From: Bui Nguyen Quoc Thanh <49302843+thanhbnq@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:22:59 +0700 Subject: dlt_client:Block in connect() (#409) Connect TCP socket with non-blocking socket Check errno and getsockopt to guarantee that the socket connection is established successfully Signed-off-by: Le Tin Signed-off-by: Le Tin --- src/lib/dlt_client.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c index 174cfa0..245ebef 100644 --- a/src/lib/dlt_client.c +++ b/src/lib/dlt_client.c @@ -91,6 +91,7 @@ #include /* for strlen(), memcmp(), memmove() */ #include #include +#include #include "dlt_types.h" #include "dlt_client.h" @@ -171,13 +172,19 @@ DltReturnValue dlt_client_init(DltClient *client, int verbose) DltReturnValue dlt_client_connect(DltClient *client, int verbose) { const int yes = 1; - char portnumbuffer[33]; + char portnumbuffer[33] = {0}; struct addrinfo hints, *servinfo, *p; struct sockaddr_un addr; int rv; struct ip_mreq mreq; DltReceiverType receiver_type = DLT_RECEIVE_FD; + struct pollfd pfds[1]; + int ret; + int n; + socklen_t m = sizeof(n); + int connect_errno = 0; + memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; @@ -205,27 +212,80 @@ DltReturnValue dlt_client_connect(DltClient *client, int verbose) continue; } - if (connect(client->sock, p->ai_addr, p->ai_addrlen) < 0) { + /* Set socket to Non-blocking mode */ + if(fcntl(client->sock, F_SETFL, fcntl(client->sock,F_GETFL,0) | O_NONBLOCK) < 0) + { + dlt_vlog(LOG_WARNING, + "%s: Socket cannot be changed to NON BLOCK: %s\n", + __func__, strerror(errno)); close(client->sock); continue; } + if (connect(client->sock, p->ai_addr, p->ai_addrlen) < 0) { + if (errno == EINPROGRESS) { + pfds[0].fd = client->sock; + pfds[0].events = POLLOUT; + ret = poll(pfds, 1, 500); + if (ret < 0) { + dlt_vlog(LOG_ERR, "%s: Failed to poll with err [%s]\n", + __func__, strerror(errno)); + close(client->sock); + continue; + } + else if ((pfds[0].revents & POLLOUT) && + getsockopt(client->sock, SOL_SOCKET, + SO_ERROR, (void*)&n, &m) == 0) { + if (n == 0) { + dlt_vlog(LOG_DEBUG, "%s: Already connect\n", __func__); + if(fcntl(client->sock, F_SETFL, + fcntl(client->sock,F_GETFL,0) & ~O_NONBLOCK) < 0) { + dlt_vlog(LOG_WARNING, + "%s: Socket cannot be changed to BLOCK with err [%s]\n", + __func__, strerror(errno)); + close(client->sock); + continue; + } + } + else { + connect_errno = n; + close(client->sock); + continue; + } + } + else { + connect_errno = errno; + close(client->sock); + continue; + } + } + else { + connect_errno = errno; + close(client->sock); + continue; + } + } + break; } freeaddrinfo(servinfo); if (p == NULL) { + dlt_vlog(LOG_ERR, + "%s: ERROR: failed to connect! %s\n", + __func__, + strerror(connect_errno)); + return DLT_RETURN_ERROR; + } + + if (verbose) { dlt_vlog(LOG_INFO, "%s: Connected to DLT daemon (%s)\n", __func__, client->servIP); - return DLT_RETURN_ERROR; } - if (verbose) - printf("Connected to DLT daemon (%s)\n", client->servIP); - receiver_type = DLT_RECEIVE_SOCKET; break; -- cgit v1.2.1