OBAMP: reset tree links if I lose the tree link with my tree parent
[olsrd.git] / lib / obamp / src / obamp.c
index 0b6138f..e9b23e5 100644 (file)
@@ -140,27 +140,26 @@ SendOBAMPData(struct in_addr *addr, unsigned char *ipPacket, int nBytes)
 {
 
   struct sockaddr_in si_other;
-  struct OBAMP_data_message4 *data_msg;
-  data_msg = malloc(sizeof(struct OBAMP_data_message4));
+  struct OBAMP_data_message4 data_msg;
 
-  data_msg->MessageID = OBAMP_DATA;
-  data_msg->router_id = (u_int32_t) myState->myipaddr.v4.s_addr;
-  data_msg->last_hop = (u_int32_t) myState->myipaddr.v4.s_addr;
+  memset(&data_msg, 0, sizeof(data_msg));
+  data_msg.MessageID = OBAMP_DATA;
+  data_msg.router_id = (u_int32_t) myState->myipaddr.v4.s_addr;
+  data_msg.last_hop = (u_int32_t) myState->myipaddr.v4.s_addr;
 
-  data_msg->CoreAddress = (u_int32_t) myState->CoreAddress.v4.s_addr;
+  data_msg.CoreAddress = (u_int32_t) myState->CoreAddress.v4.s_addr;
 
-  data_msg->SequenceNumber = myState->DataSequenceNumber;
+  data_msg.SequenceNumber = myState->DataSequenceNumber;
   myState->DataSequenceNumber++;
 
-  if (nBytes < 1471) {
-  memcpy(&data_msg->data, ipPacket, nBytes);
-  } else {
-  OLSR_DEBUG(LOG_PLUGINS, "PACKET DROPPED: %d bytes are too much",nBytes);
-  free(data_msg);
-  return 1;
+  if (nBytes >= 1471) {
+    OLSR_DEBUG(LOG_PLUGINS, "PACKET DROPPED: %d bytes are too much",nBytes);
+    return 1;
   }
 
-  data_msg->datalen = nBytes;
+  memcpy(data_msg.data, ipPacket, nBytes);
+
+  data_msg.datalen = nBytes;
 
   memset((char *)&si_other, 0, sizeof(si_other));
   si_other.sin_family = AF_INET;
@@ -168,8 +167,7 @@ SendOBAMPData(struct in_addr *addr, unsigned char *ipPacket, int nBytes)
   si_other.sin_addr = *addr;
   //sendto(sdudp, data_msg, sizeof(struct OBAMP_data_message), 0, (struct sockaddr *)&si_other, sizeof(si_other));
   //TODO: this 17 magic number is okay only for IPv4, we do not worry about this now
-  sendto(sdudp, data_msg, 17+data_msg->datalen, 0, (struct sockaddr *)&si_other, sizeof(si_other));
-  free(data_msg);
+  sendto(sdudp, &data_msg, 17+data_msg.datalen, 0, (struct sockaddr *)&si_other, sizeof(si_other));
   return 0;
 
 }
@@ -284,8 +282,9 @@ IsMulticast(union olsr_ip_addr *ipAddress)
 static void
 activate_tree_link(struct OBAMP_tree_link_ack *ack)
 {
-
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;
   struct list_head *pos;
 
@@ -306,6 +305,7 @@ activate_tree_link(struct OBAMP_tree_link_ack *ack)
       if (tmp->neighbor_ip_addr.v4.s_addr == ack->router_id.v4.s_addr) {
 
         tmp->isTree = 1;
+        myState->TreeHeartBeat = TREE_HEARTBEAT;
         OLSR_DEBUG(LOG_PLUGINS, "Tree link to %s activated", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
         return;
 
@@ -323,15 +323,14 @@ static void
 obamp_hello(struct in_addr *addr)
 {
 
-  struct OBAMP_hello *hello;
+  struct OBAMP_hello hello;
   struct sockaddr_in si_other;
 
-  hello = malloc(sizeof(struct OBAMP_hello));
-
-  hello->MessageID = OBAMP_HELLO;
+  memset(&hello, 0, sizeof(hello));
+  hello.MessageID = OBAMP_HELLO;
   //TODO: refresh IP address
-  hello->router_id = myState->myipaddr;
-  hello->CoreAddress = myState->CoreAddress;
+  hello.router_id = myState->myipaddr;
+  hello.CoreAddress = myState->CoreAddress;
 
   //TODO: implement sequence number
   //hello->HelloSequenceNumber = myState->something;
@@ -341,36 +340,40 @@ obamp_hello(struct in_addr *addr)
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
   si_other.sin_addr = *addr;
-  sendto(sdudp, hello, sizeof(struct OBAMP_hello), 0, (struct sockaddr *)&si_other, sizeof(si_other));
-
-  free(hello);
+  sendto(sdudp, &hello, sizeof(struct OBAMP_hello), 0, (struct sockaddr *)&si_other, sizeof(si_other));
 }
 
 //Request a Tree Link
 static void
 tree_link_req(struct in_addr *addr)
 {
-
-  struct OBAMP_tree_link_req *req;
+  if (myState->TreeRequestDelay == 0) { 
+  struct OBAMP_tree_link_req req;
   struct sockaddr_in si_other;
+  #if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+  #endif
 
-  req = malloc(sizeof(struct OBAMP_tree_link_req));
-
-  req->MessageID = OBAMP_TREE_REQ;
+  OLSR_DEBUG(LOG_PLUGINS, "Sending tree request to: %s", ip4_to_string(&buf, *addr));
+  memset(&req, 0, sizeof(req));
+  req.MessageID = OBAMP_TREE_REQ;
   //TODO: refresh IP address
-  req->router_id = myState->myipaddr;
-  req->CoreAddress = myState->CoreAddress;
+  req.router_id = myState->myipaddr;
+  req.CoreAddress = myState->CoreAddress;
 
-  req->SequenceNumber = myState->tree_req_sn;
+  req.SequenceNumber = myState->tree_req_sn;
   myState->tree_req_sn++;
 
   memset((char *)&si_other, 0, sizeof(si_other));
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
   si_other.sin_addr = *addr;
-  sendto(sdudp, req, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
-
-  free(req);
+  myState->TreeRequestDelay=5;
+  sendto(sdudp, &req, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
+}
+else OLSR_DEBUG(LOG_PLUGINS,"Do not send Tree Link Request because there is another one running");
 }
 
 static void
@@ -382,9 +385,11 @@ tree_link_ack(struct OBAMP_tree_link_req *req)
 
   struct ObampNode *tmp;
   struct list_head *pos;
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
 
-  struct OBAMP_tree_link_ack *ack;
+  struct OBAMP_tree_link_ack ack;
 
   //Check Core Address
   if (memcmp(&myState->CoreAddress.v4, &req->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
@@ -394,13 +399,13 @@ tree_link_ack(struct OBAMP_tree_link_req *req)
   //TODO: other checks ?
 
 
-  ack = malloc(sizeof(struct OBAMP_tree_link_ack));
-  ack->MessageID = OBAMP_TREE_ACK;
+  memset(&ack, 0, sizeof(ack));
+  ack.MessageID = OBAMP_TREE_ACK;
   //TODO: refresh IP address
-  ack->router_id = myState->myipaddr;
-  ack->CoreAddress = myState->CoreAddress;
+  ack.router_id = myState->myipaddr;
+  ack.CoreAddress = myState->CoreAddress;
 
-  ack->SequenceNumber = req->SequenceNumber;
+  ack.SequenceNumber = req->SequenceNumber;
 
   addr = req->router_id.v4;
 
@@ -419,10 +424,7 @@ tree_link_ack(struct OBAMP_tree_link_req *req)
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
   si_other.sin_addr = addr;
-  sendto(sdudp, ack, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
-
-  free(ack);
-
+  sendto(sdudp, &ack, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
 }
 
 
@@ -444,52 +446,47 @@ tree_create_forward_to(struct in_addr *addr, struct OBAMP_tree_create *mytc)
 {
 
   struct sockaddr_in si_other;
-  struct OBAMP_tree_create *temptc;
+  struct OBAMP_tree_create temptc;
 
-  temptc = malloc(sizeof(struct OBAMP_tree_create));
-  memcpy(temptc, mytc, sizeof(struct OBAMP_tree_create));
+  memset(&temptc, 0, sizeof(temptc));
+  memcpy(&temptc, mytc, sizeof(struct OBAMP_tree_create));
 
   //Check Core Address
-  if (memcmp(&myState->CoreAddress.v4, &temptc->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
+  if (memcmp(&myState->CoreAddress.v4, &temptc.CoreAddress.v4, sizeof(struct in_addr)) != 0) {
     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
     return;
   }
   //Update router id
-  temptc->router_id = myState->myipaddr;
+  temptc.router_id = myState->myipaddr;
 
   memset((char *)&si_other, 0, sizeof(si_other));
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
   si_other.sin_addr = *addr;
 
-  sendto(sdudp, temptc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
-  free(temptc);
-
+  sendto(sdudp, &temptc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
 }
 
 static void
 tree_create_gen(struct in_addr *addr)
 {
-  struct OBAMP_tree_create *mytc;
+  struct OBAMP_tree_create mytc;
   struct sockaddr_in si_other;
 
   OLSR_DEBUG(LOG_PLUGINS, "Calling tree_create_gen\n");
 
-  mytc = malloc(sizeof(struct OBAMP_tree_create));
-
-  mytc->MessageID = OBAMP_TREECREATE;
-  mytc->router_id = myState->myipaddr;
-  mytc->CoreAddress = myState->CoreAddress;
+  memset(&mytc, 0, sizeof(mytc));
+  mytc.MessageID = OBAMP_TREECREATE;
+  mytc.router_id = myState->myipaddr;
+  mytc.CoreAddress = myState->CoreAddress;
   myState->TreeCreateSequenceNumber++;
-  mytc->SequenceNumber = myState->TreeCreateSequenceNumber;
+  mytc.SequenceNumber = myState->TreeCreateSequenceNumber;
 
   memset((char *)&si_other, 0, sizeof(si_other));
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
   si_other.sin_addr = *addr;
-  sendto(sdudp, mytc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
-
-  free(mytc);
+  sendto(sdudp, &mytc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
 }
 
 
@@ -498,7 +495,9 @@ printObampNodesList(void)
 {
 
   int i = 1;
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;
   struct list_head *pos;
 
@@ -576,6 +575,7 @@ reset_tree_links(void)
   struct ObampNode *tmp;
   struct list_head *pos;
 
+  OLSR_DEBUG(LOG_PLUGINS,"Reset Tree Links Now");
   if (list_empty(&ListOfObampNodes) == 0) {     //if the list is NOT empty
 
     list_for_each(pos, &ListOfObampNodes) {
@@ -588,6 +588,8 @@ reset_tree_links(void)
 
   memset(&myState->ParentId.v4, 0, sizeof(myState->ParentId.v4));
   memset(&myState->OldParentId.v4, 1, sizeof(myState->OldParentId.v4));
+  myState->TreeCreateSequenceNumber=0;
+
 
 };
 
@@ -596,8 +598,9 @@ reset_tree_links(void)
 static void
 CoreElection(void)
 {
-
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;
   struct list_head *pos;
   u_int32_t smallestIP = 0xFFFFFFFF;
@@ -631,7 +634,8 @@ CoreElection(void)
         myState->CoreAddress = myState->myipaddr;
         myState->iamcore = 1;
         myState->TreeCreateSequenceNumber = 0;
-        reset_tree_links();
+        OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
+       reset_tree_links();
         OLSR_DEBUG(LOG_PLUGINS, "I'm the core");
       }
     } else {
@@ -640,7 +644,8 @@ CoreElection(void)
       } else {                  //core changed
         myState->iamcore = 0;
         myState->CoreAddress.v4.s_addr = smallestIP;
-        reset_tree_links();
+        OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
+       reset_tree_links();
         OLSR_DEBUG(LOG_PLUGINS, "CoreElection: current Core is - %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
       }
     }
@@ -652,6 +657,7 @@ CoreElection(void)
     myState->CoreAddress = myState->myipaddr;
     myState->iamcore = 1;
     myState->TreeCreateSequenceNumber = 0;
+    OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
     reset_tree_links();
 
 
@@ -759,6 +765,43 @@ decap_data(char *buffer)
 
 }
 
+
+
+static int
+CheckDataFromTreeLink(char *buffer)
+{
+
+  struct ObampNode *tmp;               //temp pointers used when parsing the list
+  struct list_head *pos;
+  struct OBAMP_data_message4 *data_msg;
+
+  data_msg = (struct OBAMP_data_message4 *)buffer;
+
+  if (list_empty(&ListOfObampNodes) == 0) {     //if the list is NOT empty
+
+    //Scroll the list
+    list_for_each(pos, &ListOfObampNodes) {
+      tmp = list_entry(pos, struct ObampNode, list);
+      //Scroll the list until we find the entry relative to the last hop of the packet we are processing
+      if (memcmp(&tmp->neighbor_ip_addr.v4, &data_msg->last_hop, sizeof(struct in_addr)) == 0) {
+
+        if (tmp->isTree == 1) {  //OK we receive data from a neighbor that we have a tree link with
+          return 1;
+        }
+
+       else{
+          OLSR_DEBUG(LOG_PLUGINS, "DISCARDING DATA PACKET SENT BY NOT TREE NEIGHBOR");
+          return 0;
+       }
+      }
+    }
+  }
+
+  return 0;
+
+}
+
+
 static int
 CheckDupData(char *buffer)
 {
@@ -807,15 +850,20 @@ static void
 forward_obamp_data(char *buffer)
 {
 
-  struct ipaddr_str buf;               //buf to print debug infos
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+  struct ipaddr_str buf2;
+#endif
   struct ObampNode *tmp;               //temp pointers used when parsing the list
   struct list_head *pos;
   struct OBAMP_data_message4 *data_msg;
-
   struct sockaddr_in si_other;
+  struct in_addr temporary;
 
 
   data_msg = (struct OBAMP_data_message4 *)buffer;
+  temporary.s_addr  = data_msg->last_hop;
+  data_msg->last_hop = myState->myipaddr.v4.s_addr;
 
   if (list_empty(&ListOfObampNodes) == 0) {     //if the list is NOT empty
 
@@ -823,10 +871,9 @@ forward_obamp_data(char *buffer)
     list_for_each(pos, &ListOfObampNodes) {
       tmp = list_entry(pos, struct ObampNode, list);
 
-      if (tmp->isTree == 1 && memcmp(&tmp->neighbor_ip_addr.v4, &data_msg->last_hop, sizeof(struct in_addr)) != 0) {
-
+      if (tmp->isTree == 1 && memcmp(&tmp->neighbor_ip_addr.v4, &temporary.s_addr, 4) != 0) {
+        OLSR_DEBUG(LOG_PLUGINS, "FORWARDING OBAMP DATA TO node %s because come from %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4), ip4_to_string(&buf2,temporary));
         //FORWARD DATA
-        data_msg->last_hop = myState->myipaddr.v4.s_addr;
 
 
         memset((char *)&si_other, 0, sizeof(si_other));
@@ -836,7 +883,6 @@ forward_obamp_data(char *buffer)
         //sendto(sdudp, data_msg, sizeof(struct OBAMP_data_message), 0, (struct sockaddr *)&si_other, sizeof(si_other));
        sendto(sdudp, data_msg, 17+data_msg->datalen, 0, (struct sockaddr *)&si_other, sizeof(si_other));
 
-        OLSR_DEBUG(LOG_PLUGINS, "FORWARDING OBAMP DATA TO node %s ", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
 
       }
     }
@@ -885,15 +931,16 @@ static void
 manage_tree_create(char *packet)
 {
 
-
   struct OBAMP_tree_create *msg;
 
-  struct ipaddr_str buf;               //buf to print debug infos
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
   struct ipaddr_str buf2;              //buf to print debug infos
+#endif
 
   struct ObampNode *tmp;               //temp pointers used when parsing the list
   struct list_head *pos;
-
+  OLSR_DEBUG(LOG_PLUGINS,"manage_tree_create");
   msg = (struct OBAMP_tree_create *)packet;
 
   if (msg->MessageID != OBAMP_TREECREATE) {
@@ -909,32 +956,49 @@ manage_tree_create(char *packet)
     if (myState->iamcore == 1) {        //I'm core and receiving tree create over a loop
       return;
     } else {
-      if (myState->TreeCreateSequenceNumber < msg->SequenceNumber) {    //If tree create is not a duplicate
-        myState->TreeCreateSequenceNumber = msg->SequenceNumber;
-        myState->TreeHeartBeat = TREE_HEARTBEAT;
 
 
-        myState->OldParentId.v4 = myState->ParentId.v4;
-        myState->ParentId.v4 = msg->router_id.v4;
+      if ( (((msg->SequenceNumber > myState->TreeCreateSequenceNumber) && ((msg->SequenceNumber - myState->TreeCreateSequenceNumber ) <= 127)) || ((myState->TreeCreateSequenceNumber > msg->SequenceNumber) && ((myState->TreeCreateSequenceNumber - msg->SequenceNumber) > 127 ))    /*myState->TreeCreateSequenceNumber < msg->SequenceNumber*/) || myState->TreeCreateSequenceNumber == 0 ) {    //If tree create is not a duplicate
+        OLSR_DEBUG(LOG_PLUGINS, "myState->TreeCreateSequenceNumber < msg->SequenceNumber --- %d < %d",myState->TreeCreateSequenceNumber,msg->SequenceNumber);
+       myState->TreeCreateSequenceNumber = msg->SequenceNumber;
+
+       //A bug was fixed here a battlemeshv3
+        //myState->OldParentId.v4 = myState->ParentId.v4;
+        //myState->ParentId.v4 = msg->router_id.v4;
 
-        if (memcmp(&myState->OldParentId.v4, &myState->ParentId.v4, sizeof(struct in_addr)) != 0)       //If it changed
+        //if (memcmp(&myState->OldParentId.v4, &myState->ParentId.v4, sizeof(struct in_addr)) != 0)       //If it changed
+        if (memcmp(&msg->router_id.v4, &myState->ParentId.v4, sizeof(struct in_addr)) != 0)       //If it changed
         {
-          OLSR_DEBUG(LOG_PLUGINS, "Parent changed requesting tree link");
-          reset_tree_links();
+          OLSR_DEBUG(LOG_PLUGINS, "Receiving a tree message from a link that is not parent");
+         if (DoIHaveATreeLink() == 0 ) {
+          OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
+         reset_tree_links();
           myState->ParentId.v4 = msg->router_id.v4;
           myState->OldParentId.v4 = myState->ParentId.v4;
           tree_link_req(&msg->router_id.v4);
+         }
+         else {
+         //I have a tree link already, evaluate new parent ??
+         
+         }
         }
-        if (list_empty(&ListOfObampNodes) == 0) {       //if the list is NOT empty
+       else { //Receiving a TreeCreate from my parent so I can refresh hearthbeat
+        myState->TreeHeartBeat = TREE_HEARTBEAT;
+       }
+        
+       //FORWARD the tree message on the mesh
+       if (list_empty(&ListOfObampNodes) == 0) {       //if the list is NOT empty
 
           //Scroll the list
           list_for_each(pos, &ListOfObampNodes) {
             tmp = list_entry(pos, struct ObampNode, list);
 
             if (tmp->isMesh == 1 && memcmp(&tmp->neighbor_ip_addr.v4, &msg->router_id.v4, sizeof(struct in_addr)) != 0) {       //Is neighbor and not the originator of this tree create
+               if (DoIHaveATreeLink() == 1 ) { //I forward only if I have a link tree to the core ready
               tree_create_forward_to(&tmp->neighbor_ip_addr.v4, msg);
               OLSR_DEBUG(LOG_PLUGINS, "FORWARDING TREE CREATE ORIGINATOR %s TO node %s ", ip4_to_string(&buf2, msg->router_id.v4),
                          ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
+               }
 
             }
           }
@@ -942,6 +1006,8 @@ manage_tree_create(char *packet)
           OLSR_DEBUG(LOG_PLUGINS, "Very strange, list cannot be empty here !");
         }
       } else {
+       
+        OLSR_DEBUG(LOG_PLUGINS, "myState->TreeCreateSequenceNumber < msg->SequenceNumber --- %d < %d",myState->TreeCreateSequenceNumber,msg->SequenceNumber);
         OLSR_DEBUG(LOG_PLUGINS, "DISCARDING DUP TREE CREATE");
       }
     }
@@ -955,26 +1021,25 @@ ObampSignalling(int skfd, void *data __attribute__ ((unused)), unsigned int flag
 
   char buffer[1500];
   char text_buffer[300];
-  struct sockaddr_in *addr;
+  struct sockaddr_in addr;
   int n = 0;
   socklen_t len;
   u_int8_t MessageID;
 
-  addr = malloc(sizeof(struct sockaddr_in));
-  memset((void *)addr, 0, sizeof(struct sockaddr_in));
-  len = sizeof(struct sockaddr_in);
+  memset(&addr, 0, sizeof(struct sockaddr_in));
+  len = sizeof(addr);
 
   if (skfd > 0) {
 
     //OLSR_DEBUG(LOG_PLUGINS,"INCOMING OBAMP SIGNALLING");
 
-    n = recvfrom(skfd, buffer, 1500, 0, (struct sockaddr *)addr, &len);
+    n = recvfrom(skfd, buffer, 1500, 0, (struct sockaddr *)&addr, &len);
 
     if (n < 0) {
       OLSR_DEBUG(LOG_PLUGINS, "recvfrom error");
     }
 
-    inet_ntop(AF_INET, &addr->sin_addr, text_buffer, sizeof(text_buffer));
+    inet_ntop(AF_INET, &addr.sin_addr, text_buffer, sizeof(text_buffer));
     //OLSR_DEBUG(LOG_PLUGINS,"Request from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
 
     MessageID = buffer[0];
@@ -982,9 +1047,9 @@ ObampSignalling(int skfd, void *data __attribute__ ((unused)), unsigned int flag
     switch (MessageID) {
 
     case OBAMP_DATA:
-      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_DATA from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
+      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_DATA from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
 
-      if (CheckDupData(buffer)) {
+      if (CheckDupData(buffer) && CheckDataFromTreeLink(buffer) ) {
         forward_obamp_data(buffer);
         decap_data(buffer);
       }
@@ -992,25 +1057,25 @@ ObampSignalling(int skfd, void *data __attribute__ ((unused)), unsigned int flag
       break;
 
     case OBAMP_HELLO:
-      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_HELLO from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
+      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_HELLO from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
       manage_hello(buffer);
       break;
 
     case OBAMP_TREECREATE:
       //do here
-      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREECREATE from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
+      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREECREATE from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
       manage_tree_create(buffer);
 
       break;
 
     case OBAMP_TREE_REQ:
-      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_REQ from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
+      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_REQ from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
       tree_link_ack((struct OBAMP_tree_link_req *)buffer);
       break;
 
     case OBAMP_TREE_ACK:
       //do here
-      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_ACK from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
+      OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_ACK from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
       activate_tree_link((struct OBAMP_tree_link_ack *)buffer);
       break;
 
@@ -1030,13 +1095,14 @@ If a new node is added CoreElection is called to update the current core
 int
 addObampNode4(struct in_addr *ipv4, u_int8_t status)
 {
-
-  struct ipaddr_str buf;               //Printf stuff
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+#endif
   struct ObampNode *neighbor_to_add;
   struct ObampNode *tmp;
   struct list_head *pos;
 
-  neighbor_to_add = malloc(sizeof(struct ObampNode));
+  neighbor_to_add = olsr_malloc(sizeof(struct ObampNode), "OBAMPNode");
 
 //OLSR_DEBUG(LOG_PLUGINS,"Adding to list node - %s\n",ip4_to_string(&buf,*ipv4));
 
@@ -1090,11 +1156,13 @@ addObampNode4(struct in_addr *ipv4, u_int8_t status)
  * Return     : none
  * ------------------------------------------------------------------------- */
 static void
-PacketReceivedFromOLSR(void *originator, unsigned char *obamp_message, int len)
+PacketReceivedFromOLSR(union olsr_ip_addr *originator, const uint8_t *obamp_message, int len)
 {
   u_int8_t MessageID = obamp_message[0];
-  struct OBAMP_alive *alive;
+  const struct OBAMP_alive *alive;
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
 
   struct in_addr *myOriginator = (struct in_addr *)originator;
 
@@ -1106,7 +1174,7 @@ PacketReceivedFromOLSR(void *originator, unsigned char *obamp_message, int len)
 
   case OBAMP_ALIVE:
     OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_ALIVE from %s\n", ip4_to_string(&buf, *myOriginator));
-    alive = (struct OBAMP_alive *)obamp_message;
+    alive = (const struct OBAMP_alive *)obamp_message;
     addObampNode4(myOriginator, alive->status);
     printObampNodesList();
 
@@ -1119,28 +1187,18 @@ PacketReceivedFromOLSR(void *originator, unsigned char *obamp_message, int len)
 
 //OLSR parser, received OBAMP messages
 void
-olsr_parser(union olsr_message *m, struct interface *in_if
+olsr_parser(struct olsr_message *msg, struct interface *in_if
             __attribute__ ((unused)), union olsr_ip_addr *ipaddr, enum duplicate_status status __attribute__ ((unused)))
 {
-  union olsr_ip_addr originator;
-  int size;
-  uint32_t vtime;
   //OLSR_DEBUG(LOG_PLUGINS, "OBAMP PLUGIN: Received msg in parser\n");
 
-  /* Fetch the originator of the messsage */
-  if (olsr_cnf->ip_version == AF_INET) {
-    memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
-    vtime = me_to_reltime(m->v4.olsr_vtime);
-    size = ntohs(m->v4.olsr_msgsize);
-  } else {
-    memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
-    vtime = me_to_reltime(m->v6.olsr_vtime);
-    size = ntohs(m->v6.olsr_msgsize);
+  if (msg->type != MESSAGE_TYPE) {
+    return;
   }
 
   /* Check if message originated from this node.
    *         If so - back off */
-  if (olsr_ipcmp(&originator, &olsr_cnf->router_id) == 0)
+  if (olsr_ipcmp(&msg->originator, &olsr_cnf->router_id) == 0)
     return;
 
   /* Check that the neighbor this message was received from is symmetric.
@@ -1150,60 +1208,41 @@ olsr_parser(union olsr_message *m, struct interface *in_if
     return;
   }
 
-  if (olsr_cnf->ip_version == AF_INET) {
-
-    //IPv4 Case, process your OBAMP packet here:
-    PacketReceivedFromOLSR(&m->v4.originator, (unsigned char *)&m->v4.message, size - 12);
-  } else {
-    //IPv6 Case, process your OBAMP packet here:
-    PacketReceivedFromOLSR(&m->v6.originator, (unsigned char *)&m->v6.message, size - 12 - 96);
-  }
-
+  PacketReceivedFromOLSR(&msg->originator, msg->payload, msg->end - msg->payload);
 }
 
 //Sends a packet in the OLSR network
 void
-olsr_obamp_gen(unsigned char *packet, int len)
+olsr_obamp_gen(void *packet, int len)
 {
   /* send buffer: huge */
-  char buffer[10240];
-  union olsr_message *message = (union olsr_message *)buffer;
+  uint8_t buffer[10240];
+  struct olsr_message msg;
   struct interface *ifn;
+  uint8_t *curr, *sizeptr;
 
   /* fill message */
-  if (olsr_cnf->ip_version == AF_INET) {
-    /* IPv4 */
-    message->v4.olsr_msgtype = MESSAGE_TYPE;
-    message->v4.olsr_vtime = reltime_to_me(OBAMP_VALID_TIME * MSEC_PER_SEC);
-    memcpy(&message->v4.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
-    message->v4.ttl = MAX_TTL;
-    message->v4.hopcnt = 0;
-    message->v4.seqno = htons(get_msg_seqno());
-
-    message->v4.olsr_msgsize = htons(len + 12);
-
-    memcpy(&message->v4.message, packet, len);
-    len = len + 12;
-  } else {
-    /* IPv6 */
-    message->v6.olsr_msgtype = MESSAGE_TYPE;
-    message->v6.olsr_vtime = reltime_to_me(OBAMP_VALID_TIME * MSEC_PER_SEC);
-    memcpy(&message->v6.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
-    message->v6.ttl = MAX_TTL;
-    message->v6.hopcnt = 0;
-    message->v6.seqno = htons(get_msg_seqno());
-
-    message->v6.olsr_msgsize = htons(len + 12 + 96);
-    memcpy(&message->v6.message, packet, len);
-    len = len + 12 + 96;
-  }
+  msg.type = MESSAGE_TYPE;
+  msg.vtime = OBAMP_VALID_TIME * MSEC_PER_SEC;
+  msg.originator = olsr_cnf->router_id;
+  msg.ttl = MAX_TTL;
+  msg.hopcnt = 0;
+  msg.seqno = get_msg_seqno();
+  msg.size = 0; /* put in later */
+
+  curr = buffer;
+  sizeptr = olsr_put_msg_hdr(&curr, &msg);
+  memcpy(curr, packet, len);
+
+  len = curr - buffer + len;
+  pkt_put_u16(&sizeptr, len);
 
   /* looping trough interfaces */
   OLSR_FOR_ALL_INTERFACES(ifn) {
-    if (net_outbuffer_push(ifn, message, len) != len) {
+    if (net_outbuffer_push(ifn, buffer, len) != len) {
       /* send data and try again */
       net_output(ifn);
-      if (net_outbuffer_push(ifn, message, len) != len) {
+      if (net_outbuffer_push(ifn, buffer, len) != len) {
         OLSR_DEBUG(LOG_PLUGINS, "OBAMP PLUGIN: could not send on interface: %s\n", ifn->int_name);
       }
     }
@@ -1266,8 +1305,9 @@ outer_tree_create(void *x)
 void
 tree_create(void *x)
 {
-
-  struct ipaddr_str buf;               //buf to print debug infos
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;               //temp pointers used when parsing the list
   struct list_head *pos;
 
@@ -1305,8 +1345,9 @@ tree_create(void *x)
 void
 mesh_create(void *x)
 {
-
-  struct ipaddr_str buf;               //buf to print debug infos
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;               //temp pointers used when parsing the list
   struct list_head *pos;
 
@@ -1380,6 +1421,11 @@ mesh_create(void *x)
         if (tmp->isMesh == 0 && tmp->isTree == 1) {
 
           tmp->isTree = 0;
+       
+        if (memcmp(&tmp->neighbor_ip_addr.v4, &myState->ParentId.v4, sizeof(struct in_addr)) == 0) {
+               OLSR_DEBUG(LOG_PLUGINS,"RESET TREE LINKS: I lost tree link with my PARENT");
+               reset_tree_links();
+       }       
 
         }
       }
@@ -1402,8 +1448,9 @@ mesh_create(void *x)
 void
 purge_nodes(void *x)
 {
-
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;
   struct list_head *pos;
 
@@ -1412,10 +1459,13 @@ purge_nodes(void *x)
   if (myState->TreeHeartBeat > 0)
     myState->TreeHeartBeat--;
 
-  if (myState->TreeHeartBeat == 0 && myState->iamcore == 0)
-    reset_tree_links();
-
+  if (myState->TreeRequestDelay > 0)
+    myState->TreeRequestDelay--;
 
+  if (myState->TreeHeartBeat == 0 && myState->iamcore == 0){ 
+    OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
+    reset_tree_links();
+    }
 
 //OLSR_DEBUG(LOG_PLUGINS,"OBAMP: Timer Expired Purging Nodes");
 
@@ -1454,17 +1504,15 @@ purge_nodes(void *x)
 
 
 void
-obamp_alive_gen(void *x)
+obamp_alive_gen(void *x  __attribute__ ((unused)))
 {
-  struct OBAMP_alive *myAlive;
+  struct OBAMP_alive myAlive;
   OLSR_DEBUG(LOG_PLUGINS, "Calling obamp_alive_gen\n");
-  myAlive = malloc(sizeof(struct OBAMP_alive));
-  myAlive->MessageID = OBAMP_ALIVE;
-  myAlive->status = DoIHaveATreeLink();
-  olsr_obamp_gen((unsigned char *)myAlive, sizeof(struct OBAMP_alive));
-  free(myAlive);
-  x = NULL;
 
+  memset(&myAlive, 0, sizeof(myAlive));
+  myAlive.MessageID = OBAMP_ALIVE;
+  myAlive.status = DoIHaveATreeLink();
+  olsr_obamp_gen(&myAlive, sizeof(struct OBAMP_alive));
 }
 
 
@@ -1479,7 +1527,9 @@ EncapFlowInObamp(int skfd, void *data __attribute__ ((unused)), unsigned int fla
 {
   unsigned char ipPacket[1500];        //TODO: optimize me
 
+#if !defined(REMOVE_LOG_DEBUG)
   struct ipaddr_str buf;
+#endif
   struct ObampNode *tmp;
   struct list_head *pos;
 
@@ -1592,7 +1642,7 @@ AddObampSniffingIf(const char *ifName,
 
   assert(ifName != NULL);
 
-  ifToAdd = malloc(sizeof(struct ObampSniffingIf));
+  ifToAdd = olsr_malloc(sizeof(struct ObampSniffingIf), "OBAMPSniffingIf");
 
   strncpy(ifToAdd->ifName, ifName, 16); //TODO: 16 fix this
   ifToAdd->ifName[15] = '\0';   /* Ensures null termination */
@@ -1620,7 +1670,9 @@ PreInitOBAMP(void)
 int
 InitOBAMP(void)
 {
-  struct ipaddr_str buf;               //Buffer to print debug to screen
+#if !defined(REMOVE_LOG_DEBUG)
+  struct ipaddr_str buf;
+#endif
 
 //Structs necessary for timers
 
@@ -1638,11 +1690,16 @@ InitOBAMP(void)
   struct olsr_cookie_info *tree_create_timer_cookie = NULL;
   struct olsr_cookie_info *outer_tree_create_timer_cookie = NULL;
 
+  if (olsr_cnf->ip_version == AF_INET6) {
+    OLSR_ERROR(LOG_PLUGINS, "OBAMP does not support IPv6 at the moment.");
+    return 1;
+  }
 
 //Setting OBAMP node state
-  myState = malloc(sizeof(struct ObampNodeState));
+  myState = olsr_malloc(sizeof(struct ObampNodeState), "OBAMPNodeState");
   myState->iamcore = 1;
   myState->TreeHeartBeat = 0;
+  myState->TreeRequestDelay = 0;
   memcpy(&myState->myipaddr.v4, &olsr_cnf->router_id, olsr_cnf->ipsize);
   myState->CoreAddress = myState->myipaddr;