FULL-C dns resolv functions: Porovnání verzí

(Založena nová stránka s textem „ 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,…“)
 
 
(Nejsou zobrazeny 4 mezilehlé verze od stejného uživatele.)
Řádek 18: Řádek 18:
  
 
Po odeslání dotazu se čeká na odpověď, přičemž FULL-C program pravidelně kontroluje stav voláním '''dns_resolv_status()''' funkce.
 
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ů !'''
  
  
Řádek 27: Řádek 30:
 
void main(void)
 
void main(void)
 
{
 
{
  char DNSname[64];
+
  char DNSname[96];
 
  unsigned int status;
 
  unsigned int status;
 
  unsigned int IP0, IP1, IP2, IP3;
 
  unsigned int IP0, IP1, IP2, IP3;
Řádek 35: Řádek 38:
 
  printf("RESOLVING %s \n", DNSname);
 
  printf("RESOLVING %s \n", DNSname);
  
 +
// start - select the new DNSname for all the subsequent status function calls
 
  dns_resolv(DNSname);
 
  dns_resolv(DNSname);
  
 +
// get the first status value
 
  status = dns_resolv_status(&IP0, &IP1, &IP2, &IP3);
 
  status = dns_resolv_status(&IP0, &IP1, &IP2, &IP3);
  while (status == 512)
+
// 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);
 
   status = dns_resolv_status(&IP0, &IP1, &IP2, &IP3);
 
  }
 
  }
  
  if (status == 513)
+
// check the final status value
 +
  if (513 == status)
 
  {
 
  {
 
   printf("GOT RESULT: IP = %u.%u.%u.%u\n", IP0, IP1, IP2, IP3);
 
   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
 
  } else
 
  {
 
  {
 
   printf("DNS RESOLV FAILED (error %u) \n", status);
 
   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
 
  }
 
  }
  
 
}
 
}
 
</pre>
 
</pre>
 +
 +
== 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, přičemž z odpovědi je převzata i položka TTL pro danou položku.
 +
 +
Pokud je (v interní cache) existující položka, se svou zbývající hodnotou 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ě.
 +
 +
Každou 1 sekundu dojde ke snížení zbývajících hodnot TTL u všech záznamů v interní cache.
 +
 +
Systémová proměnná na indexu [72] umožňuje limitovat počáteční hodnotu TTL, která přijde v odpovědi z DNS serveru. Nastavte si to při startu svého FULLC programu dle své potřeby. Poznámka: v případě, že přijde odpověď s položkou s TTL=0, pak je v SDS zapsána tato položka do interní DNS cache s výchozí dobou platnosti dva týdny (TTL nastaveno na 1209600 sekund).
 +
 +
 +
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 zkontroluje platnost položky v interní cache pro danou doménu a eventuálního odeslání nového dotazu (pokud záznam v cache není, nebo už je neplatný).
 +
 +
Nový dotaz není odeslán automaticky (tedy SDS neodešle nový dotazy na server), pokud položka v interní DNS cache je stále platná. Toto máte 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 tedy 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 (kdy byl 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.), kdy současně časem dojde k vypršení položek v interní cache (to lze sledovat pomocí indexu [70]), pak pokud nový dotaz nebude zodpovězen (protože nebude možná komunikace s DNS serverem), tak se hodnota v [71] ukáže jako nulová. Samozřejmě vždy jsou ve všech zde zmíněných indexech k dispozici hodnoty pouze pro ten doménový název, který jste jako poslední použili při zavolání funkce dns_resolv(), a ostatní jsou uchovány v interní cache (pokud už byly dříve přeloženy).
 +
 +
 +
== 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 k nové komunikaci s DNS serverem, a SDS (resp. váš FULLC program) bude čekat na jeho novou, čerstvou odpověď. Ta jak přijde (a pokud bude platná), tak se uloží do interní DNS cache, a to po dobu hodnoty TTL (tuto dobu určuje DNS server ! a omezuje ji hodnota v indexu [72]). Další volání dns_resolv(), pak (dokud TTL pro danou doménu v interní cache nevyprší) jsou pak vyřízeny okamžitě, protože SDS nečeká na odpověď ze serveru, a váš FULLC program dostane odpověď ihned z interní cache (dokud té nevyprší TTL).
 +
 +
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 ==
 
== Stavové hodnoty ==
  
Program musí použít volání funkce '''dns_resolv_status''' pro zjištění okamžitého stavu.
+
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
 
   dns_resolv_status()      význam
  -------------------------+-----------------------------------------------------------------------
+
  -------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------
   0                      |  klid, můžete odeslat DNS dotaz
+
   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, čekejte
+
   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)
+
   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)
+
   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
+
   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().

Aktuální verze z 10. 8. 2025, 17:32

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, přičemž z odpovědi je převzata i položka TTL pro danou položku.

Pokud je (v interní cache) existující položka, se svou zbývající hodnotou 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ě.

Každou 1 sekundu dojde ke snížení zbývajících hodnot TTL u všech záznamů v interní cache.

Systémová proměnná na indexu [72] umožňuje limitovat počáteční hodnotu TTL, která přijde v odpovědi z DNS serveru. Nastavte si to při startu svého FULLC programu dle své potřeby. Poznámka: v případě, že přijde odpověď s položkou s TTL=0, pak je v SDS zapsána tato položka do interní DNS cache s výchozí dobou platnosti dva týdny (TTL nastaveno na 1209600 sekund).


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 zkontroluje platnost položky v interní cache pro danou doménu a eventuálního odeslání nového dotazu (pokud záznam v cache není, nebo už je neplatný).

Nový dotaz není odeslán automaticky (tedy SDS neodešle nový dotazy na server), pokud položka v interní DNS cache je stále platná. Toto máte 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 tedy 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 (kdy byl 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.), kdy současně časem dojde k vypršení položek v interní cache (to lze sledovat pomocí indexu [70]), pak pokud nový dotaz nebude zodpovězen (protože nebude možná komunikace s DNS serverem), tak se hodnota v [71] ukáže jako nulová. Samozřejmě vždy jsou ve všech zde zmíněných indexech k dispozici hodnoty pouze pro ten doménový název, který jste jako poslední použili při zavolání funkce dns_resolv(), a ostatní jsou uchovány v interní cache (pokud už byly dříve přeloženy).


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 k nové komunikaci s DNS serverem, a SDS (resp. váš FULLC program) bude čekat na jeho novou, čerstvou odpověď. Ta jak přijde (a pokud bude platná), tak se uloží do interní DNS cache, a to po dobu hodnoty TTL (tuto dobu určuje DNS server ! a omezuje ji hodnota v indexu [72]). Další volání dns_resolv(), pak (dokud TTL pro danou doménu v interní cache nevyprší) jsou pak vyřízeny okamžitě, protože SDS nečeká na odpověď ze serveru, a váš FULLC program dostane odpověď ihned z interní cache (dokud té nevyprší TTL).

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