A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Fri Jan 22 13:24:08 2021 +0000
Revision:
192:0dfa138a8e7d
Parent:
189:e1c7990486c4
Child:
193:47a953ab571b
Update the NR add entry mechanism to remove redundant entries.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 172:9bc3c7b2cca1 1 #include <stdint.h>
andrewboyson 172:9bc3c7b2cca1 2 #include <stdbool.h>
andrewboyson 172:9bc3c7b2cca1 3 #include <string.h>
andrewboyson 172:9bc3c7b2cca1 4
andrewboyson 172:9bc3c7b2cca1 5 #include "log.h"
andrewboyson 172:9bc3c7b2cca1 6 #include "mstimer.h"
andrewboyson 172:9bc3c7b2cca1 7 #include "net.h"
andrewboyson 172:9bc3c7b2cca1 8 #include "eth.h"
andrewboyson 172:9bc3c7b2cca1 9 #include "mac.h"
andrewboyson 172:9bc3c7b2cca1 10 #include "dhcp.h"
andrewboyson 172:9bc3c7b2cca1 11 #include "dns.h"
andrewboyson 172:9bc3c7b2cca1 12 #include "dnsquery.h"
andrewboyson 172:9bc3c7b2cca1 13 #include "dnslabel.h"
andrewboyson 172:9bc3c7b2cca1 14 #include "http.h"
andrewboyson 182:ff48c6ea91c1 15 #include "ip6addr.h"
andrewboyson 182:ff48c6ea91c1 16 #include "ip4addr.h"
andrewboyson 182:ff48c6ea91c1 17 #include "nr.h"
andrewboyson 189:e1c7990486c4 18 #include "nrtest.h"
andrewboyson 189:e1c7990486c4 19 #include "ndp.h"
andrewboyson 172:9bc3c7b2cca1 20
andrewboyson 172:9bc3c7b2cca1 21 bool Nr4Trace = false; //Do not use
andrewboyson 172:9bc3c7b2cca1 22 bool NrTrace = false;
andrewboyson 172:9bc3c7b2cca1 23
andrewboyson 172:9bc3c7b2cca1 24 #define CACHE_TIMEOUT_MS 3600 * 1000
andrewboyson 172:9bc3c7b2cca1 25 #define STALE_TIMEOUT_MS 1800 * 1000
andrewboyson 172:9bc3c7b2cca1 26 #define EMPTY_TIMEOUT_MS 300 * 1000
andrewboyson 172:9bc3c7b2cca1 27 #define REPLY_TIMEOUT_MS 100
andrewboyson 172:9bc3c7b2cca1 28
andrewboyson 172:9bc3c7b2cca1 29 #define RECORDS_COUNT 50
andrewboyson 172:9bc3c7b2cca1 30
andrewboyson 172:9bc3c7b2cca1 31 #define STATE_EMPTY 0
andrewboyson 172:9bc3c7b2cca1 32 #define STATE_WANT 1
andrewboyson 172:9bc3c7b2cca1 33 #define STATE_WAIT_FOR_ETH 2
andrewboyson 172:9bc3c7b2cca1 34 #define STATE_WAIT_TIMEOUT 3
andrewboyson 172:9bc3c7b2cca1 35 #define STATE_VALID 4
andrewboyson 172:9bc3c7b2cca1 36
andrewboyson 182:ff48c6ea91c1 37 #define TODO_NONE 0
andrewboyson 182:ff48c6ea91c1 38 #define TODO_NAME_FROM_ADDRESS 1
andrewboyson 182:ff48c6ea91c1 39 #define TODO_ADDRESS_FROM_NAME 2
andrewboyson 182:ff48c6ea91c1 40
andrewboyson 182:ff48c6ea91c1 41 #define ADDR_TYPE_A 4
andrewboyson 182:ff48c6ea91c1 42 #define ADDR_TYPE_AAAA 6
andrewboyson 182:ff48c6ea91c1 43
andrewboyson 172:9bc3c7b2cca1 44 struct record
andrewboyson 172:9bc3c7b2cca1 45 {
andrewboyson 182:ff48c6ea91c1 46 uint32_t replyMs; //Need this in addition to the ageMs for when refreshing an existing entry
andrewboyson 172:9bc3c7b2cca1 47 uint32_t ageMs;
andrewboyson 182:ff48c6ea91c1 48 union
andrewboyson 182:ff48c6ea91c1 49 {
andrewboyson 182:ff48c6ea91c1 50 uint32_t A;
andrewboyson 182:ff48c6ea91c1 51 uint8_t AAAA[16];
andrewboyson 182:ff48c6ea91c1 52 char address[16];
andrewboyson 182:ff48c6ea91c1 53 };
andrewboyson 182:ff48c6ea91c1 54 uint8_t addrType; //ADDR_TYPE_A (4) or ADDR_TYPE_AAAA (6)
andrewboyson 172:9bc3c7b2cca1 55 uint8_t todo;
andrewboyson 172:9bc3c7b2cca1 56 uint8_t state;
andrewboyson 172:9bc3c7b2cca1 57 uint8_t dnsProtocol;
andrewboyson 172:9bc3c7b2cca1 58 uint16_t ipProtocol;
andrewboyson 182:ff48c6ea91c1 59 char name[NR_NAME_MAX_LENGTH];
andrewboyson 172:9bc3c7b2cca1 60 };
andrewboyson 172:9bc3c7b2cca1 61 static struct record records[RECORDS_COUNT];
andrewboyson 172:9bc3c7b2cca1 62
andrewboyson 182:ff48c6ea91c1 63 static void addrClear(const uint8_t addrType, char* ip)
andrewboyson 182:ff48c6ea91c1 64 {
andrewboyson 182:ff48c6ea91c1 65 switch (addrType)
andrewboyson 182:ff48c6ea91c1 66 {
andrewboyson 182:ff48c6ea91c1 67 case ADDR_TYPE_A : *(uint32_t*)ip = 0; break;
andrewboyson 182:ff48c6ea91c1 68 case ADDR_TYPE_AAAA: Ip6AddrClear(ip); break;
andrewboyson 182:ff48c6ea91c1 69 default: LogTimeF("NR - addrClear - Unknown addrType %d\r\n", addrType); break;
andrewboyson 182:ff48c6ea91c1 70 }
andrewboyson 182:ff48c6ea91c1 71 }
andrewboyson 182:ff48c6ea91c1 72 static bool addrIsEmpty(const uint8_t addrType, const char* ip)
andrewboyson 182:ff48c6ea91c1 73 {
andrewboyson 182:ff48c6ea91c1 74 switch (addrType)
andrewboyson 182:ff48c6ea91c1 75 {
andrewboyson 182:ff48c6ea91c1 76 case ADDR_TYPE_A : return *(uint32_t*)ip == 0;
andrewboyson 182:ff48c6ea91c1 77 case ADDR_TYPE_AAAA: return Ip6AddrIsEmpty(ip);
andrewboyson 182:ff48c6ea91c1 78 default: return LogTimeF("NR - addrIsEmpty - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 79 }
andrewboyson 182:ff48c6ea91c1 80 }
andrewboyson 182:ff48c6ea91c1 81 static int addrLog(uint8_t addrType, const char* ip)
andrewboyson 182:ff48c6ea91c1 82 {
andrewboyson 182:ff48c6ea91c1 83 switch (addrType)
andrewboyson 182:ff48c6ea91c1 84 {
andrewboyson 187:122fc1996c86 85 case ADDR_TYPE_A : return Ip4AddrLog(*(uint32_t*)ip);
andrewboyson 182:ff48c6ea91c1 86 case ADDR_TYPE_AAAA: return Ip6AddrLog(ip);
andrewboyson 182:ff48c6ea91c1 87 default: return LogTimeF("NR - addrLog - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 88 }
andrewboyson 182:ff48c6ea91c1 89 }
andrewboyson 182:ff48c6ea91c1 90
andrewboyson 182:ff48c6ea91c1 91 static bool addrIsSame(uint8_t addrType, const char* ipA, const char* ipB)
andrewboyson 182:ff48c6ea91c1 92 {
andrewboyson 182:ff48c6ea91c1 93 switch (addrType)
andrewboyson 182:ff48c6ea91c1 94 {
andrewboyson 182:ff48c6ea91c1 95 case ADDR_TYPE_A : return *(uint32_t*)ipA == *(uint32_t*)ipB;
andrewboyson 182:ff48c6ea91c1 96 case ADDR_TYPE_AAAA: return Ip6AddrIsSame(ipA, ipB);
andrewboyson 182:ff48c6ea91c1 97 default: return LogTimeF("NR - addrIsSame - Unknown addrType %d\r\n", addrType);
andrewboyson 182:ff48c6ea91c1 98 }
andrewboyson 182:ff48c6ea91c1 99 }
andrewboyson 182:ff48c6ea91c1 100
andrewboyson 182:ff48c6ea91c1 101 static void addrCopy(uint8_t addrType, char* ipTo, const char* ipFrom)
andrewboyson 182:ff48c6ea91c1 102 {
andrewboyson 182:ff48c6ea91c1 103 switch (addrType)
andrewboyson 182:ff48c6ea91c1 104 {
andrewboyson 182:ff48c6ea91c1 105 case ADDR_TYPE_A : *(uint32_t*)ipTo = *(uint32_t*)ipFrom; break;
andrewboyson 182:ff48c6ea91c1 106 case ADDR_TYPE_AAAA: Ip6AddrCopy(ipTo, ipFrom); break;
andrewboyson 182:ff48c6ea91c1 107 default: LogTimeF("NR - addrCopy - Unknown addrType %d\r\n", addrType); break;
andrewboyson 182:ff48c6ea91c1 108 }
andrewboyson 182:ff48c6ea91c1 109 }
andrewboyson 182:ff48c6ea91c1 110
andrewboyson 182:ff48c6ea91c1 111 static int getExistingAddress(char* address, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 112 {
andrewboyson 172:9bc3c7b2cca1 113 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 114 {
andrewboyson 172:9bc3c7b2cca1 115 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 116 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 117 if (addrIsSame(addrType, records[i].address, address)) return i;
andrewboyson 172:9bc3c7b2cca1 118 }
andrewboyson 172:9bc3c7b2cca1 119 return -1;
andrewboyson 172:9bc3c7b2cca1 120 }
andrewboyson 182:ff48c6ea91c1 121 static int getExistingName(char* name, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 122 {
andrewboyson 172:9bc3c7b2cca1 123 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 124 {
andrewboyson 172:9bc3c7b2cca1 125 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 126 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 127 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 182:ff48c6ea91c1 128 }
andrewboyson 182:ff48c6ea91c1 129 return -1;
andrewboyson 182:ff48c6ea91c1 130 }
andrewboyson 172:9bc3c7b2cca1 131 static int getOldest()
andrewboyson 172:9bc3c7b2cca1 132 {
andrewboyson 172:9bc3c7b2cca1 133 int iOldest = 0;
andrewboyson 172:9bc3c7b2cca1 134 uint32_t ageOldest = 0;
andrewboyson 172:9bc3c7b2cca1 135 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 136 {
andrewboyson 172:9bc3c7b2cca1 137 if (records[i].state == STATE_EMPTY) return i; //Found an empty slot so just return it
andrewboyson 172:9bc3c7b2cca1 138 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 139 if (age >= ageOldest)
andrewboyson 172:9bc3c7b2cca1 140 {
andrewboyson 172:9bc3c7b2cca1 141 ageOldest = age;
andrewboyson 172:9bc3c7b2cca1 142 iOldest = i;
andrewboyson 172:9bc3c7b2cca1 143 }
andrewboyson 172:9bc3c7b2cca1 144 }
andrewboyson 172:9bc3c7b2cca1 145 return iOldest; //Otherwise return the oldest
andrewboyson 172:9bc3c7b2cca1 146 }
andrewboyson 182:ff48c6ea91c1 147 static void makeRequestForNameFromAddress(uint8_t addrType, void* address )
andrewboyson 172:9bc3c7b2cca1 148 {
andrewboyson 172:9bc3c7b2cca1 149 //Don't treat non ips
andrewboyson 182:ff48c6ea91c1 150 if (addrIsEmpty(addrType, address)) return;
andrewboyson 172:9bc3c7b2cca1 151 int i;
andrewboyson 172:9bc3c7b2cca1 152
andrewboyson 172:9bc3c7b2cca1 153 //If a valid record already exists then request an update
andrewboyson 182:ff48c6ea91c1 154 i = getExistingAddress(address, addrType);
andrewboyson 172:9bc3c7b2cca1 155 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 156 {
andrewboyson 172:9bc3c7b2cca1 157 if (records[i].state != STATE_VALID) return;
andrewboyson 172:9bc3c7b2cca1 158 if (records[i].name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 159 {
andrewboyson 172:9bc3c7b2cca1 160 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 161 }
andrewboyson 172:9bc3c7b2cca1 162 else
andrewboyson 172:9bc3c7b2cca1 163 {
andrewboyson 172:9bc3c7b2cca1 164 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 165 }
andrewboyson 172:9bc3c7b2cca1 166 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 167 {
andrewboyson 192:0dfa138a8e7d 168 LogTimeF("NR - record %2d - renew name of ", i);
andrewboyson 182:ff48c6ea91c1 169 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 170 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 171 }
andrewboyson 172:9bc3c7b2cca1 172 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 173 //Leave the name as is
andrewboyson 172:9bc3c7b2cca1 174 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 175 }
andrewboyson 172:9bc3c7b2cca1 176 else
andrewboyson 172:9bc3c7b2cca1 177 {
andrewboyson 172:9bc3c7b2cca1 178 //If a record does not exist then find the first empty slot and add the IP and date
andrewboyson 188:57f44b620d0e 179 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 180 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 181 {
andrewboyson 192:0dfa138a8e7d 182 LogTimeF("NR - record %2d - request name of ", i);
andrewboyson 182:ff48c6ea91c1 183 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 184 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 185 }
andrewboyson 182:ff48c6ea91c1 186 addrCopy(addrType, records[i].address, address); //Set the address
andrewboyson 182:ff48c6ea91c1 187 records[i].name[0] = 0; //Clear the name
andrewboyson 182:ff48c6ea91c1 188 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 189 }
andrewboyson 172:9bc3c7b2cca1 190 records[i].todo = TODO_NAME_FROM_ADDRESS;
andrewboyson 182:ff48c6ea91c1 191 records[i].addrType = addrType;
andrewboyson 172:9bc3c7b2cca1 192 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 193 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 194 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 195 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 196 }
andrewboyson 182:ff48c6ea91c1 197 static void makeRequestForAddressFromName(char* name, uint8_t addrType)
andrewboyson 172:9bc3c7b2cca1 198 {
andrewboyson 172:9bc3c7b2cca1 199 //Don't treat non names
andrewboyson 172:9bc3c7b2cca1 200 if (!name[0]) return;
andrewboyson 172:9bc3c7b2cca1 201 int i;
andrewboyson 172:9bc3c7b2cca1 202
andrewboyson 172:9bc3c7b2cca1 203 //If a valid record already exists then request an update
andrewboyson 182:ff48c6ea91c1 204 i = getExistingName(name, addrType);
andrewboyson 172:9bc3c7b2cca1 205 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 206 {
andrewboyson 172:9bc3c7b2cca1 207 if (records[i].state != STATE_VALID) return;
andrewboyson 182:ff48c6ea91c1 208 if (addrIsEmpty(records[i].addrType, records[i].address))
andrewboyson 172:9bc3c7b2cca1 209 {
andrewboyson 172:9bc3c7b2cca1 210 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 211 }
andrewboyson 172:9bc3c7b2cca1 212 else
andrewboyson 172:9bc3c7b2cca1 213 {
andrewboyson 172:9bc3c7b2cca1 214 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 215 }
andrewboyson 172:9bc3c7b2cca1 216 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 217 {
andrewboyson 192:0dfa138a8e7d 218 if (addrType == ADDR_TYPE_A) LogTimeF("NR - record %2d - renew A of %s\r\n", i, name);
andrewboyson 192:0dfa138a8e7d 219 else LogTimeF("NR - record %2d - renew AAAA of %s\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 220 }
andrewboyson 172:9bc3c7b2cca1 221 //Leave name as is
andrewboyson 172:9bc3c7b2cca1 222 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 223 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 224 }
andrewboyson 172:9bc3c7b2cca1 225 else
andrewboyson 172:9bc3c7b2cca1 226 {
andrewboyson 172:9bc3c7b2cca1 227 //If a record does not exist then find the first empty slot and add the name and date
andrewboyson 188:57f44b620d0e 228 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 229 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 230 {
andrewboyson 192:0dfa138a8e7d 231 if (addrType == ADDR_TYPE_A) LogTimeF("NR - record %2d - request A of %s\r\n", i, name);
andrewboyson 192:0dfa138a8e7d 232 else LogTimeF("NR - record %2d - request AAAA of %s\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 233 }
andrewboyson 183:ee809769bf89 234 strncpy(records[i].name, name, NR_NAME_MAX_LENGTH); //Set the name
andrewboyson 182:ff48c6ea91c1 235 records[i].name[NR_NAME_MAX_LENGTH - 1] = 0;
andrewboyson 183:ee809769bf89 236 addrClear(addrType, records[i].address); //Clear the address
andrewboyson 182:ff48c6ea91c1 237 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 238 }
andrewboyson 182:ff48c6ea91c1 239 records[i].todo = TODO_ADDRESS_FROM_NAME;
andrewboyson 182:ff48c6ea91c1 240 records[i].addrType = addrType;
andrewboyson 172:9bc3c7b2cca1 241 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 242 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 243 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 244 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 245 }
andrewboyson 192:0dfa138a8e7d 246 static void addEntry(uint8_t addrType, void* address, char* name, int dnsProtocol, int ipProtocol)
andrewboyson 172:9bc3c7b2cca1 247 {
andrewboyson 192:0dfa138a8e7d 248
andrewboyson 192:0dfa138a8e7d 249 //Ignore records which do not have both address and name
andrewboyson 192:0dfa138a8e7d 250 if (addrIsEmpty(addrType, address) || name == 0 || name[0] == 0)
andrewboyson 192:0dfa138a8e7d 251 {
andrewboyson 192:0dfa138a8e7d 252 if (NrTrace) LogTimeF("NR - ignoring invalid entry\r\n");
andrewboyson 192:0dfa138a8e7d 253 return;
andrewboyson 192:0dfa138a8e7d 254 }
andrewboyson 192:0dfa138a8e7d 255 //Ignore records with the name 'UNKNOWN'
andrewboyson 192:0dfa138a8e7d 256 if (strcmp(name, "UNKNOWN") == 0) return;
andrewboyson 172:9bc3c7b2cca1 257
andrewboyson 192:0dfa138a8e7d 258 //Delete any existing records linked to the new entry
andrewboyson 192:0dfa138a8e7d 259 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 192:0dfa138a8e7d 260 {
andrewboyson 192:0dfa138a8e7d 261 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 192:0dfa138a8e7d 262 if (records[i].addrType != addrType) continue;
andrewboyson 192:0dfa138a8e7d 263 bool sameAddress = addrIsSame(addrType, records[i].address, address);
andrewboyson 192:0dfa138a8e7d 264 bool sameName = DnsLabelIsSame(records[i].name, name);
andrewboyson 192:0dfa138a8e7d 265 bool noAddress = addrIsEmpty(addrType, records[i].address);
andrewboyson 192:0dfa138a8e7d 266 bool requesting = records[i].state != STATE_VALID;
andrewboyson 192:0dfa138a8e7d 267 if (sameAddress || (sameName && (noAddress || requesting))) records[i].state = STATE_EMPTY;
andrewboyson 192:0dfa138a8e7d 268 }
andrewboyson 192:0dfa138a8e7d 269
andrewboyson 192:0dfa138a8e7d 270 //Add the new entry
andrewboyson 192:0dfa138a8e7d 271 int i = getOldest();
andrewboyson 172:9bc3c7b2cca1 272 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 273 {
andrewboyson 192:0dfa138a8e7d 274 LogTimeF("NR - record %2d - received ", i);
andrewboyson 188:57f44b620d0e 275 EthProtocolLog(ipProtocol);
andrewboyson 188:57f44b620d0e 276 Log(" ");
andrewboyson 188:57f44b620d0e 277 DnsProtocolLog(dnsProtocol);
andrewboyson 188:57f44b620d0e 278 Log(" ");
andrewboyson 182:ff48c6ea91c1 279 addrLog(addrType, address);
andrewboyson 172:9bc3c7b2cca1 280 Log(" == '");
andrewboyson 172:9bc3c7b2cca1 281 Log(name);
andrewboyson 172:9bc3c7b2cca1 282 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 283 }
andrewboyson 192:0dfa138a8e7d 284 records[i].todo = TODO_NONE;
andrewboyson 192:0dfa138a8e7d 285 records[i].ageMs = MsTimerCount;
andrewboyson 192:0dfa138a8e7d 286 records[i].addrType = addrType;
andrewboyson 192:0dfa138a8e7d 287 addrCopy(addrType, records[i].address, address);
andrewboyson 192:0dfa138a8e7d 288 records[i].dnsProtocol = dnsProtocol;
andrewboyson 192:0dfa138a8e7d 289 records[i].ipProtocol = ipProtocol;
andrewboyson 192:0dfa138a8e7d 290 records[i].state = STATE_VALID;
andrewboyson 192:0dfa138a8e7d 291 strncpy(records[i].name, name, NR_NAME_MAX_LENGTH);
andrewboyson 192:0dfa138a8e7d 292 records[i].name[NR_NAME_MAX_LENGTH - 1] = 0;
andrewboyson 172:9bc3c7b2cca1 293 }
andrewboyson 182:ff48c6ea91c1 294 static void addressToName(uint8_t addrType, void* address, char* name)
andrewboyson 172:9bc3c7b2cca1 295 {
andrewboyson 172:9bc3c7b2cca1 296 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 297 {
andrewboyson 172:9bc3c7b2cca1 298 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 299 if (addrIsSame(addrType, records[i].address, address))
andrewboyson 172:9bc3c7b2cca1 300 {
andrewboyson 172:9bc3c7b2cca1 301 strcpy(name, records[i].name);
andrewboyson 172:9bc3c7b2cca1 302 return;
andrewboyson 172:9bc3c7b2cca1 303 }
andrewboyson 172:9bc3c7b2cca1 304 }
andrewboyson 172:9bc3c7b2cca1 305 name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 306 }
andrewboyson 182:ff48c6ea91c1 307 static void nameToAddress(char* name, uint8_t addrType, void* address)
andrewboyson 172:9bc3c7b2cca1 308 {
andrewboyson 172:9bc3c7b2cca1 309 uint32_t newest = 0xFFFFFFFF;
andrewboyson 182:ff48c6ea91c1 310 addrClear(addrType, address);
andrewboyson 172:9bc3c7b2cca1 311 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 312 {
andrewboyson 172:9bc3c7b2cca1 313 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 314 if (records[i].addrType != addrType) continue;
andrewboyson 182:ff48c6ea91c1 315 if(addrIsEmpty(records[i].addrType, records[i].address)) continue;
andrewboyson 172:9bc3c7b2cca1 316 if (!DnsLabelIsSame(records[i].name, name)) continue;
andrewboyson 172:9bc3c7b2cca1 317 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 318 if (age <= newest)
andrewboyson 172:9bc3c7b2cca1 319 {
andrewboyson 172:9bc3c7b2cca1 320 newest = age;
andrewboyson 182:ff48c6ea91c1 321 addrCopy(addrType, address, records[i].address);
andrewboyson 172:9bc3c7b2cca1 322 }
andrewboyson 172:9bc3c7b2cca1 323 }
andrewboyson 172:9bc3c7b2cca1 324 }
andrewboyson 182:ff48c6ea91c1 325 void NrMakeRequestForNameFromAddress6(char* pAddress) { makeRequestForNameFromAddress(ADDR_TYPE_AAAA, pAddress); }
andrewboyson 182:ff48c6ea91c1 326 void NrMakeRequestForNameFromAddress4(uint32_t address) { makeRequestForNameFromAddress(ADDR_TYPE_A, &address); }
andrewboyson 182:ff48c6ea91c1 327 void NrMakeRequestForAddress6FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_AAAA); }
andrewboyson 182:ff48c6ea91c1 328 void NrMakeRequestForAddress4FromName(char* name) { makeRequestForAddressFromName(name, ADDR_TYPE_A ); }
andrewboyson 182:ff48c6ea91c1 329 void NrAddAddress6(char* pAddress, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_AAAA, pAddress, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 330 void NrAddAddress4(uint32_t address, char* name, int dnsProtocol) { addEntry(ADDR_TYPE_A, &address, name, dnsProtocol, EthProtocol); }
andrewboyson 182:ff48c6ea91c1 331 void NrNameToAddress6(char* name, char* address) { nameToAddress(name, ADDR_TYPE_AAAA, address); }
andrewboyson 182:ff48c6ea91c1 332 void NrNameToAddress4(char* name, uint32_t* pAddress) { nameToAddress(name, ADDR_TYPE_A, pAddress); }
andrewboyson 182:ff48c6ea91c1 333 void NrAddress6ToName(char* pAddress, char* name) { addressToName(ADDR_TYPE_AAAA, pAddress, name); }
andrewboyson 182:ff48c6ea91c1 334 void NrAddress4ToName(uint32_t address, char* name) { addressToName(ADDR_TYPE_A, &address, name); }
andrewboyson 182:ff48c6ea91c1 335
andrewboyson 172:9bc3c7b2cca1 336 static char letterFromStateAndProtocol(uint8_t dnsState, uint8_t dnsProtocol, uint16_t ipProtocol)
andrewboyson 172:9bc3c7b2cca1 337 {
andrewboyson 172:9bc3c7b2cca1 338 switch (dnsState)
andrewboyson 172:9bc3c7b2cca1 339 {
andrewboyson 172:9bc3c7b2cca1 340 case STATE_WANT: return '}';
andrewboyson 172:9bc3c7b2cca1 341 case STATE_WAIT_FOR_ETH: return ']';
andrewboyson 172:9bc3c7b2cca1 342 case STATE_WAIT_TIMEOUT: return '>';
andrewboyson 172:9bc3c7b2cca1 343
andrewboyson 172:9bc3c7b2cca1 344 case STATE_VALID:
andrewboyson 172:9bc3c7b2cca1 345 switch (dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 346 {
andrewboyson 172:9bc3c7b2cca1 347 case DNS_PROTOCOL_UDNS: if (ipProtocol == ETH_IPV4) return 'd' ; else return 'D';
andrewboyson 172:9bc3c7b2cca1 348 case DNS_PROTOCOL_MDNS: if (ipProtocol == ETH_IPV4) return 'm' ; else return 'M';
andrewboyson 172:9bc3c7b2cca1 349 case DNS_PROTOCOL_LLMNR: if (ipProtocol == ETH_IPV4) return 'l' ; else return 'L';
andrewboyson 172:9bc3c7b2cca1 350 case DNS_PROTOCOL_NONE: return '-';
andrewboyson 172:9bc3c7b2cca1 351 default: return '?';
andrewboyson 172:9bc3c7b2cca1 352 }
andrewboyson 172:9bc3c7b2cca1 353 default: return '~';
andrewboyson 172:9bc3c7b2cca1 354 }
andrewboyson 172:9bc3c7b2cca1 355 }
andrewboyson 172:9bc3c7b2cca1 356 void NrSendAjax()
andrewboyson 172:9bc3c7b2cca1 357 {
andrewboyson 172:9bc3c7b2cca1 358 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 359 {
andrewboyson 172:9bc3c7b2cca1 360 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 182:ff48c6ea91c1 361 if (!addrIsEmpty(records[i].addrType, records[i].address) || records[i].name[0])
andrewboyson 172:9bc3c7b2cca1 362 {
andrewboyson 172:9bc3c7b2cca1 363 HttpAddByteAsHex(i);
andrewboyson 172:9bc3c7b2cca1 364 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 365 HttpAddInt32AsHex(MsTimerCount - records[i].ageMs);
andrewboyson 172:9bc3c7b2cca1 366 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 367 HttpAddNibbleAsHex(records[i].addrType);
andrewboyson 182:ff48c6ea91c1 368 HttpAddChar('\t');
andrewboyson 182:ff48c6ea91c1 369 switch (records[i].addrType)
andrewboyson 182:ff48c6ea91c1 370 {
andrewboyson 182:ff48c6ea91c1 371 case ADDR_TYPE_A:
andrewboyson 182:ff48c6ea91c1 372 {
andrewboyson 182:ff48c6ea91c1 373 HttpAddInt32AsHex(records[i].A);
andrewboyson 182:ff48c6ea91c1 374 break;
andrewboyson 182:ff48c6ea91c1 375 }
andrewboyson 182:ff48c6ea91c1 376 case ADDR_TYPE_AAAA:
andrewboyson 182:ff48c6ea91c1 377 for (int b = 0; b < 16; b++) HttpAddByteAsHex(records[i].AAAA[b]);
andrewboyson 182:ff48c6ea91c1 378 break;
andrewboyson 182:ff48c6ea91c1 379 }
andrewboyson 172:9bc3c7b2cca1 380 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 381 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].dnsProtocol, records[i].ipProtocol));
andrewboyson 172:9bc3c7b2cca1 382 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 383 HttpAddText(records[i].name);
andrewboyson 172:9bc3c7b2cca1 384 HttpAddChar('\n');
andrewboyson 172:9bc3c7b2cca1 385 }
andrewboyson 172:9bc3c7b2cca1 386 }
andrewboyson 172:9bc3c7b2cca1 387 }
andrewboyson 172:9bc3c7b2cca1 388 static void clearCache(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 389 {
andrewboyson 172:9bc3c7b2cca1 390 if (MsTimerRelative(pr->ageMs, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 391 }
andrewboyson 172:9bc3c7b2cca1 392 static void queryNameFromIp(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 393 {
andrewboyson 182:ff48c6ea91c1 394 if (addrIsEmpty(pr->addrType, pr->address))
andrewboyson 176:7eb916c22084 395 {
andrewboyson 192:0dfa138a8e7d 396 LogTimeF("NR - record %2d - queryNameFromIp has no address\r\n", pr - records);
andrewboyson 176:7eb916c22084 397 return;
andrewboyson 176:7eb916c22084 398 }
andrewboyson 172:9bc3c7b2cca1 399 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 400 {
andrewboyson 192:0dfa138a8e7d 401 LogTimeF("NR - record %2d - send ", pr - records);
andrewboyson 172:9bc3c7b2cca1 402 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 403 Log(" ");
andrewboyson 172:9bc3c7b2cca1 404 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 405 Log(" request for name of ");
andrewboyson 182:ff48c6ea91c1 406 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 407 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 408 }
andrewboyson 182:ff48c6ea91c1 409 if (pr->addrType == ADDR_TYPE_A)
andrewboyson 172:9bc3c7b2cca1 410 {
andrewboyson 182:ff48c6ea91c1 411 //uint32_t address4 = addrToIp4(pr->address);
andrewboyson 182:ff48c6ea91c1 412 DnsQueryNameFromIp4(pr->A, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 413 }
andrewboyson 172:9bc3c7b2cca1 414 else
andrewboyson 172:9bc3c7b2cca1 415 {
andrewboyson 172:9bc3c7b2cca1 416 DnsQueryNameFromIp6(pr->address, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 417 }
andrewboyson 172:9bc3c7b2cca1 418 }
andrewboyson 182:ff48c6ea91c1 419 static void queryIpFromName(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 420 {
andrewboyson 172:9bc3c7b2cca1 421 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 422 {
andrewboyson 192:0dfa138a8e7d 423 LogTimeF("NR - record %2d - send ", pr - records);
andrewboyson 172:9bc3c7b2cca1 424 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 425 Log(" ");
andrewboyson 172:9bc3c7b2cca1 426 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 182:ff48c6ea91c1 427 if (pr->addrType == ADDR_TYPE_A) Log(" request for A of name '");
andrewboyson 182:ff48c6ea91c1 428 else Log(" request for AAAA of name '");
andrewboyson 172:9bc3c7b2cca1 429 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 430 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 431 }
andrewboyson 182:ff48c6ea91c1 432 if (pr->addrType == ADDR_TYPE_A) DnsQueryIp4FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 182:ff48c6ea91c1 433 else DnsQueryIp6FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 434 }
andrewboyson 183:ee809769bf89 435 static bool getIsExternal(struct record* pr)
andrewboyson 183:ee809769bf89 436 {
andrewboyson 183:ee809769bf89 437 switch(pr->todo)
andrewboyson 183:ee809769bf89 438 {
andrewboyson 183:ee809769bf89 439 case TODO_NAME_FROM_ADDRESS:
andrewboyson 183:ee809769bf89 440
andrewboyson 183:ee809769bf89 441 if (pr->addrType == ADDR_TYPE_AAAA)
andrewboyson 183:ee809769bf89 442 {
andrewboyson 187:122fc1996c86 443 return Ip6AddrIsExternal((char*)pr->AAAA);
andrewboyson 183:ee809769bf89 444 }
andrewboyson 183:ee809769bf89 445 else
andrewboyson 183:ee809769bf89 446 {
andrewboyson 187:122fc1996c86 447 return Ip4AddrIsExternal(pr->A);
andrewboyson 183:ee809769bf89 448 }
andrewboyson 183:ee809769bf89 449 case TODO_ADDRESS_FROM_NAME:
andrewboyson 183:ee809769bf89 450 return DnsLabelIsExternal(pr->name);
andrewboyson 183:ee809769bf89 451 default:
andrewboyson 183:ee809769bf89 452 LogTimeF("NR - getIsExternal - undefined todo '%d'\r\n", pr->todo);
andrewboyson 183:ee809769bf89 453 return false;
andrewboyson 183:ee809769bf89 454 }
andrewboyson 183:ee809769bf89 455 }
andrewboyson 183:ee809769bf89 456 static bool protocolIsAvailable(struct record* pr)
andrewboyson 183:ee809769bf89 457 {
andrewboyson 183:ee809769bf89 458 bool isExternal = getIsExternal(pr);
andrewboyson 183:ee809769bf89 459 switch(pr->dnsProtocol)
andrewboyson 183:ee809769bf89 460 {
andrewboyson 183:ee809769bf89 461 case DNS_PROTOCOL_MDNS: return !isExternal;
andrewboyson 183:ee809769bf89 462 case DNS_PROTOCOL_LLMNR: return !isExternal;
andrewboyson 183:ee809769bf89 463 case DNS_PROTOCOL_UDNS:
andrewboyson 183:ee809769bf89 464 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 183:ee809769bf89 465 {
andrewboyson 183:ee809769bf89 466 if (Ip6AddrIsEmpty(NdpDnsServer)) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 467 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 468 return false; //Internal but have no DHCP6 domain name so not ok
andrewboyson 183:ee809769bf89 469 }
andrewboyson 183:ee809769bf89 470 else //ETH_IPV4
andrewboyson 183:ee809769bf89 471 {
andrewboyson 183:ee809769bf89 472 if (DhcpDnsServerIp == 0) return false; //No DNS server so not ok
andrewboyson 183:ee809769bf89 473 if (isExternal) return true; //External and have DNS server so ok
andrewboyson 183:ee809769bf89 474 return DhcpDomainName[0] != 0; //Internal and have domain name so ok
andrewboyson 183:ee809769bf89 475 }
andrewboyson 183:ee809769bf89 476 case DNS_PROTOCOL_NONE: return true; //No protocol is valid as it designates 'not found'
andrewboyson 183:ee809769bf89 477 default: return false;
andrewboyson 183:ee809769bf89 478 }
andrewboyson 183:ee809769bf89 479 }
andrewboyson 172:9bc3c7b2cca1 480 static void makeNextProtocol(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 481 {
andrewboyson 172:9bc3c7b2cca1 482 //If current protocol is empty or unknown then return with the first.
andrewboyson 172:9bc3c7b2cca1 483 switch (pr->ipProtocol)
andrewboyson 172:9bc3c7b2cca1 484 {
andrewboyson 172:9bc3c7b2cca1 485 case ETH_IPV6: break;
andrewboyson 172:9bc3c7b2cca1 486 case ETH_IPV4: break;
andrewboyson 172:9bc3c7b2cca1 487 default:
andrewboyson 172:9bc3c7b2cca1 488 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 489 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 490 return;
andrewboyson 172:9bc3c7b2cca1 491 }
andrewboyson 172:9bc3c7b2cca1 492 switch (pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 493 {
andrewboyson 172:9bc3c7b2cca1 494 case DNS_PROTOCOL_MDNS: break;
andrewboyson 172:9bc3c7b2cca1 495 case DNS_PROTOCOL_LLMNR: break;
andrewboyson 172:9bc3c7b2cca1 496 case DNS_PROTOCOL_UDNS: break;
andrewboyson 172:9bc3c7b2cca1 497 default:
andrewboyson 172:9bc3c7b2cca1 498 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 499 pr->dnsProtocol = DNS_PROTOCOL_MDNS;
andrewboyson 172:9bc3c7b2cca1 500 return;
andrewboyson 172:9bc3c7b2cca1 501
andrewboyson 172:9bc3c7b2cca1 502 }
andrewboyson 172:9bc3c7b2cca1 503 switch(pr->dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 504 {
andrewboyson 172:9bc3c7b2cca1 505 case DNS_PROTOCOL_MDNS:
andrewboyson 172:9bc3c7b2cca1 506 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 507 {
andrewboyson 172:9bc3c7b2cca1 508 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 509 }
andrewboyson 172:9bc3c7b2cca1 510 else
andrewboyson 172:9bc3c7b2cca1 511 {
andrewboyson 172:9bc3c7b2cca1 512 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 513 pr->dnsProtocol = DNS_PROTOCOL_LLMNR;
andrewboyson 172:9bc3c7b2cca1 514 }
andrewboyson 172:9bc3c7b2cca1 515 break;
andrewboyson 172:9bc3c7b2cca1 516 case DNS_PROTOCOL_LLMNR:
andrewboyson 172:9bc3c7b2cca1 517 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 518 {
andrewboyson 172:9bc3c7b2cca1 519 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 520 }
andrewboyson 172:9bc3c7b2cca1 521 else
andrewboyson 172:9bc3c7b2cca1 522 {
andrewboyson 172:9bc3c7b2cca1 523 pr->ipProtocol = ETH_IPV6;
andrewboyson 172:9bc3c7b2cca1 524 pr->dnsProtocol = DNS_PROTOCOL_UDNS;
andrewboyson 172:9bc3c7b2cca1 525 }
andrewboyson 172:9bc3c7b2cca1 526 break;
andrewboyson 172:9bc3c7b2cca1 527 case DNS_PROTOCOL_UDNS:
andrewboyson 172:9bc3c7b2cca1 528 if (pr->ipProtocol == ETH_IPV6)
andrewboyson 172:9bc3c7b2cca1 529 {
andrewboyson 172:9bc3c7b2cca1 530 pr->ipProtocol = ETH_IPV4;
andrewboyson 172:9bc3c7b2cca1 531 }
andrewboyson 172:9bc3c7b2cca1 532 else
andrewboyson 172:9bc3c7b2cca1 533 {
andrewboyson 172:9bc3c7b2cca1 534 pr->ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 535 pr->dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 536 }
andrewboyson 172:9bc3c7b2cca1 537 break;
andrewboyson 172:9bc3c7b2cca1 538 }
andrewboyson 172:9bc3c7b2cca1 539 }
andrewboyson 172:9bc3c7b2cca1 540
andrewboyson 172:9bc3c7b2cca1 541 static void sendRequest(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 542 {
andrewboyson 172:9bc3c7b2cca1 543 if (DnsQueryIsBusy) return;
andrewboyson 172:9bc3c7b2cca1 544
andrewboyson 172:9bc3c7b2cca1 545 switch (pr->state)
andrewboyson 172:9bc3c7b2cca1 546 {
andrewboyson 172:9bc3c7b2cca1 547 case STATE_WANT:
andrewboyson 172:9bc3c7b2cca1 548 makeNextProtocol(pr);
andrewboyson 183:ee809769bf89 549 while (!protocolIsAvailable(pr)) makeNextProtocol(pr);
andrewboyson 172:9bc3c7b2cca1 550 if (!pr->dnsProtocol || !pr->ipProtocol) //No more protocols to try so resolution has failed
andrewboyson 172:9bc3c7b2cca1 551 {
andrewboyson 172:9bc3c7b2cca1 552 if (pr->todo == TODO_NAME_FROM_ADDRESS)
andrewboyson 172:9bc3c7b2cca1 553 {
andrewboyson 172:9bc3c7b2cca1 554 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 555 {
andrewboyson 192:0dfa138a8e7d 556 LogTimeF("NR - record %2d - request for name of ", pr - records);
andrewboyson 182:ff48c6ea91c1 557 addrLog(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 558 Log(" has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 559 }
andrewboyson 172:9bc3c7b2cca1 560 pr->name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 561 }
andrewboyson 182:ff48c6ea91c1 562 if (pr->todo == TODO_ADDRESS_FROM_NAME)
andrewboyson 172:9bc3c7b2cca1 563 {
andrewboyson 172:9bc3c7b2cca1 564 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 565 {
andrewboyson 192:0dfa138a8e7d 566 LogTimeF("NR - record %2d - request for address of '", pr - records);
andrewboyson 172:9bc3c7b2cca1 567 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 568 Log("' has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 569 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 570 }
andrewboyson 182:ff48c6ea91c1 571 addrClear(pr->addrType, pr->address);
andrewboyson 172:9bc3c7b2cca1 572 }
andrewboyson 172:9bc3c7b2cca1 573 pr->todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 574 pr->state = STATE_VALID;
andrewboyson 172:9bc3c7b2cca1 575 pr->ageMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 576 }
andrewboyson 172:9bc3c7b2cca1 577 else
andrewboyson 172:9bc3c7b2cca1 578 {
andrewboyson 172:9bc3c7b2cca1 579 pr->state = STATE_WAIT_FOR_ETH;
andrewboyson 172:9bc3c7b2cca1 580 }
andrewboyson 172:9bc3c7b2cca1 581 break;
andrewboyson 172:9bc3c7b2cca1 582 case STATE_WAIT_FOR_ETH:
andrewboyson 172:9bc3c7b2cca1 583 if (!DnsQueryIsBusy)
andrewboyson 172:9bc3c7b2cca1 584 {
andrewboyson 172:9bc3c7b2cca1 585 switch (pr->todo)
andrewboyson 172:9bc3c7b2cca1 586 {
andrewboyson 182:ff48c6ea91c1 587 case TODO_NAME_FROM_ADDRESS: queryNameFromIp(pr); break;
andrewboyson 182:ff48c6ea91c1 588 case TODO_ADDRESS_FROM_NAME: queryIpFromName(pr); break;
andrewboyson 172:9bc3c7b2cca1 589 }
andrewboyson 172:9bc3c7b2cca1 590 pr->state = STATE_WAIT_TIMEOUT;
andrewboyson 172:9bc3c7b2cca1 591 pr->replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 592 }
andrewboyson 172:9bc3c7b2cca1 593 break;
andrewboyson 172:9bc3c7b2cca1 594 case STATE_WAIT_TIMEOUT:
andrewboyson 172:9bc3c7b2cca1 595 if (MsTimerRelative(pr->replyMs, REPLY_TIMEOUT_MS))
andrewboyson 172:9bc3c7b2cca1 596 {
andrewboyson 172:9bc3c7b2cca1 597 pr->state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 598 }
andrewboyson 172:9bc3c7b2cca1 599 break;
andrewboyson 172:9bc3c7b2cca1 600 default:
andrewboyson 172:9bc3c7b2cca1 601 break;
andrewboyson 172:9bc3c7b2cca1 602 }
andrewboyson 172:9bc3c7b2cca1 603 }
andrewboyson 172:9bc3c7b2cca1 604 void NrMain()
andrewboyson 172:9bc3c7b2cca1 605 {
andrewboyson 172:9bc3c7b2cca1 606 static int i = -1;
andrewboyson 172:9bc3c7b2cca1 607 i++;
andrewboyson 172:9bc3c7b2cca1 608 if (i >= RECORDS_COUNT) i = 0;
andrewboyson 172:9bc3c7b2cca1 609
andrewboyson 172:9bc3c7b2cca1 610 struct record* pr = &records[i];
andrewboyson 172:9bc3c7b2cca1 611
andrewboyson 172:9bc3c7b2cca1 612 clearCache (pr);
andrewboyson 172:9bc3c7b2cca1 613 sendRequest (pr);
andrewboyson 189:e1c7990486c4 614
andrewboyson 189:e1c7990486c4 615 NrTestMain();
andrewboyson 172:9bc3c7b2cca1 616 }
andrewboyson 172:9bc3c7b2cca1 617 void NrInit()
andrewboyson 172:9bc3c7b2cca1 618 {
andrewboyson 172:9bc3c7b2cca1 619 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 620 }