move avl and list library into src/common
[olsrd.git] / src / olsr.c
index 76fb80b..6f638c3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
@@ -36,7 +36,6 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: olsr.c,v 1.51 2007/04/20 13:46:04 bernd67 Exp $
  */
 
 /**
@@ -60,6 +59,8 @@
 #include "neighbor_table.h"
 #include "log.h"
 #include "lq_packet.h"
+#include "common/avl.h"
+#include "net_olsr.h"
 
 #include <stdarg.h>
 #include <signal.h>
@@ -110,7 +111,7 @@ register_pcf(int (*f)(int, int, int))
 {
   struct pcf *new_pcf;
 
-  OLSR_PRINTF(1, "Registering pcf function\n")
+  OLSR_PRINTF(1, "Registering pcf function\n");
 
   new_pcf = olsr_malloc(sizeof(struct pcf), "New PCF");
 
@@ -135,11 +136,11 @@ olsr_process_changes(void)
 
 #ifdef DEBUG
   if(changes_neighborhood)
-    OLSR_PRINTF(3, "CHANGES IN NEIGHBORHOOD\n")
+    OLSR_PRINTF(3, "CHANGES IN NEIGHBORHOOD\n");
   if(changes_topology)
-    OLSR_PRINTF(3, "CHANGES IN TOPOLOGY\n")
+    OLSR_PRINTF(3, "CHANGES IN TOPOLOGY\n");
   if(changes_hna)
-    OLSR_PRINTF(3, "CHANGES IN HNA\n")
+    OLSR_PRINTF(3, "CHANGES IN HNA\n");
 #endif
   
   if(!changes_force &&
@@ -155,54 +156,21 @@ olsr_process_changes(void)
   if (olsr_cnf->debug_level > 0 && olsr_cnf->clear_screen && isatty(1))
   {
       clear_console();
-      printf("%s", OLSRD_VERSION_DATE);
+      printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
   }
 
-  if (changes_neighborhood)
-    {
-      /* Calculate new mprs, HNA and routing table */
-      if (olsr_cnf->lq_level < 1)
-        {
-          olsr_calculate_mpr();
-        }
-
-      else
-        {
-          olsr_calculate_lq_mpr();
-        }
-
-      if (olsr_cnf->lq_level < 2)
-        {
-          olsr_calculate_routing_table();
-          olsr_calculate_hna_routes();
-        }
-    }
-  
-  else if (changes_topology)
-    {
-      /* calculate the routing table and HNA */
-
-      if (olsr_cnf->lq_level < 2)
-        {
-          olsr_calculate_routing_table();
-          olsr_calculate_hna_routes();
-        }
+  if (changes_neighborhood) {
+    if (olsr_cnf->lq_level < 1) {
+      olsr_calculate_mpr();
+    } else {
+      olsr_calculate_lq_mpr();
     }
+  }
 
-  else if (changes_hna)
-    {
-      /* update HNA routes */
-
-      if (olsr_cnf->lq_level < 2)
-        {
-          olsr_calculate_hna_routes();
-        }
-    }
-  
-  if (olsr_cnf->lq_level >= 2)
-    {
-      olsr_calculate_lq_routing_table();
-    }
+  /* calculate the routing table */
+  if (changes_neighborhood || changes_topology || changes_hna) {
+    olsr_calculate_routing_table(NULL);
+  }
   
   if (olsr_cnf->debug_level > 0)
     {      
@@ -219,11 +187,13 @@ olsr_process_changes(void)
               olsr_print_hna_set();
             }
         }
-      
+
+#if 1     
       olsr_print_link_set();
       olsr_print_neighbor_table();
       olsr_print_two_hop_neighbor_table();
       olsr_print_tc_table();
+#endif
     }
 
   for(tmp_pc_list = pcf_list; 
@@ -239,9 +209,6 @@ olsr_process_changes(void)
   changes_topology = OLSR_FALSE;
   changes_hna = OLSR_FALSE;
   changes_force = OLSR_FALSE;
-
-
-  return;
 }
 
 
@@ -260,11 +227,20 @@ olsr_init_tables(void)
   changes_neighborhood = OLSR_FALSE;
   changes_hna = OLSR_FALSE;
 
+  /* Set avl tree comparator */
+  if (olsr_cnf->ipsize == 4) {
+    avl_comp_default = NULL;
+    avl_comp_prefix_default = avl_comp_ipv4_prefix;
+  } else {
+    avl_comp_default = avl_comp_ipv6;
+    avl_comp_prefix_default = avl_comp_ipv6_prefix;
+  }
+
   /* Initialize link set */
   olsr_init_link_set();
 
   /* Initialize duplicate table */
