Commit 0669cde0aa80aed19ced0b75f2f8e6f8e41c37d4

Authored by Perry Werneck
1 parent 09dddac0

Refactoring network subsystem for modularity.

@@ -271,6 +271,7 @@ @@ -271,6 +271,7 @@
271 <Unit filename="src/include/lib3270/trace.h" /> 271 <Unit filename="src/include/lib3270/trace.h" />
272 <Unit filename="src/include/linkedlist.h" /> 272 <Unit filename="src/include/linkedlist.h" />
273 <Unit filename="src/include/localdefs.h" /> 273 <Unit filename="src/include/localdefs.h" />
  274 + <Unit filename="src/include/networking.h" />
274 <Unit filename="src/include/popupsc.h" /> 275 <Unit filename="src/include/popupsc.h" />
275 <Unit filename="src/include/proxyc.h" /> 276 <Unit filename="src/include/proxyc.h" />
276 <Unit filename="src/include/resolverc.h" /> 277 <Unit filename="src/include/resolverc.h" />
@@ -306,6 +307,9 @@ @@ -306,6 +307,9 @@
306 <Unit filename="src/mkfb/mkfb.c"> 307 <Unit filename="src/mkfb/mkfb.c">
307 <Option compilerVar="CC" /> 308 <Option compilerVar="CC" />
308 </Unit> 309 </Unit>
  310 + <Unit filename="src/network_modules/unsecure.c">
  311 + <Option compilerVar="CC" />
  312 + </Unit>
309 <Unit filename="src/selection/actions.c"> 313 <Unit filename="src/selection/actions.c">
310 <Option compilerVar="CC" /> 314 <Option compilerVar="CC" />
311 </Unit> 315 </Unit>
src/core/connect.c
@@ -121,7 +121,7 @@ @@ -121,7 +121,7 @@
121 return 0; 121 return 0;
122 } 122 }
123 123
124 - if(hSession->connection.sock > 0) 124 + if(hSession->network.module->is_connected(hSession))
125 { 125 {
126 errno = EISCONN; 126 errno = EISCONN;
127 return 0; 127 return 0;
@@ -169,3 +169,41 @@ @@ -169,3 +169,41 @@
169 169
170 } 170 }
171 171
  172 + static int bg_start_tls(H3270 *hSession, void *message)
  173 + {
  174 +
  175 + }
  176 +
  177 + int lib3270_start_tls(H3270 *hSession)
  178 + {
  179 + int rc = 0;
  180 +
  181 + if(hSession->network.module->start_tls)
  182 + {
  183 + LIB3270_NETWORK_STATE state;
  184 + memset(&state,0,sizeof(state));
  185 +
  186 + non_blocking(hSession,False);
  187 +
  188 + rc = lib3270_run_task(
  189 + hSession,
  190 + (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
  191 + &state
  192 + );
  193 +
  194 + if(state.popup) {
  195 + if(lib3270_popup(hSession,state.popup,1)) {
  196 + lib3270_disconnect(hSession);
  197 + return rc;
  198 + }
  199 +
  200 + // User has selected "continue", ignore error.
  201 + return 0;
  202 + }
  203 +
  204 + }
  205 +
  206 + return rc;
  207 + }
  208 +
  209 +
src/core/iocalls.c
@@ -299,19 +299,18 @@ static void internal_remove_poll(H3270 *session, void *id) @@ -299,19 +299,18 @@ static void internal_remove_poll(H3270 *session, void *id)
299 } 299 }
300 300
301 301
  302 +/*
302 LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) 303 LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id)
303 { 304 {
304 debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id); 305 debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id);
305 remove_poll(session, id); 306 remove_poll(session, id);
306 } 307 }
  308 +*/
