Commit f4e6dc59eb1dd2d06176519d7c1772e20ac220b4

Authored by perry.werneck@gmail.com
1 parent 353fee04

Implementando novo mecanismo de conexão ao host

Showing 2 changed files with 164 additions and 187 deletions   Show diff stats
@@ -27,16 +27,127 @@ @@ -27,16 +27,127 @@
27 * 27 *
28 */ 28 */
29 29
  30 +#if defined(_WIN32)
  31 + #include <winsock2.h>
  32 + #include <windows.h>
  33 +#endif
  34 +
  35 +#include "globals.h"
  36 +#include <errno.h>
  37 +
  38 +#if defined(_WIN32)
  39 + #include <ws2tcpip.h>
  40 +#else
  41 + #include <sys/types.h>
  42 + #include <sys/socket.h>
  43 + #include <sys/ioctl.h>
  44 + #include <netinet/in.h>
  45 + #include <netdb.h>
  46 + #include <unistd.h>
  47 + #include <fcntl.h>
  48 +#endif
  49 +
  50 +
  51 +#if defined(_WIN32) /*[*/
  52 + #define SOCK_CLOSE(s) closesocket(s->sock); s->sock = -1;
  53 +#else /*][*/
  54 + #define SOCK_CLOSE(s) close(s->sock); s->sock = -1;
  55 +#endif /*]*/
  56 +
  57 +#include <stdlib.h>
  58 +#include "statusc.h"
  59 +#include "hostc.h"
  60 +#include "trace_dsc.h"
  61 +#include "utilc.h"
  62 +#include <lib3270/internals.h>
  63 +
30 /*---[ Implement ]-------------------------------------------------------------------------------*/ 64 /*---[ Implement ]-------------------------------------------------------------------------------*/
31 65
32 - LIB3270_EXPORT int lib3270_sock_connect(H3270 *hSession, const char *hostname, const char *srvc, int timeout) 66 +
  67 +static void net_connected(H3270 *hSession)
  68 +{
  69 + trace("***************** %s",__FUNCTION__);
  70 +
  71 +}
  72 +
  73 +#if defined(_WIN32) /*[*/
  74 + static void sockstart(H3270 *session)
  75 + {
  76 + static int initted = 0;
  77 + WORD wVersionRequested;
  78 + WSADATA wsaData;
  79 +
  80 + if (initted)
  81 + return;
  82 +
  83 + initted = 1;
  84 +
  85 + wVersionRequested = MAKEWORD(2, 2);
  86 +
  87 + if (WSAStartup(wVersionRequested, &wsaData) != 0)
  88 + {
  89 + lib3270_popup_dialog( session,
  90 + LIB3270_NOTIFY_CRITICAL,
  91 + N_( "Network startup error" ),
  92 + N_( "WSAStartup failed" ),
  93 + "%s", win32_strerror(GetLastError()) );
  94 +
  95 + _exit(1);
  96 + }
  97 +
  98 + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
  99 + {
  100 + lib3270_popup_dialog( session,
  101 + LIB3270_NOTIFY_CRITICAL,
  102 + N_( "Network startup error" ),
  103 + N_( "Bad winsock version" ),
  104 + N_( "Can't use winsock version %d.%d" ), LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
  105 + _exit(1);
  106 + }
  107 + }
  108 +#endif /*]*/
  109 +
  110 + static void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state)
  111 + {
  112 + if(state == hSession->secure)
  113 + return;
  114 +
  115 + trace_dsn(hSession,"SSL state changes to %d\n",(int) state);
  116 +
  117 + hSession->update_ssl(hSession,hSession->secure = state);
  118 + }
  119 +
  120 + LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc)
