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 Apr 02 19:08:25 2020 +0000
Revision:
167:3ba4e3c49631
Parent:
159:3ebef2d02f7f
Child:
170:96c637dc3f52
Modified resolution cache ajaxs to include the index

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