Tento program vznikl jako semestralni prace v ramci studia programovaciho jazyka C++ na Fakulte elektrotechnicke, CVUT. Ukolem teto prace primarne nebylo vytvorit DNS server, ale procvicit si a prohloubit znalosti ziskane studiem. Z tohoto duvodu neni vysledkem "idealni" program, ale spise naznak, jak lze postupovat pri reseni takoveho problemu, jako je tvorba serveru sitove sluzby.
NahoruDNS je zkratka anglickeho Domain Name Service - Sluzba domenovych jmen. Obecne je to sluzba, ktera usnadnuje uzivatelum - lidem - orientaci a pohyb po spletite siti internetu.
V pocitacove siti je dulezite jednoznacne (a rychle) urceni kazdeho pocitace. Proto existuji tzv. IP adresy, coz jsou (prozatim) 4 bytova cisla. V kazde pocitacove siti musi mit kazdy pocitac pridelenou jedinecnou IP adresu, prostrednictvim niz s nim komunikuji ostatni pocitace. Pro uzivatele pocitacovych siti je bezpochyby pracne pamatovat si vice takovychto cisel, proto byla zavedena tzv. domenova jmeno. Domenove jmeno je posloupnost znaku, ktera v dane siti jednoznacne specifikuje nejakou IP adresu. Nutnost zavedeni domenovych jmen je patrna z uzivani internetu.
IP adresa se vetsinou zobrazuje jako ctyri cisla od 0 do 255 oddelene teckami (tedy napr. 212.80.76.3).
Domenove jmeno (DJ) se sklada z posloupnosti retezcu oddelenych teckami. Vyjimecnym pripadem DJ je jeden znak - mezera. Toto je korenove DJ, pod ktere spadaji vsechny ostatni. Pod korenovym DJ se ostatni stromovite vetvi tak, ze uzel stromnu tvori jeden retezec. Plati, ze cim je retezec blize konci DJ, tim je blize korenovemu DJ. Kazdemu uzlu takto vznikleho stromu muze byt prirazena jedna IP adresa, ktera je charakteristicka pro DJ, jenz vznikne z daneho uzlu pridanim vsech uzlu, ktere jsou nad nim na ceste ke korenovemu DJ (tyto uzly se pridavaji doprava).
Pokud bychom tedy meli DN:
bude prislusny strom vypadat nasledovne:
kde _ znaci korenove domenove jmeno.
Oznaceni DNS tedy zahrnuje sluzby zprostredkovavajici ukladani DJ a jejich IP a vyhledavani v takto ulozenych zaznamech. DNS sluzby pouzivane ve vetsich pocitacovych sitich shromazduji mnohem vice informaci a mnohem sloziteji. Pro ucely teto prace vsak postaci tento strucny uvod.
NahoruSitova komunikace mezi DNS serverem a klientem probiha prostrednictvim protokolu UDP/IP, tedy nespojoveho protokolu. Volba tohoto protokolu vyplyva z pozadavku rychleho ziskani pozadovanych informaci a maleho zatizeni pocitacove site. Absence potvrzeni prijatych datagramu je osetrena nasobnymi pokusy o ziskani odpovedi.
Konktetni komunikace vypada takto: server posloucha na portu 53. Pokud mu prijde dotaz, zpracuje ho a na adresu a port, ze ktere dotaz prisel, posle odpoved. Format dotazove i odpovedni zpravy je shodny: na zacatku datagram obsahuje hlavicku s infomaci, zda se jedna o dotaz ci odpoved, s poradovym cislem dotazu, s poctem dodatecnych informaci a s dalsimi udaji. Nasleduji dodatecne infomaci. Jako dodatecne informace se v teto zprave vyskytuje prave dotaz, ci odpoved.
V praxi to vypada tak, ze klient vytvori zpravu dotazu (tj. vytvori hlavicku a prida dodatecnou informaci - domenove jmeno). Server tento pozadavek zpracuje, prida ke zprave dalsi dodatecnou informaci - odpoved (jen ve tvaru "IP adresa dotazovaneho DJ je ...") a zpravu vrati klientovi.
NahoruNavrh programu vychazel z pozadavku udelat DNS server, ktery bude schopny poskytovat nejake zakladni sluzby a pritom nebude prilis slozity. Jako ukol jsem si tedy stanovil udelat DNS server, ktery bude umet uchovavat DNS zaznamy (dvojice DJ - IP) a na dotaz na IP adresu konkretniho DJ bude schopen odpovedet touto IP, pokud ji bude znat.
Navrh struktury tedy byl:
Zakladni usporadani behu programu je patrne z blokoveho schematu:
Realizace programu se vicemene nelisi od navrhu. Pribyla jen specialni entita pro uchovani DJ (usnadnuje vymenu infomaci uvnitr programu) a zapouzdreni programu do izolovaneho vlakna ovladaneho jednoduchou konzolovou aplikaci.
V prubehu programovani byly vytvoreny tyto programove struktury:
Tato trida rerezenuje jedno DJ. Jak je uvedeno v kapitole Co to je DNS, jedna se o posloupnost retezcu. Daty v teto tride jsou tedy ukazatel na typ string a jeden typ int, ktery uchovava pocet retezcu. Objekt teto tridy ma nemenny obsah, je ho tedy treba nainicializovat jiz konstruktorem na nejake konkretni DJ. Pokud se zadne neuvede, vytvori se korenove DJ.
Trida obsahuje tyto metody:
Trida zajistujici sitovou komunikaci. Pro potreby teto tridy je definovana struktura SockData:
struct SockData {kde:
Vlastni trida ma jednu promenou typu SOCK, ktera predstavuje ukazatel na sitovy socket. Dale ma nasledujici metody:
Trida uchovava DNS zaznamy, tj. sitove adresy k jednotlivym DJ. Take umoznuje vyhledavani v teto databazi, tj. nalezeni sitove adresy k zadanemu DJ.
Pro potreby teto tridy je definovana struktura subdomain, ktera predstavuje uzel stromu (viz Co to je DNS):
struct subdomain {kde:
Pro snazsi datovou reprezentaci byl pouzit binarni strom. Data uvedena v kapitole Co to je DNS budou tedy reprezentovana nasledovne:
Jako data proto vlastni tride staci jeden ukazatel na korenove DJ. Jeji metody jsou:
Nedostatek v teto tride je absence destruktoru. Jelikoz je ale pro cely beh programu pouzivana jedna databaze deklarovana ve funkci main(), upustil jsem od psani destruktoru. Kdyby bylo potreba ho dopsat, je nutne zajistit spravnou destrukci vsech uzlu stromu.
NahoruTato trida zpracovava DNS zpravy - prijme dotaz, vyhleda v databazi, zda k dotazovanemu DJ existuje zaznam, a pokud existuje, vytvori z jeho IP adresy odpoved. Tato trida by mela zajistovat kompatibilnost programu s definici DNS. Vzhledem k rozsahlosti kompletniho DNS a charakteru teto prace, jsem se omezil jen vytvoreni jednoho typu odpovedi, pokud se najde odpovidajici zaznam. Pokud zaznam nebude nalezen, vrati program klientovi jeho nezmeneny dotaz. Klient proto musi mit nastaveny dalsi DNS server, ktereho se muze ptat dal. DNS sluzba resi situaci nenalezeni DNS zaznamu tim, ze se DNS server zepta jineho DNS serveru, nebo klientovi posle informaci, ze IP adresu nezna a posle muze mu poslat IP adresu jineho DNS serveru. Po prostudovani DNS definice v RFC dokumentech lze uvazovat o pridani tohoto typu zprav.
Data tridy predstavuje ukazatel na strukturu SockData (kterou trida zpracovava) a dalsi promene predstavujici infomace ulozene v hlavicce DNS zpravy. Metody teto tridy jsou:
Hlavni cast programu (zdrojovy soubor Dns.cpp) obsahuje dve funkce. Prvni z nich je jadro servru - funkce, ze ktere je mozne vytvorit samostatne vlakno programu. Jelikoz lze takto vytvorenemu vlaknu predat jen jeden parametr, je zde zavedena struktura PARAM:
struct PARAM {prostrednictvim ktere se vlaknu predava ukazatel na databazi DJ a zaroven promenou, ktera specifikuje, zda ma vlakno bezet. (Parametr quit jsem nakonec nevyuzil, protoze funkce recvfrom ve volani "Sock >> SockData" je blokovaci.) Obsahem teto funkce je inicializace prostredi a provadeni vlastniho jadra serveroveho programu ve smyslu blokoveho schematu uvedeneho v kapitole Blokove schema.
V metoda main() probiha vytvoreni databaze DJ, vytvoreni vlakna pro jadro serveru a obsluha programu pomoci "konzole". Z konzole lze pouze vypsat obsah pouzivane DNS databaze nebo ukoncit program. Ukonceni programu neni korektni - probiha terminovanim beziciho vlakna. Lepsi by bylo nastavit promenou quit v parametru vlakna na true a ve vlaknu zajistit kontrolu tohoto parametru. Opet ale narazime na blokovaci funkci recvfrom, na ktere je vlakno po vetsinu casu blokovane.
NahoruProgram sice nesplnuje specifikaci DNS serveru uvedenou v dokumentech RFC, ale pro nenarocne pouziti je plne funkcni. Lze jej s vyhodou snadne konfigurace a ovladani vyuzit v male pocitacove siti nekladouci naroky na uplnou korektnost jejiho provedeni (v domacnosti, v malem podniku, na LAN-party,...).
Pripadne dotazy, pripominky a navrhy prosim zasilejte na adresu autora:
Jan Pospisil
Vice informaci na tema DNS servery lze nalezt na internetu a to hlavne v odpovidajicich RFC dokumentech. Jedna se o dokumenty 1034, 1035 a dalsi.