cleanup, 1. step (to get some local changes away):
[olsrd.git] / lib / dot_draw / src / olsrd_dot_draw.c
index 795e102..4e4ba42 100644 (file)
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: olsrd_dot_draw.c,v 1.11 2005/02/20 15:51:15 kattemat Exp $
+ * $Id: olsrd_dot_draw.c,v 1.23 2007/04/20 14:06:18 bernd67 Exp $
  */
 
 /*
  * Dynamic linked library for the olsr.org olsr daemon
  */
 
-#include "olsrd_dot_draw.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+
+#include "olsr.h"
+#include "olsr_types.h"
+#include "neighbor_table.h"
+#include "two_hop_neighbor_table.h"
+#include "tc_set.h"
+#include "hna_set.h"
+#include "mid_set.h"
+#include "link_set.h"
+#include "socket_parser.h"
+
+#include "olsrd_dot_draw.h"
+#include "olsrd_plugin.h"
+
+
 #ifdef WIN32
 #define close(x) closesocket(x)
 #endif
 
-int ipc_socket;
-int ipc_open;
-int ipc_connection;
-int ipc_socket_up;
+
+static int ipc_socket;
+static int ipc_open;
+static int ipc_connection;
+static int ipc_socket_up;
+
+
+
+/* IPC initialization function */
+static int
+plugin_ipc_init(void);
+
+static char*
+olsr_netmask_to_string(union hna_netmask *mask);
+
+/* Event function to register with the sceduler */
+static int
+pcf_event(int, int, int);
+
+static void
+ipc_action(int);
+
+static void
+ipc_print_neigh_link(struct neighbor_entry *neighbor);
+
+static void
+ipc_print_tc_link(struct tc_entry *entry, struct topo_dst *dst_entry);
+
+static void
+ipc_print_net(union olsr_ip_addr *, union olsr_ip_addr *, union hna_netmask *);
+
+static int
+ipc_send(const char *, int);
+
+static int
+ipc_send_str(const char *);
 
 static double 
 calc_etx(double, double);
 
-static void inline
-ipc_print_neigh_link(struct neighbor_entry *);
+
+/**
+ *Do initialization here
+ *
+ *This function is called by the my_init
+ *function in uolsrd_plugin.c
+ */
+int
+olsrd_plugin_init(void)
+{
+  /* Initial IPC value */
+  ipc_open = 0;
+  ipc_socket_up = 0;
+  ipc_socket = -1;
+  ipc_connection = -1;
+
+  /* Register the "ProcessChanges" function */
+  register_pcf(&pcf_event);
+
+  plugin_ipc_init();
+
+  return 1;
+}
 
 
+/**
+ * destructor - called at unload
+ */
+void
+olsr_plugin_exit(void)
+{
+  if(ipc_open)
+    close(ipc_socket);
+}
 
 
-static void inline
+static void
 ipc_print_neigh_link(struct neighbor_entry *neighbor)
 {
   char buf[256];
-  int len;
-  char* adr;
-  double etx=0.0;
+  const char* adr;
+  double etx = 0.0;
   char* style = "solid";
   struct link_entry* link;
-  adr = olsr_ip_to_string(main_addr);
-  len = sprintf( buf, "\"%s\" -> ", adr );
-  ipc_send(buf, len);
+  adr = olsr_ip_to_string(&olsr_cnf->main_addr);
+  sprintf( buf, "\"%s\" -> ", adr );
+  ipc_send_str(buf);
   
   adr = olsr_ip_to_string(&neighbor->neighbor_main_addr);
   
   if (neighbor->status == 0) { // non SYM
        style = "dashed";
   }
-  else {
-    /* find best link to neighbor for the ETX */
-    //? why cant i just get it one time at fetch_olsrd_data??? (br1)
-    if(olsr_plugin_io(GETD__LINK_SET, &link, sizeof(link)) && link)
-    {
-      link_set = link; // for olsr_neighbor_best_link    
-      link = olsr_neighbor_best_link(&neighbor->neighbor_main_addr);
+  else {   
+      link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
       if (link) {
         etx = calc_etx( link->loss_link_quality, link->neigh_link_quality);
       }
-    }
   }
     
-  len = sprintf( buf, "\"%s\"[label=\"%.2f\", style=%s];\n", adr, etx, style );
-  ipc_send(buf, len);
+  sprintf( buf, "\"%s\"[label=\"%.2f\", style=%s];\n", adr, etx, style );
+  ipc_send_str(buf);
   
    if (neighbor->is_mpr) {
-       len = sprintf( buf, "\"%s\"[shape=box];\n", adr );
-       ipc_send(buf, len);
+       sprintf( buf, "\"%s\"[shape=box];\n", adr );
+       ipc_send_str(buf);
   }
 }
 
-/**
- *Do initialization here
- *
- *This function is called by the my_init
- *function in uolsrd_plugin.c
- */
-int
-olsr_plugin_init()
-{
-
-  /* Initial IPC value */
-  ipc_open = 0;
-  ipc_socket_up = 0;
-
-  /* Register the "ProcessChanges" function */
-  register_pcf(&pcf_event);
 
-  return 1;
-}
-
-int
-plugin_ipc_init()
+static int
+plugin_ipc_init(void)
 {
   struct sockaddr_in sin;
   olsr_u32_t yes = 1;
@@ -148,7 +206,7 @@ plugin_ipc_init()
        return 0;
       }
 
-#ifdef __FreeBSD__
+#if defined __FreeBSD__ && defined SO_NOSIGPIPE
       if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0) 
       {
        perror("SO_REUSEADDR failed");
@@ -180,6 +238,7 @@ plugin_ipc_init()
 
 
       /* Register with olsrd */
+      printf("Adding socket with olsrd\n");
       add_olsr_socket(ipc_socket, &ipc_action);
       ipc_socket_up = 1;
     }