307 309
308 LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled) 310 LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled)
309 { 311 {
310 if(id) 312 if(id)
311 - {  
312 - debug("%s: Polling on %d (%p) is %s",__FUNCTION__,session->connection.sock,id,(enabled ? "enabled" : "disabled"));  
313 set_poll_state(session, id, enabled); 313 set_poll_state(session, id, enabled);
314 - }  
315 } 314 }
316 315
317 LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd) 316 LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd)
@@ -349,7 +348,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FL @@ -349,7 +348,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FL
349 } 348 }
350 349
351 LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ) { 350 LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ) {
352 - debug("%s(%d)",__FUNCTION__,session->connection.sock); 351 + debug("%s(%d)",__FUNCTION__,fd);
353 return add_poll(session,fd,flag,call,userdata); 352 return add_poll(session,fd,flag,call,userdata);
354 } 353 }
355 354
@@ -400,11 +399,10 @@ void x_except_on(H3270 *h) @@ -400,11 +399,10 @@ void x_except_on(H3270 *h)
400 if(reading) 399 if(reading)
401 lib3270_remove_poll(h,h->xio.read); 400 lib3270_remove_poll(h,h->xio.read);
402 401
403 - h->xio.except = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); 402 + h->xio.except = h->network.module->add_poll(h,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
404 403
405 if(reading) 404 if(reading)
406 - h->xio.read = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_READ,net_input,0);  
407 - debug("%s",__FUNCTION__); 405 + h->xio.read = h->network.module->add_poll(h,LIB3270_IO_FLAG_READ,net_input,0);
408 406
409 } 407 }
410 408
@@ -522,61 +520,9 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo @@ -522,61 +520,9 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo
522 520
523 int non_blocking(H3270 *hSession, Boolean on) 521 int non_blocking(H3270 *hSession, Boolean on)
524 { 522 {
525 -  
526 - if(hSession->connection.sock < 0) 523 + if(hSession->network.module->non_blocking,on)
527 return 0; 524 return 0;
528 525
529 -#ifdef WIN32  
530 -  
531 - WSASetLastError(0);  
532 - u_long iMode= on ? 1 : 0;  
533 -  
534 - if(ioctlsocket(hSession->connection.sock,FIONBIO,&iMode))  
535 - {  
536 - lib3270_popup_dialog( hSession,  
537 - LIB3270_NOTIFY_ERROR,  
538 - _( "Connection error" ),  
539 - _( "ioctlsocket(FIONBIO) failed." ),  
540 - "%s", lib3270_win32_strerror(GetLastError()));  
541 - return -1;  
542 - }  
543 -  
544 -#else  
545 -  
546 - int f;  
547 -  
548 - if ((f = fcntl(hSession->connection.sock, F_GETFL, 0)) == -1)  
549 - {  
550 - lib3270_popup_dialog( hSession,  
551 - LIB3270_NOTIFY_ERROR,  
552 - _( "Socket error" ),  
553 - _( "fcntl() error when getting socket state." ),  
554 - _( "%s" ), strerror(errno)  
555 - );  
556 -  
557 - return -1;  
558 - }  
559 -  
560 - if (on)  
561 - f |= O_NDELAY;  
562 - else  
563 - f &= ~O_NDELAY;  
564 -  
565 - if (fcntl(hSession->connection.sock, F_SETFL, f) < 0)  
566 - {  
567 - lib3270_popup_dialog( hSession,  
568 - LIB3270_NOTIFY_ERROR,  
569 - _( "Socket error" ),  
570 - on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),  
571 - _( "%s" ), strerror(errno)  
572 - );  
573 - return -1;  
574 - }  
575 -  
576 -#endif  
577 -  
578 - debug("Socket %d is now %s",hSession->connection.sock,(on ? "Non Blocking" : "Blocking"));  
579 -  
580 lib3270_set_poll_state(hSession,hSession->xio.read, on); 526 lib3270_set_poll_state(hSession,hSession->xio.read, on);
581 lib3270_set_poll_state(hSession,hSession->xio.write, on); 527 lib3270_set_poll_state(hSession,hSession->xio.write, on);
582 lib3270_set_poll_state(hSession,hSession->xio.except, on); 528 lib3270_set_poll_state(hSession,hSession->xio.except, on);
src/core/linux/connect.c
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 #include <unistd.h> 42 #include <unistd.h>
43 #include <fcntl.h> 43 #include <fcntl.h>
44 44
45 -#define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1; 45 +// #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1;
46 46
47 #include <stdlib.h> 47 #include <stdlib.h>
48 48
@@ -69,7 +69,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -69,7 +69,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
69 hSession->xio.write = NULL; 69 hSession->xio.write = NULL;
70 } 70 }
71 71
72 - if(getsockopt(hSession->connection.sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0) 72 + if(hSession->network.module->getsockopt(hSession, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0)
73 { 73 {
74 lib3270_disconnect(hSession); 74 lib3270_disconnect(hSession);
75 lib3270_popup_dialog( 75 lib3270_popup_dialog(
@@ -88,16 +88,11 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -88,16 +88,11 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
88 return; 88 return;
89 } 89 }
90 90
91 - hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);  
92 - hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_READ,net_input,0); 91 + hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
  92 + hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0);
93 93
94 -#if defined(HAVE_LIBSSL)  
95 - if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)  
96 - {  
97 - if(ssl_negotiate(hSession))  
98 - return;  
99 - }  
100 -#endif 94 + if(lib3270_start_tls(hSession))
  95 + return;
