1
프록시 DNS를 만들고 있는데 dig에서 쿼리를 수신했지만 서버로 보내지 만 dns 서버에서 대답을 얻을 수 없습니다. 내 코드가 좋지 않다는 것을 알고 있지만 몇 시간 동안이 작업을하고 있지만 여전히 잘못 이해할 수는 없습니다. 내 프로그램은 두 번째 recvfrom 전에 막혔다. 누군가 나를 도울 수 있습니까? (BTW이 내 OS는 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;
}
}
}
그게다고 한 번 더 도와주세요. 이제는 작동하는 것처럼 보입니다. 전체 루프가 실행되고 응답을 받지만 응답 섹션이 포함되어 있지 않습니다. 이 문제는 어디에있을 수 있습니까? –
신경 쓰지 마라. 나는 serverbuf와 마지막 sendto의 두 번째 recvform에서 buf를 변경하고 작동 중이다. 도와 주셔서 감사합니다 –