Recv () возвращает 0 из DNS-запроса (C) - PullRequest
1 голос
/ 27 февраля 2011

Итак, я создал DNS-прокси на C. Я использую DIG в качестве клиентской программы;он отправляет пакет запроса на мой сервер, мой сервер пересылает его в DNS, и мой сервер получает ответы, а затем отправляет их обратно клиенту.

Мой сервер связан с сокетом UDP;Я передаю пакет DNS через TCP.Однако мой вызов recv () (из сокета TCP) всегда возвращает 0. Я получу исходный запрос обратно, но без ответов.

Код:

fromlen=sizeof(client);
recvfrom(UDPSock,buffer,sizeof(buffer),0,(struct sockaddr *)&client,&fromlen); //receive from client
int msglen=strlen(buffer);
connect(TCPSock,(struct sockaddr*) &dest, sizeof(dest)); //connect to DNS
int m=send(TCPSock,buffer,msglen,0); //send packet to dns
recv(TCPSock,buffer,sizeof(buffer),0); //this returns 0

//send back
sendto(UDPSock,buffer,sizeof(buffer),0,(struct sockaddr *)&client,fromlen); //send message back`

Буферсоставляет 300 байт.

Ответы [ 3 ]

4 голосов
/ 28 февраля 2011

Ваша непосредственная проблема в том, что вы не говорите правильный протокол.Протокол DNS / TCP / IP не идентичен протоколу DNS / UDP / IP.Прочитайте RFC, описывающие протоколы, и следуйте им.

Ваша более фундаментальная проблема - это проблема проектирования с вашим кодом, как указано.На самом деле не имеет смысла, не в последнюю очередь, с точки зрения сетевых издержек, иметь TCP / IP с одним соединением на запрос на внутренней стороне, когда на внешней стороне есть только UDP / IP.Более того: правильно написанный сервер пересылки прокси DNS должен справляться с большими пакетами UDP / IP, усеченными ответами, усеченными и иным образом искаженными запросами , таймаутами и сбросами соединения TCP / IP, обнаружением петлии DNS / UDP / IP повтор.Но это выходит за рамки вопроса.

0 голосов
/ 28 февраля 2011

recv () возвращает ноль, когда другой конец отключается. Таким образом, вы заставляете другой конец отключаться, а не отправлять какие-либо данные. Возможно, он не понимает, что вы отправляете.

0 голосов
/ 28 февраля 2011

Помимо не проверки на ошибки из-за системных вызовов, одной большой проблемой является использование strlen(3). recvfrom(2) сообщает, сколько байт было помещено в ваш буфер (или -1 для ошибки). Некоторые из этих байтов могут иметь нулевые значения, поэтому strlen(2) вообще не применимо в этом случае. Исправьте это и посмотрите, поможет ли это. В противном случае вам придется объяснить, почему вы пересылаете по TCP и подключаетесь к каждому пакету.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...