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:
Wed Dec 16 17:33:22 2020 +0000
Revision:
172:9bc3c7b2cca1
Child:
176:7eb916c22084
Modified name resolution to work with both IPv4 and IPv6. Before there were two independent modules.

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 "ip6addr.h"
andrewboyson 172:9bc3c7b2cca1 11 #include "dhcp.h"
andrewboyson 172:9bc3c7b2cca1 12 #include "dns.h"
andrewboyson 172:9bc3c7b2cca1 13 #include "dnsquery.h"
andrewboyson 172:9bc3c7b2cca1 14 #include "dnslabel.h"
andrewboyson 172:9bc3c7b2cca1 15 #include "http.h"
andrewboyson 172:9bc3c7b2cca1 16
andrewboyson 172:9bc3c7b2cca1 17 bool Nr4Trace = false; //Do not use
andrewboyson 172:9bc3c7b2cca1 18 bool NrTrace = false;
andrewboyson 172:9bc3c7b2cca1 19
andrewboyson 172:9bc3c7b2cca1 20 #define NAME_MAX_LENGTH 20
andrewboyson 172:9bc3c7b2cca1 21 #define CACHE_TIMEOUT_MS 3600 * 1000
andrewboyson 172:9bc3c7b2cca1 22 #define STALE_TIMEOUT_MS 1800 * 1000
andrewboyson 172:9bc3c7b2cca1 23 #define EMPTY_TIMEOUT_MS 300 * 1000
andrewboyson 172:9bc3c7b2cca1 24 #define REPLY_TIMEOUT_MS 100
andrewboyson 172:9bc3c7b2cca1 25
andrewboyson 172:9bc3c7b2cca1 26 #define RECORDS_COUNT 50
andrewboyson 172:9bc3c7b2cca1 27
andrewboyson 172:9bc3c7b2cca1 28 #define STATE_EMPTY 0
andrewboyson 172:9bc3c7b2cca1 29 #define STATE_WANT 1
andrewboyson 172:9bc3c7b2cca1 30 #define STATE_WAIT_FOR_ETH 2
andrewboyson 172:9bc3c7b2cca1 31 #define STATE_WAIT_TIMEOUT 3
andrewboyson 172:9bc3c7b2cca1 32 #define STATE_VALID 4
andrewboyson 172:9bc3c7b2cca1 33
andrewboyson 172:9bc3c7b2cca1 34 #define TODO_NONE 0
andrewboyson 172:9bc3c7b2cca1 35 #define TODO_NAME_FROM_ADDRESS 1
andrewboyson 172:9bc3c7b2cca1 36 #define TODO_ADDRESS4_FROM_NAME 2
andrewboyson 172:9bc3c7b2cca1 37 #define TODO_ADDRESS6_FROM_NAME 3
andrewboyson 172:9bc3c7b2cca1 38
andrewboyson 172:9bc3c7b2cca1 39 struct record
andrewboyson 172:9bc3c7b2cca1 40 {
andrewboyson 172:9bc3c7b2cca1 41 uint32_t replyMs;
andrewboyson 172:9bc3c7b2cca1 42 uint32_t ageMs;
andrewboyson 172:9bc3c7b2cca1 43 char address[16];
andrewboyson 172:9bc3c7b2cca1 44 uint8_t todo;
andrewboyson 172:9bc3c7b2cca1 45 uint8_t state;
andrewboyson 172:9bc3c7b2cca1 46 uint8_t dnsProtocol;
andrewboyson 172:9bc3c7b2cca1 47 uint16_t ipProtocol;
andrewboyson 172:9bc3c7b2cca1 48 char name[NAME_MAX_LENGTH];
andrewboyson 172:9bc3c7b2cca1 49 };
andrewboyson 172:9bc3c7b2cca1 50 static struct record records[RECORDS_COUNT];
andrewboyson 172:9bc3c7b2cca1 51
andrewboyson 172:9bc3c7b2cca1 52 static int getExistingAddress(char* address)
andrewboyson 172:9bc3c7b2cca1 53 {
andrewboyson 172:9bc3c7b2cca1 54 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 55 {
andrewboyson 172:9bc3c7b2cca1 56 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 57 if (Ip6AddrIsSame(records[i].address, address)) return i;
andrewboyson 172:9bc3c7b2cca1 58 }
andrewboyson 172:9bc3c7b2cca1 59 return -1;
andrewboyson 172:9bc3c7b2cca1 60 }
andrewboyson 172:9bc3c7b2cca1 61 static int getExistingName(char* name)
andrewboyson 172:9bc3c7b2cca1 62 {
andrewboyson 172:9bc3c7b2cca1 63 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 64 {
andrewboyson 172:9bc3c7b2cca1 65 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 66 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 172:9bc3c7b2cca1 67 }
andrewboyson 172:9bc3c7b2cca1 68 return -1;
andrewboyson 172:9bc3c7b2cca1 69 }
andrewboyson 172:9bc3c7b2cca1 70 static int getNameOnly(char* name)
andrewboyson 172:9bc3c7b2cca1 71 {
andrewboyson 172:9bc3c7b2cca1 72 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 73 {
andrewboyson 172:9bc3c7b2cca1 74 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 75 if (!Ip6AddrIsEmpty(records[i].address)) continue;
andrewboyson 172:9bc3c7b2cca1 76 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 172:9bc3c7b2cca1 77 }
andrewboyson 172:9bc3c7b2cca1 78 return -1;
andrewboyson 172:9bc3c7b2cca1 79 }
andrewboyson 172:9bc3c7b2cca1 80 static int getIpOnly(char* address)
andrewboyson 172:9bc3c7b2cca1 81 {
andrewboyson 172:9bc3c7b2cca1 82 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 83 {
andrewboyson 172:9bc3c7b2cca1 84 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 85 if (records[i].name[0] != 0) continue;
andrewboyson 172:9bc3c7b2cca1 86 if (Ip6AddrIsSame(records[i].address, address)) return i;
andrewboyson 172:9bc3c7b2cca1 87 }
andrewboyson 172:9bc3c7b2cca1 88 return -1;
andrewboyson 172:9bc3c7b2cca1 89 }
andrewboyson 172:9bc3c7b2cca1 90 static int getOldest()
andrewboyson 172:9bc3c7b2cca1 91 {
andrewboyson 172:9bc3c7b2cca1 92 int iOldest = 0;
andrewboyson 172:9bc3c7b2cca1 93 uint32_t ageOldest = 0;
andrewboyson 172:9bc3c7b2cca1 94 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 95 {
andrewboyson 172:9bc3c7b2cca1 96 if (records[i].state == STATE_EMPTY) return i; //Found an empty slot so just return it
andrewboyson 172:9bc3c7b2cca1 97 uint32_t age = MsTimerCount - records[i].ageMs;
andrewboyson 172:9bc3c7b2cca1 98 if (age >= ageOldest)
andrewboyson 172:9bc3c7b2cca1 99 {
andrewboyson 172:9bc3c7b2cca1 100 ageOldest = age;
andrewboyson 172:9bc3c7b2cca1 101 iOldest = i;
andrewboyson 172:9bc3c7b2cca1 102 }
andrewboyson 172:9bc3c7b2cca1 103 }
andrewboyson 172:9bc3c7b2cca1 104 return iOldest; //Otherwise return the oldest
andrewboyson 172:9bc3c7b2cca1 105 }
andrewboyson 172:9bc3c7b2cca1 106 static void makeRequestForNameFromAddress(char* address)
andrewboyson 172:9bc3c7b2cca1 107 {
andrewboyson 172:9bc3c7b2cca1 108 //Don't treat non ips
andrewboyson 172:9bc3c7b2cca1 109 if (Ip6AddrIsEmpty(address)) return;
andrewboyson 172:9bc3c7b2cca1 110 int i;
andrewboyson 172:9bc3c7b2cca1 111
andrewboyson 172:9bc3c7b2cca1 112 //If a valid record already exists then request an update
andrewboyson 172:9bc3c7b2cca1 113 i = getExistingAddress(address);
andrewboyson 172:9bc3c7b2cca1 114 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 115 {
andrewboyson 172:9bc3c7b2cca1 116 if (records[i].state != STATE_VALID) return;
andrewboyson 172:9bc3c7b2cca1 117 if (records[i].name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 118 {
andrewboyson 172:9bc3c7b2cca1 119 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 120 }
andrewboyson 172:9bc3c7b2cca1 121 else
andrewboyson 172:9bc3c7b2cca1 122 {
andrewboyson 172:9bc3c7b2cca1 123 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 124 }
andrewboyson 172:9bc3c7b2cca1 125 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 126 {
andrewboyson 172:9bc3c7b2cca1 127 LogTimeF("NR - renew name of ");
andrewboyson 172:9bc3c7b2cca1 128 Ip6AddrLog(address);
andrewboyson 172:9bc3c7b2cca1 129 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 130 }
andrewboyson 172:9bc3c7b2cca1 131 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 132 //Leave the name as is
andrewboyson 172:9bc3c7b2cca1 133 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 134 }
andrewboyson 172:9bc3c7b2cca1 135 else
andrewboyson 172:9bc3c7b2cca1 136 {
andrewboyson 172:9bc3c7b2cca1 137 //If a record does not exist then find the first empty slot and add the IP and date
andrewboyson 172:9bc3c7b2cca1 138 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 139 {
andrewboyson 172:9bc3c7b2cca1 140 LogTimeF("NR - request name of ");
andrewboyson 172:9bc3c7b2cca1 141 Ip6AddrLog(address);
andrewboyson 172:9bc3c7b2cca1 142 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 143 }
andrewboyson 172:9bc3c7b2cca1 144 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 145 Ip6AddrCopy(records[i].address, address); //Set the address
andrewboyson 172:9bc3c7b2cca1 146 records[i].name[0] = 0; //Clear the name
andrewboyson 172:9bc3c7b2cca1 147 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 148 }
andrewboyson 172:9bc3c7b2cca1 149 records[i].todo = TODO_NAME_FROM_ADDRESS;
andrewboyson 172:9bc3c7b2cca1 150 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 151 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 152 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 153 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 154 }
andrewboyson 172:9bc3c7b2cca1 155 static void makeRequestForAddressFromName(char* name, int todo)
andrewboyson 172:9bc3c7b2cca1 156 {
andrewboyson 172:9bc3c7b2cca1 157 //Don't treat non names
andrewboyson 172:9bc3c7b2cca1 158 if (!name[0]) return;
andrewboyson 172:9bc3c7b2cca1 159 int i;
andrewboyson 172:9bc3c7b2cca1 160
andrewboyson 172:9bc3c7b2cca1 161 //If a valid record already exists then request an update
andrewboyson 172:9bc3c7b2cca1 162 i = getExistingName(name);
andrewboyson 172:9bc3c7b2cca1 163 if (i > -1)
andrewboyson 172:9bc3c7b2cca1 164 {
andrewboyson 172:9bc3c7b2cca1 165 if (records[i].state != STATE_VALID) return;
andrewboyson 172:9bc3c7b2cca1 166 if (Ip6AddrIsEmpty(records[i].address))
andrewboyson 172:9bc3c7b2cca1 167 {
andrewboyson 172:9bc3c7b2cca1 168 if (!MsTimerRelative(records[i].ageMs, EMPTY_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 169 }
andrewboyson 172:9bc3c7b2cca1 170 else
andrewboyson 172:9bc3c7b2cca1 171 {
andrewboyson 172:9bc3c7b2cca1 172 if (!MsTimerRelative(records[i].ageMs, STALE_TIMEOUT_MS)) return;
andrewboyson 172:9bc3c7b2cca1 173 }
andrewboyson 172:9bc3c7b2cca1 174 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 175 {
andrewboyson 172:9bc3c7b2cca1 176 if (todo == TODO_ADDRESS4_FROM_NAME) LogTimeF("NR - renew A of %s\r\n", name);
andrewboyson 172:9bc3c7b2cca1 177 else LogTimeF("NR - renew AAAA of %s\r\n", name);
andrewboyson 172:9bc3c7b2cca1 178 }
andrewboyson 172:9bc3c7b2cca1 179 //Leave name as is
andrewboyson 172:9bc3c7b2cca1 180 //Leave the address as is
andrewboyson 172:9bc3c7b2cca1 181 //Leave age as is
andrewboyson 172:9bc3c7b2cca1 182 }
andrewboyson 172:9bc3c7b2cca1 183 else
andrewboyson 172:9bc3c7b2cca1 184 {
andrewboyson 172:9bc3c7b2cca1 185 //If a record does not exist then find the first empty slot and add the name and date
andrewboyson 172:9bc3c7b2cca1 186 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 187 {
andrewboyson 172:9bc3c7b2cca1 188 if (todo == TODO_ADDRESS4_FROM_NAME) LogTimeF("NR - request A of %s\r\n", name);
andrewboyson 172:9bc3c7b2cca1 189 else LogTimeF("NR - request AAAA of %s\r\n", name);
andrewboyson 172:9bc3c7b2cca1 190 }
andrewboyson 172:9bc3c7b2cca1 191 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 192 strncpy(records[i].name, name, NAME_MAX_LENGTH); //Set the name
andrewboyson 172:9bc3c7b2cca1 193 records[i].name[NAME_MAX_LENGTH - 1] = 0;
andrewboyson 172:9bc3c7b2cca1 194 Ip6AddrClear(records[i].address); //Clear the address
andrewboyson 172:9bc3c7b2cca1 195 records[i].ageMs = MsTimerCount; //Start age
andrewboyson 172:9bc3c7b2cca1 196 }
andrewboyson 172:9bc3c7b2cca1 197 records[i].todo = todo;
andrewboyson 172:9bc3c7b2cca1 198 records[i].state = STATE_WANT;
andrewboyson 172:9bc3c7b2cca1 199 records[i].replyMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 200 records[i].ipProtocol = ETH_NONE;
andrewboyson 172:9bc3c7b2cca1 201 records[i].dnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 172:9bc3c7b2cca1 202 }
andrewboyson 172:9bc3c7b2cca1 203 static void updateRecord(int i, char* address, char* name, int dnsProtocol, int ipProtocol)
andrewboyson 172:9bc3c7b2cca1 204 {
andrewboyson 172:9bc3c7b2cca1 205 records[i].todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 206 records[i].ageMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 207 Ip6AddrCopy(records[i].address, address);
andrewboyson 172:9bc3c7b2cca1 208 records[i].dnsProtocol = dnsProtocol;
andrewboyson 172:9bc3c7b2cca1 209 records[i].ipProtocol = ipProtocol;
andrewboyson 172:9bc3c7b2cca1 210 records[i].state = STATE_VALID;
andrewboyson 172:9bc3c7b2cca1 211 strncpy(records[i].name, name, NAME_MAX_LENGTH);
andrewboyson 172:9bc3c7b2cca1 212 records[i].name[NAME_MAX_LENGTH - 1] = 0;
andrewboyson 172:9bc3c7b2cca1 213 }
andrewboyson 172:9bc3c7b2cca1 214 void addEntry(char* address, char* name, int dnsProtocol, int ipProtocol)
andrewboyson 172:9bc3c7b2cca1 215 {
andrewboyson 172:9bc3c7b2cca1 216 /*
andrewboyson 172:9bc3c7b2cca1 217 A number of situations may need to be handled:
andrewboyson 172:9bc3c7b2cca1 218 - An existing address with the same name ; the usual situation : just reset the elapsed time and return
andrewboyson 172:9bc3c7b2cca1 219 - An existing address with no or a different name; usual if we are resolving an address : add or update the address of this record
andrewboyson 172:9bc3c7b2cca1 220 - Same name with an empty address ; usual if we are resolving a name : add the address to this record
andrewboyson 172:9bc3c7b2cca1 221 - Same name with another address ; normal situation : do nothing
andrewboyson 172:9bc3c7b2cca1 222 - No existing address or name ; usual if another device has done a reolution : add a new record and return
andrewboyson 172:9bc3c7b2cca1 223
andrewboyson 172:9bc3c7b2cca1 224 Quite often we will simultaneously attempt to resolve both the name and the address of the same device.
andrewboyson 172:9bc3c7b2cca1 225 When this happens there will be two entries: one with the name and an empty address; the other with the address but and an empty name.
andrewboyson 172:9bc3c7b2cca1 226 In this case we first add the name to the existing address but also check for the name with an empty address and delete it.
andrewboyson 172:9bc3c7b2cca1 227 */
andrewboyson 172:9bc3c7b2cca1 228
andrewboyson 172:9bc3c7b2cca1 229 int i;
andrewboyson 172:9bc3c7b2cca1 230
andrewboyson 172:9bc3c7b2cca1 231 //Print what is being handled
andrewboyson 172:9bc3c7b2cca1 232 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 233 {
andrewboyson 172:9bc3c7b2cca1 234 LogTimeF("NR - received ");
andrewboyson 172:9bc3c7b2cca1 235 Ip6AddrLog(address);
andrewboyson 172:9bc3c7b2cca1 236 Log(" == '");
andrewboyson 172:9bc3c7b2cca1 237 Log(name);
andrewboyson 172:9bc3c7b2cca1 238 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 239 }
andrewboyson 172:9bc3c7b2cca1 240
andrewboyson 172:9bc3c7b2cca1 241 //Ignore records which do not have both address and name
andrewboyson 172:9bc3c7b2cca1 242 if (Ip6AddrIsEmpty(address) || name == 0 || name[0] == 0)
andrewboyson 172:9bc3c7b2cca1 243 {
andrewboyson 172:9bc3c7b2cca1 244 if (NrTrace) LogTimeF("NR -- ignoring invalid entry\r\n");
andrewboyson 172:9bc3c7b2cca1 245 return;
andrewboyson 172:9bc3c7b2cca1 246 }
andrewboyson 172:9bc3c7b2cca1 247
andrewboyson 172:9bc3c7b2cca1 248 //Get existing address and, if found, add it then clear any name only entries
andrewboyson 172:9bc3c7b2cca1 249 i = getExistingAddress(address);
andrewboyson 172:9bc3c7b2cca1 250 if (i >= 0)
andrewboyson 172:9bc3c7b2cca1 251 {
andrewboyson 172:9bc3c7b2cca1 252 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 253 {
andrewboyson 172:9bc3c7b2cca1 254 if (DnsLabelIsSame(name, records[i].name))
andrewboyson 172:9bc3c7b2cca1 255 {
andrewboyson 172:9bc3c7b2cca1 256 LogTimeF("NR -- record %d - refresh existing entry\r\n", i);
andrewboyson 172:9bc3c7b2cca1 257 }
andrewboyson 172:9bc3c7b2cca1 258 else
andrewboyson 172:9bc3c7b2cca1 259 {
andrewboyson 172:9bc3c7b2cca1 260 LogTimeF("NR -- record %d - update entry name from '%s' to '%s'\r\n", i, records[i].name, name);
andrewboyson 172:9bc3c7b2cca1 261 }
andrewboyson 172:9bc3c7b2cca1 262 }
andrewboyson 172:9bc3c7b2cca1 263 updateRecord(i, address, name, dnsProtocol, ipProtocol);
andrewboyson 172:9bc3c7b2cca1 264
andrewboyson 172:9bc3c7b2cca1 265 i = getNameOnly(name);
andrewboyson 172:9bc3c7b2cca1 266 if (i >= 0)
andrewboyson 172:9bc3c7b2cca1 267 {
andrewboyson 172:9bc3c7b2cca1 268 if (NrTrace) LogTimeF("NR -- record %d - clear name '%s' with no address\r\n", i, name);
andrewboyson 172:9bc3c7b2cca1 269 records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 270 }
andrewboyson 172:9bc3c7b2cca1 271 return;
andrewboyson 172:9bc3c7b2cca1 272 }
andrewboyson 172:9bc3c7b2cca1 273
andrewboyson 172:9bc3c7b2cca1 274 //Get name only entry and, if found, add it
andrewboyson 172:9bc3c7b2cca1 275 i = getNameOnly(name);
andrewboyson 172:9bc3c7b2cca1 276 if (i >= 0)
andrewboyson 172:9bc3c7b2cca1 277 {
andrewboyson 172:9bc3c7b2cca1 278 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 279 {
andrewboyson 172:9bc3c7b2cca1 280 LogTimeF("NR -- record %d - add address ", i);
andrewboyson 172:9bc3c7b2cca1 281 Ip6AddrLog(address);
andrewboyson 172:9bc3c7b2cca1 282 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 283 }
andrewboyson 172:9bc3c7b2cca1 284 updateRecord(i, address, name, dnsProtocol, ipProtocol);
andrewboyson 172:9bc3c7b2cca1 285 return;
andrewboyson 172:9bc3c7b2cca1 286 }
andrewboyson 172:9bc3c7b2cca1 287
andrewboyson 172:9bc3c7b2cca1 288 //No other entry exists so just add it to the next available space
andrewboyson 172:9bc3c7b2cca1 289 i = getOldest();
andrewboyson 172:9bc3c7b2cca1 290 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 291 {
andrewboyson 172:9bc3c7b2cca1 292 LogTimeF("NR -- record %d - add entry\r\n", i);
andrewboyson 172:9bc3c7b2cca1 293 }
andrewboyson 172:9bc3c7b2cca1 294 updateRecord(i, address, name, dnsProtocol, ipProtocol);
andrewboyson 172:9bc3c7b2cca1 295 }
andrewboyson 172:9bc3c7b2cca1 296 static void addressToName(char* address, char* name)
andrewboyson 172:9bc3c7b2cca1 297 {
andrewboyson 172:9bc3c7b2cca1 298 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 299 {
andrewboyson 172:9bc3c7b2cca1 300 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 301 if (Ip6AddrIsSame(records[i].address, address))
andrewboyson 172:9bc3c7b2cca1 302 {
andrewboyson 172:9bc3c7b2cca1 303 strcpy(name, records[i].name);
andrewboyson 172:9bc3c7b2cca1 304 return;
andrewboyson 172:9bc3c7b2cca1 305 }
andrewboyson 172:9bc3c7b2cca1 306 }
andrewboyson 172:9bc3c7b2cca1 307 name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 308 }
andrewboyson 172:9bc3c7b2cca1 309 static void nameToAddress(char* name, char* address)
andrewboyson 172:9bc3c7b2cca1 310 {
andrewboyson 172:9bc3c7b2cca1 311 uint32_t newest = 0xFFFFFFFF;
andrewboyson 172:9bc3c7b2cca1 312 Ip6AddrClear(address);
andrewboyson 172:9bc3c7b2cca1 313 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 314 {
andrewboyson 172:9bc3c7b2cca1 315 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 316 if(Ip6AddrIsEmpty(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 172:9bc3c7b2cca1 322 Ip6AddrCopy(address, records[i].address);
andrewboyson 172:9bc3c7b2cca1 323 }
andrewboyson 172:9bc3c7b2cca1 324 }
andrewboyson 172:9bc3c7b2cca1 325 }
andrewboyson 172:9bc3c7b2cca1 326 void NrMakeRequestForNameFromAddress6(char* address6)
andrewboyson 172:9bc3c7b2cca1 327 {
andrewboyson 172:9bc3c7b2cca1 328 makeRequestForNameFromAddress(address6);
andrewboyson 172:9bc3c7b2cca1 329 }
andrewboyson 172:9bc3c7b2cca1 330 void NrMakeRequestForNameFromAddress4(uint32_t address4)
andrewboyson 172:9bc3c7b2cca1 331 {
andrewboyson 172:9bc3c7b2cca1 332 char address6[16];
andrewboyson 172:9bc3c7b2cca1 333 Ip6AddrFromIp4(address6, address4);
andrewboyson 172:9bc3c7b2cca1 334 makeRequestForNameFromAddress(address6);
andrewboyson 172:9bc3c7b2cca1 335 }
andrewboyson 172:9bc3c7b2cca1 336 void NrMakeRequestForAddress6FromName(char* name)
andrewboyson 172:9bc3c7b2cca1 337 {
andrewboyson 172:9bc3c7b2cca1 338 makeRequestForAddressFromName(name, TODO_ADDRESS6_FROM_NAME);
andrewboyson 172:9bc3c7b2cca1 339 }
andrewboyson 172:9bc3c7b2cca1 340 void NrMakeRequestForAddress4FromName(char* name)
andrewboyson 172:9bc3c7b2cca1 341 {
andrewboyson 172:9bc3c7b2cca1 342 makeRequestForAddressFromName(name, TODO_ADDRESS4_FROM_NAME);
andrewboyson 172:9bc3c7b2cca1 343 }
andrewboyson 172:9bc3c7b2cca1 344 void NrAddAddress6(char* address, char* name, int dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 345 {
andrewboyson 172:9bc3c7b2cca1 346 addEntry(address, name, dnsProtocol, EthProtocol);
andrewboyson 172:9bc3c7b2cca1 347 }
andrewboyson 172:9bc3c7b2cca1 348 void NrAddAddress4(uint32_t address4, char* name, int dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 349 {
andrewboyson 172:9bc3c7b2cca1 350 char address6[16];
andrewboyson 172:9bc3c7b2cca1 351 Ip6AddrFromIp4(address6, address4);
andrewboyson 172:9bc3c7b2cca1 352 addEntry(address6, name, dnsProtocol, EthProtocol);
andrewboyson 172:9bc3c7b2cca1 353 }
andrewboyson 172:9bc3c7b2cca1 354 void NrNameToAddress6(char* name, char* address)
andrewboyson 172:9bc3c7b2cca1 355 {
andrewboyson 172:9bc3c7b2cca1 356 nameToAddress(name, address);
andrewboyson 172:9bc3c7b2cca1 357 }
andrewboyson 172:9bc3c7b2cca1 358 void NrNameToAddress4(char* name, uint32_t* pAddress4)
andrewboyson 172:9bc3c7b2cca1 359 {
andrewboyson 172:9bc3c7b2cca1 360 char address6[16];
andrewboyson 172:9bc3c7b2cca1 361 nameToAddress(name, address6);
andrewboyson 172:9bc3c7b2cca1 362 *pAddress4 = Ip6AddrToIp4(address6);
andrewboyson 172:9bc3c7b2cca1 363 }
andrewboyson 172:9bc3c7b2cca1 364 void NrAddress6ToName(char* address, char* name)
andrewboyson 172:9bc3c7b2cca1 365 {
andrewboyson 172:9bc3c7b2cca1 366 addressToName(address, name);
andrewboyson 172:9bc3c7b2cca1 367 }
andrewboyson 172:9bc3c7b2cca1 368 void NrAddress4ToName(uint32_t address4, char* name)
andrewboyson 172:9bc3c7b2cca1 369 {
andrewboyson 172:9bc3c7b2cca1 370 char address6[16];
andrewboyson 172:9bc3c7b2cca1 371 Ip6AddrFromIp4(address6, address4);
andrewboyson 172:9bc3c7b2cca1 372 addressToName(address6, name);
andrewboyson 172:9bc3c7b2cca1 373 }
andrewboyson 172:9bc3c7b2cca1 374 static char letterFromStateAndProtocol(uint8_t dnsState, uint8_t dnsProtocol, uint16_t ipProtocol)
andrewboyson 172:9bc3c7b2cca1 375 {
andrewboyson 172:9bc3c7b2cca1 376 switch (dnsState)
andrewboyson 172:9bc3c7b2cca1 377 {
andrewboyson 172:9bc3c7b2cca1 378 case STATE_WANT: return '}';
andrewboyson 172:9bc3c7b2cca1 379 case STATE_WAIT_FOR_ETH: return ']';
andrewboyson 172:9bc3c7b2cca1 380 case STATE_WAIT_TIMEOUT: return '>';
andrewboyson 172:9bc3c7b2cca1 381
andrewboyson 172:9bc3c7b2cca1 382 case STATE_VALID:
andrewboyson 172:9bc3c7b2cca1 383 switch (dnsProtocol)
andrewboyson 172:9bc3c7b2cca1 384 {
andrewboyson 172:9bc3c7b2cca1 385 case DNS_PROTOCOL_UDNS: if (ipProtocol == ETH_IPV4) return 'd' ; else return 'D';
andrewboyson 172:9bc3c7b2cca1 386 case DNS_PROTOCOL_MDNS: if (ipProtocol == ETH_IPV4) return 'm' ; else return 'M';
andrewboyson 172:9bc3c7b2cca1 387 case DNS_PROTOCOL_LLMNR: if (ipProtocol == ETH_IPV4) return 'l' ; else return 'L';
andrewboyson 172:9bc3c7b2cca1 388 case DNS_PROTOCOL_NONE: return '-';
andrewboyson 172:9bc3c7b2cca1 389 default: return '?';
andrewboyson 172:9bc3c7b2cca1 390 }
andrewboyson 172:9bc3c7b2cca1 391 default: return '~';
andrewboyson 172:9bc3c7b2cca1 392 }
andrewboyson 172:9bc3c7b2cca1 393 }
andrewboyson 172:9bc3c7b2cca1 394 void NrSendHttp()
andrewboyson 172:9bc3c7b2cca1 395 {
andrewboyson 172:9bc3c7b2cca1 396 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 397 {
andrewboyson 172:9bc3c7b2cca1 398 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 399 if (!Ip6AddrIsEmpty(records[i].address) || records[i].name[0])
andrewboyson 172:9bc3c7b2cca1 400 {
andrewboyson 172:9bc3c7b2cca1 401 HttpAddF("%4u ", (MsTimerCount - records[i].ageMs) / 1000 / 60);
andrewboyson 172:9bc3c7b2cca1 402
andrewboyson 172:9bc3c7b2cca1 403 int ipLen;
andrewboyson 172:9bc3c7b2cca1 404 ipLen = Ip6AddrHttp(records[i].address);
andrewboyson 172:9bc3c7b2cca1 405 HttpAddFillChar(' ', 40 - ipLen);
andrewboyson 172:9bc3c7b2cca1 406
andrewboyson 172:9bc3c7b2cca1 407 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].dnsProtocol, records[i].ipProtocol));
andrewboyson 172:9bc3c7b2cca1 408
andrewboyson 172:9bc3c7b2cca1 409 HttpAddChar(' ');
andrewboyson 172:9bc3c7b2cca1 410
andrewboyson 172:9bc3c7b2cca1 411 HttpAddText(records[i].name);
andrewboyson 172:9bc3c7b2cca1 412
andrewboyson 172:9bc3c7b2cca1 413 HttpAddChar('\r');
andrewboyson 172:9bc3c7b2cca1 414 HttpAddChar('\n');
andrewboyson 172:9bc3c7b2cca1 415 }
andrewboyson 172:9bc3c7b2cca1 416 }
andrewboyson 172:9bc3c7b2cca1 417 }
andrewboyson 172:9bc3c7b2cca1 418 void NrSendAjax()
andrewboyson 172:9bc3c7b2cca1 419 {
andrewboyson 172:9bc3c7b2cca1 420 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 172:9bc3c7b2cca1 421 {
andrewboyson 172:9bc3c7b2cca1 422 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 172:9bc3c7b2cca1 423 if (!Ip6AddrIsEmpty(records[i].address) || records[i].name[0])
andrewboyson 172:9bc3c7b2cca1 424 {
andrewboyson 172:9bc3c7b2cca1 425 HttpAddByteAsHex(i);
andrewboyson 172:9bc3c7b2cca1 426 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 427 HttpAddInt32AsHex(MsTimerCount - records[i].ageMs);
andrewboyson 172:9bc3c7b2cca1 428 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 429 for (int b = 0; b < 16; b++) HttpAddByteAsHex(records[i].address[b]);
andrewboyson 172:9bc3c7b2cca1 430 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 431 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].dnsProtocol, records[i].ipProtocol));
andrewboyson 172:9bc3c7b2cca1 432 HttpAddChar('\t');
andrewboyson 172:9bc3c7b2cca1 433 HttpAddText(records[i].name);
andrewboyson 172:9bc3c7b2cca1 434 HttpAddChar('\n');
andrewboyson 172:9bc3c7b2cca1 435 }
andrewboyson 172:9bc3c7b2cca1 436 }
andrewboyson 172:9bc3c7b2cca1 437 }
andrewboyson 172:9bc3c7b2cca1 438 static void clearCache(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 439 {
andrewboyson 172:9bc3c7b2cca1 440 if (MsTimerRelative(pr->ageMs, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 441 }
andrewboyson 172:9bc3c7b2cca1 442 static void queryNameFromIp(struct record* pr)
andrewboyson 172:9bc3c7b2cca1 443 {
andrewboyson 172:9bc3c7b2cca1 444 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 445 {
andrewboyson 172:9bc3c7b2cca1 446 LogTime("NR -- send ");
andrewboyson 172:9bc3c7b2cca1 447 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 448 Log(" ");
andrewboyson 172:9bc3c7b2cca1 449 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 450 Log(" request for name of ");
andrewboyson 172:9bc3c7b2cca1 451 Ip6AddrLog(pr->address);
andrewboyson 172:9bc3c7b2cca1 452 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 453 }
andrewboyson 172:9bc3c7b2cca1 454 if (Ip6AddrIsIp4(pr->address))
andrewboyson 172:9bc3c7b2cca1 455 {
andrewboyson 172:9bc3c7b2cca1 456 uint32_t address4 = Ip6AddrToIp4(pr->address);
andrewboyson 172:9bc3c7b2cca1 457 DnsQueryNameFromIp4(address4, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 458 }
andrewboyson 172:9bc3c7b2cca1 459 else
andrewboyson 172:9bc3c7b2cca1 460 {
andrewboyson 172:9bc3c7b2cca1 461 DnsQueryNameFromIp6(pr->address, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 462 }
andrewboyson 172:9bc3c7b2cca1 463 }
andrewboyson 172:9bc3c7b2cca1 464 static void queryIpFromName(struct record* pr, int todo)
andrewboyson 172:9bc3c7b2cca1 465 {
andrewboyson 172:9bc3c7b2cca1 466 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 467 {
andrewboyson 172:9bc3c7b2cca1 468 LogTime("NR -- send ");
andrewboyson 172:9bc3c7b2cca1 469 EthProtocolLog(pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 470 Log(" ");
andrewboyson 172:9bc3c7b2cca1 471 DnsProtocolLog(pr->dnsProtocol);
andrewboyson 172:9bc3c7b2cca1 472 if (todo == TODO_ADDRESS4_FROM_NAME) Log(" request for A of name '");
andrewboyson 172:9bc3c7b2cca1 473 else Log(" request for AAAA of name '");
andrewboyson 172:9bc3c7b2cca1 474 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 475 Log("'\r\n");
andrewboyson 172:9bc3c7b2cca1 476 }
andrewboyson 172:9bc3c7b2cca1 477 if (todo == TODO_ADDRESS4_FROM_NAME) DnsQueryIp4FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 478 else DnsQueryIp6FromName(pr->name, pr->dnsProtocol, pr->ipProtocol);
andrewboyson 172:9bc3c7b2cca1 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 172:9bc3c7b2cca1 549 if (!pr->dnsProtocol || !pr->ipProtocol) //No more protocols to try so resolution has failed
andrewboyson 172:9bc3c7b2cca1 550 {
andrewboyson 172:9bc3c7b2cca1 551 if (pr->todo == TODO_NAME_FROM_ADDRESS)
andrewboyson 172:9bc3c7b2cca1 552 {
andrewboyson 172:9bc3c7b2cca1 553 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 554 {
andrewboyson 172:9bc3c7b2cca1 555 LogTimeF("NR - request for name of ");
andrewboyson 172:9bc3c7b2cca1 556 Ip6AddrLog(pr->address);
andrewboyson 172:9bc3c7b2cca1 557 Log(" has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 558 }
andrewboyson 172:9bc3c7b2cca1 559 pr->name[0] = 0;
andrewboyson 172:9bc3c7b2cca1 560 }
andrewboyson 172:9bc3c7b2cca1 561 if (pr->todo == TODO_ADDRESS4_FROM_NAME || pr->todo == TODO_ADDRESS6_FROM_NAME)
andrewboyson 172:9bc3c7b2cca1 562 {
andrewboyson 172:9bc3c7b2cca1 563 if (NrTrace)
andrewboyson 172:9bc3c7b2cca1 564 {
andrewboyson 172:9bc3c7b2cca1 565 LogTimeF("NR - request for address of '");
andrewboyson 172:9bc3c7b2cca1 566 Log(pr->name);
andrewboyson 172:9bc3c7b2cca1 567 Log("' has timed out\r\n");
andrewboyson 172:9bc3c7b2cca1 568 Log("\r\n");
andrewboyson 172:9bc3c7b2cca1 569 }
andrewboyson 172:9bc3c7b2cca1 570 Ip6AddrClear(pr->address);
andrewboyson 172:9bc3c7b2cca1 571 }
andrewboyson 172:9bc3c7b2cca1 572 pr->todo = TODO_NONE;
andrewboyson 172:9bc3c7b2cca1 573 pr->state = STATE_VALID;
andrewboyson 172:9bc3c7b2cca1 574 pr->ageMs = MsTimerCount;
andrewboyson 172:9bc3c7b2cca1 575 }
andrewboyson 172:9bc3c7b2cca1 576 else
andrewboyson 172:9bc3c7b2cca1 577 {
andrewboyson 172:9bc3c7b2cca1 578 pr->state = STATE_WAIT_FOR_ETH;
andrewboyson 172:9bc3c7b2cca1 579 }
andrewboyson 172:9bc3c7b2cca1 580 break;
andrewboyson 172:9bc3c7b2cca1 581 case STATE_WAIT_FOR_ETH:
andrewboyson 172:9bc3c7b2cca1 582 if (!DnsQueryIsBusy)
andrewboyson 172:9bc3c7b2cca1 583 {
andrewboyson 172:9bc3c7b2cca1 584 switch (pr->todo)
andrewboyson 172:9bc3c7b2cca1 585 {
andrewboyson 172:9bc3c7b2cca1 586 case TODO_NAME_FROM_ADDRESS: queryNameFromIp(pr ); break;
andrewboyson 172:9bc3c7b2cca1 587 case TODO_ADDRESS4_FROM_NAME: queryIpFromName(pr, TODO_ADDRESS4_FROM_NAME); break;
andrewboyson 172:9bc3c7b2cca1 588 case TODO_ADDRESS6_FROM_NAME: queryIpFromName(pr, TODO_ADDRESS6_FROM_NAME); 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 172:9bc3c7b2cca1 614 }
andrewboyson 172:9bc3c7b2cca1 615 void NrInit()
andrewboyson 172:9bc3c7b2cca1 616 {
andrewboyson 172:9bc3c7b2cca1 617 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 172:9bc3c7b2cca1 618 }