[Tinyos-devel] Bug in TossimActiveMessageC

Lumir Honus foldus at gmail.com
Wed Jan 21 20:07:38 PST 2009


My application consists from several parts, but I think that most
important are ForgedActiveMessageP and ParserC.

First I explain my motivation. I need my application to be *invisible*
for end user. It will be library, which user links to his project and
it provides IDS functionality. Core of this application has to be
independent on used network library.  I need to parse packets before
any higher layer can do that, and also check outgoing packets.

Therefore I forged AMQueueP, AMReceiverC, AMSenderC and AMSnooperC and
redirected Receive, Snoop and Send to ForgedActiveMessage.

ForgedActiveMessage uses interface TrafficDebug (which is provided by
ParserC) and dumps ongoing communication to ParserC. Afterwards it
forwards packets to higher/lower layers.

I attach main modules, hope it will be sufficient. I don't have any
experiences with tinyos so the problem is likely to be in my code than
in ctp.


module ForgedActiveMessageP{
 provides{
               interface AMSend[uint8_t id];
               interface Receive[uint8_t id];
               interface Receive as Snoop[uint8_t id];
 }
 uses {
   interface AMSend as ExtAMSend[uint8_t];
   interface Receive as ExtReceive[uint8_t];
   interface Receive as ExtSnoop[uint8_t];
   interface AMPacket;

   interface TrafficDebug;
 }
}

implementation
{

 /********** AMSend ************************/
 command error_t
 AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len) {
   uint8_t packet_type = call AMPacket.type(msg);
   call TrafficDebug.logSent(packet_type,msg,len);
   return call ExtAMSend.send[packet_type](addr,msg,len);
 }

 command error_t AMSend.cancel[uint8_t id](message_t* msg) {
   return call ExtAMSend.cancel[id](msg);
 }

 command uint8_t AMSend.maxPayloadLength[uint8_t id]() {
   return call ExtAMSend.maxPayloadLength[id]();
 }

 command void* AMSend.getPayload[uint8_t id](message_t* msg, uint8_t len) {
   return call AMSend.getPayload[call AMPacket.type(msg)](msg,len);
 }

 event void ExtAMSend.sendDone[uint8_t id](message_t* msg, error_t error)
       {
               signal AMSend.sendDone[call AMPacket.type(msg)](msg, error);
       }

 default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error)
       {
       }


 /********* AM RECEIVE ********************/
 event message_t*
 ExtReceive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
               am_id_t type = call AMPacket.type(msg);
   call TrafficDebug.logReceived(type,msg,len);
   signal Receive.receive[type](msg, payload, len);
   return msg;
 }

 default event message_t*
 Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
   return msg;
 }

 /********* AM SNOOP **********************/
 event message_t*
 ExtSnoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
   uint8_t type = call AMPacket.type(msg);
   call TrafficDebug.logSnooped(type,msg,len);
   signal Snoop.receive[type](msg, payload, len);
   return msg;
 }

 default event message_t*
 Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
   return msg;
 }


 /******************************************/
 default command error_t TrafficDebug.logReceived(uint8_t type,
message_t* msg, uint8_t len)
 {
     return SUCCESS;
 }

 default command error_t TrafficDebug.logSnooped(uint8_t type,
message_t* msg, uint8_t len){
     return SUCCESS;
 }

 default command error_t TrafficDebug.logSent(uint8_t type,
message_t* msg, uint8_t len){
     return SUCCESS;
 }
}


#include "NbTable.h"

module ParserC{
       uses interface AMPacket;
       uses interface Packet;
       uses interface NbTable;

       uses interface IStorage;

       provides interface TrafficDebug;
}