33 { 121 {
34 int s; 122 int s;
35 int sock = -1; 123 int sock = -1;
36 struct addrinfo hints; 124 struct addrinfo hints;
37 struct addrinfo * result = NULL; 125 struct addrinfo * result = NULL;
38 struct addrinfo * rp = NULL; 126 struct addrinfo * rp = NULL;
39 - LIB3270_MESSAGE saved_status = hSession->oia_status; 127 +
  128 + if(!hostname)
  129 + return EINVAL;
  130 +
  131 + if(!srvc)
  132 + srvc = "telnet";
  133 +
  134 + CHECK_SESSION_HANDLE(hSession);
  135 +
  136 + lib3270_main_iterate(hSession,0);
  137 +
  138 + if(hSession->auto_reconnect_inprogress)
  139 + return EAGAIN;
  140 +
  141 + if(PCONNECTED)
  142 + return EBUSY;
  143 +
  144 +#if defined(_WIN32)
  145 + sockstart(hSession);
  146 +#endif
  147 +
  148 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  149 +
  150 + hSession->ever_3270 = False;
40 151
41 memset(&hints, 0, sizeof(struct addrinfo)); 152 memset(&hints, 0, sizeof(struct addrinfo));
42 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ 153 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
@@ -47,9 +158,6 @@ @@ -47,9 +158,6 @@
47 hints.ai_addr = NULL; 158 hints.ai_addr = NULL;
48 hints.ai_next = NULL; 159 hints.ai_next = NULL;
49 160
50 - if(timeout < 0)  
51 - timeout = 10;  
52 -  
53 if(*hostname == '$') 161 if(*hostname == '$')
54 { 162 {
55 const char *name = getenv(hostname+1); 163 const char *name = getenv(hostname+1);
@@ -61,6 +169,7 @@ @@ -61,6 +169,7 @@
61 _( "Unable to find selected hostname." ), 169 _( "Unable to find selected hostname." ),
62 _( "Can't determine value for environment variable \"%s\" " ), 170 _( "Can't determine value for environment variable \"%s\" " ),
63 hostname); 171 hostname);
  172 + lib3270_set_disconnected(hSession);
64 return -1; 173 return -1;
65 } 174 }
66 hostname = name; 175 hostname = name;
@@ -79,8 +188,7 @@ @@ -79,8 +188,7 @@
79 "%s", 188 "%s",
80 gai_strerror(s)); 189 gai_strerror(s));
81 190
82 - status_changed(hSession,saved_status);  
83 - 191 + lib3270_set_disconnected(hSession);
84 return -1; 192 return -1;
85 } 193 }
86 194
@@ -88,8 +196,8 @@ @@ -88,8 +196,8 @@
88 196
89 for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next) 197 for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next)
90 { 198 {
91 - sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);  
92 - if(sock < 0) 199 + hSession->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  200 + if(hSession->sock < 0)
93 continue; 201 continue;
94 202
95 #ifdef WIN32 203 #ifdef WIN32
@@ -97,9 +205,9 @@ @@ -97,9 +205,9 @@
97 u_int len = sizeof(int); 205 u_int len = sizeof(int);
98 206
99 WSASetLastError(0); 207 WSASetLastError(0);
100 - block = 1; 208 + block = 0;
101 209
102 - if(ioctlsocket(sock,FIONBIO,&block)) 210 + if(ioctlsocket(hSession->sock,FIONBIO,&block))
103 { 211 {
104 lib3270_popup_dialog( hSession, 212 lib3270_popup_dialog( hSession,
105 LIB3270_NOTIFY_ERROR, 213 LIB3270_NOTIFY_ERROR,
@@ -107,10 +215,10 @@ @@ -107,10 +215,10 @@
107 _( "ioctlsocket(FIONBIO) failed." ), 215 _( "ioctlsocket(FIONBIO) failed." ),
108 "Windows error %d", 216 "Windows error %d",
109 WSAGetLastError() ); 217 WSAGetLastError() );
110 - close(sock);  
111 - sock = -1; 218 +
  219 + SOCK_CLOSE(hSession);
112 } 220 }
113 - else if(connect(sock, rp->ai_addr, rp->ai_addrlen)) 221 + else if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen))
114 { 222 {
115 int err = WSAGetLastError(); 223 int err = WSAGetLastError();
116 if(err != WSAEWOULDBLOCK) 224 if(err != WSAEWOULDBLOCK)
@@ -121,98 +229,15 @@ @@ -121,98 +229,15 @@
121 _( "Can't connect to host." ), 229 _( "Can't connect to host." ),
122 "Windows error %d", 230 "Windows error %d",
123 WSAGetLastError() ); 231 WSAGetLastError() );
124 - close(sock);  
125 - sock = -1;  
126 - }  
127 - }  
128 -  
129 - #error Implementar  
130 -  
131 - /*  
132 - if(sock > 0)  
133 - {  
134 - // Connection in progress, wait until socket is available for write  
135 - fd_set wr;  
136 - struct timeval tm;  
137 - int status;  
138 - int err;  
139 - socklen_t len = sizeof(err);  
140 -  
141 - FD_ZERO(&wr);  
142 - FD_SET(sock, &wr);  
143 - memset(&tm,0,sizeof(tm));  
144 - tm.tv_sec = timeout;  
145 -  
146 - switch(select(sock+1, NULL, &wr, NULL, &tm))  
147 - {  
148 - case 0:  
149 - lib3270_popup_dialog( hSession,  
150 - LIB3270_NOTIFY_ERROR,  
151 - _( "Connection error" ),  
152 - _( "Can't connect to host." ),  
153 - "%s",  
154 - strerror(errno = ETIMEDOUT));  
155 - close(sock);  
156 - sock = -1;  
157 - break;  
158 -  
159 - case -1:  
160 - lib3270_popup_dialog( hSession,  
161 - LIB3270_NOTIFY_ERROR,  
162 - _( "Connection error" ),  
163 - _( "select() error when connecting to host." ),  
164 - "%s",  
165 - strerror(errno));  
166 - close(sock);  
167 - sock = -1;  
168 - break;  
169 -  
170 - default:  
171 - // Se o socket nao esta disponivel para gravacao o connect falhou  
172 - if(!FD_ISSET(sock,&wr))  
173 - {  
174 - lib3270_popup_dialog( hSession,  
175 - LIB3270_NOTIFY_ERROR,  
176 - _( "Connection error" ),  
177 - _( "Error when connecting to host." ),  
178 - "%s",  
179 - _( "Socket was not available after connect" ));  
180 - close(sock);  
181 - sock = -1;  
182 - }  
183 - else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &err, &len) < 0)  
184 - {  
185 - lib3270_popup_dialog( hSession,  
186 - LIB3270_NOTIFY_ERROR,  
187 - _( "Connection error" ),  
188 - _( "Error getting connection state." ),  
189 - "%s",  
190 - strerror(errno));  
191 -  
192 - close(sock);  
193 - sock = -1;  
194 - }  
195 - else if(err)  
196 - {  
197 - lib3270_popup_dialog( hSession,  
198 - LIB3270_NOTIFY_ERROR,  
199 - _( "Connection error" ),  
200 - _( "socket error when connecting to host." ),  
201 - "Socket error %d",  
202 - err);  
203 -  
204 - close(sock);  
205 - sock = -1;  
206 - } 232 + SOCK_CLOSE(hSession);
207 } 233 }
208 } 234 }
209 - */  
210 235
211 #else 236 #else
212 - fcntl(sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK); 237 + fcntl(hSession->sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK);
213 238
214 errno = 0; 239 errno = 0;
215 - if(connect(sock, rp->ai_addr, rp->ai_addrlen)) 240 + if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen))
216 { 241 {
217 if( errno != EINPROGRESS ) 242 if( errno != EINPROGRESS )
218 { 243 {
@@ -222,99 +247,52 @@ @@ -222,99 +247,52 @@
222 _( "Can't connect to host." ), 247 _( "Can't connect to host." ),
223 "%s", 248 "%s",
224 strerror(errno)); 249 strerror(errno));
225 - close(sock);  
226 - sock = -1; 250 + SOCK_CLOSE(hSession);
227 } 251 }
228 } 252 }
229 253
230 - #error Implementar  
231 -  
232 -/*  
233 - if(sock > 0)  
234 - {  
235 - // Connection in progress, wait until socket is available for write  
236 - fd_set wr;  
237 - struct timeval tm;  
238 - int status;  
239 - int err;  
240 - socklen_t len = sizeof(err);  
241 -  
242 - FD_ZERO(&wr);  
243 - FD_SET(sock, &wr);  
244 - memset(&tm,0,sizeof(tm));  
245 - tm.tv_sec = timeout;  
246 -  
247 - switch(select(sock+1, NULL, &wr, NULL, &tm))  
248 - {  
249 - case 0:  
250 - lib3270_popup_dialog( hSession,  
251 - LIB3270_NOTIFY_ERROR,  
252 - _( "Connection error" ),  
253 - _( "Can't connect to host." ),  
254 - "%s",  
255 - strerror(errno = ETIMEDOUT));  
256 - close(sock);  
257 - sock = -1;  
258 - break;  
259 -  
260 - case -1:  
261 - lib3270_popup_dialog( hSession,  
262 - LIB3270_NOTIFY_ERROR,  
263 - _( "Connection error" ),  
264 - _( "select() error when connecting to host." ),  
265 - "%s",  
266 - strerror(errno));  
267 - close(sock);  
268 - sock = -1;  
269 - break;  
270 -  
271 - default:  
272 -  
273 - // Se o socket nao esta disponivel para gravacao o connect falhou  
274 - if(!FD_ISSET(sock,&wr))  
275 - {  
276 - lib3270_popup_dialog( hSession,  
277 - LIB3270_NOTIFY_ERROR,  
278 - _( "Connection error" ),  
279 - _( "Error when connecting to host." ),  
280 - "%s",  
281 - _( "Socket was not available after connect" ));  
282 - close(sock);  
283 - sock = -1;  
284 - }  
285 - else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0)  
286 - {  
287 - lib3270_popup_dialog( hSession,  
288 - LIB3270_NOTIFY_ERROR,  
289 - _( "Connection error" ),  
290 - _( "Error getting connection state." ),  
291 - "%s",  
292 - strerror(errno));  
293 -  
294 - close(sock);  
295 - sock = -1;  
296 - }  
297 - else if(err)  
298 - {  
299 - lib3270_popup_dialog( hSession,  
300 - LIB3270_NOTIFY_ERROR,  
301 - _( "Connection error" ),  
302 - _( "socket error when connecting to host." ),  
303 - "Socket error %d",  
304 - err);  
305 -  
306 - close(sock);  
307 - sock = -1;  
308 - }  
309 - }  
310 - }  
311 - */  
312 #endif // WIN32 254 #endif // WIN32
313 } 255 }
314 256
315 freeaddrinfo(result); 257 freeaddrinfo(result);
316 258
317 - status_changed(hSession,saved_status); 259 + // set options for inline out-of-band data and keepalives
  260 +
  261 + /*
  262 + int on = 1;
  263 + if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&on,sizeof(on)) < 0)
  264 + {
  265 + popup_a_sockerr(hSession, N_( "setsockopt(%s)" ), "SO_OOBINLINE");
  266 + SOCK_CLOSE(hSession);
  267 + }
  268 +
  269 +#if defined(OMTU)
  270 + else if (setsockopt(hSession->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0)
  271 + {
  272 + popup_a_sockerr(hSession, N_( "setsockopt(%s)" ), "SO_SNDBUF");
  273 + SOCK_CLOSE(hSession);
  274 + }
  275 +#endif
  276 +
  277 + */
  278 +
  279 + if(hSession->sock < 0)
  280 + {
  281 + lib3270_set_disconnected(hSession);
  282 + return -1;
  283 + }
  284 +
  285 +#if !defined(_WIN32)
  286 + /* don't share the socket with our children */
  287 + (void) fcntl(hSession->sock, F_SETFD, 1);
  288 +#endif
  289 +
  290 + // Connecting, set callbacks, wait for connection
  291 + trace_dsn(hSession,"Half-connected.\n");
  292 +
  293 + lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True);
  294 +
  295 + hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected);
318 296
319 return 0; 297 return 0;
320 298
@@ -33,8 +33,7 @@ TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c @@ -33,8 +33,7 @@ TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c
33 # tables.c utf8.c 33 # tables.c utf8.c
34 34
35 # Network I/O Sources 35 # Network I/O Sources
36 -NETWORK_SOURCES = iocalls.c proxy.c  
37 -# connect.c 36 +NETWORK_SOURCES = iocalls.c proxy.c connect.c
38 37
39 # Full library sources 38 # Full library sources
40 SOURCES = $(TERMINAL_SOURCES) $(NETWORK_SOURCES) ft.c ft_cut.c ft_dft.c glue.c resources.c \ 39 SOURCES = $(TERMINAL_SOURCES) $(NETWORK_SOURCES) ft.c ft_cut.c ft_dft.c glue.c resources.c \