Parcourir la source

single dns config per network

Grant Limberg il y a 5 ans
Parent
commit
c0c215c83c

+ 9 - 16
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 {
 	} else {
-		dns = json::array();
+		dns = json::object();
 	}
 	}
 
 
 	// Issue a certificate of ownership for all static IPs
 	// Issue a certificate of ownership for all static IPs

+ 29 - 58
controller/PostgreSQL.cpp

@@ -447,12 +447,12 @@ void PostgreSQL::initializeNetworks(PGconn *conn)
 			}
 			}
 
 
 			n = PQntuples(r2);
 			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;
 				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();
 				auto servers = json::array();
 				if (serverList.rfind("{",0) != std::string::npos) {
 				if (serverList.rfind("{",0) != std::string::npos) {
 					serverList = serverList.substr(1, serverList.size()-2);
 					serverList = serverList.substr(1, serverList.size()-2);
@@ -465,7 +465,7 @@ void PostgreSQL::initializeNetworks(PGconn *conn)
 				}
 				}
 				obj["domain"] = domain;
 				obj["domain"] = domain;
 				obj["servers"] = servers;
 				obj["servers"] = servers;
-				config["dns"].push_back(obj);
+				config["dns"] = obj;
 			}
 			}
 
 
 			PQclear(r2);
 			PQclear(r2);
@@ -1461,67 +1461,38 @@ void PostgreSQL::commitThread()
 						config = nullptr;
 						config = nullptr;
 						continue;
 						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,
 						NULL,
-						params,
+						p,
 						NULL,
 						NULL,
 						NULL,
 						NULL,
 						0);
 						0);
-
 					if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 					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(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");
 					res = PQexec(conn, "COMMIT");
 					if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 					if (PQresultStatus(res) != PGRES_COMMAND_OK) {

+ 1 - 11
include/ZeroTierOne.h

@@ -125,11 +125,6 @@ extern "C" {
  */
  */
 #define ZT_MAX_NETWORK_ROUTES 32
 #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)
  * 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 */
 		uint64_t mac; /* MAC in lower 48 bits */
 		uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */
 		uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */
 	} multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS];
 	} multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS];
-
-	/**
-	 *  Number of ZT-pushed DNS configuraitons
-	 */ 
-	unsigned int dnsCount;
 	
 	
 	/**
 	/**
 	 * Network specific DNS configuration
 	 * Network specific DNS configuration
 	 */
 	 */
-	ZT_VirtualNetworkDNS dns[ZT_MAX_NETWORK_DNS];
+	ZT_VirtualNetworkDNS dns;
 } ZT_VirtualNetworkConfig;
 } ZT_VirtualNetworkConfig;
 
 
 /**
 /**

+ 12 - 16
node/DNS.hpp

@@ -29,28 +29,24 @@ namespace ZeroTier {
 class DNS {
 class DNS {
 public:
 public:
     template<unsigned int C>
     template<unsigned int C>
-    static inline void serializeDNS(Buffer<C> &b, const ZT_VirtualNetworkDNS *dns, unsigned int dnsCount)
+    static inline void serializeDNS(Buffer<C> &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<unsigned int C>
     template<unsigned int C>
-    static inline void deserializeDNS(const Buffer<C> &b, unsigned int &p, ZT_VirtualNetworkDNS *dns, const unsigned int dnsCount)
+    static inline void deserializeDNS(const Buffer<C> &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<InetAddress *>(&(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<InetAddress *>(&(dns->server_addr[j]))->deserialize(b, p);
         }
         }
     }
     }
 };
 };

+ 1 - 5
node/Network.cpp

@@ -1428,11 +1428,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
 		ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi();
 		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)
 void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup)

+ 4 - 9
node/NetworkConfig.cpp

@@ -177,12 +177,9 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
 		}
 		}
 
 
 		tmp->clear();
 		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;
 		delete tmp;
@@ -366,9 +363,7 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
 
 
 			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_DNS, *tmp)) {
 			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_DNS, *tmp)) {
 				unsigned int p = 0;
 				unsigned int p = 0;
-				this->dnsCount = tmp->at<unsigned int>(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);
 			}
 			}
 		}
 		}
 
 

+ 2 - 2
node/NetworkConfig.hpp

@@ -240,7 +240,7 @@ public:
 		memset(routes, 0, sizeof(ZT_VirtualNetworkRoute)*ZT_MAX_NETWORK_ROUTES);
 		memset(routes, 0, sizeof(ZT_VirtualNetworkRoute)*ZT_MAX_NETWORK_ROUTES);
 		memset(staticIps, 0, sizeof(InetAddress)*ZT_MAX_ZT_ASSIGNED_ADDRESSES);
 		memset(staticIps, 0, sizeof(InetAddress)*ZT_MAX_ZT_ASSIGNED_ADDRESSES);
 		memset(rules, 0, sizeof(ZT_VirtualNetworkRule)*ZT_MAX_NETWORK_RULES);
 		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 pushed DNS configuration
 	 */
 	 */
-	ZT_VirtualNetworkDNS dns[ZT_MAX_NETWORK_DNS];
+	ZT_VirtualNetworkDNS dns;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 0 - 1
osdep/MacDNSHelper.mm

@@ -34,7 +34,6 @@ void MacDNSHelper::setDNS(uint64_t nwid, const char *domain, const std::vector<I
     CFDictionaryRef dict = CFDictionaryCreate(NULL,
     CFDictionaryRef dict = CFDictionaryCreate(NULL,
         (const void**)keys, (const void**)values, 2, &kCFCopyStringDictionaryKeyCallBacks,
         (const void**)keys, (const void**)values, 2, &kCFCopyStringDictionaryKeyCallBacks,
         &kCFTypeDictionaryValueCallBacks);
         &kCFTypeDictionaryValueCallBacks);
-    CFShow(dict);
 
 
     char buf[256] = {0};
     char buf[256] = {0};
     sprintf(buf, "State:/Network/Service/%.16llx/DNS", nwid);
     sprintf(buf, "State:/Network/Service/%.16llx/DNS", nwid);

+ 18 - 29
service/OneService.cpp

@@ -232,20 +232,19 @@ static void _networkToJson(nlohmann::json &nj,const ZT_VirtualNetworkConfig *nc,
 	}
 	}
 	nj["multicastSubscriptions"] = mca;
 	nj["multicastSubscriptions"] = mca;
 
 
-	nj["dns"] = nlohmann::json::array();
-	for(unsigned int i=0;i<nc->dnsCount;++i) {
-		nlohmann::json m;
-		m["domain"] = nc->dns[i].domain;
-		m["servers"] = nlohmann::json::array();
-		for(int j=0;j<ZT_MAX_DNS_SERVERS;++j) {
-			
-			InetAddress a(nc->dns[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;j<ZT_MAX_DNS_SERVERS;++j) {
+		
+		InetAddress a(nc->dns.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)
 static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
@@ -2002,25 +2001,15 @@ public:
 		}
 		}
 
 
 		if (syncDns) {
 		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<InetAddress> 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<InetAddress> 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);
 			}
 			}
 		}
 		}
 	}
 	}