2012-11-17 3 views
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; 
    } 
    } 
} 

답변

1
여기

적어도 두 가지 문제 :

serverAddr.sin_addr.s_addr = inet_addr(param.dnsserver);; /* line 1 */ 
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* line 2 */ 
serverAddr.sin_port = 53; /* line 3 */ 
  • 2 호선 덮어 쓰기 s의 2 호선을 제거하십시오.
  • 라인 3을 network byte order으로 변환하려면 htons(53)으로 변경해야합니다.
+0

그게다고 한 번 더 도와주세요. 이제는 작동하는 것처럼 보입니다. 전체 루프가 실행되고 응답을 받지만 응답 섹션이 포함되어 있지 않습니다. 이 문제는 어디에있을 수 있습니까? –

+0

신경 쓰지 마라. 나는 serverbuf와 마지막 sendto의 두 번째 recvform에서 buf를 변경하고 작동 중이다. 도와 주셔서 감사합니다 –

관련 문제