summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2016-06-07 10:07:57 +0000
committerRiza Sulistyo <riza@teluu.com>2016-06-07 10:07:57 +0000
commitc95d1a0f5bbf0d68ba6ab45416d482165bb7c8dc (patch)
treedd1cc8ff3798d9df09d48e3b2471dfa227b37d1a /pjsip
parent8058df78cebe49a6f8391c9a0b2c0e7bc42c7027 (diff)
Re #1929: Avoid memory pool growing when doing re-Registration.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5336 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_auth.h1
-rw-r--r--pjsip/include/pjsip/sip_config.h10
-rw-r--r--pjsip/src/pjsip-ua/sip_reg.c8
-rw-r--r--pjsip/src/pjsip/sip_auth_client.c72
4 files changed, 74 insertions, 17 deletions
diff --git a/pjsip/include/pjsip/sip_auth.h b/pjsip/include/pjsip/sip_auth.h
index ce262ef9..ba03f600 100644
--- a/pjsip/include/pjsip/sip_auth.h
+++ b/pjsip/include/pjsip/sip_auth.h
@@ -166,6 +166,7 @@ typedef struct pjsip_cached_auth
/** Standard list member */
PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);
+ pj_pool_t *pool; /**< Pool for cached auth */
pj_str_t realm; /**< Realm. */
pj_bool_t is_proxy; /**< Server type (401/407) */
pjsip_auth_qop_type qop_value; /**< qop required by server. */
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index 210c6650..1c974812 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -1122,6 +1122,16 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
# define PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM 0
#endif
+/**
+ * Maximum size of pool allowed for auth client session in pjsip_regc.
+ * After the size exceeds because of Digest authentication processing,
+ * the pool is reset.
+ *
+ * Default is 20 kB
+ */
+#ifndef PJSIP_AUTH_CACHED_POOL_MAX_SIZE
+# define PJSIP_AUTH_CACHED_POOL_MAX_SIZE (20 * 1024)
+#endif
/*****************************************************************************
* SIP Event framework and presence settings.
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index bdb0460b..52a55632 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -176,6 +176,7 @@ PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc)
regc->cb = NULL;
pj_lock_release(regc->lock);
} else {
+ pjsip_cached_auth *auth = NULL;
pjsip_tpselector_dec_ref(&regc->tp_sel);
if (regc->last_transport) {
pjsip_transport_dec_ref(regc->last_transport);
@@ -189,6 +190,13 @@ PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc)
pj_lock_release(regc->lock);
pj_lock_destroy(regc->lock);
regc->lock = NULL;
+
+ auth = regc->auth_sess.cached_auth.next;
+ while (auth != &regc->auth_sess.cached_auth) {
+ pjsip_endpt_release_pool(regc->endpt, auth->pool);
+ auth = auth->next;
+ }
+
pjsip_endpt_release_pool(regc->endpt, regc->pool);
}
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index 3b2ee372..6a4c10a7 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -357,15 +357,14 @@ static pj_status_t respond_digest( pj_pool_t *pool,
/*
* Update authentication session with a challenge.
*/
-static void update_digest_session( pj_pool_t *ses_pool,
- pjsip_cached_auth *cached_auth,
+static void update_digest_session( pjsip_cached_auth *cached_auth,
const pjsip_www_authenticate_hdr *hdr )
{
if (hdr->challenge.digest.qop.slen == 0) {
#if PJSIP_AUTH_AUTO_SEND_NEXT!=0
if (!cached_auth->last_chal || pj_stricmp2(&hdr->scheme, "digest")) {
cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
- pjsip_hdr_clone(ses_pool, hdr);
+ pjsip_hdr_clone(cached_auth->pool, hdr);
} else {
/* Only update if the new challenge is "significantly different"
* than the one in the cache, to reduce memory usage.
@@ -382,7 +381,7 @@ static void update_digest_session( pj_pool_t *ses_pool,
pj_strcmp(&d1->qop, &d2->qop))
{
cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
- pjsip_hdr_clone(ses_pool, hdr);
+ pjsip_hdr_clone(cached_auth->pool, hdr);
}
}
#endif
@@ -393,10 +392,10 @@ static void update_digest_session( pj_pool_t *ses_pool,
if (cached_auth->cnonce.slen == 0) {
/* Save the whole challenge */
cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
- pjsip_hdr_clone(ses_pool, hdr);
+ pjsip_hdr_clone(cached_auth->pool, hdr);
/* Create cnonce */
- pj_create_unique_string( ses_pool, &cached_auth->cnonce );
+ pj_create_unique_string( cached_auth->pool, &cached_auth->cnonce );
/* Initialize nonce-count */
cached_auth->nc = 1;
@@ -406,7 +405,7 @@ static void update_digest_session( pj_pool_t *ses_pool,
pj_assert(cached_auth->realm.slen != 0);
*/
if (cached_auth->realm.slen == 0) {
- pj_strdup(ses_pool, &cached_auth->realm,
+ pj_strdup(cached_auth->pool, &cached_auth->realm,
&hdr->challenge.digest.realm);
}
@@ -419,13 +418,14 @@ static void update_digest_session( pj_pool_t *ses_pool,
++cached_auth->nc;
} else {
/* Server gives new nonce. */
- pj_strdup(ses_pool, &cached_auth->last_chal->challenge.digest.nonce,
+ pj_strdup(cached_auth->pool,
+ &cached_auth->last_chal->challenge.digest.nonce,
&hdr->challenge.digest.nonce);
/* Has the opaque changed? */
if (pj_strcmp(&cached_auth->last_chal->challenge.digest.opaque,
&hdr->challenge.digest.opaque))
{
- pj_strdup(ses_pool,
+ pj_strdup(cached_auth->pool,
&cached_auth->last_chal->challenge.digest.opaque,
&hdr->challenge.digest.opaque);
}
@@ -691,7 +691,7 @@ static pj_status_t auth_respond( pj_pool_t *req_pool,
# if PJSIP_AUTH_QOP_SUPPORT
{
if (cached_auth) {
- update_digest_session( sess_pool, cached_auth, hdr );
+ update_digest_session( cached_auth, hdr );
cnonce = &cached_auth->cnonce;
nc = cached_auth->nc;
@@ -961,6 +961,33 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
}
+static void recreate_cached_auth_pool( pjsip_endpoint *endpt,
+ pjsip_cached_auth *auth )
+{
+ pj_pool_t *auth_pool = pjsip_endpt_create_pool(endpt, "regc_auth%p", 1024,
+ 1024);
+
+ if (auth->realm.slen) {
+ pj_str_t realm;
+ pj_strdup(auth_pool, &realm, &auth->realm);
+ pj_strassign(&auth->realm, &realm);
+ }
+
+ if (auth->cnonce.slen) {
+ pj_str_t cnonce;
+ pj_strdup(auth_pool, &cnonce, &auth->cnonce);
+ pj_strassign(&auth->cnonce, &cnonce);
+ }
+
+ if (auth->last_chal) {
+ auth->last_chal = (pjsip_www_authenticate_hdr*)
+ pjsip_hdr_clone(auth_pool, auth->last_chal);
+ }
+
+ pjsip_endpt_release_pool(endpt, auth->pool);
+ auth->pool = auth_pool;
+}
+
/* Process authorization challenge */
static pj_status_t process_auth( pj_pool_t *req_pool,
const pjsip_www_authenticate_hdr *hchal,
@@ -1126,33 +1153,44 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
if (hdr == &rdata->msg_info.msg->hdr)
break;
- hchal = (const pjsip_www_authenticate_hdr*) hdr;
+ hchal = (const pjsip_www_authenticate_hdr*)hdr;
++chal_cnt;
/* Find authentication session for this realm, create a new one
* if not present.
*/
- cached_auth = find_cached_auth(sess, &hchal->challenge.common.realm );
+ cached_auth = find_cached_auth(sess, &hchal->challenge.common.realm);
if (!cached_auth) {
- cached_auth = PJ_POOL_ZALLOC_T( sess->pool, pjsip_cached_auth);
- pj_strdup( sess->pool, &cached_auth->realm, &hchal->challenge.common.realm);
+ cached_auth = PJ_POOL_ZALLOC_T(sess->pool, pjsip_cached_auth);
+ cached_auth->pool = pjsip_endpt_create_pool(sess->endpt,
+ "regc_auth%p",
+ 1024,
+ 1024);
+ pj_strdup(cached_auth->pool, &cached_auth->realm,
+ &hchal->challenge.common.realm);
cached_auth->is_proxy = (hchal->type == PJSIP_H_PROXY_AUTHENTICATE);
# if (PJSIP_AUTH_HEADER_CACHING)
{
pj_list_init(&cached_auth->cached_hdr);
}
# endif
- pj_list_insert_before( &sess->cached_auth, cached_auth );
+ pj_list_insert_before(&sess->cached_auth, cached_auth);
}
/* Create authorization header for this challenge, and update
* authorization session.
*/
- status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri,
- tdata, sess, cached_auth, &hauth);
+ status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
+ tdata, sess, cached_auth, &hauth);
if (status != PJ_SUCCESS)
return status;
+ if (pj_pool_get_used_size(cached_auth->pool) >
+ PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
+ {
+ recreate_cached_auth_pool(sess->endpt, cached_auth);
+ }
+
/* Add to the message. */
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);