From eec46a137ec36dd204eaa1e4c1ad959e4de7cd29 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 19 Aug 2021 12:44:02 -0700 Subject: [PATCH] optimize data loading from psql on startup --- controller/PostgreSQL.cpp | 482 ++++++++++++----------- ext/central-controller-docker/Dockerfile | 22 +- make-linux.mk | 1 + make-mac.mk | 25 +- 4 files changed, 272 insertions(+), 258 deletions(-) diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index eda5b6841..c6636b30a 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -429,149 +429,168 @@ void PostgreSQL::initializeNetworks() std::unordered_set networkSet; fprintf(stderr, "Initializing Networks...\n"); - auto c = _pool->borrow(); - pqxx::work w{*c->c}; - pqxx::result r = w.exec_params("SELECT id, (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, capabilities, " + + char qbuf[2048] = {0}; + sprintf(qbuf, "SELECT id, (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, capabilities, " "enable_broadcast, (EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000)::bigint AS last_modified, mtu, multicast_limit, name, private, remote_trace_level, " "remote_trace_target, revision, rules, tags, v4_assign_mode, v6_assign_mode, sso_enabled FROM ztc_network " - "WHERE deleted = false AND controller_id = $1", _myAddressStr); + "WHERE deleted = false AND controller_id = '%s'", _myAddressStr.c_str()); + auto c = _pool->borrow(); + auto c2 = _pool->borrow(); + pqxx::work w{*c->c}; + + auto stream = pqxx::stream_from::query(w, qbuf); - for (auto row = r.begin(); row != r.end(); row++) { + std::tuple< + std::string // network ID + , std::optional // creationTime + , std::optional // capabilities + , std::optional // enableBroadcast + , std::optional // lastModified + , std::optional // mtu + , std::optional // multicastLimit + , std::optional // name + , bool // private + , std::optional // remoteTraceLevel + , std::optional // remoteTraceTarget + , std::optional // revision + , std::optional // rules + , std::optional // tags + , std::optional // v4AssignMode + , std::optional // v6AssignMode + , std::optional // ssoEnabled + > row; + + while (stream >> row) { json empty; json config; initNetwork(config); - std::string nwid = row[0].as(); + std::string nwid = std::get<0>(row); + std::optional creationTime = std::get<1>(row); + std::optional capabilities = std::get<2>(row); + std::optional enableBroadcast = std::get<3>(row); + std::optional lastModified = std::get<4>(row); + std::optional mtu = std::get<5>(row); + std::optional multicastLimit = std::get<6>(row); + std::optional name = std::get<7>(row); + bool isPrivate = std::get<8>(row); + std::optional remoteTraceLevel = std::get<9>(row); + std::optional remoteTraceTarget = std::get<10>(row); + std::optional revision = std::get<11>(row); + std::optional rules = std::get<12>(row); + std::optional tags = std::get<13>(row); + std::optional v4AssignMode = std::get<14>(row); + std::optional v6AssignMode = std::get<15>(row); + std::optional ssoEnabled = std::get<16>(row); - networkSet.insert(nwid); + networkSet.insert(nwid); - config["id"] = nwid; - config["nwid"] = nwid; - - if (!row[1].is_null()) { - config["creationTime"] = row[1].as(); - } else { - config["creationTime"] = 0ULL; - } - config["capabilities"] = row[2].as(); - config["enableBroadcast"] = row[3].as(); - if (!row[4].is_null()) { - config["lastModified"] = row[4].as(); - } else { - config["lastModified"] = 0ULL; - } - if (!row[5].is_null()) { - config["mtu"] = row[5].as(); - } else { - config["mtu"] = 2800; - } - if (!row[6].is_null()) { - config["multicastLimit"] = row[6].as(); - } else { - config["multicastLimit"] = 64; - } - config["name"] = row[7].as(); - config["private"] = row[8].as(); - if (!row[9].is_null()) { - config["remoteTraceLevel"] = row[9].as(); - } else { - config["remoteTraceLevel"] = 0; - } + config["id"] = nwid; + config["nwid"] = nwid; + config["creationTime"] = creationTime.value_or(0); + config["capabilities"] = json::parse(capabilities.value_or("[]")); + config["enableBroadcast"] = enableBroadcast.value_or(false); + config["lastModified"] = lastModified.value_or(0); + config["mtu"] = mtu.value_or(2800); + config["multicastLimit"] = multicastLimit.value_or(64); + config["name"] = name.value_or(""); + config["private"] = isPrivate; + config["remoteTraceLevel"] = remoteTraceLevel.value_or(0); + config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); + config["revision"] = revision.value_or(0); + config["rules"] = json::parse(rules.value_or("[]")); + config["tags"] = json::parse(tags.value_or("[]")); + config["v4AssignMode"] = json::parse(v4AssignMode.value_or("{}")); + config["v6AssignMode"] = json::parse(v6AssignMode.value_or("{}")); + config["ssoEnabled"] = ssoEnabled.value_or(false); + config["objtype"] = "network"; + config["ipAssignmentPools"] = json::array(); + config["routes"] = json::array(); - if (!row[10].is_null()) { - config["remoteTraceTarget"] = row[10].as(); - } else { - config["remoteTraceTarget"] = nullptr; - } + { + pqxx::work w2{*c2->c}; + pqxx::result r2 = w2.exec_params("SELECT host(ip_range_start), host(ip_range_end) FROM ztc_network_assignment_pool WHERE network_id = $1", nwid); + for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { + json ip; + ip["ipRangeStart"] = row2[0].as(); + ip["ipRangeEnd"] = row2[1].as(); - if (!row[11].is_null()) { - config["revision"] = row[11].as(); - } else { - config["revision"] = 0ULL; - //fprintf(stderr, "Error converting revision: %s\n", PQgetvalue(res, i, 11)); - } - config["rules"] = json::parse(row[12].as()); - config["tags"] = json::parse(row[13].as()); - config["v4AssignMode"] = json::parse(row[14].as()); - config["v6AssignMode"] = json::parse(row[15].as()); - config["ssoEnabled"] = row[16].as(); - config["objtype"] = "network"; - config["ipAssignmentPools"] = json::array(); - config["routes"] = json::array(); - - - pqxx::result r2 = w.exec_params("SELECT host(ip_range_start), host(ip_range_end) FROM ztc_network_assignment_pool WHERE network_id = $1", nwid); - - for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { - json ip; - ip["ipRangeStart"] = row2[0].as(); - ip["ipRangeEnd"] = row2[1].as(); - - config["ipAssignmentPools"].push_back(ip); - } - - - - r2 = w.exec_params("SELECT host(address), bits, host(via) FROM ztc_network_route WHERE network_id = $1", nwid); - - for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { - std::string addr = row2[0].as(); - std::string bits = row2[1].as(); - - json route; - route["target"] = addr + "/" + bits; - - if (row[2].is_null()) { - route["via"] = nullptr; - } else { - route["via"] = row[2].as(); + config["ipAssignmentPools"].push_back(ip); } - - config["routes"].push_back(route); + w2.commit(); } - r2 = w.exec_params("SELECT domain, servers FROM ztc_network_dns WHERE network_id = $1", nwid); - - if (r2.size() > 1) { - fprintf(stderr, "ERROR: invalid number of DNS configurations for network %s. Must be 0 or 1\n", nwid.c_str()); - } else if (r2.size() == 1) { - auto dnsRow = r2.begin(); - json obj; - std::string domain = dnsRow[0].as(); - std::string serverList = dnsRow[1].as(); - auto servers = json::array(); - if (serverList.rfind("{",0) != std::string::npos) { - serverList = serverList.substr(1, serverList.size()-2); - std::stringstream ss(serverList); - while(ss.good()) { - std::string server; - std::getline(ss, server, ','); - servers.push_back(server); + { + pqxx::work w2{*c2->c}; + pqxx::result r2 = w2.exec_params("SELECT host(address), bits, host(via) FROM ztc_network_route WHERE network_id = $1", nwid); + for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { + std::string addr = row2[0].as(); + std::string bits = row2[1].as(); + json route; + route["target"] = addr + "/" + bits; + if (row2[2].is_null()) { + route["via"] = nullptr; + } else { + route["via"] = row2[2].as(); } + config["routes"].push_back(route); } - obj["domain"] = domain; - obj["servers"] = servers; - config["dns"] = obj; + w2.commit(); } - r2 = w.exec_params("SELECT org.client_id, org.authorization_endpoint " - "FROM ztc_network nw " - "INNER JOIN ztc_org org " - " ON org.owner_id = nw.owner_id " - "WHERE nw.id = $1 AND nw.sso_enabled = true", nwid); - - if (r2.size() == 1) { - // only one should exist - pqxx::row row = r.at(0); - config["clientId"] = row[0].as(); - config["authorizationEndpoint"] = row[1].as(); + { + pqxx::work w2{*c2->c}; + pqxx::result r2 = w2.exec_params("SELECT domain, servers FROM ztc_network_dns WHERE network_id = $1", nwid); + + if (r2.size() > 1) { + fprintf(stderr, "ERROR: invalid number of DNS configurations for network %s. Must be 0 or 1\n", nwid.c_str()); + } else if (r2.size() == 1) { + auto dnsRow = r2.begin(); + json obj; + std::string domain = dnsRow[0].as(); + std::string serverList = dnsRow[1].as(); + auto servers = json::array(); + if (serverList.rfind("{",0) != std::string::npos) { + serverList = serverList.substr(1, serverList.size()-2); + 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"] = obj; + } + w2.commit(); } - _networkChanged(empty, config, false); + { + pqxx::work w2{*c2->c}; + pqxx::result r2 = w2.exec_params("SELECT org.client_id, org.authorization_endpoint " + "FROM ztc_network nw " + "INNER JOIN ztc_org org " + " ON org.owner_id = nw.owner_id " + "WHERE nw.id = $1 AND nw.sso_enabled = true", nwid); + + if (r2.size() == 1) { + // only one should exist + pqxx::row row2 = r2.at(0); + config["clientId"] = row2[0].as(); + config["authorizationEndpoint"] = row2[1].as(); + } + w2.commit(); + } + + _networkChanged(empty, config, false); } + w.commit(); + _pool->unborrow(c2); _pool->unborrow(c); if (++this->_ready == 2) { @@ -595,12 +614,10 @@ void PostgreSQL::initializeMembers() std::string networkId; try { std::unordered_map networkMembers; - fprintf(stderr, "Initializing Members...\n"); - auto c = _pool->borrow(); - pqxx::work w{*c->c}; - pqxx::result r = w.exec_params( - "SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, (EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, " + + char qbuf[2048]; + sprintf(qbuf, "SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, (EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, " " (EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, " " (EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, " " m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, " @@ -608,137 +625,132 @@ void PostgreSQL::initializeMembers() "FROM ztc_member m " "INNER JOIN ztc_network n " " ON n.id = m.network_id " - "WHERE n.controller_id = $1 AND m.deleted = false", _myAddressStr); + "WHERE n.controller_id = '%s' AND m.deleted = false", _myAddressStr.c_str()); + auto c = _pool->borrow(); + auto c2 = _pool->borrow(); + pqxx::work w{*c->c}; + + auto stream = pqxx::stream_from::query(w, qbuf); - for (auto row = r.begin(); row != r.end(); row++) { + std::tuple< + std::string // memberId + , std::string // memberId + , std::optional // activeBridge + , std::optional // authorized + , std::optional // capabilities + , std::optional // creationTime + , std::optional // identity + , std::optional // lastAuthorizedTime + , std::optional // lastDeauthorizedTime + , std::optional // remoteTraceLevel + , std::optional // remoteTraceTarget + , std::optional // tags + , std::optional // vMajor + , std::optional // vMinor + , std::optional // vRev + , std::optional // vProto + , std::optional // noAutoAssignIps + , std::optional // revision + , std::optional // ssoExempt + > row; + + while (stream >> row) { json empty; json config; - memberId = ""; - networkId = ""; - initMember(config); - if (row[0].is_null()) { - fprintf(stderr, "Null memberID?!?\n"); - continue; - } - if (row[1].is_null()) { - fprintf(stderr, "Null NetworkID?!?\n"); - } - memberId = row[0].as(); - networkId = row[1].as(); + memberId = std::get<0>(row); + networkId = std::get<1>(row); + std::optional activeBridge = std::get<2>(row); + std::optional authorized = std::get<3>(row); + std::optional capabilities = std::get<4>(row); + std::optional creationTime = std::get<5>(row); + std::optional identity = std::get<6>(row); + std::optional lastAuthorizedTime = std::get<7>(row); + std::optional lastDeauthorizedTime = std::get<8>(row); + std::optional remoteTraceLevel = std::get<9>(row); + std::optional remoteTraceTarget = std::get<10>(row); + std::optional tags = std::get<11>(row); + std::optional vMajor = std::get<12>(row); + std::optional vMinor = std::get<13>(row); + std::optional vRev = std::get<14>(row); + std::optional vProto = std::get<15>(row); + std::optional noAutoAssignIps = std::get<16>(row); + std::optional revision = std::get<17>(row); + std::optional ssoExempt = std::get<18>(row); + config["id"] = memberId; config["nwid"] = networkId; - config["activeBridge"] = row[2].as(); - config["authorized"] = row[3].as(); - if (row[4].is_null()) { - config["capabilities"] = json::array(); - } else { - try { - config["capabilities"] = json::parse(row[4].as()); - } catch (std::exception &e) { - config["capabilities"] = json::array(); - } - } - config["creationTime"] = row[5].as(); - config["identity"] = row[6].as(); - if (!row[7].is_null()) { - config["lastAuthorizedTime"] = row[7].as(); - } else { - config["lastAuthorizedTime"] = 0ULL; - //fprintf(stderr, "Error updating last auth time (member): %s\n", PQgetvalue(res, i, 7)); - } - if (!row[8].is_null()) { - config["lastDeauthorizedTime"] = row[8].as(); - } else { - config["lastDeauthorizedTime"] = 0ULL; - //fprintf(stderr, "Error updating last deauth time (member): %s\n", PQgetvalue(res, i, 8)); - } - if (!row[9].is_null()) { - config["remoteTraceLevel"] = row[9].as(); - } else { - config["remoteTraceLevel"] = 0; - } - if (!row[10].is_null()) { - config["remoteTraceTarget"] = row[10].as(); - } else { - config["remoteTraceTarget"] = ""; - } - if (row[11].is_null()) { - config["tags"] = json::array(); - } else { - try { - config["tags"] = json::parse(row[11].as()); - } catch (std::exception &e) { - config["tags"] = json::array(); - } - } - if (!row[12].is_null()) { - config["vMajor"] = row[12].as(); - } else { - config["vMajor"] = -1; - } - if (!row[13].is_null()) { - config["vMinor"] = row[13].as(); - } else { - config["vMinor"] = -1; - } - if (!row[14].is_null()) { - config["vRev"] = row[14].as(); - } else { - config["vRev"] = -1; - } - if (!row[15].is_null()) { - config["vProto"] = row[15].as(); - } else { - config["vProto"] = -1; - } - config["noAutoAssignIps"] = row[16].as(); - if (!row[17].is_null()) { - config["revision"] = row[17].as(); - } else { - config["revision"] = 0ULL; - } - config["ssoExempt"] = row[18].as(); + config["activeBridge"] = activeBridge.value_or(false); + config["authorized"] = authorized.value_or(false); + config["capabilities"] = json::parse(capabilities.value_or("[]")); + config["creationTime"] = creationTime.value_or(0); + config["identity"] = identity.value_or(""); + config["lastAuthorizedTime"] = lastAuthorizedTime.value_or(0); + config["lastDeauthorizedTime"] = lastDeauthorizedTime.value_or(0); + config["remoteTraceLevel"] = remoteTraceLevel.value_or(0); + config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); + config["tags"] = json::parse(tags.value_or("[]")); + config["vMajor"] = vMajor.value_or(-1); + config["vMinor"] = vMinor.value_or(-1); + config["vRev"] = vRev.value_or(-1); + config["vProto"] = vProto.value_or(-1); + config["noAutoAssignIps"] = noAutoAssignIps.value_or(false); + config["revision"] = revision.value_or(0); + config["ssoExempt"] = ssoExempt.value_or(false); - config["authenticationExpiryTime"] = 0LL; - pqxx::result authRes = w.exec_params( - "SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint " - "FROM ztc_sso_expiry e " - "INNER JOIN ztc_network n " - " ON n.id = e.network_id " - "WHERE e.network_id = $1 AND e.member_id = $2 AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL " - "ORDER BY e.authentication_expiry_time DESC LIMIT 1", networkId, memberId); - - if (authRes.size() == 1 && !authRes.at(0)[0].is_null()) { - // there is an expiry time record - config["authenticationExpiryTime"] = authRes.at(0)[0].as(); - } else { - config["authenticationExpiryTime"] = 0; + { + config["authenticationExpiryTime"] = 0LL; + + pqxx::work w2{*c2->c}; + pqxx::result authRes = w2.exec_params( + "SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint " + "FROM ztc_sso_expiry e " + "INNER JOIN ztc_network n " + " ON n.id = e.network_id " + "WHERE e.network_id = $1 AND e.member_id = $2 AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL " + "ORDER BY e.authentication_expiry_time DESC LIMIT 1", networkId, memberId); + + if (authRes.size() == 1 && !authRes.at(0)[0].is_null()) { + // there is an expiry time record + config["authenticationExpiryTime"] = authRes.at(0)[0].as(); + } else { + config["authenticationExpiryTime"] = 0; + } + w2.commit(); } config["objtype"] = "member"; - config["ipAssignments"] = json::array(); - pqxx::result r2 = w.exec_params("SELECT DISTINCT address " - "FROM ztc_member_ip_assignment " - "WHERE member_id = $1 AND network_id = $2", memberId, networkId); + { + config["ipAssignments"] = json::array(); - for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { - std::string ipaddr = row2[0].as(); - std::size_t pos = ipaddr.find('/'); - if (pos != std::string::npos) { - ipaddr = ipaddr.substr(0, pos); + pqxx::work w2{*c2->c}; + pqxx::result r2 = w2.exec_params("SELECT DISTINCT address " + "FROM ztc_member_ip_assignment " + "WHERE member_id = $1 AND network_id = $2", memberId, networkId); + + for (auto row2 = r2.begin(); row2 != r2.end(); row2++) { + std::string ipaddr = row2[0].as(); + std::size_t pos = ipaddr.find('/'); + if (pos != std::string::npos) { + ipaddr = ipaddr.substr(0, pos); + } + config["ipAssignments"].push_back(ipaddr); } - config["ipAssignments"].push_back(ipaddr); + w2.commit(); } _memberChanged(empty, config, false); + + memberId = ""; + networkId = ""; } w.commit(); + _pool->unborrow(c2); _pool->unborrow(c); if (++this->_ready == 2) { @@ -1313,7 +1325,7 @@ void PostgreSQL::onlineNotification_Postgres() // using pqxx::stream_to would be a really nice alternative here, but // unfortunately it doesn't support upserts. - fprintf(stderr, "online notification tick\n"); + // fprintf(stderr, "online notification tick\n"); std::stringstream memberUpdate; memberUpdate << "INSERT INTO ztc_member_status (network_id, member_id, address, last_updated) VALUES "; bool firstRun = true; @@ -1375,7 +1387,7 @@ void PostgreSQL::onlineNotification_Postgres() pqxx::result res = w.exec0(memberUpdate.str()); w.commit(); } - fprintf(stderr, "Updated online status of %d members\n", updateCount); + // fprintf(stderr, "Updated online status of %d members\n", updateCount); _pool->unborrow(c); } catch (std::exception &e) { fprintf(stderr, "%s: error in onlinenotification thread: %s\n", _myAddressStr.c_str(), e.what()); diff --git a/ext/central-controller-docker/Dockerfile b/ext/central-controller-docker/Dockerfile index 9669c037e..945562283 100644 --- a/ext/central-controller-docker/Dockerfile +++ b/ext/central-controller-docker/Dockerfile @@ -9,14 +9,14 @@ RUN yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x RUN dnf -qy module disable postgresql RUN yum -y install epel-release && yum -y update && yum clean all RUN yum groupinstall -y "Development Tools" -RUN yum install -y bash cmake postgresql10 postgresql10-devel clang jemalloc jemalloc-devel -RUN curl -sL https://github.com/jtv/libpqxx/archive/refs/tags/6.4.5.tar.gz -o libpqxx.tar.gz -RUN tar -xzf libpqxx.tar.gz && \ - pushd libpqxx-6.4.5/ && \ - mkdir build && pushd build/ && \ - cmake .. && \ - make install -j8 && \ - popd && popd +RUN yum install -y bash cmake postgresql10 postgresql10-devel clang jemalloc jemalloc-devel libpqxx libpqxx-devel +# RUN curl -sL https://github.com/jtv/libpqxx/archive/refs/tags/6.4.5.tar.gz -o libpqxx.tar.gz +# RUN tar -xzf libpqxx.tar.gz && \ +# pushd libpqxx-6.4.5/ && \ +# mkdir build && pushd build/ && \ +# cmake .. && \ +# make install -j8 && \ +# popd && popd # RUN git clone http://git.int.zerotier.com/zerotier/ZeroTierOne.git @@ -28,10 +28,10 @@ FROM centos:8 RUN yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm RUN dnf -qy module disable postgresql RUN yum -y install epel-release && yum -y update && yum clean all -RUN yum install -y jemalloc jemalloc-devel postgresql10 +RUN yum install -y jemalloc jemalloc-devel postgresql10 libpqxx -COPY --from=builder /usr/local/lib64/libpqxx.so /usr/local/lib64/libpqxx.so -COPY --from=builder /usr/local/lib64/libpqxx.a /usr/local/lib64/libpqxx.a +# COPY --from=builder /usr/local/lib64/libpqxx.so /usr/local/lib64/libpqxx.so +# COPY --from=builder /usr/local/lib64/libpqxx.a /usr/local/lib64/libpqxx.a COPY --from=builder /ZeroTierOne/zerotier-one /usr/local/bin/zerotier-one RUN chmod a+x /usr/local/bin/zerotier-one RUN echo "/usr/local/lib64" > /etc/ld.so.conf.d/usr-local-lib64.conf && ldconfig diff --git a/make-linux.mk b/make-linux.mk index 99d8390e2..824f36028 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -266,6 +266,7 @@ ifeq ($(ZT_OFFICIAL),1) endif ifeq ($(ZT_CONTROLLER),1) + override CXXFLAGS+=-Wall -Wno-deprecated -std=c++17 -pthread $(INCLUDES) -DNDEBUG $(DEFS) override LDLIBS+=-L/usr/pgsql-10/lib/ -lpqxx -lpq ext/hiredis-0.14.1/lib/centos8/libhiredis.a ext/redis-plus-plus-1.1.1/install/centos8/lib/libredis++.a override DEFS+=-DZT_CONTROLLER_USE_LIBPQ override INCLUDES+=-I/usr/pgsql-10/include -Iext/hiredis-0.14.1/include/ -Iext/redis-plus-plus-1.1.1/install/centos8/include/sw/ diff --git a/make-mac.mk b/make-mac.mk index ffc8b5c96..7438ad9ed 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -26,13 +26,6 @@ DEFS+=-DZT_BUILD_PLATFORM=$(ZT_BUILD_PLATFORM) -DZT_BUILD_ARCHITECTURE=$(ZT_BUIL include objects.mk ONE_OBJS+=osdep/MacEthernetTap.o osdep/MacKextEthernetTap.o osdep/MacDNSHelper.o ext/http-parser/http_parser.o - -ifeq ($(ZT_CONTROLLER),1) - LIBS+=-L/usr/local/opt/libpqxx@6/lib -L/usr/local/opt/libpq/lib -L/usr/local/opt/openssl/lib/ -lpqxx -lpq -lssl -lcrypto -lgssapi_krb5 ext/redis-plus-plus-1.1.1/install/macos/lib/libredis++.a ext/hiredis-0.14.1/lib/macos/libhiredis.a - DEFS+=-DZT_CONTROLLER_USE_LIBPQ -DZT_CONTROLLER_USE_REDIS -DZT_CONTROLLER - INCLUDES+=-I/usr/local/opt/libpq/include -I/usr/local/opt/libpqxx@6/include -Iext/hiredis-0.14.1/include/ -Iext/redis-plus-plus-1.1.1/install/macos/include/sw/ -endif - LIBS+=-framework CoreServices -framework SystemConfiguration -framework CoreFoundation # Official releases are signed with our Apple cert and apply software updates by default @@ -52,10 +45,20 @@ endif # Use fast ASM Salsa20/12 for x64 processors DEFS+=-DZT_USE_X64_ASM_SALSA2012 CORE_OBJS+=ext/x64-salsa2012-asm/salsa2012.o +CXXFLAGS=$(CFLAGS) -std=c++11 -stdlib=libc++ # Build miniupnpc and nat-pmp as included libraries -- extra defs are required for these sources DEFS+=-DMACOSX -DZT_USE_MINIUPNPC -DMINIUPNP_STATICLIB -D_DARWIN_C_SOURCE -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -D_BSD_SOURCE -D_DEFAULT_SOURCE -DOS_STRING=\"Darwin/15.0.0\" -DMINIUPNPC_VERSION_STRING=\"2.0\" -DUPNP_VERSION_STRING=\"UPnP/1.1\" -DENABLE_STRNATPMPERR ONE_OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o ext/miniupnpc/connecthostport.o ext/miniupnpc/igd_desc_parse.o ext/miniupnpc/minisoap.o ext/miniupnpc/minissdpc.o ext/miniupnpc/miniupnpc.o ext/miniupnpc/miniwget.o ext/miniupnpc/minixml.o ext/miniupnpc/portlistingparse.o ext/miniupnpc/receivedata.o ext/miniupnpc/upnpcommands.o ext/miniupnpc/upnpdev.o ext/miniupnpc/upnperrors.o ext/miniupnpc/upnpreplyparse.o osdep/PortMapper.o +ifeq ($(ZT_CONTROLLER),1) + MACOS_VERSION_MIN=10.15 + override CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++ + LIBS+=-L/usr/local/opt/libpqxx/lib -L/usr/local/opt/libpq/lib -L/usr/local/opt/openssl/lib/ -lpqxx -lpq -lssl -lcrypto -lgssapi_krb5 ext/redis-plus-plus-1.1.1/install/macos/lib/libredis++.a ext/hiredis-0.14.1/lib/macos/libhiredis.a + DEFS+=-DZT_CONTROLLER_USE_LIBPQ -DZT_CONTROLLER_USE_REDIS -DZT_CONTROLLER + INCLUDES+=-I/usr/local/opt/libpq/include -I/usr/local/opt/libpqxx/include -Iext/hiredis-0.14.1/include/ -Iext/redis-plus-plus-1.1.1/install/macos/include/sw/ +else + MACOS_VERSION_MIN=10.13 +endif # Build with address sanitization library for advanced debugging (clang) ifeq ($(ZT_SANITIZE),1) @@ -75,7 +78,7 @@ ifeq ($(ZT_DEBUG),1) node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g $(INCLUDES) $(DEFS) else CFLAGS?=-Ofast -fstack-protector-strong - CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=10.13 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) + CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=$(MACOS_VERSION_MIN) -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) STRIP=strip endif @@ -88,15 +91,13 @@ ifeq ($(ZT_VAULT_SUPPORT),1) LIBS+=-lcurl endif -CXXFLAGS=$(CFLAGS) -std=c++11 -stdlib=libc++ - all: one ext/x64-salsa2012-asm/salsa2012.o: - as -arch x86_64 -mmacosx-version-min=10.13 -o ext/x64-salsa2012-asm/salsa2012.o ext/x64-salsa2012-asm/salsa2012.s + as -arch x86_64 -mmacosx-version-min=$(MACOS_VERSION_MIN) -o ext/x64-salsa2012-asm/salsa2012.o ext/x64-salsa2012-asm/salsa2012.s mac-agent: FORCE - $(CC) -Ofast $(ARCH_FLAGS) -mmacosx-version-min=10.13 -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c + $(CC) -Ofast $(ARCH_FLAGS) -mmacosx-version-min=$(MACOS_VERSION_MIN) -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c $(CODESIGN) -f --options=runtime -s $(CODESIGN_APP_CERT) MacEthernetTapAgent osdep/MacDNSHelper.o: osdep/MacDNSHelper.mm