Commit 25a75bdeba3a5c5c3b0c88a4fe161eac530709ac
1 parent
31451987
Exists in
master
and in
5 other branches
Implementando novo mecanismo de conexão ao host
Showing
3 changed files
with
165 additions
and
187 deletions
Show diff stats
src/include/lib3270/session.h
src/lib3270/connect.c
| @@ -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 |
src/lib3270/sources.mak
| @@ -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 \ |