101 96
102 lib3270_setup_session(hSession); 97 lib3270_setup_session(hSession);
103 lib3270_set_connected_initial(hSession); 98 lib3270_set_connected_initial(hSession);
@@ -238,8 +233,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -238,8 +233,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
238 lib3270_set_cstate(hSession, LIB3270_PENDING); 233 lib3270_set_cstate(hSession, LIB3270_PENDING);
239 lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); 234 lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True);
240 235
241 - hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_WRITE,net_connected,0);  
242 - // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected); 236 + hSession->xio.write = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_WRITE,net_connected,0);
243 237
244 trace("%s: Connection in progress",__FUNCTION__); 238 trace("%s: Connection in progress",__FUNCTION__);
245 239
src/core/model.c
@@ -28,6 +28,7 @@ @@ -28,6 +28,7 @@
28 */ 28 */
29 29
30 #include <internals.h> 30 #include <internals.h>
  31 + #include <stdlib.h>
31 #include "screen.h" 32 #include "screen.h"
32 #include "ctlrc.h" 33 #include "ctlrc.h"
33 #include "popupsc.h" 34 #include "popupsc.h"
src/core/rpq.c
@@ -690,7 +690,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen @@ -690,7 +690,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen
690 void *src = NULL; 690 void *src = NULL;
691 int len = 0; 691 int len = 0;
692 692
693 - if(net_getsockname(hSession, &u, &addrlen) < 0) 693 + if(hSession->network.module->getsockname(hSession, (struct sockaddr *) &u, &addrlen) < 0)
694 return 0; 694 return 0;
695 SET16(buf, u.sa.sa_family); 695 SET16(buf, u.sa.sa_family);
696 x += 2; 696 x += 2;
src/core/session.c
@@ -74,7 +74,7 @@ void lib3270_session_free(H3270 *h) @@ -74,7 +74,7 @@ void lib3270_session_free(H3270 *h)
74 74
75 shutdown_toggles(h); 75 shutdown_toggles(h);
76 76
77 -#ifdef SSL_ENABLE_CRL_CHECK 77 +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
78 if(h->ssl.crl.prefer) 78 if(h->ssl.crl.prefer)
79 { 79 {
80 free(h->ssl.crl.prefer); 80 free(h->ssl.crl.prefer);
@@ -281,7 +281,7 @@ void lib3270_reset_callbacks(H3270 *hSession) @@ -281,7 +281,7 @@ void lib3270_reset_callbacks(H3270 *hSession)
281 memset(&hSession->cbk,0,sizeof(hSession->cbk)); 281 memset(&hSession->cbk,0,sizeof(hSession->cbk));
282 282
283 hSession->cbk.write = lib3270_sock_send; 283 hSession->cbk.write = lib3270_sock_send;
284 - hSession->cbk.disconnect = lib3270_sock_disconnect; 284 +// hSession->cbk.disconnect = lib3270_sock_disconnect;
285 hSession->cbk.update = update_char; 285 hSession->cbk.update = update_char;
286 hSession->cbk.update_model = update_model; 286 hSession->cbk.update_model = update_model;
287 hSession->cbk.update_cursor = update_cursor; 287 hSession->cbk.update_cursor = update_cursor;
@@ -331,7 +331,6 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char @@ -331,7 +331,6 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char
331 hSession->unlock_delay = 1; 331 hSession->unlock_delay = 1;
332 hSession->icrnl = 1; 332 hSession->icrnl = 1;
333 hSession->onlcr = 1; 333 hSession->onlcr = 1;
334 - hSession->connection.sock = -1;  
335 hSession->model_num = -1; 334 hSession->model_num = -1;
336 hSession->connection.state = LIB3270_NOT_CONNECTED; 335 hSession->connection.state = LIB3270_NOT_CONNECTED;
337 hSession->oia.status = -1; 336 hSession->oia.status = -1;
@@ -446,7 +445,7 @@ H3270 * lib3270_session_new(const char *model) @@ -446,7 +445,7 @@ H3270 * lib3270_session_new(const char *model)
446 hSession->ssl.protocol.max_version = 0; 445 hSession->ssl.protocol.max_version = 0;
447 #endif // HAVE_LIBSSL 446 #endif // HAVE_LIBSSL
448 447
449 -#ifdef SSL_ENABLE_CRL_CHECK 448 +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
450 hSession->ssl.crl.download = 1; 449 hSession->ssl.crl.download = 1;
451 #endif // SSL_ENABLE_CRL_CHECK 450 #endif // SSL_ENABLE_CRL_CHECK
452 451
src/core/telnet.c
@@ -507,9 +507,11 @@ static void connection_complete(H3270 *session) @@ -507,9 +507,11 @@ static void connection_complete(H3270 *session)
507 } 507 }
508 508
509 509
  510 +/*
510 LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) 511 LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
511 { 512 {
512 - trace("%s",__FUNCTION__); 513 + LIB3270_NETWORK_STATE state;
  514 + memset(&state,0,sizeof(state));
513 515
514 #if defined(HAVE_LIBSSL) 516 #if defined(HAVE_LIBSSL)
515 if(hSession->ssl.con != NULL) 517 if(hSession->ssl.con != NULL)
@@ -527,37 +529,47 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) @@ -527,37 +529,47 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
527 hSession->xio.write = 0; 529 hSession->xio.write = 0;
528 } 530 }
529 531
530 - if(hSession->connection.sock >= 0)  
531 - {  
532 - shutdown(hSession->connection.sock, 2);  
533 - SOCK_CLOSE(hSession->connection.sock);  
534 - hSession->connection.sock = -1;  
535 - } 532 + hSession->network.module->disconnect(hSession->network.context,hSession,&state);
536 533
537 } 534 }
  535 +*/
