Created
August 12, 2016 18:31
-
-
Save colmmacc/769453e7c1fe47498eafdfa6459e59ee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/tls/s2n_connection.c b/tls/s2n_connection.c | |
index 27a9c04..8a3f42e 100644 | |
--- a/tls/s2n_connection.c | |
+++ b/tls/s2n_connection.c | |
@@ -206,6 +206,7 @@ int s2n_connection_wipe(struct s2n_connection *conn) | |
conn->mode = mode; | |
conn->config = config; | |
conn->close_notify_queued = 0; | |
+ conn->current_user_data_consumed = 0; | |
conn->initial.cipher_suite = &s2n_null_cipher_suite; | |
conn->secure.cipher_suite = &s2n_null_cipher_suite; | |
conn->server = &conn->initial; | |
diff --git a/tls/s2n_connection.h b/tls/s2n_connection.h | |
index 09a127e..a8115c3 100644 | |
--- a/tls/s2n_connection.h | |
+++ b/tls/s2n_connection.h | |
@@ -95,6 +95,11 @@ struct s2n_connection { | |
/* How big is the record we are actively reading? */ | |
uint16_t current_in_record_size; | |
+ /* How much of the current user buffer have we already | |
+ * encrypted and have pending for the wire. | |
+ */ | |
+ uint16_t current_user_data_consumed; | |
+ | |
/* An alert may be fragmented across multiple records, | |
* this stuffer is used to re-assemble. | |
*/ | |
diff --git a/tls/s2n_record_write.c b/tls/s2n_record_write.c | |
index b060eeb..fa4245e 100644 | |
--- a/tls/s2n_record_write.c | |
+++ b/tls/s2n_record_write.c | |
@@ -253,6 +253,7 @@ int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s | |
} | |
conn->wire_bytes_out += actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH; | |
+ conn->current_user_data_consumed += data_bytes_to_take; | |
return data_bytes_to_take; | |
} | |
diff --git a/tls/s2n_send.c b/tls/s2n_send.c | |
index 545639f..59746c0 100644 | |
--- a/tls/s2n_send.c | |
+++ b/tls/s2n_send.c | |
@@ -49,6 +49,8 @@ int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * blocked) | |
} | |
conn->wire_bytes_out += w; | |
} | |
+ conn->current_user_buffer_consumed = 0; | |
+ | |
if (conn->closing) { | |
conn->closed = 1; | |
/* Delay wiping for close_notify. s2n_shutdown() needs to wait for peer's close_notify */ | |
@@ -91,8 +93,6 @@ int s2n_flush(struct s2n_connection *conn, s2n_blocked_status * blocked) | |
ssize_t s2n_send(struct s2n_connection * conn, void *buf, ssize_t size, s2n_blocked_status * blocked) | |
{ | |
- struct s2n_blob in = {.data = buf }; | |
- ssize_t bytes_written = 0; | |
int max_payload_size; | |
int w; | |
@@ -119,8 +119,9 @@ ssize_t s2n_send(struct s2n_connection * conn, void *buf, ssize_t size, s2n_bloc | |
} | |
/* Now write the data we were asked to send this round */ | |
- while (size) { | |
- in.size = MIN(size, max_payload_size); | |
+ while (size - conn->current_user_buffer_consumed) { | |
+ struct s2n_blob in = {.data = buf + conn->current_user_buffer_consumed}; | |
+ in.size = MIN(size - conn->current_user_buffer_consumed, max_payload_size); | |
/* Don't split messages in server mode for interoperability with naive clients. | |
* Some clients may have expectations based on the amount of content in the first record. | |
@@ -136,29 +137,11 @@ ssize_t s2n_send(struct s2n_connection * conn, void *buf, ssize_t size, s2n_bloc | |
GUARD(s2n_stuffer_rewrite(&conn->out)); | |
GUARD(s2n_record_write(conn, TLS_APPLICATION_DATA, &in)); | |
- bytes_written += in.size; | |
- | |
/* Send it */ | |
- while (s2n_stuffer_data_available(&conn->out)) { | |
- errno = 0; | |
- w = s2n_stuffer_send_to_fd(&conn->out, conn->writefd, s2n_stuffer_data_available(&conn->out)); | |
- if (w < 0) { | |
- if (errno == EWOULDBLOCK) { | |
- if (bytes_written) { | |
- return bytes_written; | |
- } | |
- S2N_ERROR(S2N_ERR_BLOCKED); | |
- } | |
- S2N_ERROR(S2N_ERR_IO); | |
- } | |
- conn->wire_bytes_out += w; | |
- } | |
- | |
- in.data += in.size; | |
- size -= in.size; | |
+ GUARD(s2n_flush(conn, blocked)); | |
} | |
*blocked = S2N_NOT_BLOCKED; | |
- return bytes_written; | |
+ return size; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment