Commit efb256445235232de72aa98085fc616dd2c34561

Authored by Perry Werneck
1 parent 2d1bf4c8

Refactoring network modules.

@@ -337,6 +337,9 @@ @@ -337,6 +337,9 @@
337 <Unit filename="src/network_modules/state.c"> 337 <Unit filename="src/network_modules/state.c">
338 <Option compilerVar="CC" /> 338 <Option compilerVar="CC" />
339 </Unit> 339 </Unit>
  340 + <Unit filename="src/network_modules/translate.c">
  341 + <Option compilerVar="CC" />
  342 + </Unit>
340 <Unit filename="src/selection/actions.c"> 343 <Unit filename="src/selection/actions.c">
341 <Option compilerVar="CC" /> 344 <Option compilerVar="CC" />
342 </Unit> 345 </Unit>
src/core/telnet.c
@@ -459,7 +459,6 @@ LIB3270_EXPORT void lib3270_setup_session(H3270 *hSession) @@ -459,7 +459,6 @@ LIB3270_EXPORT void lib3270_setup_session(H3270 *hSession)
459 459
460 } 460 }
461 461
462 -/*  
463 /// 462 ///
464 /// @brief Connection_complete. 463 /// @brief Connection_complete.
465 /// 464 ///
@@ -477,7 +476,6 @@ static void connection_complete(H3270 *session) @@ -477,7 +476,6 @@ static void connection_complete(H3270 *session)
477 lib3270_set_connected_initial(session); 476 lib3270_set_connected_initial(session);
478 net_connected(session); 477 net_connected(session);
479 } 478 }
480 -*/  
481 479
482 /// @brief Disconnect from host. 480 /// @brief Disconnect from host.
483 void net_disconnect(H3270 *hSession) 481 void net_disconnect(H3270 *hSession)
@@ -568,31 +566,23 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED @@ -568,31 +566,23 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
568 else 566 else
569 nr = hSession->network.module->recv(hSession, buffer, BUFSZ); 567 nr = hSession->network.module->recv(hSession, buffer, BUFSZ);
570 */ 568 */
  569 +
571 nr = hSession->network.module->recv(hSession, buffer, BUFSZ); 570 nr = hSession->network.module->recv(hSession, buffer, BUFSZ);
572 571
573 if (nr < 0) 572 if (nr < 0)
574 { 573 {
575 if (nr == -EWOULDBLOCK) 574 if (nr == -EWOULDBLOCK)
  575 + {
576 return; 576 return;
  577 + }
577 578
578 - /*  
579 - if (HALF_CONNECTED && nr == -EWOULDBLOCK) 579 + if(HALF_CONNECTED && nr == -EAGAIN)
580 { 580 {
581 connection_complete(hSession); 581 connection_complete(hSession);
582 return; 582 return;
583 } 583 }
584 - */  
585 584
586 - trace_dsn(hSession,"RCVD socket error %d (%s)\n", -nr, strerror(-nr));  
587 -  
588 - if (HALF_CONNECTED)  
589 - {  
590 - popup_a_sockerr(hSession, "%s", hSession->host.current);  
591 - }  
592 - else if (nr != -ECONNRESET)  
593 - {  
594 - popup_a_sockerr(hSession, _( "Socket read error" ) );  
595 - } 585 + trace_dsn(hSession,"RCVD socket error %d\n", -nr);
596 586
597 host_disconnect(hSession,True); 587 host_disconnect(hSession,True);
598 return; 588 return;
@@ -1526,7 +1516,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf @@ -1526,7 +1516,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
1526 return rc; 1516 return rc;
1527 1517
1528 // Send error, notify 1518 // Send error, notify
1529 - trace_dsn(hSession,"RCVD socket error %d\n", -rc); 1519 + trace_dsn(hSession,"SND socket error %d\n", -rc);
1530 1520
1531 return -1; 1521 return -1;
1532 } 1522 }
src/include/networking.h
@@ -113,7 +113,9 @@ @@ -113,7 +113,9 @@
113 /// 113 ///
114 /// @return Positive on data received, negative on error. 114 /// @return Positive on data received, negative on error.
115 /// 115 ///
116 - /// @retval -ENOTCONN Not connected to host. 116 + /// @retval -ENOTCONN Not connected to host.
  117 + /// @retval -EWOULDBLOCK Next request will block.
  118 + /// @retval -EAGAIN Try again.