538 536
539 /** 537 /**
540 - * @brief Shut down the socket. 538 + * @brief Disconnect from host.
541 */ 539 */
542 -void net_disconnect(H3270 *session) 540 +void net_disconnect(H3270 *hSession)
543 { 541 {
  542 + LIB3270_NETWORK_STATE state;
  543 + memset(&state,0,sizeof(state));
  544 +
  545 + // Disconnect from host
544 #if defined(HAVE_LIBSSL) 546 #if defined(HAVE_LIBSSL)
545 - set_ssl_state(session,LIB3270_SSL_UNSECURE);  
546 -#endif // HAVE_LIBSSL 547 + if(hSession->ssl.con != NULL)
  548 + {
  549 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
  550 + SSL_shutdown(hSession->ssl.con);
  551 + SSL_free(hSession->ssl.con);
  552 + hSession->ssl.con = NULL;
  553 + }
  554 + else
  555 + {
  556 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  557 + }
  558 +#endif
547 559
548 - session->cbk.disconnect(session); 560 + if(hSession->xio.write)
  561 + {
  562 + lib3270_remove_poll(hSession, hSession->xio.write);
  563 + hSession->xio.write = 0;
  564 + }
549 565
550 - trace_dsn(session,"SENT disconnect\n"); 566 + hSession->network.module->disconnect(hSession,&state);
551 567
552 - /* Restore terminal type to its default. */  
553 - /*  
554 - if (session->termname == CN)  
555 - session->termtype = session->full_model_name;  
556 - */ 568 + trace_dsn(hSession,"SENT disconnect\n");
557 569
558 // We're not connected to an LU any more. 570 // We're not connected to an LU any more.
559 - session->lu.associated = CN;  
560 - status_lu(session,CN); 571 + hSession->lu.associated = CN;
  572 + status_lu(hSession,CN);
561 573
562 } 574 }
563 575
@@ -618,8 +630,8 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED @@ -618,8 +630,8 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
618 for (;;) 630 for (;;)
619 #endif 631 #endif
620 { 632 {
621 - if (hSession->connection.sock < 0)  
622 - return; 633 +// if (hSession->connection.sock < 0)
  634 +// return;
623 635
624 #if defined(X3270_ANSI) 636 #if defined(X3270_ANSI)
625 hSession->ansi_data = 0; 637 hSession->ansi_data = 0;
@@ -629,9 +641,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED @@ -629,9 +641,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
629 if (hSession->ssl.con != NULL) 641 if (hSession->ssl.con != NULL)
630 nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); 642 nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ);
631 else 643 else
632 - nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0); 644 + nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ);
633 #else 645 #else
634 - nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0); 646 + nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ);
635 #endif // HAVE_LIBSSL 647 #endif // HAVE_LIBSSL
636 648
637 if (nr < 0) 649 if (nr < 0)
@@ -1637,7 +1649,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf @@ -1637,7 +1649,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
1637 else 1649 else
1638 rc = send(hSession->connection.sock, (const char *) buf, len, 0); 1650 rc = send(hSession->connection.sock, (const char *) buf, len, 0);
1639 #else 1651 #else
1640 - rc = send(hSession->connection.sock, (const char *) buf, len, 0); 1652 + rc = hSession->network.module->send(hSession, buf, len);
1641 #endif // HAVE_LIBSSL 1653 #endif // HAVE_LIBSSL
1642 1654
1643 if(rc > 0) 1655 if(rc > 0)
@@ -2650,9 +2662,12 @@ void net_abort(H3270 *hSession) @@ -2650,9 +2662,12 @@ void net_abort(H3270 *hSession)
2650 #endif /*]*/ 2662 #endif /*]*/
2651 2663
2652 /* Return the local address for the socket. */ 2664 /* Return the local address for the socket. */
  2665 +
  2666 +/*
2653 int net_getsockname(const H3270 *session, void *buf, int *len) 2667 int net_getsockname(const H3270 *session, void *buf, int *len)
2654 { 2668 {
2655 if (session->connection.sock < 0) 2669 if (session->connection.sock < 0)
2656 return -1; 2670 return -1;
2657 return getsockname(session->connection.sock, buf, (socklen_t *)(void *)len); 2671 return getsockname(session->connection.sock, buf, (socklen_t *)(void *)len);
2658 } 2672 }
  2673 +*/
