Перейти к содержанию
Fire Monkey от А до Я

Volt-

Пользователи
  • Постов

    11
  • Зарегистрирован

  • Посещение

Активность репутации

  1. Like
    Volt- отреагировална Евгений Корепов в Прочитать DNS запрос в idUDPServer   
    Для начал у вас не правильно работает function ReplaceSpecSymbol, она оставляет спецсимволы в конце строки. Вот накидал правильно работающую:
    function ReplaceSpecSymbol(S: String): String; var Count : Integer; begin Count:=0; Result:=''; while True do begin Count:=Ord(S.Chars[0]); Result:=Result+S.Substring(1,Count)+'.'; S:=S.Remove(0,Count+1); if Ord(S.Chars[0])=0 Then break; end; Result:=Result.TrimRight(['.']); end; После этого в вашем проекте нормально все ресолвится, но что отсылать в ответ на lookup я не имею представления. Не знаю как заставить IdDNSResolver отдать данные в сыром формате, надо искать и читать документацию.
    Вот код процедуры, но надо разобраться что слать:
    procedure TMainForm.IdUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); var S, Domain: String; I : Integer; ABuffer : TIdBytes; begin S:=ReplaceSpecSymbol(BytesToString(AData,12)); Memo_Log.Lines.Add(S); if Pos('in-addr.arpa',S)=0 then begin IdDNSResolver.Resolve(S); for I := 0 to IdDNSResolver.QueryResult.Count-1 do if IdDNSResolver.QueryResult[I].RecType = qtA then begin S:=TARecord(IdDNSResolver.QueryResult[I]).IPAddress; Memo_Log.Lines.Add('IdDNSResolver: '+S); end; // Вот дальше не знаю что именно пересылать // ABuffer:=DNSHeader.GenerateBinaryHeader; // ABuffer:=IdDNSResolver.PlainTextResult; // ABuffer:=ABuffer+IdDNSResolver.InternalQuery; // ABuffer:=IdDNSResolver.InternalQuery; ABinding.Send(ABuffer); end; Вы можете поразбираться с помощью простейшего DNS прокси, по крайней мере будете видеть что идет в запросе и что в ответе. Код ниже, только пропишите глобальную переменную ALocalPort : Integer, для запоминания забинденного порта на 127.0.0.1
    procedure TMainForm.IdUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); Const ExternalDNSHost = '8.8.8.8'; LocalHost = '127.0.0.1'; begin if ABinding.PeerIP.Equals(LocalHost) then // если запрос с локального, пересылаем на внешний dns begin ALocalPort:=ABinding.PeerPort; IdUDPServer.SendBuffer(ExternalDNSHost,53,AData); end; if ABinding.PeerIP.Equals(ExternalDNSHost) then // если с внешнего, пересылаем на локальный IdUDPServer.SendBuffer(LocalHost,ALocalPort,AData); exit; end; в коммандной строке используйте "nslookup -retry=1 -timeout=30 google.ru 127.0.0.1 " (один повтор запроса, чтоб не засирать отладку и таймаут сколько нужно секунд, что не отвалился запрос пока будете разбираться)
  2. Like
    Volt- отреагировална Евгений Корепов в Прочитать DNS запрос в idUDPServer   
    Все правильно получаете, кодировка тут не при чем. Согласно спецификации "DNS Packet Structure", вы получаете не строку, а пакет который нужно разобрать. К примеру если запрос будет "nslookup www.google.ru 127.0.0.1", то там где вы получаете имя хоста будет строка "''#3'www'#6'google'#2'ru'#0#0#1#0#1".
    Парсинг простейший:
    #3 - означает что далее идут 3 символа хоста 'www' - вот ожидаемые 3 символа #6 - далее идут еще 6 символов хоста 'google' - ага, вот они #2 - ну и еще 2 символа 'ru' - ура, они здесь #0 - конец имени хоста, складываем в кучу, перемежая точками и получаем www.google.ru #0 - дальше у нас служебная информация... #1 #0 #1 Вот как то так.
    P.S. А зачем вам на таком низком уровне работать? Может использовать IdDNSServer : TIdDNSServer ?
    P.P.S. Правильно Memo1.Lines.Add(BytesToString(AData,12)); //(12, а не 13)
×
×
  • Создать...