I have a program for k60 MQX 4.0 that receives SNMP packets through UDP, the problem is that i don't understand why the RAM memory fills more and more with every packet till TCPIP task falls with Out of memory error.
Hello Cristobal,
are you using a new socket each time you send/receive data? You may need to provide more details about your application, and how are you implementing this task. But it sound like you are using new resources each time you send/receive data and they are not being released.
Best regards,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
After a lot of debub testing I conclude that the problem is there:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
void SNMP_task
(
pointer traps,
pointer creator
)
{ /* Body */
SNMP_PARSE snmp;
sockaddr_in addr;
uint_32 sock, error, count;
int_32 inlen, j;
uint_32 outlen,time;
uint_16 addrlen;
uint_32 option;
char_ptr community_array[] = SNMPCFG_COMMUNITY_LIST;
_ip_address _PTR_ trap_receiver_list_ptr = (_ip_address _PTR_)traps;
SNMP_CONTEXT snmp_context = { 0 };
SNMP_task_id = RTCS_task_getid();
#ifdef __MQX__
/* Set up exit handler and context so that we can clean up if the SNMP agent is terminated */
_task_set_environment( _task_get_id(), (pointer) &snmp_context );
_task_set_exit_handler( _task_get_id(), SNMP_Exit_handler );
#endif
/* SNMP agent services port 161 */
addr.sin_family = AF_INET;
addr.sin_port = IPPORT_SNMP;
addr.sin_addr.s_addr = INADDR_ANY;
/* Bind to UDP port */
snmp_context.UDPSOCK = socket(PF_INET, SOCK_DGRAM, 0);
sock = snmp_context.UDPSOCK;
if (sock == RTCS_SOCKET_ERROR) {
RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
} /* Endif */
/* Begin ENGR00243356 */
/* Set socket options to no wait */
option = TRUE;
setsockopt(sock, SOL_UDP, OPT_SEND_NOWAIT, &option, sizeof(option));
/* End ENGR00243356 */
error = bind(sock, &addr, sizeof(addr));
if (error) {
RTCS_task_exit(creator, error);
} /* Endif */
IF_SNMP_STATS_ENABLED(_mem_zero(&snmp.STATS, sizeof(snmp.STATS)));
snmp.trapsock = sock;
snmp.currentcommunity = 0;
for (j = 0; j < SNMPCFG_NUM_COMMUNITY; j++) {
snmp.community[j] = community_array[j];
snmp.communitylen[j] = strlen((const char *)(community_array[j]));
} /* Endfor */
for (j = 0; j < SNMPCFG_MAX_TRAP_RECEIVERS; j++)
snmp.trap_receiver_list[j] = 0;
if(trap_receiver_list_ptr != NULL) {
count = 0;
while(*trap_receiver_list_ptr != 0 && count < SNMPCFG_MAX_TRAP_RECEIVERS) {
snmp.trap_receiver_list[count] = *trap_receiver_list_ptr;
trap_receiver_list_ptr++;
count++;
} /* Endwhile */
} /* Endif */
SNMP_set_data(&snmp);
RTCS_task_resume_creator(creator, RTCS_OK);
/* Send some traps -- but only if the application has added some traps receivers */
if (RTCS_count_trap_receivers_internal() != 0) {
SNMP_trap_select_community(snmp.community[0]);
time = RTCS_time_get();
if(time < 30) {
#ifdef SNMPCFG_SEND_V2_TRAPS
SNMPv2_trap_coldStart();
#else
SNMP_trap_coldStart();
#endif
} else {
#ifdef SNMPCFG_SEND_V2_TRAPS
SNMPv2_trap_warmStart();
#else
SNMP_trap_warmStart();
#endif
} /* Endif */
} /* Endif */
for (;;) {
addrlen = sizeof(addr);
inlen = recvfrom(sock, inbuf, SNMPCFG_BUFFER_SIZE, 0, &addr, &addrlen);
IF_SNMP_STATS_ENABLED(snmp.STATS.COMMON.ST_RX_TOTAL++);
snmp.inbuf = inbuf;
snmp.inlen = inlen;
snmp.outbuf = outbuf;
snmp.outlen = SNMPCFG_BUFFER_SIZE;
snmp.pdutype = 0; /* anything except ASN1_TYPE_PDU_SET */
snmp.errstat = SNMP_ERROR_noError;
snmp.errindex = 0;
if (SNMP_parse(&snmp, &outlen)) {
IF_SNMP_STATS_ENABLED(snmp.STATS.COMMON.ST_TX_TOTAL++);
IF_SNMP_STATS_ENABLED(snmp.STATS.ST_TX_RESPONSE++);
sendto(sock, snmp.outbuf, outlen, 0, &addr, addrlen);
} else if (snmp.errstat || snmp.pdutype == ASN1_TYPE_PDU_SET) {
if (snmp.errindex >= 0xFF) {
snmp.errstat = SNMP_ERROR_tooBig;
snmp.errindex = 0;
} /* Endif */
*snmp.errstatp = snmp.errstat;
*snmp.errindexp = snmp.errindex;
#if RTCSCFG_ENABLE_SNMP_STATS
snmp.STATS.COMMON.ST_TX_TOTAL++;
snmp.STATS.ST_TX_RESPONSE++;
switch (snmp.errstat) {
case SNMP_ERROR_noError: break;
case SNMP_ERROR_tooBig: snmp.STATS.ST_TX_TOOBIG++; break;
case SNMP_ERROR_noSuchName: snmp.STATS.ST_TX_NOSUCHNAME++; break;
case SNMP_ERROR_badValue: snmp.STATS.ST_TX_BADVALUE++; break;
case SNMP_ERROR_readOnly: snmp.STATS.ST_TX_READONLY++; break;
case SNMP_ERROR_genErr: snmp.STATS.ST_TX_GENERR++; break;
default: snmp.STATS.ST_TX_OTHER++; break;
} /* Endswitch */
#endif
sendto(sock, inbuf, inlen, 0, &addr, addrlen);
...
} /* Endbody */
----------------------------------------------------------------------------------------------------------------------------------------------------
int_32 SOCK_DGRAM_sendto
(
uint_32 sock,
/* [IN] socket handle */
pointer send_buffer,
/* [IN] data to transmit */
uint_32 buflen,
/* [IN] length of the buffer, in bytes */
uint_32 flags,
/* [IN] flags to underlying protocols */
sockaddr _PTR_ destaddr,
/* [IN] address to which to send data */
uint_16 addrlen
/* [IN] length of the address, in bytes */
)
{ /* Body */
...
error = RTCSCMD_issue(parms, UDP_send);
...
} /* Endbody */
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void UDP_send
(
UDP_PARM_PTR parms
)
{ /* Body */
...
udpbuffer = RTCS_mem_alloc_system(parms->udpword);
...
} /* Endbody */
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The socket is not changing and the memory allocate and allocate till run out of memory.
How can I solve this?
Hi Cristobal,
TCP and UDP sockets have a timeout before resources are being released. In this case it looks like you are sending many message and SNMP_task is creating new sockets each time a message is sent while other sockets remain alive.
You can use function setsockopt() to manage sockets timeouts. These timeouts are declared in tcp_prv.h on RTCS project.
#define TCP_MSL 120000L /* Maximum Segment Lifetime; the longest time that a packet can travel in the Internet (2 min) */
#define TCP_WAITTIMEOUT (2 * TCP_MSL) /* timeout for TIME_WAIT state, defined as 2 * MSL (4 min) */
#define TCP_SENDTIMEOUT_MIN 100000L /* as per RFC1122 4.2.3.5 */
#define TCP_OPENTIMEOUT_MIN 180000L /* as per RFC1122 4.2.3.5 */
But you can override these values with setsockopt().
You can also increase the number of sockets. It is possible customize runtime RTCS configuration before call the function RTCS_create() just as the web_hvac does in the C:\Freescale\Freescale MQX 4.0\demo\web_hvac\RTCS.c file.
/* runtime RTCS configuration */
_RTCSPCB_init = 4;
_RTCSPCB_grow = 2;
_RTCSPCB_max = 20;
_RTCS_msgpool_init = 4;
_RTCS_msgpool_grow = 2;
_RTCS_msgpool_max = 20;
_RTCS_socket_part_init = 4;
_RTCS_socket_part_grow = 2;
_RTCS_socket_part_max = 20;
You can also edit SNMP_task to shutdown and destroy socket after being used. However you must consider that this may impact in other tasks.
Have a great day,
Carlos
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I have tested with setsockopt and with de direct definitions but nothing changes every send udp transmision coming from SNMP task fill the memory tills it goes out of memory.
My sockets are not increasing.
RTCS Configuration
RTCS Version: 3.0800
Initialized? Yes
RTCS Task ID: 0x00010006
RTCS Options:
Priority: 6 Stack Size: 0xbb8 (3000)
IP Forwarding: Disabled RTO Minimum: 15
DHCP Broadcast: No UDP Max Queue Size: 1
Bypass Rx Checksum: No Bypass Tx Checksum: No
RTCS Queue base: 0x2 TCPIP Queue: 0x102
RTCS Buffers:
Item Init Grow Max Partition
PCBs: 4 2 20 0x200030d0
Messsages: 4 2 20 0x20001d00
Sockets: 4 2 20 0x20002070
RTCS Partition
RTCS Partition: 0x20002070
RTCS Part. Block Size: 176
RTCS Part. Free blocks: 3
RTCS Part. Constructor: None
RTCS Part. Destructor: None
MQX Partition Information:
Partition: 0x20002090
Type: Dynamic
Block Size: 0xc0
Free#: 0
Total#: 4
Max Used: 4
Grow#: 2
Limit: 20
Address State Owner
0x200020dc Owned System
0x2000219c Owned System
0x2000225c Owned System
0x2000231c Owned System