SNMP and RTCS: Out of memory

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SNMP and RTCS: Out of memory

1,386 Views
scary2021
Contributor II

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.

Tags (1)
0 Kudos
Reply
4 Replies

1,065 Views
Carlos_Musich
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

1,065 Views
scary2021
Contributor II

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?

0 Kudos
Reply

1,065 Views
Carlos_Musich
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

1,065 Views
scary2021
Contributor II

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                                                            

0 Kudos
Reply