summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/http.c7
-rw-r--r--main/manager.c18
-rw-r--r--main/tcptls.c10
3 files changed, 32 insertions, 3 deletions
diff --git a/main/http.c b/main/http.c
index e2982a73b..1009afcc2 100644
--- a/main/http.c
+++ b/main/http.c
@@ -444,7 +444,9 @@ void ast_http_send(struct ast_tcptls_session_instance *ser,
/* send content */
if (method != AST_HTTP_HEAD || status_code >= 400) {
if (out) {
- fprintf(ser->f, "%s", ast_str_buffer(out));
+ if (fwrite(ast_str_buffer(out), content_length, 1, ser->f) != 1) {
+ ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
+ }
}
if (fd) {
@@ -466,8 +468,7 @@ void ast_http_send(struct ast_tcptls_session_instance *ser,
ast_free(out);
}
- fclose(ser->f);
- ser->f = 0;
+ ast_tcptls_close_session_file(ser);
return;
}
diff --git a/main/manager.c b/main/manager.c
index 328878251..5e74fb5a8 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -1769,6 +1769,15 @@ static void session_destructor(void *obj)
}
if (session->f != NULL) {
+ /*
+ * Issuing shutdown() is necessary here to avoid a race
+ * condition where the last data written may not appear
+ * in the the TCP stream. See ASTERISK-23548
+ */
+ fflush(session->f);
+ if (session->fd != -1) {
+ shutdown(session->fd, SHUT_RDWR);
+ }
fclose(session->f);
}
if (eqe) {
@@ -6740,12 +6749,21 @@ static void process_output(struct mansession *s, struct ast_str **out, struct as
}
if (s->f) {
+ /*
+ * Issuing shutdown() is necessary here to avoid a race
+ * condition where the last data written may not appear
+ * in the the TCP stream. See ASTERISK-23548
+ */
+ if (s->fd != -1) {
+ shutdown(s->fd, SHUT_RDWR);
+ }
if (fclose(s->f)) {
ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
}
s->f = NULL;
s->fd = -1;
} else if (s->fd != -1) {
+ shutdown(s->fd, SHUT_RDWR);
if (close(s->fd)) {
ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
}
diff --git a/main/tcptls.c b/main/tcptls.c
index e07f1f1a0..417178c8f 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -625,12 +625,22 @@ error:
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
{
if (tcptls_session->f) {
+ /*
+ * Issuing shutdown() is necessary here to avoid a race
+ * condition where the last data written may not appear
+ * in the TCP stream. See ASTERISK-23548
+ */
+ fflush(tcptls_session->f);
+ if (tcptls_session->fd != -1) {
+ shutdown(tcptls_session->fd, SHUT_RDWR);
+ }
if (fclose(tcptls_session->f)) {
ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
}
tcptls_session->f = NULL;
tcptls_session->fd = -1;
} else if (tcptls_session->fd != -1) {
+ shutdown(tcptls_session->fd, SHUT_RDWR);
if (close(tcptls_session->fd)) {
ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
}