117 /// 119 ///
118 ssize_t (*recv)(H3270 *hSession, void *buf, size_t len); 120 ssize_t (*recv)(H3270 *hSession, void *buf, size_t len);
119 121
@@ -165,6 +167,29 @@ @@ -165,6 +167,29 @@
165 LIB3270_INTERNAL int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state); 167 LIB3270_INTERNAL int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state);
166 168
167 /** 169 /**
  170 + * @brief Translate system socket receive error codes, show popup if needed.
  171 + *
  172 + * @param hSession TN3270 Session handle.
  173 + *
  174 + * @return Translated error code.
  175 + *
  176 + * @retval -EWOULDBLOCK Next call would block.
  177 + * @retval -EAGAIN Try again.
  178 + *
  179 + */
  180 + LIB3270_INTERNAL int lib3270_network_recv_failed(H3270 *hSession);
  181 +
  182 + /**
  183 + * @brief Translate system socket send error codes, show popup if needed.
  184 + *
  185 + * @param hSession TN3270 Session handle.
  186 + *
  187 + * @return Translated error code.
  188 + *
  189 + */
  190 + LIB3270_INTERNAL int lib3270_network_send_failed(H3270 *hSession);
  191 +
  192 + /**
168 * @brief Select the default (unsecure) network context. 193 * @brief Select the default (unsecure) network context.
169 * 194 *
170 * @param hSession TN3270 Session handle. 195 * @param hSession TN3270 Session handle.
src/network_modules/default/main.c
@@ -65,80 +65,25 @@ @@ -65,80 +65,25 @@
65 65
66 ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) { 66 ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) {
67 67
68 - if(hSession->network.context->sock < 0) {  
69 - return -(errno = ENOTCONN);  
70 - }  
71 -  
72 ssize_t bytes = send(hSession->network.context->sock,buffer,length,0); 68 ssize_t bytes = send(hSession->network.context->sock,buffer,length,0);
73 69
74 - debug("%s bytes=%d",__FUNCTION__,(int) bytes);  
75 -  
76 if(bytes >= 0) 70 if(bytes >= 0)
77 return bytes; 71 return bytes;
78 72
79 - int rc = errno;  
80 -  
81 - debug("%s: %s",__FUNCTION__,strerror(rc)); 73 + return lib3270_network_send_failed(hSession);
82 74
83 - switch(rc)  
84 - {  
85 - case EPIPE:  
86 - lib3270_popup_dialog(  
87 - hSession,  
88 - LIB3270_NOTIFY_ERROR,  
89 - NULL,  
90 - _("Broken pipe"),  
91 - _("The system error code was %d"),  
92 - rc  
93 - );  
94 - break;  
95 -  
96 - case ECONNRESET:  
97 - lib3270_popup_dialog(  
98 - hSession,  
99 - LIB3270_NOTIFY_ERROR,  
100 - NULL,  
101 - _("Connection reset by peer"),  
102 - _("The system error code was %d"),  
103 - rc  
104 - );  
105 - break;  
106 -  
107 - case EINTR:  
108 - return 0;  
109 -  
110 - default:  
111 - lib3270_popup_dialog(  
112 - hSession,  
113 - LIB3270_NOTIFY_ERROR,  
114 - NULL,  
115 - _("Unexpected error writing to network socket"),  
116 - _("The system error code was %d (%s)"),  
117 - rc, strerror(rc)  
118 - );  
119 -  
120 - }  
121 -  
122 - return -rc;  
123 } 75 }
124 76
125 static ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { 77 static ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) {
126 78
127 - debug("%s",__FUNCTION__);  
128 -  
129 - if(hSession->network.context->sock < 0) {  
130 - return -(errno = ENOTCONN);  
131 - }  
132 -  
133 ssize_t bytes = recv(hSession->network.context->sock, (char *) buf, len, 0); 79 ssize_t bytes = recv(hSession->network.context->sock, (char *) buf, len, 0);
134 80
135 - debug("%s bytes=%d",__FUNCTION__,(int) bytes);  
136 -  
137 - if(bytes < 0) {  
138 - return -errno; 81 + if(bytes >= 0) {
  82 + return bytes;
139 } 83 }
140 84
141 - return bytes; 85 + return lib3270_network_recv_failed(hSession);
  86 +
142 } 87 }
143 88
144 static int unsecure_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { 89 static int unsecure_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
src/network_modules/openssl/main.c
@@ -79,14 +79,49 @@ static int openssl_network_disconnect(H3270 *hSession) { @@ -79,14 +79,49 @@ static int openssl_network_disconnect(H3270 *hSession) {
79 79
80 ssize_t openssl_network_send(H3270 *hSession, const void *buffer, size_t length) { 80 ssize_t openssl_network_send(H3270 *hSession, const void *buffer, size_t length) {
81 81
  82 +/*
  83 + if(hSession->network.context->sock < 0) {
  84 + return -(errno = ENOTCONN);
  85 + }
  86 +
  87 + ssize_t bytes = SSL_write(hSession->network.context->con, (const char *) buffer, length);
  88 +
  89 + debug("%s bytes=%d",__FUNCTION__,(int) bytes);
  90 +
  91 + if(bytes >= 0)
  92 + return bytes;
  93 +
  94 + // SSL Write has failed, using SSL_get_error to identify what has happened.
  95 + int error = SSL_get_error(hSession->network.context->con,(int) bytes);
  96 +
  97 + if(error == SSL_ERROR_SYSCALL) {
  98 +
  99 + #error Use errno!
  100 +
  101 + return -1;
  102 + }
  103 +
  104 + // Not a system error, inspects the result.
  105 +
  106 +
  107 +
  108 + lib3270_popup(hSession,&popup,0);
  109 +
  110 + return -1;
  111 +*/
  112 +
