15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту

 

В соответствии с правилами Интернет, каждой зоне соответствует один первичный (primary) и один или несколько вторичных (secondary) серверов. Вторичные серверы вступают в работу, когда первичный оказывается перегруженным или выходит из строя.

Исходная информация для первичного сервера DNS хранится на его дисках, то есть загружается при запуске из файлов. Вторичные серверы получают информацию от первичного. Процесс получения информации вторичным сервером от первичного называется передачей зоны (zone transfer). Как правило, обновление информации вторичного сервера (передача зоны) происходит один раз за несколько часов.

Первичные и вторичные серверы DNS независимы. Информация, которую они содержат, как правило, избыточна. Цель наличия нескольких серверов DNS в одной и той же зоне — обеспечить надежность функционирования. Сбой в работе одного из серверов DNS не повлечет за собой полной остановки работы этой службы.

Преобразование имен в IP-адреса

Идеальная картина работы преобразователя адресов значительно отличается от реального положения вещей. На самом деле, программа-клиент (преобразователь) связывается с сервером имен из своей зоны. Сервер рассматривает запрос, чтобы выяснить, в каком домене находится указанное там имя и кто его обслуживает. Если указанный домен входит в зону ответственности этого сервера, сервер преобразует имя в IP-адрес, пользуясь собственными таблицами, а затем отправляет ответ клиенту.

Если сервер не в состоянии обслужить запрос, то есть домен находится вне его зоны, дальнейшее его поведение зависит от типа запроса клиента. Преобразователь устанавливает один из двух типов запросов. Сперва он просит сервер произвести полное преобразование. В официальной терминологии этот тип запроса называется «рекурсивное выполнение* (recursive resolution). Если клиент запрашивает рекурсивное выполнение и сервер не в состоянии выполнить преобразование, он должен обратиться к тому серверу, который сможет выполнить запрос, а затем возвращает ответ клиенту.

Второй тип запроса — выполнение методом итераций (iterative resolution). Запрос на выполнение методом итераций просит сервер либо выполнить преобразование, либо, в случае неудачи, указать клиенту следующий сервер, к которому можно обратиться. Когда сервер получает запрос на выполнение методом итераций, он либо успешно преобразует имя в IP-адрес, либо его ответ содержит адрес следующего сервера, который, возможно, имеет больше информации. При этом, как видим, наш сервер не делает полного преобразования для клиента.

Взаимодействие между серверами DNS

Серверу DNS не обязательно знать имена или IP-адреса остальных серверов в Интернет. Достаточно располагать информацией о корневых серверах. Файлы конфигурации каждого первичного сервера содержат IP-адреса корневых серверов. Корневые серверы должны знать имена и IP-адреса каждого сервера DNS второго уровня. В табл. 9.2 приведен список корневых серверов DNS по состоянию на май 1994 г.

Таблица 9.2. Корневые серверы системы имен доменов Интернет по состоянию на май 1994 г.

Имя хоста Сетевой адрес Программа-сервер
NS.NIC.DDN.MIL 192.112.36.4 bind (UNIX)
AOS.BRL.MIL 128.63.4.82 26.3.0.29 192.5.25.82 bind (UNIX)
C.NYSER.NET 192.33.4.12 bind (UNIX)
TERP.UMD.EDU 128.8.10.90 bind (UNIX)
NS.NASA.GOV 192.52.195.10 128.102.16.10 bind (UNIX)
NIC.NORDU.NET 192.36.148.17 bind (UNIX)
NS1.ISI.EDU 128.9.0.107 bind (UNIX)
NS.ISC.ORG 192.5.5.241 bind (UNIX)
NS.INTERNIC.NET 198.41.0.4 bind (UNIX)


Примечание: Наиболее свежая информация о корневых серверах DNS находится в файле netinfo/root-servers.txt по адресу nic.ddn.mil. Файл можно получить при помощи анонимного ftp.

Как устроен преобразователь адресов?

Специальное программное обеспечение, работающее на стороне клиента в составе DNS, называется «преобразователь» (resolver) или «преобразователь имен». Windows API обеспечивает выполнение двух функций преобразователя: gethos-tbyaddr и gethostbyname. Обе функции получают информацию о сетевом компьютере. Прикладные программы пользуются этими функциями, чтобы преобразовать IP-адрес или имя компьютера. В обоих случаях функции связываются с серверами DNS для выполнения этого преобразования. Другими словами, программа вызывает эти функции, чтобы преобразовать IP-адрес в имя или наоборот. Функция, в свою очередь, открывает коммуникационный канал и посылает запрос к серверу имен доменов. Получив необходимую информацию, она закрывает канал и возвращает полученное значение вызывавшей прикладной программе.

