mDNS: Implemented router election mechansim to have only 1 active mDNS OLSR router...
authorAlessandro Gnagni <enterprise.nx@gmail.com>
Wed, 13 Jun 2012 15:48:32 +0000 (17:48 +0200)
committerSaverio Proto <zioproto@gmail.com>
Mon, 13 Aug 2012 17:37:40 +0000 (19:37 +0200)
Implemented IPv4 and IPv6 socket that should
capture the router election signalling packets (hellos)

Hellos are sent out with a timer

A second time triggers the router to decide if he is master

lib/mdns/src/NetworkInterfaces.c
lib/mdns/src/NetworkInterfaces.h
lib/mdns/src/RouterElection.c [new file with mode: 0644]
lib/mdns/src/RouterElection.h [new file with mode: 0644]
lib/mdns/src/list_backport.h
lib/mdns/src/mdns.c
lib/mdns/src/mdns.h
lib/mdns/src/olsrd_plugin.c

index 9aac2ea..9cfcb68 100644 (file)
@@ -171,6 +171,258 @@ CreateCaptureSocket(const char *ifName)
   return skfd;
 }                               /* CreateCaptureSocket */
 
+
+/* -------------------------------------------------------------------------
+ * Function   : CreateRouterElectionSocket
+ * Description: Create socket for capturing router election hello packets
+ * Input      : ifname - network interface (e.g. "eth0")
+ * Output     : none
+ * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
+ * Data Used  : none
+ * Notes      : The socket is a cooked IP packet socket, bound to the specified
+ *              network interface
+ * ------------------------------------------------------------------------- */
+static int
+CreateRouterElectionSocket(const char *ifName)
+{
+       int ipFamilySetting;
+       int ipProtoSetting;
+       int ipMcLoopSetting;
+       int ipAddMembershipSetting;
+       short int ipPort = htons(5354);
+       struct in_addr ipv4_addr;
+       struct ifreq req;
+       int ifIndex = if_nametoindex(ifName);
+
+       void * addr;
+       size_t addrSize;
+       union olsr_sockaddr address;
+
+       int rxSocket = -1;
+
+       int socketReuseFlagValue = 1;
+       int mcLoopValue = 1;
+
+
+       memset(&address, 0, sizeof(address));
+       if (olsr_cnf->ip_version == AF_INET) {
+               ipFamilySetting = AF_INET;
+               ipProtoSetting = IPPROTO_IP;
+               ipMcLoopSetting = IP_MULTICAST_LOOP;
+               ipAddMembershipSetting = IP_ADD_MEMBERSHIP;
+
+               address.in4.sin_family = ipFamilySetting;
+               address.in4.sin_addr.s_addr = INADDR_ANY;
+               address.in4.sin_port = ipPort;
+               addr = &address.in4;
+               addrSize = sizeof(struct sockaddr_in);
+       } else {
+               ipFamilySetting = AF_INET6;
+               ipProtoSetting = IPPROTO_IPV6;
+               ipMcLoopSetting = IPV6_MULTICAST_LOOP;
+               ipAddMembershipSetting = IPV6_ADD_MEMBERSHIP;
+
+               address.in6.sin6_family = ipFamilySetting;
+               address.in6.sin6_addr = in6addr_any;
+               address.in6.sin6_port = ipPort;
+               addr = &address.in6;
+               addrSize = sizeof(struct sockaddr_in6);
+       }
+
+       /* Create a datagram socket on which to receive. */
+       errno = 0;
+       rxSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
+       if (rxSocket < 0) {
+               BmfPError("Could not create a receive socket for interface %s",
+                               ifName);
+               goto bail;
+       }
+
+       /* Enable SO_REUSEADDR to allow multiple applications to receive the same
+        * multicast messages */
+       errno = 0;
+       if (setsockopt(rxSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
+                       sizeof(socketReuseFlagValue)) < 0) {
+               BmfPError("Could not set the reuse flag on the receive socket for"
+                       " interface %s", ifName);
+               goto bail;
+       }
+
+       /* Bind to the proper port number with the IP address INADDR_ANY
+        * (INADDR_ANY is really required here, do not change it) */
+       errno = 0;
+       if (bind(rxSocket, addr, addrSize) < 0) {
+               BmfPError("Could not bind the receive socket for interface"
+                       " %s to port %u", ifName, ntohs(ipPort));
+               goto bail;
+       }
+
+       /* Enable multicast local loopback */
+       errno = 0;
+       if (setsockopt(rxSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
+                       sizeof(mcLoopValue)) < 0) {
+               BmfPError("Could not %s multicast loopback on the"
+                       " receive socket for interface %s", mcLoopValue ? "enable"
+                               : "disable", ifName);
+               goto bail;
+       }
+
+       /* Join the multicast group on the local interface. Note that this
+        * ADD_MEMBERSHIP option must be called for each local interface over
+        * which the multicast datagrams are to be received. */
+       if (ipFamilySetting == AF_INET) {
+               struct ip_mreq mc_settings;
+               (void) memset(&mc_settings, 0, sizeof(mc_settings));
+               inet_pton(AF_INET, "224.0.0.2", &mc_settings.imr_multiaddr.s_addr);
+               (void) memset(&req, 0, sizeof(struct ifreq));
+               strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
+               req.ifr_name[IFNAMSIZ -1] = '\0';       /* Ensure null termination */
+               if(ioctl(rxSocket, SIOCGIFADDR, &req)){
+                       BmfPError("Could not get ipv4 address of %s interface", ifName);
+                       goto bail;
+               }
+               ipv4_addr = ((struct sockaddr_in *)&req.ifr_addr)->sin_addr;
+               mc_settings.imr_interface = ipv4_addr;
+               errno = 0;
+               if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
+                               &mc_settings, sizeof(mc_settings)) < 0) {
+                       BmfPError("Could not subscribe interface %s to the configured"
+                               " multicast group", ifName);
+                       goto bail;
+               }
+       } else {
+               struct ipv6_mreq mc6_settings;
+               (void) memset(&mc6_settings, 0, sizeof(mc6_settings));
+               inet_pton(AF_INET6, "ff02::2", &mc6_settings.ipv6mr_multiaddr.s6_addr);
+               mc6_settings.ipv6mr_interface = ifIndex;
+               errno = 0;
+               if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
+                               &mc6_settings, sizeof(mc6_settings)) < 0) {
+                       BmfPError("Could not subscribe interface %s to the configured"
+                               " multicast group", ifName);
+                       goto bail;
+               }
+       }
+
+       add_olsr_socket(rxSocket, DoElection, NULL, NULL,
+                       SP_PR_READ);
+
+       return rxSocket;
+
+       bail: if (rxSocket >= 0) {
+               close(rxSocket);
+       }
+       return -1;
+}                               /* CreateRouterElectionSocket */
+
+static int CreateHelloSocket(const char *ifName) {
+       int ipFamilySetting;
+       int ipProtoSetting;
+       int ipMcLoopSetting;
+       int ipMcIfSetting;
+       int ipTtlSetting;
+       short int ipPort = htons(5354);
+       struct in_addr ipv4_addr;
+       struct ifreq req;
+       int ifIndex = if_nametoindex(ifName);
+
+       void * addr;
+       size_t addrSize;
+       union olsr_sockaddr address;
+
+       int txSocket = -1;
+
+       int mcLoopValue = 0;
+       int txTtl = 2;
+
+       memset(&address, 0, sizeof(address));
+       if (olsr_cnf->ip_version == AF_INET) {
+               ipFamilySetting = AF_INET;
+               ipProtoSetting = IPPROTO_IP;
+               ipMcLoopSetting = IP_MULTICAST_LOOP;
+               ipMcIfSetting = IP_MULTICAST_IF;
+               ipTtlSetting = IP_MULTICAST_TTL;
+               ifIndex = if_nametoindex(ifName);
+       } else {
+               ipFamilySetting = AF_INET6;
+               ipProtoSetting = IPPROTO_IPV6;
+               ipMcLoopSetting = IPV6_MULTICAST_LOOP;
+               ipMcIfSetting = IPV6_MULTICAST_IF;
+               ipTtlSetting = IPV6_MULTICAST_HOPS;
+               ifIndex = if_nametoindex(ifName);
+
+               addr = &ifIndex;
+               addrSize = sizeof(ifIndex);
+       }
+
+       /*  Create a datagram socket on which to transmit */
+       errno = 0;
+       txSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
+       if (txSocket < 0) {
+               BmfPError("Could not create a transmit socket for interface %s",
+                               ifName);
+               goto bail;
+       }
+
+       if (olsr_cnf->ip_version == AF_INET) {
+               (void) memset(&req, 0, sizeof(struct ifreq));
+               strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
+               req.ifr_name[IFNAMSIZ -1] = '\0';       /* Ensure null termination */
+               if(ioctl(txSocket, SIOCGIFADDR, &req)){
+                       BmfPError("Could not get ipv4 address of %s interface", ifName);
+                       goto bail;
+               }
+               ipv4_addr = ((struct sockaddr_in *)&req.ifr_addr)->sin_addr;
+               address.in4.sin_addr = ipv4_addr;
+               address.in4.sin_family = ipFamilySetting;
+               address.in4.sin_port = ipPort;
+               addr = &address.in4;
+               addrSize = sizeof(struct sockaddr_in);
+       }
+
+       /* Bind the socket to the desired interface */
+       errno = 0;
+       if (setsockopt(txSocket, ipProtoSetting, ipMcIfSetting, addr, addrSize) < 0) {
+               BmfPError("Could not set the multicast interface on the"
+                       " transmit socket to interface %s", ifName);
+               goto bail;
+       }
+
+       /* Disable multicast local loopback */
+       errno = 0;
+       if (setsockopt(txSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
+                       sizeof(mcLoopValue)) < 0) {
+               BmfPError("Could not %s multicast loopback on the"
+                       " transmit socket for interface %s", mcLoopValue ? "enable"
+                               : "disable", ifName);
+               goto bail;
+       }
+
+       /* Set the TTL on the socket */
+       errno = 0;
+       if (setsockopt(txSocket, ipProtoSetting, ipTtlSetting, &txTtl,
+                       sizeof(txTtl)) < 0) {
+               BmfPError("Could not set TTL on the transmit socket"
+                       " for interface %s", ifName);
+               goto bail;
+       }
+
+       /* Set the no delay option on the socket */
+       errno = 0;
+       if (fcntl(txSocket, F_SETFL, O_NDELAY) < 0) {
+               BmfPError("Could not set the no delay option on the"
+                       " transmit socket for interface %s", ifName);
+               goto bail;
+       }
+
+       return txSocket;
+
+       bail: if (txSocket >= 0) {
+               close(txSocket);
+       }
+       return -1;
+}
+
 /* -------------------------------------------------------------------------
  * Function   : CreateInterface
  * Description: Create a new TBmfInterface object and adds it to the global
@@ -191,6 +443,8 @@ CreateInterface(const char *ifName, struct interface *olsrIntf)
   int capturingSkfd = -1;
   int encapsulatingSkfd = -1;
   int listeningSkfd = -1;
+  int electionSkfd = -1;
+  int helloSkfd = -1;
   int ioctlSkfd;
   struct ifreq ifr;
   int nOpened = 0;
@@ -208,8 +462,13 @@ CreateInterface(const char *ifName, struct interface *olsrIntf)
    * non-OLSR interfaces, and on OLSR-interfaces if configured. */
   if ((olsrIntf == NULL)) {
     capturingSkfd = CreateCaptureSocket(ifName);
-    if (capturingSkfd < 0) {
+    electionSkfd = CreateRouterElectionSocket(ifName);
+    helloSkfd = CreateHelloSocket(ifName);
+    if (capturingSkfd < 0 || electionSkfd < 0 || helloSkfd < 0) {
       close(encapsulatingSkfd);
+      close(capturingSkfd);
+      close(electionSkfd);
+      close(helloSkfd);
       free(newIf);
       return 0;
     }
@@ -229,6 +488,8 @@ CreateInterface(const char *ifName, struct interface *olsrIntf)
     BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
     close(capturingSkfd);
     close(encapsulatingSkfd);
+    close(electionSkfd);
+    close(helloSkfd);
     free(newIf);
     return 0;
   }
@@ -237,6 +498,8 @@ CreateInterface(const char *ifName, struct interface *olsrIntf)
   newIf->capturingSkfd = capturingSkfd;
   newIf->encapsulatingSkfd = encapsulatingSkfd;
   newIf->listeningSkfd = listeningSkfd;
+  newIf->electionSkfd = electionSkfd;
+  newIf->helloSkfd = helloSkfd;
   memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
   memcpy(newIf->ifName, ifName, IFNAMSIZ);
   newIf->olsrIntf = olsrIntf;
@@ -473,6 +736,14 @@ CloseBmfNetworkInterfaces(void)
       close(bmfIf->encapsulatingSkfd);
       nClosed++;
     }
