Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon Mar 11 16:42:45 2019 +0000
Revision:
128:79052cb4a41c
Parent:
116:60521b29e4c9
Child:
132:db2174b36a6d
Tidied up the DNS label module and removed some declarations that had not left room for the terminating null.

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 "ip4addr.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 Nr4Trace = 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 uint32_t ip;
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(uint32_t 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 (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 (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 Nr4MakeRequestForNameFromIp(uint32_t ip)
andrewboyson 60:1d8c7a1e7483 90 {
andrewboyson 60:1d8c7a1e7483 91 //Don't treat non ips
andrewboyson 60:1d8c7a1e7483 92 if (!ip) 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 93:580fc113d9e9 99 if (!MsTimerHasElapsed(records[i].elapsed, FREEZE_TIMEOUT_MS)) return;
andrewboyson 60:1d8c7a1e7483 100 if (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 101 {
andrewboyson 60:1d8c7a1e7483 102 LogTimeF("NR - renew name of ");
andrewboyson 60:1d8c7a1e7483 103 Ip4AddressLog(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 = DnsGetNextProtocol4(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 (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 115 {
andrewboyson 60:1d8c7a1e7483 116 LogTimeF("NR - request name of ");
andrewboyson 60:1d8c7a1e7483 117 Ip4AddressLog(ip);
andrewboyson 60:1d8c7a1e7483 118 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 119 }
andrewboyson 60:1d8c7a1e7483 120 i = getOldest();
andrewboyson 60:1d8c7a1e7483 121 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 = DnsGetNextProtocol4(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 Nr4MakeRequestForIpFromName(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 93:580fc113d9e9 138 if (!MsTimerHasElapsed(records[i].elapsed, FREEZE_TIMEOUT_MS)) return;
andrewboyson 60:1d8c7a1e7483 139 if (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 140 {
andrewboyson 60:1d8c7a1e7483 141 LogTimeF("NR - renew IPv4 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 = DnsGetNextProtocol4(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 (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 152 {
andrewboyson 60:1d8c7a1e7483 153 LogTimeF("NR - request IPv4 of %s\r\n", name);
andrewboyson 60:1d8c7a1e7483 154 }
andrewboyson 60:1d8c7a1e7483 155 i = getOldest();
andrewboyson 60:1d8c7a1e7483 156 records[i].ip = 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 = DnsGetNextProtocol4(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, uint32_t 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 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 Nr4AddIpRecord(uint32_t 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 (Nr4Trace)
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 Ip4AddressLog(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 (Nr4Trace) 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 (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 207 {
andrewboyson 60:1d8c7a1e7483 208 LogTimeF("NR - add ip for name ");
andrewboyson 60:1d8c7a1e7483 209 Ip4AddressLog(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 (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 221 {
andrewboyson 60:1d8c7a1e7483 222 LogTimeF("NR - add ip for name ");
andrewboyson 60:1d8c7a1e7483 223 Ip4AddressLog(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 Nr4IpToName(uint32_t 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 (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 Nr4NameToIp(char* name, uint32_t* pIp)
andrewboyson 60:1d8c7a1e7483 244 {
andrewboyson 93:580fc113d9e9 245 uint32_t newest = 0xFFFFFFFF;
andrewboyson 60:1d8c7a1e7483 246 *pIp = 0;
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 (!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 *pIp = records[i].ip;
andrewboyson 60:1d8c7a1e7483 257 }
andrewboyson 60:1d8c7a1e7483 258 }
andrewboyson 60:1d8c7a1e7483 259 }
andrewboyson 116:60521b29e4c9 260 bool Nr4HaveIpForName(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 (!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_SENT:
andrewboyson 60:1d8c7a1e7483 275 case STATE_WANT: 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 Nr4SendHttp()
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 (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 = Ip4AddressHttp(records[i].ip);
andrewboyson 60:1d8c7a1e7483 299 HttpFillChar(' ', 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 60:1d8c7a1e7483 312 static void clearCache(struct record* pr)
andrewboyson 60:1d8c7a1e7483 313 {
andrewboyson 93:580fc113d9e9 314 if (MsTimerHasElapsed(pr->elapsed, CACHE_TIMEOUT_MS)) pr->state = STATE_EMPTY;
andrewboyson 60:1d8c7a1e7483 315 }
andrewboyson 60:1d8c7a1e7483 316 static void nextProtocol(struct record* pr)
andrewboyson 60:1d8c7a1e7483 317 {
andrewboyson 93:580fc113d9e9 318 if (pr->state == STATE_SENT && MsTimerHasElapsed(pr->elapsed, REPLY_TIMEOUT_MS) && pr->protocol)
andrewboyson 60:1d8c7a1e7483 319 {
andrewboyson 60:1d8c7a1e7483 320 pr->protocol = DnsGetNextProtocol4(pr->protocol);
andrewboyson 60:1d8c7a1e7483 321 if (pr->protocol)
andrewboyson 60:1d8c7a1e7483 322 {
andrewboyson 60:1d8c7a1e7483 323 pr->state = STATE_WANT;
andrewboyson 60:1d8c7a1e7483 324 }
andrewboyson 60:1d8c7a1e7483 325 else
andrewboyson 60:1d8c7a1e7483 326 {
andrewboyson 60:1d8c7a1e7483 327 if (pr->todo == TODO_NAME_FROM_IP) pr->name[0] = 0;
andrewboyson 60:1d8c7a1e7483 328 if (pr->todo == TODO_IP_FROM_NAME) pr->ip = 0;
andrewboyson 60:1d8c7a1e7483 329 pr->state = STATE_VALID;
andrewboyson 60:1d8c7a1e7483 330 }
andrewboyson 93:580fc113d9e9 331 pr->elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 332 }
andrewboyson 60:1d8c7a1e7483 333 }
andrewboyson 60:1d8c7a1e7483 334 static void queryNameFromIp(struct record* pr)
andrewboyson 60:1d8c7a1e7483 335 {
andrewboyson 60:1d8c7a1e7483 336 if (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 337 {
andrewboyson 60:1d8c7a1e7483 338 LogTime("NR - send ");
andrewboyson 60:1d8c7a1e7483 339 DnsProtocolLog(pr->protocol);
andrewboyson 60:1d8c7a1e7483 340 Log(" request for name from IP4 ");
andrewboyson 60:1d8c7a1e7483 341 Ip4AddressLog(pr->ip);
andrewboyson 60:1d8c7a1e7483 342 Log("\r\n");
andrewboyson 60:1d8c7a1e7483 343 }
andrewboyson 60:1d8c7a1e7483 344 DnsQueryNameFromIp4(pr->ip, pr->protocol);
andrewboyson 60:1d8c7a1e7483 345 }
andrewboyson 60:1d8c7a1e7483 346 static void queryIpFromName(struct record* pr)
andrewboyson 60:1d8c7a1e7483 347 {
andrewboyson 60:1d8c7a1e7483 348 if (Nr4Trace)
andrewboyson 60:1d8c7a1e7483 349 {
andrewboyson 60:1d8c7a1e7483 350 LogTime("NR - send ");
andrewboyson 60:1d8c7a1e7483 351 DnsProtocolLog(pr->protocol);
andrewboyson 60:1d8c7a1e7483 352 Log(" request for IP4 from name '");
andrewboyson 60:1d8c7a1e7483 353 Log(pr->name);
andrewboyson 60:1d8c7a1e7483 354 Log("'\r\n");
andrewboyson 60:1d8c7a1e7483 355 }
andrewboyson 60:1d8c7a1e7483 356 DnsQueryIp4FromName(pr->name, pr->protocol);
andrewboyson 60:1d8c7a1e7483 357 }
andrewboyson 60:1d8c7a1e7483 358 static void sendRequest(struct record* pr)
andrewboyson 60:1d8c7a1e7483 359 {
andrewboyson 60:1d8c7a1e7483 360 if ( DnsQueryIsBusy ) return;
andrewboyson 60:1d8c7a1e7483 361 if ( pr->state != STATE_WANT) return;
andrewboyson 60:1d8c7a1e7483 362 if (!pr->protocol ) return;
andrewboyson 60:1d8c7a1e7483 363
andrewboyson 60:1d8c7a1e7483 364 if (pr->todo == TODO_NAME_FROM_IP) queryNameFromIp(pr);
andrewboyson 60:1d8c7a1e7483 365 if (pr->todo == TODO_IP_FROM_NAME) queryIpFromName(pr);
andrewboyson 60:1d8c7a1e7483 366
andrewboyson 60:1d8c7a1e7483 367 pr->state = STATE_SENT;
andrewboyson 93:580fc113d9e9 368 pr->elapsed = MsTimerCount;
andrewboyson 60:1d8c7a1e7483 369 }
andrewboyson 60:1d8c7a1e7483 370 void Nr4Main()
andrewboyson 60:1d8c7a1e7483 371 {
andrewboyson 60:1d8c7a1e7483 372 static int i = -1;
andrewboyson 60:1d8c7a1e7483 373 i++;
andrewboyson 60:1d8c7a1e7483 374 if (i >= RECORDS_COUNT) i = 0;
andrewboyson 60:1d8c7a1e7483 375
andrewboyson 60:1d8c7a1e7483 376 struct record* pr = &records[i];
andrewboyson 60:1d8c7a1e7483 377
andrewboyson 60:1d8c7a1e7483 378 clearCache (pr);
andrewboyson 60:1d8c7a1e7483 379 nextProtocol(pr);
andrewboyson 60:1d8c7a1e7483 380 sendRequest (pr);
andrewboyson 60:1d8c7a1e7483 381 }
andrewboyson 60:1d8c7a1e7483 382 void Nr4Init()
andrewboyson 60:1d8c7a1e7483 383 {
andrewboyson 60:1d8c7a1e7483 384 for (int i = 0; i < RECORDS_COUNT; i++) records[i].state = STATE_EMPTY;
andrewboyson 60:1d8c7a1e7483 385 }