Changeset 726
- Timestamp:
- 04/18/06 18:44:10 (7 years ago)
- Location:
- trunk/pdns/pdns
- Files:
-
- 6 modified
-
dnspacket.cc (modified) (2 diffs)
-
dnsproxy.cc (modified) (1 diff)
-
iputils.hh (modified) (5 diffs)
-
misc.cc (modified) (2 diffs)
-
misc.hh (modified) (1 diff)
-
pdns_recursor.cc (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pdns/pdns/dnspacket.cc
r680 r726 53 53 string DNSPacket::getLocal() const 54 54 { 55 struct sockaddr_in sa;56 int addrlen=sizeof(s truct sockaddr_in);55 struct sockaddr_in6 sa; 56 int addrlen=sizeof(sa); 57 57 58 58 getsockname(d_socket, (struct sockaddr *)&sa, (socklen_t *)&addrlen); 59 return sockAddrToString(&sa , (socklen_t)addrlen);59 return sockAddrToString(&sa); 60 60 } 61 61 … … 63 63 string DNSPacket::getRemote() const 64 64 { 65 return sockAddrToString((struct sockaddr_in *)remote , d_socklen);65 return sockAddrToString((struct sockaddr_in *)remote); 66 66 } 67 67 -
trunk/pdns/pdns/dnsproxy.cc
r680 r726 140 140 if(i->second.created) 141 141 L<<Logger::Warning<<"Recursive query for remote "<< 142 sockAddrToString((struct sockaddr_in *)&i->second.remote , i->second.addrlen)<<" with internal id "<<n<<142 sockAddrToString((struct sockaddr_in *)&i->second.remote)<<" with internal id "<<n<< 143 143 " was not answered by backend within timeout, reusing id"<<endl; 144 144 -
trunk/pdns/pdns/iputils.hh
r681 r726 35 35 using namespace std; 36 36 37 union ComboAddress { 38 struct sockaddr_in sin4; 39 struct sockaddr_in6 sin6; 40 41 bool operator<(const ComboAddress& rhs) const 42 { 43 if(sin4.sin_family < rhs.sin4.sin_family) 44 return true; 45 if(sin4.sin_family > rhs.sin4.sin_family) 46 return false; 47 48 if(sin4.sin_family == AF_INET) 49 return sin4.sin_addr.s_addr < rhs.sin4.sin_addr.s_addr; 50 else 51 return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6_addr.s6_addr, 16) < 0; 52 } 53 54 string toString() const 55 { 56 char tmp[128]; 57 if(sin4.sin_family==AF_INET && !inet_ntop(AF_INET, ( const char * ) &sin4.sin_addr, tmp, sizeof(tmp))) 58 return tmp; 59 60 if(sin4.sin_family==AF_INET6 && !inet_ntop(AF_INET6, ( const char * ) &sin6.sin6_addr, tmp, sizeof(tmp))) 61 return tmp; 62 63 return tmp; 64 } 65 }; 66 37 67 /** This exception is thrown by the Netmask class and by extension by the NetmaskGroup class */ 38 68 class NetmaskException: public AhuException … … 42 72 }; 43 73 74 inline ComboAddress makeComboAddress(const string& str) 75 { 76 ComboAddress address; 77 address.sin4.sin_family=AF_INET; 78 if(inet_pton(AF_INET, str.c_str(), &address.sin4.sin_addr) <= 0) { 79 address.sin4.sin_family=AF_INET6; 80 if(inet_pton(AF_INET6, str.c_str(), &address.sin6.sin6_addr) <= 0) 81 throw NetmaskException("Unable to convert '"+str+"' to a netmask"); 82 } 83 return address; 84 } 85 44 86 /** This class represents a netmask and can be queried to see if a certain 45 87 IP address is matched by this mask */ 46 47 88 class Netmask 48 89 { … … 51 92 Netmask(const string &mask) 52 93 { 53 char *p;54 uint8_t bits=32;55 d_mask=0xFFFFFFFF;56 57 if((p=strchr(mask.c_str(),'/')))58 bits = (uint8_t) atoi(p+1);59 60 if( bits < 32 )61 d_mask=~(0xFFFFFFFF>>bits);62 63 struct in_addr a;64 if(!Utility::inet_aton(mask.substr(0,p-mask.c_str()).c_str(), &a))65 throw NetmaskException("Unable to convert '"+mask+"' to a netmask");66 d_network=htonl(a.s_addr);94 pair<string,string> split=splitField(mask,'/'); 95 d_network=makeComboAddress(split.first); 96 97 if(!split.second.empty()) { 98 d_bits = (uint8_t) atoi(split.second.c_str()); 99 if(d_bits<32) 100 d_mask=~(0xFFFFFFFF>>d_bits); 101 } 102 else if(d_network.sin4.sin_family==AF_INET) { 103 d_bits = 32; 104 d_mask = 0xFFFFFFFF; 105 } 106 else 107 d_bits=128; 67 108 } 68 109 69 110 //! If this IP address in socket address matches 70 bool match(const struct sockaddr_in*ip) const111 bool match(const ComboAddress *ip) const 71 112 { 72 return match(htonl((unsigned int)ip->sin_addr.s_addr)); 113 if(d_network.sin4.sin_family != ip->sin4.sin_family) { 114 return false; 115 } 116 if(d_network.sin4.sin_family == AF_INET) { 117 return match4(htonl((unsigned int)ip->sin4.sin_addr.s_addr)); 118 } 119 if(d_network.sin6.sin6_family == AF_INET6) { 120 uint8_t bytes=d_bits/8, n; 121 const uint8_t *us=(const uint8_t*) &d_network.sin6.sin6_addr.s6_addr; 122 const uint8_t *them=(const uint8_t*) &ip->sin6.sin6_addr.s6_addr; 123 124 for(n=0; n < bytes; ++n) { 125 if(us[n]!=them[n]) { 126 return false; 127 } 128 } 129 // still here, now match remaining bits 130 uint8_t bits=bytes%8; 131 uint8_t mask= ~(0xFF>>bits); 132 return((us[n] & mask) == (them[n] & mask)); 133 } 134 return false; 73 135 } 74 136 … … 76 138 bool match(const string &ip) const 77 139 { 78 struct in_addr a; 79 Utility::inet_aton(ip.c_str(), &a); 80 return match(htonl(a.s_addr)); 140 ComboAddress address=makeComboAddress(ip); 141 return match(&address); 81 142 } 82 143 83 144 //! If this IP address in native format matches 84 bool match (uint32_t ip) const145 bool match4(uint32_t ip) const 85 146 { 86 return (ip & d_mask) == ( d_network& d_mask);147 return (ip & d_mask) == (ntohl(d_network.sin4.sin_addr.s_addr) & d_mask); 87 148 } 88 149 89 90 150 private: 91 uint32_td_network;151 ComboAddress d_network; 92 152 uint32_t d_mask; 153 uint8_t d_bits; 93 154 }; 94 155 … … 100 161 public: 101 162 //! If this IP address is matched by any of the classes within 102 bool match( struct sockaddr_in*ip)163 bool match(ComboAddress *ip) 103 164 { 104 165 for(container_t::const_iterator i=d_masks.begin();i!=d_masks.end();++i) -
trunk/pdns/pdns/misc.cc
r692 r726 367 367 } 368 368 369 const string sockAddrToString(struct sockaddr_in *remote, Utility::socklen_t socklen) 369 370 const string sockAddrToString(struct sockaddr_in *remote) 370 371 { 371 if( socklen==sizeof(struct sockaddr_in)) {372 if(remote->sin_family == AF_INET) { 372 373 struct sockaddr_in sip; 373 374 memcpy(&sip,(struct sockaddr_in*)remote,sizeof(sip)); 374 375 return inet_ntoa(sip.sin_addr); 375 376 } 376 #ifdef HAVE_IPV6377 377 else { 378 378 char tmp[128]; … … 383 383 return tmp; 384 384 } 385 #endif386 387 return "untranslateable";388 385 } 389 386 -
trunk/pdns/pdns/misc.hh
r692 r726 182 182 struct timeval d_set; 183 183 }; 184 const string sockAddrToString(struct sockaddr_in *remote , Utility::socklen_t socklen);184 const string sockAddrToString(struct sockaddr_in *remote); 185 185 int sendData(const char *buffer, int replen, int outsock); 186 186 -
trunk/pdns/pdns/pdns_recursor.cc
r724 r726 72 72 NetmaskGroup* g_allowFrom; 73 73 string s_programname="pdns_recursor"; 74 int g_tcpListenSocket;74 vector<int> g_tcpListenSockets; 75 75 int g_tcpTimeout; 76 76 … … 79 79 {} 80 80 MOADNSParser d_mdp; 81 void setRemote( struct sockaddr* sa, socklen_t len)81 void setRemote(ComboAddress* sa) 82 82 { 83 memcpy((void *)d_remote, (void *)sa, len);84 d_socklen= len;83 d_remote=*sa; 84 d_socklen= d_remote.sin4.sin_family == AF_INET ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); 85 85 } 86 86 … … 92 92 string getRemote() const 93 93 { 94 return sockAddrToString((struct sockaddr_in *)d_remote, d_socklen);94 return d_remote.toString(); 95 95 } 96 96 97 97 struct timeval d_now; 98 char d_remote[sizeof(sockaddr_in6)];98 ComboAddress d_remote; 99 99 socklen_t d_socklen; 100 100 bool d_tcp; … … 311 311 memcpy(data,packet.c_str(),min(len,*d_len)); 312 312 if(*nearMissLimit && pident.nearMisses > *nearMissLimit) { 313 L<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<sockAddrToString((struct sockaddr_in*)toaddr , sizeof(pident.remote))<<", assuming spoof attempt."<<endl;313 L<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<sockAddrToString((struct sockaddr_in*)toaddr)<<", assuming spoof attempt."<<endl; 314 314 g_stats.spoofCount++; 315 315 return -1; … … 405 405 } 406 406 407 map< uint32_t, uint32_t> g_tcpClientCounts;407 map<ComboAddress, uint32_t> g_tcpClientCounts; 408 408 409 409 struct TCPConnection … … 413 413 int qlen; 414 414 int bytesread; 415 struct sockaddr_inremote;415 ComboAddress remote; 416 416 char data[65535]; 417 417 time_t startTime; … … 420 420 { 421 421 close(fd); 422 if(!g_tcpClientCounts[remote .sin_addr.s_addr]--)423 g_tcpClientCounts.erase(remote .sin_addr.s_addr);422 if(!g_tcpClientCounts[remote]--) 423 g_tcpClientCounts.erase(remote); 424 424 s_currentConnections--; 425 425 } … … 500 500 sendit:; 501 501 if(!dc->d_tcp) { 502 sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)( dc->d_remote), dc->d_socklen);502 sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(&dc->d_remote), dc->d_socklen); 503 503 } 504 504 else { … … 617 617 if(!bytes || bytes < 0) { 618 618 if(g_logCommonErrors) 619 L<<Logger::Error<<"TCP client "<< sockAddrToString(&conn.remote,sizeof(conn.remote))<<" disconnected after first byte"<<endl;619 L<<Logger::Error<<"TCP client "<< conn.remote.toString() <<" disconnected after first byte"<<endl; 620 620 TCPConnection tmp(conn); 621 621 g_fdm->removeReadFD(fd); … … 627 627 int bytes=read(conn.fd,conn.data + conn.bytesread,conn.qlen - conn.bytesread); 628 628 if(!bytes || bytes < 0) { 629 L<<Logger::Error<<"TCP client "<< sockAddrToString(&conn.remote,sizeof(conn.remote))<<" disconnected while reading question body"<<endl;629 L<<Logger::Error<<"TCP client "<< conn.remote.toString() <<" disconnected while reading question body"<<endl; 630 630 TCPConnection tmp(conn); 631 631 g_fdm->removeReadFD(fd); … … 643 643 catch(MOADNSException &mde) { 644 644 g_stats.clientParseError++; 645 L<<Logger::Error<<"Unable to parse packet from TCP client "<< sockAddrToString(&conn.remote,sizeof(conn.remote))<<endl;645 L<<Logger::Error<<"Unable to parse packet from TCP client "<< conn.remote.toString() <<endl; 646 646 TCPConnection tmp(conn); 647 647 g_fdm->removeReadFD(fd); … … 652 652 dc->setSocket(conn.fd); 653 653 dc->d_tcp=true; 654 dc->setRemote( (struct sockaddr *)&conn.remote,sizeof(conn.remote));654 dc->setRemote(&conn.remote); 655 655 if(dc->d_mdp.d_header.qr) 656 656 L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; … … 668 668 void handleNewTCPQuestion(int fd, boost::any& ) 669 669 { 670 struct sockaddr_inaddr;670 ComboAddress addr; 671 671 socklen_t addrlen=sizeof(addr); 672 672 int newsock=accept(fd, (struct sockaddr*)&addr, &addrlen); … … 678 678 } 679 679 680 if(g_maxTCPPerClient && g_tcpClientCounts.count(addr .sin_addr.s_addr) && g_tcpClientCounts[addr.sin_addr.s_addr] >= g_maxTCPPerClient) {680 if(g_maxTCPPerClient && g_tcpClientCounts.count(addr) && g_tcpClientCounts[addr] >= g_maxTCPPerClient) { 681 681 g_stats.tcpClientOverflow++; 682 682 close(newsock); // don't call TCPConnection::closeAndCleanup here - did not enter it in the counts yet! 683 683 return; 684 684 } 685 g_tcpClientCounts[addr .sin_addr.s_addr]++;685 g_tcpClientCounts[addr]++; 686 686 Utility::setNonBlocking(newsock); 687 687 TCPConnection tc; … … 700 700 void makeTCPServerSockets() 701 701 { 702 int fd; 702 703 vector<string>locals; 703 704 stringtok(locals,::arg()["local-address"]," ,"); … … 706 707 throw AhuException("No local address specified"); 707 708 709 ComboAddress sin; 708 710 for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) { 709 g_tcpListenSocket=socket(AF_INET, SOCK_STREAM,0);710 if(g_tcpListenSocket<0)711 throw AhuException("Making a server socket for resolver: "+stringerror());712 713 struct sockaddr_in sin;714 711 memset((char *)&sin,0, sizeof(sin)); 715 716 sin.sin_family = AF_INET; 717 if(!IpToU32(*i, &sin.sin_addr.s_addr)) 718 throw AhuException("Unable to resolve local address '"+ *i +"'"); 712 ComboAddress sin; 713 sin.sin4.sin_family = AF_INET; 714 if(!IpToU32(*i, &sin.sin4.sin_addr.s_addr)) { 715 sin.sin6.sin6_family = AF_INET6; 716 if(inet_pton(AF_INET6, i->c_str(), &sin.sin6.sin6_addr) <= 0) 717 throw AhuException("Unable to resolve local address '"+ *i +"'"); 718 } 719 720 fd=socket(sin.sin6.sin6_family, SOCK_STREAM, 0); 721 if(fd<0) 722 throw AhuException("Making a TCP server socket for resolver: "+stringerror()); 719 723 720 724 int tmp=1; 721 if(setsockopt( g_tcpListenSocket,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) {725 if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) { 722 726 L<<Logger::Error<<"Setsockopt failed for TCP listening socket"<<endl; 723 727 exit(1); … … 725 729 726 730 #ifdef TCP_DEFER_ACCEPT 727 if(setsockopt(g_tcpListenSocket, SOL_TCP,TCP_DEFER_ACCEPT,(char*)&tmp,sizeof tmp) >= 0) { 728 L<<Logger::Error<<"Enabled TCP data-ready filter for (slight) DoS protection"<<endl; 731 if(setsockopt(fd, SOL_TCP,TCP_DEFER_ACCEPT,(char*)&tmp,sizeof tmp) >= 0) { 732 if(i==locals.begin()) 733 L<<Logger::Error<<"Enabled TCP data-ready filter for (slight) DoS protection"<<endl; 729 734 } 730 735 #endif 731 736 732 sin.sin _port = htons(::arg().asNum("local-port"));733 734 if (::bind( g_tcpListenSocket, (struct sockaddr *)&sin, sizeof(sin))<0)737 sin.sin4.sin_port = htons(::arg().asNum("local-port")); 738 int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6); 739 if (::bind(fd, (struct sockaddr *)&sin, socklen )<0) 735 740 throw AhuException("Binding TCP server socket for "+*i+": "+stringerror()); 736 741 737 Utility::setNonBlocking( g_tcpListenSocket);738 setSendBuffer( g_tcpListenSocket, 65000);739 listen( g_tcpListenSocket, 128);740 g_fdm->addReadFD( g_tcpListenSocket, handleNewTCPQuestion);741 L<<Logger::Error<<"Listening for TCP queries on "<< inet_ntoa(sin.sin_addr)<<":"<<::arg().asNum("local-port")<<endl;742 Utility::setNonBlocking(fd); 743 setSendBuffer(fd, 65000); 744 listen(fd, 128); 745 g_fdm->addReadFD(fd, handleNewTCPQuestion); 746 L<<Logger::Error<<"Listening for TCP queries on "<< sockAddrToString(&sin.sin4) <<":"<<::arg().asNum("local-port")<<endl; 742 747 } 743 748 } … … 747 752 int d_len; 748 753 char data[1500]; 749 struct sockaddr_infromaddr;754 ComboAddress fromaddr; 750 755 socklen_t addrlen=sizeof(fromaddr); 751 756 … … 759 764 DNSComboWriter* dc = new DNSComboWriter(data, d_len, g_now); 760 765 761 dc->setRemote( (struct sockaddr *)&fromaddr, addrlen);766 dc->setRemote(&fromaddr); 762 767 763 768 if(dc->d_mdp.d_header.qr) { … … 774 779 catch(MOADNSException& mde) { 775 780 g_stats.clientParseError++; 776 L<<Logger::Error<<"Unable to parse packet from remote UDP client "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": "<<mde.what()<<endl;781 L<<Logger::Error<<"Unable to parse packet from remote UDP client "<<fromaddr.toString() <<": "<<mde.what()<<endl; 777 782 } 778 783 } … … 793 798 794 799 for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) { 795 int fd=socket(AF_INET, SOCK_DGRAM,0); 800 ComboAddress sin; 801 memset(&sin, 0, sizeof(sin)); 802 sin.sin4.sin_family = AF_INET; 803 if(!IpToU32(*i, &sin.sin4.sin_addr.s_addr)) { 804 sin.sin6.sin6_family = AF_INET6; 805 if(inet_pton(AF_INET6, i->c_str(), &sin.sin6.sin6_addr) <= 0) 806 throw AhuException("Unable to resolve local address '"+ *i +"'"); 807 } 808 809 int fd=socket(sin.sin4.sin_family, SOCK_DGRAM,0); 796 810 if(fd<0) 797 throw AhuException("Making a server socket for resolver: "+stringerror()); 811 throw AhuException("Making a UDP server socket for resolver: "+stringerror()); 812 798 813 setReceiveBuffer(fd, 200000); 799 struct sockaddr_in sin; 800 memset((char *)&sin,0, sizeof(sin)); 801 802 sin.sin_family = AF_INET; 803 if(!IpToU32(*i, &sin.sin_addr.s_addr)) 804 throw AhuException("Unable to resolve local address '"+ *i +"'"); 805 806 sin.sin_port = htons(::arg().asNum("local-port")); 807 808 if (::bind(fd, (struct sockaddr *)&sin, sizeof(sin))<0) 814 sin.sin4.sin_port = htons(::arg().asNum("local-port")); 815 816 int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6); 817 if (::bind(fd, (struct sockaddr *)&sin, socklen)<0) 809 818 throw AhuException("Resolver binding to server socket for "+*i+": "+stringerror()); 810 819 811 820 Utility::setNonBlocking(fd); 812 821 g_fdm->addReadFD(fd, handleNewUDPQuestion); 813 L<<Logger::Error<<"Listening for UDP queries on "<<inet_ntoa(sin.sin_addr)<<":"<<::arg().asNum("local-port")<<endl; 822 g_tcpListenSockets.push_back(fd); 823 L<<Logger::Error<<"Listening for UDP queries on "<<sin.toString()<<":"<<::arg().asNum("local-port")<<endl; 814 824 } 815 825 } … … 1061 1071 g_stats.serverParseError++; 1062 1072 if(g_logCommonErrors) 1063 L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr , addrlen) <<1073 L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr) << 1064 1074 ": packet smalller than DNS header"<<endl; 1065 1075 } … … 1100 1110 } 1101 1111 else 1102 L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr , addrlen) <<endl;1112 L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr) <<endl; 1103 1113 } 1104 1114 … … 1292 1302 if(conn.state != TCPConnection::DONE) { 1293 1303 if(g_logCommonErrors) 1294 L<<Logger::Warning<<"Timeout from remote TCP client "<< sockAddrToString(&conn.remote,sizeof(conn.remote))<<endl;1304 L<<Logger::Warning<<"Timeout from remote TCP client "<< conn.remote.toString() <<endl; 1295 1305 g_fdm->removeReadFD(i->first); 1296 1306 conn.closeAndCleanup(); … … 1309 1319 1310 1320 if(listenOnTCP) { 1311 if(TCPConnection::s_currentConnections > maxTcpClients) { 1312 g_fdm->removeReadFD(g_tcpListenSocket); 1321 if(TCPConnection::s_currentConnections > maxTcpClients) { // shutdown 1322 for_each(g_tcpListenSockets.begin(), g_tcpListenSockets.end(), 1323 boost::bind(&FDMultiplexer::removeReadFD, g_fdm, _1)); 1313 1324 listenOnTCP=false; 1314 1325 } 1315 1326 } 1316 1327 else { 1317 if(TCPConnection::s_currentConnections <= maxTcpClients) { 1318 g_fdm->addReadFD(g_tcpListenSocket, handleNewTCPQuestion); 1328 if(TCPConnection::s_currentConnections <= maxTcpClients) { // reenable 1329 for_each(g_tcpListenSockets.begin(), g_tcpListenSockets.end(), 1330 boost::bind(&FDMultiplexer::addReadFD, 1331 g_fdm, _1, handleNewTCPQuestion, boost::any())); 1319 1332 listenOnTCP=true; 1320 1333 }