BB2DomainInfo bbd = createDomainEntry(domain, filename);
bbd.d_kind = DomainInfo::Slave;
- bbd.d_masters.push_back(ip);
+ bbd.d_masters.push_back(ComboAddress(ip, 53));
safePutBBDomainInfo(bbd);
return true;
}
DomainInfo::DomainKind d_kind; //!< the kind of domain
string d_filename; //!< full absolute filename of the zone on disk
string d_status; //!< message describing status of a domain, for human consumption
- vector<string> d_masters; //!< IP address of the master of this domain
+ vector<ComboAddress> d_masters; //!< IP address of the master of this domain
set<string> d_also_notify; //!< IP list of hosts to also notify
LookButDontTouch<recordstorage_t> d_records; //!< the actual records belonging to this domain
time_t d_ctime; //!< last known ctime of the file on disk
else
di.notified_serial = 0;
- if ( result.count( "PdnsDomainMaster" ) && !result["PdnsDomainMaster"].empty() )
- di.masters = result["PdnsDomainMaster"];
+ if ( result.count( "PdnsDomainMaster" ) && !result["PdnsDomainMaster"].empty() ) {
+ for(const auto& m : result["PdnsDomainMaster"])
+ di.masters.emplace_back(m, 53);
+ }
if ( result.count( "PdnsDomainType" ) && !result["PdnsDomainType"].empty() ) {
string kind = result["PdnsDomainType"][0];
while (lua_next(lua, -2)) {
value = lua_tostring(lua, -1);
lua_pop(lua,1);
- di->masters.push_back(value);
+ di->masters.push_back(ComboAddress(value, 53));
}
}
if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
{
- stringtok(di.masters, string( tmp, odbx_field_length( m_result, 3 ) ), ", \t");
+ vector<string> masters;
+ stringtok(masters, string( tmp, odbx_field_length( m_result, 3 ) ), ", \t");
+ for(const auto& m : masters)
+ {
+ di.masters.emplace_back(m, 53);
+ }
}
if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
{
if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
{
- stringtok(di.masters, string( tmp, odbx_field_length( m_result, 2 )), ", \t" );
+ vector<string> masters;
+ stringtok(masters, string( tmp, odbx_field_length( m_result, 2 )), ", \t" );
+ for(const auto& m : masters)
+ {
+ di.masters.emplace_back(m, 53);
+ }
}
if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
di.id = intFromJson(obj, "id", -1);
di.zone = DNSName(stringFromJson(obj, "zone"));
for(const auto& master: obj["masters"].array_items())
- di.masters.push_back(master.string_value());
+ di.masters.push_back(ComboAddress(master.string_value(), 53));
di.notified_serial = static_cast<unsigned int>(doubleFromJson(obj, "notified_serial", -1));
di.serial = static_cast<unsigned int>(obj["serial"].number_value());
} catch (...) {
return false;
}
- stringtok(di.masters, d_result[0][2], " ,\t");
+ vector<string> masters;
+ stringtok(masters, d_result[0][2], " ,\t");
+ for(const auto& m : masters)
+ di.masters.emplace_back(m, 53);
di.last_check=pdns_stou(d_result[0][3]);
di.notified_serial = pdns_stou(d_result[0][4]);
string type=d_result[0][5];
} catch (...) {
continue;
}
- stringtok(sd.masters, d_result[n][2], ", \t");
+
+ vector<string> masters;
+ stringtok(masters, d_result[n][2], ", \t");
+ for(const auto& m : masters)
+ sd.masters.emplace_back(m, 53);
+
sd.last_check=pdns_stou(d_result[n][3]);
sd.backend=this;
sd.kind=DomainInfo::Slave;
}
if (!row[4].empty()) {
- stringtok(di.masters, row[4], " ,\t");
+ vector<string> masters;
+ stringtok(masters, row[4], " ,\t");
+ for(const auto& m : masters)
+ di.masters.emplace_back(m, 53);
}
SOAData sd;
#include "misc.hh"
#include "pdnsexception.hh"
#include "namespaces.hh"
+#include "iputils.hh"
#define YYDEBUG 1
extern int yydebug;
#include "bindparserclasses.hh"
master: AWORD
{
- s_di.masters.push_back($1);
+ s_di.masters.push_back(ComboAddress($1, 53));
free($1);
}
;
DNSName name;
string viewName;
string filename;
- vector<string> masters;
+ vector<ComboAddress> masters;
set<string> alsoNotify;
string type;
bool hadFileDirective;
struct SuckRequest
{
DNSName domain;
- string master;
+ ComboAddress master;
bool operator<(const SuckRequest& b) const
{
return tie(domain, master) < tie(b.domain, b.master);
void drillHole(const DNSName &domain, const string &ip);
bool justNotified(const DNSName &domain, const string &ip);
- void addSuckRequest(const DNSName &domain, const string &master);
+ void addSuckRequest(const DNSName &domain, const ComboAddress& master);
void addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote);
void addTrySuperMasterRequest(DNSPacket *p);
void notify(const DNSName &domain, const string &ip);
int d_nsock4, d_nsock6;
map<pair<DNSName,string>,time_t>d_holes;
pthread_mutex_t d_holelock;
- void suck(const DNSName &domain, const string &remote);
+ void suck(const DNSName &domain, const ComboAddress& remote);
void ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, boost::scoped_ptr<AuthLua4>& pdl,
ZoneStatus& zs, vector<DNSRecord>* axfr);
return false;
}
-bool DNSSECKeeper::getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname)
+bool DNSSECKeeper::getTSIGForAccess(const DNSName& zone, const ComboAddress& master, DNSName* keyname)
{
vector<string> keynames;
d_keymetadb->getDomainMetadata(zone, "AXFR-MASTER-TSIG", keynames);
DNSName zone;
time_t last_check;
string account;
- vector<string> masters; // FIXME use ComboAddress
+ vector<ComboAddress> masters;
DNSBackend *backend;
uint32_t id;
bool unsetPublishCDS(const DNSName& zname);
bool TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname);
- bool getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname);
+ bool getTSIGForAccess(const DNSName& zone, const ComboAddress& master, DNSName* keyname);
void startTransaction(const DNSName& zone, int zone_id)
{
random_shuffle(di.masters.begin(), di.masters.end());
Communicator.addSuckRequest(domain, di.masters.front());
- return "Added retrieval request for '"+domain.toString()+"' from master "+di.masters.front();
+ return "Added retrieval request for '"+domain.toString()+"' from master "+di.masters.front().toStringWithPortExcept(53);
}
string DLNotifyHostHandler(const vector<string>&parts, Utility::pid_t ppid)
return "["+toString() + "]:" + std::to_string(ntohs(sin4.sin_port));
}
+ string toStringWithPortExcept(int port) const
+ {
+ if(ntohs(sin4.sin_port) == port)
+ return toString();
+ if(sin4.sin_family==AF_INET)
+ return toString() + ":" + std::to_string(ntohs(sin4.sin_port));
+ else
+ return "["+toString() + "]:" + std::to_string(ntohs(sin4.sin_port));
+ }
+
+
void truncate(unsigned int bits) noexcept;
uint16_t getPort() const
int PacketHandler::trySuperMasterSynchronous(const DNSPacket *p, const DNSName& tsigkeyname)
{
- string remote = p->getRemote().toString();
- if(p->hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote)) {
- remote = p->getRealRemote().toStringNoMask();
+ ComboAddress remote = p->getRemote();
+ if(p->hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote.toString())) {
+ remote = p->getRealRemote().getNetwork();
}
Resolver::res_t nsset;
try {
Resolver resolver;
uint32_t theirserial;
- resolver.getSoaSerial(remote,p->qdomain, &theirserial);
+ resolver.getSoaSerial(remote, p->qdomain, &theirserial);
resolver.resolve(remote, p->qdomain, QType::NS, &nsset);
}
catch(ResolverException &re) {
return RCode::Refused;
}
- if(!B.superMasterBackend(remote, p->qdomain, nsset, &nameserver, &account, &db)) {
+ if(!B.superMasterBackend(remote.toString(), p->qdomain, nsset, &nameserver, &account, &db)) {
g_log<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<remote<<". Remote nameservers: "<<endl;
for(const auto& rr: nsset) {
if(rr.qtype==QType::NS)
else if(di.kind == DomainInfo::Slave) {
cout<<"Master"<<addS(di.masters)<<": ";
for(const auto& m : di.masters)
- cout<<m<<" ";
+ cout<<m.toStringWithPort()<<" ";
cout<<endl;
struct tm tm;
localtime_r(&di.last_check, &tm);
tgt->setAccount(di.zone,di.account);
string masters="";
bool first = true;
- for(const string& master: di.masters) {
+ for(const auto& master: di.masters) {
if (!first)
masters += ", ";
first = false;
- masters += master;
+ masters += master.toStringWithPortExcept(53);
}
tgt->setMaster(di.zone, masters);
// move records
return true;
}
-int Resolver::resolve(const string &ipport, const DNSName &domain, int type, Resolver::res_t* res, const ComboAddress &local)
+int Resolver::resolve(const ComboAddress& to, const DNSName &domain, int type, Resolver::res_t* res, const ComboAddress &local)
{
try {
- ComboAddress to(ipport, 53);
-
int sock = -1;
int id = sendResolve(to, local, domain, type, &sock);
int err=waitForData(sock, 0, 3000000);
return parseResult(mdp, domain, type, id, res);
}
catch(ResolverException &re) {
- throw ResolverException(re.reason+" from "+ipport);
+ throw ResolverException(re.reason+" from "+to.toStringWithPortExcept(53));
}
return -1;
}
-int Resolver::resolve(const string &ipport, const DNSName &domain, int type, Resolver::res_t* res) {
+int Resolver::resolve(const ComboAddress& ipport, const DNSName &domain, int type, Resolver::res_t* res) {
ComboAddress local;
local.sin4.sin_family = 0;
return resolve(ipport, domain, type, res, local);
}
-void Resolver::getSoaSerial(const string &ipport, const DNSName &domain, uint32_t *serial)
+void Resolver::getSoaSerial(const ComboAddress& ipport, const DNSName &domain, uint32_t *serial)
{
vector<DNSResourceRecord> res;
int ret = resolve(ipport, domain, QType::SOA, &res);
if(ret || res.empty())
- throw ResolverException("Query to '" + ipport + "' for SOA of '" + domain.toLogString() + "' produced no answers");
+ throw ResolverException("Query to '" + ipport.toStringWithPortExcept(53) + "' for SOA of '" + domain.toString() + "' produced no answers");
if(res[0].qtype.getCode() != QType::SOA)
- throw ResolverException("Query to '" + ipport + "' for SOA of '" + domain.toLogString() + "' produced a "+res[0].qtype.getName()+" record");
+ throw ResolverException("Query to '" + ipport.toStringWithPortExcept(53) + "' for SOA of '" + domain.toString() + "' produced a "+res[0].qtype.getName()+" record");
vector<string>parts;
stringtok(parts, res[0].content);
if(parts.size()<3)
- throw ResolverException("Query to '" + ipport + "' for SOA of '" + domain.toLogString() + "' produced an unparseable response");
+ throw ResolverException("Query to '" + ipport.toStringWithPortExcept(53) + "' for SOA of '" + domain.toString() + "' produced an unparseable response");
try {
*serial=pdns_stou(parts[2]);
}
catch(const std::out_of_range& oor) {
- throw ResolverException("Query to '" + ipport + "' for SOA of '" + domain.toLogString() + "' produced an unparseable serial");
+ throw ResolverException("Query to '" + ipport.toStringWithPortExcept(53) + "' for SOA of '" + domain.toString() + "' produced an unparseable serial");
}
}
typedef vector<DNSResourceRecord> res_t;
//! synchronously resolve domain|type at IP, store result in result, rcode in ret
- int resolve(const string &ip, const DNSName &domain, int type, res_t* result, const ComboAddress& local);
+ int resolve(const ComboAddress &ip, const DNSName &domain, int type, res_t* result, const ComboAddress& local);
- int resolve(const string &ip, const DNSName &domain, int type, res_t* result);
+ int resolve(const ComboAddress &ip, const DNSName &domain, int type, res_t* result);
//! only send out a resolution request
uint16_t sendResolve(const ComboAddress& remote, const ComboAddress& local, const DNSName &domain, int type, int *localsock, bool dnssecOk=false,
bool tryGetSOASerial(DNSName *theirDomain, ComboAddress* remote, uint32_t* theirSerial, uint32_t* theirInception, uint32_t* theirExpire, uint16_t* id);
//! convenience function that calls resolve above
- void getSoaSerial(const string &, const DNSName &, uint32_t *);
+ void getSoaSerial(const ComboAddress&, const DNSName &, uint32_t *);
private:
std::map<std::string, int> locals;
return RCode::Refused;
}
- for(vector<string>::const_iterator master=di->masters.begin(); master != di->masters.end(); master++) {
- g_log<<Logger::Notice<<msgPrefix<<"Forwarding packet to master "<<*master<<endl;
- ComboAddress remote;
- try {
- remote = ComboAddress(*master, 53);
- }
- catch (...) {
- g_log<<Logger::Error<<msgPrefix<<"Failed to parse "<<*master<<" as valid remote."<<endl;
- continue;
- }
+ for(const auto& remote : di->masters) {
+ g_log<<Logger::Notice<<msgPrefix<<"Forwarding packet to master "<<remote.toStringWithPortExcept(53)<<endl;
ComboAddress local;
if (remote.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
using boost::scoped_ptr;
-void CommunicatorClass::addSuckRequest(const DNSName &domain, const string &master)
+void CommunicatorClass::addSuckRequest(const DNSName &domain, const ComboAddress& master)
{
Lock l(&d_lock);
SuckRequest sr;
}
-void CommunicatorClass::suck(const DNSName &domain, const string &remote)
+void CommunicatorClass::suck(const DNSName &domain, const ComboAddress& remote)
{
{
Lock l(&d_lock);
}
RemoveSentinel rs(domain, this); // this removes us from d_inprogress when we go out of scope
- g_log<<Logger::Error<<"Initiating transfer of '"<<domain<<"' from remote '"<<remote<<"'"<<endl;
+ L<<Logger::Error<<"Initiating transfer of '"<<domain<<"' from remote '"<<remote.toStringWithPortExcept(53)<<"'"<<endl;
UeberBackend B; // fresh UeberBackend
DomainInfo di;
vector<string> localaddr;
ComboAddress laddr;
- ComboAddress raddr(remote, 53);
+
if(B.getDomainMetadata(domain, "AXFR-SOURCE", localaddr) && !localaddr.empty()) {
try {
laddr = ComboAddress(localaddr[0]);
return;
}
} else {
- if(raddr.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
+ if(remote.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
laddr = ComboAddress(::arg()["query-local-address"]);
- } else if(raddr.sin4.sin_family == AF_INET6 && !::arg()["query-local-address6"].empty()) {
+ } else if(remote.sin4.sin_family == AF_INET6 && !::arg()["query-local-address6"].empty()) {
laddr = ComboAddress(::arg()["query-local-address6"]);
} else {
- bool isv6 = raddr.sin4.sin_family == AF_INET6;
+ bool isv6 = remote.sin4.sin_family == AF_INET6;
g_log<<Logger::Error<<"Unable to AXFR, destination address is IPv" << (isv6 ? "6" : "4") << ", but query-local-address"<< (isv6 ? "6" : "") << " is unset!"<<endl;
return;
}
B.getDomainMetadata(domain, "IXFR", meta);
if(!meta.empty() && meta[0]=="1") {
vector<DNSRecord> axfr;
- g_log<<Logger::Warning<<"Starting IXFR of '"<<domain<<"' from remote "<<raddr.toStringWithPort()<<endl;
- ixfrSuck(domain, tt, laddr, raddr, pdl, zs, &axfr);
+ g_log<<Logger::Warning<<"Starting IXFR of '"<<domain<<"' from remote "<<remote.toStringWithPortExcept(53)<<endl;
+ ixfrSuck(domain, tt, laddr, remote, pdl, zs, &axfr);
if(!axfr.empty()) {
- g_log<<Logger::Warning<<"IXFR of '"<<domain<<"' from remote '"<<raddr.toStringWithPort()<<"' turned into an AXFR"<<endl;
+ g_log<<Logger::Warning<<"IXFR of '"<<domain<<"' from remote '"<<remote.toStringWithPortExcept(53)<<"' turned into an AXFR"<<endl;
bool firstNSEC3=true;
rrs.reserve(axfr.size());
for(const auto& dr : axfr) {
}
if(rrs.empty()) {
- g_log<<Logger::Warning<<"Starting AXFR of '"<<domain<<"' from remote "<<raddr.toStringWithPort()<<endl;
- rrs = doAxfr(raddr, domain, tt, laddr, pdl, zs);
- g_log<<Logger::Warning<<"AXFR of '"<<domain<<"' from remote "<<raddr.toStringWithPort()<<" done"<<endl;
+ g_log<<Logger::Warning<<"Starting AXFR of '"<<domain<<"' from remote "<<remote.toStringWithPortExcept(53)<<endl;
+ rrs = doAxfr(remote, domain, tt, laddr, pdl, zs);
+ g_log<<Logger::Warning<<"AXFR of '"<<domain<<"' from remote "<<remote.toStringWithPortExcept(53)<<" done"<<endl;
}
if(zs.isNSEC3) {
{
random_shuffle(dni.di.masters.begin(), dni.di.masters.end());
try {
- ComboAddress remote(*dni.di.masters.begin(), 53);
return std::make_tuple(dni.di.zone,
- remote,
- d_resolver.sendResolve(remote,
+ *dni.di.masters.begin(),
+ d_resolver.sendResolve(*dni.di.masters.begin(),
dni.localaddr,
dni.di.zone,
QType::SOA,
#include <cstdlib>
#include "dnsname.hh"
#include "bindparserclasses.hh"
+#include "iputils.hh"
using std::string;
checkzone(0, example.com, "./zones//example.com", master, 0);
checkzone(1, test.com, "./zones//test.com", slave, 1);
- BOOST_CHECK_EQUAL(domains[1].masters[0], "1.2.3.4:5678");
+ BOOST_CHECK_EQUAL(domains[1].masters[0].toString(), ComboAddress("1.2.3.4", 5678).toString());
checkzone(2, test.dyndns, "./zones//test.dyndns", garblewarble, 0);
checkzone(3, wtest.com, "./zones//wtest.com", master, 0);
checkzone(4, nztest.com, "./zones//nztest.com", master, 0);
static Json::object getZoneInfo(const DomainInfo& di, DNSSECKeeper *dk) {
string zoneId = apiZoneNameToId(di.zone);
+ vector<string> masters;
+ for(const auto& m : di.masters)
+ masters.push_back(m.toStringWithPortExcept(53));
+
return Json::object {
// id is the canonical lookup key, which doesn't actually match the name (in some cases)
{ "id", zoneId },
{ "kind", di.getKindString() },
{ "dnssec", dk->isSecuredZone(di.zone) },
{ "account", di.account },
- { "masters", di.masters },
+ { "masters", masters },
{ "serial", (double)di.serial },
{ "notified_serial", (double)di.notified_serial },
{ "last_check", (double)di.last_check }
random_shuffle(di.masters.begin(), di.masters.end());
Communicator.addSuckRequest(zonename, di.masters.front());
- resp->setSuccessResult("Added retrieval request for '"+zonename.toString()+"' from master "+di.masters.front());
+ resp->setSuccessResult("Added retrieval request for '"+zonename.toString()+"' from master "+di.masters.front().toStringWithPortExcept(53));
}
static void apiServerZoneNotify(HttpRequest* req, HttpResponse* resp) {
cout<<"BEGIN TRANSACTION;"<<endl;
}
-static void emitDomain(const DNSName& domain, const vector<string> *masters = 0) {
+static void emitDomain(const DNSName& domain, const vector<ComboAddress> *masters = 0) {
string iDomain = domain.toStringRootDot();
if(!::arg().mustDo("slave")) {
if(g_mode==POSTGRES || g_mode==MYSQL || g_mode==SQLITE) {
if(g_mode==POSTGRES || g_mode==MYSQL || g_mode==SQLITE) {
string mstrs;
if (masters != 0 && ! masters->empty()) {
- for(const string& mstr : *masters) {
- mstrs.append(mstr);
+ for(const auto& mstr : *masters) {
+ mstrs.append(mstr.toStringWithPortExcept(53));
mstrs.append(1, ' ');
}
}