82 } 113 }
83 114
84 static ssize_t openssl_network_recv(H3270 *hSession, void *buf, size_t len) { 115 static ssize_t openssl_network_recv(H3270 *hSession, void *buf, size_t len) {
85 116
  117 +// return SSL_read(hSession->network.context->con, (char *) buf, len);
  118 +
  119 +
  120 +
86 } 121 }
87 122
88 static int openssl_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { 123 static int openssl_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
89 - 124 + return getsockname(hSession->network.context->sock, addr, addrlen);
90 } 125 }
91 126
92 static void * openssl_network_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) { 127 static void * openssl_network_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) {
@@ -147,14 +182,14 @@ static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state @@ -147,14 +182,14 @@ static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state
147 else 182 else
148 { 183 {
149 trace_ssl(hSession,"Can't get CRL next update, discarding it\n"); 184 trace_ssl(hSession,"Can't get CRL next update, discarding it\n");
150 - crl_free(context); 185 + lib3270_openssl_crl_free(context);
151 } 186 }
152 187
153 } 188 }
154 else 189 else
155 { 190 {
156 trace_ssl(hSession,"CRL is no longer valid\n"); 191 trace_ssl(hSession,"CRL is no longer valid\n");
157 - crl_free(context); 192 + lib3270_openssl_crl_free(context);
158 } 193 }
159 194
160 } 195 }
src/network_modules/openssl/start.c
@@ -232,28 +232,7 @@ @@ -232,28 +232,7 @@
232 // 232 //
233 long verify_result = SSL_get_verify_result(context->con); 233 long verify_result = SSL_get_verify_result(context->con);
234 234
235 - const struct ssl_status_msg * msg = ssl_get_status_from_error_code(verify_result);  
236 - if(!msg) {  
237 -  
238 - trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",verify_result);  
239 -  
240 - static const LIB3270_SSL_MESSAGE message = {  
241 - .type = LIB3270_NOTIFY_ERROR,  
242 - .icon = "dialog-error",  
243 - .summary = N_( "Invalid TLS/SSL verify result" ),  
244 - .body = N_( "The verification of the connection security status returned an unexpected value." )  
245 - };  
246 -  
247 - hSession->ssl.message = &message;  
248 - return EACCES;  
249 -  
250 - } else {  
251 -  
252 - trace_ssl(hSession,"The TLS/SSL verify result was %d: %s\n",verify_result, msg);  
253 -  
254 - }  
255 -  
256 - // Get SSL Message 235 + // Get validation message.
257 hSession->ssl.message = lib3270_openssl_message_from_id(verify_result); 236 hSession->ssl.message = lib3270_openssl_message_from_id(verify_result);
258 237
259 // Trace cypher 238 // Trace cypher
src/network_modules/translate.c 0 → 100644
@@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
  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 unsecure.c 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 Common methods for send/recv errors.
  32 + *
  33 + */
  34 +
  35 + #include <config.h>
  36 + #include <lib3270.h>
  37 + #include <lib3270/log.h>
  38 + #include <internals.h>
  39 + #include <networking.h>
  40 +
  41 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  42 +
  43 + int lib3270_network_recv_failed(H3270 *hSession) {
  44 +
  45 +#ifdef _WIN32
  46 +
  47 + int wsaError = WSAGetLastError();
  48 +
  49 + // EWOULDBLOCK & EAGAIN should return directly.
  50 + if(wsaError == WSAEWOULDBLOCK)
  51 + return -EWOULDBLOCK;
  52 +
  53 + if(wsaError == WSAEINPROGRESS)
  54 + return -EAGAIN;
  55 +
  56 + int rc = -wsaError;
  57 +
  58 + LIB3270_POPUP popup = {
  59 + .name = "RecvFailed",
  60 + .type = LIB3270_NOTIFY_ERROR,
  61 + .summary = _("Error receiving data from host"),
  62 + }
  63 +
  64 + // TODO: Translate WSA Error, update message body.
  65 +
  66 + lib3270_popup(hSession,&popup,0);
  67 +
  68 +#else
  69 +
  70 + // EWOULDBLOCK & EAGAIN should return directly.
  71 + if(errno == EWOULDBLOCK || errno == EAGAIN)
  72 + return -errno;
  73 +
  74 + // Network error, notify user
  75 + int rc = -errno;
  76 +
  77 + lib3270_autoptr(char) body = lib3270_strdup_printf(
  78 + _("The system error code was %d (%s)"),
  79 + errno,
  80 + strerror(errno)
  81 + );
  82 +
  83 + LIB3270_POPUP popup = {
  84 + .name = "RecvFailed",
  85 + .type = LIB3270_NOTIFY_ERROR,
  86 + .summary = _("Error receiving data from host"),
  87 + .body = body
  88 + };
  89 +
  90 + lib3270_popup(hSession,&popup,0);
  91 +
  92 +#endif // _WIN32
  93 +
  94 + return rc;
  95 +
  96 + }
  97 +
  98 + int lib3270_network_send_failed(H3270 *hSession) {
  99 +
  100 + #ifdef _WIN32
  101 +
  102 + int rc = WSAGetLastError();
  103 +
  104 + #error Have work to do.
  105 +
  106 + #else
  107 +
  108 + int rc = errno;
  109 +
  110 + switch(rc) {
  111 + case EPIPE:
  112 + lib3270_popup_dialog(
  113 + hSession,
  114 + LIB3270_NOTIFY_ERROR,
  115 + NULL,
  116 + _("Broken pipe"),
  117 + _("The system error code was %d"),
  118 + rc
  119 + );
  120 + break;
  121 +
  122 + case ECONNRESET:
  123 + lib3270_popup_dialog(
  124 + hSession,
  125 + LIB3270_NOTIFY_ERROR,
  126 + NULL,
  127 + _("Connection reset by peer"),
  128 + _("The system error code was %d"),
  129 + rc
  130 + );
  131 + break;
  132 +
  133 + case EINTR:
  134 + return 0;
  135 +
  136 + default:
  137 + lib3270_popup_dialog(
  138 + hSession,
  139 + LIB3270_NOTIFY_ERROR,
  140 + NULL,
  141 + _("Unexpected error writing to network socket"),
  142 + _("The system error code was %d (%s)"),
  143 + rc, strerror(rc)
  144 + );
  145 +
  146 + }
  147 +
  148 +
  149 + #endif // _WIN32
  150 +
  151 + }