src/core/toggles/init.c
@@ -79,21 +79,19 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle @@ -79,21 +79,19 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle
79 79
80 static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt)) 80 static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt))
81 { 81 {
82 - if(session->connection.sock > 0)  
83 - {  
84 - // Update keep-alive option  
85 - int optval = t->value ? 1 : 0; 82 + // Update keep-alive option
  83 + int optval = t->value ? 1 : 0;
86 84
87 - if (setsockopt(session->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0)  
88 - { 85 + if(session->network.module->setsockopt(session, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)
  86 + {
  87 + if(errno != ENOTCONN)
89 popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); 88 popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" ));
90 - }  
91 - else  
92 - {  
93 - trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );  
94 - }  
95 -  
96 } 89 }
  90 + else
  91 + {
  92 + trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );
  93 + }
  94 +
97 } 95 }
98 96
99 static void toggle_connect(H3270 *hSession, const struct lib3270_toggle *toggle, LIB3270_TOGGLE_TYPE tt) 97 static void toggle_connect(H3270 *hSession, const struct lib3270_toggle *toggle, LIB3270_TOGGLE_TYPE tt)
src/core/util.c
@@ -516,6 +516,7 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr) @@ -516,6 +516,7 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr)
516 516
517 } 517 }
518 518
  519 +/*
519 LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) 520 LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen)
520 { 521 {
521 CHECK_SESSION_HANDLE(hSession); 522 CHECK_SESSION_HANDLE(hSession);
@@ -544,7 +545,7 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s @@ -544,7 +545,7 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s
544 545
545 return getsockname(hSession->connection.sock, addr, addrlen); 546 return getsockname(hSession->connection.sock, addr, addrlen);
546 } 547 }
547 - 548 +*/
548 static int xdigit_value(const char scanner) 549 static int xdigit_value(const char scanner)
549 { 550 {
550 551
src/include/internals.h
@@ -39,6 +39,7 @@ @@ -39,6 +39,7 @@
39 #include <lib3270/session.h> 39 #include <lib3270/session.h>
40 #include <lib3270/actions.h> 40 #include <lib3270/actions.h>
41 #include <lib3270/popup.h> 41 #include <lib3270/popup.h>
  42 +#include <networking.h>
42 43
43 #if defined(HAVE_LIBSSL) 44 #if defined(HAVE_LIBSSL)
44 #include <openssl/ssl.h> 45 #include <openssl/ssl.h>
@@ -319,12 +320,22 @@ struct _h3270 @@ -319,12 +320,22 @@ struct _h3270
319 { 320 {
320 struct lib3270_session_callbacks cbk; ///< @brief Callback table - Always the first one. 321 struct lib3270_session_callbacks cbk; ///< @brief Callback table - Always the first one.
321 322
322 - // Session info  
323 - char id; ///< @brief Session Identifier. 323 + /// @brief Session Identifier.
  324 + char id;
  325 +
  326 + // Network
  327 + struct {
  328 +
  329 + /// @brief Network module.
  330 + const LIB3270_NET_MODULE * module;
  331 +
  332 + /// @brief Network context.
  333 + LIB3270_NET_CONTEXT * context;
  334 +
  335 + } network;
324 336
325 // Connection info 337 // Connection info
326 struct { 338 struct {
327 - int sock; ///< @brief Network socket.  
328 LIB3270_CSTATE state; ///< @brief Connection state. 339 LIB3270_CSTATE state; ///< @brief Connection state.
329 } connection; 340 } connection;
330 341
@@ -745,7 +756,7 @@ LIB3270_INTERNAL void toggle_rectselect(H3270 *session, const struct lib3270_tog @@ -745,7 +756,7 @@ LIB3270_INTERNAL void toggle_rectselect(H3270 *session, const struct lib3270_tog
745 LIB3270_INTERNAL void remove_input_calls(H3270 *session); 756 LIB3270_INTERNAL void remove_input_calls(H3270 *session);
746 757
747 LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf, int len); 758 LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf, int len);
748 -LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); 759 +// LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession);
749 760
750 LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); 761 LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block);
751 762
@@ -871,3 +882,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); @@ -871,3 +882,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
871 882
872 /// @brief Fire CState change. 883 /// @brief Fire CState change.
873 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate); 884 LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate);
  885 +
  886 + inline LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession) {
  887 + return hSession->network.context;
  888 + }
  889 +
  890 + LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession);
  891 +
  892 +
