Recv()从DNS查询(C)返回0

时间:2011-02-27 20:34:16

标签: c networking dns

所以我在C中创建了一个DNS代理。我正在使用DIG作为客户端程序;它将查询数据包发送到我的服务器,我的服务器将其转发到DNS,然后我的服务器收到答案,然后将它们发送回客户端。

我的服务器绑定到UDP套接字;我正在通过TCP传输DNS数据包。但是,我的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 个答案:

答案 0 :(得分:4)

您当前的问题是您没有说出正确的协议。 DNS / TCP / IP协议与DNS / UDP / IP协议不同。阅读描述协议的RFC并遵循它们。

您更基本的问题是您的代码存在设计问题。当前端只有UDP / IP时,在后端有一个每查询连接的TCP / IP,这在网络开销方面并没有多大意义。此外:正确编写forwarding proxy DNS server必须处理大型UDP / IP数据包,截断响应,截断和其他格式错误的查询,TCP / IP连接超时和重置,循环检测和DNS / UDP / IP重试。但这超出了问题的范围。

答案 1 :(得分:0)

除了不检查来自任何系统调用的错误之外,一个大问题是strlen(3)使用。 recvfrom(2)告诉您它在缓冲区中放置了多少字节(或-1表示错误)。其中一些字节的值可能为零,因此strlen(2)在这种情况下根本不适用。修复它,看看它是否有帮助。否则你必须解释为什么你通过TCP转发并连接每个数据包。

答案 2 :(得分:0)

当另一端断开连接时,

recv()返回零。所以你正在使另一端断开而不是发送任何数据。可能它不明白你发送的是什么。