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("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).
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.
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).
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().