-  olsr_init_duplicate_table();
+  olsr_init_duplicate_set();
 
   /* Initialize neighbor table */
   olsr_init_neighbor_table();
@@ -275,9 +251,6 @@ olsr_init_tables(void)
   /* Initialize two hop table */
   olsr_init_two_hop_table();
 
-  /* Initialize old route table */
-  olsr_init_old_table();
-
   /* Initialize topology */
   olsr_init_tc();
 
@@ -289,6 +262,12 @@ olsr_init_tables(void)
 
   /* Initialize HNA set */
   olsr_init_hna_set();  
+
+  /* Start periodic SPF and RIB recalculation */
+  if (olsr_cnf->lq_dinter > 0.0) {
+    olsr_start_timer((unsigned int)(olsr_cnf->lq_dinter * MSEC_PER_SEC), 5,
+                     OLSR_TIMER_PERIODIC, &olsr_calculate_routing_table, NULL, 0);
+  }
 }
 
 /**
@@ -303,9 +282,6 @@ olsr_init_tables(void)
  */
 int
 olsr_forward_message(union olsr_message *m, 
-                    union olsr_ip_addr *originator, 
-                    olsr_u16_t seqno,
-                    struct interface *in_if, 
                     union olsr_ip_addr *from_addr)
 {
   union olsr_ip_addr *src;
@@ -313,14 +289,19 @@ olsr_forward_message(union olsr_message *m,
   int msgsize;
   struct interface *ifn;
 
-
-  if(!olsr_check_dup_table_fwd(originator, seqno, &in_if->ip_addr))
-    {
-#ifdef DEBUG
-      OLSR_PRINTF(3, "Message already forwarded!\n")
-#endif
-      return 0;
-    }
+  /*
+   * Sven-Ola: We should not flood the mesh with overdue messages. Because
+   * of a bug in parser.c:parse_packet, we have a lot of messages because
+   * all older olsrd's have lq_fish enabled.
+   */
+  if (AF_INET == olsr_cnf->ip_version)
+  {
+    if (2 > m->v4.ttl || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl) return 0;
+  }
+  else
+  {
+    if (2 > m->v6.ttl || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl) return 0;
+  }
 
   /* Lookup sender address */
   src = mid_lookup_main_addr(from_addr);
@@ -334,15 +315,14 @@ olsr_forward_message(union olsr_message *m,
   if(neighbor->status != SYM)
     return 0;
 
-  /* Update duplicate table interface */
-  olsr_update_dup_entry(originator, seqno, &in_if->ip_addr);
-
-  
   /* Check MPR */
   if(olsr_lookup_mprs_set(src) == NULL)
     {
 #ifdef DEBUG
-      OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(src))
+#ifndef NODEBUG
+      struct ipaddr_str buf;
+#endif
+      OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(&buf, src));
 #endif
       return 0;
     }
@@ -361,9 +341,6 @@ olsr_forward_message(union olsr_message *m,
       m->v6.ttl--; 
     }
 
-  /* Update dup forwarded */
-  olsr_set_dup_forward(originator, seqno);
-
   /* Update packet data */
   msgsize = ntohs(m->v4.olsr_msgsize);
 
@@ -375,16 +352,16 @@ olsr_forward_message(union olsr_message *m,
          /*
           * Check if message is to big to be piggybacked
           */
-         if(net_outbuffer_push(ifn, (olsr_u8_t *)m, msgsize) != msgsize)
+         if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
            {
              /* Send */
              net_output(ifn);
              /* Buffer message */
              set_buffer_timer(ifn);
              
-             if(net_outbuffer_push(ifn, (olsr_u8_t *)m, msgsize) != msgsize)
+             if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
                {
-                 OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize)
+                 OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
                  olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
                }
            }
@@ -394,9 +371,9 @@ olsr_forward_message(union olsr_message *m,
          /* No forwarding pending */
          set_buffer_timer(ifn);
          
-         if(net_outbuffer_push(ifn, (olsr_u8_t *)m, msgsize) != msgsize)
+         if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
            {
-             OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize)
+             OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
              olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
            }
        }