Рассмотрим следующую небольшую программу, QLookup (Quick Lookup). Она демонстрирует основные шаги, которые нужно предпринять для обращения к серверу имен доменов. Из программы выброшено все, не относящееся к делу. Оставлены только детали, необходимые для работы с функциями gethostbyaddr и gethostbyname. Жестко заданные значения переменных и панели сообщений освобождают нас от необходимости программировать пользовательский интерфейс Windows. Программа подробно обсуждается в этом разделе, и здесь же приведен ее исходный текст:

  Листинг 1 (QLOOKUP.CPP)
#include "..\winsock.h"             // Файл заголовков Winsock 
#define PROG_NAME "Simple DNS Lookup" 
#define HOST_NAME "CERFNET.COM"     // Может быть любым (настоящим именем компьютера 
#define WINSOCK_VERSION 0х0101      // Необходим Winsock версии 1.1 
#define PF_INET_LENGTH 4            // Длина адреса в протоколах Интернет всегда равна 4 байтам 
#define HOST_ADDR "129.79.26.27"    // winftp.cica.indiana.edu 

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) 
{ 
    WSADATA wsaData;     // Сведения о реализации Winsock 
    LPHOSTENT lpHostEnt; // Структура с информацией о сетевом компьютере Интернет 
    DWORD dwIPAddr;      // IP-адрес в виде беззнакового целого двойной длины 
    LPSTR szIPAddr;      // IP-адрес в виде "десятичное с точкой" 

    if (WSAStartup(WINSOCK_VERSION, &wsaData)) 
        MessageBox(NULL, "Could not load Windows Sockets
             DLL.", PROG_NAME, MB_OK|MB_ICONSTOP); 
    else {               // Преобразуем имя сетевого хоста 

        lpHostEnt = gethostbyname(HOST_NAME); 

        if (!lpHostEnt) 
            MessageBox(NULL, "Could not get IP address!",
                 HOST_NAME, MB_OK|MB_ICONSTOP);
        else {           // IP-адрес преобразуется в нотацию "десятичное с точкой" 
            szIPAddr = inet_ntoa(*(LPIN_ADDR)*(lpHostEnt->h_addr_list));
            MessageBox(NULL, szIPAddr, IpHostEnt->h_name, 
                 MB_OK|MB_ICONINFORMATION);
        }  

        // Формат "десятичное с точкой" преобразуется в 32-разрядный IP-адрес

        dwIPAddr = inet_addr(HOST_ADDR); 

        if (dwIPAddr == INADDR_NONE) 
            MessageBox(NULL, "Invalid Internet address!", 
                 HOST_ADDR, MB_OK|MB_ICONSTOP);
        else {           // Преобразуем IP-адрес 

            lpHostEnt = gethostbyaddr((LPSTR) &dwIPAddr, PF_INET_LENGTH, PF_INET); 

            if (!lpHostEnt)
                MessageBox(NULL, "Could not get host name!", 
                     HOST_ADDR, MB_OK|MB_ICONSTOP);
            else 
                MessageBox(NULL, lpHostEnt->h_name, 
                     HOST__ADDR, MB_OK|MB_ICONINFORMATION);
            }
        }

    WSACleanup();        // Программа освобождает занятые ресурсы
                         // и завершается 
    return(NULL);
} 

 

Оператор в первой строчке листинга включает файл заголовков функций интерфейса Windows Sockets — WINSOCK.DLL.

#include " . . Winsock.h"

Вы знаете, что файл winsock.h необходимо включать в каждую программу, использующую интерфейс программирования Windows Sockets. В нем заданы константы и определены прототипы функций для всего Winsock API.

Значения констант

Сразу после оператора, включающего winsock.h, следуют пять операторов, задающих значения необходимых для работы констант:

  Листинг 2
#define PROG_NAME "Simple DNS Lookup"
#define HOST_NAME "CERFNET.COM"         // Любое (настоящее) имя компьютера
#define WINSOCK_VERSION 0х0101          // Необходим Winsock версии 1.1
#define PF_INET_LENGTH 4                // Длина адреса в протоколах Интернет всегда равна 4 байтам
#define HOST_ADDR "129.79.26.27"        // winftp.cica.indiana.edu


WINSOCK_VERSION обозначает версию интерфейса Winsock (1.1). Константа AF_INET_LENGTH определяет длину (в байтах) адреса, указываемого в вызове функции gethostbyaddr. Эти константы используются во всех программах-примерах, приведенных в этой книге.

Константа PROG_NAME определяет название (краткое описание) программы, которое можно использовать в дальнейшем. Если вы решите сменить имя программы, просто замените значение этой константы на другое.

HOST_NAME и HOST_ADDR задают имя и адрес сетевого компьютера в Интернет. В их качестве можно использовать имя и адрес любого реально существующего сетевого компьютера.

Значения переменных

Следующие несколько строк листинга QLookup начинают определение функции WinMain (она нужна для всех программ под Windows) и определяют три локальные переменные: dwIPAddr, wsaData и IpHostEnt.

  Листинг 3
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
     WSADATA wsaData;       // Сведения о реализации Winsock
     LPHOSTENT IpHostEnt;   // Структура с информацией о сетевом компьютере





Продолжение следует ....