diff options
author | Ladar Levison <ladar@lavabit.com> | 2017-03-29 16:57:42 +0300 |
---|---|---|
committer | Ladar Levison <ladar@lavabit.com> | 2017-03-29 16:57:42 +0300 |
commit | 19d0b4705675b79ca71af55f2edfee093b9c5b43 (patch) | |
tree | 5659f9fc1b923e133c96088ddabc1a4b7dc3de46 | |
parent | 6647fb607d717823f6f26e2d91588fddc7c3e47b (diff) |
Write interface cleaned up so it uses the newest error handling logic.
-rw-r--r-- | src/network/read.c | 8 | ||||
-rw-r--r-- | src/network/write.c | 102 |
2 files changed, 54 insertions, 56 deletions
diff --git a/src/network/read.c b/src/network/read.c index 24087bc4..a4be7f37 100644 --- a/src/network/read.c +++ b/src/network/read.c @@ -70,7 +70,7 @@ int64_t con_read_line(connection_t *con, bool_t block) { st_avail_get(con->network.buffer) - st_length_get(con->network.buffer), block); // If zero bytes were read, or a negative value was returned to indicate an error, call tls_erorr(), which will return - // NULL if the error can be safely ignored. + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. if (bytes <= 0 && (error = tls_error(con->network.tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(con->network.tls, MANAGEDBUF(128)); ip = con_addr_presentation(con, MANAGEDBUF(INET6_ADDRSTRLEN)); @@ -191,7 +191,7 @@ int64_t con_read(connection_t *con) { st_avail_get(con->network.buffer) - st_length_get(con->network.buffer), blocking); // If zero bytes were read, or a negative value was returned to indicate an error, call tls_erorr(), which will return - // NULL if the error can be safely ignored. + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. if (bytes <= 0 && (error = tls_error(con->network.tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(con->network.tls, MANAGEDBUF(128)); ip = con_addr_presentation(con, MANAGEDBUF(INET6_ADDRSTRLEN)); @@ -302,7 +302,7 @@ int64_t client_read_line(client_t *client) { st_avail_get(client->buffer) - st_length_get(client->buffer), blocking); // If zero bytes were read, or a negative value was returned to indicate an error, call tls_erorr(), which will return - // NULL if the error can be safely ignored. + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. if (bytes <= 0 && (error = tls_error(client->tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(client->tls, MANAGEDBUF(128)); ip = ip_presentation(client->ip, MANAGEDBUF(INET6_ADDRSTRLEN)); @@ -403,7 +403,7 @@ int64_t client_read(client_t *client) { st_avail_get(client->buffer) - st_length_get(client->buffer), blocking); // If zero bytes were read, or a negative value was returned to indicate an error, call tls_erorr(), which will return - // NULL if the error can be safely ignored. + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. if (bytes <= 0 && (error = tls_error(client->tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(client->tls, MANAGEDBUF(128)); ip = ip_presentation(client->ip, MANAGEDBUF(INET6_ADDRSTRLEN)); diff --git a/src/network/write.c b/src/network/write.c index 1a49c075..8adac0a2 100644 --- a/src/network/write.c +++ b/src/network/write.c @@ -9,7 +9,8 @@ /// HIGH: Create a simpler method of triggering a queue event following a connection write operation, and audit the code /// to ensure write calls do not accidently orphan a connection by not queuing the connection upon completion. -/// In other words, always ensure that enqueue() is being called on a connection after all processing is performed, so that it is not lost (whether it is to be kept or not). +/// In other words, always ensure that enqueue() is being called on a connection after all processing is performed, +/// so that it is not lost (whether it is to be kept or not). /** * @brief Write data to a network connection. @@ -23,7 +24,7 @@ int64_t con_write_bl(connection_t *con, char *block, size_t length) { int_t counter = 0; - ssize_t written, position = 0; + ssize_t bytes = 0, position = 0; stringer_t *ip = NULL, *cipher = NULL, *error = NULL; if (!con || con->network.sockd == -1 || con_status(con) < 0) { @@ -39,42 +40,41 @@ int64_t con_write_bl(connection_t *con, char *block, size_t length) { if (con->network.tls) { - written = tls_write(con->network.tls, block + position, length, true); + bytes = tls_write(con->network.tls, block + position, length, true); - // Check for errors on SSL writes. - if (written <= 0) { - error = tls_error(con->network.tls, written, MANAGEDBUF(512)); + // If zero bytes were written, or a negative value was returned to indicate an error, call tls_erorr(), which will return + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. + if (bytes <= 0 && (error = tls_error(con->network.tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(con->network.tls, MANAGEDBUF(128)); ip = con_addr_presentation(con, MANAGEDBUF(INET6_ADDRSTRLEN)); log_pedantic("TLS server write operation failed. { ip = %.*s / protocol = %s / %.*s / result = %zi%s%.*s }", st_length_int(ip), st_char_get(ip), st_char_get(protocol_type(con)), st_length_int(cipher), st_char_get(cipher), - written, (error ? " / " : ""), st_length_int(error), st_char_get(error)); - - int_t tlserr = SSL_get_error_d(con->network.tls, written); - if (tlserr != SSL_ERROR_NONE && tlserr != SSL_ERROR_WANT_READ && tlserr != SSL_ERROR_WANT_WRITE) { - con->network.status = -1; - return -1; - } - else { - written = 0; - } + bytes, (error ? " / " : ""), st_length_int(error), st_char_get(error)); + + con->network.status = -1; + return -1; + } + // This will occur when the read operation results in a 0, or negative value, but TLS error returns NULL to + // indicate it was a transient error. For transient errors we simply set bytes equal to 0 so the read call gets retried. + else if (bytes <= 0) { + bytes = 0; } } else { errno = 0; - written = send(con->network.sockd, block + position, length, 0); + bytes = send(con->network.sockd, block + position, length, 0); // Check for errors on non-SSL writes in the traditional way. - if (written <= 0) {// && tcp_status(con->network.sockd)) { + if (bytes <= 0 && tcp_status(con->network.sockd)) { int_t local = errno; ip = con_addr_presentation(con, MANAGEDBUF(INET6_ADDRSTRLEN)); log_pedantic("TCP server write operation failed. { ip = %.*s / result = %zi / error = %i / message = %s }", - st_length_int(ip), st_char_get(ip), written, local, strerror_r(local, MEMORYBUF(1024), 1024)); + st_length_int(ip), st_char_get(ip), bytes, local, strerror_r(local, MEMORYBUF(1024), 1024)); con->network.status = -1; return -1; @@ -82,14 +82,14 @@ int64_t con_write_bl(connection_t *con, char *block, size_t length) { } // Handle progress by advancing our position tracker. - if (written > 0) { - length -= written; - position += written; + if (bytes > 0) { + length -= bytes; + position += bytes; } - } while (length && counter++ < 8192 && status()); + } while (length && counter++ < 128 && status()); - if (written > 0) { + if (bytes > 0) { con->network.status = 1; } @@ -144,8 +144,8 @@ int64_t con_print(connection_t *con, chr_t *format, ...) { va_list args; char *buffer; - size_t length, written; int64_t result; + size_t length, bytes; if (!con || con->network.sockd == -1) { if (con) con->network.status = -1; @@ -174,10 +174,10 @@ int64_t con_print(connection_t *con, chr_t *format, ...) { // Try building the string again. va_start(args, format); - written = vsnprintf(buffer, length+1, format, args); + bytes = vsnprintf(buffer, length+1, format, args); va_end(args); - if (written != length) { + if (bytes != length) { mm_free(buffer); con->network.status = -1; return -1; @@ -202,7 +202,7 @@ int64_t client_write(client_t *client, stringer_t *s) { uchr_t *block; size_t length; int_t counter = 0; - ssize_t written, position = 0; + ssize_t bytes, position = 0; stringer_t *ip = NULL, *cipher = NULL, *error = NULL; if (!client || client->sockd == -1 || client_status(client) < 0) { @@ -218,56 +218,54 @@ int64_t client_write(client_t *client, stringer_t *s) { if (client->tls) { - written = tls_write(client->tls, block + position, length, true); + bytes = tls_write(client->tls, block + position, length, true); - // Check for errors on SSL writes. - if (written <= 0) { - error = tls_error(client->tls, written, MANAGEDBUF(512)); + // If zero bytes were written, or a negative value was returned to indicate an error, call tls_erorr(), which will return + // NULL if the error can be safely ignored. Otherwise log the output for debug purposes. + if (bytes <= 0 && (error = tls_error(client->tls, bytes, MANAGEDBUF(512)))) { cipher = tls_cipher(client->tls, MANAGEDBUF(128)); ip = ip_presentation(client->ip, MANAGEDBUF(INET6_ADDRSTRLEN)); log_pedantic("TLS client write operation failed. { ip = %.*s / %.*s / result = %zi%s%.*s }", - st_length_int(ip), st_char_get(ip), st_length_int(cipher), st_char_get(cipher), written, (error ? " / " : ""), - st_length_int(error), st_char_get(error)); - - int_t tlserr = SSL_get_error_d(client->tls, written); - if (tlserr != SSL_ERROR_NONE && tlserr != SSL_ERROR_WANT_READ && tlserr != SSL_ERROR_WANT_WRITE) { - client->status = -1; - return -1; - } - else { - written = 0; - } + st_length_int(ip), st_char_get(ip), st_length_int(cipher), st_char_get(cipher), + bytes, (error ? " / " : ""), st_length_int(error), st_char_get(error)); + + client->status = -1; + return -1; + } + // This will occur when the read operation results in a 0, or negative value, but TLS error returns NULL to + // indicate it was a transient error. For transient errors we simply set bytes equal to 0 so the read call gets retried. + else if (bytes <= 0) { + bytes = 0; } } else { errno = 0; - written = write(client->sockd, block + position, length); - //written = send(client->sockd, block + position, length, 0); + bytes = send(client->sockd, block + position, length, 0); - if (written <= 0) {// && tcp_status(con->network.sockd)) { + if (bytes <= 0 && tcp_status(client->sockd)) { int_t local = errno; ip = ip_presentation(client->ip, MANAGEDBUF(INET6_ADDRSTRLEN)); log_pedantic("TCP client write operation failed. { ip = %.*s / result = %zi / error = %i / message = %s }", - st_length_int(ip), st_char_get(ip), written, local, strerror_r(local, MEMORYBUF(1024), 1024)); + st_length_int(ip), st_char_get(ip), bytes, local, strerror_r(local, MEMORYBUF(1024), 1024)); client->status = -1; return -1; } } - if (written > 0) { - length -= written; - position += written; + if (bytes > 0) { + length -= bytes; + position += bytes; } - } while (length && counter++ < 8192 && status()); + } while (length && counter++ < 128 && status()); - if (written > 0) { + if (bytes > 0) { client->status = 1; } |