Changeset 1082
- Timestamp:
- 08/13/07 16:40:02 (3 years ago)
- Files:
-
- 1 modified
-
trunk/pdns/pdns/nproxy.cc (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pdns/pdns/nproxy.cc
r1077 r1082 10 10 #include <boost/multi_index/ordered_index.hpp> 11 11 #include <boost/multi_index/key_extractors.hpp> 12 #include <boost/algorithm/string.hpp> 13 #include <sys/types.h> 14 #include <sys/stat.h> 15 #include <fcntl.h> 12 16 13 17 #include "mplexer.hh" … … 22 26 SelectFDMultiplexer g_fdm; 23 27 int g_pdnssocket; 28 bool g_verbose; 24 29 25 30 struct NotificationInFlight … … 32 37 }; 33 38 34 map<uint16_t, NotificationInFlight> g_nifs; 39 typedef map<uint16_t, NotificationInFlight> nifs_t; 40 nifs_t g_nifs; 35 41 36 42 void handleOutsideUDPPacket(int fd, boost::any&) … … 55 61 nif.origID = mdp.d_header.id; 56 62 57 cerr<<" Packetfor: "<< nif.domain << endl;63 cerr<<"External notification received for: "<< nif.domain << endl; 58 64 59 65 if(mdp.d_header.opcode != Opcode::Notify || mdp.d_qtype != QType::SOA) { … … 89 95 socklen_t socklen=sizeof(nif.source); 90 96 91 int res=recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&nif.source, &socklen);92 if(! res)97 int len=recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&nif.source, &socklen); 98 if(!len) 93 99 return; 94 100 95 if( res< 0)101 if(len < 0) 96 102 throw runtime_error("reading packet from remote: "+stringerror()); 97 103 98 string packet(buffer, res);104 string packet(buffer, len); 99 105 MOADNSParser mdp(packet); 100 106 101 cerr<<"Inside packetfor: "<<mdp.d_qname<<endl;107 cerr<<"Inside notification response for: "<<mdp.d_qname<<endl; 102 108 103 109 if(!g_nifs.count(mdp.d_header.id)) { … … 108 114 nif=g_nifs[mdp.d_header.id]; 109 115 110 vector<uint8_t> outpacket; 111 DNSPacketWriter pw(outpacket, mdp.d_qname, mdp.d_qtype, 1, Opcode::Notify); 112 113 static uint16_t s_idpool; 114 pw.getHeader()->id = nif.resentID = s_idpool++; 115 116 if(send(g_pdnssocket, &outpacket[0], outpacket.size(), 0) < 0) { 117 throw runtime_error("Unable to send notify to PowerDNS: "+stringerror()); 118 } 116 if(!iequals(nif.domain,mdp.d_qname)) { 117 cerr<<"Response from inner PowerDNS for different domain '"<<mdp.d_qname<<"' than original notification '"<<nif.domain<<"'"<<endl; 118 } else { 119 struct dnsheader dh; 120 memcpy(&dh, buffer, sizeof(dh)); 121 dh.id = nif.origID; 122 123 if(sendto(nif.origSocket, buffer, len, 0, (sockaddr*) &nif.source, nif.source.getSocklen()) < 0) { 124 throw runtime_error("Unable to send notify to PowerDNS: "+stringerror()); 125 } 126 } 127 g_nifs.erase(mdp.d_header.id); 119 128 120 129 } … … 124 133 } 125 134 126 135 void expireOldNotifications() 136 { 137 time_t limit = time(0) - 10; 138 for(nifs_t::iterator iter = g_nifs.begin(); iter != g_nifs.end(); ) { 139 if(iter->second.resentTime < limit) { 140 cerr<<"Removing notification proxy entry for '"<<iter->second.domain<<"', expired"<<endl; 141 g_nifs.erase(iter++); 142 } 143 else 144 ++iter; 145 } 146 } 147 148 void daemonize(); 127 149 128 150 int main(int argc, char** argv) … … 132 154 desc.add_options() 133 155 ("help,h", "produce help message") 134 ("powerdns-ip", po::value<string>(), "IP address of PowerDNS server") 135 ("local-address", po::value<vector<string> >(), "IP addresses to listen on"); 156 ("powerdns-address", po::value<string>(), "IP address of PowerDNS server") 157 ("origin-address", po::value<string>()->default_value("::"), "Source address for notifications to PowerDNS") 158 ("listen-address", po::value<vector<string> >(), "IP addresses to listen on") 159 ("daemon,d", po::value<bool>()->default_value(true), "operate in the background") 160 ("verbose,v", "be verbose"); 136 161 137 162 po::store(po::command_line_parser(argc, argv).options(desc).run(), g_vm); … … 143 168 } 144 169 145 if(!g_vm.count("powerdns- ip")) {146 cerr<<"Mandatory setting 'powerdns- ip' unset:\n"<<desc<<endl;170 if(!g_vm.count("powerdns-address")) { 171 cerr<<"Mandatory setting 'powerdns-address' unset:\n"<<desc<<endl; 147 172 return EXIT_FAILURE; 148 173 } 174 175 if(!g_vm.count("verbose")) { 176 g_verbose=true; 177 } 149 178 150 179 vector<string> addresses; 151 if(g_vm.count("l ocal-address"))152 addresses=g_vm["l ocal-address"].as<vector<string> >();180 if(g_vm.count("listen-address")) 181 addresses=g_vm["listen-address"].as<vector<string> >(); 153 182 else 154 183 addresses.push_back("::"); … … 164 193 165 194 if(::bind(sock,(sockaddr*) &local, local.getSocklen()) < 0) 166 throw runtime_error("Binding socket for incoming packets : "+stringerror());195 throw runtime_error("Binding socket for incoming packets to '"+ local.toStringWithPort()+"': "+stringerror()); 167 196 168 197 g_fdm.addReadFD(sock, handleOutsideUDPPacket); // add to fdmultiplexer for each socket … … 175 204 throw runtime_error("Creating socket for packets to PowerDNS: "+stringerror()); 176 205 177 ComboAddress pdns(g_vm["powerdns-ip"].as<string>(), 53); 206 ComboAddress originAddress(g_vm["origin-address"].as<string>(), 0); 207 if(::bind(g_pdnssocket,(sockaddr*) &originAddress, originAddress.getSocklen()) < 0) 208 throw runtime_error("Binding local address of inward socket to '"+ originAddress.toStringWithPort()+"': "+stringerror()); 209 210 211 ComboAddress pdns(g_vm["powerdns-address"].as<string>(), 53); 178 212 if(connect(g_pdnssocket, (struct sockaddr*) &pdns, pdns.getSocklen()) < 0) 179 213 throw runtime_error("Failed to connect PowerDNS socket to address "+pdns.toString()+": "+stringerror()); … … 185 219 throw runtime_error("while chrooting to "+g_vm["chroot"].as<string>()); 186 220 } 221 222 if(g_vm["daemon"].as<bool>()) { 223 daemonize(); 224 } 225 187 226 188 227 // start loop … … 192 231 g_fdm.run(&now); 193 232 // check for notifications that have been outstanding for more than 10 seconds 194 cerr<<".\n"; 195 } 196 197 198 233 expireOldNotifications(); 234 } 199 235 } 200 236 catch(exception& e) 201 237 { 202 238 cerr<<"Fatal: "<<e.what()<<endl; 239 } 240 catch(AhuException& e) 241 { 242 cerr<<"Fatal: "<<e.reason<<endl; 203 243 } 204 244 … … 247 287 return false; 248 288 } 289 290 void daemonize(void) 291 { 292 if(fork()) 293 exit(0); // bye bye 294 295 setsid(); 296 297 int i=open("/dev/null",O_RDWR); /* open stdin */ 298 if(i < 0) 299 cerr<<"Unable to open /dev/null: "<<stringerror()<<endl; 300 else { 301 dup2(i,0); /* stdin */ 302 dup2(i,1); /* stderr */ 303 dup2(i,2); /* stderr */ 304 close(i); 305 } 306 }