From efb256445235232de72aa98085fc616dd2c34561 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 6 Aug 2020 00:44:56 -0300 Subject: [PATCH] Refactoring network modules. --- lib3270.cbp | 3 +++ src/core/telnet.c | 22 ++++++---------------- src/include/networking.h | 27 ++++++++++++++++++++++++++- src/network_modules/default/main.c | 65 +++++------------------------------------------------------------ src/network_modules/openssl/main.c | 41 ++++++++++++++++++++++++++++++++++++++--- src/network_modules/openssl/start.c | 23 +---------------------- src/network_modules/translate.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 230 insertions(+), 102 deletions(-) create mode 100644 src/network_modules/translate.c diff --git a/lib3270.cbp b/lib3270.cbp index ba19584..5f00494 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -337,6 +337,9 @@ + + diff --git a/src/core/telnet.c b/src/core/telnet.c index 532080d..298c7ad 100644 --- a/src/core/telnet.c +++ b/src/core/telnet.c @@ -459,7 +459,6 @@ LIB3270_EXPORT void lib3270_setup_session(H3270 *hSession) } -/* /// /// @brief Connection_complete. /// @@ -477,7 +476,6 @@ static void connection_complete(H3270 *session) lib3270_set_connected_initial(session); net_connected(session); } -*/ /// @brief Disconnect from host. void net_disconnect(H3270 *hSession) @@ -568,31 +566,23 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED else nr = hSession->network.module->recv(hSession, buffer, BUFSZ); */ + nr = hSession->network.module->recv(hSession, buffer, BUFSZ); if (nr < 0) { if (nr == -EWOULDBLOCK) + { return; + } - /* - if (HALF_CONNECTED && nr == -EWOULDBLOCK) + if(HALF_CONNECTED && nr == -EAGAIN) { connection_complete(hSession); return; } - */ - trace_dsn(hSession,"RCVD socket error %d (%s)\n", -nr, strerror(-nr)); - - if (HALF_CONNECTED) - { - popup_a_sockerr(hSession, "%s", hSession->host.current); - } - else if (nr != -ECONNRESET) - { - popup_a_sockerr(hSession, _( "Socket read error" ) ); - } + trace_dsn(hSession,"RCVD socket error %d\n", -nr); host_disconnect(hSession,True); return; @@ -1526,7 +1516,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf return rc; // Send error, notify - trace_dsn(hSession,"RCVD socket error %d\n", -rc); + trace_dsn(hSession,"SND socket error %d\n", -rc); return -1; } diff --git a/src/include/networking.h b/src/include/networking.h index d097af4..762499a 100644 --- a/src/include/networking.h +++ b/src/include/networking.h @@ -113,7 +113,9 @@ /// /// @return Positive on data received, negative on error. /// - /// @retval -ENOTCONN Not connected to host. + /// @retval -ENOTCONN Not connected to host. + /// @retval -EWOULDBLOCK Next request will block. + /// @retval -EAGAIN Try again. /// ssize_t (*recv)(H3270 *hSession, void *buf, size_t len); @@ -165,6 +167,29 @@ LIB3270_INTERNAL int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state); /** + * @brief Translate system socket receive error codes, show popup if needed. + * + * @param hSession TN3270 Session handle. + * + * @return Translated error code. + * + * @retval -EWOULDBLOCK Next call would block. + * @retval -EAGAIN Try again. + * + */ + LIB3270_INTERNAL int lib3270_network_recv_failed(H3270 *hSession); + + /** + * @brief Translate system socket send error codes, show popup if needed. + * + * @param hSession TN3270 Session handle. + * + * @return Translated error code. + * + */ + LIB3270_INTERNAL int lib3270_network_send_failed(H3270 *hSession); + + /** * @brief Select the default (unsecure) network context. * * @param hSession TN3270 Session handle. diff --git a/src/network_modules/default/main.c b/src/network_modules/default/main.c index 3b7bcd3..d395bd9 100644 --- a/src/network_modules/default/main.c +++ b/src/network_modules/default/main.c @@ -65,80 +65,25 @@ ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) { - if(hSession->network.context->sock < 0) { - return -(errno = ENOTCONN); - } - ssize_t bytes = send(hSession->network.context->sock,buffer,length,0); - debug("%s bytes=%d",__FUNCTION__,(int) bytes); - if(bytes >= 0) return bytes; - int rc = errno; - - debug("%s: %s",__FUNCTION__,strerror(rc)); + return lib3270_network_send_failed(hSession); - switch(rc) - { - case EPIPE: - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - NULL, - _("Broken pipe"), - _("The system error code was %d"), - rc - ); - break; - - case ECONNRESET: - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - NULL, - _("Connection reset by peer"), - _("The system error code was %d"), - rc - ); - break; - - case EINTR: - return 0; - - default: - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - NULL, - _("Unexpected error writing to network socket"), - _("The system error code was %d (%s)"), - rc, strerror(rc) - ); - - } - - return -rc; } static ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { - debug("%s",__FUNCTION__); - - if(hSession->network.context->sock < 0) { - return -(errno = ENOTCONN); - } - ssize_t bytes = recv(hSession->network.context->sock, (char *) buf, len, 0); - debug("%s bytes=%d",__FUNCTION__,(int) bytes); - - if(bytes < 0) { - return -errno; + if(bytes >= 0) { + return bytes; } - return bytes; + return lib3270_network_recv_failed(hSession); + } static int unsecure_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { diff --git a/src/network_modules/openssl/main.c b/src/network_modules/openssl/main.c index c276686..0e990d3 100644 --- a/src/network_modules/openssl/main.c +++ b/src/network_modules/openssl/main.c @@ -79,14 +79,49 @@ static int openssl_network_disconnect(H3270 *hSession) { ssize_t openssl_network_send(H3270 *hSession, const void *buffer, size_t length) { +/* + if(hSession->network.context->sock < 0) { + return -(errno = ENOTCONN); + } + + ssize_t bytes = SSL_write(hSession->network.context->con, (const char *) buffer, length); + + debug("%s bytes=%d",__FUNCTION__,(int) bytes); + + if(bytes >= 0) + return bytes; + + // SSL Write has failed, using SSL_get_error to identify what has happened. + int error = SSL_get_error(hSession->network.context->con,(int) bytes); + + if(error == SSL_ERROR_SYSCALL) { + + #error Use errno! + + return -1; + } + + // Not a system error, inspects the result. + + + + lib3270_popup(hSession,&popup,0); + + return -1; +*/ + } static ssize_t openssl_network_recv(H3270 *hSession, void *buf, size_t len) { +// return SSL_read(hSession->network.context->con, (char *) buf, len); + + + } static int openssl_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { - + return getsockname(hSession->network.context->sock, addr, addrlen); } 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 else { trace_ssl(hSession,"Can't get CRL next update, discarding it\n"); - crl_free(context); + lib3270_openssl_crl_free(context); } } else { trace_ssl(hSession,"CRL is no longer valid\n"); - crl_free(context); + lib3270_openssl_crl_free(context); } } diff --git a/src/network_modules/openssl/start.c b/src/network_modules/openssl/start.c index 31810ef..5147ae9 100644 --- a/src/network_modules/openssl/start.c +++ b/src/network_modules/openssl/start.c @@ -232,28 +232,7 @@ // long verify_result = SSL_get_verify_result(context->con); - const struct ssl_status_msg * msg = ssl_get_status_from_error_code(verify_result); - if(!msg) { - - trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",verify_result); - - static const LIB3270_SSL_MESSAGE message = { - .type = LIB3270_NOTIFY_ERROR, - .icon = "dialog-error", - .summary = N_( "Invalid TLS/SSL verify result" ), - .body = N_( "The verification of the connection security status returned an unexpected value." ) - }; - - hSession->ssl.message = &message; - return EACCES; - - } else { - - trace_ssl(hSession,"The TLS/SSL verify result was %d: %s\n",verify_result, msg); - - } - - // Get SSL Message + // Get validation message. hSession->ssl.message = lib3270_openssl_message_from_id(verify_result); // Trace cypher diff --git a/src/network_modules/translate.c b/src/network_modules/translate.c new file mode 100644 index 0000000..995ffa7 --- /dev/null +++ b/src/network_modules/translate.c @@ -0,0 +1,151 @@ +/* + * "Software PW3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como unsecure.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) + * + */ + + /** + * @brief Common methods for send/recv errors. + * + */ + + #include + #include + #include + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + + int lib3270_network_recv_failed(H3270 *hSession) { + +#ifdef _WIN32 + + int wsaError = WSAGetLastError(); + + // EWOULDBLOCK & EAGAIN should return directly. + if(wsaError == WSAEWOULDBLOCK) + return -EWOULDBLOCK; + + if(wsaError == WSAEINPROGRESS) + return -EAGAIN; + + int rc = -wsaError; + + LIB3270_POPUP popup = { + .name = "RecvFailed", + .type = LIB3270_NOTIFY_ERROR, + .summary = _("Error receiving data from host"), + } + + // TODO: Translate WSA Error, update message body. + + lib3270_popup(hSession,&popup,0); + +#else + + // EWOULDBLOCK & EAGAIN should return directly. + if(errno == EWOULDBLOCK || errno == EAGAIN) + return -errno; + + // Network error, notify user + int rc = -errno; + + lib3270_autoptr(char) body = lib3270_strdup_printf( + _("The system error code was %d (%s)"), + errno, + strerror(errno) + ); + + LIB3270_POPUP popup = { + .name = "RecvFailed", + .type = LIB3270_NOTIFY_ERROR, + .summary = _("Error receiving data from host"), + .body = body + }; + + lib3270_popup(hSession,&popup,0); + +#endif // _WIN32 + + return rc; + + } + + int lib3270_network_send_failed(H3270 *hSession) { + + #ifdef _WIN32 + + int rc = WSAGetLastError(); + + #error Have work to do. + + #else + + int rc = errno; + + switch(rc) { + case EPIPE: + lib3270_popup_dialog( + hSession, + LIB3270_NOTIFY_ERROR, + NULL, + _("Broken pipe"), + _("The system error code was %d"), + rc + ); + break; + + case ECONNRESET: + lib3270_popup_dialog( + hSession, + LIB3270_NOTIFY_ERROR, + NULL, + _("Connection reset by peer"), + _("The system error code was %d"), + rc + ); + break; + + case EINTR: + return 0; + + default: + lib3270_popup_dialog( + hSession, + LIB3270_NOTIFY_ERROR, + NULL, + _("Unexpected error writing to network socket"), + _("The system error code was %d (%s)"), + rc, strerror(rc) + ); + + } + + + #endif // _WIN32 + + } -- libgit2 0.21.2