From fc1f7fa97e441e4c09b5087ea673b64c1b82fb27 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 30 Nov 2018 11:49:14 +0200 Subject: [PATCH] pdns_notify: Support hostname for notification When hostname is provided, attempts to send NOTIFY to all addresses associated with the given hostname. --- pdns/notify.cc | 71 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/pdns/notify.cc b/pdns/notify.cc index 8e75e822e..270aaad36 100644 --- a/pdns/notify.cc +++ b/pdns/notify.cc @@ -58,6 +58,7 @@ void usage() { int main(int argc, char** argv) try { + set addrs; for(int n=1 ; n < argc; ++n) { if ((string) argv[n] == "--help") { @@ -76,39 +77,63 @@ try exit(1); } - int sock = socket(AF_INET, SOCK_DGRAM, 0); - if(sock < 0) - throw runtime_error("Creating socket for incoming packets: "+stringerror()); - + int sock = -1; // ComboAddress local("127.0.0.1", (int)0); // if(::bind(sock, (struct sockaddr*) &local, local.getSocklen()) < 0) // throw runtime_error("Failed to bind local socket to address "+local.toString()+": "+stringerror()); - ComboAddress pdns(argv[1], 53); - if(connect(sock, (struct sockaddr*) &pdns, pdns.getSocklen()) < 0) - throw runtime_error("Failed to connect PowerDNS socket to address "+pdns.toString()+": "+stringerror()); - - vector outpacket; - DNSPacketWriter pw(outpacket, DNSName(argv[2]), QType::SOA, 1, Opcode::Notify); - pw.getHeader()->id = random(); + try { + addrs.emplace(ComboAddress{argv[1], 53}); + } catch (PDNSException &ex) { + /* needs resolving, maybe */ + struct addrinfo *info; + vector parts; + boost::split(parts, argv[1], [](char c){return c == ':';}); + if (parts.size() == 1) + parts.push_back("domain"); + else if (parts.size() != 2) + throw runtime_error("Invalid hostname:port syntax"); + if (getaddrinfo(parts[0].c_str(), parts[1].c_str(), NULL, &info) < 0) + throw runtime_error("Cannot resolve '" + string(argv[1]) +"'"); + for(auto ptr = info; ptr != NULL; ptr = ptr->ai_next) + addrs.emplace(ComboAddress{ptr->ai_addr, ptr->ai_addrlen}); + } + for(const auto &addr: addrs) { + if (sock > -1) + (void)close(sock); + sock = socket(addr.sin4.sin_family, SOCK_DGRAM, 0); + if(sock < 0) + throw runtime_error("Creating socket for incoming packets: "+stringerror()); + if(connect(sock, (struct sockaddr*)&addr, addr.getSocklen()) < 0) { + cerr<<"Failed to connect PowerDNS socket to address "+addr.toString()+": "+stringerror()< outpacket; + DNSPacketWriter pw(outpacket, DNSName(argv[2]), QType::SOA, 1, Opcode::Notify); + pw.getHeader()->id = random(); - if(send(sock, &outpacket[0], outpacket.size(), 0) < 0) { - throw runtime_error("Unable to send notify to PowerDNS: "+stringerror()); - } - - char buffer[1500]; - int len=recv(sock, buffer, sizeof(buffer),0); - if(len < 0) - throw runtime_error("Unable to receive notification response from PowerDNS: "+stringerror()); + if(send(sock, &outpacket[0], outpacket.size(), 0) < 0) { + cerr<<"Unable to send notify to PowerDNS: "+stringerror()<