Domain Name Service - Служба Доменных Имен



         

Практическая реализация DNS - часть 4


Далее сервер реализует поиск имени по собственной базе или отправляет запрос другому серверу, но в любом случае он должен сформировать ответ для клиента.

Секция ответа состоит из полей имени ресурса, типа и класса, описанных выше. При этом их содержание можно полностью скопировать из запроса. За ними следуют четыре байта поля TTL (time-to-live), содержащее количество секунд, на которое можно кэшировать запрос (заполняем нулями). Следующие два байта - это длина данных ресурса, и сами ресурсы. В ресурс помещается информация об ответе. Как указывается в RFC 1035, она зависит от типа запроса, но в нашем случае это будут четыре байта под IP адрес.

Приведем пример ответа на предыдущий запрос:

byte[] reply={2,34,133,128,0,0,0,1,0,0,0,0,3,97,97,97,0,0,1,0,1,0,0,0,0,0,4,5,6,7,8};

Тут количество вопросов - ноль, ответов - один. И ответ устанавливает соответствие имени хоста "aaa." с IP адресом 5.6.7.8 и TTL равным 0.

Стоит обратить внимание на флаги: 133 - авторитетный ответ, 128 - сервер поддерживает рекурсию.

В качестве завершающего примера приведу код сервера, который принимает DNS пакет и генерирует ответ. При этом вне зависимости оттого, что спросит клиент, ответ будет содержать "aaa" и IP адрес 5.6.7.8

После компиляции проверить это можно при помощи утилиты nslookup

import java.net.*; import java.io.*;

class udptest {

public static void main(String arg[]) { byte id1,id2,flags; int qtype;

try { byte[] buffer = new byte[512]; DatagramPacket incoming = new DatagramPacket(buffer, buffer.length); DatagramSocket ds = new DatagramSocket(53); ds.receive(incoming); byte[] data = incoming.getData(); id1=data[0]; id2=data[1]; int i=12; String s="";

while (data[i]>0) { if (s.length()>0) {s+=".";} s += new String(data, i+1, data[i]); i+=data[i]+1; } i++; byte[] reply={0,0,0,0,0,0,0,1,0,0,0,0,3,97,97,97,0,0,1,0,1,0,0,0,0,0,4,5,6,7,8}; reply[0]=id1; reply[1]=id2; reply[2]=0&133; reply[3]=0;

DatagramPacket out = new DatagramPacket(reply,reply.length, incoming.getAddress(), incoming.getPort());

ds.send(out); } catch (IOException e) {System.err.println(e);} }//main

}//class




Содержание  Назад