]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
Change TTL dynamically to adjust for path changes
authoratibdialpad <matibuddin@dialpad.com>
Sun, 23 Aug 2020 15:11:27 +0000 (20:41 +0530)
committeratibdialpad <matibuddin@dialpad.com>
Mon, 31 Aug 2020 03:50:51 +0000 (09:20 +0530)
ui/net.c
ui/report.c

index d2a38b6b65d6316c892008af7de221a2783859b1..8f216cea77ca0c94feeee1465b4f6c3547169c23 100644 (file)
--- a/ui/net.c
+++ b/ui/net.c
@@ -47,8 +47,8 @@
 static int packetsize;          /* packet size used by ping */
 
 struct nethost {
-    ip_t addr;
-    ip_t addrs[MAXPATH];        /* for multi paths byMin */
+    ip_t addr;                  /* Latest host to respond */
+    ip_t addrs[MAXPATH];        /* For Multi paths/Path Changes: List of all hosts that have responded */
     int err;
     int xmit;
     int returned;
@@ -219,6 +219,7 @@ static void net_process_ping(
     int oldavg;                 /* usedByMin */
     int oldjavg;                /* usedByMin */
     int i;                      /* usedByMin */
+    int found = 0;
 #ifdef ENABLE_IPV6
     char addrcopy[sizeof(struct in6_addr)];
 #else
@@ -237,30 +238,31 @@ static void net_process_ping(
 
 
 
-    if (addrcmp(&nh->addr, &ctl->unspec_addr, ctl->af) == 0) {
-        /* should be out of if as addr can change */
-        memcpy(&nh->addr, addrcopy, sockaddr_addr_size(sourcesockaddr));
-        nh->mpls = *mpls;
-        display_rawhost(ctl, index, (void *)&(nh->addr), (void *)&(nh->mpls));
-
-        /* multi paths */
-        memcpy(&nh->addrs[0], addrcopy, sockaddr_addr_size(sourcesockaddr));
-        nh->mplss[0] = *mpls;
-    } else {
+    if (addrcmp(&nh->addr, &addrcopy, ctl->af) != 0) {
         for (i = 0; i < MAXPATH;) {
-            if (addrcmp(&nh->addrs[i], &addrcopy, ctl->af) == 0 ||
-                addrcmp(&nh->addrs[i], &ctl->unspec_addr, ctl->af) == 0) {
+            if (addrcmp(&nh->addrs[i], &nh->addr, ctl->af) == 0) {
+                found = 1; /* This host is already in the list */
                 break;
             }
+            if (addrcmp(&nh->addrs[i], &ctl->unspec_addr, ctl->af) == 0) {
+                break; /* Found first vacant position */
+            }
             i++;
         }
 
-        if (addrcmp(&nh->addrs[i], &addrcopy, ctl->af) != 0 && i < MAXPATH) {
-            memcpy(&nh->addrs[i], addrcopy, sockaddr_addr_size(sourcesockaddr));
+        if (found == 0 && i < MAXPATH) {
+            memcpy(&nh->addrs[i], &nh->addr, sockaddr_addr_size(sourcesockaddr));
 
-            nh->mplss[i] = *mpls;
+            nh->mplss[i] = nh->mpls;
             display_rawhost(ctl, index, (void *)&(nh->addrs[i]), (void *)&(nh->addrs[i]));
         }
+
+        /* Always save the latest host in nh->addr. This
+         * allows maxTTL to change whenever path changes.
+         */
+        memcpy(&nh->addr, addrcopy, sockaddr_addr_size(sourcesockaddr));
+        nh->mpls = *mpls;
+        display_rawhost(ctl, index, (void *)&(nh->addr), (void *)&(nh->mpls));
     }
 
     nh->jitter = totusec - nh->last;
@@ -535,6 +537,7 @@ int net_send_batch(
     struct mtr_ctl *ctl)
 {
     int n_unknown = 0, i;
+    int restart = 0;
 
     /* randomized packet size and/or bit pattern if packetsize<0 and/or 
        bitpattern<0.  abs(packetsize) and/or abs(bitpattern) will be used 
@@ -572,8 +575,11 @@ int net_send_batch(
            hosts. Removed in 0.65. 
            If the line proves necessary, it should at least NOT trigger that line
            when host[i].addr == 0 */
-        if (host_addr_cmp(i, remoteaddress, ctl->af) == 0)
-            n_unknown = MaxHost;        /* Make sure we drop into "we should restart" */
+        if (host_addr_cmp(i, remoteaddress, ctl->af) == 0) {
+            restart = 1;
+            numhosts = i + 1; /* Saves batch_at - index number of probes in the next round!*/
+            break;
+        }
     }
 
     if (                        /* success in reaching target */
@@ -582,7 +588,11 @@ int net_send_batch(
            (n_unknown > ctl->maxUnknown) ||
            /* or reach limit  */
            (batch_at >= ctl->maxTTL - 1)) {
+        restart = 1;
         numhosts = batch_at + 1;
+    }
+
+    if(restart) {
         batch_at = ctl->fstTTL - 1;
         return 1;
     }
index e51d95c2114dd69887a8a4f52971be7cca33e424..26b2543477842637e34fabd5899eb3cc8b559b87 100644 (file)
@@ -184,8 +184,8 @@ void report_close(
 
         /* This feature shows 'loadbalances' on routes */
 
-        /* z is starting at 1 because addrs[0] is the same that addr */
-        for (z = 1; z < MAXPATH; z++) {
+        /* Print list of all hosts that have responded from ttl = at + 1 away */
+        for (z = 0; z < MAXPATH; z++) {
             int found = 0;
             addr2 = net_addrs(at, z);
             mplss = net_mplss(at, z);
@@ -193,6 +193,10 @@ void report_close(
                  ((void *) &ctl->unspec_addr, (void *) addr2,
                   ctl->af)) == 0) {
                 break;
+            } else if ((addrcmp
+                        ((void *) addr, (void *) addr2,
+                          ctl->af)) == 0) {
+                continue; /* Latest Host is already printed */
             } else {
                 snprint_addr(ctl, name, sizeof(name), addr2);
                 snprintf(fmt, sizeof(fmt), "        %%-%zus", len_hosts);