From 7224fb899a0bdfb47773329a227f4bca452b2748 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 2 Jan 2008 08:24:10 +0000 Subject: Ticket #437: reduce stack and pool usage on pjnath to make it work better on Symbian git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1654 74dad513-b988-da41-8d7b-12977e46ad98 --- pjnath/include/pjnath/config.h | 51 +++++++++++++++++++++++++ pjnath/include/pjnath/ice_session.h | 7 ++++ pjnath/src/pjnath/ice_session.c | 76 +++++++++++++++++++++---------------- pjnath/src/pjnath/ice_strans.c | 3 +- pjnath/src/pjnath/nat_detect.c | 3 +- pjnath/src/pjnath/stun_msg.c | 18 +++++++++ pjnath/src/pjnath/stun_msg_dump.c | 4 +- pjnath/src/pjnath/stun_session.c | 13 ++++--- 8 files changed, 134 insertions(+), 41 deletions(-) diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h index bc381d78..c84fe18c 100644 --- a/pjnath/include/pjnath/config.h +++ b/pjnath/include/pjnath/config.h @@ -255,6 +255,57 @@ #endif +/** ICE session pool initial size. */ +#ifndef PJNATH_POOL_LEN_ICE_SESS +# define PJNATH_POOL_LEN_ICE_SESS 512 +#endif + +/** ICE session pool increment size */ +#ifndef PJNATH_POOL_INC_ICE_SESS +# define PJNATH_POOL_INC_ICE_SESS 512 +#endif + +/** ICE stream transport pool initial size. */ +#ifndef PJNATH_POOL_LEN_ICE_STRANS +# define PJNATH_POOL_LEN_ICE_STRANS 1000 +#endif + +/** ICE stream transport pool increment size */ +#ifndef PJNATH_POOL_INC_ICE_STRANS +# define PJNATH_POOL_INC_ICE_STRANS 512 +#endif + +/** NAT detect pool initial size */ +#ifndef PJNATH_POOL_LEN_NATCK +# define PJNATH_POOL_LEN_NATCK 512 +#endif + +/** NAT detect pool increment size */ +#ifndef PJNATH_POOL_INC_NATCK +# define PJNATH_POOL_INC_NATCK 512 +#endif + +/** STUN session pool initial size */ +#ifndef PJNATH_POOL_LEN_STUN_SESS +# define PJNATH_POOL_LEN_STUN_SESS 1000 +#endif + +/** STUN session pool increment size */ +#ifndef PJNATH_POOL_INC_STUN_SESS +# define PJNATH_POOL_INC_STUN_SESS 1000 +#endif + +/** STUN session transmit data pool initial size */ +#ifndef PJNATH_POOL_LEN_STUN_TDATA +# define PJNATH_POOL_LEN_STUN_TDATA 1000 +#endif + +/** STUN session transmit data pool increment size */ +#ifndef PJNATH_POOL_INC_STUN_TDATA +# define PJNATH_POOL_INC_STUN_TDATA 1000 +#endif + + /** * @} */ diff --git a/pjnath/include/pjnath/ice_session.h b/pjnath/include/pjnath/ice_session.h index 032b2dcb..2af223f3 100644 --- a/pjnath/include/pjnath/ice_session.h +++ b/pjnath/include/pjnath/ice_session.h @@ -25,6 +25,7 @@ */ #include #include +#include #include #include @@ -560,6 +561,12 @@ struct pj_ice_sess /* Valid list */ pj_ice_sess_checklist valid_list; /**< Valid list. */ + + /* Temporary buffer for misc stuffs to avoid using stack too much */ + union { + char txt[128]; + char errmsg[PJ_ERR_MSG_SIZE]; + } tmp; }; diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c index f98c25d9..5941a26e 100644 --- a/pjnath/src/pjnath/ice_session.c +++ b/pjnath/src/pjnath/ice_session.c @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include #include @@ -261,7 +260,8 @@ PJ_DEF(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg, if (name == NULL) name = "ice%p"; - pool = pj_pool_create(stun_cfg->pf, name, 4000, 4000, NULL); + pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS, + PJNATH_POOL_INC_ICE_SESS, NULL); ice = PJ_POOL_ZALLOC_T(pool, pj_ice_sess); ice->pool = pool; ice->role = role; @@ -557,7 +557,6 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, { pj_ice_sess_cand *lcand; pj_status_t status = PJ_SUCCESS; - char tmp[128]; PJ_ASSERT_RETURN(ice && comp_id && foundation && addr && base_addr && addr_len, @@ -584,7 +583,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, pj_bzero(&lcand->rel_addr, sizeof(lcand->rel_addr)); - pj_ansi_strcpy(tmp, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); + pj_ansi_strcpy(ice->tmp.txt, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); LOG4((ice->obj_name, "Candidate %d added: comp_id=%d, type=%s, foundation=%.*s, " "addr=%s:%d, base=%s:%d, prio=0x%x (%u)", @@ -593,7 +592,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, cand_type_names[lcand->type], (int)lcand->foundation.slen, lcand->foundation.ptr, - tmp, + ice->tmp.txt, (int)pj_ntohs(lcand->addr.ipv4.sin_port), pj_inet_ntoa(lcand->base_addr.ipv4.sin_addr), (int)pj_htons(lcand->base_addr.ipv4.sin_port), @@ -733,9 +732,11 @@ static const char *dump_check(char *buffer, unsigned bufsize, { const pj_ice_sess_cand *lcand = check->lcand; const pj_ice_sess_cand *rcand = check->rcand; - char laddr[CHECK_NAME_LEN]; + char laddr[PJ_INET6_ADDRSTRLEN]; int len; + PJ_CHECK_STACK(); + pj_ansi_strcpy(laddr, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); if (lcand->addr.addr.sa_family == pj_AF_INET()) { @@ -760,17 +761,16 @@ static const char *dump_check(char *buffer, unsigned bufsize, return buffer; } -static void dump_checklist(const char *title, const pj_ice_sess *ice, +static void dump_checklist(const char *title, pj_ice_sess *ice, const pj_ice_sess_checklist *clist) { unsigned i; - char buffer[CHECK_NAME_LEN]; LOG4((ice->obj_name, "%s", title)); for (i=0; icount; ++i) { const pj_ice_sess_check *c = &clist->checks[i]; LOG4((ice->obj_name, " %s (%s, state=%s)", - dump_check(buffer, sizeof(buffer), clist, c), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, c), (c->nominated ? "nominated" : "not nominated"), check_state_name[c->state])); } @@ -784,12 +784,10 @@ static void check_set_state(pj_ice_sess *ice, pj_ice_sess_check *check, pj_ice_sess_check_state st, pj_status_t err_code) { - char buf[CHECK_NAME_LEN]; - pj_assert(check->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED); LOG5((ice->obj_name, "Check %s: state changed from %s to %s", - dump_check(buf, sizeof(buf), &ice->clist, check), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), &ice->clist, check), check_state_name[check->state], check_state_name[st])); check->state = st; @@ -937,11 +935,9 @@ static pj_status_t prune_checklist(pj_ice_sess *ice, if (reason != NULL) { /* Found duplicate, remove it */ - char buf[CHECK_NAME_LEN]; - LOG5((ice->obj_name, "Check %s pruned (%s)", - dump_check(buf, sizeof(buf), &ice->clist, - &clist->checks[j]), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, &clist->checks[j]), reason)); pj_array_erase(clist->checks, sizeof(clist->checks[0]), @@ -975,14 +971,13 @@ static void on_completion_timer(pj_timer_heap_t *th, static void on_ice_complete(pj_ice_sess *ice, pj_status_t status) { if (!ice->is_complete) { - char errmsg[PJ_ERR_MSG_SIZE]; - ice->is_complete = PJ_TRUE; ice->ice_status = status; /* Log message */ LOG4((ice->obj_name, "ICE process complete, status=%s", - pj_strerror(status, errmsg, sizeof(errmsg)).ptr)); + pj_strerror(status, ice->tmp.errmsg, + sizeof(ice->tmp.errmsg)).ptr)); dump_checklist("Valid list", ice, &ice->valid_list); @@ -1056,7 +1051,6 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice, */ if (check->err_code==PJ_SUCCESS && check->nominated) { pj_ice_sess_comp *comp; - char buf[CHECK_NAME_LEN]; LOG5((ice->obj_name, "Check %d is successful and nominated", GET_CHECK_ID(&ice->clist, check))); @@ -1074,7 +1068,8 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice, /* Just fail Frozen/Waiting check */ LOG5((ice->obj_name, "Check %s to be failed because state is %s", - dump_check(buf, sizeof(buf), &ice->clist, c), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, c), check_state_name[c->state])); check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED, PJ_ECANCELLED); @@ -1087,7 +1082,8 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice, if (c->tdata) { LOG5((ice->obj_name, "Cancelling check %s (In Progress)", - dump_check(buf, sizeof(buf), &ice->clist, c))); + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, c))); pj_stun_session_cancel_req(comp->stun_sess, c->tdata, PJ_FALSE, 0); c->tdata = NULL; @@ -1368,7 +1364,6 @@ static pj_status_t perform_check(pj_ice_sess *ice, const pj_ice_sess_cand *lcand; const pj_ice_sess_cand *rcand; pj_uint32_t prio; - char buffer[128]; pj_status_t status; check = &clist->checks[check_id]; @@ -1378,7 +1373,7 @@ static pj_status_t perform_check(pj_ice_sess *ice, LOG5((ice->obj_name, "Sending connectivity check for check %s", - dump_check(buffer, sizeof(buffer), clist, check))); + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, check))); /* Create request */ status = pj_stun_session_create_req(comp->stun_sess, @@ -1553,9 +1548,11 @@ PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice) { pj_ice_sess_checklist *clist; const pj_ice_sess_cand *cand0; - const pj_str_t *flist[PJ_ICE_MAX_CAND]; + const pj_str_t *flist[PJ_ICE_MAX_CAND]; // XXX pj_ice_rx_check *rcheck; unsigned i, flist_cnt = 0; + pj_time_val delay; + pj_status_t status; PJ_ASSERT_RETURN(ice, PJ_EINVAL); @@ -1624,7 +1621,19 @@ PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice) pj_list_init(&ice->early_check); /* Start periodic check */ - return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer); + /* We could start it immediately like below, but lets schedule timer + * instead to reduce stack usage: + * return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer); + */ + clist->timer.id = PJ_TRUE; + delay.sec = delay.msec = 0; + status = pj_timer_heap_schedule(ice->stun_cfg.timer_heap, + &clist->timer, &delay); + if (status != PJ_SUCCESS) { + clist->timer.id = PJ_FALSE; + } + + return status; } @@ -1661,7 +1670,6 @@ static void on_stun_request_complete(pj_stun_session *stun_sess, pj_ice_sess_cand *lcand; pj_ice_sess_checklist *clist; pj_stun_xor_mapped_addr_attr *xaddr; - char buffer[CHECK_NAME_LEN]; unsigned i; PJ_UNUSED_ARG(stun_sess); @@ -1730,7 +1738,8 @@ static void on_stun_request_complete(pj_stun_session *stun_sess, pj_strerror(status, errmsg, sizeof(errmsg)); LOG4((ice->obj_name, "Check %s%s: connectivity check FAILED: %s", - dump_check(buffer, sizeof(buffer), &ice->clist, check), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, check), (check->nominated ? " (nominated)" : " (not nominated)"), errmsg)); @@ -1753,7 +1762,8 @@ static void on_stun_request_complete(pj_stun_session *stun_sess, status = PJNATH_EICEINSRCADDR; LOG4((ice->obj_name, "Check %s%s: connectivity check FAILED: source address mismatch", - dump_check(buffer, sizeof(buffer), &ice->clist, check), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, check), (check->nominated ? " (nominated)" : " (not nominated)"))); check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status); on_check_complete(ice, check); @@ -1779,7 +1789,8 @@ static void on_stun_request_complete(pj_stun_session *stun_sess, LOG4((ice->obj_name, "Check %s%s: connectivity check SUCCESS", - dump_check(buffer, sizeof(buffer), &ice->clist, check), + dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), + &ice->clist, check), (check->nominated ? " (nominated)" : " (not nominated)"))); /* Get the STUN XOR-MAPPED-ADDRESS attribute. */ @@ -2357,10 +2368,9 @@ PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, PJ_STUN_IS_DATAGRAM, NULL, src_addr, src_addr_len); if (status != PJ_SUCCESS) { - char errmsg[PJ_ERR_MSG_SIZE]; - pj_strerror(status, errmsg, sizeof(errmsg)); + pj_strerror(status, ice->tmp.errmsg, sizeof(ice->tmp.errmsg)); LOG4((ice->obj_name, "Error processing incoming message: %s", - errmsg)); + ice->tmp.errmsg)); } } else { (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size, diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c index a37fff12..5b3c8a13 100644 --- a/pjnath/src/pjnath/ice_strans.c +++ b/pjnath/src/pjnath/ice_strans.c @@ -97,7 +97,8 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( pj_stun_config *stun_cfg, if (name == NULL) name = "icstr%p"; - pool = pj_pool_create(stun_cfg->pf, name, 1000, 512, NULL); + pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_STRANS, + PJNATH_POOL_INC_ICE_STRANS, NULL); ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans); ice_st->pool = pool; pj_memcpy(ice_st->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME); diff --git a/pjnath/src/pjnath/nat_detect.c b/pjnath/src/pjnath/nat_detect.c index 7fe469d7..d5062a38 100644 --- a/pjnath/src/pjnath/nat_detect.c +++ b/pjnath/src/pjnath/nat_detect.c @@ -220,7 +220,8 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server, /* * Init NAT detection session. */ - pool = pj_pool_create(stun_cfg->pf, "natck%p", 512, 512, NULL); + pool = pj_pool_create(stun_cfg->pf, "natck%p", PJNATH_POOL_LEN_NATCK, + PJNATH_POOL_INC_NATCK, NULL); if (!pool) return PJ_ENOMEM; diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c index 125b3bda..9590fee6 100644 --- a/pjnath/src/pjnath/stun_msg.c +++ b/pjnath/src/pjnath/stun_msg.c @@ -707,6 +707,8 @@ static pj_status_t decode_sockaddr_attr(pj_pool_t *pool, pj_stun_sockaddr_attr *attr; pj_uint32_t val; + PJ_CHECK_STACK(); + /* Create the attribute */ attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr); GETATTRHDR(buf, &attr->hdr); @@ -771,6 +773,8 @@ static pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf, if (len < ATTR_LEN) return PJ_ETOOSMALL; + PJ_CHECK_STACK(); + /* Copy and convert headers to network byte order */ PUTVAL16H(buf, 0, ca->hdr.type); PUTVAL16H(buf, 2, STUN_GENERIC_IP_ADDR_LEN); @@ -899,6 +903,8 @@ static pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf, const pj_stun_string_attr *ca = (const pj_stun_string_attr*)a; + PJ_CHECK_STACK(); + /* Calculated total attr_len (add padding if necessary) */ *printed = (ca->value.slen + ATTR_HDR_LEN + 3) & (~3); if (len < *printed) { @@ -1080,6 +1086,8 @@ static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, { const pj_stun_uint_attr *ca = (const pj_stun_uint_attr*)a; + PJ_CHECK_STACK(); + if (len < 8) return PJ_ETOOSMALL; @@ -1163,6 +1171,8 @@ static pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf, { const pj_stun_uint64_attr *ca = (const pj_stun_uint64_attr*)a; + PJ_CHECK_STACK(); + if (len < 12) return PJ_ETOOSMALL; @@ -1242,6 +1252,8 @@ static pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf, { const pj_stun_msgint_attr *ca = (const pj_stun_msgint_attr*)a; + PJ_CHECK_STACK(); + if (len < 24) return PJ_ETOOSMALL; @@ -1346,6 +1358,8 @@ static pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf, const pj_stun_errcode_attr *ca = (const pj_stun_errcode_attr*)a; + PJ_CHECK_STACK(); + if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen) return PJ_ETOOSMALL; @@ -1461,6 +1475,8 @@ static pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf, pj_uint16_t *dst_unk_attr; unsigned i; + PJ_CHECK_STACK(); + /* Check that buffer is enough */ if (len < ATTR_HDR_LEN + (ca->attr_count << 1)) return PJ_ETOOSMALL; @@ -1561,6 +1577,8 @@ static pj_status_t encode_binary_attr(const void *a, pj_uint8_t *buf, { const pj_stun_binary_attr *ca = (const pj_stun_binary_attr*)a; + PJ_CHECK_STACK(); + /* Calculated total attr_len (add padding if necessary) */ *printed = (ca->length + ATTR_HDR_LEN + 3) & (~3); if (len < *printed) diff --git a/pjnath/src/pjnath/stun_msg_dump.c b/pjnath/src/pjnath/stun_msg_dump.c index 3ca9a80b..13fd4038 100644 --- a/pjnath/src/pjnath/stun_msg_dump.c +++ b/pjnath/src/pjnath/stun_msg_dump.c @@ -19,9 +19,9 @@ #include #include #include +#include #include - #if PJ_LOG_MAX_LEVEL > 0 @@ -236,6 +236,8 @@ PJ_DEF(char*) pj_stun_msg_dump(const pj_stun_msg *msg, PJ_ASSERT_RETURN(msg && buffer && length, NULL); + PJ_CHECK_STACK(); + p = buffer; end = buffer + length; diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c index 42e898d2..0f9fc733 100644 --- a/pjnath/src/pjnath/stun_session.c +++ b/pjnath/src/pjnath/stun_session.c @@ -45,8 +45,8 @@ struct pj_stun_session #define LOG_ERR_(sess,title,rc) pjnath_perror(sess->pool->obj_name,title,rc) -#define TDATA_POOL_SIZE 1024 -#define TDATA_POOL_INC 1024 +#define TDATA_POOL_SIZE PJNATH_POOL_LEN_STUN_TDATA +#define TDATA_POOL_INC PJNATH_POOL_INC_STUN_TDATA static void stun_tsx_on_complete(pj_stun_client_tsx *tsx, @@ -383,9 +383,10 @@ PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_config *cfg, PJ_ASSERT_RETURN(cfg && cb && p_sess, PJ_EINVAL); if (name==NULL) - name = "sess%p"; + name = "stuse%p"; - pool = pj_pool_create(cfg->pf, name, 4000, 4000, NULL); + pool = pj_pool_create(cfg->pf, name, PJNATH_POOL_LEN_STUN_SESS, + PJNATH_POOL_INC_STUN_SESS, NULL); PJ_ASSERT_RETURN(pool, PJ_ENOMEM); sess = PJ_POOL_ZALLOC_T(pool, pj_stun_session); @@ -995,7 +996,9 @@ PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); - tmp_pool = pj_pool_create(sess->cfg->pf, "tmpstun", 1024, 1024, NULL); + tmp_pool = pj_pool_create(sess->cfg->pf, "tmpstun", + PJNATH_POOL_LEN_STUN_TDATA, + PJNATH_POOL_INC_STUN_TDATA, NULL); if (!tmp_pool) return PJ_ENOMEM; -- cgit v1.2.3