1
我正在創建代理DNS,我從dig收到查詢,發送給服務器,但無法從DNS服務器獲得答案。我知道我的代碼看起來不太好,但我在這工作了幾個小時,仍然無法解決問題。我的程序在第二次recvfrom之前就卡住了。有人能幫我嗎? (順便說一句我的這個操作系統是FreeBSD和我與8.8.8.8 DNS服務器測試這個)代理DNS沒有收到迴應
這是我的代碼:一些修復後的新代碼:
int main(int argc, char *argv[])
{
char buf[BUFSIZE];
char serverbuf[BUFSIZE];
int UDPSocket, clientSocket;
int lenght;
int addr_len;
struct addrinfo *clientInfo;
struct addrinfo hintsClient;
struct sockaddr_in serverSocket, clientAddr, serverAddr;
int serverAddrLen = sizeof(serverAddr);
fd_set set, tcpset;
struct timeval tv; // struktura pro timeout
bool end = false;
int m;
TprogParam param = processParams(argc, argv);
if(param.error)
{
printError(EPARAMS);
return ERROR;
}
if(param.help)
{
printHelp();
return EXIT_SUCCESS;
}
memset(&hintsClient, 0, sizeof(struct addrinfo));
hintsClient.ai_family = AF_INET;
hintsClient.ai_socktype = SOCK_DGRAM;
hintsClient.ai_flags = 0;
hintsClient.ai_protocol = IPPROTO_UDP;
int status;
if(param.ipadress[0] == '\0')
{
if((status = getaddrinfo(INADDR_ANY, NULL, &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
else
{
if((status = getaddrinfo(param.ipadress, "13066", &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = 53;
// vytvorime socket
if((UDPSocket = socket(clientInfo->ai_family, clientInfo->ai_socktype, clientInfo->ai_protocol)) == -1)
{
printf("Nelze vytvorit udp socket");
printError(1);
return ERROR;
}
if((clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("Nelze vytvorit tcp socket");
printError(1);
return ERROR;
}
// Nastavime socket do neblokovaciho rezimu
if(bind(UDPSocket, clientInfo->ai_addr, clientInfo->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
{
printf("Nelze navazat spojeni pro naslouchani: %d", errno);
return ERROR;
}
}
printf("Poslal jsem zadost o spojeni. Zatimco se spojeni navazuje mohu delat jine veci.\n");
FD_ZERO(&set);
FD_SET(UDPSocket, &set);
tv.tv_sec = 15;
tv.tv_usec = 0;
addr_len = sizeof(struct sockaddr);
while(1)
{
printf("Prijimam pozadavek k vyrizeni.\n");
if ((lenght = recvfrom(UDPSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&clientAddr, &addr_len)) == -1)//recv(UDPSocket, buf, BUFSIZE - 1, 0)) == -1)
{
printf("Nejaka chyba pri prijimani dat");
return ERROR;
}
buf[lenght] = '\0';
printf("Prijata nasledujici data od klienta na predklad dns: %s o delce %d \n", buf, lenght);
if((m = sendto(clientSocket, buf, lenght, 0, (struct sockaddr *)&serverAddr, serverAddrLen)) == -1)
{
printf("Problem s odeslanim dat: %d %s", errno, strerror(errno));
return ERROR;
}
if((m = recvfrom(clientSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&serverAddr,&serverAddrLen)) == -1)
{
printf("nejaka chyba");
return ERROR;
}
if((lenght = sendto(UDPSocket, buf, lenght, 0,(struct sockaddr *)&clientAddr, lenght)) == -1)
{
printf("Problem s odeslanim dat: errno %d", errno);
return ERROR;
}
}
}
編輯
#include "dns_stat.h"
TprogParam processParams(int argc, char *argv[]) {
TprogParam parInfo =
{
.error = false,
.help = false,
.ipadress[0] = '\0',
.port = 0,
.dnsserver[0] = '\0',
.type = false,
.source = false,
.destination = false,
};
if(argc == 1)
{
parInfo.help = true;
}
else
{
int c;
const char *short_options = ":l:p:s:";
const struct option long_options[] = {
{ "type", 0, NULL, 't' },
{ "source", 0, NULL, 'z' },
{ "destination", 0, NULL, 'd' },
{ NULL, 0, NULL, 0 }
};
while((c = getopt_long_only(argc, argv, short_options, long_options, NULL)) != -1) {
switch (c) {
case 'l':
strcpy(parInfo.ipadress,optarg);
break;
case 'p':
parInfo.port = atoi(optarg);
break;
case 's':
strcpy(parInfo.dnsserver,optarg);//optarg);
//parInfo.dnsserver = strdup(optarg);
break;
case 't':
parInfo.type = true;
break;
case 'z':
parInfo.source = true;
break;
case 'd':
parInfo.destination = true;
break;
case '?':
parInfo.error = true;
break;
default:
printf("default");
parInfo.error = true;
abort();
}
}
}
return parInfo;
}
void printHelp()
{
printf("Napoveda\n");
}
void printError(int ecode)
{
if(ecode<EOK||ecode>EUNKNOWN){
ecode = EUNKNOWN;
}
fprintf(stderr, "%s", ECODEMSG[ecode]);
}
int main(int argc, char *argv[])
{
char buf[BUFSIZE];
char serverbuf[BUFSIZE];
int UDPSocket, clientSocket;
int lenght;
int addr_len;
struct addrinfo *clientInfo;
struct addrinfo hintsClient;
struct sockaddr_in serverSocket, clientAddr, serverAddr;
int serverAddrLen = sizeof(serverAddr);
fd_set set, tcpset;
struct timeval tv; // struktura pro timeout
bool end = false;
bool end2 = false;
int m;
TprogParam param = processParams(argc, argv);
if(param.error)
{
printError(EPARAMS);
return ERROR;
}
if(param.help)
{
printHelp();
return EXIT_SUCCESS;
}
//printf("type: %d, source: %d, destination: %d\n", param.type, param.source, param.destination);
memset(&hintsClient, 0, sizeof(struct addrinfo));
hintsClient.ai_family = AF_INET;
hintsClient.ai_socktype = SOCK_DGRAM;
hintsClient.ai_flags = 0;
hintsClient.ai_protocol = IPPROTO_UDP;
int status;
if(param.ipadress[0] == '\0')
{
if((status = getaddrinfo(INADDR_ANY, NULL, &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
else
{
if((status = getaddrinfo(param.ipadress, "13066", &hintsClient, &clientInfo)) != 0)
{
printf("Spatna adresa pro naslouchani");
printError(1);
return ERROR;
}
}
memset(&serverAddr, 0, sizeof(serverAddr));
;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);;
serverAddr.sin_port = htons(53);
// vytvorime socket
if((UDPSocket = socket(clientInfo->ai_family, clientInfo->ai_socktype, clientInfo->ai_protocol)) == -1)
{
printf("Nelze vytvorit udp socket");
printError(1);
return ERROR;
}
if((clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("Nelze vytvorit tcp socket");
printError(1);
return ERROR;
}
// Nastavime socket do neblokovaciho rezimu
if(bind(UDPSocket, clientInfo->ai_addr, clientInfo->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
{
printf("Nelze navazat spojeni pro naslouchani: %d", errno);
return ERROR;
}
}
printf("Poslal jsem zadost o spojeni. Zatimco se spojeni navazuje mohu delat jine veci.\n");
FD_ZERO(&set);
FD_SET(UDPSocket, &set);
tv.tv_sec = 15;
tv.tv_usec = 0;
addr_len = sizeof(struct sockaddr);
while(1)
{
printf("Prijimam pozadavek k vyrizeni.\n");
if ((lenght = recvfrom(UDPSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&clientAddr, &addr_len)) == -1)//recv(UDPSocket, buf, BUFSIZE - 1, 0)) == -1)
{
printf("Nejaka chyba pri prijimani dat");
return ERROR;
}
buf[lenght] = '\0';
printf("Prijata nasledujici data od klienta na predklad dns: %s o delce %d \n", buf, lenght);
if((m = sendto(clientSocket, buf, lenght, 0, (struct sockaddr *)&serverAddr, serverAddrLen)) == -1)
{
printf("Problem s odeslanim dat: %d %s", errno, strerror(errno));
return ERROR;
}
printf("tady");
fflush(stdout);
if((m = recvfrom(clientSocket, buf, BUFSIZE - 1, 0, (struct sockaddr *)&serverAddr,&serverAddrLen)) == -1)
{
printf("nejaka chyba");
return ERROR;
}
printf("Prijata nasledujici data od dns serveru: %s o delce %d \n", buf, lenght);
if((lenght = sendto(UDPSocket, buf, lenght, 0,(struct sockaddr *)&clientAddr, addr_len)) == -1)
{
printf("Problem s odeslanim dat: errno %d %s", errno, strerror(errno));
return ERROR;
}
}
}
就是這樣,並再次請幫助。現在看起來它正在工作。整個循環被執行並挖掘得到響應,但它不包含ANSWER部分。這個問題在哪裏? –
沒關係,我在serverbuf的第二個recvform中和上一個sendto中更改了buf,它正在工作。感謝幫助 –