From: Razvan Crainea 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; }