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