+    if (bmfIf->electionSkfd >= 0) {
+      close(bmfIf->electionSkfd);
+      nClosed++;
+    }
+    if (bmfIf->helloSkfd >= 0) {
+      close(bmfIf->helloSkfd);
+      nClosed++;
+    }
     //OLSR_PRINTF(
     //  7,
     //  "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
index 82371d2..4493c7b 100644 (file)
@@ -55,6 +55,7 @@
 
 /* Size of buffer in which packets are received */
 #define BMF_BUFFER_SIZE 2048
+#define HELLO_BUFFER_SIZE 2048
 
 struct TBmfInterface {
   /* File descriptor of raw packet socket, used for capturing multicast packets */
@@ -68,6 +69,14 @@ struct TBmfInterface {
    * Used only when PlParam "BmfMechanism" is set to "UnicastPromiscuous". */
   int listeningSkfd;
 
+  /* File descriptor of UDP packet socket, used for listening router election hello
+   * packets */
+  int electionSkfd;
+
+  /* File descriptor of UDP packet socket, used for sending router election hello
+   * packets */
+  int helloSkfd;
+
   unsigned char macAddr[IFHWADDRLEN];
 
   char ifName[IFNAMSIZ];
diff --git a/lib/mdns/src/RouterElection.c b/lib/mdns/src/RouterElection.c
new file mode 100644 (file)
index 0000000..36d02bc
--- /dev/null
@@ -0,0 +1,236 @@
+/* System includes */
+#include <stddef.h>             /* NULL */
+#include <sys/types.h>          /* ssize_t */
+#include <string.h>             /* strerror() */
+#include <stdarg.h>             /* va_list, va_start, va_end */
+#include <errno.h>              /* errno */
+#include <assert.h>             /* assert() */
+#include <linux/if_ether.h>     /* ETH_P_IP */
+#include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */
+//#include <pthread.h> /* pthread_t, pthread_create() */
+#include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */
+#include <netinet/ip.h>         /* struct ip */
+#include <netinet/udp.h>        /* struct udphdr */
+#include <unistd.h>             /* close() */
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+/* OLSRD includes */
+#include "plugin_util.h"        /* set_plugin_int */
+#include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */
+#include "ipcalc.h"
+#include "olsr.h"               /* //OLSR_PRINTF */
+#include "mid_set.h"            /* mid_lookup_main_addr() */
+#include "link_set.h"           /* get_best_link_to_neighbor() */
+#include "net_olsr.h"           /* ipequal */
+#include "hna_set.h"
+
+/* plugin includes */
+#include "NetworkInterfaces.h"  /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
+#include "Address.h"            /* IsMulticast() */
+#include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
+#include "list_backport.h"
+#include "RouterElection.h"
+#include "mdns.h"
+
+ISMASTER = 1;
+struct RtElHelloPkt *hello;
+
+//List for routers
+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){
+  OLSR_PRINTF(1, "parsing ipv4 packet \n");
+  listEntry->ttl = ENTRYTTL;
+  listEntry->network_id = rcvPkt->network_id;
+  listbackport_init_node(&listEntry->list);
+  (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){
+  OLSR_PRINTF(1, "parsing ipv6 packet \n");
+  listEntry6->ttl = ENTRYTTL;
+  listEntry6->network_id = rcvPkt->network_id;
+  listbackport_init_node(&listEntry6->list);
+  (void) memcpy(&listEntry6->router_id, &rcvPkt->router_id.v6, sizeof(struct in6_addr));//Need to insert an address validity check?
+  return 1;
+}
+
+int UpdateRouterList (struct RouterListEntry *listEntry){
+
+  struct RouterListEntry *tmp, *iterator;
+  int exist = 0, status = 0;
+
+  if (olsr_cnf->ip_version == AF_INET6)                //mdns plugin is running in ipv4, discard ipv6
+    return 0;
+
+  ROUTER_ELECTION_ENTRIES(tmp, iterator) {
+    OLSR_PRINTF(1,"inspecting entry");
+    if((tmp->network_id == listEntry->network_id) &&
+               (memcmp(&listEntry->router_id, &tmp->router_id, sizeof(struct in_addr)) == 0)){
+      exist = 1;
+      tmp->ttl = listEntry->ttl;
+      status = 1;
+    }
+  }
+    if (exist == 0)
+      listbackport_add_tail(&ListOfRouter, &(listEntry->list));
+  return status;
+}
+
+int UpdateRouterList6 (struct RouterListEntry6 *listEntry6){
+
+  struct RouterListEntry6 *tmp, *iterator;
+  int exist = 0, status = 0;
+
+  if (olsr_cnf->ip_version == AF_INET)         //mdns plugin is running in ipv6, discard ipv4
+    return 0;
+  ROUTER_ELECTION_ENTRIES(tmp, iterator) { 
+    if((tmp->network_id == listEntry6->network_id) &&
+              (memcmp(&listEntry6->router_id, &tmp->router_id, sizeof(struct in6_addr))) == 0){
+      exist = 1;
+      tmp->ttl = listEntry6->ttl;
+      status = 1;
+    }
+  }
+    if (exist == 0)
+      listbackport_add_tail(&ListOfRouter, &(listEntry6->list));
+  return status;
+}
+
+void helloTimer (void *foo __attribute__ ((unused))){
+
+  struct TBmfInterface *walker;
+  struct sockaddr_in dest;
+  struct sockaddr_in6 dest6;
+  OLSR_PRINTF(1,"hello start \n");
+
+  for (walker = BmfInterfaces; walker != NULL; walker = walker->next) {
+    if (olsr_cnf->ip_version == AF_INET) {
+      memset((char *) &dest, 0, sizeof(dest));
+      dest.sin_family = AF_INET;
+      dest.sin_addr.s_addr = inet_addr("224.0.0.2");
+      dest.sin_port = htons(5354);
+
+      OLSR_PRINTF(1,"hello running \n");
+
+      sendto(walker->helloSkfd, (const char * ) hello, 
+                       sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest, sizeof(dest));
+    }
+    else{
+      memset((char *) &dest6, 0, sizeof(dest6));
+      dest6.sin6_family = AF_INET6;
+      (void) inet_pton(AF_INET6, "ff02::2", &dest6.sin6_addr);
+      dest6.sin6_port = htons(5354);
+
+      OLSR_PRINTF(1,"hello running \n");
+
+      OLSR_PRINTF(1,"%i \n", (int) sendto(walker->helloSkfd, (const char * ) hello,  
+                        sizeof(struct RtElHelloPkt), 0, (struct sockaddr *)&dest6, sizeof(dest6)));
+    }
+  }
+  return;
+}
+
+void electTimer (void *foo __attribute__ ((unused))){
+
+  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;
+  }
+
+  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);
+      }
+      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);
+      }
+    }
+  }
+
+  OLSR_PRINTF(1,"elect finish \n");
+
+  return;
+}
+
+void initTimer (void *foo __attribute__ ((unused))){
+  listbackport_init_head(&ListOfRouter);
+  char hd[] = "$REP";
+
+  NETWORK_ID = (uint8_t) 1;             //Default Network id
+
+  OLSR_PRINTF(1,"Initialization \n");
+  memcpy(&ROUTER_ID, &olsr_cnf->main_addr, sizeof(union olsr_ip_addr));
+  hello = (struct RtElHelloPkt *) malloc(sizeof(struct RtElHelloPkt));
+  OLSR_PRINTF(1,"initialization running step 1\n");
+  strcpy(hello->head, hd);
+  if(olsr_cnf->ip_version == AF_INET)
+    hello->ipFamily = AF_INET;
+  else
+    hello->ipFamily = AF_INET6;
+  hello->network_id = NETWORK_ID;
+  memcpy(&hello->router_id, &ROUTER_ID, sizeof(union olsr_ip_addr));
+  OLSR_PRINTF(1,"initialization end\n");
+  return;
+}
+
+int
+set_Network_ID(const char *Network_ID, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+{
+  int temp;
+  assert(Network_ID!= NULL);
+  set_plugin_int(Network_ID, &temp, addon);
+  NETWORK_ID = (uint8_t) temp;
+  return 1;
+} /* Set Network ID */
+
+
+int InitRouterList(){
+
+  struct olsr_cookie_info *RouterElectionTimerCookie = NULL;
+  struct olsr_cookie_info *HelloTimerCookie = NULL;
+  struct olsr_cookie_info *InitCookie = NULL;
+
+  RouterElectionTimerCookie = olsr_alloc_cookie("Router Election", OLSR_COOKIE_TYPE_TIMER);
+  HelloTimerCookie = olsr_alloc_cookie("Hello Packet", OLSR_COOKIE_TYPE_TIMER);
+  InitCookie = olsr_alloc_cookie("Init", OLSR_COOKIE_TYPE_TIMER);
+
+  olsr_start_timer((unsigned int) INIT_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_ONESHOT, initTimer, NULL,
+                  InitCookie);
+  olsr_start_timer((unsigned int) HELLO_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, helloTimer, NULL,
+                  HelloTimerCookie);
+  olsr_start_timer((unsigned int) ELECTION_TIMER * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, electTimer, NULL,
+                   RouterElectionTimerCookie);
+
+  return 0;
+}
diff --git a/lib/mdns/src/RouterElection.h b/lib/mdns/src/RouterElection.h
new file mode 100644 (file)
index 0000000..a440a27
--- /dev/null
@@ -0,0 +1,43 @@
+#include <netinet/in.h>
+
+#define ELECTION_TIMER         15
+#define HELLO_TIMER            20
+#define INIT_TIMER             1
+#define ENTRYTTL               10
+
+struct RtElHelloPkt{
+  unsigned char head[4]; //"$REP"
+  int ipFamily;
+  union olsr_ip_addr router_id;
+  uint8_t network_id;
+} __attribute__((__packed__));
+
+struct RouterListEntry{
+  struct in_addr router_id;
+  uint8_t network_id;
+  int ttl;
+
+  struct list_entity list;
+};
+
+struct RouterListEntry6{
+  struct in6_addr router_id;
+  uint8_t network_id;
+  int ttl;
+
+  struct list_entity list;
+};
+
+extern int ISMASTER;
+uint8_t NETWORK_ID;
+union olsr_ip_addr ROUTER_ID;
+
+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 InitRouterList ();
+void helloTimer (void *foo __attribute__ ((unused)));
+void electTimer (void *foo __attribute__ ((unused)));
+void initTimer (void *foo __attribute__ ((unused)));
+int set_Network_ID(const char *Network_ID, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));
index 20e3a8b..7ca5afb 100644 (file)
@@ -37,8 +37,8 @@
  * the copyright holders.
  */
 