src/include/lib3270/session.h
@@ -49,7 +49,7 @@ @@ -49,7 +49,7 @@
49 struct lib3270_session_callbacks 49 struct lib3270_session_callbacks
50 { 50 {
51 int (*write)(H3270 *hSession, unsigned const char *buf, int len); 51 int (*write)(H3270 *hSession, unsigned const char *buf, int len);
52 - void (*disconnect)(H3270 *hSession); 52 +// void (*disconnect)(H3270 *hSession);
53 53
54 void (*configure)(H3270 *session, unsigned short rows, unsigned short cols); 54 void (*configure)(H3270 *session, unsigned short rows, unsigned short cols);
55 void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor); 55 void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor);
src/include/networking.h 0 → 100644
@@ -0,0 +1,141 @@ @@ -0,0 +1,141 @@
  1 +/*
  2 + * "Software G3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como networking.h e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
  27 + *
  28 + */
  29 +
  30 +#ifndef LIB3270_NETWORKING_H_INCLUDED
  31 +
  32 + #define LIB3270_NETWORKING_H_INCLUDED
  33 +
  34 + #include <lib3270/popup.h>
  35 + #include <sys/socket.h>
  36 +
  37 + typedef struct lib3270_network_state {
  38 +
  39 + int syserror; ///< @brief System error (errno)
  40 +#ifdef _WIN32
  41 + DWORD winerror; ///< @brief Win32 error got from GetLastError()
  42 +#endif // _WIN32
  43 +
  44 + const LIB3270_POPUP *popup; /// @brief Detailed info for popup.
  45 +
  46 + } LIB3270_NETWORK_STATE;
  47 +
  48 + typedef struct _lib3270_new_context LIB3270_NET_CONTEXT;
  49 +
  50 + typedef struct lib3270_net_module {
  51 +
  52 + const char * name; ///< @brief The network module name.
  53 +
  54 + /// @brief Initialize network module
  55 + ///
  56 + /// @param hSession TN3270 session.
  57 + /// @param state Pointer to state message.
  58 + ///
  59 + /// @return Allocated network context.
  60 + ///
  61 + /// @retval NULL Initialization failed.
  62 + ///
  63 + LIB3270_NET_CONTEXT * (*init)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
  64 +
  65 + /// @brief Deinitialize network module.
  66 + ///
  67 + /// @param context Network context.
  68 + /// @param hSession TN3270 session.
  69 + /// @param state Pointer to state message.
  70 + ///
  71 + void (*deinit)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
  72 +
  73 + /// @brief Connect to host.
  74 + ///
  75 + /// @param context Network context.
  76 + /// @param hSession TN3270 session.
  77 + /// @param seconds Seconds for timeout.
  78 + /// @param state Pointer to state message.
  79 + ///
  80 + int (*connect)(H3270 *hSession, int seconds, LIB3270_NETWORK_STATE *state);
  81 +
  82 + /// @brief Disconnect from host.
  83 + ///
  84 + /// @param context Network context.
  85 + /// @param hSession TN3270 session.
  86 + /// @param state Pointer to state message.
  87 + ///
  88 + int (*disconnect)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
  89 +
  90 + int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg);
  91 +
  92 + /// @brief Send on network context.
  93 + ///
  94 + /// @return Positive on data received, negative on error.
  95 + ///
  96 + ssize_t (*send)(H3270 *hSession, const void *buffer, size_t length);
  97 +
  98 + /// @brief Receive on network context.
  99 + ///
  100 + /// @return Positive on data received, negative on error.
  101 + ///
  102 + /// @retval -ENOTCONN Not connected to host.
  103 + ///
  104 + ssize_t (*recv)(H3270 *hSession, void *buf, size_t len);
  105 +
  106 + /// @brief Add socket in poll list.
  107 + void * (*add_poll)(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata);
  108 +
  109 + /// @brief Set non blocking mode.
  110 + ///
  111 + /// @retval 0 Not connected or Success.
  112 + /// @retval -1 Failed (popup was sent).
  113 + int (*non_blocking)(H3270 *hSession, const unsigned char on);
  114 +
  115 + /// @brief Check if the session is online.
  116 + ///
  117 + /// @retval 0 The session is offline.
  118 + int (*is_connected)(H3270 *hSession);
  119 +
  120 + /// @brief get socket name.
  121 + ///
  122 + /// @return On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
  123 + ///
  124 + /// @retval 0 Success.
  125 + /// @retval -1 Error (errno is set).
  126 + int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen);
  127 +
  128 + /// @brief Set socket options.
  129 + int (*setsockopt)(H3270 *hSession, int level, int optname, void *optval, size_t optlen);
  130 +
  131 + /// @brief Get socket options.
  132 + int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen);
  133 +
  134 + } LIB3270_NET_MODULE;
  135 +
  136 + LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession);
  137 + LIB3270_NET_CONTEXT * lib3270_get_default_net_context(void);
  138 +
  139 +
  140 +#endif // LIB3270_NETWORKING_H_INCLUDED
  141 +
