Module: sip-router
Branch: master
Commit: b5638f712711deb8413d7e585369adf8f4a421ee
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b5638f7…
Author: Richard Good <richard.good(a)smilecoms.com>
Committer: Richard Good <richard.good(a)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