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
resolve/nr6.c@170:96c637dc3f52, 2020-12-09 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |