mDNS: Reworked logic of router Election. The election is now handled on interface...
authorAlessandro <enterprise.nx@gmail.com>
Thu, 26 Jul 2012 14:03:07 +0000 (16:03 +0200)
committerSaverio Proto <zioproto@gmail.com>
Mon, 13 Aug 2012 17:37:40 +0000 (19:37 +0200)
lib/mdns/src/NetworkInterfaces.c
lib/mdns/src/NetworkInterfaces.h
lib/mdns/src/RouterElection.c
lib/mdns/src/RouterElection.h
lib/mdns/src/mdns.c

index ca141ec..7a3d4fa 100644 (file)
@@ -504,6 +504,7 @@ CreateInterface(const char *ifName, struct interface *olsrIntf)
   memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
   memcpy(newIf->ifName, ifName, IFNAMSIZ);
   newIf->olsrIntf = olsrIntf;
+  newIf->isActive = 1; //as default the interface is active
   if (olsrIntf != NULL) {
     /* For an OLSR-interface, copy the interface address and broadcast
      * address from the OLSR interface object. Downcast to correct sockaddr
index 32e26e7..b147d45 100644 (file)
@@ -77,6 +77,9 @@ struct TBmfInterface {
    * packets */
   int helloSkfd;
 
+  /* Used to check if the router is master on the selected interface */
+  int isActive;
+
   unsigned char macAddr[IFHWADDRLEN];
 
   char ifName[IFNAMSIZ];
index e0f2441..73c488f 100644 (file)
@@ -34,7 +34,6 @@
 #include "RouterElection.h"
 #include "mdns.h"
 
-int ISMASTER = 1;
 struct RtElHelloPkt *hello;
 uint8_t NETWORK_ID;
 union olsr_ip_addr ROUTER_ID;
@@ -43,20 +42,22 @@ union olsr_ip_addr ROUTER_ID;
 struct list_entity ListOfRouter;
 #define ROUTER_ELECTION_ENTRIES(nr, iterator) listbackport_for_each_element_safe(&ListOfRouter, nr, list, iterator)
 
-int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry){
+int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry, int skfd){
   OLSR_PRINTF(1, "parsing ipv4 packet \n");
   listEntry->ttl = ENTRYTTL;
   listEntry->network_id = rcvPkt->network_id;
   listbackport_init_node(&listEntry->list);
+  listEntry->skfd = skfd;
   (void) memcpy(&listEntry->router_id, &rcvPkt->router_id.v4, sizeof(struct in_addr));  //Need to insert an address validity check?
   return 1;
 }
 
