Blob Blame History Raw
From: Razvan Crainea <razvan@opensips.org>
Date: Tue, 12 Sep 2017 11:10:56 +0300
Subject: [PATCH] proto_wss: write all TLS chunks under a single lock

Reported by Eric Tamme from OnSIP

(cherry picked from commit e113e147c71b2fa4f84bed3621b91d1ed1de38f6)

diff --git a/modules/proto_tls/proto_tls.c b/modules/proto_tls/proto_tls.c
index 7257fc066..27dfe83b9 100644
--- a/modules/proto_tls/proto_tls.c
+++ b/modules/proto_tls/proto_tls.c
@@ -110,7 +110,12 @@ static int proto_tls_send(struct socket_info* send_sock,
 static int w_tls_blocking_write(struct tcp_connection *c, int fd, const char *buf,
 																	size_t len)
 {
-	return tls_blocking_write(c, fd, buf, len, &tls_mgm_api);
+	int ret;
+
+	lock_get(&c->write_lock);
+	ret = tls_blocking_write(c, fd, buf, len, &tls_mgm_api);
+	lock_release(&c->write_lock);
+	return ret;
 }
 
 /* buffer to be used for reading all TCP SIP messages
@@ -343,7 +348,9 @@ static int proto_tls_send(struct socket_info* send_sock,
 send_it:
 	LM_DBG("sending via fd %d...\n",fd);
 
+	lock_get(&c->write_lock);
 	n = tls_blocking_write(c, fd, buf, len, &tls_mgm_api);
+	lock_release(&c->write_lock);
 	tcp_conn_set_lifetime( c, tcp_con_lifetime);
 
 	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
diff --git a/modules/proto_wss/proto_wss.c b/modules/proto_wss/proto_wss.c
index 4c4685a4b..ec3ed2050 100644
--- a/modules/proto_wss/proto_wss.c
+++ b/modules/proto_wss/proto_wss.c
@@ -451,6 +451,7 @@ static int wss_raw_writev(struct tcp_connection *c, int fd,
 #endif
 
 #ifndef TLS_DONT_WRITE_FRAGMENTS
+	lock_get(&c->write_lock);
 	for (i = 0; i < iovcnt; i++) {
 		n = tls_blocking_write(c, fd, iov[i].iov_base, iov[i].iov_len, &tls_mgm_api);
 		if (n < 0) {
@@ -459,6 +460,7 @@ static int wss_raw_writev(struct tcp_connection *c, int fd,
 		}
 		ret += n;
 	}
+	lock_release(&c->write_lock);
 #else
 	n = 0;
 	for (i = 0; i < iovcnt; i++)
@@ -473,7 +475,9 @@ static int wss_raw_writev(struct tcp_connection *c, int fd,
 		memcpy(buf + n, iov[i].iov_base, iov[i].iov_len);
 		n += iov[i].iov_len;
 	}
+	lock_get(&c->write_lock);
 	n = tls_blocking_write(c, fd, buf, n, &tls_mgm_api);
+	lock_release(&c->write_lock);
 
 #endif /* TLS_DONT_WRITE_FRAGMENTS */
 
diff --git a/modules/tls_mgm/tls_conn_server.h b/modules/tls_mgm/tls_conn_server.h
index 240963271..af6c2b309 100644
--- a/modules/tls_mgm/tls_conn_server.h
+++ b/modules/tls_mgm/tls_conn_server.h
@@ -422,8 +422,6 @@ static int tls_blocking_write(struct tcp_connection *c, int fd, const char *buf,
 		goto error;
 	}
 
-	lock_get(&c->write_lock);
-
 	if (tls_update_fd(c, fd) < 0)
 		goto error;
 
@@ -474,7 +472,6 @@ again:
 		/*
 		* successful full write
 		*/
-		lock_release(&c->write_lock);
 		return written;
 	}
 
@@ -516,7 +513,6 @@ poll_loop:
 	}
 
 error:
-	lock_release(&c->write_lock);
 	return -1;
 }