Commit fe415dde4d86822d1417a4ff90b90ace990f6f5b
1 parent
a81e00e1
Exists in
master
and in
3 other branches
Host connect now respects timeout.
Showing
5 changed files
with
71 additions
and
2 deletions
Show diff stats
src/core/host.c
| @@ -104,6 +104,7 @@ int lib3270_activate_auto_reconnect(H3270 *hSession, unsigned long msec) | @@ -104,6 +104,7 @@ int lib3270_activate_auto_reconnect(H3270 *hSession, unsigned long msec) | ||
| 104 | 104 | ||
| 105 | LIB3270_EXPORT int lib3270_disconnect(H3270 *h) | 105 | LIB3270_EXPORT int lib3270_disconnect(H3270 *h) |
| 106 | { | 106 | { |
| 107 | + debug("%s",__FUNCTION__); | ||
| 107 | return host_disconnect(h,0); | 108 | return host_disconnect(h,0); |
| 108 | } | 109 | } |
| 109 | 110 | ||
| @@ -111,6 +112,13 @@ int host_disconnect(H3270 *hSession, int failed) | @@ -111,6 +112,13 @@ int host_disconnect(H3270 *hSession, int failed) | ||
| 111 | { | 112 | { |
| 112 | CHECK_SESSION_HANDLE(hSession); | 113 | CHECK_SESSION_HANDLE(hSession); |
| 113 | 114 | ||
| 115 | + debug("%s: connected=%s half connected=%s network=%s", | ||
| 116 | + __FUNCTION__, | ||
| 117 | + (CONNECTED ? "Yes" : "No"), | ||
| 118 | + (HALF_CONNECTED ? "Yes" : "No"), | ||
| 119 | + (hSession->network.module->is_connected(hSession) ? "Active" : "Inactive") | ||
| 120 | + ); | ||
| 121 | + | ||
| 114 | if (CONNECTED || HALF_CONNECTED) | 122 | if (CONNECTED || HALF_CONNECTED) |
| 115 | { | 123 | { |
| 116 | // Disconecting, disable input | 124 | // Disconecting, disable input |
| @@ -137,6 +145,12 @@ int host_disconnect(H3270 *hSession, int failed) | @@ -137,6 +145,12 @@ int host_disconnect(H3270 *hSession, int failed) | ||
| 137 | 145 | ||
| 138 | } | 146 | } |
| 139 | 147 | ||
| 148 | + if(hSession->network.module->is_connected(hSession)) { | ||
| 149 | + | ||
| 150 | + debug("%s: Disconnecting socket", __FUNCTION__); | ||
| 151 | + | ||
| 152 | + } | ||
| 153 | + | ||
| 140 | return errno = ENOTCONN; | 154 | return errno = ENOTCONN; |
| 141 | 155 | ||
| 142 | } | 156 | } |
src/core/linux/connect.c
| @@ -54,9 +54,55 @@ | @@ -54,9 +54,55 @@ | ||
| 54 | #include <lib3270/log.h> | 54 | #include <lib3270/log.h> |
| 55 | #include <lib3270/trace.h> | 55 | #include <lib3270/trace.h> |
| 56 | #include <networking.h> | 56 | #include <networking.h> |
| 57 | +//#include <fcntl.h> | ||
| 58 | +#include <poll.h> | ||
| 57 | 59 | ||
| 58 | /*---[ Implement ]-------------------------------------------------------------------------------*/ | 60 | /*---[ Implement ]-------------------------------------------------------------------------------*/ |
| 59 | 61 | ||
| 62 | + static int sock_connect(H3270 *hSession, int sock, const struct sockaddr *address, socklen_t address_len) { | ||
| 63 | + | ||
| 64 | + lib3270_socket_set_non_blocking(hSession, sock, 1); | ||
| 65 | + | ||
| 66 | + if(!connect(sock,address,address_len)) | ||
| 67 | + return 0; | ||
| 68 | + | ||
| 69 | + if(errno != EINPROGRESS) | ||
| 70 | + return errno; | ||
| 71 | + | ||
| 72 | + unsigned int timer; | ||
| 73 | + for(timer = 0; timer < hSession->connection.timeout; timer += 10) { | ||
| 74 | + | ||
| 75 | + if(lib3270_get_connection_state(hSession) != LIB3270_CONNECTING) | ||
| 76 | + return errno = ECANCELED; | ||
| 77 | + | ||
| 78 | + struct pollfd pfd = { | ||
| 79 | + .fd = sock, | ||
| 80 | + .events = POLLOUT | ||
| 81 | + }; | ||
| 82 | + | ||
| 83 | + switch(poll(&pfd,1,10)) { | ||
| 84 | + case -1: // Poll error | ||
| 85 | + return errno; | ||
| 86 | + | ||
| 87 | + case 0: | ||
| 88 | + break; | ||
| 89 | + | ||
| 90 | + case 1: | ||
| 91 | + // Got response. | ||
| 92 | + if(pfd.revents && POLLOUT) { | ||
| 93 | + debug("%s: Connection complete",__FUNCTION__); | ||
| 94 | + return 0; | ||
| 95 | + } | ||
| 96 | + break; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + return errno = ETIMEDOUT; | ||
| 102 | + | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + | ||
| 60 | int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | 106 | int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { |
| 61 | 107 | ||
| 62 | // Reset state | 108 | // Reset state |
| @@ -90,7 +136,7 @@ | @@ -90,7 +136,7 @@ | ||
| 90 | 136 | ||
| 91 | status_connecting(hSession); | 137 | status_connecting(hSession); |
| 92 | 138 | ||
| 93 | - for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next) | 139 | + for(rp = result; sock < 0 && rp != NULL && state->syserror != ECANCELED; rp = rp->ai_next) |
| 94 | { | 140 | { |
| 95 | // Got socket from host definition. | 141 | // Got socket from host definition. |
| 96 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | 142 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); |
| @@ -102,7 +148,7 @@ | @@ -102,7 +148,7 @@ | ||
| 102 | } | 148 | } |
| 103 | 149 | ||
| 104 | // Try connect. | 150 | // Try connect. |
| 105 | - if(connect(sock, rp->ai_addr, rp->ai_addrlen)) | 151 | + if(sock_connect(hSession, sock, rp->ai_addr, rp->ai_addrlen)) |
| 106 | { | 152 | { |
| 107 | // Can't connect to host | 153 | // Can't connect to host |
| 108 | state->syserror = errno; | 154 | state->syserror = errno; |
| @@ -111,6 +157,7 @@ | @@ -111,6 +157,7 @@ | ||
| 111 | continue; | 157 | continue; |
| 112 | } | 158 | } |
| 113 | 159 | ||
| 160 | + lib3270_socket_set_non_blocking(hSession,sock,0); | ||
| 114 | } | 161 | } |
| 115 | 162 | ||
| 116 | freeaddrinfo(result); | 163 | freeaddrinfo(result); |
| @@ -203,6 +250,7 @@ | @@ -203,6 +250,7 @@ | ||
| 203 | 250 | ||
| 204 | // Initialize and connect to host | 251 | // Initialize and connect to host |
| 205 | set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | 252 | set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); |
| 253 | + lib3270_set_cstate(hSession,LIB3270_CONNECTING); | ||
| 206 | 254 | ||
| 207 | if(lib3270_run_task(hSession, (int(*)(H3270 *, void *)) hSession->network.module->connect, &state)) | 255 | if(lib3270_run_task(hSession, (int(*)(H3270 *, void *)) hSession->network.module->connect, &state)) |
| 208 | { | 256 | { |
src/core/session.c
| @@ -328,6 +328,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char | @@ -328,6 +328,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char | ||
| 328 | hSession->onlcr = 1; | 328 | hSession->onlcr = 1; |
| 329 | hSession->model_num = -1; | 329 | hSession->model_num = -1; |
| 330 | hSession->connection.state = LIB3270_NOT_CONNECTED; | 330 | hSession->connection.state = LIB3270_NOT_CONNECTED; |
| 331 | + hSession->connection.timeout = 10000; | ||
| 331 | hSession->oia.status = LIB3270_MESSAGE_DISCONNECTED; | 332 | hSession->oia.status = LIB3270_MESSAGE_DISCONNECTED; |
| 332 | hSession->kybdlock = KL_NOT_CONNECTED; | 333 | hSession->kybdlock = KL_NOT_CONNECTED; |
| 333 | hSession->aid = AID_NO; | 334 | hSession->aid = AID_NO; |
src/include/internals.h
| @@ -337,6 +337,7 @@ struct _h3270 | @@ -337,6 +337,7 @@ struct _h3270 | ||
| 337 | // Connection info | 337 | // Connection info |
| 338 | struct { | 338 | struct { |
| 339 | LIB3270_CSTATE state; ///< @brief Connection state. | 339 | LIB3270_CSTATE state; ///< @brief Connection state. |
| 340 | + unsigned int timeout; ///< @brief Connection timeout (1000 = 1s) | ||
| 340 | } connection; | 341 | } connection; |
| 341 | 342 | ||
| 342 | // flags | 343 | // flags |
src/network_modules/openssl/main.c
| @@ -57,6 +57,8 @@ static int openssl_network_disconnect(H3270 *hSession) { | @@ -57,6 +57,8 @@ static int openssl_network_disconnect(H3270 *hSession) { | ||
| 57 | 57 | ||
| 58 | LIB3270_NET_CONTEXT * context = hSession->network.context; | 58 | LIB3270_NET_CONTEXT * context = hSession->network.context; |
| 59 | 59 | ||
| 60 | + debug("%s",__FUNCTION__); | ||
| 61 | + | ||
| 60 | if(context->con) { | 62 | if(context->con) { |
| 61 | SSL_shutdown(context->con); | 63 | SSL_shutdown(context->con); |
| 62 | SSL_free(context->con); | 64 | SSL_free(context->con); |
| @@ -190,6 +192,7 @@ static int openssl_network_non_blocking(H3270 *hSession, const unsigned char on) | @@ -190,6 +192,7 @@ static int openssl_network_non_blocking(H3270 *hSession, const unsigned char on) | ||
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | static int openssl_network_is_connected(const H3270 *hSession) { | 194 | static int openssl_network_is_connected(const H3270 *hSession) { |
| 195 | + debug("%s: %s",__FUNCTION__, (hSession->network.context->sock > 0 ? "True" : "False")) | ||
| 193 | return hSession->network.context->sock > 0; | 196 | return hSession->network.context->sock > 0; |
| 194 | } | 197 | } |
| 195 | 198 | ||
| @@ -272,6 +275,8 @@ static int openssl_network_init(H3270 *hSession) { | @@ -272,6 +275,8 @@ static int openssl_network_init(H3270 *hSession) { | ||
| 272 | 275 | ||
| 273 | static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | 276 | static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { |
| 274 | 277 | ||
| 278 | + debug("%s",__FUNCTION__); | ||
| 279 | + | ||
| 275 | LIB3270_NET_CONTEXT * context = hSession->network.context; | 280 | LIB3270_NET_CONTEXT * context = hSession->network.context; |
| 276 | 281 | ||
| 277 | if(context->crl.cert) { | 282 | if(context->crl.cert) { |