@@ -187,28 +246,37 @@ plugin_ipc_init()
   return 1;
 }
 
-void
-ipc_action(int fd)
+
+static void
+ipc_action(int fd __attribute__((unused)))
 {
   struct sockaddr_in pin;
-  socklen_t addrlen;
-  char *addr;  
-
-  addrlen = sizeof(struct sockaddr_in);
+  socklen_t addrlen = sizeof(struct sockaddr_in);
 
+  if (ipc_open)
+    {
+      int rc;
+      do {
+        rc = close(ipc_connection);
+      } while (rc == -1 && (errno == EINTR || errno == EAGAIN));
+      if (rc == -1) {
+        olsr_printf(1, "(DOT DRAW) Error on closing previously active TCP connection on fd %d: %s\n", ipc_connection, strerror(errno));
+      }
+      ipc_open = 0;
+    }
+  
   if ((ipc_connection = accept(ipc_socket, (struct sockaddr *)  &pin, &addrlen)) == -1)
     {
       olsr_printf(1, "(DOT DRAW)IPC accept: %s\n", strerror(errno));
-      exit(1);
     }
   else
     {
-      addr = inet_ntoa(pin.sin_addr);
+      char *addr = inet_ntoa(pin.sin_addr);
       if(ntohl(pin.sin_addr.s_addr) != ntohl(ipc_accept_ip.s_addr))
        {
          olsr_printf(1, "Front end-connection from foregin host(%s) not allowed!\n", addr);
          close(ipc_connection);
-         return;
+          ipc_connection = -1;
        }
       else
        {
@@ -217,42 +285,13 @@ ipc_action(int fd)
          pcf_event(1, 1, 1);
        }
     }
-
 }
 
-/*
- * destructor - called at unload
- */
-void
-olsr_plugin_exit()
-{
-  if(ipc_open)
-    close(ipc_socket);
-}
-
-
-
-/* Mulitpurpose funtion */
-int
-plugin_io(int cmd, void *data, size_t size)
-{
-
-  switch(cmd)
-    {
-    default:
-      return 0;
-    }
-  
-  return 1;
-}
-
-
-
 
 /**
  *Scheduled event
  */
-int
+static int
 pcf_event(int changes_neighborhood,
          int changes_topology,
          int changes_hna)
@@ -271,7 +310,7 @@ pcf_event(int changes_neighborhood,
     {
       /* Print tables to IPC socket */
 
-      ipc_send("digraph topology\n{\n", strlen("digraph topology\n{\n"));
+      ipc_send_str("digraph topology\n{\n");
 
       /* Neighbors */
       for(index=0;index<HASHSIZE;index++)
@@ -326,7 +365,7 @@ pcf_event(int changes_neighborhood,
        }
 
 
-      ipc_send("}\n\n", strlen("}\n\n"));
+      ipc_send_str("}\n\n");
 
       res = 1;
     }
@@ -338,6 +377,7 @@ pcf_event(int changes_neighborhood,
   return res;
 }
 
+
 #define MIN_LINK_QUALITY 0.01
 static double 
 calc_etx(double loss, double neigh_loss) 
@@ -349,61 +389,69 @@ calc_etx(double loss, double neigh_loss)
 }
 
 
-static void inline
+static void
 ipc_print_tc_link(struct tc_entry *entry, struct topo_dst *dst_entry)
 {
   char buf[256];
-  int len;
-  char* adr;
+  const char* adr;
   double etx = calc_etx( dst_entry->link_quality, dst_entry->inverse_link_quality );
 
   adr = olsr_ip_to_string(&entry->T_last_addr);
-  len = sprintf( buf, "\"%s\" -> ", adr );
-  ipc_send(buf, len);
+  sprintf( buf, "\"%s\" -> ", adr );
+  ipc_send_str(buf);
   
   adr = olsr_ip_to_string(&dst_entry->T_dest_addr);
-  len = sprintf( buf, "\"%s\"[label=\"%.2f\"];\n", adr, etx );
-  ipc_send(buf, len);
+  sprintf( buf, "\"%s\"[label=\"%.2f\"];\n", adr, etx );
+  ipc_send_str(buf);
 }
 
