expose traffic stats to 'tinc info ___' and 'tinc dump nodes'
[tinc] / src / tincctl.c
index cd2d3d8..af54aef 100644 (file)
@@ -1,6 +1,6 @@
 /*
     tincctl.c -- Controlling a running tincd
-    Copyright (C) 2007-2017 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2018 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -92,7 +92,7 @@ static struct option const long_options[] = {
 static void version(void) {
        printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
               BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
-       printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n"
+       printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
               "See the AUTHORS file for a complete list.\n\n"
               "tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
               "and you are welcome to redistribute it under certain conditions;\n"
@@ -722,19 +722,20 @@ static bool remove_service(void) {
        SC_HANDLE manager = NULL;
        SC_HANDLE service = NULL;
        SERVICE_STATUS status = {0};
+       bool success = false;
 
        manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 
        if(!manager) {
                fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError()));
-               return false;
+               goto exit;
        }
 
        service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
 
        if(!service) {
                fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
-               return false;
+               goto exit;
        }
 
        if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
@@ -745,12 +746,26 @@ static bool remove_service(void) {
 
        if(!DeleteService(service)) {
                fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError()));
-               return false;
+               goto exit;
        }
 
-       fprintf(stderr, "%s service removed\n", identname);
+       success = true;
 
-       return true;
+exit:
+
+       if(service) {
+               CloseServiceHandle(service);
+       }
+
+       if(manager) {
+               CloseServiceHandle(manager);
+       }
+
+       if(success) {
+               fprintf(stderr, "%s service removed\n", identname);
+       }
+
+       return success;
 }
 #endif
 
@@ -1013,7 +1028,7 @@ static int cmd_start(int argc, char *argv[]) {
 #endif
 
        // Pass all log messages from the umbilical to stderr.
-       // A nul-byte right before closure means tincd started succesfully.
+       // A nul-byte right before closure means tincd started successfully.
        bool failure = true;
        char buf[1024];
        ssize_t len;
@@ -1283,12 +1298,14 @@ static int cmd_dump(int argc, char *argv[]) {
                unsigned int options, status_int;
                node_status_t status;
                long int last_state_change;
+               long int udp_ping_rtt;
+               uint64_t in_packets, in_bytes, out_packets, out_bytes;
 
                switch(req) {
                case REQ_DUMP_NODES: {
-                       int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
+                       int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %ld %lu %lu %lu %lu", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes);
 
-                       if(n != 17) {
+                       if(n != 22) {
                                fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
                                return 1;
                        }
@@ -1316,8 +1333,11 @@ static int cmd_dump(int argc, char *argv[]) {
                                        continue;
                                }
 
-                               printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n",
-                                      node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
+                               printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %lu %lu tx %lu %lu",
+                                      node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes);
+                               if (udp_ping_rtt != -1)
+                                       printf(" rtt %ld.%03ld", udp_ping_rtt/1000, udp_ping_rtt%1000);
+                               printf("\n");
                        }
                }
                break;
@@ -1680,6 +1700,7 @@ const var_t variables[] = {
        {"Ed25519PrivateKeyFile", VAR_SERVER},
        {"ExperimentalProtocol", VAR_SERVER},
        {"Forwarding", VAR_SERVER},
+       {"FWMark", VAR_SERVER},
        {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE},
        {"Hostnames", VAR_SERVER},
        {"IffOneQueue", VAR_SERVER},
@@ -1859,7 +1880,7 @@ static int cmd_config(int argc, char *argv[]) {
                        }
                }
 
-               /* Change "add" into "set" for variables that do not allow multiple occurences.
+               /* Change "add" into "set" for variables that do not allow multiple occurrences.
                   Turn on warnings when it seems variables might be removed unintentionally. */
 
                if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) {