From c0c215c83c75d76aad3aafa337d69d876c13f5cf Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Wed, 12 Aug 2020 13:08:47 -0700 Subject: [PATCH] single dns config per network --- controller/EmbeddedNetworkController.cpp | 25 +++---- controller/PostgreSQL.cpp | 87 ++++++++---------------- include/ZeroTierOne.h | 12 +--- node/DNS.hpp | 28 ++++---- node/Network.cpp | 6 +- node/NetworkConfig.cpp | 13 ++-- node/NetworkConfig.hpp | 4 +- osdep/MacDNSHelper.mm | 1 - service/OneService.cpp | 47 +++++-------- 9 files changed, 76 insertions(+), 147 deletions(-) diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index a505c3edb..ad42fabb1 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -1711,25 +1711,18 @@ void EmbeddedNetworkController::_request( } } - if(dns.is_array()) { - nc->dnsCount = 0; - for(unsigned int p=0; p < dns.size(); ++p) { - json &d = dns[p]; - if (d.is_object()) { - std::string domain = OSUtils::jsonString(d["domain"],""); - memcpy(nc->dns[nc->dnsCount].domain, domain.c_str(), domain.size()); - json &addrArray = d["servers"]; - if (addrArray.is_array()) { - for(unsigned int j = 0; j < addrArray.size() && j < ZT_MAX_DNS_SERVERS; ++j) { - json &addr = addrArray[j]; - nc->dns[nc->dnsCount].server_addr[j] = InetAddress(OSUtils::jsonString(addr,"").c_str()); - } - } - ++nc->dnsCount; + if(dns.is_object()) { + std::string domain = OSUtils::jsonString(dns["domain"],""); + memcpy(nc->dns.domain, domain.c_str(), domain.size()); + json &addrArray = dns["servers"]; + if (addrArray.is_array()) { + for(unsigned int j = 0; j < addrArray.size() && j < ZT_MAX_DNS_SERVERS; ++j) { + json &addr = addrArray[j]; + nc->dns.server_addr[j] = InetAddress(OSUtils::jsonString(addr,"").c_str()); } } } else { - dns = json::array(); + dns = json::object(); } // Issue a certificate of ownership for all static IPs diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index 81908c46b..44ba2ae5d 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -447,12 +447,12 @@ void PostgreSQL::initializeNetworks(PGconn *conn) } n = PQntuples(r2); - config["dns"] = json::array(); - for (int j = 0; j < n; ++j) { - + if (n > 1) { + fprintf(stderr, "ERROR: invalid number of DNS configurations for network %s. Must be 0 or 1\n", nwid.c_str()); + } else if (n == 1) { json obj; - std::string domain = PQgetvalue(r2, j, 0); - std::string serverList = PQgetvalue(r2, j, 1); + std::string domain = PQgetvalue(r2, 0, 0); + std::string serverList = PQgetvalue(r2, 0, 1); auto servers = json::array(); if (serverList.rfind("{",0) != std::string::npos) { serverList = serverList.substr(1, serverList.size()-2); @@ -465,7 +465,7 @@ void PostgreSQL::initializeNetworks(PGconn *conn) } obj["domain"] = domain; obj["servers"] = servers; - config["dns"].push_back(obj); + config["dns"] = obj; } PQclear(r2); @@ -1461,67 +1461,38 @@ void PostgreSQL::commitThread() config = nullptr; continue; } + auto dns = (*config)["dns"]; + std::string domain = dns["domain"]; + std::stringstream servers; + servers << "{"; + for (auto j = dns["servers"].begin(); j < dns["servers"].end(); ++j) { + servers << *j; + if ( (j+1) != dns["servers"].end()) { + servers << ","; + } + } + servers << "}"; + const char *p[3] = { + id.c_str(), + domain.c_str(), + servers.str().c_str() + }; - res = PQexecParams(conn, - "DELETE FROM ztc_network_dns WHERE network_id = $1", - 1, + res = PQexecParams(conn, "INSERT INTO ztc_network_dns (network_id, domain, servers) VALUES ($1, $2, $3) ON CONFLICT (network_id) DO UPDATE SET domain = EXCLUDED.domain, servers = EXCLUDED.servers", + 3, NULL, - params, + p, NULL, NULL, 0); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "ERROR: Error updating dns: %s\n", PQresultErrorMessage(res)); + fprintf(stderr, "ERROR: Error updating DNS: %s\n", PQresultErrorMessage(res)); PQclear(res); - PQclear(PQexec(conn, "ROLLBACK")); - delete config; - config = nullptr; - continue; - } - - auto dns = (*config)["dns"]; - err = false; - for (auto i = dns.begin(); i < dns.end(); ++i) { - std::string domain = (*i)["domain"]; - std::stringstream servers; - servers << "{"; - for (auto j = dns["servers"].begin(); j < dns["servers"].end(); ++j) { - servers << *j; - if ( (j+1) != dns["servers"].end()) { - servers << ","; - } - } - servers << "}"; - - const char *p[3] = { - id.c_str(), - domain.c_str(), - servers.str().c_str() - }; - - res = PQexecParams(conn, "INSERT INTO ztc_network_dns (network_id, domain, servers) VALUES ($1, $2, $3)", - 3, - NULL, - p, - NULL, - NULL, - 0); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "ERROR: Error updating DNS: %s\n", PQresultErrorMessage(res)); - PQclear(res); - err = true; - break; - } - PQclear(res); - } - if (err) { - PQclear(PQexec(conn, "ROLLBACK")); - delete config; - config = nullptr; - continue; + err = true; + break; } + PQclear(res); res = PQexec(conn, "COMMIT"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 82ae5edfd..f7e6ef6dc 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -125,11 +125,6 @@ extern "C" { */ #define ZT_MAX_NETWORK_ROUTES 32 -/** - * Maximum number of pushed DNS configurations on a network - */ -#define ZT_MAX_NETWORK_DNS 32 - /** * Maximum number of statically assigned IP addresses per network endpoint using ZT address management (not DHCP) */ @@ -1339,16 +1334,11 @@ typedef struct uint64_t mac; /* MAC in lower 48 bits */ uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */ } multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS]; - - /** - * Number of ZT-pushed DNS configuraitons - */ - unsigned int dnsCount; /** * Network specific DNS configuration */ - ZT_VirtualNetworkDNS dns[ZT_MAX_NETWORK_DNS]; + ZT_VirtualNetworkDNS dns; } ZT_VirtualNetworkConfig; /** diff --git a/node/DNS.hpp b/node/DNS.hpp index a770859d8..ceb81e33f 100644 --- a/node/DNS.hpp +++ b/node/DNS.hpp @@ -29,28 +29,24 @@ namespace ZeroTier { class DNS { public: template - static inline void serializeDNS(Buffer &b, const ZT_VirtualNetworkDNS *dns, unsigned int dnsCount) + static inline void serializeDNS(Buffer &b, const ZT_VirtualNetworkDNS *dns) { - for(unsigned int i = 0; i < dnsCount; ++i) { - b.append(dns[i].domain, 128); - for(unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { - InetAddress tmp(dns[i].server_addr[j]); - tmp.serialize(b); - } + b.append(dns->domain, 128); + for(unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { + InetAddress tmp(dns->server_addr[j]); + tmp.serialize(b); } } template - static inline void deserializeDNS(const Buffer &b, unsigned int &p, ZT_VirtualNetworkDNS *dns, const unsigned int dnsCount) + static inline void deserializeDNS(const Buffer &b, unsigned int &p, ZT_VirtualNetworkDNS *dns) { - memset(dns, 0, sizeof(ZT_VirtualNetworkDNS)*ZT_MAX_NETWORK_DNS); - for(unsigned int i = 0; i < dnsCount; ++i) { - char *d = (char*)b.data()+p; - memcpy(dns[i].domain, d, 128); - p += 128; - for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { - p += reinterpret_cast(&(dns[i].server_addr[j]))->deserialize(b, p); - } + char *d = (char*)b.data()+p; + memset(dns, 0, sizeof(ZT_VirtualNetworkDNS)); + memcpy(dns->domain, d, 128); + p += 128; + for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { + p += reinterpret_cast(&(dns->server_addr[j]))->deserialize(b, p); } } }; diff --git a/node/Network.cpp b/node/Network.cpp index 97642fa18..3fe489a29 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -1428,11 +1428,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi(); } - ec->dnsCount = _config.dnsCount; - fprintf(stderr, "Network::_externalConfig dnsCount: %d\n", ec->dnsCount); - if (ec->dnsCount > 0) { - memcpy(&ec->dns, &_config.dns, sizeof(ZT_VirtualNetworkDNS)); - } + memcpy(&ec->dns, &_config.dns, sizeof(ZT_VirtualNetworkDNS)); } void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup) diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 503d7400a..c793462d8 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -177,12 +177,9 @@ bool NetworkConfig::toDictionary(Dictionary &d,b } tmp->clear(); - if (dnsCount > 0) { - tmp->append(dnsCount); - DNS::serializeDNS(*tmp, dns, dnsCount); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_DNS,*tmp)) return false; - } + DNS::serializeDNS(*tmp, &dns); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_DNS,*tmp)) return false; } delete tmp; @@ -366,9 +363,7 @@ bool NetworkConfig::fromDictionary(const DictionarydnsCount = tmp->at(p); - p += sizeof(unsigned int); - DNS::deserializeDNS(*tmp, p, dns, (this->dnsCount <= ZT_MAX_NETWORK_DNS) ? this->dnsCount : ZT_MAX_NETWORK_DNS); + DNS::deserializeDNS(*tmp, p, &dns); } } diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index 1daf98d01..6e66720e8 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -240,7 +240,7 @@ public: memset(routes, 0, sizeof(ZT_VirtualNetworkRoute)*ZT_MAX_NETWORK_ROUTES); memset(staticIps, 0, sizeof(InetAddress)*ZT_MAX_ZT_ASSIGNED_ADDRESSES); memset(rules, 0, sizeof(ZT_VirtualNetworkRule)*ZT_MAX_NETWORK_RULES); - memset(dns, 0, sizeof(ZT_VirtualNetworkDNS)*ZT_MAX_NETWORK_DNS); + memset(&dns, 0, sizeof(ZT_VirtualNetworkDNS)); } /** @@ -603,7 +603,7 @@ public: /** * ZT pushed DNS configuration */ - ZT_VirtualNetworkDNS dns[ZT_MAX_NETWORK_DNS]; + ZT_VirtualNetworkDNS dns; }; } // namespace ZeroTier diff --git a/osdep/MacDNSHelper.mm b/osdep/MacDNSHelper.mm index 1cfe1b265..c50de7915 100644 --- a/osdep/MacDNSHelper.mm +++ b/osdep/MacDNSHelper.mm @@ -34,7 +34,6 @@ void MacDNSHelper::setDNS(uint64_t nwid, const char *domain, const std::vectordnsCount;++i) { - nlohmann::json m; - m["domain"] = nc->dns[i].domain; - m["servers"] = nlohmann::json::array(); - for(int j=0;jdns[i].server_addr[j]); - if (a.isV4() || a.isV6()) { - char buf[256]; - m["servers"].push_back(a.toIpString(buf)); - } + nlohmann::json m; + m["domain"] = nc->dns.domain; + m["servers"] = nlohmann::json::array(); + for(int j=0;jdns.server_addr[j]); + if (a.isV4() || a.isV6()) { + char buf[256]; + m["servers"].push_back(a.toIpString(buf)); } } + nj["dns"] = m; + } static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer) @@ -2002,25 +2001,15 @@ public: } if (syncDns) { - char buf[128]; - if (n.config.dnsCount > ZT_MAX_NETWORK_DNS) { - fprintf(stderr, "ERROR: %d records > max %d. Skipping DNS\n", n.config.dnsCount, ZT_MAX_NETWORK_DNS); - return; - } - fprintf(stderr, "Syncing %d DNS configurations for network [%.16llx]\n", n.config.dnsCount, n.config.nwid); - for (int i = 0; i < n.config.dnsCount; ++i) { - if (strlen(n.config.dns[i].domain) != 0) { - fprintf(stderr, "Syncing DNS for domain: %s\n", n.config.dns[i].domain); - std::vector servers; - for (int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { - InetAddress a(n.config.dns[i].server_addr[j]); - if (a.isV4() || a.isV6()) { - fprintf(stderr, "\t Server %d: %s\n", j+1, a.toIpString(buf)); - servers.push_back(a); - } + if (strlen(n.config.dns.domain) != 0) { + std::vector servers; + for (int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { + InetAddress a(n.config.dns.server_addr[j]); + if (a.isV4() || a.isV6()) { + servers.push_back(a); } - n.tap->setDns(n.config.dns[i].domain, servers); } + n.tap->setDns(n.config.dns.domain, servers); } } }