src/include/telnetc.h
@@ -62,4 +62,4 @@ LIB3270_INTERNAL void space3270out(H3270 *hSession, int n); @@ -62,4 +62,4 @@ LIB3270_INTERNAL void space3270out(H3270 *hSession, int n);
62 #define trace_netdata(direction, buf, len) /* */ 62 #define trace_netdata(direction, buf, len) /* */
63 #endif // X3270_TRACE 63 #endif // X3270_TRACE
64 64
65 -LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len); 65 +// LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len);
src/network_modules/unsecure.c 0 → 100644
@@ -0,0 +1,193 @@ @@ -0,0 +1,193 @@
  1 +/*
  2 + * "Software PW3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como networking.h e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
  27 + *
  28 + */
  29 +
  30 + /**
  31 + * @brief Default networking methods.
  32 + *
  33 + */
  34 +
  35 + #include <config.h>
  36 + #ifdef _WIN32
  37 + #include <winsock.h>
  38 + #include <windows.h>
  39 + #endif // _WIN32
  40 +
  41 + #include <internals.h>
  42 + #include <networking.h>
  43 +
  44 + struct _lib3270_new_context {
  45 + int sock;
  46 + };
  47 +
  48 + LIB3270_NET_CONTEXT * unsecure_network_init(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  49 +
  50 + LIB3270_NET_CONTEXT * context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT));
  51 +
  52 + context->sock = -1;
  53 +
  54 + return context;
  55 + }
  56 +
  57 + void unsecure_network_deinit(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  58 + unsecure_network_disconnect(hSession->network.context,hSession,state);
  59 + lib3270_free(context);
  60 + }
  61 +
  62 +int unsecure_network_disconnect(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  63 +
  64 + debug("%s",__FUNCTION__);
  65 + if(context->sock >= 0) {
  66 + shutdown(hSession.network.context->sock, 2);
  67 + close(hSession->network.context->sock);
  68 + hSession.network.context->sock = -1;
  69 + }
  70 +
  71 +}
  72 +
  73 +ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) {
  74 +
  75 + if(hSession->network.context->sock < 0) {
  76 + return -(errno = ENOTCONN);
  77 + }
  78 +
  79 + ssize_t bytes = send(hSession->network.context->sock,buffer,length,0);
  80 +
  81 + if(bytes < 0)
  82 + return -errno;
  83 +
  84 + return 0;
  85 +}
  86 +
  87 +ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) {
  88 +
  89 + if(hSession->network.context->sock < 0) {
  90 + return -(errno = ENOTCONN);
  91 + }
  92 +
  93 + ssize_t bytes = recv(hSession->network.context->sock, (char *) buffer, len, 0);
  94 +
  95 + if(bytes < 0) {
  96 + return -errno;
  97 + }
  98 +
  99 + return bytes;
  100 +}
  101 +
  102 +int unsecure_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
  103 + if(hSession->network.context->sock < 0)
  104 + return -(errno = ENOTCONN);
  105 + return getsockname(hSession->network.context->sock, buf, addrlen);
  106 +}
  107 +
  108 +void * unsecure_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) {
  109 + return lib3270_add_poll_fd(hSession,hSession->network.context->sock,flag,call,userdata);
  110 +}
  111 +
  112 +int unsecure_non_blocking(H3270 *hSession, const unsigned char on) {
  113 +
  114 + if(hSession->network.context->sock < 0)
  115 + return 0;
  116 +
  117 +#ifdef WIN32
  118 +
  119 + WSASetLastError(0);
  120 + u_long iMode= on ? 1 : 0;
  121 +
  122 + if(ioctlsocket(hSession->network.context->sock,FIONBIO,&iMode))
  123 + {
  124 + lib3270_popup_dialog( hSession,
  125 + LIB3270_NOTIFY_ERROR,
  126 + _( "Connection error" ),
  127 + _( "ioctlsocket(FIONBIO) failed." ),
  128 + "%s", lib3270_win32_strerror(GetLastError()));
  129 + return -1;
  130 + }
  131 +
  132 +#else
  133 +
  134 + int f;
  135 +
  136 + if ((f = fcntl(hSession->network.context->sock, F_GETFL, 0)) == -1)
  137 + {
  138 + lib3270_popup_dialog( hSession,
  139 + LIB3270_NOTIFY_ERROR,
  140 + _( "Socket error" ),
  141 + _( "fcntl() error when getting socket state." ),
  142 + _( "%s" ), strerror(errno)
  143 + );
  144 +
  145 + return -1;
  146 + }
  147 +
  148 + if (on)
  149 + f |= O_NDELAY;
  150 + else
  151 + f &= ~O_NDELAY;
  152 +
  153 + if (fcntl(hSession->network.context->sock, F_SETFL, f) < 0)
  154 + {
  155 + lib3270_popup_dialog( hSession,
  156 + LIB3270_NOTIFY_ERROR,
  157 + _( "Socket error" ),
  158 + on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),
  159 + _( "%s" ), strerror(errno)
  160 + );
  161 + return -1;
  162 + }
  163 +
  164 +#endif
  165 +
  166 + debug("Socket %d is now %s",hSession->network.context->sock,(on ? "Non Blocking" : "Blocking"));
  167 +
  168 +}
  169 +
  170 +int unsecure_is_connected(H3270 *hSession) {
  171 + return hSession->network.context.sock > 0;
  172 +}
  173 +
  174 +int unsecure_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) {
  175 +
  176 + if(hSession->network.context.sock < 0) {
  177 + errno = ENOTCONN;
  178 + return -1;
  179 + }
  180 +
  181 + return setsockopt(hSession->network.context.sock, level, optname, optval, optlen);
  182 +
  183 +}
  184 +
  185 +int unsecure_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) {
  186 +
  187 + if(hSession->network.context.sock < 0) {
  188 + errno = ENOTCONN;
  189 + return -1;
  190 + }
  191 +
  192 + return getsockopt(hSession->network.context.sock, level, optname, optval, optlen)
  193 +}