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 | 104 | |
| 105 | 105 | LIB3270_EXPORT int lib3270_disconnect(H3270 *h) |
| 106 | 106 | { |
| 107 | + debug("%s",__FUNCTION__); | |
| 107 | 108 | return host_disconnect(h,0); |
| 108 | 109 | } |
| 109 | 110 | |
| ... | ... | @@ -111,6 +112,13 @@ int host_disconnect(H3270 *hSession, int failed) |
| 111 | 112 | { |
| 112 | 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 | 122 | if (CONNECTED || HALF_CONNECTED) |
| 115 | 123 | { |
| 116 | 124 | // Disconecting, disable input |
| ... | ... | @@ -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 | 154 | return errno = ENOTCONN; |
| 141 | 155 | |
| 142 | 156 | } | ... | ... |
src/core/linux/connect.c
| ... | ... | @@ -54,9 +54,55 @@ |
| 54 | 54 | #include <lib3270/log.h> |
| 55 | 55 | #include <lib3270/trace.h> |
| 56 | 56 | #include <networking.h> |
| 57 | +//#include <fcntl.h> | |
| 58 | +#include <poll.h> | |
| 57 | 59 | |
| 58 | 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 | 106 | int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { |
| 61 | 107 | |
| 62 | 108 | // Reset state |
| ... | ... | @@ -90,7 +136,7 @@ |
| 90 | 136 | |
| 91 | 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 | 141 | // Got socket from host definition. |
| 96 | 142 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); |
| ... | ... | @@ -102,7 +148,7 @@ |
| 102 | 148 | } |
| 103 | 149 | |
| 104 | 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 | 153 | // Can't connect to host |
| 108 | 154 | state->syserror = errno; |
| ... | ... | @@ -111,6 +157,7 @@ |
| 111 | 157 | continue; |
| 112 | 158 | } |
| 113 | 159 | |
| 160 | + lib3270_socket_set_non_blocking(hSession,sock,0); | |
| 114 | 161 | } |
| 115 | 162 | |
| 116 | 163 | freeaddrinfo(result); |
| ... | ... | @@ -203,6 +250,7 @@ |
| 203 | 250 | |
| 204 | 251 | // Initialize and connect to host |
| 205 | 252 | set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); |
| 253 | + lib3270_set_cstate(hSession,LIB3270_CONNECTING); | |
| 206 | 254 | |
| 207 | 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 | 328 | hSession->onlcr = 1; |
| 329 | 329 | hSession->model_num = -1; |
| 330 | 330 | hSession->connection.state = LIB3270_NOT_CONNECTED; |
| 331 | + hSession->connection.timeout = 10000; | |
| 331 | 332 | hSession->oia.status = LIB3270_MESSAGE_DISCONNECTED; |
| 332 | 333 | hSession->kybdlock = KL_NOT_CONNECTED; |
| 333 | 334 | hSession->aid = AID_NO; | ... | ... |
src/include/internals.h
src/network_modules/openssl/main.c
| ... | ... | @@ -57,6 +57,8 @@ static int openssl_network_disconnect(H3270 *hSession) { |
| 57 | 57 | |
| 58 | 58 | LIB3270_NET_CONTEXT * context = hSession->network.context; |
| 59 | 59 | |
| 60 | + debug("%s",__FUNCTION__); | |
| 61 | + | |
| 60 | 62 | if(context->con) { |
| 61 | 63 | SSL_shutdown(context->con); |
| 62 | 64 | SSL_free(context->con); |
| ... | ... | @@ -190,6 +192,7 @@ static int openssl_network_non_blocking(H3270 *hSession, const unsigned char on) |
| 190 | 192 | } |
| 191 | 193 | |
| 192 | 194 | static int openssl_network_is_connected(const H3270 *hSession) { |
| 195 | + debug("%s: %s",__FUNCTION__, (hSession->network.context->sock > 0 ? "True" : "False")) | |
| 193 | 196 | return hSession->network.context->sock > 0; |
| 194 | 197 | } |
| 195 | 198 | |
| ... | ... | @@ -272,6 +275,8 @@ static int openssl_network_init(H3270 *hSession) { |
| 272 | 275 | |
| 273 | 276 | static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { |
| 274 | 277 | |
| 278 | + debug("%s",__FUNCTION__); | |
| 279 | + | |
| 275 | 280 | LIB3270_NET_CONTEXT * context = hSession->network.context; |
| 276 | 281 | |
| 277 | 282 | if(context->crl.cert) { | ... | ... |