Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Dec 09 18:11:05 2020 +0000
Revision:
170:96c637dc3f52
Parent:
167:3ba4e3c49631
Child:
171:f708d6776752
Tidied up mdns messages

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3 #include <string.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 60:1d8c7a1e7483 5 #include "log.h"
andrewboyson 93:580fc113d9e9 6 #include "mstimer.h"
andrewboyson 60:1d8c7a1e7483 7 #include "net.h"
andrewboyson 60:1d8c7a1e7483 8 #include "mac.h"
andrewboyson 60:1d8c7a1e7483 9 #include "ip6addr.h"
andrewboyson 128:79052cb4a41c 10 #include "dhcp.h"
andrewboyson 60:1d8c7a1e7483 11 #include "dns.h"
andrewboyson 60:1d8c7a1e7483 12 #include "dnsquery.h"
andrewboyson 128:79052cb4a41c 13 #include "dnslabel.h"
andrewboyson 60:1d8c7a1e7483 14 #include "http.h"
andrewboyson 60:1d8c7a1e7483 15
andrewboyson 60:1d8c7a1e7483 16 bool Nr6Trace = false;
andrewboyson 60:1d8c7a1e7483 17
andrewboyson 93:580fc113d9e9 18 #define NAME_MAX_LENGTH 20
andrewboyson 170:96c637dc3f52 19 #define CACHE_TIMEOUT_MS 3600 * 1000
andrewboyson 170:96c637dc3f52 20 #define STALE_TIMEOUT_MS 1800 * 1000
andrewboyson 170:96c637dc3f52 21 #define EMPTY_TIMEOUT_MS 5 * 1000
andrewboyson 170:96c637dc3f52 22 #define REPLY_TIMEOUT_MS 1 * 1000
andrewboyson 60:1d8c7a1e7483 23
andrewboyson 60:1d8c7a1e7483 24 #define RECORDS_COUNT 20
andrewboyson 60:1d8c7a1e7483 25
andrewboyson 60:1d8c7a1e7483 26 #define STATE_EMPTY 0
andrewboyson 60:1d8c7a1e7483 27 #define STATE_WANT 1
andrewboyson 60:1d8c7a1e7483 28 #define STATE_SENT 2
andrewboyson 60:1d8c7a1e7483 29 #define STATE_VALID 3
andrewboyson 60:1d8c7a1e7483 30
andrewboyson 60:1d8c7a1e7483 31 #define TODO_NONE 0
andrewboyson 60:1d8c7a1e7483 32 #define TODO_NAME_FROM_IP 1
andrewboyson 60:1d8c7a1e7483 33 #define TODO_IP_FROM_NAME 2
andrewboyson 60:1d8c7a1e7483 34
andrewboyson 60:1d8c7a1e7483 35 struct record
andrewboyson 60:1d8c7a1e7483 36 {
andrewboyson 60:1d8c7a1e7483 37 uint32_t elapsed;
andrewboyson 60:1d8c7a1e7483 38 char ip[16];
andrewboyson 60:1d8c7a1e7483 39 uint8_t todo;
andrewboyson 60:1d8c7a1e7483 40 uint8_t state;
andrewboyson 60:1d8c7a1e7483 41 uint8_t protocol;
andrewboyson 60:1d8c7a1e7483 42 char name[NAME_MAX_LENGTH];
andrewboyson 60:1d8c7a1e7483 43 };
andrewboyson 60:1d8c7a1e7483 44 static struct record records[RECORDS_COUNT];
andrewboyson 60:1d8c7a1e7483 45
andrewboyson 60:1d8c7a1e7483 46 static int getExistingIp(char* ip)
andrewboyson 60:1d8c7a1e7483 47 {
andrewboyson 60:1d8c7a1e7483 48 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 49 {
andrewboyson 60:1d8c7a1e7483 50 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 60:1d8c7a1e7483 51 if (Ip6AddressIsSame(records[i].ip, ip)) return i;
andrewboyson 60:1d8c7a1e7483 52 }
andrewboyson 60:1d8c7a1e7483 53 return -1;
andrewboyson 60:1d8c7a1e7483 54 }
andrewboyson 60:1d8c7a1e7483 55 static int getExistingName(char* name)
andrewboyson 60:1d8c7a1e7483 56 {
andrewboyson 60:1d8c7a1e7483 57 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 58 {
andrewboyson 60:1d8c7a1e7483 59 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 128:79052cb4a41c 60 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 60:1d8c7a1e7483 61 }
andrewboyson 60:1d8c7a1e7483 62 return -1;
andrewboyson 60:1d8c7a1e7483 63 }
andrewboyson 60:1d8c7a1e7483 64 static int getNameOnly(char* name)
andrewboyson 60:1d8c7a1e7483 65 {
andrewboyson 60:1d8c7a1e7483 66 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 67 {
andrewboyson 60:1d8c7a1e7483 68 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 60:1d8c7a1e7483 69 if (!Ip6AddressIsEmpty(records[i].ip)) continue;
andrewboyson 128:79052cb4a41c 70 if (DnsLabelIsSame(records[i].name, name)) return i;
andrewboyson 60:1d8c7a1e7483 71 }
andrewboyson 60:1d8c7a1e7483 72 return -1;
andrewboyson 60:1d8c7a1e7483 73 }
andrewboyson 170:96c637dc3f52 74 static int getIpOnly(char* ip)
andrewboyson 170:96c637dc3f52 75 {
andrewboyson 170:96c637dc3f52 76 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 170:96c637dc3f52 77 {
andrewboyson 170:96c637dc3f52 78 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 170:96c637dc3f52 79 if (records[i].name[0] != 0) continue;
andrewboyson 170:96c637dc3f52 80 if (Ip6AddressIsSame(records[i].ip, ip)) return i;
andrewboyson 170:96c637dc3f52 81 }
andrewboyson 170:96c637dc3f52 82 return -1;
andrewboyson 170:96c637dc3f52 83 }
andrewboyson 60:1d8c7a1e7483 84 static int getOldest()
andrewboyson 60:1d8c7a1e7483 85 {
andrewboyson 93:580fc113d9e9 86 int iOldest = 0;
andrewboyson 93:580fc113d9e9 87 uint32_t ageOldest = 0;
andrewboyson 60:1d8c7a1e7483 88 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 89 {
andrewboyson 60:1d8c7a1e7483 90 if (records[i].state == STATE_EMPTY) return i; //Found an empty slot so just return it
andrewboyson 93:580fc113d9e9 91 uint32_t age = MsTimerCount - records[i].elapsed;
andrewboyson 93:580fc113d9e9 92 if (age >= ageOldest)
andrewboyson 60:1d8c7a1e7483 93 {
andrewboyson 93:580fc113d9e9 94 ageOldest = age;
andrewboyson 93:580fc113d9e9 95 iOldest = i;
andrewboyson 60:1d8c7a1e7483 96 }
andrewboyson 60:1d8c7a1e7483 97 }
andrewboyson 93:580fc113d9e9 98 return iOldest; //Otherwise return the oldest
andrewboyson 60:1d8c7a1e7483 99 }
andrewboyson 60:1d8c7a1e7483 100 void Nr6MakeRequestForNameFromIp(char* ip)
andrewboyson 60:1d8c7a1e7483 101 {
andrewboyson 60:1d8c7a1e7483 102 //Don't treat non ips
andrewboyson 60:1d8c7a1e7483 103 if (!ip[0]) return;
andrewboyson 60:1d8c7a1e7483 104 int i;
andrewboyson 60:1d8c7a1e7483 105
andrewboyson 60:1d8c7a1e7483 106 //If a record already exists then request an update
andrewboyson 60:1d8c7a1e7483 107 i = getExistingIp(ip);
andrewboyson 60:1d8c7a1e7483 108 if (i > -1)
andrewboyson 60:1d8c7a1e7483 109 {
andrewboyson 170:96c637dc3f52 110 if (records[i].name[0] == 0)
andrewboyson 170:96c637dc3f52 111 {
andrewboyson 170:96c637dc3f52 112 if (!MsTimerRelative(records[i].elapsed, EMPTY_TIMEOUT_MS)) return;
andrewboyson 170:96c637dc3f52 113 }
andrewboyson 170:96c637dc3f52 114 else
andrewboyson 170:96c637dc3f52 115 {
andrewboyson 170:96c637dc3f52 116 if (!MsTimerRelative(records[i].elapsed, STALE_TIMEOUT_MS)) return;
andrewboyson 170:96c637dc3f52 117 }
andrewboyson 60:1d8c7a1e7483 118 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 119 {
andrewboyson 60:1d8c7a1e7483 120 LogTimeF("NR - renew name of ");
andrewboyson 60:1d8c7a1e7483 121 Ip6AddressLog(ip);
andrewboyson 60:1d8c7a1e7483 122 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 123 }
andrewboyson 60:1d8c7a1e7483 124 records[i].todo = TODO_NAME_FROM_IP;
andrewboyson 60:1d8c7a1e7483 125 records[i].state = STATE_WANT;
andrewboyson 170:96c637dc3f52 126 records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
andrewboyson 93:580fc113d9e9 127 records[i].elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 128 return;
andrewboyson 60:1d8c7a1e7483 129 }
andrewboyson 60:1d8c7a1e7483 130
andrewboyson 60:1d8c7a1e7483 131 //If a record does not exist then find the first empty slot and add the IP and date
andrewboyson 60:1d8c7a1e7483 132 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 133 {
andrewboyson 60:1d8c7a1e7483 134 LogTimeF("NR - request name of ");
andrewboyson 60:1d8c7a1e7483 135 Ip6AddressLog(ip);
andrewboyson 60:1d8c7a1e7483 136 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 137 }
andrewboyson 60:1d8c7a1e7483 138 i = getOldest();
andrewboyson 60:1d8c7a1e7483 139 Ip6AddressCopy(records[i].ip, ip);
andrewboyson 60:1d8c7a1e7483 140 records[i].todo = TODO_NAME_FROM_IP;
andrewboyson 60:1d8c7a1e7483 141 records[i].state = STATE_WANT;
andrewboyson 170:96c637dc3f52 142 records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
andrewboyson 93:580fc113d9e9 143 records[i].elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 144 records[i].name[0] = 0;
andrewboyson 60:1d8c7a1e7483 145 }
andrewboyson 60:1d8c7a1e7483 146 void Nr6MakeRequestForIpFromName(char* name)
andrewboyson 60:1d8c7a1e7483 147 {
andrewboyson 60:1d8c7a1e7483 148 //Don't treat non names
andrewboyson 60:1d8c7a1e7483 149 if (!name[0]) return;
andrewboyson 60:1d8c7a1e7483 150 int i;
andrewboyson 60:1d8c7a1e7483 151
andrewboyson 60:1d8c7a1e7483 152 //If a record already exists then request an update
andrewboyson 60:1d8c7a1e7483 153 i = getExistingName(name);
andrewboyson 60:1d8c7a1e7483 154 if (i > -1)
andrewboyson 60:1d8c7a1e7483 155 {
andrewboyson 170:96c637dc3f52 156 if (Ip6AddressIsEmpty(records[i].ip))
andrewboyson 170:96c637dc3f52 157 {
andrewboyson 170:96c637dc3f52 158 if (!MsTimerRelative(records[i].elapsed, EMPTY_TIMEOUT_MS)) return;
andrewboyson 170:96c637dc3f52 159 }
andrewboyson 170:96c637dc3f52 160 else
andrewboyson 170:96c637dc3f52 161 {
andrewboyson 170:96c637dc3f52 162 if (!MsTimerRelative(records[i].elapsed, STALE_TIMEOUT_MS)) return;
andrewboyson 170:96c637dc3f52 163 }
andrewboyson 60:1d8c7a1e7483 164 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 165 {
andrewboyson 60:1d8c7a1e7483 166 LogTimeF("NR - renew IPv6 of %s\r\n", name);
andrewboyson 60:1d8c7a1e7483 167 }
andrewboyson 60:1d8c7a1e7483 168 records[i].todo = TODO_IP_FROM_NAME;
andrewboyson 60:1d8c7a1e7483 169 records[i].state = STATE_WANT;
andrewboyson 170:96c637dc3f52 170 records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
andrewboyson 93:580fc113d9e9 171 records[i].elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 172 return;
andrewboyson 60:1d8c7a1e7483 173 }
andrewboyson 60:1d8c7a1e7483 174
andrewboyson 60:1d8c7a1e7483 175 //If a record does not exist then find the first empty slot and add the name and date
andrewboyson 60:1d8c7a1e7483 176 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 177 {
andrewboyson 60:1d8c7a1e7483 178 LogTimeF("NR - request IPv6 of %s\r\n", name);
andrewboyson 60:1d8c7a1e7483 179 }
andrewboyson 60:1d8c7a1e7483 180 i = getOldest();
andrewboyson 60:1d8c7a1e7483 181 records[i].ip[0] = 0;
andrewboyson 60:1d8c7a1e7483 182 records[i].todo = TODO_IP_FROM_NAME;
andrewboyson 60:1d8c7a1e7483 183 records[i].state = STATE_WANT;
andrewboyson 170:96c637dc3f52 184 records[i].protocol = DnsGetNextProtocol(DNS_PROTOCOL_NONE);
andrewboyson 93:580fc113d9e9 185 records[i].elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 186 strncpy(records[i].name, name, NAME_MAX_LENGTH);
andrewboyson 60:1d8c7a1e7483 187 records[i].name[NAME_MAX_LENGTH - 1] = 0;
andrewboyson 60:1d8c7a1e7483 188 }
andrewboyson 60:1d8c7a1e7483 189 static void addIpRecord(int i, char* ip, char* name, int protocol)
andrewboyson 60:1d8c7a1e7483 190 {
andrewboyson 60:1d8c7a1e7483 191 records[i].todo = TODO_NONE;
andrewboyson 93:580fc113d9e9 192 records[i].elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 193 Ip6AddressCopy(records[i].ip, ip);
andrewboyson 60:1d8c7a1e7483 194 records[i].protocol = protocol;
andrewboyson 60:1d8c7a1e7483 195 records[i].state = STATE_VALID;
andrewboyson 60:1d8c7a1e7483 196 strncpy(records[i].name, name, NAME_MAX_LENGTH);
andrewboyson 60:1d8c7a1e7483 197 records[i].name[NAME_MAX_LENGTH - 1] = 0;
andrewboyson 60:1d8c7a1e7483 198 }
andrewboyson 60:1d8c7a1e7483 199 void Nr6AddIpRecord(char* ip, char* name, int protocol)
andrewboyson 60:1d8c7a1e7483 200 {
andrewboyson 60:1d8c7a1e7483 201 int i;
andrewboyson 60:1d8c7a1e7483 202
andrewboyson 170:96c637dc3f52 203 //Print what is being handled
andrewboyson 170:96c637dc3f52 204 if (Nr6Trace)
andrewboyson 170:96c637dc3f52 205 {
andrewboyson 170:96c637dc3f52 206 LogTimeF("NR - received response ");
andrewboyson 170:96c637dc3f52 207 Ip6AddressLog(ip);
andrewboyson 170:96c637dc3f52 208 Log(" == '");
andrewboyson 170:96c637dc3f52 209 Log(name);
andrewboyson 170:96c637dc3f52 210 Log("'\r\n");
andrewboyson 170:96c637dc3f52 211 }
andrewboyson 170:96c637dc3f52 212
andrewboyson 170:96c637dc3f52 213 //Ignore records which do not have both ip and name
andrewboyson 170:96c637dc3f52 214 if (Ip6AddressIsEmpty(ip) || name == 0 || name[0] == 0)
andrewboyson 170:96c637dc3f52 215 {
andrewboyson 170:96c637dc3f52 216 if (Nr6Trace) LogTimeF("NR - ignoring unresolved response\r\n");
andrewboyson 170:96c637dc3f52 217 return;
andrewboyson 170:96c637dc3f52 218 }
andrewboyson 170:96c637dc3f52 219
andrewboyson 60:1d8c7a1e7483 220 //Get existing ip and, if found, add it then clear any name only entries
andrewboyson 60:1d8c7a1e7483 221 i = getExistingIp(ip);
andrewboyson 60:1d8c7a1e7483 222 if (i >= 0)
andrewboyson 60:1d8c7a1e7483 223 {
andrewboyson 60:1d8c7a1e7483 224 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 225 {
andrewboyson 170:96c637dc3f52 226 if (DnsLabelIsSame(name, records[i].name))
andrewboyson 170:96c637dc3f52 227 {
andrewboyson 170:96c637dc3f52 228 LogTimeF("NR record %d - confirm existing name for ", i);
andrewboyson 170:96c637dc3f52 229 Ip6AddressLog(ip);
andrewboyson 170:96c637dc3f52 230 Log(" is '");
andrewboyson 170:96c637dc3f52 231 Log(name);
andrewboyson 170:96c637dc3f52 232 Log("'\r\n");
andrewboyson 170:96c637dc3f52 233 }
andrewboyson 170:96c637dc3f52 234 else
andrewboyson 170:96c637dc3f52 235 {
andrewboyson 170:96c637dc3f52 236 LogTimeF("NR record %d - update name for ip ", i);
andrewboyson 170:96c637dc3f52 237 Ip6AddressLog(ip);
andrewboyson 170:96c637dc3f52 238 Log(" from '");
andrewboyson 170:96c637dc3f52 239 Log(records[i].name);
andrewboyson 170:96c637dc3f52 240 Log("' to '");
andrewboyson 170:96c637dc3f52 241 Log(name);
andrewboyson 170:96c637dc3f52 242 Log("'\r\n");
andrewboyson 170:96c637dc3f52 243 }
andrewboyson 60:1d8c7a1e7483 244 }
andrewboyson 60:1d8c7a1e7483 245 addIpRecord(i, ip, name, protocol);
andrewboyson 60:1d8c7a1e7483 246
andrewboyson 60:1d8c7a1e7483 247 i = getNameOnly(name);
andrewboyson 60:1d8c7a1e7483 248 if (i >= 0)
andrewboyson 60:1d8c7a1e7483 249 {
andrewboyson 170:96c637dc3f52 250 if (Nr6Trace) LogTimeF("NR record %d - clear name '%s' with no ip\r\n", i, name);
andrewboyson 60:1d8c7a1e7483 251 records[i].state = STATE_EMPTY;
andrewboyson 60:1d8c7a1e7483 252 }
andrewboyson 60:1d8c7a1e7483 253 return;
andrewboyson 60:1d8c7a1e7483 254 }
andrewboyson 60:1d8c7a1e7483 255
andrewboyson 60:1d8c7a1e7483 256 //Get name only entry and, if found, add it
andrewboyson 60:1d8c7a1e7483 257 i = getNameOnly(name);
andrewboyson 60:1d8c7a1e7483 258 if (i >= 0)
andrewboyson 60:1d8c7a1e7483 259 {
andrewboyson 60:1d8c7a1e7483 260 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 261 {
andrewboyson 170:96c637dc3f52 262 LogTimeF("NR record %d - update ip for name", i);
andrewboyson 170:96c637dc3f52 263 Log(name);
andrewboyson 170:96c637dc3f52 264 Log(" from ");
andrewboyson 60:1d8c7a1e7483 265 Ip6AddressLog(ip);
andrewboyson 170:96c637dc3f52 266 Log(" to ");
andrewboyson 170:96c637dc3f52 267 Ip6AddressLog(records[i].ip);
andrewboyson 170:96c637dc3f52 268 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 269 }
andrewboyson 60:1d8c7a1e7483 270 addIpRecord(i, ip, name, protocol);
andrewboyson 60:1d8c7a1e7483 271 return;
andrewboyson 60:1d8c7a1e7483 272 }
andrewboyson 60:1d8c7a1e7483 273
andrewboyson 60:1d8c7a1e7483 274 //No other entry exists so just add it to the next available space
andrewboyson 60:1d8c7a1e7483 275 i = getOldest();
andrewboyson 60:1d8c7a1e7483 276 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 277 {
andrewboyson 170:96c637dc3f52 278 LogTimeF("NR record %d - add entry for ", i);
andrewboyson 60:1d8c7a1e7483 279 Ip6AddressLog(ip);
andrewboyson 170:96c637dc3f52 280 Log(" == '");
andrewboyson 60:1d8c7a1e7483 281 Log(name);
andrewboyson 60:1d8c7a1e7483 282 Log("'\r\n");
andrewboyson 60:1d8c7a1e7483 283 }
andrewboyson 60:1d8c7a1e7483 284 addIpRecord(i, ip, name, protocol);
andrewboyson 60:1d8c7a1e7483 285 }
andrewboyson 60:1d8c7a1e7483 286 void Nr6IpToName(char* ip, char* name)
andrewboyson 60:1d8c7a1e7483 287 {
andrewboyson 60:1d8c7a1e7483 288 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 289 {
andrewboyson 60:1d8c7a1e7483 290 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 60:1d8c7a1e7483 291 if (Ip6AddressIsSame(records[i].ip, ip))
andrewboyson 60:1d8c7a1e7483 292 {
andrewboyson 60:1d8c7a1e7483 293 strcpy(name, records[i].name);
andrewboyson 60:1d8c7a1e7483 294 return;
andrewboyson 60:1d8c7a1e7483 295 }
andrewboyson 60:1d8c7a1e7483 296 }
andrewboyson 60:1d8c7a1e7483 297 name[0] = 0;
andrewboyson 60:1d8c7a1e7483 298 }
andrewboyson 60:1d8c7a1e7483 299 void Nr6NameToIp(char* name, char* ip)
andrewboyson 60:1d8c7a1e7483 300 {
andrewboyson 93:580fc113d9e9 301 uint32_t newest = 0xFFFFFFFF;
andrewboyson 60:1d8c7a1e7483 302 Ip6AddressClear(ip);
andrewboyson 60:1d8c7a1e7483 303 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 304 {
andrewboyson 60:1d8c7a1e7483 305 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 60:1d8c7a1e7483 306 if(Ip6AddressIsEmpty(records[i].ip)) continue;
andrewboyson 128:79052cb4a41c 307 if (!DnsLabelIsSame(records[i].name, name)) continue;
andrewboyson 93:580fc113d9e9 308 uint32_t age = MsTimerCount - records[i].elapsed;
andrewboyson 93:580fc113d9e9 309 if (age <= newest)
andrewboyson 60:1d8c7a1e7483 310 {
andrewboyson 93:580fc113d9e9 311 newest = age;
andrewboyson 60:1d8c7a1e7483 312 Ip6AddressCopy(ip, records[i].ip);
andrewboyson 60:1d8c7a1e7483 313 }
andrewboyson 60:1d8c7a1e7483 314 }
andrewboyson 60:1d8c7a1e7483 315 }
andrewboyson 116:60521b29e4c9 316 bool Nr6HaveIpForName(char* name)
andrewboyson 116:60521b29e4c9 317 {
andrewboyson 116:60521b29e4c9 318 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 116:60521b29e4c9 319 {
andrewboyson 116:60521b29e4c9 320 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 116:60521b29e4c9 321 if(Ip6AddressIsEmpty(records[i].ip)) continue;
andrewboyson 128:79052cb4a41c 322 if (!DnsLabelIsSame(records[i].name, name)) return true;
andrewboyson 116:60521b29e4c9 323 }
andrewboyson 116:60521b29e4c9 324 return false;
andrewboyson 116:60521b29e4c9 325 }
andrewboyson 60:1d8c7a1e7483 326 static char letterFromStateAndProtocol(uint8_t dnsState, uint8_t protocol)
andrewboyson 60:1d8c7a1e7483 327 {
andrewboyson 60:1d8c7a1e7483 328 switch (dnsState)
andrewboyson 60:1d8c7a1e7483 329 {
andrewboyson 60:1d8c7a1e7483 330 case STATE_WANT:
andrewboyson 60:1d8c7a1e7483 331 case STATE_SENT: return '>';
andrewboyson 60:1d8c7a1e7483 332
andrewboyson 60:1d8c7a1e7483 333 case STATE_VALID:
andrewboyson 60:1d8c7a1e7483 334 switch (protocol)
andrewboyson 60:1d8c7a1e7483 335 {
andrewboyson 60:1d8c7a1e7483 336 case DNS_PROTOCOL_UDNS: return 'd';
andrewboyson 60:1d8c7a1e7483 337 case DNS_PROTOCOL_MDNS: return 'm';
andrewboyson 60:1d8c7a1e7483 338 case DNS_PROTOCOL_LLMNR: return 'l';
andrewboyson 60:1d8c7a1e7483 339 case DNS_PROTOCOL_NONE: return '-';
andrewboyson 60:1d8c7a1e7483 340 default: return '?';
andrewboyson 60:1d8c7a1e7483 341 }
andrewboyson 60:1d8c7a1e7483 342 default: return '~';
andrewboyson 60:1d8c7a1e7483 343 }
andrewboyson 60:1d8c7a1e7483 344 }
andrewboyson 60:1d8c7a1e7483 345 void Nr6SendHttp()
andrewboyson 60:1d8c7a1e7483 346 {
andrewboyson 60:1d8c7a1e7483 347 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 60:1d8c7a1e7483 348 {
andrewboyson 60:1d8c7a1e7483 349 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 60:1d8c7a1e7483 350 if (!Ip6AddressIsEmpty(records[i].ip) || records[i].name[0])
andrewboyson 60:1d8c7a1e7483 351 {
andrewboyson 93:580fc113d9e9 352 HttpAddF("%4u ", (MsTimerCount - records[i].elapsed) / 1000 / 60);
andrewboyson 60:1d8c7a1e7483 353
andrewboyson 60:1d8c7a1e7483 354 int ipLen = Ip6AddressHttp(records[i].ip);
andrewboyson 159:3ebef2d02f7f 355 HttpAddFillChar(' ', 40 - ipLen);
andrewboyson 60:1d8c7a1e7483 356
andrewboyson 60:1d8c7a1e7483 357 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].protocol));
andrewboyson 60:1d8c7a1e7483 358
andrewboyson 60:1d8c7a1e7483 359 HttpAddChar(' ');
andrewboyson 60:1d8c7a1e7483 360
andrewboyson 60:1d8c7a1e7483 361 HttpAddText(records[i].name);
andrewboyson 60:1d8c7a1e7483 362
andrewboyson 60:1d8c7a1e7483 363 HttpAddChar('\r');
andrewboyson 60:1d8c7a1e7483 364 HttpAddChar('\n');
andrewboyson 60:1d8c7a1e7483 365 }
andrewboyson 60:1d8c7a1e7483 366 }
andrewboyson 60:1d8c7a1e7483 367 }
andrewboyson 140:9000ea70b220 368 void Nr6SendAjax()
andrewboyson 140:9000ea70b220 369 {
andrewboyson 140:9000ea70b220 370 for (int i = 0; i < RECORDS_COUNT; i++)
andrewboyson 140:9000ea70b220 371 {
andrewboyson 140:9000ea70b220 372 if (records[i].state == STATE_EMPTY) continue;
andrewboyson 140:9000ea70b220 373 if (!Ip6AddressIsEmpty(records[i].ip) || records[i].name[0])
andrewboyson 140:9000ea70b220 374 {
andrewboyson 167:3ba4e3c49631 375 HttpAddByteAsHex(i);
andrewboyson 167:3ba4e3c49631 376 HttpAddChar('\t');
andrewboyson 140:9000ea70b220 377 HttpAddInt32AsHex(MsTimerCount - records[i].elapsed);
andrewboyson 167:3ba4e3c49631 378 HttpAddChar('\t');
andrewboyson 140:9000ea70b220 379 for (int b = 0; b < 16; b++) HttpAddByteAsHex(records[i].ip[b]);
andrewboyson 167:3ba4e3c49631 380 HttpAddChar('\t');
andrewboyson 140:9000ea70b220 381 HttpAddChar(letterFromStateAndProtocol(records[i].state, records[i].protocol));
andrewboyson 167:3ba4e3c49631 382 HttpAddChar('\t');
andrewboyson 140:9000ea70b220 383 HttpAddText(records[i].name);
andrewboyson 140:9000ea70b220 384 HttpAddChar('\n');
andrewboyson 140:9000ea70b220 385 }
andrewboyson 140:9000ea70b220 386 }
andrewboyson 140:9000ea70b220 387 }
andrewboyson 60:1d8c7a1e7483 388 static void clearCache(struct record* pr)
andrewboyson 60:1d8c7a1e7483 389 {
andrewboyson 133:a37eb35a03f1 390 if (MsTimerRelative(pr->elapsed, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 60:1d8c7a1e7483 391 }
andrewboyson 60:1d8c7a1e7483 392 static void nextProtocol(struct record* pr)
andrewboyson 60:1d8c7a1e7483 393 {
andrewboyson 133:a37eb35a03f1 394 if (pr->state == STATE_SENT && MsTimerRelative(pr->elapsed, REPLY_TIMEOUT_MS) && pr->protocol)
andrewboyson 60:1d8c7a1e7483 395 {
andrewboyson 170:96c637dc3f52 396 pr->protocol = DnsGetNextProtocol(pr->protocol);
andrewboyson 60:1d8c7a1e7483 397 if (pr->protocol)
andrewboyson 60:1d8c7a1e7483 398 {
andrewboyson 60:1d8c7a1e7483 399 pr->state = STATE_WANT;
andrewboyson 60:1d8c7a1e7483 400 }
andrewboyson 60:1d8c7a1e7483 401 else
andrewboyson 60:1d8c7a1e7483 402 {
andrewboyson 60:1d8c7a1e7483 403 if (pr->todo == TODO_NAME_FROM_IP) pr->name[0] = 0;
andrewboyson 60:1d8c7a1e7483 404 if (pr->todo == TODO_IP_FROM_NAME) Ip6AddressClear(pr->ip);
andrewboyson 60:1d8c7a1e7483 405 pr->state = STATE_VALID;
andrewboyson 60:1d8c7a1e7483 406 }
andrewboyson 93:580fc113d9e9 407 pr->elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 408 }
andrewboyson 60:1d8c7a1e7483 409 }
andrewboyson 60:1d8c7a1e7483 410 static void queryNameFromIp(struct record* pr)
andrewboyson 60:1d8c7a1e7483 411 {
andrewboyson 60:1d8c7a1e7483 412 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 413 {
andrewboyson 60:1d8c7a1e7483 414 LogTime("NR - send ");
andrewboyson 60:1d8c7a1e7483 415 DnsProtocolLog(pr->protocol);
andrewboyson 60:1d8c7a1e7483 416 Log(" request for name from IP6 ");
andrewboyson 60:1d8c7a1e7483 417 Ip6AddressLog(pr->ip);
andrewboyson 60:1d8c7a1e7483 418 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 419 }
andrewboyson 60:1d8c7a1e7483 420 DnsQueryNameFromIp6(pr->ip, pr->protocol);
andrewboyson 60:1d8c7a1e7483 421 }
andrewboyson 60:1d8c7a1e7483 422 static void queryIpFromName(struct record* pr)
andrewboyson 60:1d8c7a1e7483 423 {
andrewboyson 60:1d8c7a1e7483 424 if (Nr6Trace)
andrewboyson 60:1d8c7a1e7483 425 {
andrewboyson 60:1d8c7a1e7483 426 LogTime("NR - send ");
andrewboyson 60:1d8c7a1e7483 427 DnsProtocolLog(pr->protocol);
andrewboyson 60:1d8c7a1e7483 428 Log(" request for IP6 from name '");
andrewboyson 60:1d8c7a1e7483 429 Log(pr->name);
andrewboyson 60:1d8c7a1e7483 430 Log("'\r\n");
andrewboyson 60:1d8c7a1e7483 431 }
andrewboyson 60:1d8c7a1e7483 432 DnsQueryIp6FromName(pr->name, pr->protocol);
andrewboyson 60:1d8c7a1e7483 433 }
andrewboyson 60:1d8c7a1e7483 434 static void sendRequest(struct record* pr)
andrewboyson 60:1d8c7a1e7483 435 {
andrewboyson 60:1d8c7a1e7483 436 if ( DnsQueryIsBusy ) return;
andrewboyson 60:1d8c7a1e7483 437 if ( pr->state != STATE_WANT) return;
andrewboyson 60:1d8c7a1e7483 438 if (!pr->protocol ) return;
andrewboyson 60:1d8c7a1e7483 439
andrewboyson 60:1d8c7a1e7483 440 if (pr->todo == TODO_NAME_FROM_IP) queryNameFromIp(pr);
andrewboyson 60:1d8c7a1e7483 441 if (pr->todo == TODO_IP_FROM_NAME) queryIpFromName(pr);
andrewboyson 60:1d8c7a1e7483 442
andrewboyson 60:1d8c7a1e7483 443 pr->state = STATE_SENT;
andrewboyson 93:580fc113d9e9 444 pr->elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 445 }
andrewboyson 60:1d8c7a1e7483 446 void Nr6Main()
andrewboyson 60:1d8c7a1e7483 447 {
andrewboyson 60:1d8c7a1e7483 448 static int i = -1;
andrewboyson 60:1d8c7a1e7483 449 i++;
andrewboyson 60:1d8c7a1e7483 450 if (i >= RECORDS_COUNT) i = 0;
andrewboyson 60:1d8c7a1e7483 451
andrewboyson 60:1d8c7a1e7483 452 struct record* pr = &records[i];
andrewboyson 60:1d8c7a1e7483 453
andrewboyson 60:1d8c7a1e7483 454 clearCache (pr);
andrewboyson 60:1d8c7a1e7483 455 nextProtocol(pr);
andrewboyson 60:1d8c7a1e7483 456 sendRequest (pr);
andrewboyson 60:1d8c7a1e7483 457 }
andrewboyson 60:1d8c7a1e7483 458 void Nr6Init()
andrewboyson 60:1d8c7a1e7483 459 {
andrewboyson 60:1d8c7a1e7483 460 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 60:1d8c7a1e7483 461 }