implementation{
       /* Log received packet */
       command error_t TrafficDebug.logReceived(uint8_t type, message_t*
msg, uint8_t len){
               int i;

               am_addr_t source = call AMPacket.source(msg);
               am_addr_t destination = call AMPacket.destination(msg);
               uint8_t payload_length = call Packet.payloadLength(msg);
               uint8_t* ptr =  call Packet.getPayload(msg, len);

               dbg("IDS-parser","Parser:Received: packet from %d with
destination
%d ", source, destination);
       for(i=0;i<len;i++){
           dbg_clear("IDS-istorage","%d ", ptr[i]);
       }

       dbg_clear("IDS-istorage","\n");
               /**
                * If received packet is multicast, update neighbor table
                */
                if(destination == 65535){
                    call NbTable.update(source);
                }

               return SUCCESS;
       }

       /* Log snooped packet */
       command error_t TrafficDebug.logSnooped(uint8_t type, message_t*
msg, uint8_t len){

               int i;

               am_addr_t source = call AMPacket.source(msg);
               am_addr_t destination = call AMPacket.destination(msg);
               uint8_t payload_length = call Packet.payloadLength(msg);
               uint8_t* ptr =  call Packet.getPayload(msg, len);

               dbg("IDS-parser","Parser:Snooped: packet from %d with
destination %d
\n", source, destination);
               atomic{
           if( call NbTable.isWatched(destination) ){
              call IStorage.storeSimplePacket(source, destination, ptr,
payload_length);
           }

           if( call NbTable.isWatched(source)){
              uint16_t origin = ptr[4]*256 + ptr[5];// fix this
              /** it is forwarded packet, should be stored */
              if(origin != source){
                  dbg("IDS-parser","FORWARDED PACKET ALERT, origin is %d,
but source is %d --- ", origin, source);
              call IStorage.storeSimplePacket(source, destination,
ptr, payload_length);
              }
           }
       }

               return SUCCESS;
       }

       /* Log sended packet */
       command error_t TrafficDebug.logSent(uint8_t type, message_t* msg,
uint8_t len){
               int i;
               uint8_t payload_length = call Packet.payloadLength(msg);
               uint8_t* ptr =  call Packet.getPayload(msg, len);

               am_addr_t source = call AMPacket.source(msg);
               am_addr_t destination = call AMPacket.destination(msg);


           if( call NbTable.isWatched(destination) ){
          call IStorage.storeSimplePacket(source, destination, ptr,
payload_length);
       }


               dbg("IDS-parser", "Parser:Sent: packet to %d", destination );

       /* test */
       dbg("IDS-istorage", "Sent packet to %d \n", destination);
       for(i=0;i<len;i++){
               dbg_clear("IDS-istorage","%d ", ptr[i]);
       }
       dbg_clear("IDS-istorage","\n");

               return SUCCESS;
       }
}



On Thu, Jan 22, 2009 at 4:17 AM, Philip Levis <pal at cs.stanford.edu> wrote:
>
> On Jan 21, 2009, at 6:58 PM, Lumir Honus wrote:
>
>> Hello,
>>
>> I'm working on watchdog technique monitoring and during simulation I
>> found a bug in TossimActiveMessageC.
>>
>> First how to reproduce it. I use ctp  and simple application which
>> sends a packet firmly in the interval.
>> My topology follows next scheme:
>>
>> 0 ---- 1 ---- 2
>> \
>>  \
>>  3
>>
>> It means 0 is base station, 2 uses 1 for forwarding packets, 1 and 3
>> have direct connection to base station.
>>
>> When I closely watched how node 1 behaves, I found that sometimes it
>> forwards a wrong packet which it doesn't have in forwarding queue.
>> This occurs just when a node has some messages to forward in his queue
>> and it hears (snoops) some other message.
>>
>> After a very exhaustive debugging :), I found that this is due to line
>> 105 in TossimActiveMessageC --     memcpy(bufferPointer, msg,
>> sizeof(message_t));
>>
>> Honestly I don't know exactly why, but bufferPointer points to the
>> same space in memory as SendQueue which holds messages for forwarding.
>>
>> FIX:
>> I tried replace lines
>> 54. <<    message_t buffer;
>> 55. <<    message_t* bufferPointer = &buffer;
>>
>> by
>>
>> 98     event void Model.receive(message_t* msg) {
>> 99         uint8_t len;
>> 100        void* payload;
>> 101
>> 102  >>  message_t* bufferPointer = (message_t*)malloc(sizeof(message_t));
>> 103        memcpy(bufferPointer, msg, sizeof(message_t));
>>
>> and everything works ok now
>
>
> Well, this is a memory leak...
>
> The behavior you're seeing occurs if a Receive.receive handler returns a
> pointer to a buffer but some other component is still using the pointer.
> It's *possible* this is happening within CTP, but it could also be the
> application you've put on top of CTP. What does your application code look
> like?
>
> Phil
>
>
>
>
>



--
---------------------------------------------------------------------
S pozdravem
       Lumir Honus


More information about the Tinyos-devel mailing list