FULL-C dns resolv functions
Tato stránka popisuje programovací jazyk FULL-C, který je dostupný na vybraných zařízeních SDS. Některá zařízení používají SDS-C, pro který máme návody jinde na této WiKi.
Síťové funkce: dotaz na přidělenou IP adresu pro DNS jméno
Zařízení SDS umožňuje odeslat dotaz na DNS server, za účelem zjištění IP adresy přidělené k DNS názvu, který je obsahem právě takového dotazu.
Za tímto účelem jsou k dispozici tyto dvě funkce:
void dns_resolv(char *domainNameInput); unsigned int dns_resolv_status(unsigned int *IP0value, unsigned int *IP1value, unsigned int *IP2value, unsigned int *IP3value);
Princip
SDS odesílá dotaz na DNS server, který je nastaven uživatelem SDS ve webové administraci zařízení (popř. je adresa DNS serveru získána z DHCP serveru, opět záleží na konfiguraci).
Po odeslání dotazu se čeká na odpověď, přičemž FULL-C program pravidelně kontroluje stav voláním dns_resolv_status() funkce.
POZOR : Maximální délka názvu DNS domény je interně omezena na 96 znaků !
Příklad
V tomto příkladu odesílá SDS dotaz (textový název domény) na DNS server a zobrazuje případnou získanou odpověď (IP adresu).
void main(void)
{
char DNSname[96];
unsigned int status;
unsigned int IP0, IP1, IP2, IP3;
sprintf((char *)DNSname, "www.google.com");
printf("RESOLVING %s \n", DNSname);
// start - select the new DNSname for all the subsequent status function calls
dns_resolv(DNSname);
// get the first status value
status = dns_resolv_status(&IP0, &IP1, &IP2, &IP3);
// only if truly working, keep waiting
while (512 == status)
{
// keep getting a new status, until it is different than 512
status = dns_resolv_status(&IP0, &IP1, &IP2, &IP3);
}
// check the final status value
if (513 == status)
{
printf("GOT RESULT: IP = %u.%u.%u.%u\n", IP0, IP1, IP2, IP3);
// only in this case, we can use the IPx address
// ... OK
// we can print the additional internal DNS cache status, for this particular domain
// note. the value is valid only if the status is 512, otherwise not
unsigned int ttl;
ttl = SDS_get_u(70); // index [70] = actual TTL value for the selected DNS cache item
printf("REMAINING DNS-CACHE TTL-VALUE IS %u SECONDS FOR DOMAIN %s\n", ttl, DNSname);
} else
{
printf("DNS RESOLV FAILED (error %u) \n", status);
// in this case, the IPx adress is not valid, and you need to repeat the dns_resolv() call again
}
}
Interní DNS cache
Po úspěšném provedení získání DNS překladu, kdy SDS odešle dotaz na určený DNS server, a získá z něj odpověď, je výsledek k dispozici (dá se získat pomocí dns_resolv_status funkce).
Funkce dns_resolv_status() vrací vždy výsledek toho úplně posledního dotazu, který byl vyvolán zavoláním funkce dns_resolv().
Platná odpověď z DNS serveru je uložena do interní tabulky (DNS cache) v SDS.
Pokud je zbývající hodnota TTL větší než 0, bude ihned k dispozici odpověď z interní cache.
Pokud záznam v interní cache není (nebo už vypršel), bude automaticky odeslána žádost o nový překlad na DNS server.
Toto si řídí SDS interně.
Váš program tedy vždy, když potřebuje IP adresu pro jakoukoliv doménu, tak vždy musí nejprve zavolat dns_resolv(). Tím se jednak vybere aktuální doména, pro kterou chcete získat platnou aktuální IP adresu (a lze ji tedy přečíst pomocí dns_resolv_status() funkce), a také se spustí mechanismus kontroly interní cache a eventuálního odeslání nového dotazu.
Nový dotaz není odeslán automaticky, tedy SDS samo neodesílá nové dotazy, když položka v interní DNS cache vyprší. Toto máte plně pod kontrolou vy, a to tak, že voláte funkci dns_resolv(), která se teprve v ten moment (kdy ji ze svého programu zavoláte) rozhodne, jestli bude nový dotaz posílat, nebo ne (čistě dle stavu obsahu interní DNS cache). Pokud v cache není záznam pro danou doménu, nebo je ale už vypršel (TTL na nule), tak dojde k odeslání dotazu, a váš program pak musí čekat na odpověď (viz příklad výše, periodickým voláním dns_resolv_status(), kdy se průběžně zařídí dle vrácené hodnoty od této funkce).
Hodnota na indexu [71] ukazuje, kdy dorazila platná a očekávaná odpověď (paket) z DNS serveru. Pokud nedorazila, je hodnota na 0. Pokud odpověď dorazila (pro daný dotaz, položený posledním voláním funkce dns_resolv), tak je do indexu [71] zapsána časová známka (UTC čas) momentu, kdy byla odpověď přijata (paket ze serveru akceptován). Pomocí sledování indexu [71] můžete nezávisle kontrolovat činnost DNS resolveru v zařízení SDS. Např. při výpadku síťové komunikace (např. odpojení kabelu, porucha sítě atd.), dojde k vypršení položek v interní cache (to lze sledovat pomocí indexu [70]) a pokud nový dotaz nebude zodpovězen (nebude komunikace s DNS serverem), tak se hodnota v [71] ukáže jako nulová. Samozřejmě vždy jsou v těchto indexech k dispozici hodnoty pouze pro ten doménový název, který jste jako poslední použili při zavolání funkce dns_resolv().
Upozornění
Starší FW mělo bug, kdy při vypršení TTL v interní cache nedošlo ke smazání položky v interni cache. Toto je samozřejmě problém, který je vyřešen v novém firmware, všechny verze od 08/2025.
DNS cache je (záměrně) vymazána při:
- nahrání nového FULLC programu
- restartu zařízení SDS
DNS cache není vymazána při výpadku Ethernetového připojení.
DNS cache lze ručně vymazat zapsáním hodnoty 0xE4A5ECAC do systémové proměnné na indexu [70]. Zápis této speciální hodnoty kompletně smaže interní DNS cache. Tato specifická funkcionalita vyžaduje aktuální firmware (bylo to přidáno až 08/2025).
To, že je DNS cache vymazána, znamená pouze jedinou záležitost - a to, že při novém dotazu přes dns_resolv() dojde ke komunikace s DNS serverem, a bude se čekat na jeho novou, čerstvou odpověď. Ta jak přijde (a bude platná), tak je uložena do cache, po dobu hodnoty TTL (tuto dobu určuje DNS server!). Další volání dns_resolv(), dokud TTL pro danou doménu v interní cache nevyprší, jsou pak vyřízeny okamžitě, protože se nečeká na odpověď ze serveru, ale FULLC program dostane odpověď ihned z interní cache.
GOOD PRACTICE: před každým opakovaným použitím IP adresy, která byla získána z DNS resolveru, je vhodné zavolat dns_resolv() pro danou doménu znovu. Pokud je výsledná adresa (výsledek překladu domény na IP adresu) stejná, je to také okamžitě potvrzeno. Pokud však mezitím došlo ke změně (DNS záznamu), tak se jedině takto dokáže tato změna projevit ! Pokud tedy periodicky voláte např. funkci http_get(), tak vždy před každým tímto voláním, musíte provést i celé kolečko s dns_resolv() pro danou doménu, se kterou takto chcete komunikovat. Pokud to neuděláte, časem se dostanete do obtížného problému, kdy daný cílový server už může být dávno na jiné IP adrese, ale váš program bude stále chodit na starou, neplatnou, a přestane fungovat.
Stavové hodnoty
Program musí použít volání funkce dns_resolv_status pro zjištění okamžitého stavu. Dokud nezískáte finální stavovou hodnotu, musíte tuto funkci volat opakovaně (nezapomeňte na vlastní bezpečnostní timeout).
dns_resolv_status() význam -------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------- 0 | klid, můžete odeslat DNS dotaz, funkce dns_resolv_status() současně nevrací platnou IP adresu (musíte nejprve spustit DNS překlad) 512 | pracuje, dotaz odeslán (překlad nenalezen v interní cache), čekejte (funkce současně nevrací platnou IP adresu, ta bude až po dokončení překladu) 513 | hotovo OK, do *resolvedIPaddressOutput byla zapsána IP adresa (4 bajty), a záznam v interní cache je platný a živý (zbývající TTL větší než 0) 514 | odpověď nebyla získána (chyba) a současně nemáme záznam v interní DNS cache, takže funkce nevrací platnou IP adresu (musíte znovu začít s dotazem) 515 | funkce byla zavolána s neplatnými parametry - nic nebylo provedeno, funkce nevrací platnou IP adresu 516 | dotaz selhal, protože došlo k odpojení Ethernetu 517 | dotaz selhal, protože došlo ke ztrátě vlastní přidělené IP adresy zařízení SDS (typicky když vyprší IP z DHCP a není ještě obnovena)
Pokud funkce dns_resolv_status() vrátila hodnotu 513, je možné číst systémovou proměnnou z indexu [70] (uint32_t), která ukáže hodnotu TTL v momentu, kdy tuto hodnotu právě čtete. Lze takto sledovat, jak se postupně TTL snižuje (o 1 každou sekundu). Hodnota TTL odpovídá dané položce v interní cache, která byla určena právě posledním voláním funkce dns_resolv().