Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Revision:
170:96c637dc3f52
Parent:
167:3ba4e3c49631
Child:
171:f708d6776752
--- a/resolve/nr4.c	Tue Dec 01 12:56:34 2020 +0000
+++ b/resolve/nr4.c	Wed Dec 09 18:11:05 2020 +0000
@@ -16,9 +16,11 @@
 bool Nr4Trace = false;
 
 #define NAME_MAX_LENGTH      20
-#define  CACHE_TIMEOUT_MS  3600 * 1000
-#define FREEZE_TIMEOUT_MS  1800 * 1000
-#define  REPLY_TIMEOUT_MS     1 * 1000
+
+#define CACHE_TIMEOUT_MS  3600 * 1000
+#define STALE_TIMEOUT_MS  1800 * 1000
+#define EMPTY_TIMEOUT_MS     5 * 1000
+#define REPLY_TIMEOUT_MS     1 * 1000
 
 #define RECORDS_COUNT 20
 
@@ -70,6 +72,16 @@
     }
     return -1;
 }
+static int getIpOnly(uint32_t ip)
+{
+    for (int i = 0; i < RECORDS_COUNT; i++)
+    {
+        if (records[i].state == STATE_EMPTY) continue;
+        if (records[i].name[0] != 0) continue;
+        if (records[i].ip == ip) return i;
+    }
+    return -1;
+}
 static int getOldest()
 {
     int        iOldest = 0;
@@ -96,7 +108,14 @@
     i = getExistingIp(ip);
     if (i > -1)
     {
-        if (!MsTimerRelative(records[i].elapsed, FREEZE_TIMEOUT_MS)) return;
+        if (records[i].name[0] == 0)
+        {
+            if (!MsTimerRelative(records[i].elapsed, EMPTY_TIMEOUT_MS)) return;
+        }
+        else
+        {
+            if (!MsTimerRelative(records[i].elapsed, STALE_TIMEOUT_MS)) return;
+        }
         if (Nr4Trace)
         {
             LogTimeF("NR - renew name of ");
@@ -105,7 +124,7 @@
         }
         records[i].todo     = TODO_NAME_FROM_IP;
         records[i].state    = STATE_WANT;
-        records[i].protocol = DnsGetNextProtocol4(DNS_PROTOCOL_NONE);
+        records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
         records[i].elapsed  = MsTimerCount;
         return;
     }
@@ -121,7 +140,7 @@
     records[i].ip       = ip;
     records[i].todo     = TODO_NAME_FROM_IP;
     records[i].state    = STATE_WANT;
-    records[i].protocol = DnsGetNextProtocol4(DNS_PROTOCOL_NONE);
+    records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
     records[i].elapsed  = MsTimerCount;
     records[i].name[0]  = 0;
 }
@@ -135,14 +154,21 @@
     i = getExistingName(name);
     if (i > -1)
     {
-        if (!MsTimerRelative(records[i].elapsed, FREEZE_TIMEOUT_MS)) return;
+        if (records[i].ip == 0)
+        {
+            if (!MsTimerRelative(records[i].elapsed, EMPTY_TIMEOUT_MS)) return;
+        }
+        else
+        {
+            if (!MsTimerRelative(records[i].elapsed, STALE_TIMEOUT_MS)) return;
+        }
         if (Nr4Trace)
         {
             LogTimeF("NR - renew IPv4 of %s\r\n", name);
         }
         records[i].todo     = TODO_IP_FROM_NAME;
         records[i].state    = STATE_WANT;
-        records[i].protocol = DnsGetNextProtocol4(DNS_PROTOCOL_NONE);
+        records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
         records[i].elapsed  = MsTimerCount;
         return;
     }
@@ -156,7 +182,7 @@
     records[i].ip       = 0;
     records[i].todo     = TODO_IP_FROM_NAME;
     records[i].state    = STATE_WANT;
-    records[i].protocol = DnsGetNextProtocol4(DNS_PROTOCOL_NONE);
+    records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
     records[i].elapsed  = MsTimerCount;
     strncpy(records[i].name, name, NAME_MAX_LENGTH);
     records[i].name[NAME_MAX_LENGTH - 1] = 0;
