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:
Fri Feb 22 11:26:55 2019 +0000
Revision:
125:8c84daac38ab
Parent:
116:60521b29e4c9
Child:
128:79052cb4a41c
tidied up ntp data types for calculating ms from clktime.

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