| 453 | | void makeClientSocket() |
| 454 | | { |
| | 454 | // this stuff is a tad complicated. There are two client sockets, the current one and the previous one (prevclientsocket) |
| | 455 | // if this function is called, and more than 5 seconds have passed since the previous call, the previous client socket is closed, |
| | 456 | // and replaced by the current one, which is then reopened. |
| | 457 | void remakeClientSocket() |
| | 458 | { |
| | 459 | static time_t lastChange; |
| | 460 | |
| | 461 | if(d_clientsock>=0 && !::arg()["query-local-port"].empty()) // already have a port, and we are fixed |
| | 462 | return; |
| | 463 | |
| | 464 | if(!lastChange) |
| | 465 | lastChange=time(0)-10; |
| | 466 | |
| | 467 | if(lastChange > time(0) - 5) |
| | 468 | return; |
| | 469 | |
| | 470 | lastChange=time(0); |
| | 471 | |
| | 472 | if(d_prevclientsock >= 0) { |
| | 473 | close(d_prevclientsock); |
| | 474 | } |
| | 475 | d_prevclientsock=d_clientsock; |
| | 476 | |
| | 810 | |
| | 811 | if(!::arg()["allow-from"].empty()) { |
| | 812 | g_allowFrom=new NetmaskGroup; |
| | 813 | vector<string> ips; |
| | 814 | stringtok(ips, ::arg()["allow-from"], ", "); |
| | 815 | L<<Logger::Warning<<"Only allowing queries from: "; |
| | 816 | for(vector<string>::const_iterator i = ips.begin(); i!= ips.end(); ++i) { |
| | 817 | g_allowFrom->addMask(*i); |
| | 818 | if(i!=ips.begin()) |
| | 819 | L<<Logger::Warning<<", "; |
| | 820 | L<<Logger::Warning<<*i; |
| | 821 | } |
| | 822 | L<<Logger::Warning<<endl; |
| | 823 | } |
| | 824 | else if(::arg()["local-address"]!="127.0.0.1" && ::arg().asNum("local-port")==53) |
| | 825 | L<<Logger::Error<<"WARNING: Allowing queries from all IP addresses - this can be a security risk!"<<endl; |
| 938 | | |
| 939 | | if(FD_ISSET(d_clientsock,&readfds)) { // do we have a UDP question response from a server ("we are the client", hence d_clientsock) |
| 940 | | while((d_len=recvfrom(d_clientsock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { |
| 941 | | dnsheader dh; |
| 942 | | if((size_t) d_len >= sizeof(dnsheader)) { |
| 943 | | memcpy(&dh, data, sizeof(dh)); |
| 944 | | |
| 945 | | if(dh.qr && dh.qdcount) { |
| 946 | | pident.remote=fromaddr; |
| 947 | | pident.id=dh.id; |
| 948 | | string packet; |
| 949 | | packet.assign(data, d_len); |
| 950 | | if(!MT->sendEvent(pident, &packet)) { |
| 951 | | if(logCommonErrors) |
| 952 | | L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; |
| 953 | | g_stats.unexpectedCount++; |
| | 981 | |
| | 982 | for(int port=0; port < 2; ++port) { |
| | 983 | if(port && d_prevclientsock < 0) |
| | 984 | break; |
| | 985 | int sock = port ? d_prevclientsock : d_clientsock; |
| | 986 | |
| | 987 | if(FD_ISSET(sock,&readfds)) { // do we have a UDP question response from a server ("we are the client", hence d_clientsock) |
| | 988 | while((d_len=recvfrom(sock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { |
| | 989 | dnsheader dh; |
| | 990 | if((size_t) d_len >= sizeof(dnsheader)) { |
| | 991 | memcpy(&dh, data, sizeof(dh)); |
| | 992 | |
| | 993 | if(dh.qr && dh.qdcount) { |
| | 994 | pident.remote=fromaddr; |
| | 995 | pident.id=dh.id; |
| | 996 | string packet; |
| | 997 | packet.assign(data, d_len); |
| | 998 | if(!MT->sendEvent(pident, &packet)) { |
| | 999 | if(logCommonErrors) |
| | 1000 | L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; |
| | 1001 | g_stats.unexpectedCount++; |
| | 1002 | } |
| 955 | | } |
| 956 | | else |
| 957 | | L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<endl; |
| 958 | | } |
| 959 | | else { |
| 960 | | g_stats.serverParseError++; |
| 961 | | if(logCommonErrors) |
| 962 | | L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": packet too small"<<endl; |
| | 1004 | else |
| | 1005 | L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<endl; |
| | 1006 | } |
| | 1007 | else { |
| | 1008 | g_stats.serverParseError++; |
| | 1009 | if(logCommonErrors) |
| | 1010 | L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": packet too small"<<endl; |
| | 1011 | } |