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:
Thu May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
193:47a953ab571b
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

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