-static void inline
+
+static void
 ipc_print_net(union olsr_ip_addr *gw, union olsr_ip_addr *net, union hna_netmask *mask)
 {
-  char *adr;
+  const char *adr;
 
   adr = olsr_ip_to_string(gw);
-  ipc_send("\"", 1);
-  ipc_send(adr, strlen(adr));
-  ipc_send("\" -> \"", strlen("\" -> \""));
+  ipc_send_str("\"");
+  ipc_send_str(adr);
+  ipc_send_str("\" -> \"");
   adr = olsr_ip_to_string(net);
-  ipc_send(adr, strlen(adr));
-  ipc_send("/", 1);
+  ipc_send_str(adr);
+  ipc_send_str("/");
   adr = olsr_netmask_to_string(mask);
-  ipc_send(adr, strlen(adr));
-  ipc_send("\"[label=\"HNA\"];\n", strlen("\"[label=\"HNA\"];\n"));
-  ipc_send("\"", 1);
+  ipc_send_str(adr);
+  ipc_send_str("\"[label=\"HNA\"];\n");
+  ipc_send_str("\"");
   adr = olsr_ip_to_string(net);
-  ipc_send(adr, strlen(adr));
-  ipc_send("/", 1);
+  ipc_send_str(adr);
+  ipc_send_str("/");
   adr = olsr_netmask_to_string(mask);
-  ipc_send(adr, strlen(adr));
-  ipc_send("\"", 1);
-  ipc_send("[shape=diamond];\n", strlen("[shape=diamond];\n"));
+  ipc_send_str(adr);
+  ipc_send_str("\"");
+  ipc_send_str("[shape=diamond];\n");
 }
 
+static int
+ipc_send_str(const char *data)
+{
+  if(!ipc_open)
+    return 0;
+  return ipc_send(data, strlen(data));
+}
 
 
-int
-ipc_send(char *data, int size)
+static int
+ipc_send(const char *data, int size)
 {
   if(!ipc_open)
     return 0;
 
-#ifdef __FreeBSD__
-  if (send(ipc_connection, data, size, 0) < 0) 
+#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __MacOSX__
+#define FLAGS 0
 #else
-  if (send(ipc_connection, data, size, MSG_NOSIGNAL) < 0) 
+#define FLAGS MSG_NOSIGNAL
 #endif
+  if (send(ipc_connection, data, size, FLAGS) == -1)
     {
       olsr_printf(1, "(DOT DRAW)IPC connection lost!\n");
       close(ipc_connection);
@@ -414,100 +462,24 @@ ipc_send(char *data, int size)
   return 1;
 }
 
-
-
-
-
-/**
- *Converts a olsr_ip_addr to a string
- *Goes for both IPv4 and IPv6
- *
- *@param the IP to convert
- *@return a pointer to a static string buffer
- *representing the address in "dots and numbers"
- *
- */
-char *
-olsr_ip_to_string(union olsr_ip_addr *addr)
-{
-  static int index = 0;
-  static char buff[4][100];
-  char *ret;
-  struct in_addr in;
-  if(ipversion == AF_INET)
-    {
-      in.s_addr=addr->v4;
-      ret = inet_ntoa(in);
-    }
-  else
-    {
-      /* IPv6 */
-      ret = (char *)inet_ntop(AF_INET6, &addr->v6, ipv6_buf, sizeof(ipv6_buf));
-    }
-
-  strncpy(buff[index], ret, 100);
-
-  ret = buff[index];
-
-  index = (index + 1) & 3;
-
-  return ret;
-}
-
-
-/**
- *This function is just as bad as the previous one :-(
- */
-char *
+static char*
 olsr_netmask_to_string(union hna_netmask *mask)
 {
   char *ret;
   struct in_addr in;
-  
-  if(ipversion == AF_INET)
+
+  if(olsr_cnf->ip_version == AF_INET)
     {
       in.s_addr = mask->v4;
       ret = inet_ntoa(in);
-      return ret;
-
     }
   else
     {
       /* IPv6 */
+      static char netmask[5];
       sprintf(netmask, "%d", mask->v6);
-      return netmask;
+      ret = netmask;
     }
 
   return ret;
 }
-
-#define COMP_IP(ip1, ip2) (!memcmp(ip1, ip2, ipsize))
-struct link_entry *olsr_neighbor_best_link(union olsr_ip_addr *main)
-{
-  struct link_entry *walker;
-  double best = 0.0;
-  double curr;
-  struct link_entry *res = NULL;
-
-  // loop through all links
-
-  for (walker = link_set; walker != NULL; walker = walker->next)
-  {
-    // check whether it's a link to the requested neighbor and
-    // whether the link's quality is better than what we have
-    if(COMP_IP(main, &walker->neighbor->neighbor_main_addr))
-    {
-      curr = walker->loss_link_quality * walker->neigh_link_quality;
-
-      if (curr >= best)
-      {
-        best = curr;
-        res = walker;
-      }
-    }
-  }
-
-  return res;
-}
-