From fe415dde4d86822d1417a4ff90b90ace990f6f5b Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 6 Aug 2020 23:48:01 -0300 Subject: [PATCH] Host connect now respects timeout. --- src/core/host.c | 14 ++++++++++++++ src/core/linux/connect.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/core/session.c | 1 + src/include/internals.h | 1 + src/network_modules/openssl/main.c | 5 +++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/core/host.c b/src/core/host.c index 136656b..2c2d2f5 100644 --- a/src/core/host.c +++ b/src/core/host.c @@ -104,6 +104,7 @@ int lib3270_activate_auto_reconnect(H3270 *hSession, unsigned long msec) LIB3270_EXPORT int lib3270_disconnect(H3270 *h) { + debug("%s",__FUNCTION__); return host_disconnect(h,0); } @@ -111,6 +112,13 @@ int host_disconnect(H3270 *hSession, int failed) { CHECK_SESSION_HANDLE(hSession); + debug("%s: connected=%s half connected=%s network=%s", + __FUNCTION__, + (CONNECTED ? "Yes" : "No"), + (HALF_CONNECTED ? "Yes" : "No"), + (hSession->network.module->is_connected(hSession) ? "Active" : "Inactive") + ); + if (CONNECTED || HALF_CONNECTED) { // Disconecting, disable input @@ -137,6 +145,12 @@ int host_disconnect(H3270 *hSession, int failed) } + if(hSession->network.module->is_connected(hSession)) { + + debug("%s: Disconnecting socket", __FUNCTION__); + + } + return errno = ENOTCONN; } diff --git a/src/core/linux/connect.c b/src/core/linux/connect.c index 294d1cc..e0add24 100644 --- a/src/core/linux/connect.c +++ b/src/core/linux/connect.c @@ -54,9 +54,55 @@ #include #include #include +//#include +#include /*---[ Implement ]-------------------------------------------------------------------------------*/ + static int sock_connect(H3270 *hSession, int sock, const struct sockaddr *address, socklen_t address_len) { + + lib3270_socket_set_non_blocking(hSession, sock, 1); + + if(!connect(sock,address,address_len)) + return 0; + + if(errno != EINPROGRESS) + return errno; + + unsigned int timer; + for(timer = 0; timer < hSession->connection.timeout; timer += 10) { + + if(lib3270_get_connection_state(hSession) != LIB3270_CONNECTING) + return errno = ECANCELED; + + struct pollfd pfd = { + .fd = sock, + .events = POLLOUT + }; + + switch(poll(&pfd,1,10)) { + case -1: // Poll error + return errno; + + case 0: + break; + + case 1: + // Got response. + if(pfd.revents && POLLOUT) { + debug("%s: Connection complete",__FUNCTION__); + return 0; + } + break; + } + + } + + return errno = ETIMEDOUT; + + } + + int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { // Reset state @@ -90,7 +136,7 @@ status_connecting(hSession); - for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next) + for(rp = result; sock < 0 && rp != NULL && state->syserror != ECANCELED; rp = rp->ai_next) { // Got socket from host definition. sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); @@ -102,7 +148,7 @@ } // Try connect. - if(connect(sock, rp->ai_addr, rp->ai_addrlen)) + if(sock_connect(hSession, sock, rp->ai_addr, rp->ai_addrlen)) { // Can't connect to host state->syserror = errno; @@ -111,6 +157,7 @@ continue; } + lib3270_socket_set_non_blocking(hSession,sock,0); } freeaddrinfo(result); @@ -203,6 +250,7 @@ // Initialize and connect to host set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); + lib3270_set_cstate(hSession,LIB3270_CONNECTING); if(lib3270_run_task(hSession, (int(*)(H3270 *, void *)) hSession->network.module->connect, &state)) { diff --git a/src/core/session.c b/src/core/session.c index 223e6f2..1e96224 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -328,6 +328,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char hSession->onlcr = 1; hSession->model_num = -1; hSession->connection.state = LIB3270_NOT_CONNECTED; + hSession->connection.timeout = 10000; hSession->oia.status = LIB3270_MESSAGE_DISCONNECTED; hSession->kybdlock = KL_NOT_CONNECTED; hSession->aid = AID_NO; diff --git a/src/include/internals.h b/src/include/internals.h index a9b1118..7d95aa8 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -337,6 +337,7 @@ struct _h3270 // Connection info struct { LIB3270_CSTATE state; ///< @brief Connection state. + unsigned int timeout; ///< @brief Connection timeout (1000 = 1s) } connection; // flags diff --git a/src/network_modules/openssl/main.c b/src/network_modules/openssl/main.c index fbac266..7e2c919 100644 --- a/src/network_modules/openssl/main.c +++ b/src/network_modules/openssl/main.c @@ -57,6 +57,8 @@ static int openssl_network_disconnect(H3270 *hSession) { LIB3270_NET_CONTEXT * context = hSession->network.context; + debug("%s",__FUNCTION__); + if(context->con) { SSL_shutdown(context->con); SSL_free(context->con); @@ -190,6 +192,7 @@ static int openssl_network_non_blocking(H3270 *hSession, const unsigned char on) } static int openssl_network_is_connected(const H3270 *hSession) { + debug("%s: %s",__FUNCTION__, (hSession->network.context->sock > 0 ? "True" : "False")) return hSession->network.context->sock > 0; } @@ -272,6 +275,8 @@ static int openssl_network_init(H3270 *hSession) { static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { + debug("%s",__FUNCTION__); + LIB3270_NET_CONTEXT * context = hSession->network.context; if(context->crl.cert) { -- libgit2 0.21.2