Fix issues found by Coverity.
[oweals/tinc.git] / src / graph.c
index 297832cda5bb8f3eeabd8cf241c3eeacfc8601f0..73dadc47f6152c300a4f9924536d9474ca22c489 100644 (file)
@@ -1,6 +1,6 @@
 /*
     graph.c -- graph algorithms
-    Copyright (C) 2001-2011 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
                   2001-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
@@ -45,7 +45,7 @@
 #include "system.h"
 
 #include "avl_tree.h"
-#include "config.h"
+#include "conf.h"
 #include "connection.h"
 #include "device.h"
 #include "edge.h"
@@ -156,7 +156,7 @@ static void sssp_bfs(void) {
        bool indirect;
        char *name;
        char *address, *port;
-       char *envp[7];
+       char *envp[8] = {NULL};
        int i;
 
        todo_list = list_alloc(NULL);
@@ -212,9 +212,13 @@ static void sssp_bfs(void) {
                           && (!e->to->status.indirect || indirect))
                                continue;
 
+                       // Only update nexthop the first time we visit this node.
+
+                       if(!e->to->status.visited)
+                               e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
+
                        e->to->status.visited = true;
                        e->to->status.indirect = indirect;
-                       e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
                        e->to->prevedge = e;
                        e->to->via = indirect ? n->via : e->to;
                        e->to->options = e->options;
@@ -269,7 +273,7 @@ static void sssp_bfs(void) {
                        sockaddr2str(&n->address, &address, &port);
                        xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
                        xasprintf(&envp[5], "REMOTEPORT=%s", port);
-                       envp[6] = NULL;
+                       xasprintf(&envp[6], "NAME=%s", myself->name);
 
                        execute_script(n->status.reachable ? "host-up" : "host-down", envp);
 
@@ -282,15 +286,18 @@ static void sssp_bfs(void) {
                        free(address);
                        free(port);
 
-                       for(i = 0; i < 6; i++)
+                       for(i = 0; i < 7; i++)
                                free(envp[i]);
 
                        subnet_update(n, NULL, n->status.reachable);
 
-                       if(!n->status.reachable)
+                       if(!n->status.reachable) {
                                update_node_udp(n, NULL);
-                       else if(n->connection)
+                               memset(&n->status, 0, sizeof n->status);
+                               n->options = 0;
+                       } else if(n->connection) {
                                send_ans_key(n);
+                       }
                }
        }
 }
@@ -315,7 +322,7 @@ void dump_graph(void) {
        node_t *n;
        edge_t *e;
        char *filename = NULL, *tmpname = NULL;
-       FILE *file;
+       FILE *file, *pipe = NULL;
        
        if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename))
                return;
@@ -325,7 +332,7 @@ void dump_graph(void) {
        ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph");
        
        if(filename[0] == '|') {
-               file = popen(filename + 1, "w");
+               file = pipe = popen(filename + 1, "w");
        } else {
                xasprintf(&tmpname, "%s.new", filename);
                file = fopen(tmpname, "w");
@@ -333,6 +340,7 @@ void dump_graph(void) {
 
        if(!file) {
                logger(LOG_ERR, "Unable to open graph dump file %s: %s", filename, strerror(errno));
+               free(filename);
                free(tmpname);
                return;
        }
@@ -353,14 +361,17 @@ void dump_graph(void) {
 
        fprintf(file, "}\n");   
        
-       if(filename[0] == '|') {
-               pclose(file);
+       if(pipe) {
+               pclose(pipe);
        } else {
                fclose(file);
 #ifdef HAVE_MINGW
                unlink(filename);
 #endif
-               rename(tmpname, filename);
+               if(rename(tmpname, filename))
+                       logger(LOG_ERR, "Could not rename %s to %s: %s\n", tmpname, filename, strerror(errno));
                free(tmpname);
        }
+
+       free(filename);
 }