-#ifndef LIST_H_
-#define LIST_H_
+#ifndef LISTBACKPORT_H_
+#define LISTBACKPORT_H_
 
 #include <stddef.h>
 #include <stdbool.h>
index fc4e31e..5d54f1d 100644 (file)
@@ -73,6 +73,7 @@
 #include "Address.h"            /* IsMulticast() */
 #include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
 #include "list_backport.h"
+#include "RouterElection.h"
 
 #define OLSR_FOR_ALL_FILTEREDNODES_ENTRIES(n, iterator) list_for_each_element_safe(&ListOfFilteredHosts, n, list, iterator)
 
@@ -142,6 +143,9 @@ 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
+        return;
+
       nBytesWritten = sendto(walker->capturingSkfd, encapsulationUdpData, stripped_len, 0, (struct sockaddr *)&dest, sizeof(dest));
       if (nBytesWritten != stripped_len) {
         BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
@@ -382,11 +386,15 @@ BmfPacketCaptured(
        if(((u_int8_t) ipHeader->ip_ttl) <= ((u_int8_t) 1))    // Discard mdns packet with TTL limit 1 or less
                return;
 
-    if (isInFilteredList(&src)) {
+    if(ISMASTER == 0)             //Don't forward packet if isn't master router
+      return;
+
+
+/*    if (isInFilteredList(&src)) {
 
        return;
     }
-
+*/
   }                             //END IPV4
 
   else if ((encapsulationUdpData[0] & 0xf0) == 0x60) {  //IPv6
@@ -414,12 +422,16 @@ BmfPacketCaptured(
     if(my_TTL_Check)
        if(((uint8_t) ipHeader6->ip6_hops) <= ((uint8_t) 1))  // Discard mdns packet with hop limit 1 or less
                return;
-    
-    if (isInFilteredList(&src)) {
+  
+    if(ISMASTER == 0)             //Don't forward packet if isn't master router
+      return;
+
+  
+/*    if (isInFilteredList(&src)) {
     
     return;
     }
-
+*/
   }                             //END IPV6
   else
     return;                     //Is not IP packet
@@ -505,6 +517,7 @@ InitMDNS(struct interface *skipThisIntf)
   olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
   //Creates captures sockets and register them to the OLSR scheduler
   CreateBmfNetworkInterfaces(skipThisIntf);
+  InitRouterList();
 
   return 1;
 }                               /* InitMDNS */
@@ -522,3 +535,68 @@ CloseMDNS(void)
 {
   CloseBmfNetworkInterfaces();
 }
+
+void DoElection(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
+{
+  static const char * rxBufferPrefix = "$REP";
+  static const size_t rxBufferPrefixLength = 4;
+  unsigned char rxBuffer[HELLO_BUFFER_SIZE];
+  ssize_t rxCount;
+  union olsr_sockaddr sender;
+  socklen_t senderSize = sizeof(sender);
+  struct RtElHelloPkt *rcvPkt;
+  struct RouterListEntry *listEntry;
+  struct RouterListEntry6 *listEntry6;
+
+  OLSR_PRINTF(1,"Packet Received \n");
+
+  if (skfd >= 0) {
+    memset(&sender, 0, senderSize);
+    rxCount = recvfrom(skfd, &rxBuffer[0], (sizeof(rxBuffer) - 1), 0,
+               (struct sockaddr *)&sender, &senderSize);
+    if(rxCount < 0){
+      BmfPError("Receive error in %s, ignoring message.", __func__);
+      return;
+    }
+
+  /* make sure the string is null terminated */
+  rxBuffer[rxCount] = '\0';
+
+  /* do not process when this message doesn't start with $REP */
+  if ((rxCount < rxBufferPrefixLength) || (strncmp((char *) rxBuffer,
+                 rxBufferPrefix, rxBufferPrefixLength) != 0))
+    return;
+
+  if (rxCount < sizeof(struct RtElHelloPkt))
+    return;                                    // too small to be a hello pkt
+  else
+    rcvPkt = (struct RtElHelloPkt *)ARM_NOWARN_ALIGN(rxBuffer);
+
+  if (rcvPkt->ipFamily == AF_INET){
+    listEntry = (struct RouterListEntry *)malloc(sizeof(struct RouterListEntry));
+    if(ParseElectionPacket(rcvPkt, listEntry)){
+      OLSR_PRINTF(1,"processing ipv4 packet \n");
+      if(UpdateRouterList(listEntry))
+        free(listEntry);
+    }
+    else{
+      free(listEntry);
+      return;                                  //packet not valid
+    }
+  }
+  else{
+    listEntry6 = (struct RouterListEntry6 *)malloc(sizeof(struct RouterListEntry6));
+    if(ParseElectionPacket6(rcvPkt, listEntry6)){
+      OLSR_PRINTF(1,"processing ipv6 packet");
+      if(UpdateRouterList6(listEntry6))
+        free(listEntry6);
+    }
+    else{
+      free(listEntry6);
+      return;                                  //packet not valid
+    }
+  }
+  
+  }
+ return;
+}
index dd876e1..3547351 100644 (file)
@@ -74,6 +74,7 @@ extern struct list_entity ListOfFilteredHosts;
 //extern int BroadcastRetransmitCount;
 
 void DoMDNS(int sd, void *x, unsigned int y);
+void DoElection(int skfd, void *x, unsigned int y);
 void BmfPError(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
 union olsr_ip_addr *MainAddressOf(union olsr_ip_addr *ip);
 //int InterfaceChange(struct interface* interf, int action);
@@ -88,6 +89,7 @@ void olsr_mdns_gen(unsigned char *packet, int len);
 /* Parser function to register with the scheduler */
 bool olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
+
 #endif /* _MDNS_MDNS_H */
 
 /*
index ded6c71..941a910 100644 (file)
@@ -54,7 +54,7 @@
 #include "mdns.h"               /* InitBmf(), CloseBmf() */
 #include "NetworkInterfaces.h"  /* AddNonOlsrBmfIf(), SetBmfInterfaceIp(), ... */
 #include "Address.h"            /* DoLocalBroadcast() */
-
+#include "RouterElection.h"
 static void __attribute__ ((constructor)) my_init(void);
 static void __attribute__ ((destructor)) my_fini(void);
 
@@ -127,6 +127,7 @@ static const struct olsrd_plugin_parameters plugin_parameters[] = {
   {.name = "MDNS_TTL", .set_plugin_parameter = &set_MDNS_TTL, .data = NULL },
   {.name = "FilteredHost", .set_plugin_parameter = &AddFilteredHost, .data = NULL },
   {.name = "TTL_Check", .set_plugin_parameter = &set_TTL_Check, .data = NULL},
+  {.name = "Network_ID", .set_plugin_parameter = &set_Network_ID, .data = NULL},
   //{ .name = "DoLocalBroadcast", .set_plugin_parameter = &DoLocalBroadcast, .data = NULL },
   //{ .name = "BmfInterface", .set_plugin_parameter = &SetBmfInterfaceName, .data = NULL },
   //{ .name = "BmfInterfaceIp", .set_plugin_parameter = &SetBmfInterfaceIp, .data = NULL },