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;
}