Changeset 678
- Timestamp:
- 04/11/06 18:09:50 (7 years ago)
- Location:
- trunk/pdns/pdns
- Files:
-
- 4 modified
-
dnsparser.cc (modified) (1 diff)
-
pdns_recursor.cc (modified) (20 diffs)
-
rec_channel_rec.cc (modified) (1 diff)
-
syncres.hh (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pdns/pdns/dnsparser.cc
r670 r678 236 236 } 237 237 catch(out_of_range &re) { 238 throw MOADNSException(" Packet parsing error, out of bounds: "+string(re.what()));238 throw MOADNSException("Error parsing packet of "+lexical_cast<string>(len)+" bytes, out of bounds: "+string(re.what())); 239 239 } 240 240 } -
trunk/pdns/pdns/pdns_recursor.cc
r673 r678 269 269 } 270 270 271 map<uint32_t, uint32_t> g_tcpClientCounts; 272 273 struct TCPConnection 274 { 275 int fd; 276 enum {BYTE0, BYTE1, GETQUESTION, DONE} state; 277 int qlen; 278 int bytesread; 279 struct sockaddr_in remote; 280 char data[65535]; 281 time_t startTime; 282 283 void closeAndCleanup() 284 { 285 close(fd); 286 if(!g_tcpClientCounts[remote.sin_addr.s_addr]--) 287 g_tcpClientCounts.erase(remote.sin_addr.s_addr); 288 } 289 }; 290 291 vector<TCPConnection> g_tcpconnections; // all *running* TCP/IP questions (from clients) 292 271 293 void startDoResolve(void *p) 272 294 { … … 352 374 353 375 int ret=writev(dc->d_socket, iov, 2); 354 355 if(ret <= 0 ) 356 L<<Logger::Error<<"Error writing TCP answer to "<<dc->getRemote()<<": "<< (ret ? strerror(errno) : "EOF") <<endl; 376 bool hadError=true; 377 378 if(ret == 0) 379 L<<Logger::Error<<"EOF writing TCP answer to "<<dc->getRemote()<<endl; 380 else if(ret < 0 ) 381 L<<Logger::Error<<"Error writing TCP answer to "<<dc->getRemote()<<": "<< strerror(errno) <<endl; 357 382 else if((unsigned int)ret != 2 + packet.size()) 358 383 L<<Logger::Error<<"Oops, partial answer sent to "<<dc->getRemote()<<" for "<<dc->d_mdp.d_qname<<" (size="<< (2 + packet.size()) <<", sent "<<ret<<")"<<endl; 384 else 385 hadError=false; 386 387 for(vector<TCPConnection>::iterator i=g_tcpconnections.begin();i!=g_tcpconnections.end();++i) { 388 if(i->fd == dc->d_socket) { 389 if(hadError) { 390 i->closeAndCleanup(); 391 g_tcpconnections.erase(i); 392 } 393 else { 394 i->state=TCPConnection::BYTE0; 395 i->startTime=time(0); // needs to be current, TCP is slow anyhow 396 } 397 break; 398 } 399 } 359 400 } 360 401 … … 618 659 } 619 660 620 map<uint32_t, uint32_t> g_tcpClientCounts; 621 struct TCPConnection 622 { 623 int fd; 624 enum {BYTE0, BYTE1, GETQUESTION} state; 625 int qlen; 626 int bytesread; 627 struct sockaddr_in remote; 628 char data[65535]; 629 time_t startTime; 630 631 void closeAndCleanup() 632 { 633 close(fd); 634 if(!g_tcpClientCounts[remote.sin_addr.s_addr]--) 635 g_tcpClientCounts.erase(remote.sin_addr.s_addr); 636 } 637 }; 661 638 662 639 663 #if 0 … … 702 726 ::arg().set("trace","if we should output heaps of logging")="off"; 703 727 ::arg().set("daemon","Operate as a daemon")="yes"; 728 ::arg().set("log-common-errors","If we should log rather common errors")="yes"; 704 729 ::arg().set("chroot","switch to chroot jail")=""; 705 730 ::arg().set("setgid","If set, change group id to this gid for more security")=""; … … 755 780 756 781 L<<Logger::Warning<<"Operating in "<<(sizeof(unsigned long)*8) <<" bits mode"<<endl; 757 L<<Logger::Warning<<"PowerDNS comes with ABSOLUTELY NO WARRANTY. "758 "This is free software, and you are welcome to redistribute it "759 "according to the terms of the GPL version 2."<<endl;760 761 762 g_quiet=::arg().mustDo("quiet");763 if(::arg().mustDo("trace")) {782 L<<Logger::Warning<<"PowerDNS comes with ABSOLUTELY NO WARRANTY. " 783 "This is free software, and you are welcome to redistribute it " 784 "according to the terms of the GPL version 2."<<endl; 785 786 787 g_quiet=::arg().mustDo("quiet"); 788 if(::arg().mustDo("trace")) { 764 789 SyncRes::setLog(true); 765 790 ::arg().set("quiet")="no"; 766 791 g_quiet=false; 767 } 792 } 793 794 bool logCommonErrors=::arg().mustDo("log-common-errors"); 768 795 769 796 makeUDPServerSockets(); … … 815 842 Utility::dropPrivs(newuid, newgid); 816 843 817 vector<TCPConnection> tcpconnections; 844 818 845 counter=0; 819 846 struct timeval now; … … 846 873 int fdmax=max(d_clientsock, s_rcc.d_fd); 847 874 848 if(! tcpconnections.empty())875 if(!g_tcpconnections.empty()) 849 876 gettimeofday(&now, 0); 850 877 851 878 vector<TCPConnection> sweeped; 852 879 853 for(vector<TCPConnection>::iterator i=tcpconnections.begin();i!=tcpconnections.end();++i) { 854 if(now.tv_sec < i->startTime + tcpTimeout) { 855 FD_SET(i->fd, &readfds); 856 fdmax=max(fdmax,i->fd); 880 for(vector<TCPConnection>::iterator i=g_tcpconnections.begin();i!=g_tcpconnections.end();++i) { 881 if(i->state==TCPConnection::DONE || now.tv_sec < i->startTime + tcpTimeout) { // don't timeout when we are working on the question! 857 882 sweeped.push_back(*i); 883 if(i->state!=TCPConnection::DONE) { // we don't listen for data when we are processing the question 884 FD_SET(i->fd, &readfds); 885 fdmax=max(fdmax,i->fd); 886 } 858 887 } 859 888 else { 860 L<<Logger::Error<<"TCP timeout from client "<<inet_ntoa(i->remote.sin_addr)<<endl; 889 if(logCommonErrors) 890 L<<Logger::Error<<"TCP timeout from client "<<inet_ntoa(i->remote.sin_addr)<<endl; 861 891 i->closeAndCleanup(); 862 892 } 863 893 } 864 sweeped.swap( tcpconnections);894 sweeped.swap(g_tcpconnections); 865 895 866 896 for(vector<int>::const_iterator i=d_udpserversocks.begin(); i!=d_udpserversocks.end(); ++i) { … … 868 898 fdmax=max(fdmax,*i); 869 899 } 870 if( tcpconnections.size() < maxTcpClients)900 if(g_tcpconnections.size() < maxTcpClients) 871 901 for(tcpserversocks_t::const_iterator i=s_tcpserversocks.begin(); i!=s_tcpserversocks.end(); ++i) { 872 902 FD_SET(*i, &readfds ); … … 904 934 } 905 935 906 if(FD_ISSET(d_clientsock,&readfds)) { // do we have a UDP question response ?936 if(FD_ISSET(d_clientsock,&readfds)) { // do we have a UDP question response from a server ("we are the client", hence d_clientsock) 907 937 while((d_len=recvfrom(d_clientsock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 908 try { 909 DNSComboWriter dc(data, d_len, now); 910 dc.setRemote((struct sockaddr *)&fromaddr, addrlen);911 912 if(d c.d_mdp.d_header.qr) {938 dnsheader dh; 939 if(d_len >= sizeof(dnsheader)) { 940 memcpy(&dh, data, sizeof(dh)); 941 942 if(dh.qr) { 913 943 pident.remote=fromaddr; 914 pident.id=d c.d_mdp.d_header.id;944 pident.id=dh.id; 915 945 string packet; 916 946 packet.assign(data, d_len); … … 918 948 } 919 949 else 920 L<<Logger::Warning<<"Ignoring question on outgoing socket from "<<dc.getRemote()<<endl; 921 } 922 catch(MOADNSException& mde) { 923 L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": "<<mde.what()<<endl; 950 L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<endl; 951 } 952 else { 953 g_stats.serverParseError++; 954 if(logCommonErrors) 955 L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": packet too small"<<endl; 924 956 } 925 957 } … … 929 961 if(FD_ISSET(*i,&readfds)) { // do we have a new question on udp? 930 962 while((d_len=recvfrom(*i, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 931 g_stats.queryrate.pulse(now);963 // g_stats.queryrate.pulse(now); // (broken) 932 964 if(g_allowFrom && !g_allowFrom->match(&fromaddr)) { 933 965 g_stats.unauthorizedUDP++; … … 940 972 dc->setRemote((struct sockaddr *)&fromaddr, addrlen); 941 973 942 if(dc->d_mdp.d_header.qr) 943 L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 974 if(dc->d_mdp.d_header.qr) { 975 if(logCommonErrors) 976 L<<Logger::Error<<"Ignoring answer from "<<dc->getRemote()<<" on server socket!"<<endl; 977 } 944 978 else { 945 979 ++g_stats.qcounter; … … 950 984 } 951 985 catch(MOADNSException& mde) { 986 g_stats.clientParseError++; 952 987 L<<Logger::Error<<"Unable to parse packet from remote UDP client "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": "<<mde.what()<<endl; 953 988 } … … 957 992 958 993 for(tcpserversocks_t::const_iterator i=s_tcpserversocks.begin(); i!=s_tcpserversocks.end(); ++i) { 959 if(FD_ISSET(*i ,&readfds)) { // do we have a new TCP connection ?994 if(FD_ISSET(*i ,&readfds)) { // do we have a new TCP connection from a client? 960 995 struct sockaddr_in addr; 961 996 socklen_t addrlen=sizeof(addr); … … 980 1015 tc.remote=addr; 981 1016 tc.startTime=now.tv_sec; 982 tcpconnections.push_back(tc);1017 g_tcpconnections.push_back(tc); 983 1018 } 984 1019 } … … 1045 1080 1046 1081 // very braindead TCP incoming question parser 1047 for(vector<TCPConnection>::iterator i= tcpconnections.begin();i!=tcpconnections.end();++i) {1082 for(vector<TCPConnection>::iterator i=g_tcpconnections.begin();i!=g_tcpconnections.end();++i) { 1048 1083 if(FD_ISSET(i->fd, &readfds)) { 1049 1084 if(i->state==TCPConnection::BYTE0) { … … 1058 1093 if(!bytes || bytes < 0) { 1059 1094 i->closeAndCleanup(); 1060 tcpconnections.erase(i);1095 g_tcpconnections.erase(i); 1061 1096 break; 1062 1097 } … … 1070 1105 } 1071 1106 if(!bytes || bytes < 0) { 1072 L<<Logger::Error<<"TCP Remote "<<sockAddrToString(&i->remote,sizeof(i->remote))<<" disconnected after first byte"<<endl; 1107 if(logCommonErrors) 1108 L<<Logger::Error<<"TCP client "<<sockAddrToString(&i->remote,sizeof(i->remote))<<" disconnected after first byte"<<endl; 1073 1109 i->closeAndCleanup(); 1074 tcpconnections.erase(i);1110 g_tcpconnections.erase(i); 1075 1111 break; 1076 1112 } 1077 1078 1113 } 1079 1114 else if(i->state==TCPConnection::GETQUESTION) { 1080 1115 int bytes=read(i->fd,i->data + i->bytesread,i->qlen - i->bytesread); 1081 1116 if(!bytes || bytes < 0) { 1082 L<<Logger::Error<<"TCP Remote"<<sockAddrToString(&i->remote,sizeof(i->remote))<<" disconnected while reading question body"<<endl;1117 L<<Logger::Error<<"TCP client "<<sockAddrToString(&i->remote,sizeof(i->remote))<<" disconnected while reading question body"<<endl; 1083 1118 i->closeAndCleanup(); 1084 tcpconnections.erase(i);1119 g_tcpconnections.erase(i); 1085 1120 break; 1086 1121 } 1087 1122 i->bytesread+=bytes; 1088 1123 if(i->bytesread==i->qlen) { 1089 i->state=TCPConnection:: BYTE0;1124 i->state=TCPConnection::DONE; // this makes us immune from timeouts, from now on *we* are responsible 1090 1125 DNSComboWriter* dc=0; 1091 1126 try { … … 1093 1128 } 1094 1129 catch(MOADNSException &mde) { 1095 L<<Logger::Error<<"Unable to parse packet from remote TCP client "<<sockAddrToString(&i->remote,sizeof(i->remote))<<endl; 1130 g_stats.clientParseError++; 1131 L<<Logger::Error<<"Unable to parse packet from TCP client "<<sockAddrToString(&i->remote,sizeof(i->remote))<<endl; 1096 1132 i->closeAndCleanup(); 1097 tcpconnections.erase(i);1133 g_tcpconnections.erase(i); 1098 1134 break; 1099 1135 } … … 1108 1144 ++g_stats.tcpqcounter; 1109 1145 MT->makeThread(startDoResolve, dc); 1146 break; 1110 1147 } 1111 1148 } -
trunk/pdns/pdns/rec_channel_rec.cc
r669 r678 144 144 addGetStat("tcp-client-overflow", &g_stats.tcpClientOverflow); 145 145 146 addGetStat("client-parse-errors", &g_stats.clientParseError); 147 addGetStat("server-parse-errors", &g_stats.serverParseError); 148 146 149 addGetStat("answers0-1", &g_stats.answers0_1); 147 150 addGetStat("answers1-10", &g_stats.answers1_10); -
trunk/pdns/pdns/syncres.hh
r670 r678 357 357 uint64_t unauthorizedTCP; 358 358 uint64_t tcpClientOverflow; 359 uint64_t clientParseError; 360 uint64_t serverParseError; 359 361 }; 360 362