Commit fe415dde4d86822d1417a4ff90b90ace990f6f5b

Authored by Perry Werneck
1 parent a81e00e1

Host connect now respects timeout.

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
... ... @@ -337,6 +337,7 @@ struct _h3270
337 337 // Connection info
338 338 struct {
339 339 LIB3270_CSTATE state; ///< @brief Connection state.
  340 + unsigned int timeout; ///< @brief Connection timeout (1000 = 1s)
340 341 } connection;
341 342  
342 343 // flags
... ...
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) {
... ...