Module: sip-router Branch: master Commit: b5638f712711deb8413d7e585369adf8f4a421ee URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b5638f71...
Author: Richard Good richard.good@smilecoms.com Committer: Richard Good richard.good@smilecoms.com Date: Mon Oct 28 14:41:22 2013 +0200
modules/ims_qos: memory optimisation Fixed pkg memory allocation for framed IP AVP and flow buffer AVP Instead of repeatedly alloc'ing and free'ing pkg memory we allocate once and re-use Results in better pkg memory overhead
---
modules/ims_qos/rx_avp.c | 101 +++++++++++++++++++++++++++------------------- 1 files changed, 59 insertions(+), 42 deletions(-)
diff --git a/modules/ims_qos/rx_avp.c b/modules/ims_qos/rx_avp.c index d628192..65c8a43 100644 --- a/modules/ims_qos/rx_avp.c +++ b/modules/ims_qos/rx_avp.c @@ -156,9 +156,12 @@ static inline str rx_get_avp(AAAMessage *msg, int avp_code, int vendor_id, * see http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html * http://beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html */ + +static unsigned int ip_buflen = 0; +static char* ip_buf = 0; + int rx_add_framed_ip_avp(AAA_AVP_LIST * list, str ip, uint16_t version) { ip_address_prefix ip_adr; - char* ip_pkg = 0; int ret = 0;
if (ip.len < 0) return 0; @@ -169,28 +172,36 @@ int rx_add_framed_ip_avp(AAA_AVP_LIST * list, str ip, uint16_t version) { if (ip.len > INET6_ADDRSTRLEN) goto error; } - ip_pkg = (char*) pkg_malloc((ip.len + 1) * sizeof (char)); - if (!ip_pkg) { - LM_ERR("PCC_create_framed_ip_avp: could not allocate %i from pkg\n", ip.len + 1); - goto error; + int len = ip.len + 1; + if (!ip_buf || ip_buflen < len) { + if (ip_buf) + pkg_free(ip_buf); + ip_buf = (char*)pkg_malloc(len); + if (!ip_buf) { + LM_ERR("rx_add_framed_ip_avp: out of memory \ + when allocating %i bytes in pkg\n", len); + goto error; + } + ip_buflen = len; } - memcpy(ip_pkg, ip.s, ip.len); - ip_pkg[ip.len] = '\0'; - + memcpy(ip_buf, ip.s, ip.len); + ip_buf[ip.len] = '\0'; + ip_adr.addr.ai_family = version;
if (version == AF_INET) {
- if (inet_pton(AF_INET, ip_pkg, &(ip_adr.addr.ip.v4.s_addr)) != 1) goto error; + if (inet_pton(AF_INET, ip_buf, &(ip_adr.addr.ip.v4.s_addr)) != 1) goto error; ret = cdp_avp->nasapp.add_Framed_IP_Address(list, ip_adr.addr); } else {
- if (inet_pton(AF_INET6, ip_pkg, &(ip_adr.addr.ip.v6.s6_addr)) != 1) goto error; + if (inet_pton(AF_INET6, ip_buf, &(ip_adr.addr.ip.v6.s6_addr)) != 1) goto error; ret = cdp_avp->nasapp.add_Framed_IPv6_Prefix(list, ip_adr); }
+ //TODO: should free ip_buf in module shutdown.... + error: - if (ip_pkg) pkg_free(ip_pkg); return ret; }
@@ -511,14 +522,17 @@ static char * permit_out_with_ports = "permit out %i from %.*s %u to %.*s %u"; static char * permit_in_with_ports = "permit in %i from %.*s %u to %.*s %u"; //static char * permit_in_with_ports = "permit in %i from %.*s %u to %.*s %u %s";
+static unsigned int flowdata_buflen = 0; +static str flowdata_buf = {0,0}; + AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto, str *ipA, str *portA, str *ipB, str *portB) {
str data; int len, len2; - str flow_data = {0, 0}; - str flow_data2 = {0, 0}; +// str flow_data = {0, 0}; +// str flow_data2 = {0, 0}; AAA_AVP *flow_description1 = 0, *flow_description2 = 0, *flow_number = 0; AAA_AVP *flow_usage = 0;
@@ -536,21 +550,16 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto, len = (permit_out.len + from_s.len + to_s.len + ipB->len + ipA->len + 4 + proto_len + portA->len + portB->len) * sizeof (char);
- flow_data.s = (char*) pkg_malloc(len); - if (!flow_data.s) { - LM_ERR("PCC_create_media_component: out of memory \ - when allocating %i bytes in pkg\n", len); - return NULL; - } - - len2 = len - (permit_out.len - permit_in.len) * sizeof (char); - flow_data2.s = (char*) pkg_malloc(len2); - if (!flow_data2.s) { - LM_ERR("PCC_create_media_component: out of memory \ - when allocating %i bytes in pkg\n", len); - pkg_free(flow_data.s); - flow_data.s = 0; - return NULL; + if (!flowdata_buf.s || flowdata_buflen < len) { + if (flowdata_buf.s) + pkg_free(flowdata_buf.s); + flowdata_buf.s = (char*)pkg_malloc(len); + if (!flowdata_buf.s) { + LM_ERR("PCC_create_media_component: out of memory \ + when allocating %i bytes in pkg\n", len); + return NULL ; + } + flowdata_buflen = len; }
set_4bytes(x, number); @@ -563,26 +572,39 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto,
/*IMS Flow descriptions*/ /*first flow is the receive flow*/ - flow_data.len = snprintf(flow_data.s, len, permit_out_with_ports, proto_int, + flowdata_buf.len = snprintf(flowdata_buf.s, len, permit_out_with_ports, proto_int, ipB->len, ipB->s, intportB, ipA->len, ipA->s, intportA);
- flow_data.len = strlen(flow_data.s); + flowdata_buf.len = strlen(flowdata_buf.s); flow_description1 = cdpb.AAACreateAVP(AVP_IMS_Flow_Description, AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC, - IMS_vendor_id_3GPP, flow_data.s, flow_data.len, + IMS_vendor_id_3GPP, flowdata_buf.s, flowdata_buf.len, AVP_DUPLICATE_DATA); cdpb.AAAAddAVPToList(&list, flow_description1);
- /*second flow*/ - flow_data2.len = snprintf(flow_data2.s, len2, permit_in_with_ports, proto_int, + /*second flow*/ + len2 = len - (permit_out.len - permit_in.len) * sizeof (char); + if (!flowdata_buf.s || flowdata_buflen <= len2) { + if (flowdata_buf.s) + pkg_free(flowdata_buf.s); + flowdata_buf.s = (char*) pkg_malloc(len2); + if (!flowdata_buf.s) { + LM_ERR("PCC_create_media_component: out of memory \ + when allocating %i bytes in pkg\n", len2); + return NULL ; + } + flowdata_buflen = len2; + } + + flowdata_buf.len = snprintf(flowdata_buf.s, len2, permit_in_with_ports, proto_int, ipA->len, ipA->s, intportA, ipB->len, ipB->s, intportB);
- flow_data2.len = strlen(flow_data2.s); + flowdata_buf.len = strlen(flowdata_buf.s); flow_description2 = cdpb.AAACreateAVP(AVP_IMS_Flow_Description, AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC, - IMS_vendor_id_3GPP, flow_data2.s, flow_data2.len, + IMS_vendor_id_3GPP, flowdata_buf.s, flowdata_buf.len, AVP_DUPLICATE_DATA); cdpb.AAAAddAVPToList(&list, flow_description2);
@@ -596,13 +618,9 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto, /*group all AVPS into one big.. and then free the small ones*/
data = cdpb.AAAGroupAVPS(list); - - cdpb.AAAFreeAVPList(&list); - pkg_free(flow_data.s); - flow_data.s = 0; - pkg_free(flow_data2.s); - flow_data2.s = 0; + + //TODO: should free the buffer for the flows in module shutdown....
return (cdpb.AAACreateAVP(AVP_IMS_Media_Sub_Component, AAA_AVP_FLAG_MANDATORY | AAA_AVP_FLAG_VENDOR_SPECIFIC, @@ -610,7 +628,6 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, char* proto, AVP_FREE_DATA)); }
- //just for registration to signalling status much cut down MSC AVP //see 3GPP TS 29.214 4.4.5