diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index b6621f29a..f37e4f776 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -1416,7 +1416,9 @@ void EmbeddedNetworkController::_request( json &tags = network["tags"]; json &memberCapabilities = member["capabilities"]; json &memberTags = member["tags"]; - json &dns = member["dns"]; + json &dns = network["dns"]; + + fprintf(stderr, "DNS Config for Network ID %.16llx: %s\n", nwid, OSUtils::jsonDump(dns, 2).c_str()); if (metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,0) <= 0) { // Old versions with no rules engine support get an allow everything rule. @@ -1727,6 +1729,8 @@ void EmbeddedNetworkController::_request( ++nc->dnsCount; } } + } else { + dns = json::array(); } // Issue a certificate of ownership for all static IPs diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index 0f5fde77b..b8e01e200 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -430,6 +430,46 @@ void PostgreSQL::initializeNetworks(PGconn *conn) config["routes"].push_back(route); } + r2 = PQexecParams(conn, + "SELECT domain, servers FROM ztc_network_dns WHERE network_id = $1", + 1, + NULL, + nwidparam, + NULL, + NULL, + 0); + + if (PQresultStatus(r2) != PGRES_TUPLES_OK) { + fprintf(stderr, "ERROR: Error retrieving DNS settings for network: %s\n", PQresultErrorMessage(r2)); + PQclear(r2); + PQclear(res); + exit(1); + } + + n = PQntuples(r2); + config["dns"] = json::array(); + for (int j = 0; j < n; ++j) { + + json obj; + std::string domain = PQgetvalue(r2, j, 0); + std::string serverList = PQgetvalue(r2, j, 1); + auto servers = json::array(); + if (serverList.rfind("{",0) != std::string::npos) { + serverList = serverList.substr(1, serverList.size()-2); + fprintf(stderr, "Server List: %s\n", serverList.c_str()); + std::stringstream ss(serverList); + while(ss.good()) { + std::string server; + std::getline(ss, server, ','); + servers.push_back(server); + } + } + obj["domain"] = domain; + obj["servers"] = servers; + config["dns"].push_back(obj); + } + fprintf(stderr, "%s\n", OSUtils::jsonDump(config["dns"], 2).c_str()); + PQclear(r2); _networkChanged(empty, config, false); @@ -1424,6 +1464,67 @@ void PostgreSQL::commitThread() continue; } + + res = PQexecParams(conn, + "DELETE FROM ztc_network_dns WHERE network_id = $1", + 1, + NULL, + params, + NULL, + NULL, + 0); + + if (PQresultStatus(res) != PGRES_COMMAND_OK) { + 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; + } + res = PQexec(conn, "COMMIT"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "ERROR: Error committing network update: %s\n", PQresultErrorMessage(res)); diff --git a/service/OneService.cpp b/service/OneService.cpp index ff8c37c95..d9239a16c 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1992,7 +1992,7 @@ public: fprintf(stderr, "ERROR: %d records > max %d. Skipping DNS\n", n.config.dnsCount, ZT_MAX_NETWORK_DNS); return; } - fprintf(stderr, "Syncing %d DNS configurations\n", n.config.dnsCount); + 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);