@@ -175,43 +201,94 @@
 {    
     int i;
     
-    //Get existing ip and, if found, add it then clear any name only entries
+    //Print what is being handled
+    if (Nr4Trace)
+    {
+        LogTimeF("NR - received response ");
+        Ip4AddressLog(ip);
+        Log(" == '");
+        Log(name);
+        Log("'\r\n");
+    }
+
+    //Ignore records which do not have both ip and name    
+    if (ip == 0 || name == 0 || name[0] == 0)
+    {
+        if (Nr4Trace) LogTimeF("NR - ignoring unresolved response\r\n");
+        return;
+    }
+    
+    //Get existing ip and, if found, add the name then clear any name only entries
     i = getExistingIp(ip);
     if (i >= 0)
     {
         if (Nr4Trace)
         {
-            if (DnsLabelIsSame(name, records[i].name)) LogTimeF("NR - confirm existing ");
-            else                                       LogTimeF("NR - replace name for existing ip ");
-            Ip4AddressLog(ip);
-            Log(" == '");
-            Log(name);
-            Log("'\r\n");
+            if (DnsLabelIsSame(name, records[i].name))
+            {
+                LogTimeF("NR record %d - confirm existing name for ip ", i);
+                Ip4AddressLog(ip);
+                Log(" is '");
+                Log(name);
+                Log("'\r\n");
+            }
+            else
+            {
+                LogTimeF("NR record %d - update name for ip ", i);
+                Ip4AddressLog(ip);
+                Log(" from '");
+                Log(records[i].name);
+                Log("' to '");
+                Log(name);
+                Log("'\r\n");
+            }
         }
         addIpRecord(i, ip, name, protocol);
         
         i = getNameOnly(name);
         if (i >= 0)
         {
-            if (Nr4Trace) LogTimeF("NR - clear name '%s' with no ip\r\n", name);
+            if (Nr4Trace) LogTimeF("NR record %d - clear name '%s' with no ip\r\n", i, name);
             records[i].state = STATE_EMPTY;
         }
         return;
     }
     
-    //Get name only entry and, if found, add it
-    i = getNameOnly(name);
+    //Get existing name and, if found, add the ip then clear any ip only entries
+    i = getExistingName(name);
     if (i >= 0)
     {
         if (Nr4Trace)
         {
-            LogTimeF("NR - add ip for name ");
-            Ip4AddressLog(ip);
-            Log(" == '");
-            Log(name);
-            Log("'\r\n");
+            if (ip == records[i].ip)
+            {
+                LogTimeF("NR record %d - confirm existing ip for name '", i);
+                Log(name);
+                Log("' is ");
+                Ip4AddressLog(ip);
+                Log("\r\n");
+            }
+            else
+            {
+                LogTimeF("NR record %d - update ip for name '", i);
+                Log(name);
+                Log("' from ");
+                Ip4AddressLog(records[i].ip);
+                Log(" to ");
+                Ip4AddressLog(ip);
+                Log("\r\n");
+            }
         }
         addIpRecord(i, ip, name, protocol);
+        
+        i = getIpOnly(ip);
+        if (i >= 0)
+        {
+            if (Nr4Trace) LogTimeF("NR record %d - clear ip ", i);
+            Ip4AddressLog(ip);
+            Log(" with no name\r\n");
+            records[i].state = STATE_EMPTY;
+        }
         return;
     }
     
@@ -219,7 +296,7 @@
     i = getOldest();
     if (Nr4Trace)
     {
-        LogTimeF("NR - add ip for name ");
+        LogTimeF("NR record %d - add entry for ", i);
         Ip4AddressLog(ip);
         Log(" == '");
         Log(name);
@@ -337,7 +414,7 @@
 {
     if (pr->state == STATE_SENT && MsTimerRelative(pr->elapsed, REPLY_TIMEOUT_MS) && pr->protocol)
     {
-        pr->protocol = DnsGetNextProtocol4(pr->protocol);
+        pr->protocol = DnsGetNextProtocol(pr->protocol);
         if (pr->protocol)
         {
             pr->state = STATE_WANT;