-int ParseElectionPacket6 (struct RtElHelloPkt *rcvPkt, struct RouterListEntry6 *listEntry6){
+int ParseElectionPacket6 (struct RtElHelloPkt *rcvPkt, struct RouterListEntry6 *listEntry6, int skfd){
   OLSR_PRINTF(1, "parsing ipv6 packet \n");
   listEntry6->ttl = ENTRYTTL;
   listEntry6->network_id = rcvPkt->network_id;
   listbackport_init_node(&listEntry6->list);
+  listEntry6->skfd = skfd;
   (void) memcpy(&listEntry6->router_id, &rcvPkt->router_id.v6, sizeof(struct in6_addr));//Need to insert an address validity check?
   return 1;
 }
@@ -71,7 +72,7 @@ int UpdateRouterList (struct RouterListEntry *listEntry){
 
   ROUTER_ELECTION_ENTRIES(tmp, iterator) {
     OLSR_PRINTF(1,"inspecting entry");
-    if((tmp->network_id == listEntry->network_id) &&
+    if((tmp->network_id == listEntry->network_id) && (tmp->skfd == listEntry->skfd) &&
                (memcmp(&listEntry->router_id, &tmp->router_id, sizeof(struct in_addr)) == 0)){
       exist = 1;
       tmp->ttl = listEntry->ttl;
@@ -92,7 +93,7 @@ int UpdateRouterList6 (struct RouterListEntry6 *listEntry6){
     return 0;
  
   ROUTER_ELECTION_ENTRIES(tmp, iterator) { 
-    if((tmp->network_id == listEntry6->network_id) &&
+    if((tmp->network_id == listEntry6->network_id) && (tmp->skfd == listEntry6->skfd)  &&
               (memcmp(&listEntry6->router_id, &tmp->router_id, sizeof(struct in6_addr))) == 0){
       exist = 1;
       tmp->ttl = listEntry6->ttl;
@@ -140,47 +141,52 @@ void helloTimer (void *foo __attribute__ ((unused))){
 
 void electTimer (void *foo __attribute__ ((unused))){
 
+  struct TBmfInterface *walker;
   struct RouterListEntry *tmp, *iterator;
   struct RouterListEntry6 *tmp6, *iterator6;
 
   OLSR_PRINTF(1,"elect start \n");
 
-  if (listbackport_is_empty(&ListOfRouter)){
-    ISMASTER = 1;
-    OLSR_PRINTF(1,"elect empty \n");
-    return;
-  }
+  for(walker = BmfInterfaces; walker != NULL; walker = walker->next){
+    if (listbackport_is_empty(&ListOfRouter)){
+      walker->isActive = 1;
+      OLSR_PRINTF(1,"elect empty \n");
+      continue;
+    }
 
-  ISMASTER = 1;
-  if (olsr_cnf->ip_version == AF_INET) {
-    ROUTER_ELECTION_ENTRIES(tmp, iterator){
-      OLSR_PRINTF(1,"inspecting element \n");
-      if(tmp->network_id == NETWORK_ID)
-        if(memcmp(&tmp->router_id, &ROUTER_ID.v4, sizeof(struct in_addr)) < 0)
-          ISMASTER = 0;
-      OLSR_PRINTF(1,"confrontation done \n");
-      tmp->ttl = ((tmp->ttl)- 1);
-      if(tmp->ttl <= 0){
-        listbackport_remove(&tmp->list);
-        free(tmp);
+    walker->isActive = 1;
+    if (olsr_cnf->ip_version == AF_INET) {
+      ROUTER_ELECTION_ENTRIES(tmp, iterator){
+        OLSR_PRINTF(1,"inspecting element \n");
+        if(tmp->network_id == NETWORK_ID)
+          if(tmp->skfd == walker->electionSkfd)
+            if(memcmp(&tmp->router_id, &ROUTER_ID.v4, sizeof(struct in_addr)) < 0)
+              walker->isActive = 0;
+        OLSR_PRINTF(1,"confrontation done \n");
+        tmp->ttl = ((tmp->ttl)- 1);
+        if(tmp->ttl <= 0){
+          listbackport_remove(&tmp->list);
+          free(tmp);
+        }
+        OLSR_PRINTF(1,"inspect finish \n");
       }
-      OLSR_PRINTF(1,"inspect finish \n");
     }
-  }
-  else{
-    ROUTER_ELECTION_ENTRIES(tmp6, iterator6){
-      if(tmp6->network_id == NETWORK_ID)
-        if(memcmp(&tmp6->router_id, &ROUTER_ID.v6, sizeof(struct in6_addr)) < 0)
-          ISMASTER = 0;
-      tmp6->ttl = ((tmp6->ttl)- 1);
-      if(tmp6->ttl <=  0){
-        listbackport_remove(&tmp6->list);
-        free(tmp6);
+    else{
+      ROUTER_ELECTION_ENTRIES(tmp6, iterator6){
+        if(tmp6->network_id == NETWORK_ID)
+          if(tmp->skfd == walker->electionSkfd)
+            if(memcmp(&tmp6->router_id, &ROUTER_ID.v6, sizeof(struct in6_addr)) < 0)
+              walker->isActive = 0;
+        tmp6->ttl = ((tmp6->ttl)- 1);
+        if(tmp6->ttl <=  0){
+          listbackport_remove(&tmp6->list);
+          free(tmp6);
+        }
       }
     }
-  }
 
-  OLSR_PRINTF(1,"elect finish \n");
+    OLSR_PRINTF(1,"elect finish \n");
+  }
 
   return;
 }
index 09141f2..4871787 100644 (file)
@@ -19,6 +19,7 @@ struct RouterListEntry{
   struct in_addr router_id;
   uint8_t network_id;
   int ttl;
+  int skfd;
 
   struct list_entity list;
 };
@@ -27,16 +28,15 @@ struct RouterListEntry6{
   struct in6_addr router_id;
   uint8_t network_id;
   int ttl;
+  int skfd;
 
   struct list_entity list;
 };
 
-extern int ISMASTER;
-
 int UpdateRouterList (struct RouterListEntry *listEntry);      //update router list
 int UpdateRouterList6 (struct RouterListEntry6 *listEntry6);
-int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry);      //used to parse a received packet into
-int ParseElectionPacket6 (struct RtElHelloPkt *rcvPkt, struct RouterListEntry6 *listEntry6);   //a list entry for ipv4/ipv6
+int ParseElectionPacket (struct RtElHelloPkt *rcvPkt, struct RouterListEntry *listEntry, int skfd);    //used to parse a received 
+int ParseElectionPacket6 (struct RtElHelloPkt *rcvPkt, struct RouterListEntry6 *listEntry6, int skfd); //packet into a list entry
 int InitRouterList (void *foo __attribute__ ((unused)));
 void helloTimer (void *foo __attribute__ ((unused)));
 void electTimer (void *foo __attribute__ ((unused)));
index 75bbb1f..e4979b9 100644 (file)
@@ -145,7 +145,7 @@ PacketReceivedFromOLSR(unsigned char *encapsulationUdpData, int len)
        * in that case. */
       memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
       
-      if(ISMASTER == 0)             //Don't forward packet if isn't master router
+      if(walker->isActive == 0)             //Don't forward packet if isn't master router
         return;
 
       nBytesWritten = sendto(walker->capturingSkfd, encapsulationUdpData, stripped_len, 0, (struct sockaddr *)&dest, sizeof(dest));
@@ -438,10 +438,6 @@ BmfPacketCaptured(
        if(((u_int8_t) ipHeader->ip_ttl) <= ((u_int8_t) 1))    // Discard mdns packet with TTL limit 1 or less
                return;
 
-    if(ISMASTER == 0)             //Don't forward packet if isn't master router
-      return;
-
-
     if (isInFilteredList(&src)) {
       return;
     }
@@ -474,10 +470,6 @@ BmfPacketCaptured(
        if(((uint8_t) ipHeader6->ip6_hops) <= ((uint8_t) 1))  // Discard mdns packet with hop limit 1 or less
                return;
   
-    if(ISMASTER == 0)             //Don't forward packet if isn't master router
-      return;
-
-  
     if (isInFilteredList(&src)) {
       return;
     }
@@ -511,6 +503,7 @@ DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attri
     socklen_t addrLen = sizeof(pktAddr);
     int nBytes;
     unsigned char *ipPacket;
+    struct TBmfInterface *walker;
 
     /* Receive the captured Ethernet frame, leaving space for the BMF
      * encapsulation header */
@@ -540,6 +533,11 @@ DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attri
       return;                   /* for */
     }
 
+    for(walker = BmfInterfaces; walker != NULL; walker = walker->next){        //if the router isn't the master for this interface
+      if(skfd == walker->capturingSkfd && walker->isActive == 0)       //discard mdns packets
+        return;
+    }
+
     if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
         pktAddr.sll_pkttype == PACKET_MULTICAST || pktAddr.sll_pkttype == PACKET_BROADCAST) {
       /* A multicast or broadcast packet was captured */
@@ -621,7 +619,7 @@ void DoElection(int skfd, void *data __attribute__ ((unused)), unsigned int flag
 
   if (rcvPkt->ipFamily == AF_INET){
     listEntry = (struct RouterListEntry *)malloc(sizeof(struct RouterListEntry));
-    if(ParseElectionPacket(rcvPkt, listEntry)){
+    if(ParseElectionPacket(rcvPkt, listEntry, skfd)){
       OLSR_PRINTF(1,"processing ipv4 packet \n");
       if(UpdateRouterList(listEntry))
         free(listEntry);
@@ -633,7 +631,7 @@ void DoElection(int skfd, void *data __attribute__ ((unused)), unsigned int flag
   }
   else{
     listEntry6 = (struct RouterListEntry6 *)malloc(sizeof(struct RouterListEntry6));
-    if(ParseElectionPacket6(rcvPkt, listEntry6)){
+    if(ParseElectionPacket6(rcvPkt, listEntry6, skfd)){
       OLSR_PRINTF(1,"processing ipv6 packet");
       if(UpdateRouterList6(listEntry6))
         free(listEntry6);