@@ -407,22 +384,22 @@ olsr_forward_message(union olsr_message *m,
 
 void
 set_buffer_timer(struct interface *ifn)
-{
-  float jitter;
-      
+{      
   /* Set timer */
-  jitter = (float) random()/RAND_MAX;
-  jitter *= olsr_cnf->max_jitter;
-
-  ifn->fwdtimer = GET_TIMESTAMP(jitter*1000);
+  ifn->fwdtimer = GET_TIMESTAMP(random() * olsr_cnf->max_jitter * 1000 / RAND_MAX);
 }
 
 void
 olsr_init_willingness(void)
 {
-  if(olsr_cnf->willingness_auto)
-    olsr_register_scheduler_event(&olsr_update_willingness, 
-                                 NULL, olsr_cnf->will_int, olsr_cnf->will_int, NULL);
+  if (olsr_cnf->willingness_auto) {
+
+    /* Run it first and then periodic. */
+    olsr_update_willingness(NULL);
+
+    olsr_start_timer((unsigned int)olsr_cnf->will_int * MSEC_PER_SEC, 5,
+                     OLSR_TIMER_PERIODIC, &olsr_update_willingness, NULL, 0);
+  }
 }
 
 void
@@ -435,7 +412,7 @@ olsr_update_willingness(void *foo __attribute__((unused)))
 
   if(tmp_will != olsr_cnf->willingness)
     {
-      OLSR_PRINTF(1, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness)
+      OLSR_PRINTF(1, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
     }
 }
 
@@ -498,7 +475,7 @@ olsr_msgtype_to_string(olsr_u8_t msgtype)
       break;
     }
 
-  snprintf(type, 20, "UNKNOWN(%d)", msgtype);
+  snprintf(type, sizeof(type), "UNKNOWN(%d)", msgtype);
   return type;
 }
 
@@ -524,7 +501,7 @@ olsr_link_to_string(olsr_u8_t linktype)
       break;
     }
 
-  snprintf(type, 20, "UNKNOWN(%d)", linktype);
+  snprintf(type, sizeof(type), "UNKNOWN(%d)", linktype);
   return type;
 }
 
@@ -546,7 +523,7 @@ olsr_status_to_string(olsr_u8_t status)
       break;
     }
 
-  snprintf(type, 20, "UNKNOWN(%d)", status);
+  snprintf(type, sizeof(type), "UNKNOWN(%d)", status);
   return type;
 }
 
@@ -561,7 +538,7 @@ olsr_status_to_string(olsr_u8_t status)
 void
 olsr_exit(const char *msg, int val)
 {
-  OLSR_PRINTF(1, "OLSR EXIT: %s\n", msg)
+  OLSR_PRINTF(1, "OLSR EXIT: %s\n", msg);
   olsr_syslog(OLSR_LOG_ERR, "olsrd exit: %s\n", msg);
   fflush(stdout);
   olsr_cnf->exit_value = val;
@@ -571,25 +548,32 @@ olsr_exit(const char *msg, int val)
 
 
 /**
- *Wrapper for malloc(3) that does error-checking
+ * Wrapper for malloc(3) that does error-checking
  *
- *@param size the number of bytes to allocalte
- *@param caller a string identifying the caller for
- *use in error messaging
+ * @param size the number of bytes to allocalte
+ * @param caller a string identifying the caller for
+ * use in error messaging
  *
- *@return a void pointer to the memory allocated
+ * @return a void pointer to the memory allocated
  */
 void *
 olsr_malloc(size_t size, const char *id)
 {
   void *ptr;
 
-  if((ptr = malloc(size)) == 0) 
-    {
-      OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", strerror(errno))
-      olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");
-      olsr_exit((char *)id, EXIT_FAILURE);
-    }
+  /*
+   * Not all the callers do a proper cleaning of memory.
+   * Clean it on behalf of those.
+   */
+  ptr = calloc(1, size);
+
+  if (!ptr) {
+      const char * const err_msg = strerror(errno);
+      OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);
+      olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);
+      olsr_exit(id, EXIT_FAILURE);
+  }
+
   return ptr;
 }
 
@@ -601,7 +585,7 @@ olsr_malloc(size_t size, const char *id)
  */
 
 int
-olsr_printf(int loglevel, char *format, ...)
+olsr_printf(int loglevel, const char *format, ...)
 {
   if((loglevel <= olsr_cnf->debug_level) && debug_handle)
     {
@@ -612,3 +596,9 @@ olsr_printf(int loglevel, char *format, ...)
     }
   return 0;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */