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