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) { |