summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2015-11-11 17:11:53 -0600
committerMark Michelson <mmichelson@digium.com>2015-11-12 11:41:27 -0500
commit2f9cb7d62bf1ee2d3f7d878607d2d1eb9995dd03 (patch)
treed4459c8c979169eaa11d01bd62b01c4ff3da2421 /res
parent7ae22c26901abede6e4542aa6ccd94151f4ca134 (diff)
res_pjsip: Deny requests when threadpool queue is backed up.
We have observed situations where the SIP threadpool may become deadlocked. However, because incoming traffic is still arriving, the SIP threadpool's queue can continue to grow, eventually running the system out of memory. This change makes it so that incoming traffic gets rejected with a 503 response if the queue is backed up too much. Change-Id: I4e736d48a2ba79fd1f8056c0dcd330e38e6a3816
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip.c5
-rw-r--r--res/res_pjsip/pjsip_distributor.c14
2 files changed, 18 insertions, 1 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index d2b393fcc..babbe7aaa 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3755,6 +3755,11 @@ static void remove_request_headers(pjsip_endpoint *endpt)
}
}
+long ast_sip_threadpool_queue_size(void)
+{
+ return ast_threadpool_queue_size(sip_threadpool);
+}
+
AST_TEST_DEFINE(xml_sanitization_end_null)
{
char sanitized[8];
diff --git a/res/res_pjsip/pjsip_distributor.c b/res/res_pjsip/pjsip_distributor.c
index 9b052603a..1d39e0fd2 100644
--- a/res/res_pjsip/pjsip_distributor.c
+++ b/res/res_pjsip/pjsip_distributor.c
@@ -246,6 +246,8 @@ static pjsip_module endpoint_mod = {
.on_rx_request = endpoint_lookup,
};
+#define SIP_MAX_QUEUE 500L
+
static pj_bool_t distributor(pjsip_rx_data *rdata)
{
pjsip_dialog *dlg = find_dialog(rdata);
@@ -280,7 +282,17 @@ static pj_bool_t distributor(pjsip_rx_data *rdata)
clone->endpt_info.mod_data[endpoint_mod.id] = ao2_bump(dist->endpoint);
}
- ast_sip_push_task(serializer, distribute, clone);
+ if (ast_sip_threadpool_queue_size() > SIP_MAX_QUEUE) {
+ /* When the threadpool is backed up this much, there is a good chance that we have encountered
+ * some sort of terrible condition and don't need to be adding more work to the threadpool.
+ * It's in our best interest to send back a 503 response and be done with it.
+ */
+ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 503, NULL, NULL, NULL);
+ ao2_cleanup(clone->endpt_info.mod_data[endpoint_mod.id]);
+ pjsip_rx_data_free_cloned(clone);
+ } else {
+ ast_sip_push_task(serializer, distribute, clone);
+ }
end:
if (dlg) {