diff --git a/Makefile b/Makefile index 1bedf304a..f77767fb8 100644 --- a/Makefile +++ b/Makefile @@ -31,3 +31,6 @@ drone: @echo "rendering .drone.yaml from .drone.jsonnet" drone jsonnet --format --stream drone sign zerotier/ZeroTierOne --save + +clang-format: + find node osdep service tcp-proxy controller -iname '*.cpp' -o -iname '*.hpp' | xargs clang-format -i diff --git a/controller/CV1.cpp b/controller/CV1.cpp index ca0164b7d..920ed7ec8 100644 --- a/controller/CV1.cpp +++ b/controller/CV1.cpp @@ -17,19 +17,17 @@ #include "../node/Constants.hpp" #include "../node/SHA512.hpp" -#include "EmbeddedNetworkController.hpp" #include "../version.h" -#include "Redis.hpp" #include "CtlUtil.hpp" +#include "EmbeddedNetworkController.hpp" +#include "Redis.hpp" -#include - -#include -#include -#include -#include #include - +#include +#include +#include +#include +#include // #define REDIS_TRACE 1 @@ -39,18 +37,15 @@ namespace { static const int DB_MINIMUM_VERSION = 38; - - -} // anonymous namespace +} // anonymous namespace using namespace ZeroTier; - -using Attrs = std::vector>; +using Attrs = std::vector >; using Item = std::pair; using ItemStream = std::vector; -CV1::CV1(const Identity &myId, const char *path, int listenPort, RedisConfig *rc) +CV1::CV1(const Identity& myId, const char* path, int listenPort, RedisConfig* rc) : DB() , _pool() , _myId(myId) @@ -70,11 +65,10 @@ CV1::CV1(const Identity &myId, const char *path, int listenPort, RedisConfig *rc _myAddressStr = myId.address().toString(myAddress); _connString = std::string(path); auto f = std::make_shared(_connString); - _pool = std::make_shared >( - 15, 5, std::static_pointer_cast(f)); - + _pool = std::make_shared >(15, 5, std::static_pointer_cast(f)); + memset(_ssoPsk, 0, sizeof(_ssoPsk)); - char *const ssoPskHex = getenv("ZT_SSO_PSK"); + char* const ssoPskHex = getenv("ZT_SSO_PSK"); #ifdef ZT_TRACE fprintf(stderr, "ZT_SSO_PSK: %s\n", ssoPskHex); #endif @@ -84,16 +78,16 @@ CV1::CV1(const Identity &myId, const char *path, int listenPort, RedisConfig *rc // it will be padded at the end with zeroes. If longer, it'll be truncated. Utils::unhex(ssoPskHex, _ssoPsk, sizeof(_ssoPsk)); } - const char *redisMemberStatus = getenv("ZT_REDIS_MEMBER_STATUS"); + const char* redisMemberStatus = getenv("ZT_REDIS_MEMBER_STATUS"); if (redisMemberStatus && (strcmp(redisMemberStatus, "true") == 0)) { - _redisMemberStatus = true; + _redisMemberStatus = true; fprintf(stderr, "Using redis for member status\n"); } auto c = _pool->borrow(); - pqxx::work txn{*c->c}; + pqxx::work txn { *c->c }; - pqxx::row r{txn.exec1("SELECT version FROM ztc_database")}; + pqxx::row r { txn.exec1("SELECT version FROM ztc_database") }; int dbVersion = r[0].as(); txn.commit(); @@ -119,14 +113,15 @@ CV1::CV1(const Identity &myId, const char *path, int listenPort, RedisConfig *rc if (_rc->clusterMode) { fprintf(stderr, "Using Redis in Cluster Mode\n"); _cluster = std::make_shared(opts, poolOpts); - } else { + } + else { fprintf(stderr, "Using Redis in Standalone Mode\n"); _redis = std::make_shared(opts, poolOpts); } } _readyLock.lock(); - + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL waiting for initial data download..." ZT_EOL_S, ::_timestr(), (unsigned long long)_myAddress.toInt()); _waitNoticePrinted = true; @@ -164,28 +159,29 @@ CV1::~CV1() _onlineNotificationThread.join(); } -void CV1::configureSmee() +void CV1::configureSmee() { - const char *TEMPORAL_SCHEME = "ZT_TEMPORAL_SCHEME"; - const char *TEMPORAL_HOST = "ZT_TEMPORAL_HOST"; - const char *TEMPORAL_PORT = "ZT_TEMPORAL_PORT"; - const char *TEMPORAL_NAMESPACE = "ZT_TEMPORAL_NAMESPACE"; - const char *SMEE_TASK_QUEUE = "ZT_SMEE_TASK_QUEUE"; + const char* TEMPORAL_SCHEME = "ZT_TEMPORAL_SCHEME"; + const char* TEMPORAL_HOST = "ZT_TEMPORAL_HOST"; + const char* TEMPORAL_PORT = "ZT_TEMPORAL_PORT"; + const char* TEMPORAL_NAMESPACE = "ZT_TEMPORAL_NAMESPACE"; + const char* SMEE_TASK_QUEUE = "ZT_SMEE_TASK_QUEUE"; - const char *scheme = getenv(TEMPORAL_SCHEME); + const char* scheme = getenv(TEMPORAL_SCHEME); if (scheme == NULL) { scheme = "http"; } - const char *host = getenv(TEMPORAL_HOST); - const char *port = getenv(TEMPORAL_PORT); - const char *ns = getenv(TEMPORAL_NAMESPACE); - const char *task_queue = getenv(SMEE_TASK_QUEUE); + const char* host = getenv(TEMPORAL_HOST); + const char* port = getenv(TEMPORAL_PORT); + const char* ns = getenv(TEMPORAL_NAMESPACE); + const char* task_queue = getenv(SMEE_TASK_QUEUE); if (scheme != NULL && host != NULL && port != NULL && ns != NULL && task_queue != NULL) { fprintf(stderr, "creating smee client\n"); std::string hostPort = std::string(scheme) + std::string("://") + std::string(host) + std::string(":") + std::string(port); this->_smee = smeeclient::smee_client_new(hostPort.c_str(), ns, task_queue); - } else { + } + else { fprintf(stderr, "Smee client not configured\n"); } } @@ -201,54 +197,59 @@ bool CV1::waitForReady() bool CV1::isReady() { - return ((_ready == 2)&&(_connected)); + return ((_ready == 2) && (_connected)); } -bool CV1::save(nlohmann::json &record,bool notifyListeners) +bool CV1::save(nlohmann::json& record, bool notifyListeners) { bool modified = false; try { - if (!record.is_object()) { + if (! record.is_object()) { fprintf(stderr, "record is not an object?!?\n"); return false; } const std::string objtype = record["objtype"]; if (objtype == "network") { - //fprintf(stderr, "network save\n"); - const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + // fprintf(stderr, "network save\n"); + const uint64_t nwid = OSUtils::jsonIntHex(record["id"], 0ULL); if (nwid) { nlohmann::json old; - get(nwid,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _commitQueue.post(std::pair(record,notifyListeners)); + get(nwid, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _commitQueue.post(std::pair(record, notifyListeners)); modified = true; } } - } else if (objtype == "member") { + } + else if (objtype == "member") { std::string networkId = record["nwid"]; std::string memberId = record["id"]; - const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); - const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); - //fprintf(stderr, "member save %s-%s\n", networkId.c_str(), memberId.c_str()); - if ((id)&&(nwid)) { - nlohmann::json network,old; - get(nwid,network,id,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - //fprintf(stderr, "commit queue post\n"); - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _commitQueue.post(std::pair(record,notifyListeners)); + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"], 0ULL); + const uint64_t id = OSUtils::jsonIntHex(record["id"], 0ULL); + // fprintf(stderr, "member save %s-%s\n", networkId.c_str(), memberId.c_str()); + if ((id) && (nwid)) { + nlohmann::json network, old; + get(nwid, network, id, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + // fprintf(stderr, "commit queue post\n"); + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _commitQueue.post(std::pair(record, notifyListeners)); modified = true; - } else { - //fprintf(stderr, "no change\n"); + } + else { + // fprintf(stderr, "no change\n"); } } - } else { + } + else { fprintf(stderr, "uhh waaat\n"); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what()); - } catch (...) { + } + catch (...) { fprintf(stderr, "Unknown error on PostgreSQL::save\n"); } return modified; @@ -260,7 +261,7 @@ void CV1::eraseNetwork(const uint64_t networkId) char tmp2[24]; waitForReady(); Utils::hex(networkId, tmp2); - std::pair tmp; + std::pair tmp; tmp.first["id"] = tmp2; tmp.first["objtype"] = "_delete_network"; tmp.second = true; @@ -274,7 +275,7 @@ void CV1::eraseMember(const uint64_t networkId, const uint64_t memberId) fprintf(stderr, "PostgreSQL::eraseMember\n"); char tmp2[24]; waitForReady(); - std::pair tmp, nw; + std::pair tmp, nw; Utils::hex(networkId, tmp2); tmp.first["nwid"] = tmp2; Utils::hex(memberId, tmp2); @@ -286,10 +287,10 @@ void CV1::eraseMember(const uint64_t networkId, const uint64_t memberId) _memberChanged(tmp.first, nullJson, true); } -void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress, const char *osArch) +void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) { std::lock_guard l(_lastOnline_l); - NodeOnlineRecord &i = _lastOnline[std::pair(networkId, memberId)]; + NodeOnlineRecord& i = _lastOnline[std::pair(networkId, memberId)]; i.lastSeen = OSUtils::now(); if (physicalAddress) { i.physicalAddress = physicalAddress; @@ -297,17 +298,17 @@ void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const i.osArch = std::string(osArch); } -void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress) +void CV1::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) { this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); } -AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) +AuthInfo CV1::getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) { Metrics::db_get_sso_info++; // NONCE is just a random character string. no semantic meaning // state = HMAC SHA384 of Nonce based on shared sso key - // + // // need nonce timeout in database? make sure it's used within X time // X is 5 minutes for now. Make configurable later? // @@ -315,68 +316,79 @@ AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &re std::string networkId = member["nwid"]; std::string memberId = member["id"]; - - char authenticationURL[4096] = {0}; + char authenticationURL[4096] = { 0 }; AuthInfo info; info.enabled = true; - //if (memberId == "a10dccea52" && networkId == "8056c2e21c24673d") { + // if (memberId == "a10dccea52" && networkId == "8056c2e21c24673d") { // fprintf(stderr, "invalid authinfo for grant's machine\n"); // info.version=1; // return info; - //} - // fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str()); + // } + // fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str()); std::shared_ptr c; try { c = _pool->borrow(); pqxx::work w(*c->c); - char nonceBytes[16] = {0}; + char nonceBytes[16] = { 0 }; std::string nonce = ""; // check if the member exists first. pqxx::row count = w.exec_params1("SELECT count(id) FROM ztc_member WHERE id = $1 AND network_id = $2 AND deleted = false", memberId, networkId); if (count[0].as() == 1) { // get active nonce, if exists. - pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + pqxx::result r = w.exec_params( + "SELECT nonce FROM ztc_sso_expiry " "WHERE network_id = $1 AND member_id = $2 " "AND ((NOW() AT TIME ZONE 'UTC') <= authentication_expiry_time) AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", - networkId, memberId); + networkId, + memberId); if (r.size() == 0) { // no active nonce. // find an unused nonce, if one exists. - pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + pqxx::result r = w.exec_params( + "SELECT nonce FROM ztc_sso_expiry " "WHERE network_id = $1 AND member_id = $2 " "AND authentication_expiry_time IS NULL AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", - networkId, memberId); + networkId, + memberId); if (r.size() == 1) { // we have an existing nonce. Use it nonce = r.at(0)[0].as(); Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); - } else if (r.empty()) { + } + else if (r.empty()) { // create a nonce Utils::getSecureRandom(nonceBytes, 16); - char nonceBuf[64] = {0}; + char nonceBuf[64] = { 0 }; Utils::hex(nonceBytes, sizeof(nonceBytes), nonceBuf); nonce = std::string(nonceBuf); - pqxx::result ir = w.exec_params0("INSERT INTO ztc_sso_expiry " + pqxx::result ir = w.exec_params0( + "INSERT INTO ztc_sso_expiry " "(nonce, nonce_expiration, network_id, member_id) VALUES " "($1, TO_TIMESTAMP($2::double precision/1000), $3, $4)", - nonce, OSUtils::now() + 300000, networkId, memberId); + nonce, + OSUtils::now() + 300000, + networkId, + memberId); w.commit(); - } else { + } + else { // > 1 ?!? Thats an error! fprintf(stderr, "> 1 unused nonce!\n"); exit(6); } - } else if (r.size() == 1) { + } + else if (r.size() == 1) { nonce = r.at(0)[0].as(); Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); - } else { + } + else { // more than 1 nonce in use? Uhhh... fprintf(stderr, "> 1 nonce in use for network member?!?\n"); exit(7); @@ -387,12 +399,13 @@ AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &re "FROM ztc_network AS n " "INNER JOIN ztc_org o " " ON o.owner_id = n.owner_id " - "LEFT OUTER JOIN ztc_network_oidc_config noc " + "LEFT OUTER JOIN ztc_network_oidc_config noc " " ON noc.network_id = n.id " "LEFT OUTER JOIN ztc_oidc_config oc " " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " - "WHERE n.id = $1 AND n.sso_enabled = true", networkId); - + "WHERE n.id = $1 AND n.sso_enabled = true", + networkId); + std::string client_id = ""; std::string authorization_endpoint = ""; std::string issuer = ""; @@ -400,30 +413,33 @@ AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &re uint64_t sso_version = 0; if (r.size() == 1) { - client_id = r.at(0)[0].as>().value_or(""); - authorization_endpoint = r.at(0)[1].as>().value_or(""); - issuer = r.at(0)[2].as>().value_or(""); - provider = r.at(0)[3].as>().value_or(""); - sso_version = r.at(0)[4].as>().value_or(1); - } else if (r.size() > 1) { + client_id = r.at(0)[0].as >().value_or(""); + authorization_endpoint = r.at(0)[1].as >().value_or(""); + issuer = r.at(0)[2].as >().value_or(""); + provider = r.at(0)[3].as >().value_or(""); + sso_version = r.at(0)[4].as >().value_or(1); + } + else if (r.size() > 1) { fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", networkId.c_str()); - } else { + } + else { fprintf(stderr, "No client or auth endpoint?!?\n"); } - + info.version = sso_version; - + // no catch all else because we don't actually care if no records exist here. just continue as normal. - if ((!client_id.empty())&&(!authorization_endpoint.empty())) { - + if ((! client_id.empty()) && (! authorization_endpoint.empty())) { uint8_t state[48]; HMACSHA384(_ssoPsk, nonceBytes, sizeof(nonceBytes), state); char state_hex[256]; Utils::hex(state, 48, state_hex); - + if (info.version == 0) { - char url[2048] = {0}; - OSUtils::ztsnprintf(url, sizeof(authenticationURL), + char url[2048] = { 0 }; + OSUtils::ztsnprintf( + url, + sizeof(authenticationURL), "%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redirect_uri=%s&nonce=%s&state=%s&client_id=%s", authorization_endpoint.c_str(), url_encode(redirectURL).c_str(), @@ -431,12 +447,13 @@ AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &re state_hex, client_id.c_str()); info.authenticationURL = std::string(url); - } else if (info.version == 1) { + } + else if (info.version == 1) { info.ssoClientID = client_id; info.issuerURL = issuer; info.ssoProvider = provider; info.ssoNonce = nonce; - info.ssoState = std::string(state_hex) + "_" +networkId; + info.ssoState = std::string(state_hex) + "_" + networkId; info.centralAuthURL = redirectURL; #ifdef ZT_DEBUG fprintf( @@ -450,24 +467,26 @@ AuthInfo CV1::getSSOAuthInfo(const nlohmann::json &member, const std::string &re provider.c_str()); #endif } - } else { + } + else { fprintf(stderr, "client_id: %s\nauthorization_endpoint: %s\n", client_id.c_str(), authorization_endpoint.c_str()); } } _pool->unborrow(c); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error updating member on load for network %s: %s\n", networkId.c_str(), e.what()); } - return info; //std::string(authenticationURL); + return info; // std::string(authenticationURL); } void CV1::initializeNetworks() { try { std::string setKey = "networks:{" + _myAddressStr + "}"; - + fprintf(stderr, "Initializing Networks...\n"); if (_redisMemberStatus) { @@ -475,18 +494,21 @@ void CV1::initializeNetworks() try { if (_rc->clusterMode) { _cluster->del(setKey); - } else { + } + else { _redis->del(setKey); } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { // ignore. if this key doesn't exist, there's no reason to delete it } } std::unordered_set networkSet; - char qbuf[2048] = {0}; - sprintf(qbuf, + char qbuf[2048] = { 0 }; + sprintf( + qbuf, "SELECT n.id, (EXTRACT(EPOCH FROM n.creation_time AT TIME ZONE 'UTC')*1000)::bigint as creation_time, n.capabilities, " "n.enable_broadcast, (EXTRACT(EPOCH FROM n.last_modified AT TIME ZONE 'UTC')*1000)::bigint AS last_modified, n.mtu, n.multicast_limit, n.name, n.private, n.remote_trace_level, " "n.remote_trace_target, n.revision, n.rules, n.tags, n.v4_assign_mode, n.v6_assign_mode, n.sso_enabled, (CASE WHEN n.sso_enabled THEN noc.client_id ELSE NULL END) as client_id, " @@ -503,40 +525,65 @@ void CV1::initializeNetworks() " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " "LEFT OUTER JOIN ztc_network_dns d " " ON d.network_id = n.id " - "WHERE deleted = false AND controller_id = '%s'", _myAddressStr.c_str()); + "WHERE deleted = false AND controller_id = '%s'", + _myAddressStr.c_str()); auto c = _pool->borrow(); auto c2 = _pool->borrow(); - pqxx::work w{*c->c}; + pqxx::work w { *c->c }; fprintf(stderr, "Load networks from psql...\n"); auto stream = pqxx::stream_from::query(w, qbuf); 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 - , std::optional // clientId - , std::optional // authorizationEndpoint - , std::optional // ssoProvider - , std::optional // domain - , std::optional // servers - , std::string // assignmentPoolString - , std::string // routeString - > row; + 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 + , + std::optional // clientId + , + std::optional // authorizationEndpoint + , + std::optional // ssoProvider + , + std::optional // domain + , + std::optional // servers + , + std::string // assignmentPoolString + , + std::string // routeString + > + row; uint64_t count = 0; auto tmp = std::chrono::high_resolution_clock::now(); @@ -573,28 +620,28 @@ void CV1::initializeNetworks() std::optional dnsServers = std::get<21>(row); std::string assignmentPoolString = std::get<22>(row); std::string routesString = std::get<23>(row); - - config["id"] = nwid; - config["nwid"] = nwid; + + 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["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(); + 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(); config["clientId"] = clientId.value_or(""); config["authorizationEndpoint"] = authorizationEndpoint.value_or(""); config["provider"] = ssoProvider.value_or(""); @@ -605,10 +652,10 @@ void CV1::initializeNetworks() std::string serverList = dnsServers.value(); json obj; auto servers = json::array(); - if (serverList.rfind("{",0) != std::string::npos) { - serverList = serverList.substr(1, serverList.size()-2); + if (serverList.rfind("{", 0) != std::string::npos) { + serverList = serverList.substr(1, serverList.size() - 2); std::stringstream ss(serverList); - while(ss.good()) { + while (ss.good()) { std::string server; std::getline(ss, server, ','); servers.push_back(server); @@ -619,9 +666,9 @@ void CV1::initializeNetworks() config["dns"] = obj; } - config["ipAssignmentPools"] = json::array(); + config["ipAssignmentPools"] = json::array(); if (assignmentPoolString != "{}") { - std::string tmp = assignmentPoolString.substr(1, assignmentPoolString.size()-2); + std::string tmp = assignmentPoolString.substr(1, assignmentPoolString.size() - 2); std::vector assignmentPools = split(tmp, ','); for (auto it = assignmentPools.begin(); it != assignmentPools.end(); ++it) { std::vector r = split(*it, '|'); @@ -634,32 +681,33 @@ void CV1::initializeNetworks() config["routes"] = json::array(); if (routesString != "{}") { - std::string tmp = routesString.substr(1, routesString.size()-2); + std::string tmp = routesString.substr(1, routesString.size() - 2); std::vector routes = split(tmp, ','); for (auto it = routes.begin(); it != routes.end(); ++it) { std::vector r = split(*it, '|'); json route; route["target"] = r[0]; - route["via"] = ((route["via"] == "NULL")? nullptr : r[1]); + route["via"] = ((route["via"] == "NULL") ? nullptr : r[1]); config["routes"].push_back(route); } } Metrics::network_count++; - _networkChanged(empty, config, false); + _networkChanged(empty, config, false); auto end = std::chrono::high_resolution_clock::now(); - auto dur = std::chrono::duration_cast(end - start);; + auto dur = std::chrono::duration_cast(end - start); + ; total += dur.count(); ++count; if (count > 0 && count % 10000 == 0) { - fprintf(stderr, "Averaging %llu us per network\n", (total/count)); + fprintf(stderr, "Averaging %llu us per network\n", (total / count)); } } if (count > 0) { - fprintf(stderr, "Took %llu us per network to load\n", (total/count)); + fprintf(stderr, "Took %llu us per network to load\n", (total / count)); } stream.complete(); @@ -668,7 +716,7 @@ void CV1::initializeNetworks() _pool->unborrow(c); fprintf(stderr, "done.\n"); - if (!networkSet.empty()) { + if (! networkSet.empty()) { if (_redisMemberStatus) { fprintf(stderr, "adding networks to redis...\n"); if (_rc->clusterMode) { @@ -682,7 +730,8 @@ void CV1::initializeNetworks() } } tx.exec(); - } else { + } + else { auto tx = _redis->transaction(true, false); uint64_t count = 0; for (std::string nwid : networkSet) { @@ -700,16 +749,18 @@ void CV1::initializeNetworks() if (++this->_ready == 2) { if (_waitNoticePrinted) { - fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S, _timestr(), (unsigned long long)_myAddress.toInt()); } _readyLock.unlock(); } fprintf(stderr, "network init done.\n"); - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Error initializing networks in Redis: %s\n", e.what()); std::this_thread::sleep_for(std::chrono::milliseconds(5000)); exit(-1); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error initializing networks: %s\n", e.what()); std::this_thread::sleep_for(std::chrono::milliseconds(5000)); exit(-1); @@ -730,16 +781,16 @@ void CV1::initializeMembers() fprintf(stderr, "Initialize Redis for members...\n"); std::unique_lock l(_networks_l); std::unordered_set deletes; - for ( auto it : _networks) { + for (auto it : _networks) { uint64_t nwid_i = it.first; - char nwidTmp[64] = {0}; + char nwidTmp[64] = { 0 }; OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); std::string nwid(nwidTmp); std::string key = setKeyBase + nwid; deletes.insert(key); } - if (!deletes.empty()) { + if (! deletes.empty()) { try { if (_rc->clusterMode) { auto tx = _cluster->transaction(_myAddressStr, true, false); @@ -747,73 +798,98 @@ void CV1::initializeMembers() tx.del(k); } tx.exec(); - } else { + } + else { auto tx = _redis->transaction(true, false); for (std::string k : deletes) { tx.del(k); } tx.exec(); } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { // ignore } } } char qbuf[2048]; - sprintf(qbuf, + 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, " - "m.no_auto_assign_ips, m.revision, m.sso_exempt, " - "(CASE WHEN n.sso_enabled = TRUE AND m.sso_exempt = FALSE THEN " - " ( " - " SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint " - " FROM ztc_sso_expiry e " - " INNER JOIN ztc_network n1 " - " ON n1.id = e.network_id AND n1.deleted = TRUE " - " WHERE e.network_id = m.network_id AND e.member_id = m.id AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL " - " ORDER BY e.authentication_expiry_time DESC LIMIT 1 " - " ) " - " ELSE NULL " - " END) AS authentication_expiry_time, " - "ARRAY(SELECT DISTINCT address FROM ztc_member_ip_assignment WHERE member_id = m.id AND network_id = m.network_id) AS assigned_addresses " + "(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, " + "m.no_auto_assign_ips, m.revision, m.sso_exempt, " + "(CASE WHEN n.sso_enabled = TRUE AND m.sso_exempt = FALSE THEN " + " ( " + " SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint " + " FROM ztc_sso_expiry e " + " INNER JOIN ztc_network n1 " + " ON n1.id = e.network_id AND n1.deleted = TRUE " + " WHERE e.network_id = m.network_id AND e.member_id = m.id AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL " + " ORDER BY e.authentication_expiry_time DESC LIMIT 1 " + " ) " + " ELSE NULL " + " END) AS authentication_expiry_time, " + "ARRAY(SELECT DISTINCT address FROM ztc_member_ip_assignment WHERE member_id = m.id AND network_id = m.network_id) AS assigned_addresses " "FROM ztc_member m " "INNER JOIN ztc_network n " " ON n.id = m.network_id " - "WHERE n.controller_id = '%s' AND n.deleted = FALSE AND m.deleted = FALSE", _myAddressStr.c_str()); + "WHERE n.controller_id = '%s' AND n.deleted = FALSE AND m.deleted = FALSE", + _myAddressStr.c_str()); auto c = _pool->borrow(); auto c2 = _pool->borrow(); - pqxx::work w{*c->c}; + pqxx::work w { *c->c }; fprintf(stderr, "Load members from psql...\n"); auto stream = pqxx::stream_from::query(w, qbuf); 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 - , std::optional // authenticationExpiryTime - , std::string // assignedAddresses - > row; + 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 + , + std::optional // authenticationExpiryTime + , + std::string // assignedAddresses + > + row; uint64_t count = 0; auto tmp = std::chrono::high_resolution_clock::now(); @@ -822,7 +898,7 @@ void CV1::initializeMembers() auto start = std::chrono::high_resolution_clock::now(); json empty; json config; - + initMember(config); memberId = std::get<0>(row); @@ -847,7 +923,7 @@ void CV1::initializeMembers() std::optional authenticationExpiryTime = std::get<19>(row); std::string assignedAddresses = std::get<20>(row); - networkMembers.insert(std::pair(setKeyBase+networkId, memberId)); + networkMembers.insert(std::pair(setKeyBase + networkId, memberId)); config["id"] = memberId; config["address"] = memberId; @@ -860,7 +936,7 @@ void CV1::initializeMembers() config["lastAuthorizedTime"] = lastAuthorizedTime.value_or(0); config["lastDeauthorizedTime"] = lastDeauthorizedTime.value_or(0); config["remoteTraceLevel"] = remoteTraceLevel.value_or(0); - config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); + config["remoteTraceTarget"] = remoteTraceTarget.value_or(""); config["tags"] = json::parse(tags.value_or("[]")); config["vMajor"] = vMajor.value_or(-1); config["vMinor"] = vMinor.value_or(-1); @@ -874,7 +950,7 @@ void CV1::initializeMembers() config["ipAssignments"] = json::array(); if (assignedAddresses != "{}") { - std::string tmp = assignedAddresses.substr(1, assignedAddresses.size()-2); + std::string tmp = assignedAddresses.substr(1, assignedAddresses.size() - 2); std::vector addrs = split(tmp, ','); for (auto it = addrs.begin(); it != addrs.end(); ++it) { config["ipAssignments"].push_back(*it); @@ -893,11 +969,11 @@ void CV1::initializeMembers() total += dur.count(); ++count; if (count > 0 && count % 10000 == 0) { - fprintf(stderr, "Averaging %llu us per member\n", (total/count)); + fprintf(stderr, "Averaging %llu us per member\n", (total / count)); } } if (count > 0) { - fprintf(stderr, "Took %llu us per member to load\n", (total/count)); + fprintf(stderr, "Took %llu us per member to load\n", (total / count)); } stream.complete(); @@ -907,7 +983,7 @@ void CV1::initializeMembers() _pool->unborrow(c); fprintf(stderr, "done.\n"); - if (!networkMembers.empty()) { + if (! networkMembers.empty()) { if (_redisMemberStatus) { fprintf(stderr, "Load member data into redis...\n"); if (_rc->clusterMode) { @@ -921,7 +997,8 @@ void CV1::initializeMembers() } } tx.exec(); - } else { + } + else { auto tx = _redis->transaction(true, false); uint64_t count = 0; for (auto it : networkMembers) { @@ -941,14 +1018,16 @@ void CV1::initializeMembers() if (++this->_ready == 2) { if (_waitNoticePrinted) { - fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S, _timestr(), (unsigned long long)_myAddress.toInt()); } _readyLock.unlock(); } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Error initializing members (redis): %s\n", e.what()); exit(-1); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what()); exit(-1); } @@ -958,27 +1037,28 @@ void CV1::heartbeat() { char publicId[1024]; char hostnameTmp[1024]; - _myId.toString(false,publicId); - if (gethostname(hostnameTmp, sizeof(hostnameTmp))!= 0) { + _myId.toString(false, publicId); + if (gethostname(hostnameTmp, sizeof(hostnameTmp)) != 0) { hostnameTmp[0] = (char)0; - } else { + } + else { for (int i = 0; i < (int)sizeof(hostnameTmp); ++i) { - if ((hostnameTmp[i] == '.')||(hostnameTmp[i] == 0)) { + if ((hostnameTmp[i] == '.') || (hostnameTmp[i] == 0)) { hostnameTmp[i] = (char)0; break; } } } - const char *controllerId = _myAddressStr.c_str(); - const char *publicIdentity = publicId; - const char *hostname = hostnameTmp; + const char* controllerId = _myAddressStr.c_str(); + const char* publicIdentity = publicId; + const char* hostname = hostnameTmp; while (_run == 1) { // fprintf(stderr, "%s: heartbeat\n", controllerId); auto c = _pool->borrow(); int64_t ts = OSUtils::now(); - if(c->c) { + if (c->c) { std::string major = std::to_string(ZEROTIER_ONE_VERSION_MAJOR); std::string minor = std::to_string(ZEROTIER_ONE_VERSION_MINOR); std::string rev = std::to_string(ZEROTIER_ONE_VERSION_REVISION); @@ -987,25 +1067,27 @@ void CV1::heartbeat() std::string host_port = std::to_string(_listenPort); std::string use_redis = (_rc != NULL) ? "true" : "false"; std::string redis_mem_status = (_redisMemberStatus) ? "true" : "false"; - - try { - pqxx::work w{*c->c}; - pqxx::result res = - w.exec0("INSERT INTO ztc_controller (id, cluster_host, last_alive, public_identity, v_major, v_minor, v_rev, v_build, host_port, use_redis, redis_member_status) " - "VALUES ("+w.quote(controllerId)+", "+w.quote(hostname)+", TO_TIMESTAMP("+now+"::double precision/1000), "+ - w.quote(publicIdentity)+", "+major+", "+minor+", "+rev+", "+build+", "+host_port+", "+use_redis+", "+redis_mem_status+") " - "ON CONFLICT (id) DO UPDATE SET cluster_host = EXCLUDED.cluster_host, last_alive = EXCLUDED.last_alive, " - "public_identity = EXCLUDED.public_identity, v_major = EXCLUDED.v_major, v_minor = EXCLUDED.v_minor, " - "v_rev = EXCLUDED.v_rev, v_build = EXCLUDED.v_rev, host_port = EXCLUDED.host_port, " - "use_redis = EXCLUDED.use_redis, redis_member_status = EXCLUDED.redis_member_status"); + try { + pqxx::work w { *c->c }; + + pqxx::result res = w.exec0( + "INSERT INTO ztc_controller (id, cluster_host, last_alive, public_identity, v_major, v_minor, v_rev, v_build, host_port, use_redis, redis_member_status) " + "VALUES (" + + w.quote(controllerId) + ", " + w.quote(hostname) + ", TO_TIMESTAMP(" + now + "::double precision/1000), " + w.quote(publicIdentity) + ", " + major + ", " + minor + ", " + rev + ", " + build + ", " + host_port + ", " + + use_redis + ", " + redis_mem_status + + ") " + "ON CONFLICT (id) DO UPDATE SET cluster_host = EXCLUDED.cluster_host, last_alive = EXCLUDED.last_alive, " + "public_identity = EXCLUDED.public_identity, v_major = EXCLUDED.v_major, v_minor = EXCLUDED.v_minor, " + "v_rev = EXCLUDED.v_rev, v_build = EXCLUDED.v_rev, host_port = EXCLUDED.host_port, " + "use_redis = EXCLUDED.use_redis, redis_member_status = EXCLUDED.redis_member_status"); w.commit(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s: Heartbeat update failed: %s\n", controllerId, e.what()); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); continue; } - } _pool->unborrow(c); @@ -1013,11 +1095,13 @@ void CV1::heartbeat() if (_redisMemberStatus) { if (_rc->clusterMode) { _cluster->zadd("controllers", "controllerId", ts); - } else { + } + else { _redis->zadd("controllers", "controllerId", ts); } } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Redis error in heartbeat thread: %s\n", e.what()); } @@ -1030,7 +1114,8 @@ void CV1::membersDbWatcher() { if (_rc) { _membersWatcher_Redis(); - } else { + } + else { _membersWatcher_Postgres(); } @@ -1041,7 +1126,8 @@ void CV1::membersDbWatcher() fprintf(stderr, "Exited membersDbWatcher\n"); } -void CV1::_membersWatcher_Postgres() { +void CV1::_membersWatcher_Postgres() +{ auto c = _pool->borrow(); std::string stream = "member_" + _myAddressStr; @@ -1049,15 +1135,16 @@ void CV1::_membersWatcher_Postgres() { fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); MemberNotificationReceiver m(this, *c->c, stream); - while(_run == 1) { + while (_run == 1) { c->c->await_notification(5, 0); } _pool->unborrow(c); } -void CV1::_membersWatcher_Redis() { - char buf[11] = {0}; +void CV1::_membersWatcher_Redis() +{ + char buf[11] = { 0 }; std::string key = "member-stream:{" + std::string(_myAddress.toString(buf)) + "}"; std::string lastID = "0"; fprintf(stderr, "Listening to member stream: %s\n", key.c_str()); @@ -1067,42 +1154,47 @@ void CV1::_membersWatcher_Redis() { std::unordered_map result; if (_rc->clusterMode) { _cluster->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); - } else { + } + else { _redis->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); } - if (!result.empty()) { + if (! result.empty()) { for (auto element : result) { - #ifdef REDIS_TRACE +#ifdef REDIS_TRACE fprintf(stdout, "Received notification from: %s\n", element.first.c_str()); - #endif +#endif for (auto rec : element.second) { std::string id = rec.first; auto attrs = rec.second; - #ifdef REDIS_TRACE +#ifdef REDIS_TRACE fprintf(stdout, "Record ID: %s\n", id.c_str()); fprintf(stdout, "attrs len: %lu\n", attrs.size()); - #endif +#endif for (auto a : attrs) { - #ifdef REDIS_TRACE +#ifdef REDIS_TRACE fprintf(stdout, "key: %s\nvalue: %s\n", a.first.c_str(), a.second.c_str()); - #endif +#endif try { tmp = json::parse(a.second); - json &ov = tmp["old_val"]; - json &nv = tmp["new_val"]; + json& ov = tmp["old_val"]; + json& nv = tmp["new_val"]; json oldConfig, newConfig; - if (ov.is_object()) oldConfig = ov; - if (nv.is_object()) newConfig = nv; - if (oldConfig.is_object()||newConfig.is_object()) { - _memberChanged(oldConfig,newConfig,(this->_ready >= 2)); + if (ov.is_object()) + oldConfig = ov; + if (nv.is_object()) + newConfig = nv; + if (oldConfig.is_object() || newConfig.is_object()) { + _memberChanged(oldConfig, newConfig, (this->_ready >= 2)); } - } catch (...) { + } + catch (...) { fprintf(stderr, "json parse error in _membersWatcher_Redis: %s\n", a.second.c_str()); } } if (_rc->clusterMode) { _cluster->xdel(key, id); - } else { + } + else { _redis->xdel(key, id); } lastID = id; @@ -1110,7 +1202,8 @@ void CV1::_membersWatcher_Redis() { } } } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "Error in Redis members watcher: %s\n", e.what()); } } @@ -1121,7 +1214,8 @@ void CV1::networksDbWatcher() { if (_rc) { _networksWatcher_Redis(); - } else { + } + else { _networksWatcher_Postgres(); } @@ -1132,22 +1226,24 @@ void CV1::networksDbWatcher() fprintf(stderr, "Exited networksDbWatcher\n"); } -void CV1::_networksWatcher_Postgres() { +void CV1::_networksWatcher_Postgres() +{ std::string stream = "network_" + _myAddressStr; fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); - + auto c = _pool->borrow(); NetworkNotificationReceiver n(this, *c->c, stream); - while(_run == 1) { - c->c->await_notification(5,0); + while (_run == 1) { + c->c->await_notification(5, 0); } } -void CV1::_networksWatcher_Redis() { - char buf[11] = {0}; +void CV1::_networksWatcher_Redis() +{ + char buf[11] = { 0 }; std::string key = "network-stream:{" + std::string(_myAddress.toString(buf)) + "}"; std::string lastID = "0"; while (_run == 1) { @@ -1156,11 +1252,12 @@ void CV1::_networksWatcher_Redis() { std::unordered_map result; if (_rc->clusterMode) { _cluster->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); - } else { + } + else { _redis->xread(key, lastID, std::chrono::seconds(1), 0, std::inserter(result, result.end())); } - - if (!result.empty()) { + + if (! result.empty()) { for (auto element : result) { #ifdef REDIS_TRACE fprintf(stdout, "Received notification from: %s\n", element.first.c_str()); @@ -1178,21 +1275,25 @@ void CV1::_networksWatcher_Redis() { #endif try { tmp = json::parse(a.second); - json &ov = tmp["old_val"]; - json &nv = tmp["new_val"]; + json& ov = tmp["old_val"]; + json& nv = tmp["new_val"]; json oldConfig, newConfig; - if (ov.is_object()) oldConfig = ov; - if (nv.is_object()) newConfig = nv; - if (oldConfig.is_object()||newConfig.is_object()) { - _networkChanged(oldConfig,newConfig,(this->_ready >= 2)); + if (ov.is_object()) + oldConfig = ov; + if (nv.is_object()) + newConfig = nv; + if (oldConfig.is_object() || newConfig.is_object()) { + _networkChanged(oldConfig, newConfig, (this->_ready >= 2)); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "json parse error in networkWatcher_Redis: what: %s json: %s\n", e.what(), a.second.c_str()); } } if (_rc->clusterMode) { _cluster->xdel(key, id); - } else { + } + else { _redis->xdel(key, id); } lastID = id; @@ -1200,7 +1301,8 @@ void CV1::_networksWatcher_Redis() { Metrics::redis_net_notification++; } } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "Error in Redis networks watcher: %s\n", e.what()); } } @@ -1210,10 +1312,10 @@ void CV1::_networksWatcher_Redis() { void CV1::commitThread() { fprintf(stderr, "%s: commitThread start\n", _myAddressStr.c_str()); - std::pair qitem; - while(_commitQueue.get(qitem)&(_run == 1)) { - //fprintf(stderr, "commitThread tick\n"); - if (!qitem.first.is_object()) { + std::pair qitem; + while (_commitQueue.get(qitem) & (_run == 1)) { + // fprintf(stderr, "commitThread tick\n"); + if (! qitem.first.is_object()) { fprintf(stderr, "not an object\n"); continue; } @@ -1221,19 +1323,20 @@ void CV1::commitThread() std::shared_ptr c; try { c = _pool->borrow(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "ERROR: %s\n", e.what()); continue; } - if (!c) { + if (! c) { fprintf(stderr, "Error getting database connection\n"); continue; } - + Metrics::pgsql_commit_ticks++; try { - nlohmann::json &config = (qitem.first); + nlohmann::json& config = (qitem.first); const std::string objtype = config["objtype"]; if (objtype == "member") { // fprintf(stderr, "%s: commitThread: member\n", _myAddressStr.c_str()); @@ -1244,12 +1347,12 @@ void CV1::commitThread() memberId = config["id"]; networkId = config["nwid"]; - + std::string target = "NULL"; - if (!config["remoteTraceTarget"].is_null()) { + if (! config["remoteTraceTarget"].is_null()) { target = config["remoteTraceTarget"]; } - + pqxx::row nwrow = w.exec_params1("SELECT COUNT(id) FROM ztc_network WHERE id = $1", networkId); int nwcount = nwrow[0].as(); @@ -1260,7 +1363,6 @@ void CV1::commitThread() continue; } - pqxx::row mrow = w.exec_params1("SELECT COUNT(id) FROM ztc_member WHERE id = $1 AND network_id = $2", memberId, networkId); int membercount = mrow[0].as(); @@ -1292,7 +1394,8 @@ void CV1::commitThread() (int)config["vMinor"], (int)config["vRev"], (int)config["vProto"]); - } else { + } + else { // existing member pqxx::result res = w.exec_params0( "UPDATE ztc_member " @@ -1318,13 +1421,11 @@ void CV1::commitThread() (int)config["vMajor"], (int)config["vMinor"], (int)config["vRev"], - (int)config["vProto"] - ); + (int)config["vProto"]); } - if (!isNewMember) { - pqxx::result res = w.exec_params0("DELETE FROM ztc_member_ip_assignment WHERE member_id = $1 AND network_id = $2", - memberId, networkId); + if (! isNewMember) { + pqxx::result res = w.exec_params0("DELETE FROM ztc_member_ip_assignment WHERE member_id = $1 AND network_id = $2", memberId, networkId); } std::vector assignments; @@ -1336,9 +1437,7 @@ void CV1::commitThread() continue; } - pqxx::result res = w.exec_params0( - "INSERT INTO ztc_member_ip_assignment (member_id, network_id, address) VALUES ($1, $2, $3) ON CONFLICT (network_id, member_id, address) DO NOTHING", - memberId, networkId, addr); + pqxx::result res = w.exec_params0("INSERT INTO ztc_member_ip_assignment (member_id, network_id, address) VALUES ($1, $2, $3) ON CONFLICT (network_id, member_id, address) DO NOTHING", memberId, networkId, addr); assignments.push_back(addr); } @@ -1362,8 +1461,7 @@ void CV1::commitThread() " INNER JOIN ztc_network n ON n.owner_id = o.owner_id " " WHERE " "n.id = $1 ", - networkId - ); + networkId); int64_t hookCount = row[0].as(); if (hookCount > 0) { notifyNewMember(networkId, memberId); @@ -1381,20 +1479,23 @@ void CV1::commitThread() get(nwidInt, nwOrig, memberidInt, memOrig); _memberChanged(memOrig, memNew, qitem.second); - } else { + } + else { fprintf(stderr, "%s: Can't notify of change. Error parsing nwid or memberid: %llu-%llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt, (unsigned long long)memberidInt); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error updating member %s-%s: %s\n", _myAddressStr.c_str(), networkId.c_str(), memberId.c_str(), e.what()); } - } else if (objtype == "network") { + } + else if (objtype == "network") { try { // fprintf(stderr, "%s: commitThread: network\n", _myAddressStr.c_str()); pqxx::work w(*c->c); std::string id = config["id"]; std::string remoteTraceTarget = ""; - if(!config["remoteTraceTarget"].is_null()) { + if (! config["remoteTraceTarget"].is_null()) { remoteTraceTarget = config["remoteTraceTarget"]; } std::string rulesSource = ""; @@ -1433,14 +1534,14 @@ void CV1::commitThread() OSUtils::now(), (int)config["mtu"], (int)config["multicastLimit"], - OSUtils::jsonString(config["name"],""), + OSUtils::jsonString(config["name"], ""), (bool)config["private"], (int)config["remoteTraceLevel"], remoteTraceTarget, OSUtils::jsonDump(config["rules"], -1), rulesSource, OSUtils::jsonDump(config["tags"], -1), - OSUtils::jsonDump(config["v4AssignMode"],-1), + OSUtils::jsonDump(config["v4AssignMode"], -1), OSUtils::jsonDump(config["v6AssignMode"], -1), OSUtils::jsonBool(config["ssoEnabled"], false)); @@ -1454,7 +1555,10 @@ void CV1::commitThread() res = w.exec_params0( "INSERT INTO ztc_network_assignment_pool (network_id, ip_range_start, ip_range_end) " - "VALUES ($1, $2, $3)", id, start, end); + "VALUES ($1, $2, $3)", + id, + start, + end); } res = w.exec_params0("DELETE FROM ztc_network_route WHERE network_id = $1", id); @@ -1466,7 +1570,7 @@ void CV1::commitThread() std::vector target; std::istringstream f(t); std::string s; - while(std::getline(f, s, '/')) { + while (std::getline(f, s, '/')) { target.push_back(s); } if (target.empty() || target.size() != 2) { @@ -1475,12 +1579,11 @@ void CV1::commitThread() std::string targetAddr = target[0]; std::string targetBits = target[1]; std::string via = "NULL"; - if (!(*i)["via"].is_null()) { + if (! (*i)["via"].is_null()) { via = (*i)["via"]; } - res = w.exec_params0("INSERT INTO ztc_network_route (network_id, address, bits, via) VALUES ($1, $2, $3, $4)", - id, targetAddr, targetBits, (via == "NULL" ? NULL : via.c_str())); + res = w.exec_params0("INSERT INTO ztc_network_route (network_id, address, bits, via) VALUES ($1, $2, $3, $4)", id, targetAddr, targetBits, (via == "NULL" ? NULL : via.c_str())); } if (err) { fprintf(stderr, "%s: route add error\n", _myAddressStr.c_str()); @@ -1495,7 +1598,7 @@ void CV1::commitThread() servers << "{"; for (auto j = dns["servers"].begin(); j < dns["servers"].end(); ++j) { servers << *j; - if ( (j+1) != dns["servers"].end()) { + if ((j + 1) != dns["servers"].end()) { servers << ","; } } @@ -1503,8 +1606,7 @@ void CV1::commitThread() std::string s = servers.str(); - res = w.exec_params0("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", - id, domain, s); + res = w.exec_params0("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", id, domain, s); w.commit(); @@ -1516,10 +1618,12 @@ void CV1::commitThread() get(nwidInt, nwOrig); _networkChanged(nwOrig, nwNew, qitem.second); - } else { + } + else { fprintf(stderr, "%s: Can't notify network changed: %llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); } if (_redisMemberStatus) { @@ -1529,25 +1633,28 @@ void CV1::commitThread() std::string key = "networks:{" + controllerId + "}"; if (_rc->clusterMode) { _cluster->sadd(key, id); - } else { + } + else { _redis->sadd(key, id); } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); } } - } else if (objtype == "_delete_network") { + } + else if (objtype == "_delete_network") { // fprintf(stderr, "%s: commitThread: delete network\n", _myAddressStr.c_str()); try { pqxx::work w(*c->c); std::string networkId = config["nwid"]; - pqxx::result res = w.exec_params0("UPDATE ztc_network SET deleted = true WHERE id = $1", - networkId); + pqxx::result res = w.exec_params0("UPDATE ztc_network SET deleted = true WHERE id = $1", networkId); w.commit(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error deleting network: %s\n", _myAddressStr.c_str(), e.what()); } if (_redisMemberStatus) { @@ -1557,17 +1664,19 @@ void CV1::commitThread() std::string key = "networks:{" + controllerId + "}"; if (_rc->clusterMode) { _cluster->srem(key, id); - _cluster->del("network-nodes-online:{"+controllerId+"}:"+id); - } else { - _redis->srem(key, id); - _redis->del("network-nodes-online:{"+controllerId+"}:"+id); + _cluster->del("network-nodes-online:{" + controllerId + "}:" + id); } - } catch (sw::redis::Error &e) { + else { + _redis->srem(key, id); + _redis->del("network-nodes-online:{" + controllerId + "}:" + id); + } + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Error adding network to Redis: %s\n", e.what()); } } - - } else if (objtype == "_delete_member") { + } + else if (objtype == "_delete_member") { // fprintf(stderr, "%s commitThread: delete member\n", _myAddressStr.c_str()); try { pqxx::work w(*c->c); @@ -1575,12 +1684,11 @@ void CV1::commitThread() std::string memberId = config["id"]; std::string networkId = config["nwid"]; - pqxx::result res = w.exec_params0( - "UPDATE ztc_member SET hidden = true, deleted = true WHERE id = $1 AND network_id = $2", - memberId, networkId); + pqxx::result res = w.exec_params0("UPDATE ztc_member SET hidden = true, deleted = true WHERE id = $1 AND network_id = $2", memberId, networkId); w.commit(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error deleting member: %s\n", _myAddressStr.c_str(), e.what()); } if (_redisMemberStatus) { @@ -1591,19 +1699,23 @@ void CV1::commitThread() std::string key = "network-nodes-all:{" + controllerId + "}:" + networkId; if (_rc->clusterMode) { _cluster->srem(key, memberId); - _cluster->del("member:{"+controllerId+"}:"+networkId+":"+memberId); - } else { - _redis->srem(key, memberId); - _redis->del("member:{"+controllerId+"}:"+networkId+":"+memberId); + _cluster->del("member:{" + controllerId + "}:" + networkId + ":" + memberId); } - } catch (sw::redis::Error &e) { + else { + _redis->srem(key, memberId); + _redis->del("member:{" + controllerId + "}:" + networkId + ":" + memberId); + } + } + catch (sw::redis::Error& e) { fprintf(stderr, "ERROR: Error deleting member from Redis: %s\n", e.what()); } } - } else { + } + else { fprintf(stderr, "%s ERROR: unknown objtype\n", _myAddressStr.c_str()); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error getting objtype: %s\n", _myAddressStr.c_str(), e.what()); } _pool->unborrow(c); @@ -1613,20 +1725,19 @@ void CV1::commitThread() fprintf(stderr, "%s commitThread finished\n", _myAddressStr.c_str()); } -void CV1::notifyNewMember(const std::string &networkID, const std::string &memberID) { - smeeclient::smee_client_notify_network_joined( - _smee, - networkID.c_str(), - memberID.c_str()); +void CV1::notifyNewMember(const std::string& networkID, const std::string& memberID) +{ + smeeclient::smee_client_notify_network_joined(_smee, networkID.c_str(), memberID.c_str()); } void CV1::onlineNotificationThread() { - waitForReady(); + waitForReady(); if (_redisMemberStatus) { - onlineNotification_Redis(); - } else { - onlineNotification_Postgres(); + onlineNotification_Redis(); + } + else { + onlineNotification_Postgres(); } } @@ -1649,7 +1760,7 @@ void CV1::onlineNotification_Postgres() auto c2 = _pool->borrow(); try { fprintf(stderr, "%s onlineNotification_Postgres\n", _myAddressStr.c_str()); - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > lastOnline; + std::unordered_map, NodeOnlineRecord, _PairHasher> lastOnline; { std::lock_guard l(_lastOnline_l); lastOnline.swap(_lastOnline); @@ -1660,33 +1771,33 @@ void CV1::onlineNotification_Postgres() pqxx::work w2(*c2->c); fprintf(stderr, "online notification tick\n"); - + bool firstRun = true; bool memberAdded = false; int updateCount = 0; pqxx::pipeline pipe(w); - for (auto i=lastOnline.begin(); i != lastOnline.end(); ++i) { + for (auto i = lastOnline.begin(); i != lastOnline.end(); ++i) { updateCount += 1; uint64_t nwid_i = i->first.first; char nwidTmp[64]; char memTmp[64]; char ipTmp[64]; - OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); - OSUtils::ztsnprintf(memTmp,sizeof(memTmp), "%.10llx", i->first.second); + OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); + OSUtils::ztsnprintf(memTmp, sizeof(memTmp), "%.10llx", i->first.second); - if(!get(nwid_i, jtmp1, i->first.second, jtmp2)) { - continue; // skip non existent networks/members + if (! get(nwid_i, jtmp1, i->first.second, jtmp2)) { + continue; // skip non existent networks/members } std::string networkId(nwidTmp); std::string memberId(memTmp); try { - pqxx::row r = w2.exec_params1("SELECT id, network_id FROM ztc_member WHERE network_id = $1 AND id = $2", - networkId, memberId); - } catch (pqxx::unexpected_rows &e) { + pqxx::row r = w2.exec_params1("SELECT id, network_id FROM ztc_member WHERE network_id = $1 AND id = $2", networkId, memberId); + } + catch (pqxx::unexpected_rows& e) { continue; } @@ -1697,19 +1808,20 @@ void CV1::onlineNotification_Postgres() std::stringstream memberUpdate; memberUpdate << "INSERT INTO ztc_member_status (network_id, member_id, address, last_updated) VALUES " - << "('" << networkId << "', '" << memberId << "', "; + << "('" << networkId << "', '" << memberId << "', "; if (ipAddr.empty()) { memberUpdate << "NULL, "; - } else { + } + else { memberUpdate << "'" << ipAddr << "', "; } memberUpdate << "TO_TIMESTAMP(" << timestamp << "::double precision/1000)) " - << " ON CONFLICT (network_id, member_id) DO UPDATE SET address = EXCLUDED.address, last_updated = EXCLUDED.last_updated"; + << " ON CONFLICT (network_id, member_id) DO UPDATE SET address = EXCLUDED.address, last_updated = EXCLUDED.last_updated"; pipe.insert(memberUpdate.str()); Metrics::pgsql_node_checkin++; } - while(!pipe.empty()) { + while (! pipe.empty()) { pipe.retrieve(); } @@ -1717,15 +1829,15 @@ void CV1::onlineNotification_Postgres() w.commit(); fprintf(stderr, "%s: Updated online status of %d members\n", _myAddressStr.c_str(), updateCount); #endif - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s: error in onlinenotification thread: %s\n", _myAddressStr.c_str(), e.what()); - } + } _pool->unborrow(c2); _pool->unborrow(c); ConnectionPoolStats stats = _pool->get_stats(); - fprintf(stderr, "%s pool stats: in use size: %llu, available size: %llu, total: %llu\n", - _myAddressStr.c_str(), stats.borrowed_size, stats.pool_size, (stats.borrowed_size + stats.pool_size)); + fprintf(stderr, "%s pool stats: in use size: %llu, available size: %llu, total: %llu\n", _myAddressStr.c_str(), stats.borrowed_size, stats.pool_size, (stats.borrowed_size + stats.pool_size)); std::this_thread::sleep_for(std::chrono::seconds(10)); } @@ -1739,8 +1851,8 @@ void CV1::onlineNotification_Postgres() void CV1::onlineNotification_Redis() { _connected = 1; - - char buf[11] = {0}; + + char buf[11] = { 0 }; std::string controllerId = std::string(_myAddress.toString(buf)); while (_run == 1) { @@ -1748,22 +1860,24 @@ void CV1::onlineNotification_Redis() auto start = std::chrono::high_resolution_clock::now(); uint64_t count = 0; - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > lastOnline; + std::unordered_map, NodeOnlineRecord, _PairHasher> lastOnline; { std::lock_guard l(_lastOnline_l); lastOnline.swap(_lastOnline); } try { - if (!lastOnline.empty()) { + if (! lastOnline.empty()) { if (_rc->clusterMode) { auto tx = _cluster->transaction(controllerId, true, false); count = _doRedisUpdate(tx, controllerId, lastOnline); - } else { + } + else { auto tx = _redis->transaction(true, false); count = _doRedisUpdate(tx, controllerId, lastOnline); } } - } catch (sw::redis::Error &e) { + } + catch (sw::redis::Error& e) { fprintf(stderr, "Error in online notification thread (redis): %s\n", e.what()); } @@ -1777,23 +1891,22 @@ void CV1::onlineNotification_Redis() } } -uint64_t CV1::_doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId, - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > &lastOnline) +uint64_t CV1::_doRedisUpdate(sw::redis::Transaction& tx, std::string& controllerId, std::unordered_map, NodeOnlineRecord, _PairHasher>& lastOnline) { nlohmann::json jtmp1, jtmp2; uint64_t count = 0; - for (auto i=lastOnline.begin(); i != lastOnline.end(); ++i) { + for (auto i = lastOnline.begin(); i != lastOnline.end(); ++i) { uint64_t nwid_i = i->first.first; uint64_t memberid_i = i->first.second; char nwidTmp[64]; char memTmp[64]; char ipTmp[64]; - OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); - OSUtils::ztsnprintf(memTmp,sizeof(memTmp), "%.10llx", memberid_i); + OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); + OSUtils::ztsnprintf(memTmp, sizeof(memTmp), "%.10llx", memberid_i); - if (!get(nwid_i, jtmp1, memberid_i, jtmp2)){ - continue; // skip non existent members/networks + if (! get(nwid_i, jtmp1, memberid_i, jtmp2)) { + continue; // skip non existent members/networks } std::string networkId(nwidTmp); @@ -1804,41 +1917,30 @@ uint64_t CV1::_doRedisUpdate(sw::redis::Transaction &tx, std::string &controller std::string timestamp = std::to_string(ts); std::string osArch = i->second.osArch; - std::unordered_map record = { - {"id", memberId}, - {"address", ipAddr}, - {"last_updated", std::to_string(ts)} - }; - tx.zadd("nodes-online:{"+controllerId+"}", memberId, ts) - .zadd("nodes-online2:{"+controllerId+"}", networkId+"-"+memberId, ts) - .zadd("network-nodes-online:{"+controllerId+"}:"+networkId, memberId, ts) - .zadd("active-networks:{"+controllerId+"}", networkId, ts) - .sadd("network-nodes-all:{"+controllerId+"}:"+networkId, memberId) - .hmset("member:{"+controllerId+"}:"+networkId+":"+memberId, record.begin(), record.end()); + std::unordered_map record = { { "id", memberId }, { "address", ipAddr }, { "last_updated", std::to_string(ts) } }; + tx.zadd("nodes-online:{" + controllerId + "}", memberId, ts) + .zadd("nodes-online2:{" + controllerId + "}", networkId + "-" + memberId, ts) + .zadd("network-nodes-online:{" + controllerId + "}:" + networkId, memberId, ts) + .zadd("active-networks:{" + controllerId + "}", networkId, ts) + .sadd("network-nodes-all:{" + controllerId + "}:" + networkId, memberId) + .hmset("member:{" + controllerId + "}:" + networkId + ":" + memberId, record.begin(), record.end()); ++count; Metrics::redis_node_checkin++; } // expire records from all-nodes and network-nodes member list uint64_t expireOld = OSUtils::now() - 300000; - - tx.zremrangebyscore("nodes-online:{"+controllerId+"}", - sw::redis::RightBoundedInterval(expireOld, - sw::redis::BoundType::LEFT_OPEN)); - tx.zremrangebyscore("nodes-online2:{"+controllerId+"}", - sw::redis::RightBoundedInterval(expireOld, - sw::redis::BoundType::LEFT_OPEN)); - tx.zremrangebyscore("active-networks:{"+controllerId+"}", - sw::redis::RightBoundedInterval(expireOld, - sw::redis::BoundType::LEFT_OPEN)); + + tx.zremrangebyscore("nodes-online:{" + controllerId + "}", sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); + tx.zremrangebyscore("nodes-online2:{" + controllerId + "}", sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); + tx.zremrangebyscore("active-networks:{" + controllerId + "}", sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); { std::shared_lock l(_networks_l); - for (const auto &it : _networks) { + for (const auto& it : _networks) { uint64_t nwid_i = it.first; char nwidTmp[64]; - OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); - tx.zremrangebyscore("network-nodes-online:{"+controllerId+"}:"+nwidTmp, - sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); + OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); + tx.zremrangebyscore("network-nodes-online:{" + controllerId + "}:" + nwidTmp, sw::redis::RightBoundedInterval(expireOld, sw::redis::BoundType::LEFT_OPEN)); } } tx.exec(); @@ -1847,5 +1949,4 @@ uint64_t CV1::_doRedisUpdate(sw::redis::Transaction &tx, std::string &controller return count; } - -#endif //ZT_CONTROLLER_USE_LIBPQ +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/controller/CV1.hpp b/controller/CV1.hpp index 753184a9c..549b17912 100644 --- a/controller/CV1.hpp +++ b/controller/CV1.hpp @@ -20,19 +20,16 @@ #define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 -#include "ConnectionPool.hpp" -#include - -#include -#include - #include "../node/Metrics.hpp" - +#include "ConnectionPool.hpp" #include "PostgreSQL.hpp" +#include +#include +#include namespace smeeclient { - struct SmeeClient; +struct SmeeClient; } namespace ZeroTier { @@ -45,39 +42,43 @@ struct RedisConfig; * This is for use with ZeroTier Central. Others are free to build and use it * but be aware that we might change it at any time. */ -class CV1 : public DB -{ -public: - CV1(const Identity &myId, const char *path, int listenPort, RedisConfig *rc); +class CV1 : public DB { + public: + CV1(const Identity& myId, const char* path, int listenPort, RedisConfig* rc); virtual ~CV1(); virtual bool waitForReady(); virtual bool isReady(); - virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual bool save(nlohmann::json& record, bool notifyListeners); virtual void eraseNetwork(const uint64_t networkId); virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch); - virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); + virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - virtual bool ready() { + virtual bool ready() + { return _ready == 2; } -protected: - struct _PairHasher - { - inline std::size_t operator()(const std::pair &p) const { return (std::size_t)(p.first ^ p.second); } + protected: + struct _PairHasher { + inline std::size_t operator()(const std::pair& p) const + { + return (std::size_t)(p.first ^ p.second); + } }; - virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) { + virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners) + { DB::_memberChanged(old, memberConfig, notifyListeners); } - virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) { + virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners) + { DB::_networkChanged(old, networkConfig, notifyListeners); } -private: + private: void initializeNetworks(); void initializeMembers(); void heartbeat(); @@ -93,16 +94,12 @@ private: void onlineNotificationThread(); void onlineNotification_Postgres(); void onlineNotification_Redis(); - uint64_t _doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId, - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > &lastOnline); + uint64_t _doRedisUpdate(sw::redis::Transaction& tx, std::string& controllerId, std::unordered_map, NodeOnlineRecord, _PairHasher>& lastOnline); void configureSmee(); - void notifyNewMember(const std::string &networkID, const std::string &memberID); + void notifyNewMember(const std::string& networkID, const std::string& memberID); - enum OverrideMode { - ALLOW_PGBOUNCER_OVERRIDE = 0, - NO_OVERRIDE = 1 - }; + enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 }; std::shared_ptr > _pool; @@ -111,7 +108,7 @@ private: std::string _myAddressStr; std::string _connString; - BlockingQueue< std::pair > _commitQueue; + BlockingQueue > _commitQueue; std::thread _heartbeatThread; std::thread _membersDbWatcher; @@ -119,7 +116,7 @@ private: std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; std::thread _onlineNotificationThread; - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > _lastOnline; + std::unordered_map, NodeOnlineRecord, _PairHasher> _lastOnline; mutable std::mutex _lastOnline_l; mutable std::mutex _readyLock; @@ -129,16 +126,16 @@ private: int _listenPort; uint8_t _ssoPsk[48]; - RedisConfig *_rc; + RedisConfig* _rc; std::shared_ptr _redis; std::shared_ptr _cluster; - bool _redisMemberStatus; + bool _redisMemberStatus; - smeeclient::SmeeClient *_smee; + smeeclient::SmeeClient* _smee; }; -} // namespace ZeroTier +} // namespace ZeroTier -#endif // ZT_CONTROLLER_CV1_HPP +#endif // ZT_CONTROLLER_CV1_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/controller/CV2.cpp b/controller/CV2.cpp index 8259471ab..9b3849737 100644 --- a/controller/CV2.cpp +++ b/controller/CV2.cpp @@ -17,16 +17,15 @@ #include "../node/Constants.hpp" #include "../node/SHA512.hpp" -#include "EmbeddedNetworkController.hpp" #include "../version.h" #include "CtlUtil.hpp" +#include "EmbeddedNetworkController.hpp" +#include +#include +#include #include #include -#include -#include -#include - using json = nlohmann::json; @@ -36,29 +35,19 @@ namespace { using namespace ZeroTier; -CV2::CV2(const Identity &myId, const char *path, int listenPort) - : DB() - , _pool() - , _myId(myId) - , _myAddress(myId.address()) - , _ready(0) - , _connected(1) - , _run(1) - , _waitNoticePrinted(false) - , _listenPort(listenPort) +CV2::CV2(const Identity& myId, const char* path, int listenPort) : DB(), _pool(), _myId(myId), _myAddress(myId.address()), _ready(0), _connected(1), _run(1), _waitNoticePrinted(false), _listenPort(listenPort) { fprintf(stderr, "CV2::CV2\n"); char myAddress[64]; _myAddressStr = myId.address().toString(myAddress); - _connString = std::string(path); - + _connString = std::string(path); + auto f = std::make_shared(_connString); - _pool = std::make_shared >( - 15, 5, std::static_pointer_cast(f)); - + _pool = std::make_shared >(15, 5, std::static_pointer_cast(f)); + memset(_ssoPsk, 0, sizeof(_ssoPsk)); - char *const ssoPskHex = getenv("ZT_SSO_PSK"); + char* const ssoPskHex = getenv("ZT_SSO_PSK"); #ifdef ZT_TRACE fprintf(stderr, "ZT_SSO_PSK: %s\n", ssoPskHex); #endif @@ -70,7 +59,7 @@ CV2::CV2(const Identity &myId, const char *path, int listenPort) } _readyLock.lock(); - + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL waiting for initial data download..." ZT_EOL_S, ::_timestr(), (unsigned long long)_myAddress.toInt()); _waitNoticePrinted = true; @@ -112,54 +101,59 @@ bool CV2::waitForReady() bool CV2::isReady() { - return (_ready == 2) && _connected; -} + return (_ready == 2) && _connected; +} -bool CV2::save(nlohmann::json &record,bool notifyListeners) +bool CV2::save(nlohmann::json& record, bool notifyListeners) { bool modified = false; try { - if (!record.is_object()) { + if (! record.is_object()) { fprintf(stderr, "record is not an object?!?\n"); return false; } const std::string objtype = record["objtype"]; if (objtype == "network") { - //fprintf(stderr, "network save\n"); - const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + // fprintf(stderr, "network save\n"); + const uint64_t nwid = OSUtils::jsonIntHex(record["id"], 0ULL); if (nwid) { nlohmann::json old; - get(nwid,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _commitQueue.post(std::pair(record,notifyListeners)); + get(nwid, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _commitQueue.post(std::pair(record, notifyListeners)); modified = true; } } - } else if (objtype == "member") { + } + else if (objtype == "member") { std::string networkId = record["nwid"]; std::string memberId = record["id"]; - const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); - const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); - //fprintf(stderr, "member save %s-%s\n", networkId.c_str(), memberId.c_str()); - if ((id)&&(nwid)) { - nlohmann::json network,old; - get(nwid,network,id,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - //fprintf(stderr, "commit queue post\n"); - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _commitQueue.post(std::pair(record,notifyListeners)); + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"], 0ULL); + const uint64_t id = OSUtils::jsonIntHex(record["id"], 0ULL); + // fprintf(stderr, "member save %s-%s\n", networkId.c_str(), memberId.c_str()); + if ((id) && (nwid)) { + nlohmann::json network, old; + get(nwid, network, id, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + // fprintf(stderr, "commit queue post\n"); + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _commitQueue.post(std::pair(record, notifyListeners)); modified = true; - } else { - //fprintf(stderr, "no change\n"); + } + else { + // fprintf(stderr, "no change\n"); } } - } else { + } + else { fprintf(stderr, "uhh waaat\n"); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "Error on PostgreSQL::save: %s\n", e.what()); - } catch (...) { + } + catch (...) { fprintf(stderr, "Unknown error on PostgreSQL::save\n"); } return modified; @@ -171,7 +165,7 @@ void CV2::eraseNetwork(const uint64_t networkId) char tmp2[24]; waitForReady(); Utils::hex(networkId, tmp2); - std::pair tmp; + std::pair tmp; tmp.first["id"] = tmp2; tmp.first["objtype"] = "_delete_network"; tmp.second = true; @@ -185,7 +179,7 @@ void CV2::eraseMember(const uint64_t networkId, const uint64_t memberId) fprintf(stderr, "PostgreSQL::eraseMember\n"); char tmp2[24]; waitForReady(); - std::pair tmp, nw; + std::pair tmp, nw; Utils::hex(networkId, tmp2); tmp.first["nwid"] = tmp2; Utils::hex(memberId, tmp2); @@ -197,10 +191,10 @@ void CV2::eraseMember(const uint64_t networkId, const uint64_t memberId) _memberChanged(tmp.first, nullJson, true); } -void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress, const char *osArch) +void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) { std::lock_guard l(_lastOnline_l); - NodeOnlineRecord &i = _lastOnline[std::pair(networkId, memberId)]; + NodeOnlineRecord& i = _lastOnline[std::pair(networkId, memberId)]; i.lastSeen = OSUtils::now(); if (physicalAddress) { i.physicalAddress = physicalAddress; @@ -208,19 +202,19 @@ void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const i.osArch = std::string(osArch); } -void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress) +void CV2::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) { this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); } -AuthInfo CV2::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) +AuthInfo CV2::getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) { - // TODO: Redo this for CV2 + // TODO: Redo this for CV2 Metrics::db_get_sso_info++; // NONCE is just a random character string. no semantic meaning // state = HMAC SHA384 of Nonce based on shared sso key - // + // // need nonce timeout in database? make sure it's used within X time // X is 5 minutes for now. Make configurable later? // @@ -228,162 +222,166 @@ AuthInfo CV2::getSSOAuthInfo(const nlohmann::json &member, const std::string &re std::string networkId = member["nwid"]; std::string memberId = member["id"]; - - char authenticationURL[4096] = {0}; + char authenticationURL[4096] = { 0 }; AuthInfo info; info.enabled = true; - //if (memberId == "a10dccea52" && networkId == "8056c2e21c24673d") { + // if (memberId == "a10dccea52" && networkId == "8056c2e21c24673d") { // fprintf(stderr, "invalid authinfo for grant's machine\n"); // info.version=1; // return info; - //} - // fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str()); + // } + // fprintf(stderr, "PostgreSQL::updateMemberOnLoad: %s-%s\n", networkId.c_str(), memberId.c_str()); std::shared_ptr c; try { -// c = _pool->borrow(); -// pqxx::work w(*c->c); + // c = _pool->borrow(); + // pqxx::work w(*c->c); -// char nonceBytes[16] = {0}; -// std::string nonce = ""; + // char nonceBytes[16] = {0}; + // std::string nonce = ""; -// // check if the member exists first. -// pqxx::row count = w.exec_params1("SELECT count(id) FROM ztc_member WHERE id = $1 AND network_id = $2 AND deleted = false", memberId, networkId); -// if (count[0].as() == 1) { -// // get active nonce, if exists. -// pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " -// "WHERE network_id = $1 AND member_id = $2 " -// "AND ((NOW() AT TIME ZONE 'UTC') <= authentication_expiry_time) AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", -// networkId, memberId); + // // check if the member exists first. + // pqxx::row count = w.exec_params1("SELECT count(id) FROM ztc_member WHERE id = $1 AND network_id = $2 AND deleted = false", memberId, networkId); + // if (count[0].as() == 1) { + // // get active nonce, if exists. + // pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + // "WHERE network_id = $1 AND member_id = $2 " + // "AND ((NOW() AT TIME ZONE 'UTC') <= authentication_expiry_time) AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", + // networkId, memberId); -// if (r.size() == 0) { -// // no active nonce. -// // find an unused nonce, if one exists. -// pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " -// "WHERE network_id = $1 AND member_id = $2 " -// "AND authentication_expiry_time IS NULL AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", -// networkId, memberId); + // if (r.size() == 0) { + // // no active nonce. + // // find an unused nonce, if one exists. + // pqxx::result r = w.exec_params("SELECT nonce FROM ztc_sso_expiry " + // "WHERE network_id = $1 AND member_id = $2 " + // "AND authentication_expiry_time IS NULL AND ((NOW() AT TIME ZONE 'UTC') <= nonce_expiration)", + // networkId, memberId); -// if (r.size() == 1) { -// // we have an existing nonce. Use it -// nonce = r.at(0)[0].as(); -// Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); -// } else if (r.empty()) { -// // create a nonce -// Utils::getSecureRandom(nonceBytes, 16); -// char nonceBuf[64] = {0}; -// Utils::hex(nonceBytes, sizeof(nonceBytes), nonceBuf); -// nonce = std::string(nonceBuf); + // if (r.size() == 1) { + // // we have an existing nonce. Use it + // nonce = r.at(0)[0].as(); + // Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); + // } else if (r.empty()) { + // // create a nonce + // Utils::getSecureRandom(nonceBytes, 16); + // char nonceBuf[64] = {0}; + // Utils::hex(nonceBytes, sizeof(nonceBytes), nonceBuf); + // nonce = std::string(nonceBuf); -// pqxx::result ir = w.exec_params0("INSERT INTO ztc_sso_expiry " -// "(nonce, nonce_expiration, network_id, member_id) VALUES " -// "($1, TO_TIMESTAMP($2::double precision/1000), $3, $4)", -// nonce, OSUtils::now() + 300000, networkId, memberId); + // pqxx::result ir = w.exec_params0("INSERT INTO ztc_sso_expiry " + // "(nonce, nonce_expiration, network_id, member_id) VALUES " + // "($1, TO_TIMESTAMP($2::double precision/1000), $3, $4)", + // nonce, OSUtils::now() + 300000, networkId, memberId); -// w.commit(); -// } else { -// // > 1 ?!? Thats an error! -// fprintf(stderr, "> 1 unused nonce!\n"); -// exit(6); -// } -// } else if (r.size() == 1) { -// nonce = r.at(0)[0].as(); -// Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); -// } else { -// // more than 1 nonce in use? Uhhh... -// fprintf(stderr, "> 1 nonce in use for network member?!?\n"); -// exit(7); -// } + // w.commit(); + // } else { + // // > 1 ?!? Thats an error! + // fprintf(stderr, "> 1 unused nonce!\n"); + // exit(6); + // } + // } else if (r.size() == 1) { + // nonce = r.at(0)[0].as(); + // Utils::unhex(nonce.c_str(), nonceBytes, sizeof(nonceBytes)); + // } else { + // // more than 1 nonce in use? Uhhh... + // fprintf(stderr, "> 1 nonce in use for network member?!?\n"); + // exit(7); + // } -// r = w.exec_params( -// "SELECT oc.client_id, oc.authorization_endpoint, oc.issuer, oc.provider, oc.sso_impl_version " -// "FROM ztc_network AS n " -// "INNER JOIN ztc_org o " -// " ON o.owner_id = n.owner_id " -// "LEFT OUTER JOIN ztc_network_oidc_config noc " -// " ON noc.network_id = n.id " -// "LEFT OUTER JOIN ztc_oidc_config oc " -// " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " -// "WHERE n.id = $1 AND n.sso_enabled = true", networkId); - -// std::string client_id = ""; -// std::string authorization_endpoint = ""; -// std::string issuer = ""; -// std::string provider = ""; -// uint64_t sso_version = 0; + // r = w.exec_params( + // "SELECT oc.client_id, oc.authorization_endpoint, oc.issuer, oc.provider, oc.sso_impl_version " + // "FROM ztc_network AS n " + // "INNER JOIN ztc_org o " + // " ON o.owner_id = n.owner_id " + // "LEFT OUTER JOIN ztc_network_oidc_config noc " + // " ON noc.network_id = n.id " + // "LEFT OUTER JOIN ztc_oidc_config oc " + // " ON noc.client_id = oc.client_id AND oc.org_id = o.org_id " + // "WHERE n.id = $1 AND n.sso_enabled = true", networkId); -// if (r.size() == 1) { -// client_id = r.at(0)[0].as>().value_or(""); -// authorization_endpoint = r.at(0)[1].as>().value_or(""); -// issuer = r.at(0)[2].as>().value_or(""); -// provider = r.at(0)[3].as>().value_or(""); -// sso_version = r.at(0)[4].as>().value_or(1); -// } else if (r.size() > 1) { -// fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", networkId.c_str()); -// } else { -// fprintf(stderr, "No client or auth endpoint?!?\n"); -// } - -// info.version = sso_version; - -// // no catch all else because we don't actually care if no records exist here. just continue as normal. -// if ((!client_id.empty())&&(!authorization_endpoint.empty())) { - -// uint8_t state[48]; -// HMACSHA384(_ssoPsk, nonceBytes, sizeof(nonceBytes), state); -// char state_hex[256]; -// Utils::hex(state, 48, state_hex); - -// if (info.version == 0) { -// char url[2048] = {0}; -// OSUtils::ztsnprintf(url, sizeof(authenticationURL), -// "%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redirect_uri=%s&nonce=%s&state=%s&client_id=%s", -// authorization_endpoint.c_str(), -// url_encode(redirectURL).c_str(), -// nonce.c_str(), -// state_hex, -// client_id.c_str()); -// info.authenticationURL = std::string(url); -// } else if (info.version == 1) { -// info.ssoClientID = client_id; -// info.issuerURL = issuer; -// info.ssoProvider = provider; -// info.ssoNonce = nonce; -// info.ssoState = std::string(state_hex) + "_" +networkId; -// info.centralAuthURL = redirectURL; -// #ifdef ZT_DEBUG -// fprintf( -// stderr, -// "ssoClientID: %s\nissuerURL: %s\nssoNonce: %s\nssoState: %s\ncentralAuthURL: %s\nprovider: %s\n", -// info.ssoClientID.c_str(), -// info.issuerURL.c_str(), -// info.ssoNonce.c_str(), -// info.ssoState.c_str(), -// info.centralAuthURL.c_str(), -// provider.c_str()); -// #endif -// } -// } else { -// fprintf(stderr, "client_id: %s\nauthorization_endpoint: %s\n", client_id.c_str(), authorization_endpoint.c_str()); -// } -// } + // std::string client_id = ""; + // std::string authorization_endpoint = ""; + // std::string issuer = ""; + // std::string provider = ""; + // uint64_t sso_version = 0; -// _pool->unborrow(c); - } catch (std::exception &e) { + // if (r.size() == 1) { + // client_id = r.at(0)[0].as>().value_or(""); + // authorization_endpoint = r.at(0)[1].as>().value_or(""); + // issuer = r.at(0)[2].as>().value_or(""); + // provider = r.at(0)[3].as>().value_or(""); + // sso_version = r.at(0)[4].as>().value_or(1); + // } else if (r.size() > 1) { + // fprintf(stderr, "ERROR: More than one auth endpoint for an organization?!?!? NetworkID: %s\n", networkId.c_str()); + // } else { + // fprintf(stderr, "No client or auth endpoint?!?\n"); + // } + + // info.version = sso_version; + + // // no catch all else because we don't actually care if no records exist here. just continue as normal. + // if ((!client_id.empty())&&(!authorization_endpoint.empty())) { + + // uint8_t state[48]; + // HMACSHA384(_ssoPsk, nonceBytes, sizeof(nonceBytes), state); + // char state_hex[256]; + // Utils::hex(state, 48, state_hex); + + // if (info.version == 0) { + // char url[2048] = {0}; + // OSUtils::ztsnprintf(url, sizeof(authenticationURL), + // "%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redirect_uri=%s&nonce=%s&state=%s&client_id=%s", + // authorization_endpoint.c_str(), + // url_encode(redirectURL).c_str(), + // nonce.c_str(), + // state_hex, + // client_id.c_str()); + // info.authenticationURL = std::string(url); + // } else if (info.version == 1) { + // info.ssoClientID = client_id; + // info.issuerURL = issuer; + // info.ssoProvider = provider; + // info.ssoNonce = nonce; + // info.ssoState = std::string(state_hex) + "_" +networkId; + // info.centralAuthURL = redirectURL; + // #ifdef ZT_DEBUG + // fprintf( + // stderr, + // "ssoClientID: %s\nissuerURL: %s\nssoNonce: %s\nssoState: %s\ncentralAuthURL: %s\nprovider: %s\n", + // info.ssoClientID.c_str(), + // info.issuerURL.c_str(), + // info.ssoNonce.c_str(), + // info.ssoState.c_str(), + // info.centralAuthURL.c_str(), + // provider.c_str()); + // #endif + // } + // } else { + // fprintf(stderr, "client_id: %s\nauthorization_endpoint: %s\n", client_id.c_str(), authorization_endpoint.c_str()); + // } + // } + + // _pool->unborrow(c); + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error updating member on load for network %s: %s\n", networkId.c_str(), e.what()); } - return info; //std::string(authenticationURL); + return info; // std::string(authenticationURL); } void CV2::initializeNetworks() -{ fprintf(stderr, "Initializing networks...\n"); - - try { +{ + fprintf(stderr, "Initializing networks...\n"); + + try { char qbuf[2048]; - sprintf(qbuf, "SELECT id, name, configuration , (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint, " + sprintf( + qbuf, + "SELECT id, name, configuration , (EXTRACT(EPOCH FROM creation_time AT TIME ZONE 'UTC')*1000)::bigint, " "(EXTRACT(EPOCH FROM last_modified AT TIME ZONE 'UTC')*1000)::bigint, revision " - "FROM networks_ctl WHERE controller_id = '%s'", _myAddressStr.c_str()); + "FROM networks_ctl WHERE controller_id = '%s'", + _myAddressStr.c_str()); auto c = _pool->borrow(); pqxx::work w(*c->c); @@ -391,13 +389,19 @@ void CV2::initializeNetworks() fprintf(stderr, "Load networks from psql...\n"); auto stream = pqxx::stream_from::query(w, qbuf); std::tuple< - std::string // network ID - , std::optional // name - , std::string // configuration - , std::optional // creation_time - , std::optional // last_modified - , std::optional // revision - > row; + std::string // network ID + , + std::optional // name + , + std::string // configuration + , + std::optional // creation_time + , + std::optional // last_modified + , + std::optional // revision + > + row; uint64_t count = 0; uint64_t total = 0; while (stream >> row) { @@ -432,13 +436,15 @@ void CV2::initializeNetworks() config["tags"] = cfgtmp["tags"].is_array() ? cfgtmp["tags"] : json::array(); if (cfgtmp["v4AssignMode"].is_object()) { config["v4AssignMode"] = cfgtmp["v4AssignMode"]; - } else { + } + else { config["v4AssignMode"] = json::object(); config["v4AssignMode"]["zt"] = true; } if (cfgtmp["v6AssignMode"].is_object()) { config["v6AssignMode"] = cfgtmp["v6AssignMode"]; - } else { + } + else { config["v6AssignMode"] = json::object(); config["v6AssignMode"]["zt"] = true; config["v6AssignMode"]["6plane"] = true; @@ -450,11 +456,12 @@ void CV2::initializeNetworks() config["clientId"] = cfgtmp["clientId"].is_string() ? cfgtmp["clientId"].get() : ""; config["authorizationEndpoint"] = cfgtmp["authorizationEndpoint"].is_string() ? cfgtmp["authorizationEndpoint"].get() : nullptr; config["provider"] = cfgtmp["ssoProvider"].is_string() ? cfgtmp["ssoProvider"].get() : ""; - if (!cfgtmp["dns"].is_object()) { + if (! cfgtmp["dns"].is_object()) { cfgtmp["dns"] = json::object(); cfgtmp["dns"]["domain"] = ""; - cfgtmp["dns"]["servers"] = json::array(); - } else { + cfgtmp["dns"]["servers"] = json::array(); + } + else { config["dns"] = cfgtmp["dns"]; } config["ipAssignmentPools"] = cfgtmp["ipAssignmentPools"].is_array() ? cfgtmp["ipAssignmentPools"] : json::array(); @@ -464,11 +471,12 @@ void CV2::initializeNetworks() _networkChanged(empty, config, false); auto end = std::chrono::high_resolution_clock::now(); - auto dur = std::chrono::duration_cast(end - start);; + auto dur = std::chrono::duration_cast(end - start); + ; total += dur.count(); ++count; if (count > 0 && count % 10000 == 0) { - fprintf(stderr, "Averaging %lu us per network\n", (total/count)); + fprintf(stderr, "Averaging %lu us per network\n", (total / count)); } } @@ -476,27 +484,29 @@ void CV2::initializeNetworks() _pool->unborrow(c); fprintf(stderr, "done.\n"); - if (++this->_ready == 2) { + if (++this->_ready == 2) { if (_waitNoticePrinted) { - fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S, _timestr(), (unsigned long long)_myAddress.toInt()); } _readyLock.unlock(); } - fprintf(stderr, "network init done\n"); - } catch (std::exception &e) { + fprintf(stderr, "network init done\n"); + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error initializing networks: %s\n", e.what()); std::this_thread::sleep_for(std::chrono::milliseconds(5000)); exit(-1); } -} +} void CV2::initializeMembers() { - std::string memberId; + std::string memberId; std::string networkId; - try { + try { char qbuf[2048]; - sprintf(qbuf, + sprintf( + qbuf, "SELECT nm.device_id, nm.network_id, nm.authorized, nm.active_bridge, nm.ip_assignments, nm.no_auto_assign_ips, " "nm.sso_exempt, (EXTRACT(EPOCH FROM nm.authentication_expiry_time AT TIME ZONE 'UTC')*1000)::bigint, " "(EXTRACT(EPOCH FROM nm.creation_time AT TIME ZONE 'UTC')*1000)::bigint, nm.identity, " @@ -506,31 +516,49 @@ void CV2::initializeMembers() "FROM network_memberships_ctl nm " "INNER JOIN networks_ctl n " " ON nm.network_id = n.id " - "WHERE n.controller_id = '%s'", _myAddressStr.c_str()); - + "WHERE n.controller_id = '%s'", + _myAddressStr.c_str()); + auto c = _pool->borrow(); pqxx::work w(*c->c); fprintf(stderr, "Load members from psql...\n"); auto stream = pqxx::stream_from::query(w, qbuf); std::tuple< - std::string // device ID - , std::string // network ID - , bool // authorized - , std::optional // active_bridge - , std::optional // ip_assignments - , std::optional // no_auto_assign_ips - , std::optional // sso_exempt - , std::optional // authentication_expiry_time - , std::optional // creation_time - , std::optional // identity - , std::optional // last_authorized_time - , std::optional // last_deauthorized_time - , std::optional // remote_trace_level - , std::optional // remote_trace_target - , std::optional // revision - , std::optional // capabilities - , std::optional // tags - > row; + std::string // device ID + , + std::string // network ID + , + bool // authorized + , + std::optional // active_bridge + , + std::optional // ip_assignments + , + std::optional // no_auto_assign_ips + , + std::optional // sso_exempt + , + std::optional // authentication_expiry_time + , + std::optional // creation_time + , + std::optional // identity + , + std::optional // last_authorized_time + , + std::optional // last_deauthorized_time + , + std::optional // remote_trace_level + , + std::optional // remote_trace_target + , + std::optional // revision + , + std::optional // capabilities + , + std::optional // tags + > + row; uint64_t count = 0; uint64_t total = 0; @@ -597,11 +625,11 @@ void CV2::initializeMembers() total += dur.count(); ++count; if (count > 0 && count % 10000 == 0) { - fprintf(stderr, "Averaging %lu us per member\n", (total/count)); + fprintf(stderr, "Averaging %lu us per member\n", (total / count)); } } if (count > 0) { - fprintf(stderr, "Took %lu us per member to load\n", (total/count)); + fprintf(stderr, "Took %lu us per member to load\n", (total / count)); } stream.complete(); @@ -609,14 +637,15 @@ void CV2::initializeMembers() _pool->unborrow(c); fprintf(stderr, "done.\n"); - if (++this->_ready == 2) { + if (++this->_ready == 2) { if (_waitNoticePrinted) { - fprintf(stderr,"[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S,_timestr(),(unsigned long long)_myAddress.toInt()); + fprintf(stderr, "[%s] NOTICE: %.10llx controller PostgreSQL data download complete." ZT_EOL_S, _timestr(), (unsigned long long)_myAddress.toInt()); } _readyLock.unlock(); } - fprintf(stderr, "member init done\n"); - } catch (std::exception &e) { + fprintf(stderr, "member init done\n"); + } + catch (std::exception& e) { fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what()); exit(-1); } @@ -624,100 +653,109 @@ void CV2::initializeMembers() void CV2::heartbeat() { - char publicId[1024]; + char publicId[1024]; char hostnameTmp[1024]; - _myId.toString(false,publicId); - if (gethostname(hostnameTmp, sizeof(hostnameTmp))!= 0) { + _myId.toString(false, publicId); + if (gethostname(hostnameTmp, sizeof(hostnameTmp)) != 0) { hostnameTmp[0] = (char)0; - } else { + } + else { for (int i = 0; i < (int)sizeof(hostnameTmp); ++i) { - if ((hostnameTmp[i] == '.')||(hostnameTmp[i] == 0)) { + if ((hostnameTmp[i] == '.') || (hostnameTmp[i] == 0)) { hostnameTmp[i] = (char)0; break; } } } - const char *controllerId = _myAddressStr.c_str(); - const char *publicIdentity = publicId; - const char *hostname = hostnameTmp; + const char* controllerId = _myAddressStr.c_str(); + const char* publicIdentity = publicId; + const char* hostname = hostnameTmp; - while (_run == 1) { - auto c = _pool->borrow(); - int64_t ts = OSUtils::now(); + while (_run == 1) { + auto c = _pool->borrow(); + int64_t ts = OSUtils::now(); - if (c->c) { - std::string major = std::to_string(ZEROTIER_ONE_VERSION_MAJOR); - std::string minor = std::to_string(ZEROTIER_ONE_VERSION_MINOR); - std::string rev = std::to_string(ZEROTIER_ONE_VERSION_REVISION); - std::string version = major + "." + minor + "." + rev; - std::string versionStr = "v" + version; + if (c->c) { + std::string major = std::to_string(ZEROTIER_ONE_VERSION_MAJOR); + std::string minor = std::to_string(ZEROTIER_ONE_VERSION_MINOR); + std::string rev = std::to_string(ZEROTIER_ONE_VERSION_REVISION); + std::string version = major + "." + minor + "." + rev; + std::string versionStr = "v" + version; - try { - pqxx::work w{*c->c}; - w.exec_params0("INSERT INTO controllers_ctl (id, hostname, last_heartbeat, public_identity, version) VALUES " - "($1, $2, TO_TIMESTAMP($3::double precision/1000), $4, $5) " - "ON CONFLICT (id) DO UPDATE SET hostname = EXCLUDED.hostname, last_heartbeat = EXCLUDED.last_heartbeat, " - "public_identity = EXCLUDED.public_identity, version = EXCLUDED.version", - controllerId, hostname, ts, publicIdentity, versionStr); - w.commit(); - } catch (std::exception &e) { - fprintf(stderr, "ERROR: Error in heartbeat: %s\n", e.what()); - continue; - } catch (...) { - fprintf(stderr, "ERROR: Unknown error in heartbeat\n"); - continue; - } - } + try { + pqxx::work w { *c->c }; + w.exec_params0( + "INSERT INTO controllers_ctl (id, hostname, last_heartbeat, public_identity, version) VALUES " + "($1, $2, TO_TIMESTAMP($3::double precision/1000), $4, $5) " + "ON CONFLICT (id) DO UPDATE SET hostname = EXCLUDED.hostname, last_heartbeat = EXCLUDED.last_heartbeat, " + "public_identity = EXCLUDED.public_identity, version = EXCLUDED.version", + controllerId, + hostname, + ts, + publicIdentity, + versionStr); + w.commit(); + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: Error in heartbeat: %s\n", e.what()); + continue; + } + catch (...) { + fprintf(stderr, "ERROR: Unknown error in heartbeat\n"); + continue; + } + } - _pool->unborrow(c); + _pool->unborrow(c); - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - fprintf(stderr, "Exited heartbeat thread\n"); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + fprintf(stderr, "Exited heartbeat thread\n"); } -void CV2::membersDbWatcher() { - auto c = _pool->borrow(); +void CV2::membersDbWatcher() +{ + auto c = _pool->borrow(); std::string stream = "member_" + _myAddressStr; fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); MemberNotificationReceiver m(this, *c->c, stream); - while(_run == 1) { + while (_run == 1) { c->c->await_notification(5, 0); } _pool->unborrow(c); - fprintf(stderr, "Exited membersDbWatcher\n"); + fprintf(stderr, "Exited membersDbWatcher\n"); } void CV2::networksDbWatcher() { - std::string stream = "network_" + _myAddressStr; + std::string stream = "network_" + _myAddressStr; fprintf(stderr, "Listening to member stream: %s\n", stream.c_str()); - + auto c = _pool->borrow(); NetworkNotificationReceiver n(this, *c->c, stream); - while(_run == 1) { - c->c->await_notification(5,0); + while (_run == 1) { + c->c->await_notification(5, 0); } - _pool->unborrow(c); - fprintf(stderr, "Exited networksDbWatcher\n"); + _pool->unborrow(c); + fprintf(stderr, "Exited networksDbWatcher\n"); } void CV2::commitThread() { fprintf(stderr, "%s: commitThread start\n", _myAddressStr.c_str()); - std::pair qitem; - while(_commitQueue.get(qitem)&&(_run == 1)) { - //fprintf(stderr, "commitThread tick\n"); - if (!qitem.first.is_object()) { + std::pair qitem; + while (_commitQueue.get(qitem) && (_run == 1)) { + // fprintf(stderr, "commitThread tick\n"); + if (! qitem.first.is_object()) { fprintf(stderr, "not an object\n"); continue; } @@ -725,19 +763,20 @@ void CV2::commitThread() std::shared_ptr c; try { c = _pool->borrow(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "ERROR: %s\n", e.what()); continue; } - if (!c) { + if (! c) { fprintf(stderr, "Error getting database connection\n"); continue; } - + Metrics::pgsql_commit_ticks++; try { - nlohmann::json &config = (qitem.first); + nlohmann::json& config = (qitem.first); const std::string objtype = config["objtype"]; if (objtype == "member") { // fprintf(stderr, "%s: commitThread: member\n", _myAddressStr.c_str()); @@ -745,15 +784,15 @@ void CV2::commitThread() std::string networkId; try { pqxx::work w(*c->c); - + memberId = config["id"]; networkId = config["nwid"]; std::string target = "NULL"; - if (!config["remoteTraceTarget"].is_null()) { + if (! config["remoteTraceTarget"].is_null()) { target = config["remoteTraceTarget"]; } - + pqxx::row nwrow = w.exec_params1("SELECT COUNT(id) FROM networks WHERE id = $1", networkId); int nwcount = nwrow[0].as(); @@ -793,7 +832,7 @@ void CV2::commitThread() networkId, (bool)config["authorized"], (bool)config["activeBridge"], - config["ipAssignments"].get>(), + config["ipAssignments"].get >(), (bool)config["noAutoAssignIps"], (bool)config["ssoExempt"], (uint64_t)config["authenticationExpiryTime"], @@ -843,29 +882,33 @@ void CV2::commitThread() get(nwidInt, nwOrig, memberidInt, memOrig); _memberChanged(memOrig, memNew, qitem.second); - } else { + } + else { fprintf(stderr, "%s: Can't notify of change. Error parsing nwid or memberid: %llu-%llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt, (unsigned long long)memberidInt); } - } catch (pqxx::data_exception &e) { + } + catch (pqxx::data_exception& e) { std::string cfgDump = OSUtils::jsonDump(config, 2); fprintf(stderr, "Member save %s-%s: %s\n", networkId.c_str(), memberId.c_str(), cfgDump.c_str()); - - const pqxx::sql_error *s=dynamic_cast(&e); + + const pqxx::sql_error* s = dynamic_cast(&e); fprintf(stderr, "%s ERROR: Error updating member: %s\n", _myAddressStr.c_str(), e.what()); if (s) { fprintf(stderr, "%s ERROR: SQL error: %s\n", _myAddressStr.c_str(), s->query().c_str()); } - } catch (std::exception &e) { + } + catch (std::exception& e) { std::string cfgDump = OSUtils::jsonDump(config, 2); fprintf(stderr, "%s ERROR: Error updating member %s-%s: %s\njsonDump: %s\n", _myAddressStr.c_str(), networkId.c_str(), memberId.c_str(), e.what(), cfgDump.c_str()); } - } else if (objtype == "network") { + } + else if (objtype == "network") { try { // fprintf(stderr, "%s: commitThread: network\n", _myAddressStr.c_str()); pqxx::work w(*c->c); std::string id = config["id"]; - + // network must already exist pqxx::result res = w.exec_params0( "INSERT INTO networks_ctl (id, name, configuration, controller_id, revision) " @@ -876,8 +919,7 @@ void CV2::commitThread() OSUtils::jsonString(config["name"], ""), OSUtils::jsonDump(config, -1), _myAddressStr, - ((uint64_t)config["revision"]) - ); + ((uint64_t)config["revision"])); w.commit(); @@ -889,34 +931,40 @@ void CV2::commitThread() get(nwidInt, nwOrig); _networkChanged(nwOrig, nwNew, qitem.second); - } else { + } + else { fprintf(stderr, "%s: Can't notify network changed: %llu\n", _myAddressStr.c_str(), (unsigned long long)nwidInt); } - } catch (pqxx::data_exception &e) { - const pqxx::sql_error *s=dynamic_cast(&e); + } + catch (pqxx::data_exception& e) { + const pqxx::sql_error* s = dynamic_cast(&e); fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); if (s) { fprintf(stderr, "%s ERROR: SQL error: %s\n", _myAddressStr.c_str(), s->query().c_str()); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error updating network: %s\n", _myAddressStr.c_str(), e.what()); } - } else if (objtype == "_delete_network") { + } + else if (objtype == "_delete_network") { // fprintf(stderr, "%s: commitThread: delete network\n", _myAddressStr.c_str()); try { // don't think we need this. Deletion handled by CV2 API - + pqxx::work w(*c->c); std::string networkId = config["id"]; - + w.exec_params0("DELETE FROM network_memberships_ctl WHERE network_id = $1", networkId); w.exec_params0("DELETE FROM networks_ctl WHERE id = $1", networkId); w.commit(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error deleting network: %s\n", _myAddressStr.c_str(), e.what()); } - } else if (objtype == "_delete_member") { + } + else if (objtype == "_delete_member") { // fprintf(stderr, "%s commitThread: delete member\n", _myAddressStr.c_str()); try { pqxx::work w(*c->c); @@ -924,18 +972,19 @@ void CV2::commitThread() std::string memberId = config["id"]; std::string networkId = config["nwid"]; - pqxx::result res = w.exec_params0( - "DELETE FROM network_memberships_ctl WHERE device_id = $1 AND network_id = $2", - memberId, networkId); + pqxx::result res = w.exec_params0("DELETE FROM network_memberships_ctl WHERE device_id = $1 AND network_id = $2", memberId, networkId); w.commit(); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error deleting member: %s\n", _myAddressStr.c_str(), e.what()); } - } else { + } + else { fprintf(stderr, "%s ERROR: unknown objtype\n", _myAddressStr.c_str()); } - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error getting objtype: %s\n", _myAddressStr.c_str(), e.what()); } _pool->unborrow(c); @@ -945,20 +994,21 @@ void CV2::commitThread() fprintf(stderr, "%s commitThread finished\n", _myAddressStr.c_str()); } -void CV2::onlineNotificationThread() { - waitForReady(); +void CV2::onlineNotificationThread() +{ + waitForReady(); - _connected = 1; + _connected = 1; - nlohmann::json jtmp1, jtmp2; - while (_run == 1) { + nlohmann::json jtmp1, jtmp2; + while (_run == 1) { auto c = _pool->borrow(); auto c2 = _pool->borrow(); try { fprintf(stderr, "%s onlineNotificationThread\n", _myAddressStr.c_str()); - std::unordered_map, NodeOnlineRecord,_PairHasher> lastOnline; + std::unordered_map, NodeOnlineRecord, _PairHasher> lastOnline; { std::lock_guard l(_lastOnline_l); lastOnline.swap(_lastOnline); @@ -981,20 +1031,20 @@ void CV2::onlineNotificationThread() { char memTmp[64]; char ipTmp[64]; - OSUtils::ztsnprintf(nwidTmp,sizeof(nwidTmp), "%.16llx", nwid_i); - OSUtils::ztsnprintf(memTmp,sizeof(memTmp), "%.10llx", i->first.second); + OSUtils::ztsnprintf(nwidTmp, sizeof(nwidTmp), "%.16llx", nwid_i); + OSUtils::ztsnprintf(memTmp, sizeof(memTmp), "%.10llx", i->first.second); - if(!get(nwid_i, jtmp1, i->first.second, jtmp2)) { - continue; // skip non existent networks/members + if (! get(nwid_i, jtmp1, i->first.second, jtmp2)) { + continue; // skip non existent networks/members } std::string networkId(nwidTmp); std::string memberId(memTmp); try { - pqxx::row r = w2.exec_params1("SELECT device_id, network_id FROM network_memberships_ctl WHERE network_id = $1 AND device_id = $2", - networkId, memberId); - } catch (pqxx::unexpected_rows &e) { + pqxx::row r = w2.exec_params1("SELECT device_id, network_id FROM network_memberships_ctl WHERE network_id = $1 AND device_id = $2", networkId, memberId); + } + catch (pqxx::unexpected_rows& e) { continue; } @@ -1011,37 +1061,44 @@ void CV2::onlineNotificationThread() { } json record = { - {ipAddr, ts}, + { ipAddr, ts }, }; - std::string device_network_insert = "INSERT INTO network_memberships_ctl (device_id, network_id, last_seen, os, arch) " - "VALUES ('"+w2.esc(memberId)+"', '"+w2.esc(networkId)+"', '"+w2.esc(record.dump())+"'::JSONB, " - "'"+w2.esc(os)+"', '"+w2.esc(arch)+"') " - "ON CONFLICT (device_id, network_id) DO UPDATE SET os = EXCLUDED.os, arch = EXCLUDED.arch, " - "last_seen = network_memberships_ctl.last_seen || EXCLUDED.last_seen"; + std::string device_network_insert = "INSERT INTO network_memberships_ctl (device_id, network_id, last_seen, os, arch) " + "VALUES ('" + + w2.esc(memberId) + "', '" + w2.esc(networkId) + "', '" + w2.esc(record.dump()) + + "'::JSONB, " + "'" + + w2.esc(os) + "', '" + w2.esc(arch) + + "') " + "ON CONFLICT (device_id, network_id) DO UPDATE SET os = EXCLUDED.os, arch = EXCLUDED.arch, " + "last_seen = network_memberships_ctl.last_seen || EXCLUDED.last_seen"; pipe.insert(device_network_insert); Metrics::pgsql_node_checkin++; } - pipe.complete();; + pipe.complete(); + ; w2.commit(); w.commit(); fprintf(stderr, "%s: Updated online status of %lu members\n", _myAddressStr.c_str(), updateCount); - } catch (std::exception &e) { + } + catch (std::exception& e) { fprintf(stderr, "%s ERROR: Error in onlineNotificationThread: %s\n", _myAddressStr.c_str(), e.what()); - } catch (...) { + } + catch (...) { fprintf(stderr, "%s ERROR: Unknown error in onlineNotificationThread\n", _myAddressStr.c_str()); } _pool->unborrow(c2); _pool->unborrow(c); std::this_thread::sleep_for(std::chrono::seconds(10)); - } + } - fprintf(stderr, "%s: Fell out of run loop in onlineNotificationThread\n", _myAddressStr.c_str()); + fprintf(stderr, "%s: Fell out of run loop in onlineNotificationThread\n", _myAddressStr.c_str()); if (_run == 1) { fprintf(stderr, "ERROR: %s onlineNotificationThread should still be running! Exiting Controller.\n", _myAddressStr.c_str()); exit(6); } } -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/CV2.hpp b/controller/CV2.hpp index 1c432bf25..8302b98d3 100644 --- a/controller/CV2.hpp +++ b/controller/CV2.hpp @@ -20,51 +20,53 @@ #define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 +#include "../node/Metrics.hpp" #include "ConnectionPool.hpp" -#include +#include "PostgreSQL.hpp" #include +#include #include -#include "../node/Metrics.hpp" - -#include "PostgreSQL.hpp" - namespace ZeroTier { -class CV2 : public DB -{ -public: - CV2(const Identity &myId, const char *path, int listenPort); +class CV2 : public DB { + public: + CV2(const Identity& myId, const char* path, int listenPort); virtual ~CV2(); virtual bool waitForReady(); virtual bool isReady(); - virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual bool save(nlohmann::json& record, bool notifyListeners); virtual void eraseNetwork(const uint64_t networkId); virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch); - virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); + virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - virtual bool ready() { + virtual bool ready() + { return _ready == 2; } -protected: - struct _PairHasher - { - inline std::size_t operator()(const std::pair &p) const { return (std::size_t)(p.first ^ p.second); } + protected: + struct _PairHasher { + inline std::size_t operator()(const std::pair& p) const + { + return (std::size_t)(p.first ^ p.second); + } }; - virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) { + virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners) + { DB::_memberChanged(old, memberConfig, notifyListeners); } - virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) { + virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners) + { DB::_networkChanged(old, networkConfig, notifyListeners); } -private: + private: void initializeNetworks(); void initializeMembers(); void heartbeat(); @@ -76,10 +78,7 @@ private: // void notifyNewMember(const std::string &networkID, const std::string &memberID); - enum OverrideMode { - ALLOW_PGBOUNCER_OVERRIDE = 0, - NO_OVERRIDE = 1 - }; + enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 }; std::shared_ptr > _pool; @@ -88,7 +87,7 @@ private: std::string _myAddressStr; std::string _connString; - BlockingQueue< std::pair > _commitQueue; + BlockingQueue > _commitQueue; std::thread _heartbeatThread; std::thread _membersDbWatcher; @@ -96,7 +95,7 @@ private: std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; std::thread _onlineNotificationThread; - std::unordered_map< std::pair,NodeOnlineRecord,_PairHasher > _lastOnline; + std::unordered_map, NodeOnlineRecord, _PairHasher> _lastOnline; mutable std::mutex _lastOnline_l; mutable std::mutex _readyLock; @@ -107,7 +106,7 @@ private: uint8_t _ssoPsk[48]; }; -} // namespace Zerotier +} // namespace ZeroTier -#endif // ZT_CONTROLLER_CV2_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_CV2_HPP +#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/ConnectionPool.hpp b/controller/ConnectionPool.hpp index 8ccfb6bee..3c080bad5 100644 --- a/controller/ConnectionPool.hpp +++ b/controller/ConnectionPool.hpp @@ -14,162 +14,162 @@ #ifndef ZT_CONNECTION_POOL_H_ #define ZT_CONNECTION_POOL_H_ - #ifndef _DEBUG - #define _DEBUG(x) +#define _DEBUG(x) #endif #include "../node/Metrics.hpp" #include -#include +#include #include #include -#include +#include #include namespace ZeroTier { -struct ConnectionUnavailable : std::exception { - char const* what() const throw() { - return "Unable to allocate connection"; - }; +struct ConnectionUnavailable : std::exception { + char const* what() const throw() + { + return "Unable to allocate connection"; + }; }; - class Connection { -public: - virtual ~Connection() {}; + public: + virtual ~Connection() {}; }; class ConnectionFactory { -public: - virtual ~ConnectionFactory() {}; - virtual std::shared_ptr create()=0; + public: + virtual ~ConnectionFactory() {}; + virtual std::shared_ptr create() = 0; }; struct ConnectionPoolStats { - size_t pool_size; - size_t borrowed_size; + size_t pool_size; + size_t borrowed_size; }; -template -class ConnectionPool { -public: - ConnectionPool(size_t max_pool_size, size_t min_pool_size, std::shared_ptr factory) - : m_maxPoolSize(max_pool_size) - , m_minPoolSize(min_pool_size) - , m_factory(factory) - { - Metrics::max_pool_size += max_pool_size; - Metrics::min_pool_size += min_pool_size; - while(m_pool.size() < m_minPoolSize){ - m_pool.push_back(m_factory->create()); - Metrics::pool_avail++; - } - }; +template class ConnectionPool { + public: + ConnectionPool(size_t max_pool_size, size_t min_pool_size, std::shared_ptr factory) : m_maxPoolSize(max_pool_size), m_minPoolSize(min_pool_size), m_factory(factory) + { + Metrics::max_pool_size += max_pool_size; + Metrics::min_pool_size += min_pool_size; + while (m_pool.size() < m_minPoolSize) { + m_pool.push_back(m_factory->create()); + Metrics::pool_avail++; + } + }; - ConnectionPoolStats get_stats() { - std::unique_lock lock(m_poolMutex); + ConnectionPoolStats get_stats() + { + std::unique_lock lock(m_poolMutex); - ConnectionPoolStats stats; - stats.pool_size = m_pool.size(); - stats.borrowed_size = m_borrowed.size(); + ConnectionPoolStats stats; + stats.pool_size = m_pool.size(); + stats.borrowed_size = m_borrowed.size(); - return stats; - }; + return stats; + }; - ~ConnectionPool() { - }; + ~ConnectionPool() {}; - /** - * Borrow - * - * Borrow a connection for temporary use - * - * When done, either (a) call unborrow() to return it, or (b) (if it's bad) just let it go out of scope. This will cause it to automatically be replaced. - * @retval a shared_ptr to the connection object - */ - std::shared_ptr borrow() { - std::unique_lock l(m_poolMutex); - - while((m_pool.size() + m_borrowed.size()) < m_minPoolSize) { - std::shared_ptr conn = m_factory->create(); - m_pool.push_back(conn); - Metrics::pool_avail++; - } + /** + * Borrow + * + * Borrow a connection for temporary use + * + * When done, either (a) call unborrow() to return it, or (b) (if it's bad) just let it go out of scope. This will cause it to automatically be replaced. + * @retval a shared_ptr to the connection object + */ + std::shared_ptr borrow() + { + std::unique_lock l(m_poolMutex); - if(m_pool.size()==0){ - - if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { - try { - std::shared_ptr conn = m_factory->create(); - m_borrowed.insert(conn); - Metrics::pool_in_use++; - return std::static_pointer_cast(conn); - } catch (std::exception &e) { - Metrics::pool_errors++; - throw ConnectionUnavailable(); - } - } else { - for(auto it = m_borrowed.begin(); it != m_borrowed.end(); ++it){ - if((*it).unique()) { - // This connection has been abandoned! Destroy it and create a new connection - try { - // If we are able to create a new connection, return it - _DEBUG("Creating new connection to replace discarded connection"); - std::shared_ptr conn = m_factory->create(); - m_borrowed.erase(it); - m_borrowed.insert(conn); - return std::static_pointer_cast(conn); - } catch(std::exception& e) { - // Error creating a replacement connection - Metrics::pool_errors++; - throw ConnectionUnavailable(); - } - } - } - // Nothing available - Metrics::pool_errors++; - throw ConnectionUnavailable(); - } - } + while ((m_pool.size() + m_borrowed.size()) < m_minPoolSize) { + std::shared_ptr conn = m_factory->create(); + m_pool.push_back(conn); + Metrics::pool_avail++; + } - // Take one off the front - std::shared_ptr conn = m_pool.front(); - m_pool.pop_front(); - Metrics::pool_avail--; - // Add it to the borrowed list - m_borrowed.insert(conn); - Metrics::pool_in_use++; - return std::static_pointer_cast(conn); - }; + if (m_pool.size() == 0) { + if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { + try { + std::shared_ptr conn = m_factory->create(); + m_borrowed.insert(conn); + Metrics::pool_in_use++; + return std::static_pointer_cast(conn); + } + catch (std::exception& e) { + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } + else { + for (auto it = m_borrowed.begin(); it != m_borrowed.end(); ++it) { + if ((*it).unique()) { + // This connection has been abandoned! Destroy it and create a new connection + try { + // If we are able to create a new connection, return it + _DEBUG("Creating new connection to replace discarded connection"); + std::shared_ptr conn = m_factory->create(); + m_borrowed.erase(it); + m_borrowed.insert(conn); + return std::static_pointer_cast(conn); + } + catch (std::exception& e) { + // Error creating a replacement connection + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } + } + // Nothing available + Metrics::pool_errors++; + throw ConnectionUnavailable(); + } + } - /** - * Unborrow a connection - * - * Only call this if you are returning a working connection. If the connection was bad, just let it go out of scope (so the connection manager can replace it). - * @param the connection - */ - void unborrow(std::shared_ptr conn) { - // Lock - std::unique_lock lock(m_poolMutex); - m_borrowed.erase(conn); - Metrics::pool_in_use--; - if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { - Metrics::pool_avail++; - m_pool.push_back(conn); - } - }; -protected: - size_t m_maxPoolSize; - size_t m_minPoolSize; - std::shared_ptr m_factory; - std::deque > m_pool; - std::set > m_borrowed; - std::mutex m_poolMutex; + // Take one off the front + std::shared_ptr conn = m_pool.front(); + m_pool.pop_front(); + Metrics::pool_avail--; + // Add it to the borrowed list + m_borrowed.insert(conn); + Metrics::pool_in_use++; + return std::static_pointer_cast(conn); + }; + + /** + * Unborrow a connection + * + * Only call this if you are returning a working connection. If the connection was bad, just let it go out of scope (so the connection manager can replace it). + * @param the connection + */ + void unborrow(std::shared_ptr conn) + { + // Lock + std::unique_lock lock(m_poolMutex); + m_borrowed.erase(conn); + Metrics::pool_in_use--; + if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) { + Metrics::pool_avail++; + m_pool.push_back(conn); + } + }; + + protected: + size_t m_maxPoolSize; + size_t m_minPoolSize; + std::shared_ptr m_factory; + std::deque > m_pool; + std::set > m_borrowed; + std::mutex m_poolMutex; }; -} +} // namespace ZeroTier #endif diff --git a/controller/CtlUtil.cpp b/controller/CtlUtil.cpp index 87d7345c1..e1e82f7a3 100644 --- a/controller/CtlUtil.cpp +++ b/controller/CtlUtil.cpp @@ -2,17 +2,17 @@ #ifdef ZT_CONTROLLER_USE_LIBPQ -#include #include +#include namespace ZeroTier { -const char *_timestr() +const char* _timestr() { time_t t = time(0); - char *ts = ctime(&t); - char *p = ts; - if (!p) + char* ts = ctime(&t); + char* p = ts; + if (! p) return ""; while (*p) { if (*p == '\n') { @@ -24,39 +24,41 @@ const char *_timestr() return ts; } -std::vector split(std::string str, char delim){ +std::vector split(std::string str, char delim) +{ std::istringstream iss(str); std::vector tokens; std::string item; - while(std::getline(iss, item, delim)) { + while (std::getline(iss, item, delim)) { tokens.push_back(item); } return tokens; } -std::string url_encode(const std::string &value) { - std::ostringstream escaped; - escaped.fill('0'); - escaped << std::hex; +std::string url_encode(const std::string& value) +{ + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; - for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) { - std::string::value_type c = (*i); + for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) { + std::string::value_type c = (*i); - // Keep alphanumeric and other accepted characters intact - if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { - escaped << c; - continue; - } + // Keep alphanumeric and other accepted characters intact + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + escaped << c; + continue; + } - // Any other characters are percent-encoded - escaped << std::uppercase; - escaped << '%' << std::setw(2) << int((unsigned char) c); - escaped << std::nouppercase; - } + // Any other characters are percent-encoded + escaped << std::uppercase; + escaped << '%' << std::setw(2) << int((unsigned char)c); + escaped << std::nouppercase; + } - return escaped.str(); + return escaped.str(); } -} // namespace ZeroTier +} // namespace ZeroTier #endif \ No newline at end of file diff --git a/controller/CtlUtil.hpp b/controller/CtlUtil.hpp index f4d339169..0ba665af3 100644 --- a/controller/CtlUtil.hpp +++ b/controller/CtlUtil.hpp @@ -1,16 +1,16 @@ #ifndef ZT_CTLUTIL_HPP #define ZT_CTLUTIL_HPP -#include #include +#include namespace ZeroTier { - const char *_timestr(); +const char* _timestr(); - std::vector split(std::string str, char delim); +std::vector split(std::string str, char delim); - std::string url_encode(const std::string &value); -} +std::string url_encode(const std::string& value); +} // namespace ZeroTier -#endif // namespace ZeroTier \ No newline at end of file +#endif // namespace ZeroTier \ No newline at end of file diff --git a/controller/DB.cpp b/controller/DB.cpp index 2c354ae7f..6d2f4f409 100644 --- a/controller/DB.cpp +++ b/controller/DB.cpp @@ -12,77 +12,114 @@ /****/ #include "DB.hpp" -#include "EmbeddedNetworkController.hpp" -#include "../node/Metrics.hpp" -#include +#include "../node/Metrics.hpp" +#include "EmbeddedNetworkController.hpp" + #include +#include #include using json = nlohmann::json; namespace ZeroTier { -void DB::initNetwork(nlohmann::json &network) +void DB::initNetwork(nlohmann::json& network) { - if (!network.count("private")) network["private"] = true; - if (!network.count("creationTime")) network["creationTime"] = OSUtils::now(); - if (!network.count("name")) network["name"] = ""; - if (!network.count("multicastLimit")) network["multicastLimit"] = (uint64_t)32; - if (!network.count("enableBroadcast")) network["enableBroadcast"] = true; - if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}}; - if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}}; - if (!network.count("authTokens")) network["authTokens"] = {{}}; - if (!network.count("capabilities")) network["capabilities"] = nlohmann::json::array(); - if (!network.count("tags")) network["tags"] = nlohmann::json::array(); - if (!network.count("routes")) network["routes"] = nlohmann::json::array(); - if (!network.count("ipAssignmentPools")) network["ipAssignmentPools"] = nlohmann::json::array(); - if (!network.count("mtu")) network["mtu"] = ZT_DEFAULT_MTU; - if (!network.count("remoteTraceTarget")) network["remoteTraceTarget"] = nlohmann::json(); - if (!network.count("removeTraceLevel")) network["remoteTraceLevel"] = 0; - if (!network.count("rulesSource")) network["rulesSource"] = ""; - if (!network.count("rules")) { + if (! network.count("private")) + network["private"] = true; + if (! network.count("creationTime")) + network["creationTime"] = OSUtils::now(); + if (! network.count("name")) + network["name"] = ""; + if (! network.count("multicastLimit")) + network["multicastLimit"] = (uint64_t)32; + if (! network.count("enableBroadcast")) + network["enableBroadcast"] = true; + if (! network.count("v4AssignMode")) + network["v4AssignMode"] = { { "zt", false } }; + if (! network.count("v6AssignMode")) + network["v6AssignMode"] = { { "rfc4193", false }, { "zt", false }, { "6plane", false } }; + if (! network.count("authTokens")) + network["authTokens"] = { {} }; + if (! network.count("capabilities")) + network["capabilities"] = nlohmann::json::array(); + if (! network.count("tags")) + network["tags"] = nlohmann::json::array(); + if (! network.count("routes")) + network["routes"] = nlohmann::json::array(); + if (! network.count("ipAssignmentPools")) + network["ipAssignmentPools"] = nlohmann::json::array(); + if (! network.count("mtu")) + network["mtu"] = ZT_DEFAULT_MTU; + if (! network.count("remoteTraceTarget")) + network["remoteTraceTarget"] = nlohmann::json(); + if (! network.count("removeTraceLevel")) + network["remoteTraceLevel"] = 0; + if (! network.count("rulesSource")) + network["rulesSource"] = ""; + if (! network.count("rules")) { // If unspecified, rules are set to allow anything and behave like a flat L2 segment - network["rules"] = {{ - { "not",false }, - { "or", false }, - { "type","ACTION_ACCEPT" } - }}; + network["rules"] = { { { "not", false }, { "or", false }, { "type", "ACTION_ACCEPT" } } }; } - if (!network.count("dns")) network["dns"] = nlohmann::json::array(); - if (!network.count("ssoEnabled")) network["ssoEnabled"] = false; - if (!network.count("clientId")) network["clientId"] = ""; - if (!network.count("authorizationEndpoint")) network["authorizationEndpoint"] = ""; + if (! network.count("dns")) + network["dns"] = nlohmann::json::array(); + if (! network.count("ssoEnabled")) + network["ssoEnabled"] = false; + if (! network.count("clientId")) + network["clientId"] = ""; + if (! network.count("authorizationEndpoint")) + network["authorizationEndpoint"] = ""; network["objtype"] = "network"; } -void DB::initMember(nlohmann::json &member) +void DB::initMember(nlohmann::json& member) { - if (!member.count("authorized")) member["authorized"] = false; - if (!member.count("ssoExempt")) member["ssoExempt"] = false; - if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array(); - if (!member.count("activeBridge")) member["activeBridge"] = false; - if (!member.count("tags")) member["tags"] = nlohmann::json::array(); - if (!member.count("capabilities")) member["capabilities"] = nlohmann::json::array(); - if (!member.count("creationTime")) member["creationTime"] = OSUtils::now(); - if (!member.count("noAutoAssignIps")) member["noAutoAssignIps"] = false; - if (!member.count("revision")) member["revision"] = 0ULL; - if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL; - if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL; - if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json(); - if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json(); - if (!member.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = 0LL; - if (!member.count("vMajor")) member["vMajor"] = -1; - if (!member.count("vMinor")) member["vMinor"] = -1; - if (!member.count("vRev")) member["vRev"] = -1; - if (!member.count("vProto")) member["vProto"] = -1; - if (!member.count("remoteTraceTarget")) member["remoteTraceTarget"] = nlohmann::json(); - if (!member.count("removeTraceLevel")) member["remoteTraceLevel"] = 0; + if (! member.count("authorized")) + member["authorized"] = false; + if (! member.count("ssoExempt")) + member["ssoExempt"] = false; + if (! member.count("ipAssignments")) + member["ipAssignments"] = nlohmann::json::array(); + if (! member.count("activeBridge")) + member["activeBridge"] = false; + if (! member.count("tags")) + member["tags"] = nlohmann::json::array(); + if (! member.count("capabilities")) + member["capabilities"] = nlohmann::json::array(); + if (! member.count("creationTime")) + member["creationTime"] = OSUtils::now(); + if (! member.count("noAutoAssignIps")) + member["noAutoAssignIps"] = false; + if (! member.count("revision")) + member["revision"] = 0ULL; + if (! member.count("lastDeauthorizedTime")) + member["lastDeauthorizedTime"] = 0ULL; + if (! member.count("lastAuthorizedTime")) + member["lastAuthorizedTime"] = 0ULL; + if (! member.count("lastAuthorizedCredentialType")) + member["lastAuthorizedCredentialType"] = nlohmann::json(); + if (! member.count("lastAuthorizedCredential")) + member["lastAuthorizedCredential"] = nlohmann::json(); + if (! member.count("authenticationExpiryTime")) + member["authenticationExpiryTime"] = 0LL; + if (! member.count("vMajor")) + member["vMajor"] = -1; + if (! member.count("vMinor")) + member["vMinor"] = -1; + if (! member.count("vRev")) + member["vRev"] = -1; + if (! member.count("vProto")) + member["vProto"] = -1; + if (! member.count("remoteTraceTarget")) + member["remoteTraceTarget"] = nlohmann::json(); + if (! member.count("removeTraceLevel")) + member["remoteTraceLevel"] = 0; member["objtype"] = "member"; } -void DB::cleanNetwork(nlohmann::json &network) +void DB::cleanNetwork(nlohmann::json& network) { network.erase("clock"); network.erase("authorizedMemberCount"); @@ -91,21 +128,25 @@ void DB::cleanNetwork(nlohmann::json &network) network.erase("lastModified"); } -void DB::cleanMember(nlohmann::json &member) +void DB::cleanMember(nlohmann::json& member) { member.erase("clock"); member.erase("physicalAddr"); member.erase("recentLog"); member.erase("lastModified"); member.erase("lastRequestMetaData"); - member.erase("authenticationURL"); // computed - member.erase("authenticationClientID"); // computed + member.erase("authenticationURL"); // computed + member.erase("authenticationClientID"); // computed } -DB::DB() {} -DB::~DB() {} +DB::DB() +{ +} +DB::~DB() +{ +} -bool DB::get(const uint64_t networkId,nlohmann::json &network) +bool DB::get(const uint64_t networkId, nlohmann::json& network) { waitForReady(); Metrics::db_get_network++; @@ -124,7 +165,7 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network) return true; } -bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) +bool DB::get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member) { waitForReady(); Metrics::db_get_network_and_member++; @@ -147,7 +188,7 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem return true; } -bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info) +bool DB::get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member, NetworkSummaryInfo& info) { waitForReady(); Metrics::db_get_network_and_member_and_summary++; @@ -162,7 +203,7 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem { std::shared_lock l2(nw->lock); network = nw->config; - _fillSummaryInfo(nw,info); + _fillSummaryInfo(nw, info); auto m = nw->members.find(memberId); if (m == nw->members.end()) return false; @@ -171,7 +212,7 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem return true; } -bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector &members) +bool DB::get(const uint64_t networkId, nlohmann::json& network, std::vector& members) { waitForReady(); Metrics::db_get_member_list++; @@ -186,23 +227,23 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector l2(nw->lock); network = nw->config; - for(auto m=nw->members.begin();m!=nw->members.end();++m) { + for (auto m = nw->members.begin(); m != nw->members.end(); ++m) { members.push_back(m->second); } } return true; } -void DB::networks(std::set &networks) +void DB::networks(std::set& networks) { waitForReady(); Metrics::db_get_network_list++; std::shared_lock l(_networks_l); - for(auto n=_networks.begin();n!=_networks.end();++n) + for (auto n = _networks.begin(); n != _networks.end(); ++n) networks.insert(n->first); } -void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) +void DB::_memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners) { Metrics::db_member_change++; uint64_t memberId = 0; @@ -212,9 +253,9 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no std::shared_ptr<_Network> nw; if (old.is_object()) { - memberId = OSUtils::jsonIntHex(old["id"],0ULL); - networkId = OSUtils::jsonIntHex(old["nwid"],0ULL); - if ((memberId)&&(networkId)) { + memberId = OSUtils::jsonIntHex(old["id"], 0ULL); + networkId = OSUtils::jsonIntHex(old["nwid"], 0ULL); + if ((memberId) && (networkId)) { { std::unique_lock l(_networks_l); auto nw2 = _networks.find(networkId); @@ -224,17 +265,17 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no } if (nw) { std::unique_lock l(nw->lock); - if (OSUtils::jsonBool(old["activeBridge"],false)) { + if (OSUtils::jsonBool(old["activeBridge"], false)) { nw->activeBridgeMembers.erase(memberId); } - wasAuth = OSUtils::jsonBool(old["authorized"],false); + wasAuth = OSUtils::jsonBool(old["authorized"], false); if (wasAuth) { nw->authorizedMembers.erase(memberId); } - json &ips = old["ipAssignments"]; + json& ips = old["ipAssignments"]; if (ips.is_array()) { - for(unsigned long i=0;i l(_networks_l); - std::shared_ptr<_Network> &nw2 = _networks[networkId]; - if (!nw2) + std::shared_ptr<_Network>& nw2 = _networks[networkId]; + if (! nw2) nw2.reset(new _Network); nw = nw2; } @@ -265,18 +306,18 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no nw->members[memberId] = memberConfig; - if (OSUtils::jsonBool(memberConfig["activeBridge"],false)) { + if (OSUtils::jsonBool(memberConfig["activeBridge"], false)) { nw->activeBridgeMembers.insert(memberId); } - isAuth = OSUtils::jsonBool(memberConfig["authorized"],false); + isAuth = OSUtils::jsonBool(memberConfig["authorized"], false); if (isAuth) { Metrics::member_auths++; nw->authorizedMembers.insert(memberId); } - json &ips = memberConfig["ipAssignments"]; + json& ips = memberConfig["ipAssignments"]; if (ips.is_array()) { - for(unsigned long i=0;i nw->mostRecentDeauthTime) nw->mostRecentDeauthTime = ldt; } @@ -295,11 +336,12 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no if (notifyListeners) { std::unique_lock ll(_changeListeners_l); - for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { - (*i)->onNetworkMemberUpdate(this,networkId,memberId,memberConfig); + for (auto i = _changeListeners.begin(); i != _changeListeners.end(); ++i) { + (*i)->onNetworkMemberUpdate(this, networkId, memberId, memberConfig); } } - } else if (memberId) { + } + else if (memberId) { if (nw) { std::unique_lock l(nw->lock); nw->members.erase(memberId); @@ -307,7 +349,7 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no if (networkId) { std::unique_lock l(_networks_l); auto er = _networkByMember.equal_range(memberId); - for(auto i=er.first;i!=er.second;++i) { + for (auto i = er.first; i != er.second; ++i) { if (i->second == networkId) { _networkByMember.erase(i); break; @@ -317,40 +359,45 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no } if (notifyListeners) { - if(networkId != 0 && memberId != 0 && old.is_object() && !memberConfig.is_object()) { + if (networkId != 0 && memberId != 0 && old.is_object() && ! memberConfig.is_object()) { // member delete Metrics::member_count--; - } else if (networkId != 0 && memberId != 0 && !old.is_object() && memberConfig.is_object()) { + } + else if (networkId != 0 && memberId != 0 && ! old.is_object() && memberConfig.is_object()) { // new member Metrics::member_count++; } - if (!wasAuth && isAuth) { + if (! wasAuth && isAuth) { Metrics::member_auths++; - } else if (wasAuth && !isAuth) { + } + else if (wasAuth && ! isAuth) { Metrics::member_deauths++; - } else { + } + else { Metrics::member_changes++; } } - if ((notifyListeners)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId))) { + if ((notifyListeners) && ((wasAuth) && (! isAuth) && (networkId) && (memberId))) { std::unique_lock ll(_changeListeners_l); - for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { - (*i)->onNetworkMemberDeauthorize(this,networkId,memberId); + for (auto i = _changeListeners.begin(); i != _changeListeners.end(); ++i) { + (*i)->onNetworkMemberDeauthorize(this, networkId, memberId); } } } -void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) +void DB::_networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners) { Metrics::db_network_change++; if (notifyListeners) { if (old.is_object() && old.contains("id") && networkConfig.is_object() && networkConfig.contains("id")) { Metrics::network_changes++; - } else if (!old.is_object() && networkConfig.is_object() && networkConfig.contains("id")) { + } + else if (! old.is_object() && networkConfig.is_object() && networkConfig.contains("id")) { Metrics::network_count++; - } else if (old.is_object() && old.contains("id") && !networkConfig.is_object()) { + } + else if (old.is_object() && old.contains("id") && ! networkConfig.is_object()) { Metrics::network_count--; } } @@ -362,8 +409,8 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool std::shared_ptr<_Network> nw; { std::unique_lock l(_networks_l); - std::shared_ptr<_Network> &nw2 = _networks[networkId]; - if (!nw2) + std::shared_ptr<_Network>& nw2 = _networks[networkId]; + if (! nw2) nw2.reset(new _Network); nw = nw2; } @@ -373,12 +420,13 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool } if (notifyListeners) { std::unique_lock ll(_changeListeners_l); - for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { - (*i)->onNetworkUpdate(this,networkId,networkConfig); + for (auto i = _changeListeners.begin(); i != _changeListeners.end(); ++i) { + (*i)->onNetworkUpdate(this, networkId, networkConfig); } } } - } else if (old.is_object()) { + } + else if (old.is_object()) { const std::string ids = old["id"]; const uint64_t networkId = Utils::hexStrToU64(ids.c_str()); if (networkId) { @@ -387,15 +435,16 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool nlohmann::json network; std::vector members; this->get(networkId, network, members); - for(auto i=members.begin();i!=members.end();++i) { + for (auto i = members.begin(); i != members.end(); ++i) { const std::string nodeID = (*i)["id"]; const uint64_t memberId = Utils::hexStrToU64(nodeID.c_str()); std::unique_lock ll(_changeListeners_l); - for(auto j=_changeListeners.begin();j!=_changeListeners.end();++j) { - (*j)->onNetworkMemberDeauthorize(this,networkId,memberId); + for (auto j = _changeListeners.begin(); j != _changeListeners.end(); ++j) { + (*j)->onNetworkMemberDeauthorize(this, networkId, memberId); } } - } catch (std::exception &e) { + } + catch (std::exception& e) { std::cerr << "Error deauthorizing members on network delete: " << e.what() << std::endl; } @@ -406,17 +455,17 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool } } -void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info) +void DB::_fillSummaryInfo(const std::shared_ptr<_Network>& nw, NetworkSummaryInfo& info) { - for(auto ab=nw->activeBridgeMembers.begin();ab!=nw->activeBridgeMembers.end();++ab) + for (auto ab = nw->activeBridgeMembers.begin(); ab != nw->activeBridgeMembers.end(); ++ab) info.activeBridges.push_back(Address(*ab)); - std::sort(info.activeBridges.begin(),info.activeBridges.end()); - for(auto ip=nw->allocatedIps.begin();ip!=nw->allocatedIps.end();++ip) + std::sort(info.activeBridges.begin(), info.activeBridges.end()); + for (auto ip = nw->allocatedIps.begin(); ip != nw->allocatedIps.end(); ++ip) info.allocatedIps.push_back(*ip); - std::sort(info.allocatedIps.begin(),info.allocatedIps.end()); + std::sort(info.allocatedIps.begin(), info.allocatedIps.end()); info.authorizedMemberCount = (unsigned long)nw->authorizedMembers.size(); info.totalMemberCount = (unsigned long)nw->members.size(); info.mostRecentDeauthTime = nw->mostRecentDeauthTime; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/controller/DB.hpp b/controller/DB.hpp index 827c30f09..9dd9c06c6 100644 --- a/controller/DB.hpp +++ b/controller/DB.hpp @@ -14,49 +14,36 @@ #ifndef ZT_CONTROLLER_DB_HPP #define ZT_CONTROLLER_DB_HPP -//#define ZT_CONTROLLER_USE_LIBPQ +// #define ZT_CONTROLLER_USE_LIBPQ #include "../node/Constants.hpp" #include "../node/Identity.hpp" #include "../node/InetAddress.hpp" -#include "../osdep/OSUtils.hpp" #include "../osdep/BlockingQueue.hpp" +#include "../osdep/OSUtils.hpp" +#include +#include #include +#include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include - -#include - -#include #define ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE 25000 -namespace ZeroTier -{ +namespace ZeroTier { -struct AuthInfo -{ -public: - AuthInfo() - : enabled(false) - , version(0) - , authenticationURL() - , authenticationExpiryTime(0) - , issuerURL() - , centralAuthURL() - , ssoNonce() - , ssoState() - , ssoClientID() - , ssoProvider("default") - {} +struct AuthInfo { + public: + AuthInfo() : enabled(false), version(0), authenticationURL(), authenticationExpiryTime(0), issuerURL(), centralAuthURL(), ssoNonce(), ssoState(), ssoClientID(), ssoProvider("default") + { + } bool enabled; uint64_t version; @@ -73,26 +60,35 @@ public: /** * Base class with common infrastructure for all controller DB implementations */ -class DB -{ +class DB { #ifdef ZT_CONTROLLER_USE_LIBPQ friend class MemberNotificationReceiver; friend class NetworkNotificationReceiver; #endif -public: - class ChangeListener - { - public: - ChangeListener() {} - virtual ~ChangeListener() {} - virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) {} - virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) {} - virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) {} + public: + class ChangeListener { + public: + ChangeListener() + { + } + virtual ~ChangeListener() + { + } + virtual void onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network) + { + } + virtual void onNetworkMemberUpdate(const void* db, uint64_t networkId, uint64_t memberId, const nlohmann::json& member) + { + } + virtual void onNetworkMemberDeauthorize(const void* db, uint64_t networkId, uint64_t memberId) + { + } }; - struct NetworkSummaryInfo - { - NetworkSummaryInfo() : authorizedMemberCount(0),totalMemberCount(0),mostRecentDeauthTime(0) {} + struct NetworkSummaryInfo { + NetworkSummaryInfo() : authorizedMemberCount(0), totalMemberCount(0), mostRecentDeauthTime(0) + { + } std::vector
activeBridges; std::vector allocatedIps; unsigned long authorizedMemberCount; @@ -100,10 +96,10 @@ public: int64_t mostRecentDeauthTime; }; - static void initNetwork(nlohmann::json &network); - static void initMember(nlohmann::json &member); - static void cleanNetwork(nlohmann::json &network); - static void cleanMember(nlohmann::json &member); + static void initNetwork(nlohmann::json& network); + static void initMember(nlohmann::json& member); + static void cleanNetwork(nlohmann::json& network); + static void cleanMember(nlohmann::json& member); DB(); virtual ~DB(); @@ -117,42 +113,44 @@ public: return (_networks.find(networkId) != _networks.end()); } - bool get(const uint64_t networkId,nlohmann::json &network); - bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member); - bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info); - bool get(const uint64_t networkId,nlohmann::json &network,std::vector &members); + bool get(const uint64_t networkId, nlohmann::json& network); + bool get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member); + bool get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member, NetworkSummaryInfo& info); + bool get(const uint64_t networkId, nlohmann::json& network, std::vector& members); - void networks(std::set &networks); + void networks(std::set& networks); - template - inline void each(F f) + template inline void each(F f) { nlohmann::json nullJson; std::unique_lock lck(_networks_l); - for(auto nw=_networks.begin();nw!=_networks.end();++nw) { - f(nw->first,nw->second->config,0,nullJson); // first provide network with 0 for member ID - for(auto m=nw->second->members.begin();m!=nw->second->members.end();++m) { - f(nw->first,nw->second->config,m->first,m->second); + for (auto nw = _networks.begin(); nw != _networks.end(); ++nw) { + f(nw->first, nw->second->config, 0, nullJson); // first provide network with 0 for member ID + for (auto m = nw->second->members.begin(); m != nw->second->members.end(); ++m) { + f(nw->first, nw->second->config, m->first, m->second); } } } - virtual bool save(nlohmann::json &record,bool notifyListeners) = 0; + virtual bool save(nlohmann::json& record, bool notifyListeners) = 0; virtual void eraseNetwork(const uint64_t networkId) = 0; - virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0; - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0; - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch) = 0; + virtual void eraseMember(const uint64_t networkId, const uint64_t memberId) = 0; + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) = 0; + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) = 0; - virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) { return AuthInfo(); } + virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) + { + return AuthInfo(); + } - inline void addListener(DB::ChangeListener *const listener) + inline void addListener(DB::ChangeListener* const listener) { std::unique_lock l(_changeListeners_l); _changeListeners.push_back(listener); } -protected: - static inline bool _compareRecords(const nlohmann::json &a,const nlohmann::json &b) + protected: + static inline bool _compareRecords(const nlohmann::json& a, const nlohmann::json& b) { if (a.is_object() == b.is_object()) { if (a.is_object()) { @@ -160,10 +158,10 @@ protected: return false; auto amap = a.get(); auto bmap = b.get(); - for(auto ai=amap.begin();ai!=amap.end();++ai) { - if (ai->first != "revision") { // ignore revision, compare only non-revision-counter fields + for (auto ai = amap.begin(); ai != amap.end(); ++ai) { + if (ai->first != "revision") { // ignore revision, compare only non-revision-counter fields auto bi = bmap.find(ai->first); - if ((bi == bmap.end())||(bi->second != ai->second)) + if ((bi == bmap.end()) || (bi->second != ai->second)) return false; } } @@ -174,29 +172,30 @@ protected: return false; } - struct _Network - { - _Network() : mostRecentDeauthTime(0) {} + struct _Network { + _Network() : mostRecentDeauthTime(0) + { + } nlohmann::json config; - std::unordered_map members; + std::unordered_map members; std::unordered_set activeBridgeMembers; std::unordered_set authorizedMembers; - std::unordered_set allocatedIps; + std::unordered_set allocatedIps; int64_t mostRecentDeauthTime; std::shared_mutex lock; }; - virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners); - virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners); - void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info); + virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners); + virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners); + void _fillSummaryInfo(const std::shared_ptr<_Network>& nw, NetworkSummaryInfo& info); - std::vector _changeListeners; - std::unordered_map< uint64_t,std::shared_ptr<_Network> > _networks; - std::unordered_multimap< uint64_t,uint64_t > _networkByMember; + std::vector _changeListeners; + std::unordered_map > _networks; + std::unordered_multimap _networkByMember; mutable std::shared_mutex _changeListeners_l; mutable std::shared_mutex _networks_l; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp index 1d96c0106..bf2118923 100644 --- a/controller/DBMirrorSet.cpp +++ b/controller/DBMirrorSet.cpp @@ -15,56 +15,54 @@ namespace ZeroTier { -DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) - : _listener(listener) - , _running(true) - , _syncCheckerThread() - , _dbs() - , _dbs_l() +DBMirrorSet::DBMirrorSet(DB::ChangeListener* listener) : _listener(listener), _running(true), _syncCheckerThread(), _dbs(), _dbs_l() { _syncCheckerThread = std::thread([this]() { - for(;;) { - for(int i=0;i<120;++i) { // 1 minute delay between checks - if (!_running) + for (;;) { + for (int i = 0; i < 120; ++i) { // 1 minute delay between checks + if (! _running) return; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - std::vector< std::shared_ptr > dbs; + std::vector > dbs; { std::unique_lock l(_dbs_l); if (_dbs.size() <= 1) - continue; // no need to do this if there's only one DB, so skip the iteration + continue; // no need to do this if there's only one DB, so skip the iteration dbs = _dbs; } - for(auto db=dbs.begin();db!=dbs.end();++db) { - (*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { + for (auto db = dbs.begin(); db != dbs.end(); ++db) { + (*db)->each([&dbs, &db](uint64_t networkId, const nlohmann::json& network, uint64_t memberId, const nlohmann::json& member) { try { if (network.is_object()) { if (memberId == 0) { - for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + for (auto db2 = dbs.begin(); db2 != dbs.end(); ++db2) { if (db->get() != db2->get()) { nlohmann::json nw2; - if ((!(*db2)->get(networkId,nw2))||((nw2.is_object())&&(OSUtils::jsonInt(nw2["revision"],0) < OSUtils::jsonInt(network["revision"],0)))) { + if ((! (*db2)->get(networkId, nw2)) || ((nw2.is_object()) && (OSUtils::jsonInt(nw2["revision"], 0) < OSUtils::jsonInt(network["revision"], 0)))) { nw2 = network; - (*db2)->save(nw2,false); + (*db2)->save(nw2, false); } } } - } else if (member.is_object()) { - for(auto db2=dbs.begin();db2!=dbs.end();++db2) { + } + else if (member.is_object()) { + for (auto db2 = dbs.begin(); db2 != dbs.end(); ++db2) { if (db->get() != db2->get()) { - nlohmann::json nw2,m2; - if ((!(*db2)->get(networkId,nw2,memberId,m2))||((m2.is_object())&&(OSUtils::jsonInt(m2["revision"],0) < OSUtils::jsonInt(member["revision"],0)))) { + nlohmann::json nw2, m2; + if ((! (*db2)->get(networkId, nw2, memberId, m2)) || ((m2.is_object()) && (OSUtils::jsonInt(m2["revision"], 0) < OSUtils::jsonInt(member["revision"], 0)))) { m2 = member; - (*db2)->save(m2,false); + (*db2)->save(m2, false); } } } } } - } catch ( ... ) {} // skip entries that generate JSON errors + } + catch (...) { + } // skip entries that generate JSON errors }); } } @@ -80,58 +78,58 @@ DBMirrorSet::~DBMirrorSet() bool DBMirrorSet::hasNetwork(const uint64_t networkId) const { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { if ((*d)->hasNetwork(networkId)) return true; } return false; } -bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network) +bool DBMirrorSet::get(const uint64_t networkId, nlohmann::json& network) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - if ((*d)->get(networkId,network)) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + if ((*d)->get(networkId, network)) { return true; } } return false; } -bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) +bool DBMirrorSet::get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - if ((*d)->get(networkId,network,memberId,member)) + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + if ((*d)->get(networkId, network, memberId, member)) return true; } return false; } -bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info) +bool DBMirrorSet::get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member, DB::NetworkSummaryInfo& info) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - if ((*d)->get(networkId,network,memberId,member,info)) + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + if ((*d)->get(networkId, network, memberId, member, info)) return true; } return false; } -bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vector &members) +bool DBMirrorSet::get(const uint64_t networkId, nlohmann::json& network, std::vector& members) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - if ((*d)->get(networkId,network,members)) + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + if ((*d)->get(networkId, network, members)) return true; } return false; } -AuthInfo DBMirrorSet::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) +AuthInfo DBMirrorSet::getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { AuthInfo info = (*d)->getSSOAuthInfo(member, redirectURL); if (info.enabled) { return info; @@ -140,10 +138,10 @@ AuthInfo DBMirrorSet::getSSOAuthInfo(const nlohmann::json &member, const std::st return AuthInfo(); } -void DBMirrorSet::networks(std::set &networks) +void DBMirrorSet::networks(std::set& networks) { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { (*d)->networks(networks); } } @@ -152,7 +150,7 @@ bool DBMirrorSet::waitForReady() { bool r = false; std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { r |= (*d)->waitForReady(); } return r; @@ -161,30 +159,31 @@ bool DBMirrorSet::waitForReady() bool DBMirrorSet::isReady() { std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - if (!(*d)->isReady()) + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + if (! (*d)->isReady()) return false; } return true; } -bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners) +bool DBMirrorSet::save(nlohmann::json& record, bool notifyListeners) { - std::vector< std::shared_ptr > dbs; + std::vector > dbs; { std::unique_lock l(_dbs_l); dbs = _dbs; } if (notifyListeners) { - for(auto d=dbs.begin();d!=dbs.end();++d) { - if ((*d)->save(record,true)) + for (auto d = dbs.begin(); d != dbs.end(); ++d) { + if ((*d)->save(record, true)) return true; } return false; - } else { + } + else { bool modified = false; - for(auto d=dbs.begin();d!=dbs.end();++d) { - modified |= (*d)->save(record,false); + for (auto d = dbs.begin(); d != dbs.end(); ++d) { + modified |= (*d)->save(record, false); } return modified; } @@ -193,58 +192,59 @@ bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners) void DBMirrorSet::eraseNetwork(const uint64_t networkId) { std::unique_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { (*d)->eraseNetwork(networkId); } } -void DBMirrorSet::eraseMember(const uint64_t networkId,const uint64_t memberId) +void DBMirrorSet::eraseMember(const uint64_t networkId, const uint64_t memberId) { std::unique_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - (*d)->eraseMember(networkId,memberId); + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + (*d)->eraseMember(networkId, memberId); } } -void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch) { - std::shared_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { - (*d)->nodeIsOnline(networkId,memberId,physicalAddress,osArch); - } -} - -void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) { - this->nodeIsOnline(networkId,memberId,physicalAddress,"unknown/unknown"); + std::shared_lock l(_dbs_l); + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { + (*d)->nodeIsOnline(networkId, memberId, physicalAddress, osArch); + } } -void DBMirrorSet::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) +void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) +{ + this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); +} + +void DBMirrorSet::onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network) { nlohmann::json record(network); std::unique_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { if (d->get() != db) { - (*d)->save(record,false); + (*d)->save(record, false); } } - _listener->onNetworkUpdate(this,networkId,network); + _listener->onNetworkUpdate(this, networkId, network); } -void DBMirrorSet::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) +void DBMirrorSet::onNetworkMemberUpdate(const void* db, uint64_t networkId, uint64_t memberId, const nlohmann::json& member) { nlohmann::json record(member); std::unique_lock l(_dbs_l); - for(auto d=_dbs.begin();d!=_dbs.end();++d) { + for (auto d = _dbs.begin(); d != _dbs.end(); ++d) { if (d->get() != db) { - (*d)->save(record,false); + (*d)->save(record, false); } } - _listener->onNetworkMemberUpdate(this,networkId,memberId,member); + _listener->onNetworkMemberUpdate(this, networkId, memberId, member); } -void DBMirrorSet::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) +void DBMirrorSet::onNetworkMemberDeauthorize(const void* db, uint64_t networkId, uint64_t memberId) { - _listener->onNetworkMemberDeauthorize(this,networkId,memberId); + _listener->onNetworkMemberDeauthorize(this, networkId, memberId); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/controller/DBMirrorSet.hpp b/controller/DBMirrorSet.hpp index 10a15ecca..50230c545 100644 --- a/controller/DBMirrorSet.hpp +++ b/controller/DBMirrorSet.hpp @@ -16,59 +16,58 @@ #include "DB.hpp" -#include #include -#include #include +#include #include +#include namespace ZeroTier { -class DBMirrorSet : public DB::ChangeListener -{ -public: - DBMirrorSet(DB::ChangeListener *listener); +class DBMirrorSet : public DB::ChangeListener { + public: + DBMirrorSet(DB::ChangeListener* listener); virtual ~DBMirrorSet(); bool hasNetwork(const uint64_t networkId) const; - bool get(const uint64_t networkId,nlohmann::json &network); - bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member); - bool get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info); - bool get(const uint64_t networkId,nlohmann::json &network,std::vector &members); + bool get(const uint64_t networkId, nlohmann::json& network); + bool get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member); + bool get(const uint64_t networkId, nlohmann::json& network, const uint64_t memberId, nlohmann::json& member, DB::NetworkSummaryInfo& info); + bool get(const uint64_t networkId, nlohmann::json& network, std::vector& members); - void networks(std::set &networks); + void networks(std::set& networks); bool waitForReady(); bool isReady(); - bool save(nlohmann::json &record,bool notifyListeners); + bool save(nlohmann::json& record, bool notifyListeners); void eraseNetwork(const uint64_t networkId); - void eraseMember(const uint64_t networkId,const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch); + void eraseMember(const uint64_t networkId, const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); // These are called by various DB instances when changes occur. - virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network); - virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); - virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); + virtual void onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network); + virtual void onNetworkMemberUpdate(const void* db, uint64_t networkId, uint64_t memberId, const nlohmann::json& member); + virtual void onNetworkMemberDeauthorize(const void* db, uint64_t networkId, uint64_t memberId); - AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL); + AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - inline void addDB(const std::shared_ptr &db) + inline void addDB(const std::shared_ptr& db) { db->addListener(this); std::unique_lock l(_dbs_l); _dbs.push_back(db); } -private: - DB::ChangeListener *const _listener; + private: + DB::ChangeListener* const _listener; std::atomic_bool _running; std::thread _syncCheckerThread; - std::vector< std::shared_ptr< DB > > _dbs; + std::vector > _dbs; mutable std::shared_mutex _dbs_l; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 8d3850971..04f7ac6b2 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -21,34 +21,32 @@ #ifndef _WIN32 #include #endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "../include/ZeroTierOne.h" #include "../version.h" - #include "EmbeddedNetworkController.hpp" -#include "LFDB.hpp" #include "FileDB.hpp" +#include "LFDB.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef ZT_CONTROLLER_USE_LIBPQ #include "CV1.hpp" #include "CV2.hpp" #endif -#include "../node/Node.hpp" #include "../node/CertificateOfMembership.hpp" -#include "../node/NetworkConfig.hpp" #include "../node/Dictionary.hpp" #include "../node/MAC.hpp" +#include "../node/NetworkConfig.hpp" +#include "../node/Node.hpp" using json = nlohmann::json; @@ -65,13 +63,13 @@ namespace ZeroTier { namespace { -static json _renderRule(ZT_VirtualNetworkRule &rule) +static json _renderRule(ZT_VirtualNetworkRule& rule) { char tmp[128]; json r = json::object(); const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rule.t & 0x3f); - switch(rt) { + switch (rt) { case ZT_NETWORK_RULE_ACTION_DROP: r["type"] = "ACTION_DROP"; break; @@ -103,7 +101,7 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) } if (r.empty()) { - switch(rt) { + switch (rt) { case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS: r["type"] = "MATCH_SOURCE_ZEROTIER_ADDRESS"; r["zt"] = Address(rule.v.zt).toString(tmp); @@ -126,29 +124,47 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) break; case ZT_NETWORK_RULE_MATCH_MAC_SOURCE: r["type"] = "MATCH_MAC_SOURCE"; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + OSUtils::ztsnprintf( + tmp, + sizeof(tmp), + "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + (unsigned int)rule.v.mac[0], + (unsigned int)rule.v.mac[1], + (unsigned int)rule.v.mac[2], + (unsigned int)rule.v.mac[3], + (unsigned int)rule.v.mac[4], + (unsigned int)rule.v.mac[5]); r["mac"] = tmp; break; case ZT_NETWORK_RULE_MATCH_MAC_DEST: r["type"] = "MATCH_MAC_DEST"; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + OSUtils::ztsnprintf( + tmp, + sizeof(tmp), + "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + (unsigned int)rule.v.mac[0], + (unsigned int)rule.v.mac[1], + (unsigned int)rule.v.mac[2], + (unsigned int)rule.v.mac[3], + (unsigned int)rule.v.mac[4], + (unsigned int)rule.v.mac[5]); r["mac"] = tmp; break; case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE: r["type"] = "MATCH_IPV4_SOURCE"; - r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp); + r["ip"] = InetAddress(&(rule.v.ipv4.ip), 4, (unsigned int)rule.v.ipv4.mask).toString(tmp); break; case ZT_NETWORK_RULE_MATCH_IPV4_DEST: r["type"] = "MATCH_IPV4_DEST"; - r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp); + r["ip"] = InetAddress(&(rule.v.ipv4.ip), 4, (unsigned int)rule.v.ipv4.mask).toString(tmp); break; case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE: r["type"] = "MATCH_IPV6_SOURCE"; - r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp); + r["ip"] = InetAddress(rule.v.ipv6.ip, 16, (unsigned int)rule.v.ipv6.mask).toString(tmp); break; case ZT_NETWORK_RULE_MATCH_IPV6_DEST: r["type"] = "MATCH_IPV6_DEST"; - r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp); + r["ip"] = InetAddress(rule.v.ipv6.ip, 16, (unsigned int)rule.v.ipv6.mask).toString(tmp); break; case ZT_NETWORK_RULE_MATCH_IP_TOS: r["type"] = "MATCH_IP_TOS"; @@ -169,7 +185,8 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) r["icmpType"] = (unsigned int)rule.v.icmp.type; if ((rule.v.icmp.flags & 0x01) != 0) r["icmpCode"] = (unsigned int)rule.v.icmp.code; - else r["icmpCode"] = json(); + else + r["icmpCode"] = json(); break; case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE: r["type"] = "MATCH_IP_SOURCE_PORT_RANGE"; @@ -183,7 +200,7 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) break; case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS: r["type"] = "MATCH_CHARACTERISTICS"; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", rule.v.characteristics); r["mask"] = tmp; break; case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE: @@ -232,9 +249,9 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) break; case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: r["type"] = "INTEGER_RANGE"; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", rule.v.intRange.start); r["start"] = tmp; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start + (uint64_t)rule.v.intRange.end); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", rule.v.intRange.start + (uint64_t)rule.v.intRange.end); r["end"] = tmp; r["idx"] = rule.v.intRange.idx; r["little"] = ((rule.v.intRange.format & 0x80) != 0); @@ -244,7 +261,7 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) break; } - if (!r.empty()) { + if (! r.empty()) { r["not"] = ((rule.t & 0x80) != 0); r["or"] = ((rule.t & 0x40) != 0); } @@ -253,217 +270,259 @@ static json _renderRule(ZT_VirtualNetworkRule &rule) return r; } -static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule) +static bool _parseRule(json& r, ZT_VirtualNetworkRule& rule) { - if (!r.is_object()) + if (! r.is_object()) return false; - const std::string t(OSUtils::jsonString(r["type"],"")); - memset(&rule,0,sizeof(ZT_VirtualNetworkRule)); + const std::string t(OSUtils::jsonString(r["type"], "")); + memset(&rule, 0, sizeof(ZT_VirtualNetworkRule)); - if (OSUtils::jsonBool(r["not"],false)) + if (OSUtils::jsonBool(r["not"], false)) rule.t = 0x80; - else rule.t = 0x00; - if (OSUtils::jsonBool(r["or"],false)) + else + rule.t = 0x00; + if (OSUtils::jsonBool(r["or"], false)) rule.t |= 0x40; bool tag = false; if (t == "ACTION_DROP") { rule.t |= ZT_NETWORK_RULE_ACTION_DROP; return true; - } else if (t == "ACTION_ACCEPT") { + } + else if (t == "ACTION_ACCEPT") { rule.t |= ZT_NETWORK_RULE_ACTION_ACCEPT; return true; - } else if (t == "ACTION_TEE") { + } + else if (t == "ACTION_TEE") { rule.t |= ZT_NETWORK_RULE_ACTION_TEE; - rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; - rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); - rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL); + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"], "0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"], 0ULL) & 0xffffffffULL); + rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"], 0ULL) & 0xffffULL); return true; - } else if (t == "ACTION_WATCH") { + } + else if (t == "ACTION_WATCH") { rule.t |= ZT_NETWORK_RULE_ACTION_WATCH; - rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; - rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); - rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL); + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"], "0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"], 0ULL) & 0xffffffffULL); + rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"], 0ULL) & 0xffffULL); return true; - } else if (t == "ACTION_REDIRECT") { + } + else if (t == "ACTION_REDIRECT") { rule.t |= ZT_NETWORK_RULE_ACTION_REDIRECT; - rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL; - rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL); + rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"], "0").c_str()) & 0xffffffffffULL; + rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"], 0ULL) & 0xffffffffULL); return true; - } else if (t == "ACTION_BREAK") { + } + else if (t == "ACTION_BREAK") { rule.t |= ZT_NETWORK_RULE_ACTION_BREAK; return true; - } else if (t == "MATCH_SOURCE_ZEROTIER_ADDRESS") { + } + else if (t == "MATCH_SOURCE_ZEROTIER_ADDRESS") { rule.t |= ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS; - rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL; + rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"], "0").c_str()) & 0xffffffffffULL; return true; - } else if (t == "MATCH_DEST_ZEROTIER_ADDRESS") { + } + else if (t == "MATCH_DEST_ZEROTIER_ADDRESS") { rule.t |= ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS; - rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL; + rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"], "0").c_str()) & 0xffffffffffULL; return true; - } else if (t == "MATCH_VLAN_ID") { + } + else if (t == "MATCH_VLAN_ID") { rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_ID; - rule.v.vlanId = (uint16_t)(OSUtils::jsonInt(r["vlanId"],0ULL) & 0xffffULL); + rule.v.vlanId = (uint16_t)(OSUtils::jsonInt(r["vlanId"], 0ULL) & 0xffffULL); return true; - } else if (t == "MATCH_VLAN_PCP") { + } + else if (t == "MATCH_VLAN_PCP") { rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_PCP; - rule.v.vlanPcp = (uint8_t)(OSUtils::jsonInt(r["vlanPcp"],0ULL) & 0xffULL); + rule.v.vlanPcp = (uint8_t)(OSUtils::jsonInt(r["vlanPcp"], 0ULL) & 0xffULL); return true; - } else if (t == "MATCH_VLAN_DEI") { + } + else if (t == "MATCH_VLAN_DEI") { rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_DEI; - rule.v.vlanDei = (uint8_t)(OSUtils::jsonInt(r["vlanDei"],0ULL) & 0xffULL); + rule.v.vlanDei = (uint8_t)(OSUtils::jsonInt(r["vlanDei"], 0ULL) & 0xffULL); return true; - } else if (t == "MATCH_MAC_SOURCE") { + } + else if (t == "MATCH_MAC_SOURCE") { rule.t |= ZT_NETWORK_RULE_MATCH_MAC_SOURCE; - std::string mac(OSUtils::jsonString(r["mac"],"0")); + std::string mac(OSUtils::jsonString(r["mac"], "0")); Utils::cleanMac(mac); - Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6); + Utils::unhex(mac.c_str(), (unsigned int)mac.length(), rule.v.mac, 6); return true; - } else if (t == "MATCH_MAC_DEST") { + } + else if (t == "MATCH_MAC_DEST") { rule.t |= ZT_NETWORK_RULE_MATCH_MAC_DEST; - std::string mac(OSUtils::jsonString(r["mac"],"0")); + std::string mac(OSUtils::jsonString(r["mac"], "0")); Utils::cleanMac(mac); - Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6); + Utils::unhex(mac.c_str(), (unsigned int)mac.length(), rule.v.mac, 6); return true; - } else if (t == "MATCH_IPV4_SOURCE") { + } + else if (t == "MATCH_IPV4_SOURCE") { rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_SOURCE; - InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str()); - rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; - rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; - if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32; + InetAddress ip(OSUtils::jsonString(r["ip"], "0.0.0.0").c_str()); + rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; + rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; + if (rule.v.ipv4.mask > 32) + rule.v.ipv4.mask = 32; return true; - } else if (t == "MATCH_IPV4_DEST") { + } + else if (t == "MATCH_IPV4_DEST") { rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_DEST; - InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str()); - rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; - rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; - if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32; + InetAddress ip(OSUtils::jsonString(r["ip"], "0.0.0.0").c_str()); + rule.v.ipv4.ip = reinterpret_cast(&ip)->sin_addr.s_addr; + rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast(&ip)->sin_port) & 0xff; + if (rule.v.ipv4.mask > 32) + rule.v.ipv4.mask = 32; return true; - } else if (t == "MATCH_IPV6_SOURCE") { + } + else if (t == "MATCH_IPV6_SOURCE") { rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_SOURCE; - InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str()); - memcpy(rule.v.ipv6.ip,reinterpret_cast(&ip)->sin6_addr.s6_addr,16); - rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; - if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128; + InetAddress ip(OSUtils::jsonString(r["ip"], "::0").c_str()); + memcpy(rule.v.ipv6.ip, reinterpret_cast(&ip)->sin6_addr.s6_addr, 16); + rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; + if (rule.v.ipv6.mask > 128) + rule.v.ipv6.mask = 128; return true; - } else if (t == "MATCH_IPV6_DEST") { + } + else if (t == "MATCH_IPV6_DEST") { rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_DEST; - InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str()); - memcpy(rule.v.ipv6.ip,reinterpret_cast(&ip)->sin6_addr.s6_addr,16); - rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; - if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128; + InetAddress ip(OSUtils::jsonString(r["ip"], "::0").c_str()); + memcpy(rule.v.ipv6.ip, reinterpret_cast(&ip)->sin6_addr.s6_addr, 16); + rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast(&ip)->sin6_port) & 0xff; + if (rule.v.ipv6.mask > 128) + rule.v.ipv6.mask = 128; return true; - } else if (t == "MATCH_IP_TOS") { + } + else if (t == "MATCH_IP_TOS") { rule.t |= ZT_NETWORK_RULE_MATCH_IP_TOS; - rule.v.ipTos.mask = (uint8_t)(OSUtils::jsonInt(r["mask"],0ULL) & 0xffULL); - rule.v.ipTos.value[0] = (uint8_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffULL); - rule.v.ipTos.value[1] = (uint8_t)(OSUtils::jsonInt(r["end"],0ULL) & 0xffULL); + rule.v.ipTos.mask = (uint8_t)(OSUtils::jsonInt(r["mask"], 0ULL) & 0xffULL); + rule.v.ipTos.value[0] = (uint8_t)(OSUtils::jsonInt(r["start"], 0ULL) & 0xffULL); + rule.v.ipTos.value[1] = (uint8_t)(OSUtils::jsonInt(r["end"], 0ULL) & 0xffULL); return true; - } else if (t == "MATCH_IP_PROTOCOL") { + } + else if (t == "MATCH_IP_PROTOCOL") { rule.t |= ZT_NETWORK_RULE_MATCH_IP_PROTOCOL; - rule.v.ipProtocol = (uint8_t)(OSUtils::jsonInt(r["ipProtocol"],0ULL) & 0xffULL); + rule.v.ipProtocol = (uint8_t)(OSUtils::jsonInt(r["ipProtocol"], 0ULL) & 0xffULL); return true; - } else if (t == "MATCH_ETHERTYPE") { + } + else if (t == "MATCH_ETHERTYPE") { rule.t |= ZT_NETWORK_RULE_MATCH_ETHERTYPE; - rule.v.etherType = (uint16_t)(OSUtils::jsonInt(r["etherType"],0ULL) & 0xffffULL); + rule.v.etherType = (uint16_t)(OSUtils::jsonInt(r["etherType"], 0ULL) & 0xffffULL); return true; - } else if (t == "MATCH_ICMP") { + } + else if (t == "MATCH_ICMP") { rule.t |= ZT_NETWORK_RULE_MATCH_ICMP; - rule.v.icmp.type = (uint8_t)(OSUtils::jsonInt(r["icmpType"],0ULL) & 0xffULL); - json &code = r["icmpCode"]; + rule.v.icmp.type = (uint8_t)(OSUtils::jsonInt(r["icmpType"], 0ULL) & 0xffULL); + json& code = r["icmpCode"]; if (code.is_null()) { rule.v.icmp.code = 0; rule.v.icmp.flags = 0x00; - } else { - rule.v.icmp.code = (uint8_t)(OSUtils::jsonInt(code,0ULL) & 0xffULL); + } + else { + rule.v.icmp.code = (uint8_t)(OSUtils::jsonInt(code, 0ULL) & 0xffULL); rule.v.icmp.flags = 0x01; } return true; - } else if (t == "MATCH_IP_SOURCE_PORT_RANGE") { + } + else if (t == "MATCH_IP_SOURCE_PORT_RANGE") { rule.t |= ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE; - rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); - rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL); + rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"], 0ULL) & 0xffffULL); + rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"], (uint64_t)rule.v.port[0]) & 0xffffULL); return true; - } else if (t == "MATCH_IP_DEST_PORT_RANGE") { + } + else if (t == "MATCH_IP_DEST_PORT_RANGE") { rule.t |= ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE; - rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); - rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL); + rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"], 0ULL) & 0xffffULL); + rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"], (uint64_t)rule.v.port[0]) & 0xffffULL); return true; - } else if (t == "MATCH_CHARACTERISTICS") { + } + else if (t == "MATCH_CHARACTERISTICS") { rule.t |= ZT_NETWORK_RULE_MATCH_CHARACTERISTICS; if (r.count("mask")) { - json &v = r["mask"]; + json& v = r["mask"]; if (v.is_number()) { rule.v.characteristics = v; - } else { + } + else { std::string tmp = v; rule.v.characteristics = Utils::hexStrToU64(tmp.c_str()); } } return true; - } else if (t == "MATCH_FRAME_SIZE_RANGE") { + } + else if (t == "MATCH_FRAME_SIZE_RANGE") { rule.t |= ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE; - rule.v.frameSize[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL); - rule.v.frameSize[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.frameSize[0]) & 0xffffULL); + rule.v.frameSize[0] = (uint16_t)(OSUtils::jsonInt(r["start"], 0ULL) & 0xffffULL); + rule.v.frameSize[1] = (uint16_t)(OSUtils::jsonInt(r["end"], (uint64_t)rule.v.frameSize[0]) & 0xffffULL); return true; - } else if (t == "MATCH_RANDOM") { + } + else if (t == "MATCH_RANDOM") { rule.t |= ZT_NETWORK_RULE_MATCH_RANDOM; - rule.v.randomProbability = (uint32_t)(OSUtils::jsonInt(r["probability"],0ULL) & 0xffffffffULL); + rule.v.randomProbability = (uint32_t)(OSUtils::jsonInt(r["probability"], 0ULL) & 0xffffffffULL); return true; - } else if (t == "MATCH_TAGS_DIFFERENCE") { + } + else if (t == "MATCH_TAGS_DIFFERENCE") { rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE; tag = true; - } else if (t == "MATCH_TAGS_BITWISE_AND") { + } + else if (t == "MATCH_TAGS_BITWISE_AND") { rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND; tag = true; - } else if (t == "MATCH_TAGS_BITWISE_OR") { + } + else if (t == "MATCH_TAGS_BITWISE_OR") { rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR; tag = true; - } else if (t == "MATCH_TAGS_BITWISE_XOR") { + } + else if (t == "MATCH_TAGS_BITWISE_XOR") { rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR; tag = true; - } else if (t == "MATCH_TAGS_EQUAL") { + } + else if (t == "MATCH_TAGS_EQUAL") { rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_EQUAL; tag = true; - } else if (t == "MATCH_TAG_SENDER") { + } + else if (t == "MATCH_TAG_SENDER") { rule.t |= ZT_NETWORK_RULE_MATCH_TAG_SENDER; tag = true; - } else if (t == "MATCH_TAG_RECEIVER") { + } + else if (t == "MATCH_TAG_RECEIVER") { rule.t |= ZT_NETWORK_RULE_MATCH_TAG_RECEIVER; tag = true; - } else if (t == "INTEGER_RANGE") { - json &s = r["start"]; + } + else if (t == "INTEGER_RANGE") { + json& s = r["start"]; if (s.is_string()) { std::string tmp = s; rule.v.intRange.start = Utils::hexStrToU64(tmp.c_str()); - } else { - rule.v.intRange.start = OSUtils::jsonInt(s,0ULL); } - json &e = r["end"]; + else { + rule.v.intRange.start = OSUtils::jsonInt(s, 0ULL); + } + json& e = r["end"]; if (e.is_string()) { std::string tmp = e; rule.v.intRange.end = (uint32_t)(Utils::hexStrToU64(tmp.c_str()) - rule.v.intRange.start); - } else { - rule.v.intRange.end = (uint32_t)(OSUtils::jsonInt(e,0ULL) - rule.v.intRange.start); } - rule.v.intRange.idx = (uint16_t)OSUtils::jsonInt(r["idx"],0ULL); - rule.v.intRange.format = (OSUtils::jsonBool(r["little"],false)) ? 0x80 : 0x00; - rule.v.intRange.format |= (uint8_t)((OSUtils::jsonInt(r["bits"],1ULL) - 1) & 63); + else { + rule.v.intRange.end = (uint32_t)(OSUtils::jsonInt(e, 0ULL) - rule.v.intRange.start); + } + rule.v.intRange.idx = (uint16_t)OSUtils::jsonInt(r["idx"], 0ULL); + rule.v.intRange.format = (OSUtils::jsonBool(r["little"], false)) ? 0x80 : 0x00; + rule.v.intRange.format |= (uint8_t)((OSUtils::jsonInt(r["bits"], 1ULL) - 1) & 63); } if (tag) { - rule.v.tag.id = (uint32_t)(OSUtils::jsonInt(r["id"],0ULL) & 0xffffffffULL); - rule.v.tag.value = (uint32_t)(OSUtils::jsonInt(r["value"],0ULL) & 0xffffffffULL); + rule.v.tag.id = (uint32_t)(OSUtils::jsonInt(r["id"], 0ULL) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(OSUtils::jsonInt(r["value"], 0ULL) & 0xffffffffULL); return true; } return false; } -} // anonymous namespace +} // anonymous namespace -EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc) +EmbeddedNetworkController::EmbeddedNetworkController(Node* node, const char* ztPath, const char* dbPath, int listenPort, RedisConfig* rc) : _startTime(OSUtils::now()) , _listenPort(listenPort) , _node(node) @@ -471,7 +530,7 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPa , _path(dbPath) , _signingId() , _signingIdAddressString() - , _sender((NetworkController::Sender *)0) + , _sender((NetworkController::Sender*)0) , _db(this) , _queue() , _threads() @@ -484,29 +543,29 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPa , _ssoExpiryRunning(true) , _ssoExpiry(std::thread(&EmbeddedNetworkController::_ssoExpiryThread, this)) -#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - , _member_status_lookup{"nc_member_status_lookup",""} - , _member_status_lookup_count{"nc_member_status_lookup_count",""} - , _node_is_online{"nc_node_is_online",""} - , _node_is_online_count{"nc_node_is_online_count",""} - , _get_and_init_member{"nc_get_and_init_member",""} - , _get_and_init_member_count{"nc_get_and_init_member_count",""} - , _have_identity{"nc_have_identity",""} - , _have_identity_count{"nc_have_identity_count",""} - , _determine_auth{"nc_determine_auth",""} - , _determine_auth_count{"nc_determine_auth_count",""} - , _sso_check{"nc_sso_check",""} - , _sso_check_count{"nc_sso_check_count",""} - , _auth_check{"nc_auth_check",""} - , _auth_check_count{"nc_auth_check_count",""} - , _json_schlep{"nc_json_schlep",""} - , _json_schlep_count{"nc_json_schlep_count",""} - , _issue_certificate{"nc_issue_certificate", ""} - , _issue_certificate_count{"nc_issue_certificate_count",""} - , _save_member{"nc_save_member",""} - , _save_member_count{"nc_save_member_count",""} - , _send_netconf{"nc_send_netconf2",""} - , _send_netconf_count{"nc_send_netconf2_count",""} +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + , _member_status_lookup { "nc_member_status_lookup", "" } + , _member_status_lookup_count { "nc_member_status_lookup_count", "" } + , _node_is_online { "nc_node_is_online", "" } + , _node_is_online_count { "nc_node_is_online_count", "" } + , _get_and_init_member { "nc_get_and_init_member", "" } + , _get_and_init_member_count { "nc_get_and_init_member_count", "" } + , _have_identity { "nc_have_identity", "" } + , _have_identity_count { "nc_have_identity_count", "" } + , _determine_auth { "nc_determine_auth", "" } + , _determine_auth_count { "nc_determine_auth_count", "" } + , _sso_check { "nc_sso_check", "" } + , _sso_check_count { "nc_sso_check_count", "" } + , _auth_check { "nc_auth_check", "" } + , _auth_check_count { "nc_auth_check_count", "" } + , _json_schlep { "nc_json_schlep", "" } + , _json_schlep_count { "nc_json_schlep_count", "" } + , _issue_certificate { "nc_issue_certificate", "" } + , _issue_certificate_count { "nc_issue_certificate_count", "" } + , _save_member { "nc_save_member", "" } + , _save_member_count { "nc_save_member_count", "" } + , _send_netconf { "nc_send_netconf2", "" } + , _send_netconf_count { "nc_send_netconf2_count", "" } #endif { } @@ -515,18 +574,19 @@ EmbeddedNetworkController::~EmbeddedNetworkController() { std::lock_guard l(_threads_l); _queue.stop(); - for(auto t=_threads.begin();t!=_threads.end();++t) { + for (auto t = _threads.begin(); t != _threads.end(); ++t) { t->join(); } _ssoExpiryRunning = false; _ssoExpiry.join(); } -void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) { +void EmbeddedNetworkController::setSSORedirectURL(const std::string& url) +{ _ssoRedirectURL = url; } -void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) +void EmbeddedNetworkController::init(const Identity& signingId, Sender* sender) { char tmp[64]; _signingId = signingId; @@ -534,13 +594,15 @@ void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) _signingIdAddressString = signingId.address().toString(tmp); #ifdef ZT_CONTROLLER_USE_LIBPQ - if ((_path.length() > 9)&&(_path.substr(0,9) == "postgres:")) { + if ((_path.length() > 9) && (_path.substr(0, 9) == "postgres:")) { fprintf(stderr, "CV1\n"); - _db.addDB(std::shared_ptr(new CV1(_signingId,_path.substr(9).c_str(), _listenPort, _rc))); - } else if ((_path.length() > 4)&&(_path.substr(0,4) == "cv2:")) { + _db.addDB(std::shared_ptr(new CV1(_signingId, _path.substr(9).c_str(), _listenPort, _rc))); + } + else if ((_path.length() > 4) && (_path.substr(0, 4) == "cv2:")) { fprintf(stderr, "CV2\n"); - _db.addDB(std::shared_ptr(new CV2(_signingId,_path.substr(4).c_str(),_listenPort))); - } else { + _db.addDB(std::shared_ptr(new CV2(_signingId, _path.substr(4).c_str(), _listenPort))); + } + else { fprintf(stderr, "FileDB\n"); #endif _db.addDB(std::shared_ptr(new FileDB(_path.c_str()))); @@ -549,12 +611,12 @@ void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) #endif std::string lfJSON; - OSUtils::readFile((_ztPath + ZT_PATH_SEPARATOR_S "local.conf").c_str(),lfJSON); + OSUtils::readFile((_ztPath + ZT_PATH_SEPARATOR_S "local.conf").c_str(), lfJSON); if (lfJSON.length() > 0) { nlohmann::json lfConfig(OSUtils::jsonParse(lfJSON)); - nlohmann::json &settings = lfConfig["settings"]; + nlohmann::json& settings = lfConfig["settings"]; if (settings.is_object()) { - nlohmann::json &controllerDb = settings["controllerDb"]; + nlohmann::json& controllerDb = settings["controllerDb"]; if (controllerDb.is_object()) { std::string type = controllerDb["type"]; if (type == "lf") { @@ -562,14 +624,14 @@ void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) std::string lfHost = controllerDb["host"]; int lfPort = controllerDb["port"]; bool storeOnlineState = controllerDb["storeOnlineState"]; - if ((lfOwner.length())&&(lfHost.length())&&(lfPort > 0)&&(lfPort < 65536)) { + if ((lfOwner.length()) && (lfHost.length()) && (lfPort > 0) && (lfPort < 65536)) { std::size_t pubHdrLoc = lfOwner.find("Public: "); - if ((pubHdrLoc > 0)&&((pubHdrLoc + 8) < lfOwner.length())) { + if ((pubHdrLoc > 0) && ((pubHdrLoc + 8) < lfOwner.length())) { std::string lfOwnerPublic = lfOwner.substr(pubHdrLoc + 8); std::size_t pubHdrEnd = lfOwnerPublic.find_first_of("\n\r\t "); if (pubHdrEnd != std::string::npos) { - lfOwnerPublic = lfOwnerPublic.substr(0,pubHdrEnd); - _db.addDB(std::shared_ptr(new LFDB(_signingId,_path.c_str(),lfOwner.c_str(),lfOwnerPublic.c_str(),lfHost.c_str(),lfPort,storeOnlineState))); + lfOwnerPublic = lfOwnerPublic.substr(0, pubHdrEnd); + _db.addDB(std::shared_ptr(new LFDB(_signingId, _path.c_str(), lfOwner.c_str(), lfOwnerPublic.c_str(), lfHost.c_str(), lfPort, storeOnlineState))); } } } @@ -581,14 +643,9 @@ void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender) _db.waitForReady(); } -void EmbeddedNetworkController::request( - uint64_t nwid, - const InetAddress &fromAddr, - uint64_t requestPacketId, - const Identity &identity, - const Dictionary &metaData) +void EmbeddedNetworkController::request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData) { - if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender)) + if (((! _signingId) || (! _signingId.hasPrivate())) || (_signingId.address().toInt() != (nwid >> 24)) || (! _sender)) return; _startThreads(); @@ -596,14 +653,14 @@ void EmbeddedNetworkController::request( if (requestPacketId) { std::lock_guard l(_memberStatus_l); - _MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())]; + _MemberStatus& ms = _memberStatus[_MemberStatusKey(nwid, identity.address().toInt())]; if ((now - ms.lastRequestTime) <= ZT_NETCONF_MIN_REQUEST_PERIOD) { return; } ms.lastRequestTime = now; } - _RQEntry *qe = new _RQEntry; + _RQEntry* qe = new _RQEntry; qe->nwid = nwid; qe->requestPacketId = requestPacketId; qe->fromAddr = fromAddr; @@ -613,7 +670,7 @@ void EmbeddedNetworkController::request( _queue.post(qe); } -std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networkID, const std::string &body) +std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networkID, const std::string& body) { json b = OSUtils::jsonParse(body); @@ -623,45 +680,56 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ json network; _db.get(networkID, network); DB::initNetwork(network); - if (b.count("name")) network["name"] = OSUtils::jsonString(b["name"],""); - if (b.count("private")) network["private"] = OSUtils::jsonBool(b["private"],true); - if (b.count("enableBroadcast")) network["enableBroadcast"] = OSUtils::jsonBool(b["enableBroadcast"],false); - if (b.count("multicastLimit")) network["multicastLimit"] = OSUtils::jsonInt(b["multicastLimit"],32ULL); - if (b.count("mtu")) network["mtu"] = std::max(std::min((unsigned int)OSUtils::jsonInt(b["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU); + if (b.count("name")) + network["name"] = OSUtils::jsonString(b["name"], ""); + if (b.count("private")) + network["private"] = OSUtils::jsonBool(b["private"], true); + if (b.count("enableBroadcast")) + network["enableBroadcast"] = OSUtils::jsonBool(b["enableBroadcast"], false); + if (b.count("multicastLimit")) + network["multicastLimit"] = OSUtils::jsonInt(b["multicastLimit"], 32ULL); + if (b.count("mtu")) + network["mtu"] = std::max(std::min((unsigned int)OSUtils::jsonInt(b["mtu"], ZT_DEFAULT_MTU), (unsigned int)ZT_MAX_MTU), (unsigned int)ZT_MIN_MTU); if (b.count("remoteTraceTarget")) { - const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],"")); + const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"], "")); if (rtt.length() == 10) { network["remoteTraceTarget"] = rtt; - } else { + } + else { network["remoteTraceTarget"] = json(); } } - if (b.count("remoteTraceLevel")) network["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL); + if (b.count("remoteTraceLevel")) + network["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"], 0ULL); if (b.count("v4AssignMode")) { json nv4m; - json &v4m = b["v4AssignMode"]; - if (v4m.is_string()) { // backward compatibility - nv4m["zt"] = (OSUtils::jsonString(v4m,"") == "zt"); - } else if (v4m.is_object()) { - nv4m["zt"] = OSUtils::jsonBool(v4m["zt"],false); - } else nv4m["zt"] = false; + json& v4m = b["v4AssignMode"]; + if (v4m.is_string()) { // backward compatibility + nv4m["zt"] = (OSUtils::jsonString(v4m, "") == "zt"); + } + else if (v4m.is_object()) { + nv4m["zt"] = OSUtils::jsonBool(v4m["zt"], false); + } + else + nv4m["zt"] = false; network["v4AssignMode"] = nv4m; } if (b.count("v6AssignMode")) { json nv6m; - json &v6m = b["v6AssignMode"]; - if (!nv6m.is_object()) nv6m = json::object(); - if (v6m.is_string()) { // backward compatibility - std::vector v6ms(OSUtils::split(OSUtils::jsonString(v6m,"").c_str(),",","","")); - std::sort(v6ms.begin(),v6ms.end()); - v6ms.erase(std::unique(v6ms.begin(),v6ms.end()),v6ms.end()); + json& v6m = b["v6AssignMode"]; + if (! nv6m.is_object()) + nv6m = json::object(); + if (v6m.is_string()) { // backward compatibility + std::vector v6ms(OSUtils::split(OSUtils::jsonString(v6m, "").c_str(), ",", "", "")); + std::sort(v6ms.begin(), v6ms.end()); + v6ms.erase(std::unique(v6ms.begin(), v6ms.end()), v6ms.end()); nv6m["rfc4193"] = false; nv6m["zt"] = false; nv6m["6plane"] = false; - for(std::vector::iterator i(v6ms.begin());i!=v6ms.end();++i) { + for (std::vector::iterator i(v6ms.begin()); i != v6ms.end(); ++i) { if (*i == "rfc4193") nv6m["rfc4193"] = true; else if (*i == "zt") @@ -669,11 +737,16 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ else if (*i == "6plane") nv6m["6plane"] = true; } - } else if (v6m.is_object()) { - if (v6m.count("rfc4193")) nv6m["rfc4193"] = OSUtils::jsonBool(v6m["rfc4193"],false); - if (v6m.count("zt")) nv6m["zt"] = OSUtils::jsonBool(v6m["zt"],false); - if (v6m.count("6plane")) nv6m["6plane"] = OSUtils::jsonBool(v6m["6plane"],false); - } else { + } + else if (v6m.is_object()) { + if (v6m.count("rfc4193")) + nv6m["rfc4193"] = OSUtils::jsonBool(v6m["rfc4193"], false); + if (v6m.count("zt")) + nv6m["zt"] = OSUtils::jsonBool(v6m["zt"], false); + if (v6m.count("6plane")) + nv6m["6plane"] = OSUtils::jsonBool(v6m["6plane"], false); + } + else { nv6m["rfc4193"] = false; nv6m["zt"] = false; nv6m["6plane"] = false; @@ -682,25 +755,27 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } if (b.count("routes")) { - json &rts = b["routes"]; + json& rts = b["routes"]; if (rts.is_array()) { json nrts = json::array(); - for(unsigned long i=0;i().c_str()); InetAddress v; - if (via.is_string()) v.fromString(via.get().c_str()); - if ( ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) && (t.netmaskBitsValid()) ) { + if (via.is_string()) + v.fromString(via.get().c_str()); + if (((t.ss_family == AF_INET) || (t.ss_family == AF_INET6)) && (t.netmaskBitsValid())) { json tmp; char tmp2[64]; tmp["target"] = t.toString(tmp2); if (v.ss_family == t.ss_family) tmp["via"] = v.toIpString(tmp2); - else tmp["via"] = json(); + else + tmp["via"] = json(); nrts.push_back(tmp); if (nrts.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; @@ -713,15 +788,15 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } if (b.count("ipAssignmentPools")) { - json &ipp = b["ipAssignmentPools"]; + json& ipp = b["ipAssignmentPools"]; if (ipp.is_array()) { json nipp = json::array(); - for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; @@ -756,39 +831,40 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } if (b.count("authTokens")) { - json &authTokens = b["authTokens"]; + json& authTokens = b["authTokens"]; if (authTokens.is_object()) { json nat; - for(json::iterator t(authTokens.begin());t!=authTokens.end();++t) { - if ((t.value().is_number())&&(t.value() >= 0)) + for (json::iterator t(authTokens.begin()); t != authTokens.end(); ++t) { + if ((t.value().is_number()) && (t.value() >= 0)) nat[t.key()] = t.value(); } network["authTokens"] = nat; - } else { - network["authTokens"] = {{}}; + } + else { + network["authTokens"] = { {} }; } } if (b.count("capabilities")) { - json &capabilities = b["capabilities"]; + json& capabilities = b["capabilities"]; if (capabilities.is_array()) { - std::map< uint64_t,json > ncaps; - for(unsigned long i=0;i ncaps; + for (unsigned long i = 0; i < capabilities.size(); ++i) { + json& cap = capabilities[i]; if (cap.is_object()) { json ncap = json::object(); - const uint64_t capId = OSUtils::jsonInt(cap["id"],0ULL); + const uint64_t capId = OSUtils::jsonInt(cap["id"], 0ULL); ncap["id"] = capId; - ncap["default"] = OSUtils::jsonBool(cap["default"],false); + ncap["default"] = OSUtils::jsonBool(cap["default"], false); - json &rules = cap["rules"]; + json& rules = cap["rules"]; json nrules = json::array(); if (rules.is_array()) { - for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; @@ -803,7 +879,7 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } json ncapsa = json::array(); - for(std::map< uint64_t,json >::iterator c(ncaps.begin());c!=ncaps.end();++c) { + for (std::map::iterator c(ncaps.begin()); c != ncaps.end(); ++c) { ncapsa.push_back(c->second); if (ncapsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; @@ -813,25 +889,26 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } if (b.count("tags")) { - json &tags = b["tags"]; + json& tags = b["tags"]; if (tags.is_array()) { - std::map< uint64_t,json > ntags; - for(unsigned long i=0;i ntags; + for (unsigned long i = 0; i < tags.size(); ++i) { + json& tag = tags[i]; if (tag.is_object()) { json ntag = json::object(); - const uint64_t tagId = OSUtils::jsonInt(tag["id"],0ULL); + const uint64_t tagId = OSUtils::jsonInt(tag["id"], 0ULL); ntag["id"] = tagId; - json &dfl = tag["default"]; + json& dfl = tag["default"]; if (dfl.is_null()) ntag["default"] = dfl; - else ntag["default"] = OSUtils::jsonInt(dfl,0ULL); + else + ntag["default"] = OSUtils::jsonInt(dfl, 0ULL); ntags[tagId] = ntag; } } json ntagsa = json::array(); - for(std::map< uint64_t,json >::iterator t(ntags.begin());t!=ntags.end();++t) { + for (std::map::iterator t(ntags.begin()); t != ntags.end(); ++t) { ntagsa.push_back(t->second); if (ntagsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; @@ -841,16 +918,16 @@ std::string EmbeddedNetworkController::networkUpdateFromPostData(uint64_t networ } if (b.count("dns")) { - json &dns = b["dns"]; + json& dns = b["dns"]; if (dns.is_object()) { json nd; nd["domain"] = dns["domain"]; - json &srv = dns["servers"]; + json& srv = dns["servers"]; if (srv.is_array()) { json ns = json::array(); - for(unsigned int i=0;i setContent) +void EmbeddedNetworkController::configureHTTPControlPlane(httplib::Server& s, httplib::Server& sv6, const std::function setContent) { // Control plane Endpoints std::string controllerPath = "/controller"; @@ -884,8 +958,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( std::string memberListPath2 = "/unstable/controller/network/([0-9a-fA-F]{16})/member"; std::string memberPath = "/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})"; - - auto controllerGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto controllerGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { char tmp[4096]; const bool dbOk = _db.isReady(); OSUtils::ztsnprintf( @@ -896,7 +969,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( (unsigned long long)OSUtils::now(), dbOk ? "true" : "false"); - if (!dbOk) { + if (! dbOk) { res.status = 503; } @@ -905,13 +978,13 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(controllerPath, controllerGet); sv6.Get(controllerPath, controllerGet); - auto networkListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkListGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { std::set networkIds; _db.networks(networkIds); char tmp[64]; auto out = json::array(); - for(std::set::const_iterator i(networkIds.begin()); i != networkIds.end(); ++i) { + for (std::set::const_iterator i(networkIds.begin()); i != networkIds.end(); ++i) { OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", *i); out.push_back(tmp); } @@ -921,7 +994,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(networkListPath, networkListGet); sv6.Get(networkListPath, networkListGet); - auto networkListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkListGet2 = [&, setContent](const httplib::Request& req, httplib::Response& res) { std::set networkIds; _db.networks(networkIds); @@ -929,22 +1002,24 @@ void EmbeddedNetworkController::configureHTTPControlPlane( auto data = json::array(); uint64_t networkCount = 0; - for(std::set::const_iterator nwid(networkIds.begin()); nwid != networkIds.end(); ++nwid) { + for (std::set::const_iterator nwid(networkIds.begin()); nwid != networkIds.end(); ++nwid) { json network; - if (!_db.get(*nwid, network)) { + if (! _db.get(*nwid, network)) { continue; } std::vector memTmp; if (_db.get(*nwid, network, memTmp)) { - if (!network.is_null()) { + if (! network.is_null()) { uint64_t authorizedCount = 0; uint64_t totalCount = memTmp.size(); networkCount++; for (auto m = memTmp.begin(); m != memTmp.end(); ++m) { bool a = OSUtils::jsonBool((*m)["authorized"], 0); - if (a) { authorizedCount++; } + if (a) { + authorizedCount++; + } } auto nwMeta = json::object(); @@ -967,11 +1042,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(networkListPath2, networkListGet2); sv6.Get(networkListPath2, networkListGet2); - auto networkGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1]; uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); json network; - if (!_db.get(nwid, network)) { + if (! _db.get(nwid, network)) { res.status = 404; return; } @@ -981,21 +1056,22 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(networkPath, networkGet); sv6.Get(networkPath, networkGet); - auto createNewNetwork = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto createNewNetwork = [&, setContent](const httplib::Request& req, httplib::Response& res) { // fprintf(stderr, "creating new network (new style)\n"); uint64_t nwid = 0; uint64_t nwidPrefix = (Utils::hexStrToU64(_signingIdAddressString.c_str()) << 24) & 0xffffffffff000000ULL; uint64_t nwidPostfix = 0; - for(unsigned long k=0;k<100000;++k) { // sanity limit on trials - Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); + for (unsigned long k = 0; k < 100000; ++k) { // sanity limit on trials + Utils::getSecureRandom(&nwidPostfix, sizeof(nwidPostfix)); uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); - if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL; - if (!_db.hasNetwork(tryNwid)) { + if ((tryNwid & 0xffffffULL) == 0ULL) + tryNwid |= 1ULL; + if (! _db.hasNetwork(tryNwid)) { nwid = tryNwid; break; } } - if (!nwid) { + if (! nwid) { res.status = 503; return; } @@ -1007,7 +1083,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( sv6.Put(networkListPath, createNewNetwork); sv6.Post(networkListPath, createNewNetwork); - auto createNewNetworkOldAndBusted = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto createNewNetworkOldAndBusted = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto inID = req.matches[1].str(); if (inID != _signingIdAddressString) { @@ -1018,16 +1094,17 @@ void EmbeddedNetworkController::configureHTTPControlPlane( uint64_t nwid = 0; uint64_t nwidPrefix = (Utils::hexStrToU64(inID.c_str()) << 24) & 0xffffffffff000000ULL; uint64_t nwidPostfix = 0; - for(unsigned long k=0;k<100000;++k) { // sanity limit on trials - Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); + for (unsigned long k = 0; k < 100000; ++k) { // sanity limit on trials + Utils::getSecureRandom(&nwidPostfix, sizeof(nwidPostfix)); uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); - if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL; - if (!_db.hasNetwork(tryNwid)) { + if ((tryNwid & 0xffffffULL) == 0ULL) + tryNwid |= 1ULL; + if (! _db.hasNetwork(tryNwid)) { nwid = tryNwid; break; } } - if (!nwid) { + if (! nwid) { res.status = 503; return; } @@ -1038,7 +1115,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( sv6.Put(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); sv6.Post(oldAndBustedNetworkCreatePath, createNewNetworkOldAndBusted); - auto networkPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkPost = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1].str(); uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); @@ -1050,12 +1127,12 @@ void EmbeddedNetworkController::configureHTTPControlPlane( sv6.Put(networkPath, networkPost); sv6.Post(networkPath, networkPost); - auto networkDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkDelete = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1].str(); uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); json network; - if (!_db.get(nwid,network)) { + if (! _db.get(nwid, network)) { res.status = 404; return; } @@ -1066,11 +1143,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Delete(networkPath, networkDelete); sv6.Delete(networkPath, networkDelete); - auto memberListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto memberListGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1]; uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); json network; - if (!_db.get(nwid, network)) { + if (! _db.get(nwid, network)) { res.status = 404; return; } @@ -1092,11 +1169,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(memberListPath, memberListGet); sv6.Get(memberListPath, memberListGet); - auto memberListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto memberListGet2 = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1]; uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); json network; - if (!_db.get(nwid, network)) { + if (! _db.get(nwid, network)) { res.status = 404; return; } @@ -1109,7 +1186,9 @@ void EmbeddedNetworkController::configureHTTPControlPlane( uint64_t totalCount = memTmp.size(); for (auto m = memTmp.begin(); m != memTmp.end(); ++m) { bool a = OSUtils::jsonBool((*m)["authorized"], 0); - if (a) { authorizedCount++; } + if (a) { + authorizedCount++; + } } meta["totalCount"] = totalCount; @@ -1119,7 +1198,8 @@ void EmbeddedNetworkController::configureHTTPControlPlane( out["meta"] = meta; setContent(req, res, out.dump()); - } else { + } + else { res.status = 404; return; } @@ -1127,14 +1207,14 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(memberListPath2, memberListGet2); sv6.Get(memberListPath2, memberListGet2); - auto memberGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto memberGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1]; auto memberID = req.matches[2]; uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str()); uint64_t memid = Utils::hexStrToU64(memberID.str().c_str()); json network; json member; - if (!_db.get(nwid, network, memid, member)) { + if (! _db.get(nwid, network, memid, member)) { res.status = 404; return; } @@ -1144,13 +1224,13 @@ void EmbeddedNetworkController::configureHTTPControlPlane( s.Get(memberPath, memberGet); sv6.Get(memberPath, memberGet); - auto memberPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto memberPost = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1].str(); auto memberID = req.matches[2].str(); uint64_t nwid = Utils::hexStrToU64(networkID.c_str()); uint64_t memid = Utils::hexStrToU64(memberID.c_str()); - if (!_db.hasNetwork(nwid)) { + if (! _db.hasNetwork(nwid)) { res.status = 404; return; } @@ -1162,25 +1242,32 @@ void EmbeddedNetworkController::configureHTTPControlPlane( json b = OSUtils::jsonParse(req.body); - if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false); - if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false); - if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL); - if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], ""); - if (b.count("name")) member["name"] = OSUtils::jsonString(b["name"], ""); + if (b.count("activeBridge")) + member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false); + if (b.count("noAutoAssignIps")) + member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false); + if (b.count("authenticationExpiryTime")) + member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL); + if (b.count("authenticationURL")) + member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], ""); + if (b.count("name")) + member["name"] = OSUtils::jsonString(b["name"], ""); if (b.count("remoteTraceTarget")) { - const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],"")); + const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"], "")); if (rtt.length() == 10) { member["remoteTraceTarget"] = rtt; - } else { + } + else { member["remoteTraceTarget"] = json(); } } - if (b.count("remoteTraceLevel")) member["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL); + if (b.count("remoteTraceLevel")) + member["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"], 0ULL); if (b.count("authorized")) { - const bool newAuth = OSUtils::jsonBool(b["authorized"],false); - if (newAuth != OSUtils::jsonBool(member["authorized"],false)) { + const bool newAuth = OSUtils::jsonBool(b["authorized"], false); + if (newAuth != OSUtils::jsonBool(member["authorized"], false)) { member["authorized"] = newAuth; member[((newAuth) ? "lastAuthorizedTime" : "lastDeauthorizedTime")] = OSUtils::now(); if (newAuth) { @@ -1191,13 +1278,13 @@ void EmbeddedNetworkController::configureHTTPControlPlane( } if (b.count("ipAssignments")) { - json &ipa = b["ipAssignments"]; + json& ipa = b["ipAssignments"]; if (ipa.is_array()) { json mipa(json::array()); - for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) @@ -1209,16 +1296,16 @@ void EmbeddedNetworkController::configureHTTPControlPlane( } if (b.count("tags")) { - json &tags = b["tags"]; + json& tags = b["tags"]; if (tags.is_array()) { - std::map mtags; - for(unsigned long i=0;i mtags; + for (unsigned long i = 0; i < tags.size(); ++i) { + json& tag = tags[i]; + if ((tag.is_array()) && (tag.size() == 2)) + mtags[OSUtils::jsonInt(tag[0], 0ULL) & 0xffffffffULL] = OSUtils::jsonInt(tag[1], 0ULL) & 0xffffffffULL; } json mtagsa = json::array(); - for(std::map::iterator t(mtags.begin());t!=mtags.end();++t) { + for (std::map::iterator t(mtags.begin()); t != mtags.end(); ++t) { json ta = json::array(); ta.push_back(t->first); ta.push_back(t->second); @@ -1231,16 +1318,16 @@ void EmbeddedNetworkController::configureHTTPControlPlane( } if (b.count("capabilities")) { - json &capabilities = b["capabilities"]; + json& capabilities = b["capabilities"]; if (capabilities.is_array()) { json mcaps = json::array(); - for(unsigned long i=0;i= ZT_CONTROLLER_MAX_ARRAY_SIZE) break; } - std::sort(mcaps.begin(),mcaps.end()); - mcaps.erase(std::unique(mcaps.begin(),mcaps.end()),mcaps.end()); + std::sort(mcaps.begin(), mcaps.end()); + mcaps.erase(std::unique(mcaps.begin(), mcaps.end()), mcaps.end()); member["capabilities"] = mcaps; } } @@ -1259,7 +1346,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane( sv6.Put(memberPath, memberPost); sv6.Post(memberPath, memberPost); - auto memberDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto memberDelete = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto networkID = req.matches[1].str(); auto memberID = req.matches[2].str(); @@ -1267,12 +1354,12 @@ void EmbeddedNetworkController::configureHTTPControlPlane( uint64_t address = Utils::hexStrToU64(memberID.c_str()); json network, member; - if (!_db.get(nwid, network, address, member)) { + if (! _db.get(nwid, network, address, member)) { res.status = 404; return; } - if (!member.size()) { + if (! member.size()) { res.status = 404; return; } @@ -1285,115 +1372,125 @@ void EmbeddedNetworkController::configureHTTPControlPlane( sv6.Delete(memberPath, memberDelete); } -void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt) +void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace& rt) { static volatile unsigned long idCounter = 0; - char id[128],tmp[128]; - std::string k,v; + char id[128], tmp[128]; + std::string k, v; try { // Convert Dictionary into JSON object json d; - char *saveptr = (char *)0; - for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) { - char *eq = strchr(l,'='); + char* saveptr = (char*)0; + for (char* l = Utils::stok(rt.data, "\n", &saveptr); (l); l = Utils::stok((char*)0, "\n", &saveptr)) { + char* eq = strchr(l, '='); if (eq > l) { - k.assign(l,(unsigned long)(eq - l)); + k.assign(l, (unsigned long)(eq - l)); v.clear(); ++eq; while (*eq) { if (*eq == '\\') { ++eq; if (*eq) { - switch(*eq) { - case 'r': v.push_back('\r'); break; - case 'n': v.push_back('\n'); break; - case '0': v.push_back((char)0); break; - case 'e': v.push_back('='); break; - default: v.push_back(*eq); break; + switch (*eq) { + case 'r': + v.push_back('\r'); + break; + case 'n': + v.push_back('\n'); + break; + case '0': + v.push_back((char)0); + break; + case 'e': + v.push_back('='); + break; + default: + v.push_back(*eq); + break; } ++eq; } - } else { + } + else { v.push_back(*(eq++)); } } - if ((k.length() > 0)&&(v.length() > 0)) + if ((k.length() > 0) && (v.length() > 0)) d[k] = v; } } const int64_t now = OSUtils::now(); - OSUtils::ztsnprintf(id,sizeof(id),"%.10llx-%.16llx-%.10llx-%.4x",_signingId.address().toInt(),now,rt.origin,(unsigned int)(idCounter++ & 0xffff)); + OSUtils::ztsnprintf(id, sizeof(id), "%.10llx-%.16llx-%.10llx-%.4x", _signingId.address().toInt(), now, rt.origin, (unsigned int)(idCounter++ & 0xffff)); d["id"] = id; d["objtype"] = "trace"; d["ts"] = now; - d["nodeId"] = Utils::hex10(rt.origin,tmp); - _db.save(d,true); - } catch ( ... ) { + d["nodeId"] = Utils::hex10(rt.origin, tmp); + _db.save(d, true); + } + catch (...) { // drop invalid trace messages if an error occurs } } -void EmbeddedNetworkController::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) +void EmbeddedNetworkController::onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network) { // Send an update to all members of the network that are online const int64_t now = OSUtils::now(); std::lock_guard l(_memberStatus_l); - for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { - if ((i->first.networkId == networkId)&&(i->second.online(now))&&(i->second.lastRequestMetaData)) - request(networkId,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData); + for (auto i = _memberStatus.begin(); i != _memberStatus.end(); ++i) { + if ((i->first.networkId == networkId) && (i->second.online(now)) && (i->second.lastRequestMetaData)) + request(networkId, InetAddress(), 0, i->second.identity, i->second.lastRequestMetaData); } } -void EmbeddedNetworkController::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) +void EmbeddedNetworkController::onNetworkMemberUpdate(const void* db, uint64_t networkId, uint64_t memberId, const nlohmann::json& member) { // Push update to member if online try { std::lock_guard l(_memberStatus_l); - _MemberStatus &ms = _memberStatus[_MemberStatusKey(networkId,memberId)]; - if ((ms.online(OSUtils::now()))&&(ms.lastRequestMetaData)) - request(networkId,InetAddress(),0,ms.identity,ms.lastRequestMetaData); - } catch ( ... ) {} + _MemberStatus& ms = _memberStatus[_MemberStatusKey(networkId, memberId)]; + if ((ms.online(OSUtils::now())) && (ms.lastRequestMetaData)) + request(networkId, InetAddress(), 0, ms.identity, ms.lastRequestMetaData); + } + catch (...) { + } } -void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) +void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void* db, uint64_t networkId, uint64_t memberId) { const int64_t now = OSUtils::now(); - Revocation rev((uint32_t)_node->prng(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); + Revocation rev((uint32_t)_node->prng(), networkId, 0, now, ZT_REVOCATION_FLAG_FAST_PROPAGATE, Address(memberId), Revocation::CREDENTIAL_TYPE_COM); rev.sign(_signingId); { std::lock_guard l(_memberStatus_l); - for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) { - if ((i->first.networkId == networkId)&&(i->second.online(now))) - _node->ncSendRevocation(Address(i->first.nodeId),rev); + for (auto i = _memberStatus.begin(); i != _memberStatus.end(); ++i) { + if ((i->first.networkId == networkId) && (i->second.online(now))) + _node->ncSendRevocation(Address(i->first.nodeId), rev); } } } -void EmbeddedNetworkController::_request( - uint64_t nwid, - const InetAddress &fromAddr, - uint64_t requestPacketId, - const Identity &identity, - const Dictionary &metaData) +void EmbeddedNetworkController::_request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData) { Metrics::network_config_request++; auto tid = std::this_thread::get_id(); - std::stringstream ss; ss << tid; + std::stringstream ss; + ss << tid; std::string threadID = ss.str(); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b1 = _member_status_lookup.Add({{"thread", threadID}}); - auto c1 = _member_status_lookup_count.Add({{"thread", threadID}}); + auto b1 = _member_status_lookup.Add({ { "thread", threadID } }); + auto c1 = _member_status_lookup_count.Add({ { "thread", threadID } }); c1++; b1.start(); #endif char nwids[24]; DB::NetworkSummaryInfo ns; - json network,member; + json network, member; - if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender)) { + if (((! _signingId) || (! _signingId.hasPrivate())) || (_signingId.address().toInt() != (nwid >> 24)) || (! _sender)) { return; } @@ -1401,8 +1498,8 @@ void EmbeddedNetworkController::_request( #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b1.stop(); - auto b2 = _node_is_online.Add({{"thread",threadID}}); - auto c2 = _node_is_online_count.Add({{"thread",threadID}}); + auto b2 = _node_is_online.Add({ { "thread", threadID } }); + auto c2 = _node_is_online_count.Add({ { "thread", threadID } }); c2++; b2.start(); #endif @@ -1410,62 +1507,64 @@ void EmbeddedNetworkController::_request( metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH, osArch, sizeof(osArch)); // fprintf(stderr, "Network Config Request: nwid=%.16llx, nodeid=%.10llx, osArch=%s\n", // nwid, identity.address().toInt(), osArch); - _db.nodeIsOnline(nwid,identity.address().toInt(),fromAddr, osArch); + _db.nodeIsOnline(nwid, identity.address().toInt(), fromAddr, osArch); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b2.stop(); - auto b3 = _get_and_init_member.Add({{"thread", threadID}}); - auto c3 = _get_and_init_member_count.Add({{"thread",threadID}}); + auto b3 = _get_and_init_member.Add({ { "thread", threadID } }); + auto c3 = _get_and_init_member_count.Add({ { "thread", threadID } }); c3++; b3.start(); #endif - Utils::hex(nwid,nwids); - _db.get(nwid,network,identity.address().toInt(),member,ns); - if ((!network.is_object())||(network.empty())) { - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND, nullptr, 0); + Utils::hex(nwid, nwids); + _db.get(nwid, network, identity.address().toInt(), member, ns); + if ((! network.is_object()) || (network.empty())) { + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_OBJECT_NOT_FOUND, nullptr, 0); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b3.stop(); #endif return; } - const bool newMember = ((!member.is_object())||(member.empty())); + const bool newMember = ((! member.is_object()) || (member.empty())); DB::initMember(member); - _MemberStatusKey msk(nwid,identity.address().toInt()); + _MemberStatusKey msk(nwid, identity.address().toInt()); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b3.stop(); #endif { #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b4 = _have_identity.Add({{"thread",threadID}}); - auto c4 = _have_identity_count.Add({{"thread",threadID}}); + auto b4 = _have_identity.Add({ { "thread", threadID } }); + auto c4 = _have_identity_count.Add({ { "thread", threadID } }); c4++; b4.start(); #endif - const std::string haveIdStr(OSUtils::jsonString(member["identity"],"")); + const std::string haveIdStr(OSUtils::jsonString(member["identity"], "")); if (haveIdStr.length() > 0) { // If we already know this member's identity perform a full compare. This prevents // a "collision" from being able to auth onto our network in place of an already // known member. try { if (Identity(haveIdStr.c_str()) != identity) { - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); - #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b4.stop(); - #endif +#endif return; } - } catch ( ... ) { - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); - #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + } + catch (...) { + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b4.stop(); - #endif +#endif return; } - } else { + } + else { // If we do not yet know this member's identity, learn it. char idtmp[1024]; - member["identity"] = identity.toString(false,idtmp); + member["identity"] = identity.toString(false, idtmp); } #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b4.stop(); @@ -1483,30 +1582,32 @@ void EmbeddedNetworkController::_request( // Determine whether and how member is authorized #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b5 = _determine_auth.Add({{"thread",threadID}}); - auto c5 = _determine_auth_count.Add({{"thread",threadID}}); + auto b5 = _determine_auth.Add({ { "thread", threadID } }); + auto c5 = _determine_auth_count.Add({ { "thread", threadID } }); c5++; b5.start(); #endif bool authorized = false; bool autoAuthorized = false; - json autoAuthCredentialType,autoAuthCredential; - if (OSUtils::jsonBool(member["authorized"],false)) { + json autoAuthCredentialType, autoAuthCredential; + if (OSUtils::jsonBool(member["authorized"], false)) { authorized = true; - } else if (!OSUtils::jsonBool(network["private"],true)) { + } + else if (! OSUtils::jsonBool(network["private"], true)) { authorized = true; autoAuthorized = true; autoAuthCredentialType = "public"; - } else { + } + else { char presentedAuth[512]; - if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH,presentedAuth,sizeof(presentedAuth)) > 0) { - presentedAuth[511] = (char)0; // sanity check - if ((strlen(presentedAuth) > 6)&&(!strncmp(presentedAuth,"token:",6))) { - const char *const presentedToken = presentedAuth + 6; + if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH, presentedAuth, sizeof(presentedAuth)) > 0) { + presentedAuth[511] = (char)0; // sanity check + if ((strlen(presentedAuth) > 6) && (! strncmp(presentedAuth, "token:", 6))) { + const char* const presentedToken = presentedAuth + 6; json authTokens(network["authTokens"]); - json &tokenExpires = authTokens[presentedToken]; + json& tokenExpires = authTokens[presentedToken]; if (tokenExpires.is_number()) { - if ((tokenExpires == 0)||(tokenExpires > now)) { + if ((tokenExpires == 0) || (tokenExpires > now)) { authorized = true; autoAuthorized = true; autoAuthCredentialType = "token"; @@ -1518,7 +1619,7 @@ void EmbeddedNetworkController::_request( } // If we auto-authorized, update member record - if ((autoAuthorized)&&(authorized)) { + if ((autoAuthorized) && (authorized)) { member["authorized"] = true; member["lastAuthorizedTime"] = now; member["lastAuthorizedCredentialType"] = autoAuthCredentialType; @@ -1532,8 +1633,8 @@ void EmbeddedNetworkController::_request( // If network is configured with SSO, and the member is not marked exempt: yes // Otherwise no, we use standard auth logic. #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b6 = _sso_check.Add({{"thread",threadID}}); - auto c6 = _sso_check_count.Add({{"thread",threadID}}); + auto b6 = _sso_check.Add({ { "thread", threadID } }); + auto c6 = _sso_check_count.Add({ { "thread", threadID } }); c6++; b6.start(); #endif @@ -1541,7 +1642,7 @@ void EmbeddedNetworkController::_request( int64_t authenticationExpiryTime = -1; bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false); bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false); - if (networkSSOEnabled && !memberSSOExempt) { + if (networkSSOEnabled && ! memberSSOExempt) { authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0); info = _db.getSSOAuthInfo(member, _ssoRedirectURL); assert(info.enabled == networkSSOEnabled); @@ -1550,41 +1651,42 @@ void EmbeddedNetworkController::_request( Dictionary<4096> authInfo; authInfo.add(ZT_AUTHINFO_DICT_KEY_VERSION, (uint64_t)0ULL); authInfo.add(ZT_AUTHINFO_DICT_KEY_AUTHENTICATION_URL, info.authenticationURL.c_str()); - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); - } else if (info.version == 1) { + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); + } + else if (info.version == 1) { Dictionary<8192> authInfo; authInfo.add(ZT_AUTHINFO_DICT_KEY_VERSION, info.version); authInfo.add(ZT_AUTHINFO_DICT_KEY_ISSUER_URL, info.issuerURL.c_str()); authInfo.add(ZT_AUTHINFO_DICT_KEY_CENTRAL_ENDPOINT_URL, info.centralAuthURL.c_str()); authInfo.add(ZT_AUTHINFO_DICT_KEY_NONCE, info.ssoNonce.c_str()); authInfo.add(ZT_AUTHINFO_DICT_KEY_STATE, info.ssoState.c_str()); - authInfo.add(ZT_AUTHINFO_DICT_KEY_CLIENT_ID, info.ssoClientID.c_str()); + authInfo.add(ZT_AUTHINFO_DICT_KEY_CLIENT_ID, info.ssoClientID.c_str()); authInfo.add(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, info.ssoProvider.c_str()); - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes()); } DB::cleanMember(member); - _db.save(member,true); - #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + _db.save(member, true); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b6.stop(); - #endif +#endif return; } } #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b6.stop(); - auto b7 = _auth_check.Add({{"thread",threadID}}); - auto c7 = _auth_check_count.Add({{"thread",threadID}}); + auto b7 = _auth_check.Add({ { "thread", threadID } }); + auto c7 = _auth_check_count.Add({ { "thread", threadID } }); c7++; b7.start(); #endif if (authorized) { // Update version info and meta-data if authorized and if this is a genuine request if (requestPacketId) { - const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0); - const uint64_t vMinor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0); - const uint64_t vRev = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0); - const uint64_t vProto = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,0); + const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION, 0); + const uint64_t vMinor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION, 0); + const uint64_t vRev = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION, 0); + const uint64_t vProto = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION, 0); member["vMajor"] = vMajor; member["vMinor"] = vMinor; @@ -1593,7 +1695,7 @@ void EmbeddedNetworkController::_request( { std::lock_guard l(_memberStatus_l); - _MemberStatus &ms = _memberStatus[msk]; + _MemberStatus& ms = _memberStatus[msk]; ms.authenticationExpiryTime = authenticationExpiryTime; ms.vMajor = (int)vMajor; ms.vMinor = (int)vMinor; @@ -1608,14 +1710,15 @@ void EmbeddedNetworkController::_request( _expiringSoon.insert(std::pair(authenticationExpiryTime, msk)); } } - } else { + } + else { // If they are not authorized, STOP! DB::cleanMember(member); - _db.save(member,true); - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); - #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + _db.save(member, true); + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b7.stop(); - #endif +#endif return; } #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK @@ -1629,8 +1732,8 @@ void EmbeddedNetworkController::_request( // Default timeout: 15 minutes. Maximum: two hours. Can be specified by an optional field in the network config // if something longer than 15 minutes is desired. Minimum is 5 minutes since shorter than that would be flaky. #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b8 = _json_schlep.Add({{"thread",threadID}}); - auto c8 = _json_schlep_count.Add({{"thread", threadID}}); + auto b8 = _json_schlep.Add({ { "thread", threadID } }); + auto c8 = _json_schlep_count.Add({ { "thread", threadID } }); c8++; b8.start(); #endif @@ -1643,139 +1746,143 @@ void EmbeddedNetworkController::_request( std::unique_ptr nc(new NetworkConfig()); nc->networkId = nwid; - nc->type = OSUtils::jsonBool(network["private"],true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; + nc->type = OSUtils::jsonBool(network["private"], true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; nc->timestamp = now; nc->credentialTimeMaxDelta = credentialtmd; - nc->revision = OSUtils::jsonInt(network["revision"],0ULL); + nc->revision = OSUtils::jsonInt(network["revision"], 0ULL); nc->issuedTo = identity.address(); - if (OSUtils::jsonBool(network["enableBroadcast"],true)) nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST; - Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str()); - nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU); - nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL); + if (OSUtils::jsonBool(network["enableBroadcast"], true)) + nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST; + Utils::scopy(nc->name, sizeof(nc->name), OSUtils::jsonString(network["name"], "").c_str()); + nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"], ZT_DEFAULT_MTU), (unsigned int)ZT_MAX_MTU), (unsigned int)ZT_MIN_MTU); + nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"], 32ULL); - nc->ssoEnabled = networkSSOEnabled; //OSUtils::jsonBool(network["ssoEnabled"], false); + nc->ssoEnabled = networkSSOEnabled; // OSUtils::jsonBool(network["ssoEnabled"], false); nc->ssoVersion = info.version; if (info.version == 0) { nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL); - if (!info.authenticationURL.empty()) { + if (! info.authenticationURL.empty()) { Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), info.authenticationURL.c_str()); } } else if (info.version == 1) { nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL); - if (!info.authenticationURL.empty()) { + if (! info.authenticationURL.empty()) { Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), info.authenticationURL.c_str()); } - if (!info.centralAuthURL.empty()) { + if (! info.centralAuthURL.empty()) { Utils::scopy(nc->centralAuthURL, sizeof(nc->centralAuthURL), info.centralAuthURL.c_str()); } - if (!info.issuerURL.empty()) { - #ifdef ZT_DEBUG + if (! info.issuerURL.empty()) { +#ifdef ZT_DEBUG fprintf(stderr, "copying issuerURL to nc: %s\n", info.issuerURL.c_str()); - #endif +#endif Utils::scopy(nc->issuerURL, sizeof(nc->issuerURL), info.issuerURL.c_str()); } - if (!info.ssoNonce.empty()) { + if (! info.ssoNonce.empty()) { Utils::scopy(nc->ssoNonce, sizeof(nc->ssoNonce), info.ssoNonce.c_str()); } - if (!info.ssoState.empty()) { + if (! info.ssoState.empty()) { Utils::scopy(nc->ssoState, sizeof(nc->ssoState), info.ssoState.c_str()); } - if (!info.ssoClientID.empty()) { + if (! info.ssoClientID.empty()) { Utils::scopy(nc->ssoClientID, sizeof(nc->ssoClientID), info.ssoClientID.c_str()); } } - std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],"")); + std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"], "")); if (rtt.length() == 10) { nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str())); - nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(member["remoteTraceLevel"],0ULL); - } else { - rtt = OSUtils::jsonString(network["remoteTraceTarget"],""); + nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(member["remoteTraceLevel"], 0ULL); + } + else { + rtt = OSUtils::jsonString(network["remoteTraceTarget"], ""); if (rtt.length() == 10) { nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str())); - } else { + } + else { nc->remoteTraceTarget.zero(); } - nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(network["remoteTraceLevel"],0ULL); + nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(network["remoteTraceLevel"], 0ULL); } - for(std::vector
::const_iterator ab(ns.activeBridges.begin());ab!=ns.activeBridges.end();++ab) { - nc->addSpecialist(*ab,ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); + for (std::vector
::const_iterator ab(ns.activeBridges.begin()); ab != ns.activeBridges.end(); ++ab) { + nc->addSpecialist(*ab, ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); } - json &v4AssignMode = network["v4AssignMode"]; - json &v6AssignMode = network["v6AssignMode"]; - json &ipAssignmentPools = network["ipAssignmentPools"]; - json &routes = network["routes"]; - json &rules = network["rules"]; - json &capabilities = network["capabilities"]; - json &tags = network["tags"]; - json &memberCapabilities = member["capabilities"]; - json &memberTags = member["tags"]; - json &dns = network["dns"]; + json& v4AssignMode = network["v4AssignMode"]; + json& v6AssignMode = network["v6AssignMode"]; + json& ipAssignmentPools = network["ipAssignmentPools"]; + json& routes = network["routes"]; + json& rules = network["rules"]; + json& capabilities = network["capabilities"]; + json& tags = network["tags"]; + json& memberCapabilities = member["capabilities"]; + json& memberTags = member["tags"]; + json& dns = network["dns"]; - //fprintf(stderr, "IP Assignment Pools for Network %s: %s\n", nwids, OSUtils::jsonDump(ipAssignmentPools, 2).c_str()); + // fprintf(stderr, "IP Assignment Pools for Network %s: %s\n", nwids, OSUtils::jsonDump(ipAssignmentPools, 2).c_str()); - if (metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,0) <= 0) { + 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. // Since rules are enforced bidirectionally, newer versions *will* still // enforce rules on the inbound side. nc->ruleCount = 1; nc->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT; - } else { + } + else { if (rules.is_array()) { - for(unsigned long i=0;iruleCount >= ZT_MAX_NETWORK_RULES) break; - if (_parseRule(rules[i],nc->rules[nc->ruleCount])) + if (_parseRule(rules[i], nc->rules[nc->ruleCount])) ++nc->ruleCount; } } - std::map< uint64_t,json * > capsById; - if (!memberCapabilities.is_array()) + std::map capsById; + if (! memberCapabilities.is_array()) memberCapabilities = json::array(); if (capabilities.is_array()) { - for(unsigned long i=0;i::const_iterator ctmp = capsById.find(capId); + for (unsigned long i = 0; i < memberCapabilities.size(); ++i) { + const uint64_t capId = OSUtils::jsonInt(memberCapabilities[i], 0ULL) & 0xffffffffULL; + std::map::const_iterator ctmp = capsById.find(capId); if (ctmp != capsById.end()) { - json *cap = ctmp->second; - if ((cap)&&(cap->is_object())&&(!cap->empty())) { + json* cap = ctmp->second; + if ((cap) && (cap->is_object()) && (! cap->empty())) { ZT_VirtualNetworkRule capr[ZT_MAX_CAPABILITY_RULES]; unsigned int caprc = 0; - json &caprj = (*cap)["rules"]; - if ((caprj.is_array())&&(!caprj.empty())) { - for(unsigned long j=0;j= ZT_MAX_CAPABILITY_RULES) break; - if (_parseRule(caprj[j],capr[caprc])) + if (_parseRule(caprj[j], capr[caprc])) ++caprc; } } - nc->capabilities[nc->capabilityCount] = Capability((uint32_t)capId,nwid,now,1,capr,caprc); - if (nc->capabilities[nc->capabilityCount].sign(_signingId,identity.address())) + nc->capabilities[nc->capabilityCount] = Capability((uint32_t)capId, nwid, now, 1, capr, caprc); + if (nc->capabilities[nc->capabilityCount].sign(_signingId, identity.address())) ++nc->capabilityCount; if (nc->capabilityCount >= ZT_MAX_NETWORK_CAPABILITIES) break; @@ -1783,87 +1890,88 @@ void EmbeddedNetworkController::_request( } } - std::map< uint32_t,uint32_t > memberTagsById; + std::map memberTagsById; if (memberTags.is_array()) { - for(unsigned long i=0;i::const_iterator t(memberTagsById.begin());t!=memberTagsById.end();++t) { + for (std::map::const_iterator t(memberTagsById.begin()); t != memberTagsById.end(); ++t) { if (nc->tagCount >= ZT_MAX_NETWORK_TAGS) break; - nc->tags[nc->tagCount] = Tag(nwid,now,identity.address(),t->first,t->second); + nc->tags[nc->tagCount] = Tag(nwid, now, identity.address(), t->first, t->second); if (nc->tags[nc->tagCount].sign(_signingId)) ++nc->tagCount; } } if (routes.is_array()) { - for(unsigned long i=0;irouteCount >= ZT_MAX_NETWORK_ROUTES) break; - json &route = routes[i]; - json &target = route["target"]; - json &via = route["via"]; + json& route = routes[i]; + json& target = route["target"]; + json& via = route["via"]; if (target.is_string()) { const InetAddress t(target.get().c_str()); InetAddress v; - if (via.is_string()) v.fromString(via.get().c_str()); - if ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) { - ZT_VirtualNetworkRoute *r = &(nc->routes[nc->routeCount]); - *(reinterpret_cast(&(r->target))) = t; + if (via.is_string()) + v.fromString(via.get().c_str()); + if ((t.ss_family == AF_INET) || (t.ss_family == AF_INET6)) { + ZT_VirtualNetworkRoute* r = &(nc->routes[nc->routeCount]); + *(reinterpret_cast(&(r->target))) = t; if (v.ss_family == t.ss_family) - *(reinterpret_cast(&(r->via))) = v; - ++nc->routeCount; + *(reinterpret_cast(&(r->via))) = v; + ++nc->routeCount; } } } } - const bool noAutoAssignIps = OSUtils::jsonBool(member["noAutoAssignIps"],false); + const bool noAutoAssignIps = OSUtils::jsonBool(member["noAutoAssignIps"], false); - if ((v6AssignMode.is_object())&&(!noAutoAssignIps)) { - if ((OSUtils::jsonBool(v6AssignMode["rfc4193"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { - nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt()); + if ((v6AssignMode.is_object()) && (! noAutoAssignIps)) { + if ((OSUtils::jsonBool(v6AssignMode["rfc4193"], false)) && (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { + nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid, identity.address().toInt()); nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; } - if ((OSUtils::jsonBool(v6AssignMode["6plane"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { - nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv66plane(nwid,identity.address().toInt()); + if ((OSUtils::jsonBool(v6AssignMode["6plane"], false)) && (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { + nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv66plane(nwid, identity.address().toInt()); nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; } } bool haveManagedIpv4AutoAssignment = false; - bool haveManagedIpv6AutoAssignment = false; // "special" NDP-emulated address types do not count - json ipAssignments = member["ipAssignments"]; // we want to make a copy + bool haveManagedIpv6AutoAssignment = false; // "special" NDP-emulated address types do not count + json ipAssignments = member["ipAssignments"]; // we want to make a copy if (ipAssignments.is_array()) { - for(unsigned long i=0;irouteCount;++rk) { - if (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip)) { - const int nb = (int)(reinterpret_cast(&(nc->routes[rk].target))->netmaskBits()); + for (unsigned int rk = 0; rk < nc->routeCount; ++rk) { + if (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip)) { + const int nb = (int)(reinterpret_cast(&(nc->routes[rk].target))->netmaskBits()); if (nb > routedNetmaskBits) routedNetmaskBits = nb; } @@ -1881,20 +1989,21 @@ void EmbeddedNetworkController::_request( } } } - } else { + } + else { ipAssignments = json::array(); } - if ( (ipAssignmentPools.is_array()) && ((v6AssignMode.is_object())&&(OSUtils::jsonBool(v6AssignMode["zt"],false))) && (!haveManagedIpv6AutoAssignment) && (!noAutoAssignIps) ) { - for(unsigned long p=0;((p s[1])&&((e[1] - s[1]) >= 0xffffffffffULL)) { + for (unsigned int trialCount = 0; trialCount < 1000; ++trialCount) { + if ((trialCount == 0) && (e[1] > s[1]) && ((e[1] - s[1]) >= 0xffffffffffULL)) { // First see if we can just cram a ZeroTier ID into the higher 64 bits. If so do that. xx[0] = Utils::hton(x[0]); xx[1] = Utils::hton(x[1] + identity.address().toInt()); - } else { + } + else { // Otherwise pick random addresses -- this technically doesn't explore the whole range if the lower 64 bit range is >= 1 but that won't matter since that would be huge anyway - Utils::getSecureRandom((void *)xx,16); + Utils::getSecureRandom((void*)xx, 16); if ((e[0] > s[0])) xx[0] %= (e[0] - s[0]); - else xx[0] = 0; + else + xx[0] = 0; if ((e[1] > s[1])) xx[1] %= (e[1] - s[1]); - else xx[1] = 0; + else + xx[1] = 0; xx[0] = Utils::hton(x[0] + xx[0]); xx[1] = Utils::hton(x[1] + xx[1]); } - InetAddress ip6((const void *)xx,16,0); + InetAddress ip6((const void*)xx, 16, 0); // Check if this IP is within a local-to-Ethernet routed network int routedNetmaskBits = 0; - for(unsigned int rk=0;rkrouteCount;++rk) { - if ( (!nc->routes[rk].via.ss_family) && (nc->routes[rk].target.ss_family == AF_INET6) && (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip6)) ) - routedNetmaskBits = reinterpret_cast(&(nc->routes[rk].target))->netmaskBits(); + for (unsigned int rk = 0; rk < nc->routeCount; ++rk) { + if ((! nc->routes[rk].via.ss_family) && (nc->routes[rk].target.ss_family == AF_INET6) && (reinterpret_cast(&(nc->routes[rk].target))->containsAddress(ip6))) + routedNetmaskBits = reinterpret_cast(&(nc->routes[rk].target))->netmaskBits(); } // If it's routed, then try to claim and assign it and if successful end loop - if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip6)) ) { + if ((routedNetmaskBits > 0) && (! std::binary_search(ns.allocatedIps.begin(), ns.allocatedIps.end(), ip6))) { char tmpip[64]; const std::string ipStr(ip6.toIpString(tmpip)); - if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) { + if (std::find(ipAssignments.begin(), ipAssignments.end(), ipStr) == ipAssignments.end()) { ipAssignments.push_back(ipStr); member["ipAssignments"] = ipAssignments; ip6.setPort((unsigned int)routedNetmaskBits); @@ -1949,36 +2061,36 @@ void EmbeddedNetworkController::_request( } } - if ( (ipAssignmentPools.is_array()) && ((v4AssignMode.is_object())&&(OSUtils::jsonBool(v4AssignMode["zt"],false))) && (!haveManagedIpv4AutoAssignment) && (!noAutoAssignIps) ) { - for(unsigned long p=0;((p(&ipRangeStartIA)->sin_addr.s_addr)); - uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast(&ipRangeEndIA)->sin_addr.s_addr)); + InetAddress ipRangeStartIA(OSUtils::jsonString(pool["ipRangeStart"], "").c_str()); + InetAddress ipRangeEndIA(OSUtils::jsonString(pool["ipRangeEnd"], "").c_str()); + if ((ipRangeStartIA.ss_family == AF_INET) && (ipRangeEndIA.ss_family == AF_INET)) { + uint32_t ipRangeStart = Utils::ntoh((uint32_t)(reinterpret_cast(&ipRangeStartIA)->sin_addr.s_addr)); + uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast(&ipRangeEndIA)->sin_addr.s_addr)); - if ((ipRangeEnd < ipRangeStart)||(ipRangeStart == 0)) + if ((ipRangeEnd < ipRangeStart) || (ipRangeStart == 0)) continue; uint32_t ipRangeLen = ipRangeEnd - ipRangeStart; // Start with the LSB of the member's address uint32_t ipTrialCounter = (uint32_t)(identity.address().toInt() & 0xffffffff); - for(uint32_t k=ipRangeStart,trialCount=0;((k<=ipRangeEnd)&&(trialCount < 1000));++k,++trialCount) { + for (uint32_t k = ipRangeStart, trialCount = 0; ((k <= ipRangeEnd) && (trialCount < 1000)); ++k, ++trialCount) { uint32_t ip = (ipRangeLen > 0) ? (ipRangeStart + (ipTrialCounter % ipRangeLen)) : ipRangeStart; ++ipTrialCounter; if ((ip & 0x000000ff) == 0x000000ff) { - continue; // don't allow addresses that end in .255 + continue; // don't allow addresses that end in .255 } // Check if this IP is within a local-to-Ethernet routed network int routedNetmaskBits = -1; - for(unsigned int rk=0;rkrouteCount;++rk) { + for (unsigned int rk = 0; rk < nc->routeCount; ++rk) { if (nc->routes[rk].target.ss_family == AF_INET) { - uint32_t targetIp = Utils::ntoh((uint32_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_addr.s_addr)); - int targetBits = Utils::ntoh((uint16_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_port)); + uint32_t targetIp = Utils::ntoh((uint32_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_addr.s_addr)); + int targetBits = Utils::ntoh((uint16_t)(reinterpret_cast(&(nc->routes[rk].target))->sin_port)); if ((ip & (0xffffffff << (32 - targetBits))) == targetIp) { routedNetmaskBits = targetBits; break; @@ -1987,15 +2099,15 @@ void EmbeddedNetworkController::_request( } // If it's routed, then try to claim and assign it and if successful end loop - const InetAddress ip4(Utils::hton(ip),0); - if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip4)) ) { + const InetAddress ip4(Utils::hton(ip), 0); + if ((routedNetmaskBits > 0) && (! std::binary_search(ns.allocatedIps.begin(), ns.allocatedIps.end(), ip4))) { char tmpip[64]; const std::string ipStr(ip4.toIpString(tmpip)); - if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) { + if (std::find(ipAssignments.begin(), ipAssignments.end(), ipStr) == ipAssignments.end()) { ipAssignments.push_back(ipStr); member["ipAssignments"] = ipAssignments; if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) { - struct sockaddr_in *const v4ip = reinterpret_cast(&(nc->staticIps[nc->staticIpCount++])); + struct sockaddr_in* const v4ip = reinterpret_cast(&(nc->staticIps[nc->staticIpCount++])); v4ip->sin_family = AF_INET; v4ip->sin_port = Utils::hton((uint16_t)routedNetmaskBits); v4ip->sin_addr.s_addr = Utils::hton(ip); @@ -2009,18 +2121,19 @@ void EmbeddedNetworkController::_request( } } } - - if(dns.is_object()) { - std::string domain = OSUtils::jsonString(dns["domain"],""); + + if (dns.is_object()) { + std::string domain = OSUtils::jsonString(dns["domain"], ""); memcpy(nc->dns.domain, domain.c_str(), domain.size()); - json &addrArray = dns["servers"]; + 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()); + 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::object(); } #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK @@ -2029,49 +2142,50 @@ void EmbeddedNetworkController::_request( // Issue a certificate of ownership for all static IPs #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK - auto b9 = _issue_certificate.Add({{"thread",threadID}}); - auto c9 = _issue_certificate_count.Add({{"thread",threadID}}); + auto b9 = _issue_certificate.Add({ { "thread", threadID } }); + auto c9 = _issue_certificate_count.Add({ { "thread", threadID } }); c9++; b9.start(); #endif if (nc->staticIpCount) { - nc->certificatesOfOwnership[0] = CertificateOfOwnership(nwid,now,identity.address(),1); - for(unsigned int i=0;istaticIpCount;++i) { + nc->certificatesOfOwnership[0] = CertificateOfOwnership(nwid, now, identity.address(), 1); + for (unsigned int i = 0; i < nc->staticIpCount; ++i) { nc->certificatesOfOwnership[0].addThing(nc->staticIps[i]); } nc->certificatesOfOwnership[0].sign(_signingId); nc->certificateOfOwnershipCount = 1; } - CertificateOfMembership com(now,credentialtmd,nwid,identity); + CertificateOfMembership com(now, credentialtmd, nwid, identity); if (com.sign(_signingId)) { nc->com = com; - } else { - _sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR, nullptr, 0); - #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK + } + else { + _sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR, nullptr, 0); +#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b9.stop(); - #endif +#endif return; } #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b9.stop(); - auto b10 = _save_member.Add({{"thread",threadID}}); - auto c10 = _save_member_count.Add({{"thread",threadID}}); + auto b10 = _save_member.Add({ { "thread", threadID } }); + auto c10 = _save_member_count.Add({ { "thread", threadID } }); c10++; b10.start(); #endif DB::cleanMember(member); - _db.save(member,true); + _db.save(member, true); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b10.stop(); - auto b11 = _send_netconf.Add({{"thread",threadID}}); - auto c11 = _send_netconf_count.Add({{"thread",threadID}}); + auto b11 = _send_netconf.Add({ { "thread", threadID } }); + auto c11 = _send_netconf_count.Add({ { "thread", threadID } }); c11++; b11.start(); #endif - _sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6); + _sender->ncSendConfig(nwid, requestPacketId, identity.address(), *(nc.get()), metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION, 0) < 6); #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK b11.stop(); #endif @@ -2080,27 +2194,30 @@ void EmbeddedNetworkController::_request( void EmbeddedNetworkController::_startThreads() { std::lock_guard l(_threads_l); - if (!_threads.empty()) { + if (! _threads.empty()) { return; } - const long hwc = std::max((long)std::thread::hardware_concurrency(),(long)1); - for(long t=0;t::STOP) { + if (timedWaitResult == BlockingQueue<_RQEntry*>::STOP) { break; - } else if (timedWaitResult == BlockingQueue<_RQEntry *>::OK) { + } + else if (timedWaitResult == BlockingQueue<_RQEntry*>::OK) { if (qe) { try { - _request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData); - } catch (std::exception &e) { - fprintf(stderr,"ERROR: exception in controller request handling thread: %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S); + _request(qe->nwid, qe->fromAddr, qe->requestPacketId, qe->identity, qe->metaData); + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: exception in controller request handling thread: %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S); } delete qe; qe = nullptr; @@ -2112,14 +2229,15 @@ void EmbeddedNetworkController::_startThreads() } } -void EmbeddedNetworkController::_ssoExpiryThread() { - while(_ssoExpiryRunning) { +void EmbeddedNetworkController::_ssoExpiryThread() +{ + while (_ssoExpiryRunning) { std::vector<_MemberStatusKey> expired; nlohmann::json network, member; int64_t now = OSUtils::now(); { std::lock_guard l(_expiringSoon_l); - for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) { + for (auto s = _expiringSoon.begin(); s != _expiringSoon.end();) { Metrics::sso_expiration_checks++; const int64_t when = s->first; if (when <= now) { @@ -2133,13 +2251,14 @@ void EmbeddedNetworkController::_ssoExpiryThread() { } } s = _expiringSoon.erase(s); - } else { + } + else { // Don't bother going further into the future than necessary. break; } } } - for(auto e=expired.begin();e!=expired.end();++e) { + for (auto e = expired.begin(); e != expired.end(); ++e) { Metrics::sso_member_deauth++; onNetworkMemberDeauthorize(nullptr, e->networkId, e->nodeId); } @@ -2147,4 +2266,4 @@ void EmbeddedNetworkController::_ssoExpiryThread() { } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index aa3f162f1..111417bfb 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -14,112 +14,109 @@ #ifndef ZT_SQLITENETWORKCONTROLLER_HPP #define ZT_SQLITENETWORKCONTROLLER_HPP -#include - -#include -#include -#include -#include -#include -#include -#include -#include - +#include "../node/Address.hpp" #include "../node/Constants.hpp" +#include "../node/InetAddress.hpp" #include "../node/NetworkController.hpp" #include "../node/Utils.hpp" -#include "../node/Address.hpp" -#include "../node/InetAddress.hpp" - +#include "../osdep/BlockingQueue.hpp" #include "../osdep/OSUtils.hpp" #include "../osdep/Thread.hpp" -#include "../osdep/BlockingQueue.hpp" - -#include - -#include - #include "DB.hpp" #include "DBMirrorSet.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace ZeroTier { class Node; struct RedisConfig; -class EmbeddedNetworkController : public NetworkController,public DB::ChangeListener -{ -public: +class EmbeddedNetworkController + : public NetworkController + , public DB::ChangeListener { + public: /** * @param node Parent node * @param dbPath Database path (file path or database credentials) */ - EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc); + EmbeddedNetworkController(Node* node, const char* ztPath, const char* dbPath, int listenPort, RedisConfig* rc); virtual ~EmbeddedNetworkController(); - virtual void init(const Identity &signingId,Sender *sender); + virtual void init(const Identity& signingId, Sender* sender); - void setSSORedirectURL(const std::string &url); + void setSSORedirectURL(const std::string& url); - virtual void request( - uint64_t nwid, - const InetAddress &fromAddr, - uint64_t requestPacketId, - const Identity &identity, - const Dictionary &metaData); + virtual void request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData); - void configureHTTPControlPlane( - httplib::Server &s, - httplib::Server &sV6, - const std::function); + void configureHTTPControlPlane(httplib::Server& s, httplib::Server& sV6, const std::function); - void handleRemoteTrace(const ZT_RemoteTrace &rt); + void handleRemoteTrace(const ZT_RemoteTrace& rt); - virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network); - virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); - virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); + virtual void onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network); + virtual void onNetworkMemberUpdate(const void* db, uint64_t networkId, uint64_t memberId, const nlohmann::json& member); + virtual void onNetworkMemberDeauthorize(const void* db, uint64_t networkId, uint64_t memberId); -private: - void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary &metaData); + private: + void _request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData); void _startThreads(); void _ssoExpiryThread(); - std::string networkUpdateFromPostData(uint64_t networkID, const std::string &body); + std::string networkUpdateFromPostData(uint64_t networkID, const std::string& body); - struct _RQEntry - { + struct _RQEntry { uint64_t nwid; uint64_t requestPacketId; InetAddress fromAddr; Identity identity; Dictionary metaData; - enum { - RQENTRY_TYPE_REQUEST = 0 - } type; + enum { RQENTRY_TYPE_REQUEST = 0 } type; }; - struct _MemberStatusKey - { - _MemberStatusKey() : networkId(0),nodeId(0) {} - _MemberStatusKey(const uint64_t nwid,const uint64_t nid) : networkId(nwid),nodeId(nid) {} + struct _MemberStatusKey { + _MemberStatusKey() : networkId(0), nodeId(0) + { + } + _MemberStatusKey(const uint64_t nwid, const uint64_t nid) : networkId(nwid), nodeId(nid) + { + } uint64_t networkId; uint64_t nodeId; - inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); } - inline bool operator<(const _MemberStatusKey &k) const { return (k.networkId < networkId) || ((k.networkId == networkId)&&(k.nodeId < nodeId)); } + inline bool operator==(const _MemberStatusKey& k) const + { + return ((k.networkId == networkId) && (k.nodeId == nodeId)); + } + inline bool operator<(const _MemberStatusKey& k) const + { + return (k.networkId < networkId) || ((k.networkId == networkId) && (k.nodeId < nodeId)); + } }; - struct _MemberStatus - { - _MemberStatus() : lastRequestTime(0),authenticationExpiryTime(-1),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {} + struct _MemberStatus { + _MemberStatus() : lastRequestTime(0), authenticationExpiryTime(-1), vMajor(-1), vMinor(-1), vRev(-1), vProto(-1) + { + } int64_t lastRequestTime; int64_t authenticationExpiryTime; - int vMajor,vMinor,vRev,vProto; + int vMajor, vMinor, vRev, vProto; Dictionary lastRequestMetaData; Identity identity; - inline bool online(const int64_t now) const { return ((now - lastRequestTime) < (ZT_NETWORK_AUTOCONF_DELAY * 2)); } + inline bool online(const int64_t now) const + { + return ((now - lastRequestTime) < (ZT_NETWORK_AUTOCONF_DELAY * 2)); + } }; - struct _MemberStatusHash - { - inline std::size_t operator()(const _MemberStatusKey &networkIdNodeId) const + struct _MemberStatusHash { + inline std::size_t operator()(const _MemberStatusKey& networkIdNodeId) const { return (std::size_t)(networkIdNodeId.networkId + networkIdNodeId.nodeId); } @@ -127,26 +124,26 @@ private: const int64_t _startTime; int _listenPort; - Node *const _node; + Node* const _node; std::string _ztPath; std::string _path; Identity _signingId; std::string _signingIdAddressString; - NetworkController::Sender *_sender; + NetworkController::Sender* _sender; DBMirrorSet _db; - BlockingQueue< _RQEntry * > _queue; + BlockingQueue<_RQEntry*> _queue; std::vector _threads; std::mutex _threads_l; - std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; + std::unordered_map<_MemberStatusKey, _MemberStatus, _MemberStatusHash> _memberStatus; std::mutex _memberStatus_l; - std::set< std::pair > _expiringSoon; + std::set > _expiringSoon; std::mutex _expiringSoon_l; - RedisConfig *_rc; + RedisConfig* _rc; std::string _ssoRedirectURL; bool _ssoExpiryRunning; @@ -154,30 +151,30 @@ private: #ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK prometheus::simpleapi::benchmark_family_t _member_status_lookup; - prometheus::simpleapi::counter_family_t _member_status_lookup_count; + prometheus::simpleapi::counter_family_t _member_status_lookup_count; prometheus::simpleapi::benchmark_family_t _node_is_online; - prometheus::simpleapi::counter_family_t _node_is_online_count; + prometheus::simpleapi::counter_family_t _node_is_online_count; prometheus::simpleapi::benchmark_family_t _get_and_init_member; - prometheus::simpleapi::counter_family_t _get_and_init_member_count; + prometheus::simpleapi::counter_family_t _get_and_init_member_count; prometheus::simpleapi::benchmark_family_t _have_identity; - prometheus::simpleapi::counter_family_t _have_identity_count; + prometheus::simpleapi::counter_family_t _have_identity_count; prometheus::simpleapi::benchmark_family_t _determine_auth; - prometheus::simpleapi::counter_family_t _determine_auth_count; + prometheus::simpleapi::counter_family_t _determine_auth_count; prometheus::simpleapi::benchmark_family_t _sso_check; - prometheus::simpleapi::counter_family_t _sso_check_count; + prometheus::simpleapi::counter_family_t _sso_check_count; prometheus::simpleapi::benchmark_family_t _auth_check; - prometheus::simpleapi::counter_family_t _auth_check_count; + prometheus::simpleapi::counter_family_t _auth_check_count; prometheus::simpleapi::benchmark_family_t _json_schlep; - prometheus::simpleapi::counter_family_t _json_schlep_count; + prometheus::simpleapi::counter_family_t _json_schlep_count; prometheus::simpleapi::benchmark_family_t _issue_certificate; - prometheus::simpleapi::counter_family_t _issue_certificate_count; + prometheus::simpleapi::counter_family_t _issue_certificate_count; prometheus::simpleapi::benchmark_family_t _save_member; - prometheus::simpleapi::counter_family_t _save_member_count; + prometheus::simpleapi::counter_family_t _save_member_count; prometheus::simpleapi::benchmark_family_t _send_netconf; - prometheus::simpleapi::counter_family_t _send_netconf_count; + prometheus::simpleapi::counter_family_t _send_netconf_count; #endif }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/controller/FileDB.cpp b/controller/FileDB.cpp index d039f00b7..2ccdad6ff 100644 --- a/controller/FileDB.cpp +++ b/controller/FileDB.cpp @@ -15,51 +15,49 @@ #include "../node/Metrics.hpp" -namespace ZeroTier -{ +namespace ZeroTier { -FileDB::FileDB(const char *path) : - DB(), - _path(path), - _networksPath(_path + ZT_PATH_SEPARATOR_S + "network"), - _tracePath(_path + ZT_PATH_SEPARATOR_S + "trace"), - _running(true) +FileDB::FileDB(const char* path) : DB(), _path(path), _networksPath(_path + ZT_PATH_SEPARATOR_S + "network"), _tracePath(_path + ZT_PATH_SEPARATOR_S + "trace"), _running(true) { OSUtils::mkdir(_path.c_str()); - OSUtils::lockDownFile(_path.c_str(),true); + OSUtils::lockDownFile(_path.c_str(), true); OSUtils::mkdir(_networksPath.c_str()); OSUtils::mkdir(_tracePath.c_str()); - std::vector networks(OSUtils::listDirectory(_networksPath.c_str(),false)); + std::vector networks(OSUtils::listDirectory(_networksPath.c_str(), false)); std::string buf; - for(auto n=networks.begin();n!=networks.end();++n) { + for (auto n = networks.begin(); n != networks.end(); ++n) { buf.clear(); - if ((n->length() == 21)&&(OSUtils::readFile((_networksPath + ZT_PATH_SEPARATOR_S + *n).c_str(),buf))) { + if ((n->length() == 21) && (OSUtils::readFile((_networksPath + ZT_PATH_SEPARATOR_S + *n).c_str(), buf))) { try { nlohmann::json network(OSUtils::jsonParse(buf)); const std::string nwids = network["id"]; if (nwids.length() == 16) { nlohmann::json nullJson; - _networkChanged(nullJson,network,false); + _networkChanged(nullJson, network, false); Metrics::network_count++; std::string membersPath(_networksPath + ZT_PATH_SEPARATOR_S + nwids + ZT_PATH_SEPARATOR_S "member"); - std::vector members(OSUtils::listDirectory(membersPath.c_str(),false)); - for(auto m=members.begin();m!=members.end();++m) { + std::vector members(OSUtils::listDirectory(membersPath.c_str(), false)); + for (auto m = members.begin(); m != members.end(); ++m) { buf.clear(); - if ((m->length() == 15)&&(OSUtils::readFile((membersPath + ZT_PATH_SEPARATOR_S + *m).c_str(),buf))) { + if ((m->length() == 15) && (OSUtils::readFile((membersPath + ZT_PATH_SEPARATOR_S + *m).c_str(), buf))) { try { nlohmann::json member(OSUtils::jsonParse(buf)); const std::string addrs = member["id"]; if (addrs.length() == 10) { nlohmann::json nullJson2; - _memberChanged(nullJson2,member,false); + _memberChanged(nullJson2, member, false); Metrics::member_count++; } - } catch ( ... ) {} + } + catch (...) { + } } } } - } catch ( ... ) {} + } + catch (...) { + } } } } @@ -71,101 +69,109 @@ FileDB::~FileDB() _running = false; _online_l.unlock(); _onlineUpdateThread.join(); - } catch ( ... ) {} + } + catch (...) { + } } -bool FileDB::waitForReady() { return true; } -bool FileDB::isReady() { return true; } - -bool FileDB::save(nlohmann::json &record,bool notifyListeners) +bool FileDB::waitForReady() { - char p1[4096],p2[4096],pb[4096]; + return true; +} +bool FileDB::isReady() +{ + return true; +} + +bool FileDB::save(nlohmann::json& record, bool notifyListeners) +{ + char p1[4096], p2[4096], pb[4096]; bool modified = false; try { const std::string objtype = record["objtype"]; if (objtype == "network") { - - const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + const uint64_t nwid = OSUtils::jsonIntHex(record["id"], 0ULL); if (nwid) { nlohmann::json old; - get(nwid,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid); - if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { - fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); + get(nwid, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + OSUtils::ztsnprintf(p1, sizeof(p1), "%s" ZT_PATH_SEPARATOR_S "%.16llx.json", _networksPath.c_str(), nwid); + if (! OSUtils::writeFile(p1, OSUtils::jsonDump(record, -1))) { + fprintf(stderr, "WARNING: controller unable to write to path: %s" ZT_EOL_S, p1); } - _networkChanged(old,record,notifyListeners); + _networkChanged(old, record, notifyListeners); modified = true; } } - - } else if (objtype == "member") { - - const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); - const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); - if ((id)&&(nwid)) { - nlohmann::json network,old; - get(nwid,network,id,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid); - OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id); - if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { - OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)nwid); + } + else if (objtype == "member") { + const uint64_t id = OSUtils::jsonIntHex(record["id"], 0ULL); + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"], 0ULL); + if ((id) && (nwid)) { + nlohmann::json network, old; + get(nwid, network, id, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + OSUtils::ztsnprintf(pb, sizeof(pb), "%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member", _networksPath.c_str(), (unsigned long long)nwid); + OSUtils::ztsnprintf(p1, sizeof(p1), "%s" ZT_PATH_SEPARATOR_S "%.10llx.json", pb, (unsigned long long)id); + if (! OSUtils::writeFile(p1, OSUtils::jsonDump(record, -1))) { + OSUtils::ztsnprintf(p2, sizeof(p2), "%s" ZT_PATH_SEPARATOR_S "%.16llx", _networksPath.c_str(), (unsigned long long)nwid); OSUtils::mkdir(p2); OSUtils::mkdir(pb); - if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { - fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); + if (! OSUtils::writeFile(p1, OSUtils::jsonDump(record, -1))) { + fprintf(stderr, "WARNING: controller unable to write to path: %s" ZT_EOL_S, p1); } } - _memberChanged(old,record,notifyListeners); + _memberChanged(old, record, notifyListeners); modified = true; } } - } - } catch ( ... ) {} // drop invalid records missing fields + } + catch (...) { + } // drop invalid records missing fields return modified; } void FileDB::eraseNetwork(const uint64_t networkId) { - nlohmann::json network,nullJson; - get(networkId,network); + nlohmann::json network, nullJson; + get(networkId, network); char p[16384]; - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),networkId); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.16llx.json", _networksPath.c_str(), networkId); OSUtils::rm(p); - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)networkId); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.16llx", _networksPath.c_str(), (unsigned long long)networkId); OSUtils::rmDashRf(p); - _networkChanged(network,nullJson,true); + _networkChanged(network, nullJson, true); std::lock_guard l(this->_online_l); this->_online.erase(networkId); } -void FileDB::eraseMember(const uint64_t networkId,const uint64_t memberId) +void FileDB::eraseMember(const uint64_t networkId, const uint64_t memberId) { - nlohmann::json network,member,nullJson; - get(networkId,network,memberId,member); + nlohmann::json network, member, nullJson; + get(networkId, network, memberId, member); char p[4096]; - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json",_networksPath.c_str(),networkId,memberId); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json", _networksPath.c_str(), networkId, memberId); OSUtils::rm(p); - _memberChanged(member,nullJson,true); + _memberChanged(member, nullJson, true); std::lock_guard l(this->_online_l); this->_online[networkId].erase(memberId); } -void FileDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch) { - char mid[32],atmp[64]; - OSUtils::ztsnprintf(mid,sizeof(mid),"%.10llx",(unsigned long long)memberId); +void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) +{ + char mid[32], atmp[64]; + OSUtils::ztsnprintf(mid, sizeof(mid), "%.10llx", (unsigned long long)memberId); physicalAddress.toString(atmp); std::lock_guard l(this->_online_l); this->_online[networkId][memberId][OSUtils::now()] = physicalAddress; } -void FileDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) { - this->nodeIsOnline(networkId,memberId,physicalAddress,"unknown/unknown"); + this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/controller/FileDB.hpp b/controller/FileDB.hpp index e45be970e..e10753223 100644 --- a/controller/FileDB.hpp +++ b/controller/FileDB.hpp @@ -16,33 +16,31 @@ #include "DB.hpp" -namespace ZeroTier -{ +namespace ZeroTier { -class FileDB : public DB -{ -public: - FileDB(const char *path); +class FileDB : public DB { + public: + FileDB(const char* path); virtual ~FileDB(); virtual bool waitForReady(); virtual bool isReady(); - virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual bool save(nlohmann::json& record, bool notifyListeners); virtual void eraseNetwork(const uint64_t networkId); - virtual void eraseMember(const uint64_t networkId,const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch); - -protected: + virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); + + protected: std::string _path; std::string _networksPath; std::string _tracePath; std::thread _onlineUpdateThread; - std::map< uint64_t,std::map > > _online; + std::map > > _online; std::mutex _online_l; bool _running; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/controller/LFDB.cpp b/controller/LFDB.cpp index 29fe287e0..77fa8ffe1 100644 --- a/controller/LFDB.cpp +++ b/controller/LFDB.cpp @@ -13,51 +13,52 @@ #include "LFDB.hpp" -#include +#include "../ext/cpp-httplib/httplib.h" +#include "../osdep/OSUtils.hpp" + #include #include #include +#include -#include "../osdep/OSUtils.hpp" -#include "../ext/cpp-httplib/httplib.h" +namespace ZeroTier { -namespace ZeroTier -{ - -LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,const char *lfOwnerPublic,const char *lfNodeHost,int lfNodePort,bool storeOnlineState) : - DB(), - _myId(myId), - _lfOwnerPrivate((lfOwnerPrivate) ? lfOwnerPrivate : ""), - _lfOwnerPublic((lfOwnerPublic) ? lfOwnerPublic : ""), - _lfNodeHost((lfNodeHost) ? lfNodeHost : "127.0.0.1"), - _lfNodePort(((lfNodePort > 0)&&(lfNodePort < 65536)) ? lfNodePort : 9980), - _running(true), - _ready(false), - _storeOnlineState(storeOnlineState) +LFDB::LFDB(const Identity& myId, const char* path, const char* lfOwnerPrivate, const char* lfOwnerPublic, const char* lfNodeHost, int lfNodePort, bool storeOnlineState) + : DB() + , _myId(myId) + , _lfOwnerPrivate((lfOwnerPrivate) ? lfOwnerPrivate : "") + , _lfOwnerPublic((lfOwnerPublic) ? lfOwnerPublic : "") + , _lfNodeHost((lfNodeHost) ? lfNodeHost : "127.0.0.1") + , _lfNodePort(((lfNodePort > 0) && (lfNodePort < 65536)) ? lfNodePort : 9980) + , _running(true) + , _ready(false) + , _storeOnlineState(storeOnlineState) { _syncThread = std::thread([this]() { char controllerAddress[24]; const uint64_t controllerAddressInt = _myId.address().toInt(); _myId.address().toString(controllerAddress); - std::string networksSelectorName("com.zerotier.controller.lfdb:"); networksSelectorName.append(controllerAddress); networksSelectorName.append("/network"); + std::string networksSelectorName("com.zerotier.controller.lfdb:"); + networksSelectorName.append(controllerAddress); + networksSelectorName.append("/network"); // LF record masking key is the first 32 bytes of SHA512(controller private key) in hex, // hiding record values from anything but the controller or someone who has its key. uint8_t sha512pk[64]; _myId.sha512PrivateKey(sha512pk); - char maskingKey [128]; - Utils::hex(sha512pk,32,maskingKey); + char maskingKey[128]; + Utils::hex(sha512pk, 32, maskingKey); - httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort); + httplib::Client htcli(_lfNodeHost.c_str(), _lfNodePort); int64_t timeRangeStart = 0; while (_running.load()) { { std::lock_guard sl(_state_l); - for(auto ns=_state.begin();ns!=_state.end();++ns) { + for (auto ns = _state.begin(); ns != _state.end(); ++ns) { if (ns->second.dirty) { nlohmann::json network; - if (get(ns->first,network)) { - nlohmann::json newrec,selector0; + if (get(ns->first, network)) { + nlohmann::json newrec, selector0; selector0["Name"] = networksSelectorName; selector0["Ordinal"] = ns->first; newrec["Selectors"].push_back(selector0); @@ -66,30 +67,34 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons newrec["MaskingKey"] = maskingKey; newrec["PulseIfUnchanged"] = true; try { - auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); if (resp) { if (resp->status == 200) { ns->second.dirty = false; - //printf("SET network %.16llx %s\n",ns->first,resp->body.c_str()); - } else { - fprintf(stderr,"ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + // printf("SET network %.16llx %s\n",ns->first,resp->body.c_str()); + } + else { + fprintf(stderr, "ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S, resp->status, resp->body.c_str()); } - } else { - fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); } - } catch (std::exception &e) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update network): unknown exception" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); + } + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update network): %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update network): unknown exception" ZT_EOL_S); } } } - for(auto ms=ns->second.members.begin();ms!=ns->second.members.end();++ms) { - if ((_storeOnlineState)&&(ms->second.lastOnlineDirty)&&(ms->second.lastOnlineAddress)) { - nlohmann::json newrec,selector0,selector1,selectors,ip; - char tmp[1024],tmp2[128]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"com.zerotier.controller.lfdb:%s/network/%.16llx/online",controllerAddress,(unsigned long long)ns->first); + for (auto ms = ns->second.members.begin(); ms != ns->second.members.end(); ++ms) { + if ((_storeOnlineState) && (ms->second.lastOnlineDirty) && (ms->second.lastOnlineAddress)) { + nlohmann::json newrec, selector0, selector1, selectors, ip; + char tmp[1024], tmp2[128]; + OSUtils::ztsnprintf(tmp, sizeof(tmp), "com.zerotier.controller.lfdb:%s/network/%.16llx/online", controllerAddress, (unsigned long long)ns->first); ms->second.lastOnlineAddress.toIpString(tmp2); selector0["Name"] = tmp; selector0["Ordinal"] = ms->first; @@ -98,18 +103,18 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons selectors.push_back(selector0); selectors.push_back(selector1); newrec["Selectors"] = selectors; - const uint8_t *const rawip = (const uint8_t *)ms->second.lastOnlineAddress.rawIpData(); - switch(ms->second.lastOnlineAddress.ss_family) { + const uint8_t* const rawip = (const uint8_t*)ms->second.lastOnlineAddress.rawIpData(); + switch (ms->second.lastOnlineAddress.ss_family) { case AF_INET: - for(int j=0;j<4;++j) + for (int j = 0; j < 4; ++j) ip.push_back((unsigned int)rawip[j]); break; case AF_INET6: - for(int j=0;j<16;++j) + for (int j = 0; j < 16; ++j) ip.push_back((unsigned int)rawip[j]); break; default: - ip = tmp2; // should never happen since only IP transport is currently supported + ip = tmp2; // should never happen since only IP transport is currently supported break; } newrec["Value"] = ip; @@ -118,28 +123,32 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons newrec["Timestamp"] = ms->second.lastOnlineTime; newrec["PulseIfUnchanged"] = true; try { - auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); if (resp) { if (resp->status == 200) { ms->second.lastOnlineDirty = false; - //printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); - } else { - fprintf(stderr,"ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + // printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); + } + else { + fprintf(stderr, "ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S, resp->status, resp->body.c_str()); } - } else { - fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); } - } catch (std::exception &e) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member online status): unknown exception" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); + } + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member online status): %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member online status): unknown exception" ZT_EOL_S); } } if (ms->second.dirty) { - nlohmann::json network,member; - if (get(ns->first,network,ms->first,member)) { - nlohmann::json newrec,selector0,selector1,selectors; + nlohmann::json network, member; + if (get(ns->first, network, ms->first, member)) { + nlohmann::json newrec, selector0, selector1, selectors; selector0["Name"] = networksSelectorName; selector0["Ordinal"] = ns->first; selector1["Name"] = "member"; @@ -152,21 +161,25 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons newrec["MaskingKey"] = maskingKey; newrec["PulseIfUnchanged"] = true; try { - auto resp = htcli.Post("/makerecord",newrec.dump(),"application/json"); + auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); if (resp) { if (resp->status == 200) { ms->second.dirty = false; - //printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); - } else { - fprintf(stderr,"ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S,resp->status,resp->body.c_str()); + // printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); + } + else { + fprintf(stderr, "ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S, resp->status, resp->body.c_str()); } - } else { - fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); } - } catch (std::exception &e) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (create/update member): unknown exception" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); + } + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member): %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member): unknown exception" ZT_EOL_S); } } } @@ -176,143 +189,161 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons try { std::ostringstream query; - query << - "{" - "\"Ranges\":[{" - "\"Name\":\"" << networksSelectorName << "\"," - "\"Range\":[0,18446744073709551615]" - "}]," - "\"TimeRange\":[" << timeRangeStart << ",9223372036854775807]," - "\"MaskingKey\":\"" << maskingKey << "\"," - "\"Owners\":[\"" << _lfOwnerPublic << "\"]" - "}"; - auto resp = htcli.Post("/query",query.str(),"application/json"); + query << "{" + "\"Ranges\":[{" + "\"Name\":\"" + << networksSelectorName + << "\"," + "\"Range\":[0,18446744073709551615]" + "}]," + "\"TimeRange\":[" + << timeRangeStart + << ",9223372036854775807]," + "\"MaskingKey\":\"" + << maskingKey + << "\"," + "\"Owners\":[\"" + << _lfOwnerPublic + << "\"]" + "}"; + auto resp = htcli.Post("/query", query.str(), "application/json"); if (resp) { if (resp->status == 200) { nlohmann::json results(OSUtils::jsonParse(resp->body)); - if ((results.is_array())&&(!results.empty())) { - for(std::size_t ri=0;ri> 24) == controllerAddressInt) { // sanity check + if ((id >> 24) == controllerAddressInt) { // sanity check nlohmann::json oldNetwork; - if ((timeRangeStart > 0)&&(get(id,oldNetwork))) { + if ((timeRangeStart > 0) && (get(id, oldNetwork))) { const uint64_t revision = network["revision"]; const uint64_t prevRevision = oldNetwork["revision"]; if (prevRevision < revision) { - _networkChanged(oldNetwork,network,timeRangeStart > 0); + _networkChanged(oldNetwork, network, timeRangeStart > 0); } - } else { - nlohmann::json nullJson; - _networkChanged(nullJson,network,timeRangeStart > 0); } - + else { + nlohmann::json nullJson; + _networkChanged(nullJson, network, timeRangeStart > 0); + } } } } } - } } } - } else { - fprintf(stderr,"ERROR: LFDB: %d from node (check for network updates): %s" ZT_EOL_S,resp->status,resp->body.c_str()); } - } else { - fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: %d from node (check for network updates): %s" ZT_EOL_S, resp->status, resp->body.c_str()); + } } - } catch (std::exception &e) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for network updates): unknown exception" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); + } + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for network updates): %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for network updates): unknown exception" ZT_EOL_S); } try { std::ostringstream query; - query << - "{" - "\"Ranges\":[{" - "\"Name\":\"" << networksSelectorName << "\"," - "\"Range\":[0,18446744073709551615]" - "},{" - "\"Name\":\"member\"," - "\"Range\":[0,18446744073709551615]" - "}]," - "\"TimeRange\":[" << timeRangeStart << ",9223372036854775807]," - "\"MaskingKey\":\"" << maskingKey << "\"," - "\"Owners\":[\"" << _lfOwnerPublic << "\"]" - "}"; - auto resp = htcli.Post("/query",query.str(),"application/json"); + query << "{" + "\"Ranges\":[{" + "\"Name\":\"" + << networksSelectorName + << "\"," + "\"Range\":[0,18446744073709551615]" + "},{" + "\"Name\":\"member\"," + "\"Range\":[0,18446744073709551615]" + "}]," + "\"TimeRange\":[" + << timeRangeStart + << ",9223372036854775807]," + "\"MaskingKey\":\"" + << maskingKey + << "\"," + "\"Owners\":[\"" + << _lfOwnerPublic + << "\"]" + "}"; + auto resp = htcli.Post("/query", query.str(), "application/json"); if (resp) { if (resp->status == 200) { nlohmann::json results(OSUtils::jsonParse(resp->body)); - if ((results.is_array())&&(!results.empty())) { - for(std::size_t ri=0;ri> 24) == controllerAddressInt)) { // sanity check + if ((id) && ((nwid >> 24) == controllerAddressInt)) { // sanity check - nlohmann::json network,oldMember; - if ((timeRangeStart > 0)&&(get(nwid,network,id,oldMember))) { + nlohmann::json network, oldMember; + if ((timeRangeStart > 0) && (get(nwid, network, id, oldMember))) { const uint64_t revision = member["revision"]; const uint64_t prevRevision = oldMember["revision"]; if (prevRevision < revision) - _memberChanged(oldMember,member,timeRangeStart > 0); - } else if (hasNetwork(nwid)) { - nlohmann::json nullJson; - _memberChanged(nullJson,member,timeRangeStart > 0); + _memberChanged(oldMember, member, timeRangeStart > 0); + } + else if (hasNetwork(nwid)) { + nlohmann::json nullJson; + _memberChanged(nullJson, member, timeRangeStart > 0); } - } } } } - } } } - } else { - fprintf(stderr,"ERROR: LFDB: %d from node (check for member updates): %s" ZT_EOL_S,resp->status,resp->body.c_str()); } - } else { - fprintf(stderr,"ERROR: LFDB: node is offline" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: %d from node (check for member updates): %s" ZT_EOL_S, resp->status, resp->body.c_str()); + } } - } catch (std::exception &e) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): %s" ZT_EOL_S,e.what()); - } catch ( ... ) { - fprintf(stderr,"ERROR: LFDB: unexpected exception querying node (check for member updates): unknown exception" ZT_EOL_S); + else { + fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); + } + } + catch (std::exception& e) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for member updates): %s" ZT_EOL_S, e.what()); + } + catch (...) { + fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for member updates): unknown exception" ZT_EOL_S); } - timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates + timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates _ready.store(true); - for(int k=0;k<4;++k) { // 2s delay between queries for remotely modified networks or members - if (!_running.load()) + for (int k = 0; k < 4; ++k) { // 2s delay between queries for remotely modified networks or members + if (! _running.load()) return; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -328,7 +359,7 @@ LFDB::~LFDB() bool LFDB::waitForReady() { - while (!_ready.load()) { + while (! _ready.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } return true; @@ -339,18 +370,18 @@ bool LFDB::isReady() return (_ready.load()); } -bool LFDB::save(nlohmann::json &record,bool notifyListeners) +bool LFDB::save(nlohmann::json& record, bool notifyListeners) { bool modified = false; const std::string objtype = record["objtype"]; if (objtype == "network") { - const uint64_t nwid = OSUtils::jsonIntHex(record["id"],0ULL); + const uint64_t nwid = OSUtils::jsonIntHex(record["id"], 0ULL); if (nwid) { nlohmann::json old; - get(nwid,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _networkChanged(old,record,notifyListeners); + get(nwid, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _networkChanged(old, record, notifyListeners); { std::lock_guard l(_state_l); _state[nwid].dirty = true; @@ -358,15 +389,16 @@ bool LFDB::save(nlohmann::json &record,bool notifyListeners) modified = true; } } - } else if (objtype == "member") { - const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"],0ULL); - const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL); - if ((id)&&(nwid)) { - nlohmann::json network,old; - get(nwid,network,id,old); - if ((!old.is_object())||(!_compareRecords(old,record))) { - record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; - _memberChanged(old,record,notifyListeners); + } + else if (objtype == "member") { + const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"], 0ULL); + const uint64_t id = OSUtils::jsonIntHex(record["id"], 0ULL); + if ((id) && (nwid)) { + nlohmann::json network, old; + get(nwid, network, id, old); + if ((! old.is_object()) || (! _compareRecords(old, record))) { + record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; + _memberChanged(old, record, notifyListeners); { std::lock_guard l(_state_l); _state[nwid].members[id].dirty = true; @@ -383,12 +415,12 @@ void LFDB::eraseNetwork(const uint64_t networkId) // TODO } -void LFDB::eraseMember(const uint64_t networkId,const uint64_t memberId) +void LFDB::eraseMember(const uint64_t networkId, const uint64_t memberId) { // TODO } -void LFDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress,const char *osArch) +void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) { std::lock_guard l(_state_l); auto nw = _state.find(networkId); @@ -403,9 +435,9 @@ void LFDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const I } } -void LFDB::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) +void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) { - this->nodeIsOnline(networkId,memberId,physicalAddress,"unknown/unknown"); + this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/controller/LFDB.hpp b/controller/LFDB.hpp index f4895b494..3632e483f 100644 --- a/controller/LFDB.hpp +++ b/controller/LFDB.hpp @@ -16,19 +16,18 @@ #include "DB.hpp" +#include #include #include #include -#include namespace ZeroTier { /** * DB implementation for controller that stores data in LF */ -class LFDB : public DB -{ -public: +class LFDB : public DB { + public: /** * @param myId This controller's identity * @param path Base path for ZeroTier node itself @@ -38,45 +37,41 @@ public: * @param lfNodePort LF node http (not https) port * @param storeOnlineState If true, store online/offline state and IP info in LF (a lot of data, only for private networks!) */ - LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,const char *lfOwnerPublic,const char *lfNodeHost,int lfNodePort,bool storeOnlineState); + LFDB(const Identity& myId, const char* path, const char* lfOwnerPrivate, const char* lfOwnerPublic, const char* lfNodeHost, int lfNodePort, bool storeOnlineState); virtual ~LFDB(); virtual bool waitForReady(); virtual bool isReady(); - virtual bool save(nlohmann::json &record,bool notifyListeners); + virtual bool save(nlohmann::json& record, bool notifyListeners); virtual void eraseNetwork(const uint64_t networkId); - virtual void eraseMember(const uint64_t networkId,const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress, const char *osArch); - -protected: + virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); + + protected: const Identity _myId; - std::string _lfOwnerPrivate,_lfOwnerPublic; + std::string _lfOwnerPrivate, _lfOwnerPublic; std::string _lfNodeHost; int _lfNodePort; - struct _MemberState - { - _MemberState() : - lastOnlineAddress(), - lastOnlineTime(0), - dirty(false), - lastOnlineDirty(false) {} + struct _MemberState { + _MemberState() : lastOnlineAddress(), lastOnlineTime(0), dirty(false), lastOnlineDirty(false) + { + } InetAddress lastOnlineAddress; int64_t lastOnlineTime; bool dirty; bool lastOnlineDirty; }; - struct _NetworkState - { - _NetworkState() : - members(), - dirty(false) {} - std::unordered_map members; + struct _NetworkState { + _NetworkState() : members(), dirty(false) + { + } + std::unordered_map members; bool dirty; }; - std::unordered_map _state; + std::unordered_map _state; std::mutex _state_l; std::atomic_bool _running; @@ -85,6 +80,6 @@ protected: bool _storeOnlineState; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index 5fa014777..a0ebff793 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -8,48 +8,48 @@ using namespace nlohmann; using namespace ZeroTier; -MemberNotificationReceiver::MemberNotificationReceiver(DB *p, pqxx::connection &c, const std::string &channel) - : pqxx::notification_receiver(c, channel) - , _psql(p) +MemberNotificationReceiver::MemberNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel) : pqxx::notification_receiver(c, channel), _psql(p) { fprintf(stderr, "initialize MemberNotificationReceiver\n"); } - -void MemberNotificationReceiver::operator() (const std::string &payload, int packend_pid) { +void MemberNotificationReceiver::operator()(const std::string& payload, int packend_pid) +{ fprintf(stderr, "Member Notification received: %s\n", payload.c_str()); Metrics::pgsql_mem_notification++; json tmp(json::parse(payload)); - json &ov = tmp["old_val"]; - json &nv = tmp["new_val"]; + json& ov = tmp["old_val"]; + json& nv = tmp["new_val"]; json oldConfig, newConfig; - if (ov.is_object()) oldConfig = ov; - if (nv.is_object()) newConfig = nv; + if (ov.is_object()) + oldConfig = ov; + if (nv.is_object()) + newConfig = nv; if (oldConfig.is_object() || newConfig.is_object()) { - _psql->_memberChanged(oldConfig,newConfig,_psql->isReady()); + _psql->_memberChanged(oldConfig, newConfig, _psql->isReady()); fprintf(stderr, "payload sent\n"); } } - -NetworkNotificationReceiver::NetworkNotificationReceiver(DB *p, pqxx::connection &c, const std::string &channel) - : pqxx::notification_receiver(c, channel) - , _psql(p) +NetworkNotificationReceiver::NetworkNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel) : pqxx::notification_receiver(c, channel), _psql(p) { fprintf(stderr, "initialize NetworkNotificationReceiver\n"); } -void NetworkNotificationReceiver::operator() (const std::string &payload, int packend_pid) { +void NetworkNotificationReceiver::operator()(const std::string& payload, int packend_pid) +{ fprintf(stderr, "Network Notification received: %s\n", payload.c_str()); Metrics::pgsql_net_notification++; json tmp(json::parse(payload)); - json &ov = tmp["old_val"]; - json &nv = tmp["new_val"]; + json& ov = tmp["old_val"]; + json& nv = tmp["new_val"]; json oldConfig, newConfig; - if (ov.is_object()) oldConfig = ov; - if (nv.is_object()) newConfig = nv; + if (ov.is_object()) + oldConfig = ov; + if (nv.is_object()) + newConfig = nv; if (oldConfig.is_object() || newConfig.is_object()) { - _psql->_networkChanged(oldConfig,newConfig,_psql->isReady()); + _psql->_networkChanged(oldConfig, newConfig, _psql->isReady()); fprintf(stderr, "payload sent\n"); } } diff --git a/controller/PostgreSQL.hpp b/controller/PostgreSQL.hpp index 51f9c1848..dc73405f5 100644 --- a/controller/PostgreSQL.hpp +++ b/controller/PostgreSQL.hpp @@ -16,10 +16,11 @@ #ifndef ZT_CONTROLLER_POSTGRESQL_HPP #define ZT_CONTROLLER_POSTGRESQL_HPP -#include "DB.hpp" #include "ConnectionPool.hpp" -#include +#include "DB.hpp" + #include +#include namespace ZeroTier { @@ -27,56 +28,60 @@ extern "C" { typedef struct pg_conn PGconn; } - class PostgresConnection : public Connection { -public: - virtual ~PostgresConnection() { + public: + virtual ~PostgresConnection() + { } std::shared_ptr c; int a; }; - class PostgresConnFactory : public ConnectionFactory { -public: - PostgresConnFactory(std::string &connString) - : m_connString(connString) + public: + PostgresConnFactory(std::string& connString) : m_connString(connString) { } - virtual std::shared_ptr create() { + virtual std::shared_ptr create() + { Metrics::conn_counter++; auto c = std::shared_ptr(new PostgresConnection()); c->c = std::make_shared(m_connString); return std::static_pointer_cast(c); } -private: + + private: std::string m_connString; }; class MemberNotificationReceiver : public pqxx::notification_receiver { -public: - MemberNotificationReceiver(DB *p, pqxx::connection &c, const std::string &channel); - virtual ~MemberNotificationReceiver() { + public: + MemberNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel); + virtual ~MemberNotificationReceiver() + { fprintf(stderr, "MemberNotificationReceiver destroyed\n"); } - virtual void operator() (const std::string &payload, int backendPid); -private: - DB *_psql; + virtual void operator()(const std::string& payload, int backendPid); + + private: + DB* _psql; }; class NetworkNotificationReceiver : public pqxx::notification_receiver { -public: - NetworkNotificationReceiver(DB *p, pqxx::connection &c, const std::string &channel); - virtual ~NetworkNotificationReceiver() { + public: + NetworkNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel); + virtual ~NetworkNotificationReceiver() + { fprintf(stderr, "NetworkNotificationReceiver destroyed\n"); }; - virtual void operator() (const std::string &payload, int packend_pid); -private: - DB *_psql; + virtual void operator()(const std::string& payload, int packend_pid); + + private: + DB* _psql; }; struct NodeOnlineRecord { @@ -85,8 +90,8 @@ struct NodeOnlineRecord { std::string osArch; }; -} // namespace ZeroTier +} // namespace ZeroTier -#endif // ZT_CONTROLLER_POSTGRESQL_HPP +#endif // ZT_CONTROLLER_POSTGRESQL_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file diff --git a/controller/Redis.hpp b/controller/Redis.hpp index 095419b01..c6845d517 100644 --- a/controller/Redis.hpp +++ b/controller/Redis.hpp @@ -5,11 +5,11 @@ namespace ZeroTier { struct RedisConfig { - std::string hostname; - int port; - std::string password; - bool clusterMode; + std::string hostname; + int port; + std::string password; + bool clusterMode; }; -} +} // namespace ZeroTier #endif \ No newline at end of file diff --git a/node/AES.cpp b/node/AES.cpp index 739e88899..1ba6aeeb7 100644 --- a/node/AES.cpp +++ b/node/AES.cpp @@ -11,9 +11,10 @@ */ /****/ -#include "Constants.hpp" #include "AES.hpp" +#include "Constants.hpp" + #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif @@ -31,40 +32,40 @@ namespace ZeroTier { namespace { -#define s_bmul32(N, x, y, rh, rl) \ - uint32_t x0t_##N = (x) & 0x11111111U; \ - uint32_t x1t_##N = (x) & 0x22222222U; \ - uint32_t x2t_##N = (x) & 0x44444444U; \ - uint32_t x3t_##N = (x) & 0x88888888U; \ - uint32_t y0t_##N = (y) & 0x11111111U; \ - uint32_t y1t_##N = (y) & 0x22222222U; \ - uint32_t y2t_##N = (y) & 0x44444444U; \ - uint32_t y3t_##N = (y) & 0x88888888U; \ - uint64_t z0t_##N = (((uint64_t)x0t_##N * y0t_##N) ^ ((uint64_t)x1t_##N * y3t_##N) ^ ((uint64_t)x2t_##N * y2t_##N) ^ ((uint64_t)x3t_##N * y1t_##N)) & 0x1111111111111111ULL; \ - uint64_t z1t_##N = (((uint64_t)x0t_##N * y1t_##N) ^ ((uint64_t)x1t_##N * y0t_##N) ^ ((uint64_t)x2t_##N * y3t_##N) ^ ((uint64_t)x3t_##N * y2t_##N)) & 0x2222222222222222ULL; \ - uint64_t z2t_##N = (((uint64_t)x0t_##N * y2t_##N) ^ ((uint64_t)x1t_##N * y1t_##N) ^ ((uint64_t)x2t_##N * y0t_##N) ^ ((uint64_t)x3t_##N * y3t_##N)) & 0x4444444444444444ULL; \ - z0t_##N |= z1t_##N; \ - z2t_##N |= z0t_##N; \ - uint64_t zt_##N = z2t_##N | ((((uint64_t)x0t_##N * y3t_##N) ^ ((uint64_t)x1t_##N * y2t_##N) ^ ((uint64_t)x2t_##N * y1t_##N) ^ ((uint64_t)x3t_##N * y0t_##N)) & 0x8888888888888888ULL); \ - (rh) = (uint32_t)(zt_##N >> 32U); \ +#define s_bmul32(N, x, y, rh, rl) \ + uint32_t x0t_##N = (x) & 0x11111111U; \ + uint32_t x1t_##N = (x) & 0x22222222U; \ + uint32_t x2t_##N = (x) & 0x44444444U; \ + uint32_t x3t_##N = (x) & 0x88888888U; \ + uint32_t y0t_##N = (y) & 0x11111111U; \ + uint32_t y1t_##N = (y) & 0x22222222U; \ + uint32_t y2t_##N = (y) & 0x44444444U; \ + uint32_t y3t_##N = (y) & 0x88888888U; \ + uint64_t z0t_##N = (((uint64_t)x0t_##N * y0t_##N) ^ ((uint64_t)x1t_##N * y3t_##N) ^ ((uint64_t)x2t_##N * y2t_##N) ^ ((uint64_t)x3t_##N * y1t_##N)) & 0x1111111111111111ULL; \ + uint64_t z1t_##N = (((uint64_t)x0t_##N * y1t_##N) ^ ((uint64_t)x1t_##N * y0t_##N) ^ ((uint64_t)x2t_##N * y3t_##N) ^ ((uint64_t)x3t_##N * y2t_##N)) & 0x2222222222222222ULL; \ + uint64_t z2t_##N = (((uint64_t)x0t_##N * y2t_##N) ^ ((uint64_t)x1t_##N * y1t_##N) ^ ((uint64_t)x2t_##N * y0t_##N) ^ ((uint64_t)x3t_##N * y3t_##N)) & 0x4444444444444444ULL; \ + z0t_##N |= z1t_##N; \ + z2t_##N |= z0t_##N; \ + uint64_t zt_##N = z2t_##N | ((((uint64_t)x0t_##N * y3t_##N) ^ ((uint64_t)x1t_##N * y2t_##N) ^ ((uint64_t)x2t_##N * y1t_##N) ^ ((uint64_t)x3t_##N * y0t_##N)) & 0x8888888888888888ULL); \ + (rh) = (uint32_t)(zt_##N >> 32U); \ (rl) = (uint32_t)zt_##N; -void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t &y0, uint64_t &y1) noexcept +void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t& y0, uint64_t& y1) noexcept { uint32_t hhh = (uint32_t)(hh >> 32U); uint32_t hhl = (uint32_t)hh; uint32_t hlh = (uint32_t)(hl >> 32U); uint32_t hll = (uint32_t)hl; - uint32_t hhXlh = hhh ^hlh; - uint32_t hhXll = hhl ^hll; + uint32_t hhXlh = hhh ^ hlh; + uint32_t hhXll = hhl ^ hll; uint64_t yl = Utils::ntoh(y0); uint64_t yh = Utils::ntoh(y1); uint32_t cilh = (uint32_t)(yh >> 32U); uint32_t cill = (uint32_t)yh; uint32_t cihh = (uint32_t)(yl >> 32U); uint32_t cihl = (uint32_t)yl; - uint32_t cihXlh = cihh ^cilh; - uint32_t cihXll = cihl ^cill; + uint32_t cihXlh = cihh ^ cilh; + uint32_t cihXll = cihl ^ cill; uint32_t aah, aal, abh, abl, ach, acl; s_bmul32(M0, cihh, hhh, aah, aal); s_bmul32(M1, cihl, hhl, abh, abl); @@ -94,8 +95,8 @@ void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t &y0, uint64_t &y1) n cbh ^= bbh ^ abh; cbl ^= bbl ^ abl; uint64_t zhh = ((uint64_t)aah << 32U) | aal; - uint64_t zhl = (((uint64_t)abh << 32U) | abl) ^(((uint64_t)cah << 32U) | cal); - uint64_t zlh = (((uint64_t)bah << 32U) | bal) ^(((uint64_t)cbh << 32U) | cbl); + uint64_t zhl = (((uint64_t)abh << 32U) | abl) ^ (((uint64_t)cah << 32U) | cal); + uint64_t zlh = (((uint64_t)bah << 32U) | bal) ^ (((uint64_t)cbh << 32U) | cbl); uint64_t zll = ((uint64_t)bbh << 32U) | bbl; zhh = zhh << 1U | zhl >> 63U; zhl = zhl << 1U | zlh >> 63U; @@ -108,11 +109,11 @@ void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t &y0, uint64_t &y1) n y1 = Utils::hton(zhl); } -} // anonymous namespace +} // anonymous namespace -void AES::GMAC::update(const void *const data, unsigned int len) noexcept +void AES::GMAC::update(const void* const data, unsigned int len) noexcept { - const uint8_t *in = reinterpret_cast(data); + const uint8_t* in = reinterpret_cast(data); _len += len; #ifdef ZT_AES_AESNI @@ -120,14 +121,14 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept p_aesNIUpdate(in, len); return; } -#endif // ZT_AES_AESNI +#endif // ZT_AES_AESNI #ifdef ZT_AES_NEON if (Utils::ARMCAP.pmull) { p_armUpdate(in, len); return; } -#endif // ZT_AES_NEON +#endif // ZT_AES_NEON const uint64_t h0 = _aes.p_k.sw.h[0]; const uint64_t h1 = _aes.p_k.sw.h[1]; @@ -136,14 +137,14 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept if (_rp) { for (;;) { - if (!len) { + if (! len) { return; } --len; _r[_rp++] = *(in++); if (_rp == 16) { - y0 ^= Utils::loadMachineEndian< uint64_t >(_r); - y1 ^= Utils::loadMachineEndian< uint64_t >(_r + 8); + y0 ^= Utils::loadMachineEndian(_r); + y1 ^= Utils::loadMachineEndian(_r + 8); s_gfmul(h0, h1, y0, y1); break; } @@ -151,8 +152,8 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept } while (len >= 16) { - y0 ^= Utils::loadMachineEndian< uint64_t >(in); - y1 ^= Utils::loadMachineEndian< uint64_t >(in + 8); + y0 ^= Utils::loadMachineEndian(in); + y1 ^= Utils::loadMachineEndian(in + 8); in += 16; s_gfmul(h0, h1, y0, y1); len -= 16; @@ -164,7 +165,7 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept for (unsigned int i = 0; i < len; ++i) { _r[i] = in[i]; } - _rp = len; // len is always less than 16 here + _rp = len; // len is always less than 16 here } void AES::GMAC::finish(uint8_t tag[16]) noexcept @@ -174,14 +175,14 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept p_aesNIFinish(tag); return; } -#endif // ZT_AES_AESNI +#endif // ZT_AES_AESNI #ifdef ZT_AES_NEON if (Utils::ARMCAP.pmull) { p_armFinish(tag); return; } -#endif // ZT_AES_NEON +#endif // ZT_AES_NEON const uint64_t h0 = _aes.p_k.sw.h[0]; const uint64_t h1 = _aes.p_k.sw.h[1]; @@ -192,8 +193,8 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept while (_rp < 16) { _r[_rp++] = 0; } - y0 ^= Utils::loadMachineEndian< uint64_t >(_r); - y1 ^= Utils::loadMachineEndian< uint64_t >(_r + 8); + y0 ^= Utils::loadMachineEndian(_r); + y1 ^= Utils::loadMachineEndian(_r + 8); s_gfmul(h0, h1, y0, y1); } @@ -201,57 +202,57 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept s_gfmul(h0, h1, y0, y1); uint64_t iv2[2]; - Utils::copy< 12 >(iv2, _iv); + Utils::copy<12>(iv2, _iv); #if __BYTE_ORDER == __BIG_ENDIAN - reinterpret_cast(iv2)[3] = 0x00000001; + reinterpret_cast(iv2)[3] = 0x00000001; #else - reinterpret_cast(iv2)[3] = 0x01000000; + reinterpret_cast(iv2)[3] = 0x01000000; #endif _aes.encrypt(iv2, iv2); - Utils::storeMachineEndian< uint64_t >(tag, iv2[0] ^ y0); - Utils::storeMachineEndian< uint64_t >(tag + 8, iv2[1] ^ y1); + Utils::storeMachineEndian(tag, iv2[0] ^ y0); + Utils::storeMachineEndian(tag + 8, iv2[1] ^ y1); } // AES-CTR ------------------------------------------------------------------------------------------------------------ -void AES::CTR::crypt(const void *const input, unsigned int len) noexcept +void AES::CTR::crypt(const void* const input, unsigned int len) noexcept { - const uint8_t *in = reinterpret_cast(input); - uint8_t *out = _out; + const uint8_t* in = reinterpret_cast(input); + uint8_t* out = _out; #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { p_aesNICrypt(in, out, len); return; } -#endif // ZT_AES_AESNI +#endif // ZT_AES_AESNI #ifdef ZT_AES_NEON if (Utils::ARMCAP.aes) { p_armCrypt(in, out, len); return; } -#endif // ZT_AES_NEON +#endif // ZT_AES_NEON uint64_t keyStream[2]; - uint32_t ctr = Utils::ntoh(reinterpret_cast(_ctr)[3]); + uint32_t ctr = Utils::ntoh(reinterpret_cast(_ctr)[3]); unsigned int totalLen = _len; if ((totalLen & 15U)) { for (;;) { - if (!len) { + if (! len) { _len = (totalLen + len); return; } --len; out[totalLen++] = *(in++); - if (!(totalLen & 15U)) { - _aes.p_encryptSW(reinterpret_cast(_ctr), reinterpret_cast(keyStream)); - reinterpret_cast(_ctr)[3] = Utils::hton(++ctr); - uint8_t *outblk = out + (totalLen - 16); + if (! (totalLen & 15U)) { + _aes.p_encryptSW(reinterpret_cast(_ctr), reinterpret_cast(keyStream)); + reinterpret_cast(_ctr)[3] = Utils::hton(++ctr); + uint8_t* outblk = out + (totalLen - 16); for (int i = 0; i < 16; ++i) { - outblk[i] ^= reinterpret_cast(keyStream)[i]; + outblk[i] ^= reinterpret_cast(keyStream)[i]; } break; } @@ -262,10 +263,10 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept _len = (totalLen + len); if (likely(len >= 16)) { - const uint32_t *const restrict rk = _aes.p_k.sw.ek; - const uint32_t ctr0rk0 = Utils::ntoh(reinterpret_cast(_ctr)[0]) ^rk[0]; - const uint32_t ctr1rk1 = Utils::ntoh(reinterpret_cast(_ctr)[1]) ^rk[1]; - const uint32_t ctr2rk2 = Utils::ntoh(reinterpret_cast(_ctr)[2]) ^rk[2]; + const uint32_t* const restrict rk = _aes.p_k.sw.ek; + const uint32_t ctr0rk0 = Utils::ntoh(reinterpret_cast(_ctr)[0]) ^ rk[0]; + const uint32_t ctr1rk1 = Utils::ntoh(reinterpret_cast(_ctr)[1]) ^ rk[1]; + const uint32_t ctr2rk2 = Utils::ntoh(reinterpret_cast(_ctr)[2]) ^ rk[2]; const uint32_t m8 = 0x000000ff; const uint32_t m8_8 = 0x0000ff00; const uint32_t m8_16 = 0x00ff0000; @@ -278,8 +279,8 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept s2 = ctr2rk2; s3 = ctr++ ^ rk[3]; - const uint64_t in0 = *reinterpret_cast(in); - const uint64_t in1 = *reinterpret_cast(in + 8); + const uint64_t in0 = *reinterpret_cast(in); + const uint64_t in1 = *reinterpret_cast(in + 8); in += 16; t0 = Te0[s0 >> 24U] ^ Te1_r((s1 >> 16U) & m8) ^ Te2_r((s2 >> 8U) & m8) ^ Te3_r(s3 & m8) ^ rk[4]; @@ -339,11 +340,12 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8) ^ (Te1_r(t1 & m8) & m8) ^ rk[58]; s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8) ^ (Te1_r(t2 & m8) & m8) ^ rk[59]; - *reinterpret_cast(out) = in0 ^ Utils::hton(((uint64_t)s0 << 32U) | (uint64_t)s1); - *reinterpret_cast(out + 8) = in1 ^ Utils::hton(((uint64_t)s2 << 32U) | (uint64_t)s3); + *reinterpret_cast(out) = in0 ^ Utils::hton(((uint64_t)s0 << 32U) | (uint64_t)s1); + *reinterpret_cast(out + 8) = in1 ^ Utils::hton(((uint64_t)s2 << 32U) | (uint64_t)s3); out += 16; } while ((len -= 16) >= 16); - } else { + } + else { do { uint32_t s0, s1, s2, s3, t0, t1, t2, t3; s0 = ctr0rk0; @@ -428,7 +430,7 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept in += 16; } while ((len -= 16) >= 16); } - reinterpret_cast(_ctr)[3] = Utils::hton(ctr); + reinterpret_cast(_ctr)[3] = Utils::hton(ctr); } // Any remaining input is placed in _out. This will be picked up and crypted @@ -454,48 +456,76 @@ void AES::CTR::finish() noexcept // Software AES and AES key expansion --------------------------------------------------------------------------------- -const uint32_t AES::Te0[256] = {0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, - 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, - 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, - 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, - 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, - 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, - 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, - 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a}; -const uint32_t AES::Te4[256] = {0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171, 0xd8d8d8d8, 0x31313131, - 0x15151515, 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, - 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, - 0xa8a8a8a8, 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, - 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4, - 0x79797979, 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, - 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828, - 0xdfdfdfdf, 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616}; -const uint32_t AES::Td0[256] = {0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, - 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, - 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, - 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, - 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, - 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, - 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, - 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742}; -const uint8_t AES::Td4[256] = {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, - 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, - 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; -const uint32_t AES::rcon[15] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000}; +const uint32_t AES::Te0[256] = { 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a }; +const uint32_t AES::Te4[256] = { 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, + 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, + 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515, + 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, + 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, + 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, + 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, + 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, + 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, + 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, + 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, + 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, + 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, + 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, + 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, + 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616 }; +const uint32_t AES::Td0[256] = { 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 }; +const uint8_t AES::Td4[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; +const uint32_t AES::rcon[15] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000 }; -void AES::p_initSW(const uint8_t *key) noexcept +void AES::p_initSW(const uint8_t* key) noexcept { - uint32_t *rk = p_k.sw.ek; + uint32_t* rk = p_k.sw.ek; - rk[0] = Utils::loadBigEndian< uint32_t >(key); - rk[1] = Utils::loadBigEndian< uint32_t >(key + 4); - rk[2] = Utils::loadBigEndian< uint32_t >(key + 8); - rk[3] = Utils::loadBigEndian< uint32_t >(key + 12); - rk[4] = Utils::loadBigEndian< uint32_t >(key + 16); - rk[5] = Utils::loadBigEndian< uint32_t >(key + 20); - rk[6] = Utils::loadBigEndian< uint32_t >(key + 24); - rk[7] = Utils::loadBigEndian< uint32_t >(key + 28); + rk[0] = Utils::loadBigEndian(key); + rk[1] = Utils::loadBigEndian(key + 4); + rk[2] = Utils::loadBigEndian(key + 8); + rk[3] = Utils::loadBigEndian(key + 12); + rk[4] = Utils::loadBigEndian(key + 16); + rk[5] = Utils::loadBigEndian(key + 20); + rk[6] = Utils::loadBigEndian(key + 24); + rk[7] = Utils::loadBigEndian(key + 28); for (int i = 0;;) { uint32_t temp = rk[7]; rk[8] = rk[0] ^ (Te2_r((temp >> 16U) & 0xffU) & 0xff000000U) ^ (Te3_r((temp >> 8U) & 0xffU) & 0x00ff0000U) ^ (Te0[(temp) & 0xffU] & 0x0000ff00U) ^ (Te1_r(temp >> 24U) & 0x000000ffU) ^ rcon[i]; @@ -513,7 +543,7 @@ void AES::p_initSW(const uint8_t *key) noexcept rk += 8; } - p_encryptSW((const uint8_t *)Utils::ZERO256, (uint8_t *)p_k.sw.h); + p_encryptSW((const uint8_t*)Utils::ZERO256, (uint8_t*)p_k.sw.h); p_k.sw.h[0] = Utils::ntoh(p_k.sw.h[0]); p_k.sw.h[1] = Utils::ntoh(p_k.sw.h[1]); @@ -545,17 +575,17 @@ void AES::p_initSW(const uint8_t *key) noexcept } } -void AES::p_encryptSW(const uint8_t *in, uint8_t *out) const noexcept +void AES::p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept { - const uint32_t *const restrict rk = p_k.sw.ek; + const uint32_t* const restrict rk = p_k.sw.ek; const uint32_t m8 = 0x000000ff; const uint32_t m8_8 = 0x0000ff00; const uint32_t m8_16 = 0x00ff0000; const uint32_t m8_24 = 0xff000000; - uint32_t s0 = Utils::loadBigEndian< uint32_t >(in) ^rk[0]; - uint32_t s1 = Utils::loadBigEndian< uint32_t >(in + 4) ^rk[1]; - uint32_t s2 = Utils::loadBigEndian< uint32_t >(in + 8) ^rk[2]; - uint32_t s3 = Utils::loadBigEndian< uint32_t >(in + 12) ^rk[3]; + uint32_t s0 = Utils::loadBigEndian(in) ^ rk[0]; + uint32_t s1 = Utils::loadBigEndian(in + 4) ^ rk[1]; + uint32_t s2 = Utils::loadBigEndian(in + 8) ^ rk[2]; + uint32_t s3 = Utils::loadBigEndian(in + 12) ^ rk[3]; uint32_t t0, t1, t2, t3; t0 = Te0[s0 >> 24U] ^ Te1_r((s1 >> 16U) & m8) ^ Te2_r((s2 >> 8U) & m8) ^ Te3_r(s3 & m8) ^ rk[4]; @@ -615,20 +645,20 @@ void AES::p_encryptSW(const uint8_t *in, uint8_t *out) const noexcept s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8) ^ (Te1_r(t1 & m8) & m8) ^ rk[58]; s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8) ^ (Te1_r(t2 & m8) & m8) ^ rk[59]; - Utils::storeBigEndian< uint32_t >(out, s0); - Utils::storeBigEndian< uint32_t >(out + 4, s1); - Utils::storeBigEndian< uint32_t >(out + 8, s2); - Utils::storeBigEndian< uint32_t >(out + 12, s3); + Utils::storeBigEndian(out, s0); + Utils::storeBigEndian(out + 4, s1); + Utils::storeBigEndian(out + 8, s2); + Utils::storeBigEndian(out + 12, s3); } -void AES::p_decryptSW(const uint8_t *in, uint8_t *out) const noexcept +void AES::p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept { - const uint32_t *restrict rk = p_k.sw.dk; + const uint32_t* restrict rk = p_k.sw.dk; const uint32_t m8 = 0x000000ff; - uint32_t s0 = Utils::loadBigEndian< uint32_t >(in) ^rk[0]; - uint32_t s1 = Utils::loadBigEndian< uint32_t >(in + 4) ^rk[1]; - uint32_t s2 = Utils::loadBigEndian< uint32_t >(in + 8) ^rk[2]; - uint32_t s3 = Utils::loadBigEndian< uint32_t >(in + 12) ^rk[3]; + uint32_t s0 = Utils::loadBigEndian(in) ^ rk[0]; + uint32_t s1 = Utils::loadBigEndian(in + 4) ^ rk[1]; + uint32_t s2 = Utils::loadBigEndian(in + 8) ^ rk[2]; + uint32_t s3 = Utils::loadBigEndian(in + 12) ^ rk[3]; uint32_t t0, t1, t2, t3; t0 = Td0[s0 >> 24U] ^ Td1_r((s3 >> 16U) & m8) ^ Td2_r((s2 >> 8U) & m8) ^ Td3_r(s1 & m8) ^ rk[4]; @@ -683,15 +713,15 @@ void AES::p_decryptSW(const uint8_t *in, uint8_t *out) const noexcept t1 = Td0[s1 >> 24U] ^ Td1_r((s0 >> 16U) & m8) ^ Td2_r((s3 >> 8U) & m8) ^ Td3_r(s2 & m8) ^ rk[53]; t2 = Td0[s2 >> 24U] ^ Td1_r((s1 >> 16U) & m8) ^ Td2_r((s0 >> 8U) & m8) ^ Td3_r(s3 & m8) ^ rk[54]; t3 = Td0[s3 >> 24U] ^ Td1_r((s2 >> 16U) & m8) ^ Td2_r((s1 >> 8U) & m8) ^ Td3_r(s0 & m8) ^ rk[55]; - s0 = (Td4[t0 >> 24U] << 24U) ^ (Td4[(t3 >> 16U) & m8] << 16U) ^ (Td4[(t2 >> 8U) & m8] << 8U) ^ (Td4[(t1) & m8]) ^ rk[56]; - s1 = (Td4[t1 >> 24U] << 24U) ^ (Td4[(t0 >> 16U) & m8] << 16U) ^ (Td4[(t3 >> 8U) & m8] << 8U) ^ (Td4[(t2) & m8]) ^ rk[57]; - s2 = (Td4[t2 >> 24U] << 24U) ^ (Td4[(t1 >> 16U) & m8] << 16U) ^ (Td4[(t0 >> 8U) & m8] << 8U) ^ (Td4[(t3) & m8]) ^ rk[58]; - s3 = (Td4[t3 >> 24U] << 24U) ^ (Td4[(t2 >> 16U) & m8] << 16U) ^ (Td4[(t1 >> 8U) & m8] << 8U) ^ (Td4[(t0) & m8]) ^ rk[59]; + s0 = (Td4[t0 >> 24U] << 24U) ^ (Td4[(t3 >> 16U) & m8] << 16U) ^ (Td4[(t2 >> 8U) & m8] << 8U) ^ (Td4[(t1)&m8]) ^ rk[56]; + s1 = (Td4[t1 >> 24U] << 24U) ^ (Td4[(t0 >> 16U) & m8] << 16U) ^ (Td4[(t3 >> 8U) & m8] << 8U) ^ (Td4[(t2)&m8]) ^ rk[57]; + s2 = (Td4[t2 >> 24U] << 24U) ^ (Td4[(t1 >> 16U) & m8] << 16U) ^ (Td4[(t0 >> 8U) & m8] << 8U) ^ (Td4[(t3)&m8]) ^ rk[58]; + s3 = (Td4[t3 >> 24U] << 24U) ^ (Td4[(t2 >> 16U) & m8] << 16U) ^ (Td4[(t1 >> 8U) & m8] << 8U) ^ (Td4[(t0)&m8]) ^ rk[59]; - Utils::storeBigEndian< uint32_t >(out, s0); - Utils::storeBigEndian< uint32_t >(out + 4, s1); - Utils::storeBigEndian< uint32_t >(out + 8, s2); - Utils::storeBigEndian< uint32_t >(out + 12, s3); + Utils::storeBigEndian(out, s0); + Utils::storeBigEndian(out + 4, s1); + Utils::storeBigEndian(out + 8, s2); + Utils::storeBigEndian(out + 12, s3); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/AES.hpp b/node/AES.hpp index 70a688412..cb4ca23f5 100644 --- a/node/AES.hpp +++ b/node/AES.hpp @@ -15,16 +15,16 @@ #define ZT_AES_HPP #include "Constants.hpp" -#include "Utils.hpp" #include "SHA512.hpp" +#include "Utils.hpp" // Uncomment to disable all hardware acceleration (usually for testing) -//#define ZT_AES_NO_ACCEL +// #define ZT_AES_NO_ACCEL -#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64) +#if ! defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64) #define ZT_AES_AESNI 1 #endif -#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_ARM_HAS_NEON) && defined(ZT_ARCH_ARM_HAS_CRYPTO) +#if ! defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_ARM_HAS_NEON) && defined(ZT_ARCH_ARM_HAS_CRYPTO) #define ZT_AES_NEON 1 #endif @@ -40,9 +40,8 @@ namespace ZeroTier { * This includes hardware acceleration for certain processors. The software * mode is fallback and is significantly slower. */ -class AES -{ -public: +class AES { + public: /** * @return True if this system has hardware AES acceleration */ @@ -63,39 +62,44 @@ public: * Create an un-initialized AES instance (must call init() before use) */ ZT_INLINE AES() noexcept - {} + { + } /** * Create an AES instance with the given key * * @param key 256-bit key */ - explicit ZT_INLINE AES(const void *const key) noexcept - { this->init(key); } + explicit ZT_INLINE AES(const void* const key) noexcept + { + this->init(key); + } ZT_INLINE ~AES() - { Utils::burn(&p_k, sizeof(p_k)); } + { + Utils::burn(&p_k, sizeof(p_k)); + } /** * Set (or re-set) this AES256 cipher's key * * @param key 256-bit / 32-byte key */ - ZT_INLINE void init(const void *const key) noexcept + ZT_INLINE void init(const void* const key) noexcept { #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { - p_init_aesni(reinterpret_cast(key)); + p_init_aesni(reinterpret_cast(key)); return; } #endif #ifdef ZT_AES_NEON if (Utils::ARMCAP.aes) { - p_init_armneon_crypto(reinterpret_cast(key)); + p_init_armneon_crypto(reinterpret_cast(key)); return; } #endif - p_initSW(reinterpret_cast(key)); + p_initSW(reinterpret_cast(key)); } /** @@ -104,7 +108,7 @@ public: * @param in Input block * @param out Output block (can be same as input) */ - ZT_INLINE void encrypt(const void *const in, void *const out) const noexcept + ZT_INLINE void encrypt(const void* const in, void* const out) const noexcept { #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { @@ -118,7 +122,7 @@ public: return; } #endif - p_encryptSW(reinterpret_cast(in), reinterpret_cast(out)); + p_encryptSW(reinterpret_cast(in), reinterpret_cast(out)); } /** @@ -127,7 +131,7 @@ public: * @param in Input block * @param out Output block (can be same as input) */ - ZT_INLINE void decrypt(const void *const in, void *const out) const noexcept + ZT_INLINE void decrypt(const void* const in, void* const out) const noexcept { #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { @@ -141,7 +145,7 @@ public: return; } #endif - p_decryptSW(reinterpret_cast(in), reinterpret_cast(out)); + p_decryptSW(reinterpret_cast(in), reinterpret_cast(out)); } class GMACSIVEncryptor; @@ -150,12 +154,11 @@ public: /** * Streaming GMAC calculator */ - class GMAC - { + class GMAC { friend class GMACSIVEncryptor; friend class GMACSIVDecryptor; - public: + public: /** * @return True if this system has hardware GMAC acceleration */ @@ -177,8 +180,9 @@ public: * * @param aes Keyed AES instance to use */ - ZT_INLINE GMAC(const AES &aes) : _aes(aes) - {} + ZT_INLINE GMAC(const AES& aes) : _aes(aes) + { + } /** * Reset and initialize for a new GMAC calculation @@ -192,12 +196,12 @@ public: // We fill the least significant 32 bits in the _iv field with 1 since in GCM mode // this would hold the counter, but we're not doing GCM. The counter is therefore // always 1. -#ifdef ZT_AES_AESNI // also implies an x64 processor - *reinterpret_cast(_iv) = *reinterpret_cast(iv); - *reinterpret_cast(_iv + 8) = *reinterpret_cast(iv + 8); - *reinterpret_cast(_iv + 12) = 0x01000000; // 0x00000001 in big-endian byte order +#ifdef ZT_AES_AESNI // also implies an x64 processor + *reinterpret_cast(_iv) = *reinterpret_cast(iv); + *reinterpret_cast(_iv + 8) = *reinterpret_cast(iv + 8); + *reinterpret_cast(_iv + 12) = 0x01000000; // 0x00000001 in big-endian byte order #else - for(int i=0;i<12;++i) { + for (int i = 0; i < 12; ++i) { _iv[i] = iv[i]; } _iv[12] = 0; @@ -215,7 +219,7 @@ public: * @param data Bytes to process * @param len Length of input */ - void update(const void *data, unsigned int len) noexcept; + void update(const void* data, unsigned int len) noexcept; /** * Process any remaining cached bytes and generate tag @@ -226,19 +230,19 @@ public: */ void finish(uint8_t tag[16]) noexcept; - private: + private: #ifdef ZT_AES_AESNI - void p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept; + void p_aesNIUpdate(const uint8_t* in, unsigned int len) noexcept; void p_aesNIFinish(uint8_t tag[16]) noexcept; #endif #ifdef ZT_AES_NEON - void p_armUpdate(const uint8_t *in, unsigned int len) noexcept; + void p_armUpdate(const uint8_t* in, unsigned int len) noexcept; void p_armFinish(uint8_t tag[16]) noexcept; #endif - const AES &_aes; + const AES& _aes; unsigned int _rp; unsigned int _len; - uint8_t _r[16]; // remainder + uint8_t _r[16]; // remainder uint8_t _iv[16]; uint64_t _y[2]; }; @@ -249,14 +253,14 @@ public: * NOTE: this doesn't support overflow of the counter in the least significant 32 bits. * AES-GMAC-CTR doesn't need this, so we don't support it as an optimization. */ - class CTR - { + class CTR { friend class GMACSIVEncryptor; friend class GMACSIVDecryptor; - public: - ZT_INLINE CTR(const AES &aes) noexcept: _aes(aes) - {} + public: + ZT_INLINE CTR(const AES& aes) noexcept : _aes(aes) + { + } /** * Initialize this CTR instance to encrypt a new stream @@ -264,10 +268,10 @@ public: * @param iv Unique initialization vector and initial 32-bit counter (least significant 32 bits, big-endian) * @param output Buffer to which to store output (MUST be large enough for total bytes processed!) */ - ZT_INLINE void init(const uint8_t iv[16], void *const output) noexcept + ZT_INLINE void init(const uint8_t iv[16], void* const output) noexcept { - Utils::copy< 16 >(_ctr, iv); - _out = reinterpret_cast(output); + Utils::copy<16>(_ctr, iv); + _out = reinterpret_cast(output); _len = 0; } @@ -278,11 +282,11 @@ public: * @param ic Initial counter (must be in big-endian byte order!) * @param output Buffer to which to store output (MUST be large enough for total bytes processed!) */ - ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void *const output) noexcept + ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void* const output) noexcept { - Utils::copy< 12 >(_ctr, iv); - reinterpret_cast(_ctr)[3] = ic; - _out = reinterpret_cast(output); + Utils::copy<12>(_ctr, iv); + reinterpret_cast(_ctr)[3] = ic; + _out = reinterpret_cast(output); _len = 0; } @@ -292,7 +296,7 @@ public: * @param input Input data * @param len Length of input */ - void crypt(const void *input, unsigned int len) noexcept; + void crypt(const void* input, unsigned int len) noexcept; /** * Finish any remaining bytes if total bytes processed wasn't a multiple of 16 @@ -301,16 +305,16 @@ public: */ void finish() noexcept; - private: + private: #ifdef ZT_AES_AESNI - void p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept; + void p_aesNICrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept; #endif #ifdef ZT_AES_NEON - void p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept; + void p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept; #endif - const AES &_aes; + const AES& _aes; uint64_t _ctr[2]; - uint8_t *_out; + uint8_t* _out; unsigned int _len; }; @@ -325,19 +329,19 @@ public: * This supports encryption of a maximum of 2^31 bytes of data per * call to init(). */ - class GMACSIVEncryptor - { - public: + class GMACSIVEncryptor { + public: /** * Create a new AES-GMAC-SIV encryptor keyed with the provided AES instances * * @param k0 First of two AES instances keyed with K0 * @param k1 Second of two AES instances keyed with K1 */ - ZT_INLINE GMACSIVEncryptor(const AES &k0, const AES &k1) noexcept : - _gmac(k0), - _ctr(k1) - {} + ZT_INLINE GMACSIVEncryptor(const AES& k0, const AES& k1) noexcept + : _gmac(k0) + , _ctr(k1) + { + } /** * Initialize AES-GMAC-SIV @@ -345,7 +349,7 @@ public: * @param iv IV in network byte order (byte order in which it will appear on the wire) * @param output Pointer to buffer to receive ciphertext, must be large enough for all to-be-processed data! */ - ZT_INLINE void init(const uint64_t iv, void *const output) noexcept + ZT_INLINE void init(const uint64_t iv, void* const output) noexcept { // Output buffer to receive the result of AES-CTR encryption. _output = output; @@ -353,7 +357,7 @@ public: // Initialize GMAC with 64-bit IV (and remaining 32 bits padded to zero). _tag[0] = iv; _tag[1] = 0; - _gmac.init(reinterpret_cast(_tag)); + _gmac.init(reinterpret_cast(_tag)); } /** @@ -367,7 +371,7 @@ public: * @param aad Additional authenticated data * @param len Length of AAD in bytes */ - ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept + ZT_INLINE void aad(const void* const aad, unsigned int len) noexcept { // Feed ADD into GMAC first _gmac.update(aad, len); @@ -385,8 +389,10 @@ public: * @param input Plaintext chunk * @param len Length of plaintext chunk */ - ZT_INLINE void update1(const void *const input, const unsigned int len) noexcept - { _gmac.update(input, len); } + ZT_INLINE void update1(const void* const input, const unsigned int len) noexcept + { + _gmac.update(input, len); + } /** * Finish first pass, compute CTR IV, initialize second pass. @@ -395,7 +401,7 @@ public: { // Compute 128-bit GMAC tag. uint64_t tmp[2]; - _gmac.finish(reinterpret_cast(tmp)); + _gmac.finish(reinterpret_cast(tmp)); // Shorten to 64 bits, concatenate with message IV, and encrypt with AES to // yield the CTR IV and opaque IV/MAC blob. In ZeroTier's use of GMAC-SIV @@ -415,7 +421,7 @@ public: // and so 2^31 should be considered the input limit. tmp[0] = _tag[0]; tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL); - _ctr.init(reinterpret_cast(tmp), _output); + _ctr.init(reinterpret_cast(tmp), _output); } /** @@ -427,8 +433,10 @@ public: * @param input Plaintext chunk * @param len Length of plaintext chunk */ - ZT_INLINE void update2(const void *const input, const unsigned int len) noexcept - { _ctr.crypt(input, len); } + ZT_INLINE void update2(const void* const input, const unsigned int len) noexcept + { + _ctr.crypt(input, len); + } /** * Finish second pass and return a pointer to the opaque 128-bit IV+MAC block @@ -438,14 +446,14 @@ public: * * @return Pointer to 128-bit opaque IV+MAC (packed into two 64-bit integers) */ - ZT_INLINE const uint64_t *finish2() + ZT_INLINE const uint64_t* finish2() { _ctr.finish(); return _tag; } - private: - void *_output; + private: + void* _output; uint64_t _tag[2]; AES::GMAC _gmac; AES::CTR _ctr; @@ -456,13 +464,13 @@ public: * * GMAC-SIV decryption is single-pass. AAD (if any) must be processed first. */ - class GMACSIVDecryptor - { - public: - ZT_INLINE GMACSIVDecryptor(const AES &k0, const AES &k1) noexcept: - _ctr(k1), - _gmac(k0) - {} + class GMACSIVDecryptor { + public: + ZT_INLINE GMACSIVDecryptor(const AES& k0, const AES& k1) noexcept + : _ctr(k1) + , _gmac(k0) + { + } /** * Initialize decryptor for a new message @@ -470,18 +478,18 @@ public: * @param tag 128-bit combined IV/MAC originally created by GMAC-SIV encryption * @param output Buffer in which to write output plaintext (must be large enough!) */ - ZT_INLINE void init(const uint64_t tag[2], void *const output) noexcept + ZT_INLINE void init(const uint64_t tag[2], void* const output) noexcept { uint64_t tmp[2]; tmp[0] = tag[0]; tmp[1] = tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL); - _ctr.init(reinterpret_cast(tmp), output); + _ctr.init(reinterpret_cast(tmp), output); _ctr._aes.decrypt(tag, _ivMac); tmp[0] = _ivMac[0]; tmp[1] = 0; - _gmac.init(reinterpret_cast(tmp)); + _gmac.init(reinterpret_cast(tmp)); _output = output; _decryptedLen = 0; @@ -493,7 +501,7 @@ public: * @param aad Additional authenticated data * @param len Length of AAD in bytes */ - ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept + ZT_INLINE void aad(const void* const aad, unsigned int len) noexcept { _gmac.update(aad, len); len &= 0xfU; @@ -510,7 +518,7 @@ public: * @param input Input ciphertext * @param len Length of ciphertext */ - ZT_INLINE void update(const void *const input, const unsigned int len) noexcept + ZT_INLINE void update(const void* const input, const unsigned int len) noexcept { _ctr.crypt(input, len); _decryptedLen += len; @@ -527,52 +535,48 @@ public: uint64_t gmacTag[2]; _gmac.update(_output, _decryptedLen); - _gmac.finish(reinterpret_cast(gmacTag)); + _gmac.finish(reinterpret_cast(gmacTag)); return (gmacTag[0] ^ gmacTag[1]) == _ivMac[1]; } - private: + private: uint64_t _ivMac[2]; AES::CTR _ctr; AES::GMAC _gmac; - void *_output; + void* _output; unsigned int _decryptedLen; }; -private: + private: static const uint32_t Te0[256]; static const uint32_t Te4[256]; static const uint32_t Td0[256]; static const uint8_t Td4[256]; static const uint32_t rcon[15]; - void p_initSW(const uint8_t *key) noexcept; - void p_encryptSW(const uint8_t *in, uint8_t *out) const noexcept; - void p_decryptSW(const uint8_t *in, uint8_t *out) const noexcept; + void p_initSW(const uint8_t* key) noexcept; + void p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept; + void p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept; - union - { + union { #ifdef ZT_AES_AESNI - struct - { + struct { __m128i k[28]; - __m128i h[4]; // h, hh, hhh, hhhh - __m128i h2[4]; // _mm_xor_si128(_mm_shuffle_epi32(h, 78), h), etc. + __m128i h[4]; // h, hh, hhh, hhhh + __m128i h2[4]; // _mm_xor_si128(_mm_shuffle_epi32(h, 78), h), etc. } ni; #endif #ifdef ZT_AES_NEON - struct - { - uint64_t hsw[2]; // in case it has AES but not PMULL, not sure if that ever happens + struct { + uint64_t hsw[2]; // in case it has AES but not PMULL, not sure if that ever happens uint8x16_t ek[15]; uint8x16_t dk[15]; uint8x16_t h; } neon; #endif - struct - { + struct { uint64_t h[2]; uint32_t ek[60]; uint32_t dk[60]; @@ -580,18 +584,18 @@ private: } p_k; #ifdef ZT_AES_AESNI - void p_init_aesni(const uint8_t *key) noexcept; - void p_encrypt_aesni(const void *in, void *out) const noexcept; - void p_decrypt_aesni(const void *in, void *out) const noexcept; + void p_init_aesni(const uint8_t* key) noexcept; + void p_encrypt_aesni(const void* in, void* out) const noexcept; + void p_decrypt_aesni(const void* in, void* out) const noexcept; #endif #ifdef ZT_AES_NEON - void p_init_armneon_crypto(const uint8_t *key) noexcept; - void p_encrypt_armneon_crypto(const void *in, void *out) const noexcept; - void p_decrypt_armneon_crypto(const void *in, void *out) const noexcept; + void p_init_armneon_crypto(const uint8_t* key) noexcept; + void p_encrypt_armneon_crypto(const void* in, void* out) const noexcept; + void p_decrypt_armneon_crypto(const void* in, void* out) const noexcept; #endif }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/AES_aesni.cpp b/node/AES_aesni.cpp index c8de46dfe..e4509425a 100644 --- a/node/AES_aesni.cpp +++ b/node/AES_aesni.cpp @@ -11,8 +11,8 @@ */ /****/ -#include "Constants.hpp" #include "AES.hpp" +#include "Constants.hpp" #ifdef ZT_AES_AESNI @@ -29,7 +29,8 @@ const __m128i s_sseSwapBytes = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 #ifdef __GNUC__ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul"))) #endif -__m128i p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept +__m128i +p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept { y = _mm_shuffle_epi8(y, s_sseSwapBytes); __m128i t1 = _mm_clmulepi64_si128(h, y, 0x00); @@ -55,7 +56,7 @@ __m128i p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept * The performance gain can be significant but regular SSE is already so * fast it's highly unlikely to be a rate limiting factor except on massive * servers and network infrastructure stuff. */ -#if !defined(__WINDOWS__) && ((__GNUC__ >= 8) || (__clang_major__ >= 7)) +#if ! defined(__WINDOWS__) && ((__GNUC__ >= 8) || (__clang_major__ >= 7)) #define ZT_AES_VAES512 1 @@ -80,12 +81,8 @@ void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, co const __m512i kk13 = _mm512_broadcast_i32x4(k[13]); const __m512i kk14 = _mm512_broadcast_i32x4(k[14]); do { - __m512i p0 = _mm512_loadu_si512(reinterpret_cast(in)); - __m512i d0 = _mm512_set_epi64( - (long long)Utils::hton(c1 + 3ULL), (long long)c0, - (long long)Utils::hton(c1 + 2ULL), (long long)c0, - (long long)Utils::hton(c1 + 1ULL), (long long)c0, - (long long)Utils::hton(c1), (long long)c0); + __m512i p0 = _mm512_loadu_si512(reinterpret_cast(in)); + __m512i d0 = _mm512_set_epi64((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0, (long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0); c1 += 4; in += 64; len -= 64; @@ -104,7 +101,7 @@ void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, co d0 = _mm512_aesenc_epi128(d0, kk12); d0 = _mm512_aesenc_epi128(d0, kk13); d0 = _mm512_aesenclast_epi128(d0, kk14); - _mm512_storeu_si512(reinterpret_cast<__m512i *>(out), _mm512_xor_si512(p0, d0)); + _mm512_storeu_si512(reinterpret_cast<__m512i*>(out), _mm512_xor_si512(p0, d0)); out += 64; } while (likely(len >= 64)); } @@ -132,14 +129,10 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co const __m256i kk13 = _mm256_broadcastsi128_si256(k[13]); const __m256i kk14 = _mm256_broadcastsi128_si256(k[14]); do { - __m256i p0 = _mm256_loadu_si256(reinterpret_cast(in)); - __m256i p1 = _mm256_loadu_si256(reinterpret_cast(in + 32)); - __m256i d0 = _mm256_set_epi64x( - (long long)Utils::hton(c1 + 1ULL), (long long)c0, - (long long)Utils::hton(c1), (long long)c0); - __m256i d1 = _mm256_set_epi64x( - (long long)Utils::hton(c1 + 3ULL), (long long)c0, - (long long)Utils::hton(c1 + 2ULL), (long long)c0); + __m256i p0 = _mm256_loadu_si256(reinterpret_cast(in)); + __m256i p1 = _mm256_loadu_si256(reinterpret_cast(in + 32)); + __m256i d0 = _mm256_set_epi64x((long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0); + __m256i d1 = _mm256_set_epi64x((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0); c1 += 4; in += 64; len -= 64; @@ -173,18 +166,19 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co d1 = _mm256_aesenc_epi128(d1, kk13); d0 = _mm256_aesenclast_epi128(d0, kk14); d1 = _mm256_aesenclast_epi128(d1, kk14); - _mm256_storeu_si256(reinterpret_cast<__m256i *>(out), _mm256_xor_si256(d0, p0)); - _mm256_storeu_si256(reinterpret_cast<__m256i *>(out + 32), _mm256_xor_si256(d1, p1)); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(out), _mm256_xor_si256(d0, p0)); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(out + 32), _mm256_xor_si256(d1, p1)); out += 64; } while (likely(len >= 64)); } -#endif // does compiler support AVX2 and AVX512 AES intrinsics? +#endif // does compiler support AVX2 and AVX512 AES intrinsics? #ifdef __GNUC__ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul"))) #endif -__m128i p_init256_1_aesni(__m128i a, __m128i b) noexcept +__m128i +p_init256_1_aesni(__m128i a, __m128i b) noexcept { __m128i x, y; b = _mm_shuffle_epi32(b, 0xff); @@ -201,7 +195,8 @@ __m128i p_init256_1_aesni(__m128i a, __m128i b) noexcept #ifdef __GNUC__ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul"))) #endif -__m128i p_init256_2_aesni(__m128i a, __m128i b) noexcept +__m128i +p_init256_2_aesni(__m128i a, __m128i b) noexcept { __m128i x, y, z; y = _mm_aeskeygenassist_si128(a, 0x00); @@ -216,25 +211,25 @@ __m128i p_init256_2_aesni(__m128i a, __m128i b) noexcept return x; } -} // anonymous namespace +} // anonymous namespace #ifdef __GNUC__ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul"))) #endif void AES::GMAC::p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept { - __m128i y = _mm_loadu_si128(reinterpret_cast(_y)); + __m128i y = _mm_loadu_si128(reinterpret_cast(_y)); // Handle anything left over from a previous run that wasn't a multiple of 16 bytes. if (_rp) { for (;;) { - if (!len) { + if (! len) { return; } --len; _r[_rp++] = *(in++); if (_rp == 16) { - y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i *>(_r)))); + y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i*>(_r)))); break; } } @@ -250,17 +245,21 @@ void AES::GMAC::p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept const __m128i hh2 = _aes.p_k.ni.h2[1]; const __m128i hhh2 = _aes.p_k.ni.h2[2]; const __m128i hhhh2 = _aes.p_k.ni.h2[3]; - const uint8_t *const end64 = in + (len & ~((unsigned int)63)); + const uint8_t* const end64 = in + (len & ~((unsigned int)63)); len &= 63U; do { - __m128i d1 = _mm_shuffle_epi8(_mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast(in))), sb); - __m128i d2 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 16)), sb); - __m128i d3 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 32)), sb); - __m128i d4 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 48)), sb); + __m128i d1 = _mm_shuffle_epi8(_mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast(in))), sb); + __m128i d2 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 16)), sb); + __m128i d3 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 32)), sb); + __m128i d4 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast(in + 48)), sb); in += 64; __m128i a = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x00), _mm_clmulepi64_si128(hhh, d2, 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x00), _mm_clmulepi64_si128(h, d4, 0x00))); __m128i b = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x11), _mm_clmulepi64_si128(hhh, d2, 0x11)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x11), _mm_clmulepi64_si128(h, d4, 0x11))); - __m128i c = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))), _mm_xor_si128(a, b)); + __m128i c = _mm_xor_si128( + _mm_xor_si128( + _mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)), + _mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))), + _mm_xor_si128(a, b)); a = _mm_xor_si128(_mm_slli_si128(c, 8), a); b = _mm_xor_si128(_mm_srli_si128(c, 8), b); c = _mm_srli_epi32(a, 31); @@ -274,18 +273,18 @@ void AES::GMAC::p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept } while (len >= 16) { - y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast(in)))); + y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast(in)))); in += 16; len -= 16; } - _mm_storeu_si128(reinterpret_cast<__m128i *>(_y), y); + _mm_storeu_si128(reinterpret_cast<__m128i*>(_y), y); // Any overflow is cached for a later run or finish(). for (unsigned int i = 0; i < len; ++i) { _r[i] = in[i]; } - _rp = len; // len is always less than 16 here + _rp = len; // len is always less than 16 here } #ifdef __GNUC__ @@ -293,23 +292,23 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul,aes"))) #endif void AES::GMAC::p_aesNIFinish(uint8_t tag[16]) noexcept { - __m128i y = _mm_loadu_si128(reinterpret_cast(_y)); + __m128i y = _mm_loadu_si128(reinterpret_cast(_y)); // Handle any remaining bytes, padding the last block with zeroes. if (_rp) { while (_rp < 16) { _r[_rp++] = 0; } - y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i *>(_r)))); + y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i*>(_r)))); } // Interleave encryption of IV with the final GHASH of y XOR (length * 8). // Then XOR these together to get the final tag. - const __m128i *const k = _aes.p_k.ni.k; + const __m128i* const k = _aes.p_k.ni.k; const __m128i h = _aes.p_k.ni.h[0]; y = _mm_xor_si128(y, _mm_set_epi64x(0LL, (long long)Utils::hton((uint64_t)_len << 3U))); y = _mm_shuffle_epi8(y, s_sseSwapBytes); - __m128i encIV = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(_iv)), k[0]); + __m128i encIV = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(_iv)), k[0]); __m128i t1 = _mm_clmulepi64_si128(h, y, 0x00); __m128i t2 = _mm_clmulepi64_si128(h, y, 0x01); __m128i t3 = _mm_clmulepi64_si128(h, y, 0x10); @@ -359,7 +358,7 @@ void AES::GMAC::p_aesNIFinish(uint8_t tag[16]) noexcept t4 = _mm_xor_si128(t4, t3); encIV = _mm_aesenclast_si128(encIV, k[14]); t4 = _mm_xor_si128(t4, t5); - _mm_storeu_si128(reinterpret_cast<__m128i *>(tag), _mm_xor_si128(_mm_shuffle_epi8(t4, s_sseSwapBytes), encIV)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(tag), _mm_xor_si128(_mm_shuffle_epi8(t4, s_sseSwapBytes), encIV)); } #ifdef __GNUC__ @@ -370,7 +369,7 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n const __m128i dd = _mm_set_epi64x(0, (long long)_ctr[0]); uint64_t c1 = Utils::ntoh(_ctr[1]); - const __m128i *const k = _aes.p_k.ni.k; + const __m128i* const k = _aes.p_k.ni.k; const __m128i k0 = k[0]; const __m128i k1 = k[1]; const __m128i k2 = k[2]; @@ -391,14 +390,14 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n unsigned int totalLen = _len; if ((totalLen & 15U)) { for (;;) { - if (unlikely(!len)) { + if (unlikely(! len)) { _ctr[1] = Utils::hton(c1); _len = totalLen; return; } --len; out[totalLen++] = *(in++); - if (!(totalLen & 15U)) { + if (! (totalLen & 15U)) { __m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1++), 1); d0 = _mm_xor_si128(d0, k0); d0 = _mm_aesenc_si128(d0, k1); @@ -411,7 +410,7 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n d0 = _mm_aesenc_si128(d0, k8); d0 = _mm_aesenc_si128(d0, k9); d0 = _mm_aesenc_si128(d0, k10); - __m128i *const outblk = reinterpret_cast<__m128i *>(out + (totalLen - 16)); + __m128i* const outblk = reinterpret_cast<__m128i*>(out + (totalLen - 16)); d0 = _mm_aesenc_si128(d0, k11); const __m128i p0 = _mm_loadu_si128(outblk); d0 = _mm_aesenc_si128(d0, k12); @@ -427,26 +426,26 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n _len = totalLen + len; if (likely(len >= 64)) { - #if defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256) if (Utils::CPUID.vaes && (len >= 256)) { if (Utils::CPUID.avx512f) { p_aesCtrInnerVAES512(len, _ctr[0], c1, in, out, k); - } else { + } + else { p_aesCtrInnerVAES256(len, _ctr[0], c1, in, out, k); } goto skip_conventional_aesni_64; } #endif -#if !defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256) +#if ! defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256) if (Utils::CPUID.vaes && (len >= 256)) { p_aesCtrInnerVAES256(len, _ctr[0], c1, in, out, k); goto skip_conventional_aesni_64; } #endif - const uint8_t *const eof64 = in + (len & ~((unsigned int)63)); + const uint8_t* const eof64 = in + (len & ~((unsigned int)63)); len &= 63; __m128i d0, d1, d2, d3; do { @@ -515,21 +514,20 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n d1 = _mm_aesenc_si128(d1, k13); d2 = _mm_aesenc_si128(d2, k13); d3 = _mm_aesenc_si128(d3, k13); - d0 = _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast(in))); - d1 = _mm_xor_si128(_mm_aesenclast_si128(d1, k14), _mm_loadu_si128(reinterpret_cast(in + 16))); - d2 = _mm_xor_si128(_mm_aesenclast_si128(d2, k14), _mm_loadu_si128(reinterpret_cast(in + 32))); - d3 = _mm_xor_si128(_mm_aesenclast_si128(d3, k14), _mm_loadu_si128(reinterpret_cast(in + 48))); + d0 = _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast(in))); + d1 = _mm_xor_si128(_mm_aesenclast_si128(d1, k14), _mm_loadu_si128(reinterpret_cast(in + 16))); + d2 = _mm_xor_si128(_mm_aesenclast_si128(d2, k14), _mm_loadu_si128(reinterpret_cast(in + 32))); + d3 = _mm_xor_si128(_mm_aesenclast_si128(d3, k14), _mm_loadu_si128(reinterpret_cast(in + 48))); in += 64; - _mm_storeu_si128(reinterpret_cast<__m128i *>(out), d0); - _mm_storeu_si128(reinterpret_cast<__m128i *>(out + 16), d1); - _mm_storeu_si128(reinterpret_cast<__m128i *>(out + 32), d2); - _mm_storeu_si128(reinterpret_cast<__m128i *>(out + 48), d3); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out), d0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out + 16), d1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out + 32), d2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out + 48), d3); out += 64; } while (likely(in != eof64)); - } - skip_conventional_aesni_64: +skip_conventional_aesni_64: while (len >= 16) { __m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1++), 1); d0 = _mm_xor_si128(d0, k0); @@ -546,7 +544,7 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n d0 = _mm_aesenc_si128(d0, k11); d0 = _mm_aesenc_si128(d0, k12); d0 = _mm_aesenc_si128(d0, k13); - _mm_storeu_si128(reinterpret_cast<__m128i *>(out), _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast(in)))); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out), _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast(in)))); in += 16; len -= 16; out += 16; @@ -568,8 +566,8 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul"))) void AES::p_init_aesni(const uint8_t *key) noexcept { __m128i t1, t2, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13; - p_k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i *)key); - p_k.ni.k[1] = k1 = t2 = _mm_loadu_si128((const __m128i *)(key + 16)); + p_k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i*)key); + p_k.ni.k[1] = k1 = t2 = _mm_loadu_si128((const __m128i*)(key + 16)); p_k.ni.k[2] = k2 = t1 = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x01)); p_k.ni.k[3] = k3 = t2 = p_init256_2_aesni(t1, t2); p_k.ni.k[4] = k4 = t1 = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x02)); @@ -597,7 +595,7 @@ void AES::p_init_aesni(const uint8_t *key) noexcept p_k.ni.k[26] = _mm_aesimc_si128(k2); p_k.ni.k[27] = _mm_aesimc_si128(k1); - __m128i h = p_k.ni.k[0]; // _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]); + __m128i h = p_k.ni.k[0]; // _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]); h = _mm_aesenc_si128(h, k1); h = _mm_aesenc_si128(h, k2); h = _mm_aesenc_si128(h, k3); @@ -631,7 +629,7 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul"))) #endif void AES::p_encrypt_aesni(const void *const in, void *const out) const noexcept { - __m128i tmp = _mm_loadu_si128((const __m128i *)in); + __m128i tmp = _mm_loadu_si128((const __m128i*)in); tmp = _mm_xor_si128(tmp, p_k.ni.k[0]); tmp = _mm_aesenc_si128(tmp, p_k.ni.k[1]); tmp = _mm_aesenc_si128(tmp, p_k.ni.k[2]); @@ -646,7 +644,7 @@ void AES::p_encrypt_aesni(const void *const in, void *const out) const noexcept tmp = _mm_aesenc_si128(tmp, p_k.ni.k[11]); tmp = _mm_aesenc_si128(tmp, p_k.ni.k[12]); tmp = _mm_aesenc_si128(tmp, p_k.ni.k[13]); - _mm_storeu_si128((__m128i *)out, _mm_aesenclast_si128(tmp, p_k.ni.k[14])); + _mm_storeu_si128((__m128i*)out, _mm_aesenclast_si128(tmp, p_k.ni.k[14])); } #ifdef __GNUC__ @@ -654,7 +652,7 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul"))) #endif void AES::p_decrypt_aesni(const void *in, void *out) const noexcept { - __m128i tmp = _mm_loadu_si128((const __m128i *)in); + __m128i tmp = _mm_loadu_si128((const __m128i*)in); tmp = _mm_xor_si128(tmp, p_k.ni.k[14]); tmp = _mm_aesdec_si128(tmp, p_k.ni.k[15]); tmp = _mm_aesdec_si128(tmp, p_k.ni.k[16]); @@ -669,9 +667,9 @@ void AES::p_decrypt_aesni(const void *in, void *out) const noexcept tmp = _mm_aesdec_si128(tmp, p_k.ni.k[25]); tmp = _mm_aesdec_si128(tmp, p_k.ni.k[26]); tmp = _mm_aesdec_si128(tmp, p_k.ni.k[27]); - _mm_storeu_si128((__m128i *)out, _mm_aesdeclast_si128(tmp, p_k.ni.k[0])); + _mm_storeu_si128((__m128i*)out, _mm_aesdeclast_si128(tmp, p_k.ni.k[0])); } -} // namespace ZeroTier +} // namespace ZeroTier -#endif // ZT_AES_AESNI +#endif // ZT_AES_AESNI diff --git a/node/AES_armcrypto.cpp b/node/AES_armcrypto.cpp index 2319ae855..a1be0b003 100644 --- a/node/AES_armcrypto.cpp +++ b/node/AES_armcrypto.cpp @@ -11,8 +11,8 @@ */ /****/ -#include "Constants.hpp" #include "AES.hpp" +#include "Constants.hpp" #ifdef ZT_AES_NEON @@ -29,34 +29,34 @@ ZT_INLINE uint8x16_t s_clmul_armneon_crypto(uint8x16_t h, uint8x16_t y, const ui y = vrbitq_u8(y); const uint8x16_t p = vreinterpretq_u8_u64(vdupq_n_u64(0x0000000000000087)); t0 = vextq_u8(y, y, 8); - __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w" (r0) : "w" (h), "w" (y)); - __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" :"=w" (r1) : "w" (h), "w" (y)); - __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w" (t1) : "w" (h), "w" (t0)); - __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" :"=w" (t0) : "w" (h), "w" (t0)); + __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w"(r0) : "w"(h), "w"(y)); + __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" : "=w"(r1) : "w"(h), "w"(y)); + __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w"(t1) : "w"(h), "w"(t0)); + __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" : "=w"(t0) : "w"(h), "w"(t0)); t0 = veorq_u8(t0, t1); t1 = vextq_u8(z, t0, 8); r0 = veorq_u8(r0, t1); t1 = vextq_u8(t0, z, 8); r1 = veorq_u8(r1, t1); - __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" :"=w" (t0) : "w" (r1), "w" (p)); + __asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" : "=w"(t0) : "w"(r1), "w"(p)); t1 = vextq_u8(t0, z, 8); r1 = veorq_u8(r1, t1); t1 = vextq_u8(z, t0, 8); r0 = veorq_u8(r0, t1); - __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w" (t0) : "w" (r1), "w" (p)); + __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w"(t0) : "w"(r1), "w"(p)); return vrbitq_u8(veorq_u8(r0, t0)); } -} // anonymous namespace +} // anonymous namespace -void AES::GMAC::p_armUpdate(const uint8_t *in, unsigned int len) noexcept +void AES::GMAC::p_armUpdate(const uint8_t* in, unsigned int len) noexcept { - uint8x16_t y = vld1q_u8(reinterpret_cast(_y)); + uint8x16_t y = vld1q_u8(reinterpret_cast(_y)); const uint8x16_t h = _aes.p_k.neon.h; if (_rp) { - for(;;) { - if (!len) { + for (;;) { + if (! len) { return; } --len; @@ -74,18 +74,18 @@ void AES::GMAC::p_armUpdate(const uint8_t *in, unsigned int len) noexcept len -= 16; } - vst1q_u8(reinterpret_cast(_y), y); + vst1q_u8(reinterpret_cast(_y), y); for (unsigned int i = 0; i < len; ++i) { _r[i] = in[i]; } - _rp = len; // len is always less than 16 here + _rp = len; // len is always less than 16 here } void AES::GMAC::p_armFinish(uint8_t tag[16]) noexcept { uint64_t tmp[2]; - uint8x16_t y = vld1q_u8(reinterpret_cast(_y)); + uint8x16_t y = vld1q_u8(reinterpret_cast(_y)); const uint8x16_t h = _aes.p_k.neon.h; if (_rp) { @@ -97,25 +97,25 @@ void AES::GMAC::p_armFinish(uint8_t tag[16]) noexcept tmp[0] = Utils::hton((uint64_t)_len << 3U); tmp[1] = 0; - y = s_clmul_armneon_crypto(h, y, reinterpret_cast(tmp)); + y = s_clmul_armneon_crypto(h, y, reinterpret_cast(tmp)); - Utils::copy< 12 >(tmp, _iv); + Utils::copy<12>(tmp, _iv); #if __BYTE_ORDER == __BIG_ENDIAN - reinterpret_cast(tmp)[3] = 0x00000001; + reinterpret_cast(tmp)[3] = 0x00000001; #else - reinterpret_cast(tmp)[3] = 0x01000000; + reinterpret_cast(tmp)[3] = 0x01000000; #endif _aes.encrypt(tmp, tmp); uint8x16_t yy = y; - Utils::storeMachineEndian< uint64_t >(tag, tmp[0] ^ reinterpret_cast(&yy)[0]); - Utils::storeMachineEndian< uint64_t >(tag + 8, tmp[1] ^ reinterpret_cast(&yy)[1]); + Utils::storeMachineEndian(tag, tmp[0] ^ reinterpret_cast(&yy)[0]); + Utils::storeMachineEndian(tag + 8, tmp[1] ^ reinterpret_cast(&yy)[1]); } -void AES::CTR::p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept +void AES::CTR::p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept { - uint8x16_t dd = vrev32q_u8(vld1q_u8(reinterpret_cast(_ctr))); - const uint32x4_t one = {0,0,0,1}; + uint8x16_t dd = vrev32q_u8(vld1q_u8(reinterpret_cast(_ctr))); + const uint32x4_t one = { 0, 0, 0, 1 }; uint8x16_t k0 = _aes.p_k.neon.ek[0]; uint8x16_t k1 = _aes.p_k.neon.ek[1]; @@ -136,15 +136,15 @@ void AES::CTR::p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noe unsigned int totalLen = _len; if ((totalLen & 15U) != 0) { for (;;) { - if (unlikely(!len)) { - vst1q_u8(reinterpret_cast(_ctr), vrev32q_u8(dd)); + if (unlikely(! len)) { + vst1q_u8(reinterpret_cast(_ctr), vrev32q_u8(dd)); _len = totalLen; return; } --len; out[totalLen++] = *(in++); if ((totalLen & 15U) == 0) { - uint8_t *const otmp = out + (totalLen - 16); + uint8_t* const otmp = out + (totalLen - 16); uint8x16_t d0 = vrev32q_u8(dd); uint8x16_t pt = vld1q_u8(otmp); d0 = vaesmcq_u8(vaeseq_u8(d0, k0)); @@ -298,46 +298,52 @@ void AES::CTR::p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noe out[i] = in[i]; } - vst1q_u8(reinterpret_cast(_ctr), vrev32q_u8(dd)); + vst1q_u8(reinterpret_cast(_ctr), vrev32q_u8(dd)); } #define ZT_INIT_ARMNEON_CRYPTO_SUBWORD(w) ((uint32_t)s_sbox[w & 0xffU] + ((uint32_t)s_sbox[(w >> 8U) & 0xffU] << 8U) + ((uint32_t)s_sbox[(w >> 16U) & 0xffU] << 16U) + ((uint32_t)s_sbox[(w >> 24U) & 0xffU] << 24U)) #define ZT_INIT_ARMNEON_CRYPTO_ROTWORD(w) (((w) << 8U) | ((w) >> 24U)) -#define ZT_INIT_ARMNEON_CRYPTO_NK 8 -#define ZT_INIT_ARMNEON_CRYPTO_NB 4 -#define ZT_INIT_ARMNEON_CRYPTO_NR 14 +#define ZT_INIT_ARMNEON_CRYPTO_NK 8 +#define ZT_INIT_ARMNEON_CRYPTO_NB 4 +#define ZT_INIT_ARMNEON_CRYPTO_NR 14 -void AES::p_init_armneon_crypto(const uint8_t *key) noexcept +void AES::p_init_armneon_crypto(const uint8_t* key) noexcept { - static const uint8_t s_sbox[256] = {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, - 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, - 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + static const uint8_t s_sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; uint64_t h[2]; - uint32_t *const w = reinterpret_cast(p_k.neon.ek); + uint32_t* const w = reinterpret_cast(p_k.neon.ek); - for (unsigned int i=0;i(in)); + uint8x16_t tmp = vld1q_u8(reinterpret_cast(in)); tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[0])); tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[1])); tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[2])); @@ -366,12 +372,12 @@ void AES::p_encrypt_armneon_crypto(const void *const in, void *const out) const tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[11])); tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[12])); tmp = veorq_u8(vaeseq_u8(tmp, p_k.neon.ek[13]), p_k.neon.ek[14]); - vst1q_u8(reinterpret_cast(out), tmp); + vst1q_u8(reinterpret_cast(out), tmp); } -void AES::p_decrypt_armneon_crypto(const void *const in, void *const out) const noexcept +void AES::p_decrypt_armneon_crypto(const void* const in, void* const out) const noexcept { - uint8x16_t tmp = vld1q_u8(reinterpret_cast(in)); + uint8x16_t tmp = vld1q_u8(reinterpret_cast(in)); tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[0])); tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[1])); tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[2])); @@ -386,9 +392,9 @@ void AES::p_decrypt_armneon_crypto(const void *const in, void *const out) const tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[11])); tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[12])); tmp = veorq_u8(vaesdq_u8(tmp, p_k.neon.dk[13]), p_k.neon.dk[14]); - vst1q_u8(reinterpret_cast(out), tmp); + vst1q_u8(reinterpret_cast(out), tmp); } -} // namespace ZeroTier +} // namespace ZeroTier -#endif // ZT_AES_NEON +#endif // ZT_AES_NEON diff --git a/node/Address.hpp b/node/Address.hpp index 69847b911..182ccb7bb 100644 --- a/node/Address.hpp +++ b/node/Address.hpp @@ -14,49 +14,64 @@ #ifndef ZT_ADDRESS_HPP #define ZT_ADDRESS_HPP -#include -#include -#include -#include - -#include - +#include "Buffer.hpp" #include "Constants.hpp" #include "Utils.hpp" -#include "Buffer.hpp" + +#include +#include +#include +#include +#include namespace ZeroTier { /** * A ZeroTier address */ -class Address -{ -public: - Address() : _a(0) {} - Address(const Address &a) : _a(a._a) {} - Address(uint64_t a) : _a(a & 0xffffffffffULL) {} +class Address { + public: + Address() : _a(0) + { + } + Address(const Address& a) : _a(a._a) + { + } + Address(uint64_t a) : _a(a & 0xffffffffffULL) + { + } /** * @param bits Raw address -- 5 bytes, big-endian byte order * @param len Length of array */ - Address(const void *bits,unsigned int len) { setTo(bits,len); } + Address(const void* bits, unsigned int len) + { + setTo(bits, len); + } - inline Address &operator=(const Address &a) { _a = a._a; return *this; } - inline Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; } + inline Address& operator=(const Address& a) + { + _a = a._a; + return *this; + } + inline Address& operator=(const uint64_t a) + { + _a = (a & 0xffffffffffULL); + return *this; + } /** * @param bits Raw address -- 5 bytes, big-endian byte order * @param len Length of array */ - inline void setTo(const void *bits,const unsigned int len) + inline void setTo(const void* bits, const unsigned int len) { if (len < ZT_ADDRESS_LENGTH) { _a = 0; return; } - const unsigned char *b = (const unsigned char *)bits; + const unsigned char* b = (const unsigned char*)bits; uint64_t a = ((uint64_t)*b++) << 32; a |= ((uint64_t)*b++) << 24; a |= ((uint64_t)*b++) << 16; @@ -69,12 +84,12 @@ public: * @param bits Buffer to hold 5-byte address in big-endian byte order * @param len Length of array */ - inline void copyTo(void *const bits,const unsigned int len) const + inline void copyTo(void* const bits, const unsigned int len) const { if (len < ZT_ADDRESS_LENGTH) { return; } - unsigned char *b = (unsigned char *)bits; + unsigned char* b = (unsigned char*)bits; *(b++) = (unsigned char)((_a >> 32) & 0xff); *(b++) = (unsigned char)((_a >> 24) & 0xff); *(b++) = (unsigned char)((_a >> 16) & 0xff); @@ -87,10 +102,9 @@ public: * * @param b Buffer to append to */ - template - inline void appendTo(Buffer &b) const + template inline void appendTo(Buffer& b) const { - unsigned char *p = (unsigned char *)b.appendField(ZT_ADDRESS_LENGTH); + unsigned char* p = (unsigned char*)b.appendField(ZT_ADDRESS_LENGTH); *(p++) = (unsigned char)((_a >> 32) & 0xff); *(p++) = (unsigned char)((_a >> 24) & 0xff); *(p++) = (unsigned char)((_a >> 16) & 0xff); @@ -101,22 +115,34 @@ public: /** * @return Integer containing address (0 to 2^40) */ - inline uint64_t toInt() const { return _a; } + inline uint64_t toInt() const + { + return _a; + } /** * @return Hash code for use with Hashtable */ - inline unsigned long hashCode() const { return (unsigned long)_a; } + inline unsigned long hashCode() const + { + return (unsigned long)_a; + } /** * @return Hexadecimal string */ - inline char *toString(char buf[11]) const { return Utils::hex10(_a,buf); } + inline char* toString(char buf[11]) const + { + return Utils::hex10(_a, buf); + } /** * @return True if this address is not zero */ - inline operator bool() const { return (_a != 0); } + inline operator bool() const + { + return (_a != 0); + } /** * Check if this address is reserved @@ -127,34 +153,79 @@ public: * * @return True if address is reserved and may not be used */ - inline bool isReserved() const { return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX)); } + inline bool isReserved() const + { + return ((! _a) || ((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX)); + } /** * @param i Value from 0 to 4 (inclusive) * @return Byte at said position (address interpreted in big-endian order) */ - inline uint8_t operator[](unsigned int i) const { return (uint8_t)(_a >> (32 - (i * 8))); } + inline uint8_t operator[](unsigned int i) const + { + return (uint8_t)(_a >> (32 - (i * 8))); + } - inline void zero() { _a = 0; } + inline void zero() + { + _a = 0; + } - inline bool operator==(const uint64_t &a) const { return (_a == (a & 0xffffffffffULL)); } - inline bool operator!=(const uint64_t &a) const { return (_a != (a & 0xffffffffffULL)); } - inline bool operator>(const uint64_t &a) const { return (_a > (a & 0xffffffffffULL)); } - inline bool operator<(const uint64_t &a) const { return (_a < (a & 0xffffffffffULL)); } - inline bool operator>=(const uint64_t &a) const { return (_a >= (a & 0xffffffffffULL)); } - inline bool operator<=(const uint64_t &a) const { return (_a <= (a & 0xffffffffffULL)); } + inline bool operator==(const uint64_t& a) const + { + return (_a == (a & 0xffffffffffULL)); + } + inline bool operator!=(const uint64_t& a) const + { + return (_a != (a & 0xffffffffffULL)); + } + inline bool operator>(const uint64_t& a) const + { + return (_a > (a & 0xffffffffffULL)); + } + inline bool operator<(const uint64_t& a) const + { + return (_a < (a & 0xffffffffffULL)); + } + inline bool operator>=(const uint64_t& a) const + { + return (_a >= (a & 0xffffffffffULL)); + } + inline bool operator<=(const uint64_t& a) const + { + return (_a <= (a & 0xffffffffffULL)); + } - inline bool operator==(const Address &a) const { return (_a == a._a); } - inline bool operator!=(const Address &a) const { return (_a != a._a); } - inline bool operator>(const Address &a) const { return (_a > a._a); } - inline bool operator<(const Address &a) const { return (_a < a._a); } - inline bool operator>=(const Address &a) const { return (_a >= a._a); } - inline bool operator<=(const Address &a) const { return (_a <= a._a); } + inline bool operator==(const Address& a) const + { + return (_a == a._a); + } + inline bool operator!=(const Address& a) const + { + return (_a != a._a); + } + inline bool operator>(const Address& a) const + { + return (_a > a._a); + } + inline bool operator<(const Address& a) const + { + return (_a < a._a); + } + inline bool operator>=(const Address& a) const + { + return (_a >= a._a); + } + inline bool operator<=(const Address& a) const + { + return (_a <= a._a); + } -private: + private: uint64_t _a; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/AtomicCounter.hpp b/node/AtomicCounter.hpp index 5d0b21f31..1e75d6e9f 100644 --- a/node/AtomicCounter.hpp +++ b/node/AtomicCounter.hpp @@ -25,15 +25,17 @@ namespace ZeroTier { /** * Simple atomic counter supporting increment and decrement */ -class AtomicCounter -{ -public: - AtomicCounter() { _v = 0; } +class AtomicCounter { + public: + AtomicCounter() + { + _v = 0; + } inline int load() const { #ifdef __GNUC__ - return __sync_or_and_fetch(const_cast(&_v),0); + return __sync_or_and_fetch(const_cast(&_v), 0); #else return _v.load(); #endif @@ -42,7 +44,7 @@ public: inline int operator++() { #ifdef __GNUC__ - return __sync_add_and_fetch(&_v,1); + return __sync_add_and_fetch(&_v, 1); #else return ++_v; #endif @@ -51,15 +53,20 @@ public: inline int operator--() { #ifdef __GNUC__ - return __sync_sub_and_fetch(&_v,1); + return __sync_sub_and_fetch(&_v, 1); #else return --_v; #endif } -private: - AtomicCounter(const AtomicCounter &) {} - const AtomicCounter &operator=(const AtomicCounter &) { return *this; } + private: + AtomicCounter(const AtomicCounter&) + { + } + const AtomicCounter& operator=(const AtomicCounter&) + { + return *this; + } #ifdef __GNUC__ int _v; @@ -68,6 +75,6 @@ private: #endif }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Bond.cpp b/node/Bond.cpp index 2a061796d..f503a154c 100644 --- a/node/Bond.cpp +++ b/node/Bond.cpp @@ -373,7 +373,7 @@ SharedPtr Bond::getAppropriatePath(int64_t now, int32_t flowId) */ if (_policy == ZT_BOND_POLICY_ACTIVE_BACKUP) { if (_abPathIdx != ZT_MAX_PEER_NETWORK_PATHS && _paths[_abPathIdx].p) { - //fprintf(stderr, "trying to send via (_abPathIdx=%d) %s\n", _abPathIdx, pathToStr(_paths[_abPathIdx].p).c_str()); + // fprintf(stderr, "trying to send via (_abPathIdx=%d) %s\n", _abPathIdx, pathToStr(_paths[_abPathIdx].p).c_str()); return _paths[_abPathIdx].p; } } @@ -1584,7 +1584,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now) } } } - if (!foundPreferredPath && foundPathOnPrimaryLink && (nonPreferredPathIdx != ZT_MAX_PEER_NETWORK_PATHS)) { + if (! foundPreferredPath && foundPathOnPrimaryLink && (nonPreferredPathIdx != ZT_MAX_PEER_NETWORK_PATHS)) { log("found non-preferred primary link (_abPathIdx=%d)", _abPathIdx); _abPathIdx = nonPreferredPathIdx; } diff --git a/node/Bond.hpp b/node/Bond.hpp index d5d3f673e..f7d1f05a2 100644 --- a/node/Bond.hpp +++ b/node/Bond.hpp @@ -1144,7 +1144,7 @@ class Bond { __attribute__((format(printf, 2, 3))) #endif { - //if (_peerId != 0x0 && _peerId != 0x0) { return; } + // if (_peerId != 0x0 && _peerId != 0x0) { return; } #ifdef ZT_TRACE time_t rawtime; struct tm* timeinfo; @@ -1176,7 +1176,7 @@ class Bond { __attribute__((format(printf, 2, 3))) #endif { - //if (_peerId != 0x0 && _peerId != 0x0) { return; } + // if (_peerId != 0x0 && _peerId != 0x0) { return; } #ifdef ZT_DEBUG time_t rawtime; struct tm* timeinfo; diff --git a/node/Buffer.hpp b/node/Buffer.hpp index 8dbc51efe..ae013c790 100644 --- a/node/Buffer.hpp +++ b/node/Buffer.hpp @@ -14,18 +14,17 @@ #ifndef ZT_BUFFER_HPP #define ZT_BUFFER_HPP -#include -#include - -#include -#include -#include -#include - #include "Constants.hpp" #include "Utils.hpp" -#if defined(__GNUC__) && (!defined(ZT_NO_TYPE_PUNNING)) +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && (! defined(ZT_NO_TYPE_PUNNING)) #define ZT_VAR_MAY_ALIAS __attribute__((__may_alias__)) #else #define ZT_VAR_MAY_ALIAS @@ -46,36 +45,57 @@ namespace ZeroTier { * * @tparam C Total capacity */ -template -class Buffer -{ +template class Buffer { // I love me! template friend class Buffer; -public: + public: // STL container idioms typedef unsigned char value_type; - typedef unsigned char * pointer; - typedef const char * const_pointer; - typedef char & reference; - typedef const char & const_reference; - typedef char * iterator; - typedef const char * const_iterator; + typedef unsigned char* pointer; + typedef const char* const_pointer; + typedef char& reference; + typedef const char& const_reference; + typedef char* iterator; + typedef const char* const_iterator; typedef unsigned int size_type; typedef int difference_type; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; - inline iterator begin() { return _b; } - inline iterator end() { return (_b + _l); } - inline const_iterator begin() const { return _b; } - inline const_iterator end() const { return (_b + _l); } - inline reverse_iterator rbegin() { return reverse_iterator(begin()); } - inline reverse_iterator rend() { return reverse_iterator(end()); } - inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); } - inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); } + inline iterator begin() + { + return _b; + } + inline iterator end() + { + return (_b + _l); + } + inline const_iterator begin() const + { + return _b; + } + inline const_iterator end() const + { + return (_b + _l); + } + inline reverse_iterator rbegin() + { + return reverse_iterator(begin()); + } + inline reverse_iterator rend() + { + return reverse_iterator(end()); + } + inline const_reverse_iterator rbegin() const + { + return const_reverse_iterator(begin()); + } + inline const_reverse_iterator rend() const + { + return const_reverse_iterator(end()); + } - Buffer() : - _l(0) + Buffer() : _l(0) { } @@ -87,37 +107,36 @@ public: _l = l; } - template - Buffer(const Buffer &b) + template Buffer(const Buffer& b) { *this = b; } - Buffer(const void *b,unsigned int l) + Buffer(const void* b, unsigned int l) { - copyFrom(b,l); + copyFrom(b, l); } - template - inline Buffer &operator=(const Buffer &b) + template inline Buffer& operator=(const Buffer& b) { if (unlikely(b._l > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } if (C2 == C) { - memcpy(this,&b,sizeof(Buffer)); - } else { - memcpy(_b,b._b,_l = b._l); + memcpy(this, &b, sizeof(Buffer)); + } + else { + memcpy(_b, b._b, _l = b._l); } return *this; } - inline void copyFrom(const void *b,unsigned int l) + inline void copyFrom(const void* b, unsigned int l) { if (unlikely(l > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - memcpy(_b,b,l); + memcpy(_b, b, l); _l = l; } @@ -129,12 +148,12 @@ public: return (unsigned char)_b[i]; } - unsigned char &operator[](const unsigned int i) + unsigned char& operator[](const unsigned int i) { if (unlikely(i >= _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - return ((unsigned char *)_b)[i]; + return ((unsigned char*)_b)[i]; } /** @@ -150,19 +169,19 @@ public: * @return Pointer to field data * @throws std::out_of_range Field extends beyond data size */ - unsigned char *field(unsigned int i,unsigned int l) + unsigned char* field(unsigned int i, unsigned int l) { if (unlikely((i + l) > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - return (unsigned char *)(_b + i); + return (unsigned char*)(_b + i); } - const unsigned char *field(unsigned int i,unsigned int l) const + const unsigned char* field(unsigned int i, unsigned int l) const { if (unlikely((i + l) > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - return (const unsigned char *)(_b + i); + return (const unsigned char*)(_b + i); } /** @@ -172,19 +191,18 @@ public: * @param v Value * @tparam T Integer type (e.g. uint16_t, int64_t) */ - template - inline void setAt(unsigned int i,const T v) + template inline void setAt(unsigned int i, const T v) { if (unlikely((i + sizeof(T)) > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } #ifdef ZT_NO_TYPE_PUNNING - uint8_t *p = reinterpret_cast(_b + i); - for(unsigned int x=1;x<=sizeof(T);++x) { + uint8_t* p = reinterpret_cast(_b + i); + for (unsigned int x = 1; x <= sizeof(T); ++x) { *(p++) = (uint8_t)(v >> (8 * (sizeof(T) - x))); } #else - T *const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + i); + T* const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + i); *p = Utils::hton(v); #endif } @@ -196,22 +214,21 @@ public: * @tparam T Integer type (e.g. uint16_t, int64_t) * @return Integer value */ - template - inline T at(unsigned int i) const + template inline T at(unsigned int i) const { if (unlikely((i + sizeof(T)) > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } #ifdef ZT_NO_TYPE_PUNNING T v = 0; - const uint8_t *p = reinterpret_cast(_b + i); - for(unsigned int x=0;x(_b + i); + for (unsigned int x = 0; x < sizeof(T); ++x) { v <<= 8; - v |= (T)*(p++); + v |= (T) * (p++); } return v; #else - const T *const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + i); + const T* const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + i); return Utils::ntoh(*p); #endif } @@ -223,19 +240,18 @@ public: * @tparam T Integer type (e.g. uint16_t, int64_t) * @throws std::out_of_range Attempt to append beyond capacity */ - template - inline void append(const T v) + template inline void append(const T v) { if (unlikely((_l + sizeof(T)) > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } #ifdef ZT_NO_TYPE_PUNNING - uint8_t *p = reinterpret_cast(_b + _l); - for(unsigned int x=1;x<=sizeof(T);++x) { + uint8_t* p = reinterpret_cast(_b + _l); + for (unsigned int x = 1; x <= sizeof(T); ++x) { *(p++) = (uint8_t)(v >> (8 * (sizeof(T) - x))); } #else - T *const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + _l); + T* const ZT_VAR_MAY_ALIAS p = reinterpret_cast(_b + _l); *p = Utils::hton(v); #endif _l += sizeof(T); @@ -248,12 +264,12 @@ public: * @param n Number of times to append * @throws std::out_of_range Attempt to append beyond capacity */ - inline void append(unsigned char c,unsigned int n) + inline void append(unsigned char c, unsigned int n) { if (unlikely((_l + n) > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - for(unsigned int i=0;i C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - Utils::getSecureRandom(_b + _l,n); + Utils::getSecureRandom(_b + _l, n); _l += n; } @@ -279,12 +295,12 @@ public: * @param l Length * @throws std::out_of_range Attempt to append beyond capacity */ - inline void append(const void *b,unsigned int l) + inline void append(const void* b, unsigned int l) { if (unlikely((_l + l) > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - memcpy(_b + _l,b,l); + memcpy(_b + _l, b, l); _l += l; } @@ -294,13 +310,13 @@ public: * @param s C string * @throws std::out_of_range Attempt to append beyond capacity */ - inline void appendCString(const char *s) + inline void appendCString(const char* s) { - for(;;) { + for (;;) { if (unlikely(_l >= C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - if (!(_b[_l++] = *(s++))) { + if (! (_b[_l++] = *(s++))) { break; } } @@ -313,10 +329,9 @@ public: * @tparam C2 Capacity of second buffer (typically inferred) * @throws std::out_of_range Attempt to append beyond capacity */ - template - inline void append(const Buffer &b) + template inline void append(const Buffer& b) { - append(b._b,b._l); + append(b._b, b._l); } /** @@ -329,12 +344,12 @@ public: * @param l Length of field to append * @return Pointer to beginning of appended field of length 'l' */ - inline char *appendField(unsigned int l) + inline char* appendField(unsigned int l) { if (unlikely((_l + l) > C)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - char *r = _b + _l; + char* r = _b + _l; _l += l; return r; } @@ -379,13 +394,13 @@ public: */ inline void behead(const unsigned int at) { - if (!at) { + if (! at) { return; } if (unlikely(at > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - ::memmove(_b,_b + at,_l -= at); + ::memmove(_b, _b + at, _l -= at); } /** @@ -395,92 +410,110 @@ public: * @param length Length of block to erase * @throws std::out_of_range Position plus length is beyond size of buffer */ - inline void erase(const unsigned int at,const unsigned int length) + inline void erase(const unsigned int at, const unsigned int length) { const unsigned int endr = at + length; if (unlikely(endr > _l)) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; } - ::memmove(_b + at,_b + endr,_l - endr); + ::memmove(_b + at, _b + endr, _l - endr); _l -= length; } /** * Set buffer data length to zero */ - inline void clear() { _l = 0; } + inline void clear() + { + _l = 0; + } /** * Zero buffer up to size() */ - inline void zero() { memset(_b,0,_l); } + inline void zero() + { + memset(_b, 0, _l); + } /** * Zero unused capacity area */ - inline void zeroUnused() { memset(_b + _l,0,C - _l); } + inline void zeroUnused() + { + memset(_b + _l, 0, C - _l); + } /** * Unconditionally and securely zero buffer's underlying memory */ - inline void burn() { Utils::burn(_b,sizeof(_b)); } + inline void burn() + { + Utils::burn(_b, sizeof(_b)); + } /** * @return Constant pointer to data in buffer */ - inline const void *data() const { return _b; } + inline const void* data() const + { + return _b; + } /** * @return Non-constant pointer to data in buffer */ - inline void *unsafeData() { return _b; } + inline void* unsafeData() + { + return _b; + } /** * @return Size of data in buffer */ - inline unsigned int size() const { return _l; } + inline unsigned int size() const + { + return _l; + } /** * @return Capacity of buffer */ - inline unsigned int capacity() const { return C; } + inline unsigned int capacity() const + { + return C; + } - template - inline bool operator==(const Buffer &b) const + template inline bool operator==(const Buffer& b) const { - return ((_l == b._l)&&(!memcmp(_b,b._b,_l))); + return ((_l == b._l) && (! memcmp(_b, b._b, _l))); } - template - inline bool operator!=(const Buffer &b) const + template inline bool operator!=(const Buffer& b) const { - return ((_l != b._l)||(memcmp(_b,b._b,_l))); + return ((_l != b._l) || (memcmp(_b, b._b, _l))); } - template - inline bool operator<(const Buffer &b) const + template inline bool operator<(const Buffer& b) const { - return (memcmp(_b,b._b,std::min(_l,b._l)) < 0); + return (memcmp(_b, b._b, std::min(_l, b._l)) < 0); } - template - inline bool operator>(const Buffer &b) const + template inline bool operator>(const Buffer& b) const { return (b < *this); } - template - inline bool operator<=(const Buffer &b) const + template inline bool operator<=(const Buffer& b) const { - return !(b < *this); + return ! (b < *this); } - template - inline bool operator>=(const Buffer &b) const + template inline bool operator>=(const Buffer& b) const { - return !(*this < b); + return ! (*this < b); } -private: + private: char ZT_VAR_MAY_ALIAS _b[C]; unsigned int _l; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/C25519.cpp b/node/C25519.cpp index f425540d8..77ff9dc5a 100644 --- a/node/C25519.cpp +++ b/node/C25519.cpp @@ -7,19 +7,20 @@ Derived from public domain code by D. J. Bernstein. // Modified very slightly for ZeroTier One by Adam Ierymenko // This code remains in the public domain. +#include "C25519.hpp" + +#include "Buffer.hpp" +#include "Constants.hpp" +#include "Hashtable.hpp" +#include "Mutex.hpp" +#include "SHA512.hpp" + #include #include #include -#include "Constants.hpp" -#include "C25519.hpp" -#include "SHA512.hpp" -#include "Buffer.hpp" -#include "Hashtable.hpp" -#include "Mutex.hpp" - #ifdef __WINDOWS__ -#pragma warning(disable: 4146) +#pragma warning(disable : 4146) #endif #ifdef __GNUC__ @@ -28,10 +29,10 @@ Derived from public domain code by D. J. Bernstein. namespace { -#define crypto_int32 int32_t -#define crypto_uint32 uint32_t -#define crypto_int64 int64_t -#define crypto_uint64 uint64_t +#define crypto_int32 int32_t +#define crypto_uint32 uint32_t +#define crypto_int64 int64_t +#define crypto_uint64 uint64_t #define crypto_hash_sha512_BYTES 64 ////////////////////////////////////////////////////////////////////////////// @@ -41,159 +42,92 @@ typedef uint8_t u8; typedef int32_t s32; typedef int64_t limb; -static inline void fsum(limb *output, const limb *in) { - unsigned i; - for (i = 0; i < 10; i += 2) { - output[0+i] = output[0+i] + in[0+i]; - output[1+i] = output[1+i] + in[1+i]; - } +static inline void fsum(limb* output, const limb* in) +{ + unsigned i; + for (i = 0; i < 10; i += 2) { + output[0 + i] = output[0 + i] + in[0 + i]; + output[1 + i] = output[1 + i] + in[1 + i]; + } } -static inline void fdifference(limb *output, const limb *in) { - unsigned i; - for (i = 0; i < 10; ++i) { - output[i] = in[i] - output[i]; - } +static inline void fdifference(limb* output, const limb* in) +{ + unsigned i; + for (i = 0; i < 10; ++i) { + output[i] = in[i] - output[i]; + } } -static inline void fscalar_product(limb *output, const limb *in, const limb scalar) { - unsigned i; - for (i = 0; i < 10; ++i) { - output[i] = in[i] * scalar; - } +static inline void fscalar_product(limb* output, const limb* in, const limb scalar) +{ + unsigned i; + for (i = 0; i < 10; ++i) { + output[i] = in[i] * scalar; + } } -static inline void fproduct(limb *output, const limb *in2, const limb *in) { - output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); - output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + - ((limb) ((s32) in2[1])) * ((s32) in[0]); - output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) + - ((limb) ((s32) in2[0])) * ((s32) in[2]) + - ((limb) ((s32) in2[2])) * ((s32) in[0]); - output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) + - ((limb) ((s32) in2[2])) * ((s32) in[1]) + - ((limb) ((s32) in2[0])) * ((s32) in[3]) + - ((limb) ((s32) in2[3])) * ((s32) in[0]); - output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) + - 2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) + - ((limb) ((s32) in2[3])) * ((s32) in[1])) + - ((limb) ((s32) in2[0])) * ((s32) in[4]) + - ((limb) ((s32) in2[4])) * ((s32) in[0]); - output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) + - ((limb) ((s32) in2[3])) * ((s32) in[2]) + - ((limb) ((s32) in2[1])) * ((s32) in[4]) + - ((limb) ((s32) in2[4])) * ((s32) in[1]) + - ((limb) ((s32) in2[0])) * ((s32) in[5]) + - ((limb) ((s32) in2[5])) * ((s32) in[0]); - output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) + - ((limb) ((s32) in2[1])) * ((s32) in[5]) + - ((limb) ((s32) in2[5])) * ((s32) in[1])) + - ((limb) ((s32) in2[2])) * ((s32) in[4]) + - ((limb) ((s32) in2[4])) * ((s32) in[2]) + - ((limb) ((s32) in2[0])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[0]); - output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) + - ((limb) ((s32) in2[4])) * ((s32) in[3]) + - ((limb) ((s32) in2[2])) * ((s32) in[5]) + - ((limb) ((s32) in2[5])) * ((s32) in[2]) + - ((limb) ((s32) in2[1])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[1]) + - ((limb) ((s32) in2[0])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[0]); - output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) + - 2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) + - ((limb) ((s32) in2[5])) * ((s32) in[3]) + - ((limb) ((s32) in2[1])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[1])) + - ((limb) ((s32) in2[2])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[2]) + - ((limb) ((s32) in2[0])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[0]); - output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) + - ((limb) ((s32) in2[5])) * ((s32) in[4]) + - ((limb) ((s32) in2[3])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[3]) + - ((limb) ((s32) in2[2])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[2]) + - ((limb) ((s32) in2[1])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[1]) + - ((limb) ((s32) in2[0])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[0]); - output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) + - ((limb) ((s32) in2[3])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[3]) + - ((limb) ((s32) in2[1])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[1])) + - ((limb) ((s32) in2[4])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[4]) + - ((limb) ((s32) in2[2])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[2]); - output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) + - ((limb) ((s32) in2[6])) * ((s32) in[5]) + - ((limb) ((s32) in2[4])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[4]) + - ((limb) ((s32) in2[3])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[3]) + - ((limb) ((s32) in2[2])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[2]); - output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) + - 2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[5]) + - ((limb) ((s32) in2[3])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[3])) + - ((limb) ((s32) in2[4])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[4]); - output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) + - ((limb) ((s32) in2[7])) * ((s32) in[6]) + - ((limb) ((s32) in2[5])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[5]) + - ((limb) ((s32) in2[4])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[4]); - output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) + - ((limb) ((s32) in2[5])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[5])) + - ((limb) ((s32) in2[6])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[6]); - output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) + - ((limb) ((s32) in2[8])) * ((s32) in[7]) + - ((limb) ((s32) in2[6])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[6]); - output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) + - 2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[7])); - output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) + - ((limb) ((s32) in2[9])) * ((s32) in[8]); - output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); +static inline void fproduct(limb* output, const limb* in2, const limb* in) +{ + output[0] = ((limb)((s32)in2[0])) * ((s32)in[0]); + output[1] = ((limb)((s32)in2[0])) * ((s32)in[1]) + ((limb)((s32)in2[1])) * ((s32)in[0]); + output[2] = 2 * ((limb)((s32)in2[1])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[2]) + ((limb)((s32)in2[2])) * ((s32)in[0]); + output[3] = ((limb)((s32)in2[1])) * ((s32)in[2]) + ((limb)((s32)in2[2])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[0]); + output[4] = ((limb)((s32)in2[2])) * ((s32)in[2]) + 2 * (((limb)((s32)in2[1])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[1])) + ((limb)((s32)in2[0])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[0]); + output[5] = + ((limb)((s32)in2[2])) * ((s32)in[3]) + ((limb)((s32)in2[3])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[0]); + output[6] = 2 * (((limb)((s32)in2[3])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[1])) + ((limb)((s32)in2[2])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[2]) + + ((limb)((s32)in2[0])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[0]); + output[7] = ((limb)((s32)in2[3])) * ((s32)in[4]) + ((limb)((s32)in2[4])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[6]) + + ((limb)((s32)in2[6])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[0]); + output[8] = ((limb)((s32)in2[4])) * ((s32)in[4]) + 2 * (((limb)((s32)in2[3])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[1])) + + ((limb)((s32)in2[2])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[2]) + ((limb)((s32)in2[0])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[0]); + output[9] = ((limb)((s32)in2[4])) * ((s32)in[5]) + ((limb)((s32)in2[5])) * ((s32)in[4]) + ((limb)((s32)in2[3])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[7]) + + ((limb)((s32)in2[7])) * ((s32)in[2]) + ((limb)((s32)in2[1])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[1]) + ((limb)((s32)in2[0])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[0]); + output[10] = 2 * (((limb)((s32)in2[5])) * ((s32)in[5]) + ((limb)((s32)in2[3])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[3]) + ((limb)((s32)in2[1])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[1])) + + ((limb)((s32)in2[4])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[4]) + ((limb)((s32)in2[2])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[2]); + output[11] = ((limb)((s32)in2[5])) * ((s32)in[6]) + ((limb)((s32)in2[6])) * ((s32)in[5]) + ((limb)((s32)in2[4])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[4]) + ((limb)((s32)in2[3])) * ((s32)in[8]) + + ((limb)((s32)in2[8])) * ((s32)in[3]) + ((limb)((s32)in2[2])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[2]); + output[12] = ((limb)((s32)in2[6])) * ((s32)in[6]) + 2 * (((limb)((s32)in2[5])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[5]) + ((limb)((s32)in2[3])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[3])) + + ((limb)((s32)in2[4])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[4]); + output[13] = + ((limb)((s32)in2[6])) * ((s32)in[7]) + ((limb)((s32)in2[7])) * ((s32)in[6]) + ((limb)((s32)in2[5])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[5]) + ((limb)((s32)in2[4])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[4]); + output[14] = 2 * (((limb)((s32)in2[7])) * ((s32)in[7]) + ((limb)((s32)in2[5])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[5])) + ((limb)((s32)in2[6])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[6]); + output[15] = ((limb)((s32)in2[7])) * ((s32)in[8]) + ((limb)((s32)in2[8])) * ((s32)in[7]) + ((limb)((s32)in2[6])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[6]); + output[16] = ((limb)((s32)in2[8])) * ((s32)in[8]) + 2 * (((limb)((s32)in2[7])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[7])); + output[17] = ((limb)((s32)in2[8])) * ((s32)in[9]) + ((limb)((s32)in2[9])) * ((s32)in[8]); + output[18] = 2 * ((limb)((s32)in2[9])) * ((s32)in[9]); } -static inline void freduce_degree(limb *output) { - output[8] += output[18] << 4; - output[8] += output[18] << 1; - output[8] += output[18]; - output[7] += output[17] << 4; - output[7] += output[17] << 1; - output[7] += output[17]; - output[6] += output[16] << 4; - output[6] += output[16] << 1; - output[6] += output[16]; - output[5] += output[15] << 4; - output[5] += output[15] << 1; - output[5] += output[15]; - output[4] += output[14] << 4; - output[4] += output[14] << 1; - output[4] += output[14]; - output[3] += output[13] << 4; - output[3] += output[13] << 1; - output[3] += output[13]; - output[2] += output[12] << 4; - output[2] += output[12] << 1; - output[2] += output[12]; - output[1] += output[11] << 4; - output[1] += output[11] << 1; - output[1] += output[11]; - output[0] += output[10] << 4; - output[0] += output[10] << 1; - output[0] += output[10]; +static inline void freduce_degree(limb* output) +{ + output[8] += output[18] << 4; + output[8] += output[18] << 1; + output[8] += output[18]; + output[7] += output[17] << 4; + output[7] += output[17] << 1; + output[7] += output[17]; + output[6] += output[16] << 4; + output[6] += output[16] << 1; + output[6] += output[16]; + output[5] += output[15] << 4; + output[5] += output[15] << 1; + output[5] += output[15]; + output[4] += output[14] << 4; + output[4] += output[14] << 1; + output[4] += output[14]; + output[3] += output[13] << 4; + output[3] += output[13] << 1; + output[3] += output[13]; + output[2] += output[12] << 4; + output[2] += output[12] << 1; + output[2] += output[12]; + output[1] += output[11] << 4; + output[1] += output[11] << 1; + output[1] += output[11]; + output[0] += output[10] << 4; + output[0] += output[10] << 1; + output[0] += output[10]; } #if (-1 & 3) != 3 @@ -202,167 +136,132 @@ static inline void freduce_degree(limb *output) { static inline limb div_by_2_26(const limb v) { - /* High word of v; no shift needed. */ - const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); - /* Set to all 1s if v was negative; else set to 0s. */ - const int32_t sign = ((int32_t) highword) >> 31; - /* Set to 0x3ffffff if v was negative; else set to 0. */ - const int32_t roundoff = ((uint32_t) sign) >> 6; - /* Should return v / (1<<26) */ - return (v + roundoff) >> 26; + /* High word of v; no shift needed. */ + const uint32_t highword = (uint32_t)(((uint64_t)v) >> 32); + /* Set to all 1s if v was negative; else set to 0s. */ + const int32_t sign = ((int32_t)highword) >> 31; + /* Set to 0x3ffffff if v was negative; else set to 0. */ + const int32_t roundoff = ((uint32_t)sign) >> 6; + /* Should return v / (1<<26) */ + return (v + roundoff) >> 26; } static inline limb div_by_2_25(const limb v) { - /* High word of v; no shift needed*/ - const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); - /* Set to all 1s if v was negative; else set to 0s. */ - const int32_t sign = ((int32_t) highword) >> 31; - /* Set to 0x1ffffff if v was negative; else set to 0. */ - const int32_t roundoff = ((uint32_t) sign) >> 7; - /* Should return v / (1<<25) */ - return (v + roundoff) >> 25; + /* High word of v; no shift needed*/ + const uint32_t highword = (uint32_t)(((uint64_t)v) >> 32); + /* Set to all 1s if v was negative; else set to 0s. */ + const int32_t sign = ((int32_t)highword) >> 31; + /* Set to 0x1ffffff if v was negative; else set to 0. */ + const int32_t roundoff = ((uint32_t)sign) >> 7; + /* Should return v / (1<<25) */ + return (v + roundoff) >> 25; } -static inline void freduce_coefficients(limb *output) { - unsigned i; +static inline void freduce_coefficients(limb* output) +{ + unsigned i; - output[10] = 0; + output[10] = 0; - for (i = 0; i < 10; i += 2) { - limb over = div_by_2_26(output[i]); - /* The entry condition (that |output[i]| < 280*2^54) means that over is, at - * most, 280*2^28 in the first iteration of this loop. This is added to the - * next limb and we can approximate the resulting bound of that limb by - * 281*2^54. */ - output[i] -= over << 26; - output[i+1] += over; + for (i = 0; i < 10; i += 2) { + limb over = div_by_2_26(output[i]); + /* The entry condition (that |output[i]| < 280*2^54) means that over is, at + * most, 280*2^28 in the first iteration of this loop. This is added to the + * next limb and we can approximate the resulting bound of that limb by + * 281*2^54. */ + output[i] -= over << 26; + output[i + 1] += over; - /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < - * 281*2^29. When this is added to the next limb, the resulting bound can - * be approximated as 281*2^54. - * - * For subsequent iterations of the loop, 281*2^54 remains a conservative - * bound and no overflow occurs. */ - over = div_by_2_25(output[i+1]); - output[i+1] -= over << 25; - output[i+2] += over; - } - /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ - output[0] += output[10] << 4; - output[0] += output[10] << 1; - output[0] += output[10]; + /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < + * 281*2^29. When this is added to the next limb, the resulting bound can + * be approximated as 281*2^54. + * + * For subsequent iterations of the loop, 281*2^54 remains a conservative + * bound and no overflow occurs. */ + over = div_by_2_25(output[i + 1]); + output[i + 1] -= over << 25; + output[i + 2] += over; + } + /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ + output[0] += output[10] << 4; + output[0] += output[10] << 1; + output[0] += output[10]; - output[10] = 0; + output[10] = 0; - /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 - * So |over| will be no more than 2^16. */ - { - limb over = div_by_2_26(output[0]); - output[0] -= over << 26; - output[1] += over; - } + /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 + * So |over| will be no more than 2^16. */ + { + limb over = div_by_2_26(output[0]); + output[0] -= over << 26; + output[1] += over; + } - /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The - * bound on |output[1]| is sufficient to meet our needs. */ + /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The + * bound on |output[1]| is sufficient to meet our needs. */ } -static inline void fmul(limb *output, const limb *in, const limb *in2) { - limb t[19]; - fproduct(t, in, in2); - /* |t[i]| < 14*2^54 */ - freduce_degree(t); - freduce_coefficients(t); - /* |t[i]| < 2^26 */ - memcpy(output, t, sizeof(limb) * 10); +static inline void fmul(limb* output, const limb* in, const limb* in2) +{ + limb t[19]; + fproduct(t, in, in2); + /* |t[i]| < 14*2^54 */ + freduce_degree(t); + freduce_coefficients(t); + /* |t[i]| < 2^26 */ + memcpy(output, t, sizeof(limb) * 10); } -static inline void fsquare_inner(limb *output, const limb *in) { - output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); - output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); - output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + - ((limb) ((s32) in[0])) * ((s32) in[2])); - output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) + - ((limb) ((s32) in[0])) * ((s32) in[3])); - output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) + - 4 * ((limb) ((s32) in[1])) * ((s32) in[3]) + - 2 * ((limb) ((s32) in[0])) * ((s32) in[4]); - output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) + - ((limb) ((s32) in[1])) * ((s32) in[4]) + - ((limb) ((s32) in[0])) * ((s32) in[5])); - output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) + - ((limb) ((s32) in[2])) * ((s32) in[4]) + - ((limb) ((s32) in[0])) * ((s32) in[6]) + - 2 * ((limb) ((s32) in[1])) * ((s32) in[5])); - output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) + - ((limb) ((s32) in[2])) * ((s32) in[5]) + - ((limb) ((s32) in[1])) * ((s32) in[6]) + - ((limb) ((s32) in[0])) * ((s32) in[7])); - output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) + - 2 * (((limb) ((s32) in[2])) * ((s32) in[6]) + - ((limb) ((s32) in[0])) * ((s32) in[8]) + - 2 * (((limb) ((s32) in[1])) * ((s32) in[7]) + - ((limb) ((s32) in[3])) * ((s32) in[5]))); - output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) + - ((limb) ((s32) in[3])) * ((s32) in[6]) + - ((limb) ((s32) in[2])) * ((s32) in[7]) + - ((limb) ((s32) in[1])) * ((s32) in[8]) + - ((limb) ((s32) in[0])) * ((s32) in[9])); - output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) + - ((limb) ((s32) in[4])) * ((s32) in[6]) + - ((limb) ((s32) in[2])) * ((s32) in[8]) + - 2 * (((limb) ((s32) in[3])) * ((s32) in[7]) + - ((limb) ((s32) in[1])) * ((s32) in[9]))); - output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) + - ((limb) ((s32) in[4])) * ((s32) in[7]) + - ((limb) ((s32) in[3])) * ((s32) in[8]) + - ((limb) ((s32) in[2])) * ((s32) in[9])); - output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) + - 2 * (((limb) ((s32) in[4])) * ((s32) in[8]) + - 2 * (((limb) ((s32) in[5])) * ((s32) in[7]) + - ((limb) ((s32) in[3])) * ((s32) in[9]))); - output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) + - ((limb) ((s32) in[5])) * ((s32) in[8]) + - ((limb) ((s32) in[4])) * ((s32) in[9])); - output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) + - ((limb) ((s32) in[6])) * ((s32) in[8]) + - 2 * ((limb) ((s32) in[5])) * ((s32) in[9])); - output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) + - ((limb) ((s32) in[6])) * ((s32) in[9])); - output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) + - 4 * ((limb) ((s32) in[7])) * ((s32) in[9]); - output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]); - output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); +static inline void fsquare_inner(limb* output, const limb* in) +{ + output[0] = ((limb)((s32)in[0])) * ((s32)in[0]); + output[1] = 2 * ((limb)((s32)in[0])) * ((s32)in[1]); + output[2] = 2 * (((limb)((s32)in[1])) * ((s32)in[1]) + ((limb)((s32)in[0])) * ((s32)in[2])); + output[3] = 2 * (((limb)((s32)in[1])) * ((s32)in[2]) + ((limb)((s32)in[0])) * ((s32)in[3])); + output[4] = ((limb)((s32)in[2])) * ((s32)in[2]) + 4 * ((limb)((s32)in[1])) * ((s32)in[3]) + 2 * ((limb)((s32)in[0])) * ((s32)in[4]); + output[5] = 2 * (((limb)((s32)in[2])) * ((s32)in[3]) + ((limb)((s32)in[1])) * ((s32)in[4]) + ((limb)((s32)in[0])) * ((s32)in[5])); + output[6] = 2 * (((limb)((s32)in[3])) * ((s32)in[3]) + ((limb)((s32)in[2])) * ((s32)in[4]) + ((limb)((s32)in[0])) * ((s32)in[6]) + 2 * ((limb)((s32)in[1])) * ((s32)in[5])); + output[7] = 2 * (((limb)((s32)in[3])) * ((s32)in[4]) + ((limb)((s32)in[2])) * ((s32)in[5]) + ((limb)((s32)in[1])) * ((s32)in[6]) + ((limb)((s32)in[0])) * ((s32)in[7])); + output[8] = ((limb)((s32)in[4])) * ((s32)in[4]) + 2 * (((limb)((s32)in[2])) * ((s32)in[6]) + ((limb)((s32)in[0])) * ((s32)in[8]) + 2 * (((limb)((s32)in[1])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[5]))); + output[9] = 2 * (((limb)((s32)in[4])) * ((s32)in[5]) + ((limb)((s32)in[3])) * ((s32)in[6]) + ((limb)((s32)in[2])) * ((s32)in[7]) + ((limb)((s32)in[1])) * ((s32)in[8]) + ((limb)((s32)in[0])) * ((s32)in[9])); + output[10] = 2 * (((limb)((s32)in[5])) * ((s32)in[5]) + ((limb)((s32)in[4])) * ((s32)in[6]) + ((limb)((s32)in[2])) * ((s32)in[8]) + 2 * (((limb)((s32)in[3])) * ((s32)in[7]) + ((limb)((s32)in[1])) * ((s32)in[9]))); + output[11] = 2 * (((limb)((s32)in[5])) * ((s32)in[6]) + ((limb)((s32)in[4])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[8]) + ((limb)((s32)in[2])) * ((s32)in[9])); + output[12] = ((limb)((s32)in[6])) * ((s32)in[6]) + 2 * (((limb)((s32)in[4])) * ((s32)in[8]) + 2 * (((limb)((s32)in[5])) * ((s32)in[7]) + ((limb)((s32)in[3])) * ((s32)in[9]))); + output[13] = 2 * (((limb)((s32)in[6])) * ((s32)in[7]) + ((limb)((s32)in[5])) * ((s32)in[8]) + ((limb)((s32)in[4])) * ((s32)in[9])); + output[14] = 2 * (((limb)((s32)in[7])) * ((s32)in[7]) + ((limb)((s32)in[6])) * ((s32)in[8]) + 2 * ((limb)((s32)in[5])) * ((s32)in[9])); + output[15] = 2 * (((limb)((s32)in[7])) * ((s32)in[8]) + ((limb)((s32)in[6])) * ((s32)in[9])); + output[16] = ((limb)((s32)in[8])) * ((s32)in[8]) + 4 * ((limb)((s32)in[7])) * ((s32)in[9]); + output[17] = 2 * ((limb)((s32)in[8])) * ((s32)in[9]); + output[18] = 2 * ((limb)((s32)in[9])) * ((s32)in[9]); } -static void fsquare(limb *output, const limb *in) { - limb t[19]; - fsquare_inner(t, in); - /* |t[i]| < 14*2^54 because the largest product of two limbs will be < - * 2^(27+27) and fsquare_inner adds together, at most, 14 of those - * products. */ - freduce_degree(t); - freduce_coefficients(t); - /* |t[i]| < 2^26 */ - memcpy(output, t, sizeof(limb) * 10); +static void fsquare(limb* output, const limb* in) +{ + limb t[19]; + fsquare_inner(t, in); + /* |t[i]| < 14*2^54 because the largest product of two limbs will be < + * 2^(27+27) and fsquare_inner adds together, at most, 14 of those + * products. */ + freduce_degree(t); + freduce_coefficients(t); + /* |t[i]| < 2^26 */ + memcpy(output, t, sizeof(limb) * 10); } -static inline void fexpand(limb *output, const u8 *input) { -#define F(n,start,shift,mask) \ - output[n] = ((((limb) input[start + 0]) | \ - ((limb) input[start + 1]) << 8 | \ - ((limb) input[start + 2]) << 16 | \ - ((limb) input[start + 3]) << 24) >> shift) & mask; - F(0, 0, 0, 0x3ffffff); - F(1, 3, 2, 0x1ffffff); - F(2, 6, 3, 0x3ffffff); - F(3, 9, 5, 0x1ffffff); - F(4, 12, 6, 0x3ffffff); - F(5, 16, 0, 0x1ffffff); - F(6, 19, 1, 0x3ffffff); - F(7, 22, 3, 0x1ffffff); - F(8, 25, 4, 0x3ffffff); - F(9, 28, 6, 0x1ffffff); +static inline void fexpand(limb* output, const u8* input) +{ +#define F(n, start, shift, mask) output[n] = ((((limb)input[start + 0]) | ((limb)input[start + 1]) << 8 | ((limb)input[start + 2]) << 16 | ((limb)input[start + 3]) << 24) >> shift) & mask; + F(0, 0, 0, 0x3ffffff); + F(1, 3, 2, 0x1ffffff); + F(2, 6, 3, 0x3ffffff); + F(3, 9, 5, 0x1ffffff); + F(4, 12, 6, 0x3ffffff); + F(5, 16, 0, 0x1ffffff); + F(6, 19, 1, 0x3ffffff); + F(7, 22, 3, 0x1ffffff); + F(8, 25, 4, 0x3ffffff); + F(9, 28, 6, 0x1ffffff); #undef F } @@ -370,385 +269,415 @@ static inline void fexpand(limb *output, const u8 *input) { #error "This code only works when >> does sign-extension on negative numbers" #endif -static inline s32 s32_eq(s32 a, s32 b) { - a = ~(a ^ b); - a &= a << 16; - a &= a << 8; - a &= a << 4; - a &= a << 2; - a &= a << 1; - return a >> 31; +static inline s32 s32_eq(s32 a, s32 b) +{ + a = ~(a ^ b); + a &= a << 16; + a &= a << 8; + a &= a << 4; + a &= a << 2; + a &= a << 1; + return a >> 31; } -static inline s32 s32_gte(s32 a, s32 b) { - a -= b; - /* a >= 0 iff a >= b. */ - return ~(a >> 31); +static inline s32 s32_gte(s32 a, s32 b) +{ + a -= b; + /* a >= 0 iff a >= b. */ + return ~(a >> 31); } -static inline void fcontract(u8 *output, limb *input_limbs) { - int i; - int j; - s32 input[10]; - s32 mask; +static inline void fcontract(u8* output, limb* input_limbs) +{ + int i; + int j; + s32 input[10]; + s32 mask; - /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ - for (i = 0; i < 10; i++) { - input[i] = input_limbs[i]; - } + /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ + for (i = 0; i < 10; i++) { + input[i] = input_limbs[i]; + } - for (j = 0; j < 2; ++j) { - for (i = 0; i < 9; ++i) { - if ((i & 1) == 1) { - /* This calculation is a time-invariant way to make input[i] - * non-negative by borrowing from the next-larger limb. */ - const s32 mask = input[i] >> 31; - const s32 carry = -((input[i] & mask) >> 25); - input[i] = input[i] + (carry << 25); - input[i+1] = input[i+1] - carry; - } else { - const s32 mask = input[i] >> 31; - const s32 carry = -((input[i] & mask) >> 26); - input[i] = input[i] + (carry << 26); - input[i+1] = input[i+1] - carry; - } - } + for (j = 0; j < 2; ++j) { + for (i = 0; i < 9; ++i) { + if ((i & 1) == 1) { + /* This calculation is a time-invariant way to make input[i] + * non-negative by borrowing from the next-larger limb. */ + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 25); + input[i] = input[i] + (carry << 25); + input[i + 1] = input[i + 1] - carry; + } + else { + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 26); + input[i] = input[i] + (carry << 26); + input[i + 1] = input[i + 1] - carry; + } + } - /* There's no greater limb for input[9] to borrow from, but we can multiply - * by 19 and borrow from input[0], which is valid mod 2^255-19. */ - { - const s32 mask = input[9] >> 31; - const s32 carry = -((input[9] & mask) >> 25); - input[9] = input[9] + (carry << 25); - input[0] = input[0] - (carry * 19); - } + /* There's no greater limb for input[9] to borrow from, but we can multiply + * by 19 and borrow from input[0], which is valid mod 2^255-19. */ + { + const s32 mask = input[9] >> 31; + const s32 carry = -((input[9] & mask) >> 25); + input[9] = input[9] + (carry << 25); + input[0] = input[0] - (carry * 19); + } - /* After the first iteration, input[1..9] are non-negative and fit within - * 25 or 26 bits, depending on position. However, input[0] may be - * negative. */ - } + /* After the first iteration, input[1..9] are non-negative and fit within + * 25 or 26 bits, depending on position. However, input[0] may be + * negative. */ + } - /* The first borrow-propagation pass above ended with every limb - except (possibly) input[0] non-negative. + /* The first borrow-propagation pass above ended with every limb + except (possibly) input[0] non-negative. - If input[0] was negative after the first pass, then it was because of a - carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, - one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. + If input[0] was negative after the first pass, then it was because of a + carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, + one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. - In the second pass, each limb is decreased by at most one. Thus the second - borrow-propagation pass could only have wrapped around to decrease - input[0] again if the first pass left input[0] negative *and* input[1] - through input[9] were all zero. In that case, input[1] is now 2^25 - 1, - and this last borrow-propagation step will leave input[1] non-negative. */ - { - const s32 mask = input[0] >> 31; - const s32 carry = -((input[0] & mask) >> 26); - input[0] = input[0] + (carry << 26); - input[1] = input[1] - carry; - } + In the second pass, each limb is decreased by at most one. Thus the second + borrow-propagation pass could only have wrapped around to decrease + input[0] again if the first pass left input[0] negative *and* input[1] + through input[9] were all zero. In that case, input[1] is now 2^25 - 1, + and this last borrow-propagation step will leave input[1] non-negative. */ + { + const s32 mask = input[0] >> 31; + const s32 carry = -((input[0] & mask) >> 26); + input[0] = input[0] + (carry << 26); + input[1] = input[1] - carry; + } - /* All input[i] are now non-negative. However, there might be values between - * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ - for (j = 0; j < 2; j++) { - for (i = 0; i < 9; i++) { - if ((i & 1) == 1) { - const s32 carry = input[i] >> 25; - input[i] &= 0x1ffffff; - input[i+1] += carry; - } else { - const s32 carry = input[i] >> 26; - input[i] &= 0x3ffffff; - input[i+1] += carry; - } - } + /* All input[i] are now non-negative. However, there might be values between + * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ + for (j = 0; j < 2; j++) { + for (i = 0; i < 9; i++) { + if ((i & 1) == 1) { + const s32 carry = input[i] >> 25; + input[i] &= 0x1ffffff; + input[i + 1] += carry; + } + else { + const s32 carry = input[i] >> 26; + input[i] &= 0x3ffffff; + input[i + 1] += carry; + } + } - { - const s32 carry = input[9] >> 25; - input[9] &= 0x1ffffff; - input[0] += 19*carry; - } - } + { + const s32 carry = input[9] >> 25; + input[9] &= 0x1ffffff; + input[0] += 19 * carry; + } + } - /* If the first carry-chain pass, just above, ended up with a carry from - * input[9], and that caused input[0] to be out-of-bounds, then input[0] was - * < 2^26 + 2*19, because the carry was, at most, two. - * - * If the second pass carried from input[9] again then input[0] is < 2*19 and - * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ + /* If the first carry-chain pass, just above, ended up with a carry from + * input[9], and that caused input[0] to be out-of-bounds, then input[0] was + * < 2^26 + 2*19, because the carry was, at most, two. + * + * If the second pass carried from input[9] again then input[0] is < 2*19 and + * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ - /* It still remains the case that input might be between 2^255-19 and 2^255. - * In this case, input[1..9] must take their maximum value and input[0] must - * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ - mask = s32_gte(input[0], 0x3ffffed); - for (i = 1; i < 10; i++) { - if ((i & 1) == 1) { - mask &= s32_eq(input[i], 0x1ffffff); - } else { - mask &= s32_eq(input[i], 0x3ffffff); - } - } + /* It still remains the case that input might be between 2^255-19 and 2^255. + * In this case, input[1..9] must take their maximum value and input[0] must + * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ + mask = s32_gte(input[0], 0x3ffffed); + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + mask &= s32_eq(input[i], 0x1ffffff); + } + else { + mask &= s32_eq(input[i], 0x3ffffff); + } + } - /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus - * this conditionally subtracts 2^255-19. */ - input[0] -= mask & 0x3ffffed; + /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus + * this conditionally subtracts 2^255-19. */ + input[0] -= mask & 0x3ffffed; - for (i = 1; i < 10; i++) { - if ((i & 1) == 1) { - input[i] -= mask & 0x1ffffff; - } else { - input[i] -= mask & 0x3ffffff; - } - } + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + input[i] -= mask & 0x1ffffff; + } + else { + input[i] -= mask & 0x3ffffff; + } + } - input[1] <<= 2; - input[2] <<= 3; - input[3] <<= 5; - input[4] <<= 6; - input[6] <<= 1; - input[7] <<= 3; - input[8] <<= 4; - input[9] <<= 6; -#define F(i, s) \ - output[s+0] |= input[i] & 0xff; \ - output[s+1] = (input[i] >> 8) & 0xff; \ - output[s+2] = (input[i] >> 16) & 0xff; \ - output[s+3] = (input[i] >> 24) & 0xff; - output[0] = 0; - output[16] = 0; - F(0,0); - F(1,3); - F(2,6); - F(3,9); - F(4,12); - F(5,16); - F(6,19); - F(7,22); - F(8,25); - F(9,28); + input[1] <<= 2; + input[2] <<= 3; + input[3] <<= 5; + input[4] <<= 6; + input[6] <<= 1; + input[7] <<= 3; + input[8] <<= 4; + input[9] <<= 6; +#define F(i, s) \ + output[s + 0] |= input[i] & 0xff; \ + output[s + 1] = (input[i] >> 8) & 0xff; \ + output[s + 2] = (input[i] >> 16) & 0xff; \ + output[s + 3] = (input[i] >> 24) & 0xff; + output[0] = 0; + output[16] = 0; + F(0, 0); + F(1, 3); + F(2, 6); + F(3, 9); + F(4, 12); + F(5, 16); + F(6, 19); + F(7, 22); + F(8, 25); + F(9, 28); #undef F } -static inline void fmonty(limb *x2, limb *z2, /* output 2Q */ - limb *x3, limb *z3, /* output Q + Q' */ - limb *x, limb *z, /* input Q */ - limb *xprime, limb *zprime, /* input Q' */ - const limb *qmqp /* input Q - Q' */) { - limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], - zzprime[19], zzzprime[19], xxxprime[19]; - - memcpy(origx, x, 10 * sizeof(limb)); - fsum(x, z); - /* |x[i]| < 2^27 */ - fdifference(z, origx); /* does x - z */ - /* |z[i]| < 2^27 */ - - memcpy(origxprime, xprime, sizeof(limb) * 10); - fsum(xprime, zprime); - /* |xprime[i]| < 2^27 */ - fdifference(zprime, origxprime); - /* |zprime[i]| < 2^27 */ - fproduct(xxprime, xprime, z); - /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < - * 2^(27+27) and fproduct adds together, at most, 14 of those products. - * (Approximating that to 2^58 doesn't work out.) */ - fproduct(zzprime, x, zprime); - /* |zzprime[i]| < 14*2^54 */ - freduce_degree(xxprime); - freduce_coefficients(xxprime); - /* |xxprime[i]| < 2^26 */ - freduce_degree(zzprime); - freduce_coefficients(zzprime); - /* |zzprime[i]| < 2^26 */ - memcpy(origxprime, xxprime, sizeof(limb) * 10); - fsum(xxprime, zzprime); - /* |xxprime[i]| < 2^27 */ - fdifference(zzprime, origxprime); - /* |zzprime[i]| < 2^27 */ - fsquare(xxxprime, xxprime); - /* |xxxprime[i]| < 2^26 */ - fsquare(zzzprime, zzprime); - /* |zzzprime[i]| < 2^26 */ - fproduct(zzprime, zzzprime, qmqp); - /* |zzprime[i]| < 14*2^52 */ - freduce_degree(zzprime); - freduce_coefficients(zzprime); - /* |zzprime[i]| < 2^26 */ - memcpy(x3, xxxprime, sizeof(limb) * 10); - memcpy(z3, zzprime, sizeof(limb) * 10); - - fsquare(xx, x); - /* |xx[i]| < 2^26 */ - fsquare(zz, z); - /* |zz[i]| < 2^26 */ - fproduct(x2, xx, zz); - /* |x2[i]| < 14*2^52 */ - freduce_degree(x2); - freduce_coefficients(x2); - /* |x2[i]| < 2^26 */ - fdifference(zz, xx); // does zz = xx - zz - /* |zz[i]| < 2^27 */ - memset(zzz + 10, 0, sizeof(limb) * 9); - fscalar_product(zzz, zz, 121665); - /* |zzz[i]| < 2^(27+17) */ - /* No need to call freduce_degree here: - fscalar_product doesn't increase the degree of its input. */ - freduce_coefficients(zzz); - /* |zzz[i]| < 2^26 */ - fsum(zzz, xx); - /* |zzz[i]| < 2^27 */ - fproduct(z2, zz, zzz); - /* |z2[i]| < 14*2^(26+27) */ - freduce_degree(z2); - freduce_coefficients(z2); - /* |z2|i| < 2^26 */ -} - -static inline void swap_conditional(limb a[19], limb b[19], limb iswap) { - unsigned i; - const s32 swap = (s32) -iswap; - - for (i = 0; i < 10; ++i) { - const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) ); - a[i] = ((s32)a[i]) ^ x; - b[i] = ((s32)b[i]) ^ x; - } -} - -static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { - limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0}; - limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; - limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1}; - limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; - - unsigned i, j; - - memcpy(nqpqx, q, sizeof(limb) * 10); - - for (i = 0; i < 32; ++i) { - u8 byte = n[31 - i]; - for (j = 0; j < 8; ++j) { - const limb bit = byte >> 7; - - swap_conditional(nqx, nqpqx, bit); - swap_conditional(nqz, nqpqz, bit); - fmonty(nqx2, nqz2, - nqpqx2, nqpqz2, - nqx, nqz, - nqpqx, nqpqz, - q); - swap_conditional(nqx2, nqpqx2, bit); - swap_conditional(nqz2, nqpqz2, bit); - - t = nqx; - nqx = nqx2; - nqx2 = t; - t = nqz; - nqz = nqz2; - nqz2 = t; - t = nqpqx; - nqpqx = nqpqx2; - nqpqx2 = t; - t = nqpqz; - nqpqz = nqpqz2; - nqpqz2 = t; - - byte <<= 1; - } - } - - memcpy(resultx, nqx, sizeof(limb) * 10); - memcpy(resultz, nqz, sizeof(limb) * 10); -} - -static inline void crecip(limb *out, const limb *z) { - limb z2[10]; - limb z9[10]; - limb z11[10]; - limb z2_5_0[10]; - limb z2_10_0[10]; - limb z2_20_0[10]; - limb z2_50_0[10]; - limb z2_100_0[10]; - limb t0[10]; - limb t1[10]; - int i; - - /* 2 */ fsquare(z2,z); - /* 4 */ fsquare(t1,z2); - /* 8 */ fsquare(t0,t1); - /* 9 */ fmul(z9,t0,z); - /* 11 */ fmul(z11,z9,z2); - /* 22 */ fsquare(t0,z11); - /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9); - - /* 2^6 - 2^1 */ fsquare(t0,z2_5_0); - /* 2^7 - 2^2 */ fsquare(t1,t0); - /* 2^8 - 2^3 */ fsquare(t0,t1); - /* 2^9 - 2^4 */ fsquare(t1,t0); - /* 2^10 - 2^5 */ fsquare(t0,t1); - /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0); - - /* 2^11 - 2^1 */ fsquare(t0,z2_10_0); - /* 2^12 - 2^2 */ fsquare(t1,t0); - /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } - /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0); - - /* 2^21 - 2^1 */ fsquare(t0,z2_20_0); - /* 2^22 - 2^2 */ fsquare(t1,t0); - /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } - /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0); - - /* 2^41 - 2^1 */ fsquare(t1,t0); - /* 2^42 - 2^2 */ fsquare(t0,t1); - /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } - /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0); - - /* 2^51 - 2^1 */ fsquare(t0,z2_50_0); - /* 2^52 - 2^2 */ fsquare(t1,t0); - /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } - /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0); - - /* 2^101 - 2^1 */ fsquare(t1,z2_100_0); - /* 2^102 - 2^2 */ fsquare(t0,t1); - /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } - /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0); - - /* 2^201 - 2^1 */ fsquare(t0,t1); - /* 2^202 - 2^2 */ fsquare(t1,t0); - /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } - /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0); - - /* 2^251 - 2^1 */ fsquare(t1,t0); - /* 2^252 - 2^2 */ fsquare(t0,t1); - /* 2^253 - 2^3 */ fsquare(t1,t0); - /* 2^254 - 2^4 */ fsquare(t0,t1); - /* 2^255 - 2^5 */ fsquare(t1,t0); - /* 2^255 - 21 */ fmul(out,t1,z11); -} - -static void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) { - limb bp[10], x[10], z[11], zmone[10]; - uint8_t e[32]; - int i; - - for (i = 0; i < 32; ++i) { - e[i] = secret[i]; - } - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; - - fexpand(bp, basepoint); - cmult(x, z, e, bp); - crecip(zmone, z); - fmul(z, x, zmone); - fcontract(mypublic, z); -} - -static const unsigned char base[32] = {9}; -static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) +static inline void fmonty( + limb* x2, + limb* z2, /* output 2Q */ + limb* x3, + limb* z3, /* output Q + Q' */ + limb* x, + limb* z, /* input Q */ + limb* xprime, + limb* zprime, /* input Q' */ + const limb* qmqp /* input Q - Q' */) { - crypto_scalarmult(q,n,base); + limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], zzprime[19], zzzprime[19], xxxprime[19]; + + memcpy(origx, x, 10 * sizeof(limb)); + fsum(x, z); + /* |x[i]| < 2^27 */ + fdifference(z, origx); /* does x - z */ + /* |z[i]| < 2^27 */ + + memcpy(origxprime, xprime, sizeof(limb) * 10); + fsum(xprime, zprime); + /* |xprime[i]| < 2^27 */ + fdifference(zprime, origxprime); + /* |zprime[i]| < 2^27 */ + fproduct(xxprime, xprime, z); + /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < + * 2^(27+27) and fproduct adds together, at most, 14 of those products. + * (Approximating that to 2^58 doesn't work out.) */ + fproduct(zzprime, x, zprime); + /* |zzprime[i]| < 14*2^54 */ + freduce_degree(xxprime); + freduce_coefficients(xxprime); + /* |xxprime[i]| < 2^26 */ + freduce_degree(zzprime); + freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ + memcpy(origxprime, xxprime, sizeof(limb) * 10); + fsum(xxprime, zzprime); + /* |xxprime[i]| < 2^27 */ + fdifference(zzprime, origxprime); + /* |zzprime[i]| < 2^27 */ + fsquare(xxxprime, xxprime); + /* |xxxprime[i]| < 2^26 */ + fsquare(zzzprime, zzprime); + /* |zzzprime[i]| < 2^26 */ + fproduct(zzprime, zzzprime, qmqp); + /* |zzprime[i]| < 14*2^52 */ + freduce_degree(zzprime); + freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ + memcpy(x3, xxxprime, sizeof(limb) * 10); + memcpy(z3, zzprime, sizeof(limb) * 10); + + fsquare(xx, x); + /* |xx[i]| < 2^26 */ + fsquare(zz, z); + /* |zz[i]| < 2^26 */ + fproduct(x2, xx, zz); + /* |x2[i]| < 14*2^52 */ + freduce_degree(x2); + freduce_coefficients(x2); + /* |x2[i]| < 2^26 */ + fdifference(zz, xx); // does zz = xx - zz + /* |zz[i]| < 2^27 */ + memset(zzz + 10, 0, sizeof(limb) * 9); + fscalar_product(zzz, zz, 121665); + /* |zzz[i]| < 2^(27+17) */ + /* No need to call freduce_degree here: + fscalar_product doesn't increase the degree of its input. */ + freduce_coefficients(zzz); + /* |zzz[i]| < 2^26 */ + fsum(zzz, xx); + /* |zzz[i]| < 2^27 */ + fproduct(z2, zz, zzz); + /* |z2[i]| < 14*2^(26+27) */ + freduce_degree(z2); + freduce_coefficients(z2); + /* |z2|i| < 2^26 */ +} + +static inline void swap_conditional(limb a[19], limb b[19], limb iswap) +{ + unsigned i; + const s32 swap = (s32)-iswap; + + for (i = 0; i < 10; ++i) { + const s32 x = swap & (((s32)a[i]) ^ ((s32)b[i])); + a[i] = ((s32)a[i]) ^ x; + b[i] = ((s32)b[i]) ^ x; + } +} + +static inline void cmult(limb* resultx, limb* resultz, const u8* n, const limb* q) +{ + limb a[19] = { 0 }, b[19] = { 1 }, c[19] = { 1 }, d[19] = { 0 }; + limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; + limb e[19] = { 0 }, f[19] = { 1 }, g[19] = { 0 }, h[19] = { 1 }; + limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; + + unsigned i, j; + + memcpy(nqpqx, q, sizeof(limb) * 10); + + for (i = 0; i < 32; ++i) { + u8 byte = n[31 - i]; + for (j = 0; j < 8; ++j) { + const limb bit = byte >> 7; + + swap_conditional(nqx, nqpqx, bit); + swap_conditional(nqz, nqpqz, bit); + fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); + swap_conditional(nqx2, nqpqx2, bit); + swap_conditional(nqz2, nqpqz2, bit); + + t = nqx; + nqx = nqx2; + nqx2 = t; + t = nqz; + nqz = nqz2; + nqz2 = t; + t = nqpqx; + nqpqx = nqpqx2; + nqpqx2 = t; + t = nqpqz; + nqpqz = nqpqz2; + nqpqz2 = t; + + byte <<= 1; + } + } + + memcpy(resultx, nqx, sizeof(limb) * 10); + memcpy(resultz, nqz, sizeof(limb) * 10); +} + +static inline void crecip(limb* out, const limb* z) +{ + limb z2[10]; + limb z9[10]; + limb z11[10]; + limb z2_5_0[10]; + limb z2_10_0[10]; + limb z2_20_0[10]; + limb z2_50_0[10]; + limb z2_100_0[10]; + limb t0[10]; + limb t1[10]; + int i; + + /* 2 */ fsquare(z2, z); + /* 4 */ fsquare(t1, z2); + /* 8 */ fsquare(t0, t1); + /* 9 */ fmul(z9, t0, z); + /* 11 */ fmul(z11, z9, z2); + /* 22 */ fsquare(t0, z11); + /* 2^5 - 2^0 = 31 */ fmul(z2_5_0, t0, z9); + + /* 2^6 - 2^1 */ fsquare(t0, z2_5_0); + /* 2^7 - 2^2 */ fsquare(t1, t0); + /* 2^8 - 2^3 */ fsquare(t0, t1); + /* 2^9 - 2^4 */ fsquare(t1, t0); + /* 2^10 - 2^5 */ fsquare(t0, t1); + /* 2^10 - 2^0 */ fmul(z2_10_0, t0, z2_5_0); + + /* 2^11 - 2^1 */ fsquare(t0, z2_10_0); + /* 2^12 - 2^2 */ fsquare(t1, t0); + /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { + fsquare(t0, t1); + fsquare(t1, t0); + } + /* 2^20 - 2^0 */ fmul(z2_20_0, t1, z2_10_0); + + /* 2^21 - 2^1 */ fsquare(t0, z2_20_0); + /* 2^22 - 2^2 */ fsquare(t1, t0); + /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { + fsquare(t0, t1); + fsquare(t1, t0); + } + /* 2^40 - 2^0 */ fmul(t0, t1, z2_20_0); + + /* 2^41 - 2^1 */ fsquare(t1, t0); + /* 2^42 - 2^2 */ fsquare(t0, t1); + /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { + fsquare(t1, t0); + fsquare(t0, t1); + } + /* 2^50 - 2^0 */ fmul(z2_50_0, t0, z2_10_0); + + /* 2^51 - 2^1 */ fsquare(t0, z2_50_0); + /* 2^52 - 2^2 */ fsquare(t1, t0); + /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { + fsquare(t0, t1); + fsquare(t1, t0); + } + /* 2^100 - 2^0 */ fmul(z2_100_0, t1, z2_50_0); + + /* 2^101 - 2^1 */ fsquare(t1, z2_100_0); + /* 2^102 - 2^2 */ fsquare(t0, t1); + /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { + fsquare(t1, t0); + fsquare(t0, t1); + } + /* 2^200 - 2^0 */ fmul(t1, t0, z2_100_0); + + /* 2^201 - 2^1 */ fsquare(t0, t1); + /* 2^202 - 2^2 */ fsquare(t1, t0); + /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { + fsquare(t0, t1); + fsquare(t1, t0); + } + /* 2^250 - 2^0 */ fmul(t0, t1, z2_50_0); + + /* 2^251 - 2^1 */ fsquare(t1, t0); + /* 2^252 - 2^2 */ fsquare(t0, t1); + /* 2^253 - 2^3 */ fsquare(t1, t0); + /* 2^254 - 2^4 */ fsquare(t0, t1); + /* 2^255 - 2^5 */ fsquare(t1, t0); + /* 2^255 - 21 */ fmul(out, t1, z11); +} + +static void crypto_scalarmult(u8* mypublic, const u8* secret, const u8* basepoint) +{ + limb bp[10], x[10], z[11], zmone[10]; + uint8_t e[32]; + int i; + + for (i = 0; i < 32; ++i) { + e[i] = secret[i]; + } + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + fexpand(bp, basepoint); + cmult(x, z, e, bp); + crecip(zmone, z); + fmul(z, x, zmone); + fcontract(mypublic, z); +} + +static const unsigned char base[32] = { 9 }; +static inline void crypto_scalarmult_base(unsigned char* q, const unsigned char* n) +{ + crypto_scalarmult(q, n, base); } ////////////////////////////////////////////////////////////////////////////// @@ -756,26 +685,19 @@ static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char * // Ed25519 ref from: http://bench.cr.yp.to/supercop.html -typedef struct -{ +typedef struct { crypto_uint32 v[32]; -} -fe25519; +} fe25519; -typedef struct -{ +typedef struct { crypto_uint32 v[32]; -} -sc25519; +} sc25519; -typedef struct -{ +typedef struct { crypto_uint32 v[16]; -} -shortsc25519; +} shortsc25519; -typedef struct -{ +typedef struct { fe25519 x; fe25519 y; fe25519 z; @@ -784,43 +706,40 @@ typedef struct #define ge25519_p3 ge25519 -typedef struct -{ +typedef struct { fe25519 x; fe25519 z; fe25519 y; fe25519 t; } ge25519_p1p1; -typedef struct -{ +typedef struct { fe25519 x; fe25519 y; fe25519 z; } ge25519_p2; -typedef struct -{ +typedef struct { fe25519 x; fe25519 y; } ge25519_aff; -static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); +static inline void fe25519_sub(fe25519* r, const fe25519* x, const fe25519* y); -static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ +static inline crypto_uint32 equal(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ { crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */ - x -= 1; /* 4294967295: yes; 0..65534: no */ - x >>= 31; /* 1: yes; 0: no */ + x -= 1; /* 4294967295: yes; 0..65534: no */ + x >>= 31; /* 1: yes; 0: no */ return x; } -static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ +static inline crypto_uint32 ge(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ { unsigned int x = a; - x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ - x >>= 31; /* 0: yes; 1: no */ - x ^= 1; /* 1: yes; 0: no */ + x -= (unsigned int)b; /* 0..65535: yes; 4294901761..4294967295: no */ + x >>= 31; /* 0: yes; 1: no */ + x ^= 1; /* 1: yes; 0: no */ return x; } @@ -834,89 +753,89 @@ static inline crypto_uint32 times38(crypto_uint32 a) return (a << 5) + (a << 2) + (a << 1); } -static inline void reduce_add_sub(fe25519 *r) +static inline void reduce_add_sub(fe25519* r) { crypto_uint32 t; - int i,rep; + int i, rep; - for(rep=0;rep<4;rep++) { + for (rep = 0; rep < 4; rep++) { t = r->v[31] >> 7; r->v[31] &= 127; t = times19(t); r->v[0] += t; - for(i=0;i<31;i++) { + for (i = 0; i < 31; i++) { t = r->v[i] >> 8; - r->v[i+1] += t; + r->v[i + 1] += t; r->v[i] &= 255; } } } -static inline void reduce_mul(fe25519 *r) +static inline void reduce_mul(fe25519* r) { crypto_uint32 t; - int i,rep; + int i, rep; - for(rep=0;rep<2;rep++) { + for (rep = 0; rep < 2; rep++) { t = r->v[31] >> 7; r->v[31] &= 127; t = times19(t); r->v[0] += t; - for(i=0;i<31;i++) { + for (i = 0; i < 31; i++) { t = r->v[i] >> 8; - r->v[i+1] += t; + r->v[i + 1] += t; r->v[i] &= 255; } } } /* reduction modulo 2^255-19 */ -static inline void fe25519_freeze(fe25519 *r) +static inline void fe25519_freeze(fe25519* r) { int i; - crypto_uint32 m = equal(r->v[31],127); - for(i=30;i>0;i--) { - m &= equal(r->v[i],255); + crypto_uint32 m = equal(r->v[31], 127); + for (i = 30; i > 0; i--) { + m &= equal(r->v[i], 255); } - m &= ge(r->v[0],237); + m &= ge(r->v[0], 237); m = -m; - r->v[31] -= m&127; - for(i=30;i>0;i--) { - r->v[i] -= m&255; + r->v[31] -= m & 127; + for (i = 30; i > 0; i--) { + r->v[i] -= m & 255; } - r->v[0] -= m&237; + r->v[0] -= m & 237; } -static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32]) +static inline void fe25519_unpack(fe25519* r, const unsigned char x[32]) { int i; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] = x[i]; } r->v[31] &= 127; } /* Assumes input x being reduced below 2^255 */ -static inline void fe25519_pack(unsigned char r[32], const fe25519 *x) +static inline void fe25519_pack(unsigned char r[32], const fe25519* x) { int i; fe25519 y = *x; fe25519_freeze(&y); - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r[i] = y.v[i]; } } -static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) +static inline int fe25519_iseq_vartime(const fe25519* x, const fe25519* y) { int i; fe25519 t1 = *x; fe25519 t2 = *y; fe25519_freeze(&t1); fe25519_freeze(&t2); - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { if (t1.v[i] != t2.v[i]) { return 0; } @@ -924,103 +843,103 @@ static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) return 1; } -static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) +static inline void fe25519_cmov(fe25519* r, const fe25519* x, unsigned char b) { int i; crypto_uint32 mask = b; mask = -mask; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] ^= mask & (x->v[i] ^ r->v[i]); } } -static inline unsigned char fe25519_getparity(const fe25519 *x) +static inline unsigned char fe25519_getparity(const fe25519* x) { fe25519 t = *x; fe25519_freeze(&t); return t.v[0] & 1; } -static inline void fe25519_setone(fe25519 *r) +static inline void fe25519_setone(fe25519* r) { int i; r->v[0] = 1; - for(i=1;i<32;i++) { - r->v[i]=0; + for (i = 1; i < 32; i++) { + r->v[i] = 0; } } -static inline void fe25519_setzero(fe25519 *r) +static inline void fe25519_setzero(fe25519* r) { int i; - for(i=0;i<32;i++) { - r->v[i]=0; + for (i = 0; i < 32; i++) { + r->v[i] = 0; } } -static inline void fe25519_neg(fe25519 *r, const fe25519 *x) +static inline void fe25519_neg(fe25519* r, const fe25519* x) { fe25519 t; int i; - for(i=0;i<32;i++) { - t.v[i]=x->v[i]; + for (i = 0; i < 32; i++) { + t.v[i] = x->v[i]; } fe25519_setzero(r); fe25519_sub(r, r, &t); } -static inline void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) +static inline void fe25519_add(fe25519* r, const fe25519* x, const fe25519* y) { int i; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] = x->v[i] + y->v[i]; } reduce_add_sub(r); } -static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) +static inline void fe25519_sub(fe25519* r, const fe25519* x, const fe25519* y) { int i; crypto_uint32 t[32]; t[0] = x->v[0] + 0x1da; t[31] = x->v[31] + 0xfe; - for(i=1;i<31;i++) { + for (i = 1; i < 31; i++) { t[i] = x->v[i] + 0x1fe; } - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] = t[i] - y->v[i]; } reduce_add_sub(r); } -static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) +static inline void fe25519_mul(fe25519* r, const fe25519* x, const fe25519* y) { - int i,j; + int i, j; crypto_uint32 t[63]; - for(i=0;i<63;i++) { + for (i = 0; i < 63; i++) { t[i] = 0; } - for(i=0;i<32;i++) { - for(j=0;j<32;j++) { - t[i+j] += x->v[i] * y->v[j]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + t[i + j] += x->v[i] * y->v[j]; } } - for(i=32;i<63;i++) { - r->v[i-32] = t[i-32] + times38(t[i]); + for (i = 32; i < 63; i++) { + r->v[i - 32] = t[i - 32] + times38(t[i]); } r->v[31] = t[31]; /* result now in r[0]...r[31] */ reduce_mul(r); } -static inline void fe25519_square(fe25519 *r, const fe25519 *x) +static inline void fe25519_square(fe25519* r, const fe25519* x) { fe25519_mul(r, x, x); } -static inline void fe25519_invert(fe25519 *r, const fe25519 *x) +static inline void fe25519_invert(fe25519* r, const fe25519* x) { fe25519 z2; fe25519 z9; @@ -1034,60 +953,78 @@ static inline void fe25519_invert(fe25519 *r, const fe25519 *x) fe25519 t1; int i; - /* 2 */ fe25519_square(&z2,x); - /* 4 */ fe25519_square(&t1,&z2); - /* 8 */ fe25519_square(&t0,&t1); - /* 9 */ fe25519_mul(&z9,&t0,x); - /* 11 */ fe25519_mul(&z11,&z9,&z2); - /* 22 */ fe25519_square(&t0,&z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9); + /* 2 */ fe25519_square(&z2, x); + /* 4 */ fe25519_square(&t1, &z2); + /* 8 */ fe25519_square(&t0, &t1); + /* 9 */ fe25519_mul(&z9, &t0, x); + /* 11 */ fe25519_mul(&z11, &z9, &z2); + /* 22 */ fe25519_square(&t0, &z11); + /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t0, &z9); - /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0); - /* 2^7 - 2^2 */ fe25519_square(&t1,&t0); - /* 2^8 - 2^3 */ fe25519_square(&t0,&t1); - /* 2^9 - 2^4 */ fe25519_square(&t1,&t0); - /* 2^10 - 2^5 */ fe25519_square(&t0,&t1); - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0); + /* 2^6 - 2^1 */ fe25519_square(&t0, &z2_5_0); + /* 2^7 - 2^2 */ fe25519_square(&t1, &t0); + /* 2^8 - 2^3 */ fe25519_square(&t0, &t1); + /* 2^9 - 2^4 */ fe25519_square(&t1, &t0); + /* 2^10 - 2^5 */ fe25519_square(&t0, &t1); + /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t0, &z2_5_0); - /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0); - /* 2^12 - 2^2 */ fe25519_square(&t1,&t0); - /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0); + /* 2^11 - 2^1 */ fe25519_square(&t0, &z2_10_0); + /* 2^12 - 2^2 */ fe25519_square(&t1, &t0); + /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { + fe25519_square(&t0, &t1); + fe25519_square(&t1, &t0); + } + /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t1, &z2_10_0); - /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0); - /* 2^22 - 2^2 */ fe25519_square(&t1,&t0); - /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } - /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0); + /* 2^21 - 2^1 */ fe25519_square(&t0, &z2_20_0); + /* 2^22 - 2^2 */ fe25519_square(&t1, &t0); + /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { + fe25519_square(&t0, &t1); + fe25519_square(&t1, &t0); + } + /* 2^40 - 2^0 */ fe25519_mul(&t0, &t1, &z2_20_0); - /* 2^41 - 2^1 */ fe25519_square(&t1,&t0); - /* 2^42 - 2^2 */ fe25519_square(&t0,&t1); - /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0); + /* 2^41 - 2^1 */ fe25519_square(&t1, &t0); + /* 2^42 - 2^2 */ fe25519_square(&t0, &t1); + /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { + fe25519_square(&t1, &t0); + fe25519_square(&t0, &t1); + } + /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t0, &z2_10_0); - /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0); - /* 2^52 - 2^2 */ fe25519_square(&t1,&t0); - /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0); + /* 2^51 - 2^1 */ fe25519_square(&t0, &z2_50_0); + /* 2^52 - 2^2 */ fe25519_square(&t1, &t0); + /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { + fe25519_square(&t0, &t1); + fe25519_square(&t1, &t0); + } + /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t1, &z2_50_0); - /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0); - /* 2^102 - 2^2 */ fe25519_square(&t0,&t1); - /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } - /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0); + /* 2^101 - 2^1 */ fe25519_square(&t1, &z2_100_0); + /* 2^102 - 2^2 */ fe25519_square(&t0, &t1); + /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { + fe25519_square(&t1, &t0); + fe25519_square(&t0, &t1); + } + /* 2^200 - 2^0 */ fe25519_mul(&t1, &t0, &z2_100_0); - /* 2^201 - 2^1 */ fe25519_square(&t0,&t1); - /* 2^202 - 2^2 */ fe25519_square(&t1,&t0); - /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } - /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0); + /* 2^201 - 2^1 */ fe25519_square(&t0, &t1); + /* 2^202 - 2^2 */ fe25519_square(&t1, &t0); + /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { + fe25519_square(&t0, &t1); + fe25519_square(&t1, &t0); + } + /* 2^250 - 2^0 */ fe25519_mul(&t0, &t1, &z2_50_0); - /* 2^251 - 2^1 */ fe25519_square(&t1,&t0); - /* 2^252 - 2^2 */ fe25519_square(&t0,&t1); - /* 2^253 - 2^3 */ fe25519_square(&t1,&t0); - /* 2^254 - 2^4 */ fe25519_square(&t0,&t1); - /* 2^255 - 2^5 */ fe25519_square(&t1,&t0); - /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11); + /* 2^251 - 2^1 */ fe25519_square(&t1, &t0); + /* 2^252 - 2^2 */ fe25519_square(&t0, &t1); + /* 2^253 - 2^3 */ fe25519_square(&t1, &t0); + /* 2^254 - 2^4 */ fe25519_square(&t0, &t1); + /* 2^255 - 2^5 */ fe25519_square(&t1, &t0); + /* 2^255 - 21 */ fe25519_mul(r, &t1, &z11); } -static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x) +static inline void fe25519_pow2523(fe25519* r, const fe25519* x) { fe25519 z2; fe25519 z9; @@ -1100,60 +1037,60 @@ static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x) fe25519 t; int i; - /* 2 */ fe25519_square(&z2,x); - /* 4 */ fe25519_square(&t,&z2); - /* 8 */ fe25519_square(&t,&t); - /* 9 */ fe25519_mul(&z9,&t,x); - /* 11 */ fe25519_mul(&z11,&z9,&z2); - /* 22 */ fe25519_square(&t,&z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); + /* 2 */ fe25519_square(&z2, x); + /* 4 */ fe25519_square(&t, &z2); + /* 8 */ fe25519_square(&t, &t); + /* 9 */ fe25519_mul(&z9, &t, x); + /* 11 */ fe25519_mul(&z11, &z9, &z2); + /* 22 */ fe25519_square(&t, &z11); + /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t, &z9); - /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); - /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); + /* 2^6 - 2^1 */ fe25519_square(&t, &z2_5_0); + /* 2^10 - 2^5 */ for (i = 1; i < 5; i++) { fe25519_square(&t, &t); } + /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t, &z2_5_0); - /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); - /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); + /* 2^11 - 2^1 */ fe25519_square(&t, &z2_10_0); + /* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { fe25519_square(&t, &t); } + /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t, &z2_10_0); - /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); - /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } - /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); + /* 2^21 - 2^1 */ fe25519_square(&t, &z2_20_0); + /* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { fe25519_square(&t, &t); } + /* 2^40 - 2^0 */ fe25519_mul(&t, &t, &z2_20_0); - /* 2^41 - 2^1 */ fe25519_square(&t,&t); - /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); + /* 2^41 - 2^1 */ fe25519_square(&t, &t); + /* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { fe25519_square(&t, &t); } + /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t, &z2_10_0); - /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); - /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); + /* 2^51 - 2^1 */ fe25519_square(&t, &z2_50_0); + /* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { fe25519_square(&t, &t); } + /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t, &z2_50_0); - /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); - /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } - /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); + /* 2^101 - 2^1 */ fe25519_square(&t, &z2_100_0); + /* 2^200 - 2^100 */ for (i = 1; i < 100; i++) { fe25519_square(&t, &t); } + /* 2^200 - 2^0 */ fe25519_mul(&t, &t, &z2_100_0); - /* 2^201 - 2^1 */ fe25519_square(&t,&t); - /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); + /* 2^201 - 2^1 */ fe25519_square(&t, &t); + /* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { fe25519_square(&t, &t); } + /* 2^250 - 2^0 */ fe25519_mul(&t, &t, &z2_50_0); - /* 2^251 - 2^1 */ fe25519_square(&t,&t); - /* 2^252 - 2^2 */ fe25519_square(&t,&t); - /* 2^252 - 3 */ fe25519_mul(r,&t,x); + /* 2^251 - 2^1 */ fe25519_square(&t, &t); + /* 2^252 - 2^2 */ fe25519_square(&t, &t); + /* 2^252 - 3 */ fe25519_mul(r, &t, x); } -static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; -static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; +static const crypto_uint32 m[32] = { 0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; +static const crypto_uint32 mu[33] = { 0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F }; -static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ +static inline crypto_uint32 lt(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ { unsigned int x = a; - x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ - x >>= 31; /* 0: no; 1: yes */ + x -= (unsigned int)b; /* 0..65535: no; 4294901761..4294967295: yes */ + x >>= 31; /* 0: no; 1: yes */ return x; } /* Reduce coefficients of r before calling reduce_add_sub */ -static inline void reduce_add_sub(sc25519 *r) +static inline void reduce_add_sub(sc25519* r) { crypto_uint32 pb = 0; crypto_uint32 b; @@ -1161,42 +1098,42 @@ static inline void reduce_add_sub(sc25519 *r) int i; unsigned char t[32]; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { pb += m[i]; - b = lt(r->v[i],pb); - t[i] = r->v[i]-pb+(b<<8); + b = lt(r->v[i], pb); + t[i] = r->v[i] - pb + (b << 8); pb = b; } mask = b - 1; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] ^= mask & (r->v[i] ^ t[i]); } } /* Reduce coefficients of x before calling barrett_reduce */ -static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) +static inline void barrett_reduce(sc25519* r, const crypto_uint32 x[64]) { /* See HAC, Alg. 14.42 */ - int i,j; + int i, j; crypto_uint32 q2[66]; - crypto_uint32 *q3 = q2 + 33; + crypto_uint32* q3 = q2 + 33; crypto_uint32 r1[33]; crypto_uint32 r2[33]; crypto_uint32 carry; crypto_uint32 pb = 0; crypto_uint32 b; - for (i = 0;i < 66;++i) { + for (i = 0; i < 66; ++i) { q2[i] = 0; } - for (i = 0;i < 33;++i) { + for (i = 0; i < 33; ++i) { r2[i] = 0; } - for(i=0;i<33;i++) { - for(j=0;j<33;j++) { - if(i+j >= 31) { - q2[i+j] += mu[i]*x[j+31]; + for (i = 0; i < 33; i++) { + for (j = 0; j < 33; j++) { + if (i + j >= 31) { + q2[i + j] += mu[i] * x[j + 31]; } } } @@ -1205,27 +1142,27 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) carry = q2[32] >> 8; q2[33] += carry; - for(i=0;i<33;i++) { + for (i = 0; i < 33; i++) { r1[i] = x[i]; } - for(i=0;i<32;i++) { - for(j=0;j<33;j++) { - if(i+j < 33) { - r2[i+j] += m[i]*q3[j]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 33; j++) { + if (i + j < 33) { + r2[i + j] += m[i] * q3[j]; } } } - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { carry = r2[i] >> 8; - r2[i+1] += carry; + r2[i + 1] += carry; r2[i] &= 0xff; } - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { pb += r2[i]; - b = lt(r1[i],pb); - r->v[i] = r1[i]-pb+(b<<8); + b = lt(r1[i], pb); + r->v[i] = r1[i] - pb + (b << 8); pb = b; } @@ -1237,1020 +1174,1013 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) reduce_add_sub(r); } -static inline void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) +static inline void sc25519_from32bytes(sc25519* r, const unsigned char x[32]) { int i; crypto_uint32 t[64]; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { t[i] = x[i]; } - for(i=32;i<64;++i) { + for (i = 32; i < 64; ++i) { t[i] = 0; } barrett_reduce(r, t); } -static inline void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) +static inline void sc25519_from64bytes(sc25519* r, const unsigned char x[64]) { int i; crypto_uint32 t[64]; - for(i=0;i<64;i++) { + for (i = 0; i < 64; i++) { t[i] = x[i]; } barrett_reduce(r, t); } -static inline void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) +static inline void sc25519_to32bytes(unsigned char r[32], const sc25519* x) { int i; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r[i] = x->v[i]; } } -static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y) +static inline void sc25519_add(sc25519* r, const sc25519* x, const sc25519* y) { int i, carry; - for(i=0;i<32;i++) { + for (i = 0; i < 32; i++) { r->v[i] = x->v[i] + y->v[i]; } - for(i=0;i<31;i++) { + for (i = 0; i < 31; i++) { carry = r->v[i] >> 8; - r->v[i+1] += carry; + r->v[i + 1] += carry; r->v[i] &= 0xff; } reduce_add_sub(r); } -static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y) +static inline void sc25519_mul(sc25519* r, const sc25519* x, const sc25519* y) { - int i,j,carry; + int i, j, carry; crypto_uint32 t[64]; - for(i=0;i<64;i++) { + for (i = 0; i < 64; i++) { t[i] = 0; } - for(i=0;i<32;i++) { - for(j=0;j<32;j++) { - t[i+j] += x->v[i] * y->v[j]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + t[i + j] += x->v[i] * y->v[j]; } } - for(i=0;i<63;i++) { + for (i = 0; i < 63; i++) { carry = t[i] >> 8; - t[i+1] += carry; + t[i + 1] += carry; t[i] &= 0xff; } barrett_reduce(r, t); } -static inline void sc25519_window3(signed char r[85], const sc25519 *s) +static inline void sc25519_window3(signed char r[85], const sc25519* s) { char carry; int i; - for(i=0;i<10;i++) { - r[8*i+0] = s->v[3*i+0] & 7; - r[8*i+1] = (s->v[3*i+0] >> 3) & 7; - r[8*i+2] = (s->v[3*i+0] >> 6) & 7; - r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; - r[8*i+3] = (s->v[3*i+1] >> 1) & 7; - r[8*i+4] = (s->v[3*i+1] >> 4) & 7; - r[8*i+5] = (s->v[3*i+1] >> 7) & 7; - r[8*i+5] ^= (s->v[3*i+2] << 1) & 7; - r[8*i+6] = (s->v[3*i+2] >> 2) & 7; - r[8*i+7] = (s->v[3*i+2] >> 5) & 7; + for (i = 0; i < 10; i++) { + r[8 * i + 0] = s->v[3 * i + 0] & 7; + r[8 * i + 1] = (s->v[3 * i + 0] >> 3) & 7; + r[8 * i + 2] = (s->v[3 * i + 0] >> 6) & 7; + r[8 * i + 2] ^= (s->v[3 * i + 1] << 2) & 7; + r[8 * i + 3] = (s->v[3 * i + 1] >> 1) & 7; + r[8 * i + 4] = (s->v[3 * i + 1] >> 4) & 7; + r[8 * i + 5] = (s->v[3 * i + 1] >> 7) & 7; + r[8 * i + 5] ^= (s->v[3 * i + 2] << 1) & 7; + r[8 * i + 6] = (s->v[3 * i + 2] >> 2) & 7; + r[8 * i + 7] = (s->v[3 * i + 2] >> 5) & 7; } - r[8*i+0] = s->v[3*i+0] & 7; - r[8*i+1] = (s->v[3*i+0] >> 3) & 7; - r[8*i+2] = (s->v[3*i+0] >> 6) & 7; - r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; - r[8*i+3] = (s->v[3*i+1] >> 1) & 7; - r[8*i+4] = (s->v[3*i+1] >> 4) & 7; + r[8 * i + 0] = s->v[3 * i + 0] & 7; + r[8 * i + 1] = (s->v[3 * i + 0] >> 3) & 7; + r[8 * i + 2] = (s->v[3 * i + 0] >> 6) & 7; + r[8 * i + 2] ^= (s->v[3 * i + 1] << 2) & 7; + r[8 * i + 3] = (s->v[3 * i + 1] >> 1) & 7; + r[8 * i + 4] = (s->v[3 * i + 1] >> 4) & 7; /* Making it signed */ carry = 0; - for(i=0;i<84;i++) { + for (i = 0; i < 84; i++) { r[i] += carry; - r[i+1] += r[i] >> 3; + r[i + 1] += r[i] >> 3; r[i] &= 7; carry = r[i] >> 2; - r[i] -= carry<<3; + r[i] -= carry << 3; } r[84] += carry; } -static inline void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) +static inline void sc25519_2interleave2(unsigned char r[127], const sc25519* s1, const sc25519* s2) { int i; - for(i=0;i<31;i++) { - r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2); - r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); - r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); - r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); + for (i = 0; i < 31; i++) { + r[4 * i] = (s1->v[i] & 3) ^ ((s2->v[i] & 3) << 2); + r[4 * i + 1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); + r[4 * i + 2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); + r[4 * i + 3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); } - r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2); + r[124] = (s1->v[31] & 3) ^ ((s2->v[31] & 3) << 2); r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2); r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2); } /* d */ -static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, - 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}}; +static const fe25519 ge25519_ecd = { { 0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52 } }; /* 2*d */ -static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, - 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}}; +static const fe25519 ge25519_ec2d = { { 0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24 } }; /* sqrt(-1) */ -static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, - 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}}; +static const fe25519 ge25519_sqrtm1 = { { 0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B } }; /* Packed coordinates of the base point */ -static const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, - 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}}, - {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, - 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}}; +static const ge25519 ge25519_base = { { { 0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21 } }, + { { 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67 } } }; /* Multiples of the base point in affine representation */ static const ge25519_aff ge25519_base_multiples_affine[425] = { -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} , - {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}}, -{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} , - {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}}, -{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} , - {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}}, -{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} , - {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} , - {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}}, -{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} , - {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}}, -{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} , - {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}}, -{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} , - {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} , - {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}}, -{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} , - {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}}, -{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} , - {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}}, -{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} , - {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} , - {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}}, -{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} , - {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}}, -{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} , - {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}}, -{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} , - {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} , - {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}}, -{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} , - {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}}, -{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} , - {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}}, -{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} , - {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} , - {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}}, -{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} , - {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}}, -{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} , - {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}}, -{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} , - {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} , - {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}}, -{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} , - {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}}, -{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} , - {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}}, -{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} , - {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} , - {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}}, -{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} , - {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}}, -{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} , - {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}}, -{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} , - {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} , - {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}}, -{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} , - {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}}, -{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} , - {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}}, -{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} , - {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} , - {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}}, -{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} , - {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}}, -{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} , - {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}}, -{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} , - {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} , - {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}}, -{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} , - {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}}, -{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} , - {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}}, -{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} , - {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} , - {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}}, -{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} , - {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}}, -{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} , - {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}}, -{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} , - {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} , - {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}}, -{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} , - {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}}, -{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} , - {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}}, -{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} , - {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} , - {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}}, -{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} , - {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}}, -{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} , - {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}}, -{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} , - {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} , - {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}}, -{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} , - {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}}, -{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} , - {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}}, -{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} , - {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} , - {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}}, -{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} , - {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}}, -{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} , - {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}}, -{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} , - {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} , - {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}}, -{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} , - {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}}, -{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} , - {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}}, -{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} , - {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} , - {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}}, -{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} , - {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}}, -{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} , - {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}}, -{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} , - {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} , - {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}}, -{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} , - {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}}, -{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} , - {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}}, -{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} , - {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} , - {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}}, -{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} , - {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}}, -{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} , - {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}}, -{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} , - {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} , - {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}}, -{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} , - {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}}, -{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} , - {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}}, -{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} , - {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} , - {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}}, -{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} , - {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}}, -{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} , - {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}}, -{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} , - {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} , - {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}}, -{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} , - {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}}, -{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} , - {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}}, -{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} , - {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} , - {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}}, -{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} , - {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}}, -{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} , - {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}}, -{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} , - {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} , - {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}}, -{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} , - {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}}, -{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} , - {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}}, -{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} , - {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} , - {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}}, -{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} , - {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}}, -{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} , - {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}}, -{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} , - {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} , - {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}}, -{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} , - {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}}, -{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} , - {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}}, -{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} , - {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} , - {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}}, -{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} , - {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}}, -{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} , - {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}}, -{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} , - {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} , - {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}}, -{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} , - {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}}, -{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} , - {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}}, -{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} , - {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} , - {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}}, -{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} , - {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}}, -{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} , - {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}}, -{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} , - {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} , - {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}}, -{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} , - {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}}, -{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} , - {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}}, -{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} , - {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} , - {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}}, -{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} , - {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}}, -{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} , - {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}}, -{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} , - {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} , - {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}}, -{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} , - {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}}, -{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} , - {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}}, -{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} , - {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} , - {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}}, -{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} , - {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}}, -{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} , - {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}}, -{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} , - {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} , - {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}}, -{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} , - {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}}, -{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} , - {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}}, -{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} , - {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} , - {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}}, -{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} , - {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}}, -{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} , - {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}}, -{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} , - {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} , - {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}}, -{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} , - {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}}, -{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} , - {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}}, -{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} , - {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} , - {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}}, -{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} , - {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}}, -{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} , - {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}}, -{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} , - {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} , - {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}}, -{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} , - {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}}, -{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} , - {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}}, -{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} , - {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} , - {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}}, -{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} , - {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}}, -{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} , - {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}}, -{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} , - {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} , - {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}}, -{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} , - {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}}, -{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} , - {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}}, -{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} , - {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} , - {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}}, -{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} , - {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}}, -{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} , - {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}}, -{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} , - {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} , - {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}}, -{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} , - {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}}, -{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} , - {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}}, -{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} , - {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} , - {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}}, -{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} , - {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}}, -{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} , - {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}}, -{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} , - {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} , - {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}}, -{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} , - {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}}, -{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} , - {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}}, -{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} , - {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} , - {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}}, -{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} , - {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}}, -{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} , - {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}}, -{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} , - {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} , - {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}}, -{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} , - {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}}, -{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} , - {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}}, -{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} , - {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} , - {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}}, -{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} , - {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}}, -{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} , - {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}}, -{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} , - {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} , - {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}}, -{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} , - {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}}, -{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} , - {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}}, -{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} , - {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} , - {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}}, -{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} , - {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}}, -{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} , - {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}}, -{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} , - {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} , - {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}}, -{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} , - {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}}, -{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} , - {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}}, -{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} , - {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} , - {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}}, -{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} , - {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}}, -{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} , - {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}}, -{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} , - {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} , - {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}}, -{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} , - {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}}, -{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} , - {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}}, -{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} , - {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} , - {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}}, -{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} , - {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}}, -{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} , - {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}}, -{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} , - {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} , - {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}}, -{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} , - {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}}, -{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} , - {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}}, -{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} , - {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} , - {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}}, -{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} , - {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}}, -{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} , - {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}}, -{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} , - {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} , - {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}}, -{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} , - {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}}, -{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} , - {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}}, -{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} , - {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} , - {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}}, -{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} , - {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}}, -{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} , - {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}}, -{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} , - {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} , - {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}}, -{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} , - {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}}, -{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} , - {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}}, -{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} , - {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} , - {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}}, -{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} , - {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}}, -{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} , - {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}}, -{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} , - {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} , - {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}}, -{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} , - {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}}, -{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} , - {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}}, -{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} , - {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} , - {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}}, -{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} , - {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}}, -{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} , - {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}}, -{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} , - {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} , - {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}}, -{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} , - {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}}, -{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} , - {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}}, -{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} , - {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} , - {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}}, -{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} , - {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}}, -{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} , - {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}}, -{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} , - {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} , - {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}}, -{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} , - {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}}, -{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} , - {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}}, -{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} , - {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} , - {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}}, -{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} , - {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}}, -{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} , - {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}}, -{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} , - {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} , - {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}}, -{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} , - {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}}, -{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} , - {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}}, -{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} , - {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} , - {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}}, -{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} , - {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}}, -{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} , - {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}}, -{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} , - {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} , - {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}}, -{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} , - {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}}, -{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} , - {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}}, -{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} , - {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} , - {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}}, -{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} , - {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}}, -{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} , - {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}}, -{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} , - {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} , - {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}}, -{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} , - {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}}, -{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} , - {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}}, -{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} , - {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} , - {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}}, -{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} , - {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}}, -{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} , - {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}}, -{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} , - {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} , - {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}}, -{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} , - {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}}, -{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} , - {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}}, -{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} , - {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} , - {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}}, -{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} , - {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}}, -{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} , - {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}}, -{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} , - {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} , - {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}}, -{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} , - {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}}, -{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} , - {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}}, -{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} , - {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} , - {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}}, -{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} , - {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}}, -{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} , - {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}}, -{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} , - {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} , - {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}}, -{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} , - {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}}, -{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} , - {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}}, -{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} , - {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} , - {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}}, -{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} , - {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}}, -{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} , - {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}}, -{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} , - {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} , - {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}}, -{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} , - {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}}, -{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} , - {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}}, -{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} , - {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} , - {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}}, -{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} , - {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}}, -{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} , - {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}}, -{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} , - {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} , - {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}}, -{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} , - {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}}, -{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} , - {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}}, -{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} , - {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} , - {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}}, -{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} , - {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}}, -{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} , - {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}}, -{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} , - {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} , - {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}}, -{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} , - {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}}, -{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} , - {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}}, -{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} , - {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} , - {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}}, -{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} , - {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}}, -{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} , - {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}}, -{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} , - {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} , - {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}}, -{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} , - {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}}, -{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} , - {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}}, -{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} , - {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}} + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 } }, + { { 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 } } }, + { { { 0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36 } }, + { { 0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22 } } }, + { { { 0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67 } }, + { { 0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12 } } }, + { { { 0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20 } }, + { { 0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67 } }, + { { 0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21 } } }, + { { { 0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23 } }, + { { 0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70 } } }, + { { { 0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70 } }, + { { 0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60 } } }, + { { { 0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39 } }, + { { 0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05 } }, + { { 0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d } } }, + { { { 0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37 } }, + { { 0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28 } } }, + { { { 0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e } }, + { { 0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77 } } }, + { { { 0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e } }, + { { 0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e } }, + { { 0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54 } } }, + { { { 0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b } }, + { { 0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a } } }, + { { { 0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60 } }, + { { 0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f } } }, + { { { 0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c } }, + { { 0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d } }, + { { 0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59 } } }, + { { { 0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17 } }, + { { 0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73 } } }, + { { { 0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08 } }, + { { 0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72 } } }, + { { { 0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07 } }, + { { 0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b } }, + { { 0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40 } } }, + { { { 0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d } }, + { { 0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c } } }, + { { { 0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31 } }, + { { 0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65 } } }, + { { { 0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74 } }, + { { 0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a } }, + { { 0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16 } } }, + { { { 0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24 } }, + { { 0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37 } } }, + { { { 0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29 } }, + { { 0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15 } } }, + { { { 0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06 } }, + { { 0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48 } }, + { { 0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73 } } }, + { { { 0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b } }, + { { 0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d } } }, + { { { 0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28 } }, + { { 0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d } } }, + { { { 0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45 } }, + { { 0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a } }, + { { 0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21 } } }, + { { { 0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b } }, + { { 0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d } } }, + { { { 0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45 } }, + { { 0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69 } } }, + { { { 0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67 } }, + { { 0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29 } }, + { { 0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c } } }, + { { { 0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e } }, + { { 0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e } } }, + { { { 0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55 } }, + { { 0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04 } } }, + { { { 0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61 } }, + { { 0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48 } }, + { { 0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31 } } }, + { { { 0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79 } }, + { { 0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e } } }, + { { { 0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d } }, + { { 0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72 } } }, + { { { 0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d } }, + { { 0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b } }, + { { 0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73 } } }, + { { { 0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33 } }, + { { 0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53 } } }, + { { { 0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56 } }, + { { 0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a } } }, + { { { 0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44 } }, + { { 0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b } }, + { { 0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f } } }, + { { { 0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b } }, + { { 0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17 } } }, + { { { 0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37 } }, + { { 0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c } } }, + { { { 0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01 } }, + { { 0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63 } }, + { { 0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04 } } }, + { { { 0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f } }, + { { 0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d } } }, + { { { 0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e } }, + { { 0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a } } }, + { { { 0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b } }, + { { 0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18 } }, + { { 0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e } } }, + { { { 0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a } }, + { { 0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67 } } }, + { { { 0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05 } }, + { { 0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78 } } }, + { { { 0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52 } }, + { { 0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50 } }, + { { 0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f } } }, + { { { 0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d } }, + { { 0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a } } }, + { { { 0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a } }, + { { 0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a } } }, + { { { 0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56 } }, + { { 0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52 } }, + { { 0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50 } } }, + { { { 0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f } }, + { { 0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41 } } }, + { { { 0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f } }, + { { 0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68 } } }, + { { { 0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e } }, + { { 0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b } }, + { { 0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34 } } }, + { { { 0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00 } }, + { { 0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72 } } }, + { { { 0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15 } }, + { { 0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c } } }, + { { { 0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f } }, + { { 0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08 } }, + { { 0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27 } } }, + { { { 0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a } }, + { { 0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77 } } }, + { { { 0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d } }, + { { 0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c } } }, + { { { 0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71 } }, + { { 0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30 } }, + { { 0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40 } } }, + { { { 0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42 } }, + { { 0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70 } } }, + { { { 0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e } }, + { { 0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e } } }, + { { { 0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c } }, + { { 0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57 } }, + { { 0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b } } }, + { { { 0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20 } }, + { { 0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32 } } }, + { { { 0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68 } }, + { { 0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d } } }, + { { { 0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59 } }, + { { 0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04 } }, + { { 0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72 } } }, + { { { 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62 } }, + { { 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03 } } }, + { { { 0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69 } }, + { { 0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f } } }, + { { { 0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02 } }, + { { 0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d } }, + { { 0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54 } } }, + { { { 0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b } }, + { { 0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19 } } }, + { { { 0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f } }, + { { 0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64 } } }, + { { { 0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71 } }, + { { 0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22 } }, + { { 0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79 } } }, + { { { 0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c } }, + { { 0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57 } } }, + { { { 0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e } }, + { { 0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f } } }, + { { { 0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f } }, + { { 0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f } }, + { { 0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77 } } }, + { { { 0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f } }, + { { 0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b } } }, + { { { 0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39 } }, + { { 0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f } } }, + { { { 0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f } }, + { { 0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47 } }, + { { 0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28 } } }, + { { { 0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22 } }, + { { 0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63 } } }, + { { { 0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17 } }, + { { 0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65 } } }, + { { { 0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a } }, + { { 0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36 } }, + { { 0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b } } }, + { { { 0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f } }, + { { 0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16 } } }, + { { { 0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b } }, + { { 0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07 } } }, + { { { 0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60 } }, + { { 0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08 } }, + { { 0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47 } } }, + { { { 0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b } }, + { { 0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63 } } }, + { { { 0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d } }, + { { 0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51 } } }, + { { { 0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b } }, + { { 0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f } }, + { { 0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f } } }, + { { { 0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08 } }, + { { 0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38 } } }, + { { { 0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10 } }, + { { 0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49 } } }, + { { { 0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25 } }, + { { 0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05 } }, + { { 0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23 } } }, + { { { 0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69 } }, + { { 0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e } } }, + { { { 0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12 } }, + { { 0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07 } } }, + { { { 0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62 } }, + { { 0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e } }, + { { 0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a } } }, + { { { 0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f } }, + { { 0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13 } } }, + { { { 0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c } }, + { { 0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f } } }, + { { { 0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e } }, + { { 0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c } }, + { { 0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f } } }, + { { { 0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c } }, + { { 0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00 } } }, + { { { 0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77 } }, + { { 0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72 } } }, + { { { 0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a } }, + { { 0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51 } }, + { { 0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35 } } }, + { { { 0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56 } }, + { { 0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c } } }, + { { { 0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f } }, + { { 0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13 } } }, + { { { 0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33 } }, + { { 0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33 } }, + { { 0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c } } }, + { { { 0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f } }, + { { 0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a } } }, + { { { 0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39 } }, + { { 0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34 } } }, + { { { 0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30 } }, + { { 0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60 } }, + { { 0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b } } }, + { { { 0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e } }, + { { 0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d } } }, + { { { 0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a } }, + { { 0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08 } } }, + { { { 0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19 } }, + { { 0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28 } }, + { { 0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09 } } }, + { { { 0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34 } }, + { { 0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b } } }, + { { { 0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57 } }, + { { 0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79 } } }, + { { { 0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c } }, + { { 0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49 } }, + { { 0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32 } } }, + { { { 0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65 } }, + { { 0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50 } } }, + { { { 0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34 } }, + { { 0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51 } } }, + { { { 0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09 } }, + { { 0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46 } }, + { { 0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f } } }, + { { { 0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43 } }, + { { 0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d } } }, + { { { 0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c } }, + { { 0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70 } } }, + { { { 0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62 } }, + { { 0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b } }, + { { 0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09 } } }, + { { { 0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e } }, + { { 0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10 } } }, + { { { 0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20 } }, + { { 0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03 } } }, + { { { 0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b } }, + { { 0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19 } }, + { { 0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e } } }, + { { { 0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45 } }, + { { 0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52 } } }, + { { { 0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06 } }, + { { 0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34 } } }, + { { { 0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39 } }, + { { 0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d } }, + { { 0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31 } } }, + { { { 0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22 } }, + { { 0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62 } } }, + { { { 0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32 } }, + { { 0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42 } } }, + { { { 0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04 } }, + { { 0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63 } }, + { { 0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b } } }, + { { { 0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b } }, + { { 0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47 } } }, + { { { 0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66 } }, + { { 0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48 } } }, + { { { 0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06 } }, + { { 0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f } }, + { { 0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66 } } }, + { { { 0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d } }, + { { 0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b } } }, + { { { 0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72 } }, + { { 0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02 } } }, + { { { 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c } }, + { { 0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78 } }, + { { 0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65 } } }, + { { { 0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21 } }, + { { 0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50 } } }, + { { { 0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d } }, + { { 0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56 } } }, + { { { 0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77 } }, + { { 0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53 } }, + { { 0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a } } }, + { { { 0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26 } }, + { { 0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a } } }, + { { { 0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28 } }, + { { 0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d } } }, + { { { 0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56 } }, + { { 0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21 } }, + { { 0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a } } }, + { { { 0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b } }, + { { 0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c } } }, + { { { 0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d } }, + { { 0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c } } }, + { { { 0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f } }, + { { 0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f } }, + { { 0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59 } } }, + { { { 0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08 } }, + { { 0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b } } }, + { { { 0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06 } }, + { { 0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22 } } }, + { { { 0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78 } }, + { { 0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17 } }, + { { 0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b } } }, + { { { 0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01 } }, + { { 0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b } } }, + { { { 0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06 } }, + { { 0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36 } } }, + { { { 0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f } }, + { { 0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b } }, + { { 0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b } } }, + { { { 0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f } }, + { { 0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53 } } }, + { { { 0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e } }, + { { 0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41 } } }, + { { { 0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61 } }, + { { 0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13 } }, + { { 0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08 } } }, + { { { 0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f } }, + { { 0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16 } } }, + { { { 0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c } }, + { { 0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16 } } }, + { { { 0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25 } }, + { { 0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e } }, + { { 0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e } } }, + { { { 0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28 } }, + { { 0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32 } } }, + { { { 0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b } }, + { { 0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e } } }, + { { { 0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c } }, + { { 0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27 } }, + { { 0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57 } } }, + { { { 0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c } }, + { { 0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12 } } }, + { { { 0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22 } }, + { { 0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a } } }, + { { { 0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c } }, + { { 0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31 } }, + { { 0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77 } } }, + { { { 0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50 } }, + { { 0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f } } }, + { { { 0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f } }, + { { 0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f } } }, + { { { 0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24 } }, + { { 0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73 } }, + { { 0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11 } } }, + { { { 0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54 } }, + { { 0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03 } } }, + { { { 0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07 } }, + { { 0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c } } }, + { { { 0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02 } }, + { { 0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28 } }, + { { 0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54 } } }, + { { { 0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c } }, + { { 0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42 } } }, + { { { 0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54 } }, + { { 0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b } } }, + { { { 0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a } }, + { { 0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38 } }, + { { 0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d } } }, + { { { 0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68 } }, + { { 0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b } } }, + { { { 0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b } }, + { { 0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01 } } }, + { { { 0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37 } }, + { { 0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e } }, + { { 0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f } } }, + { { { 0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d } }, + { { 0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e } } }, + { { { 0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d } }, + { { 0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07 } } }, + { { { 0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f } }, + { { 0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70 } }, + { { 0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14 } } }, + { { { 0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47 } }, + { { 0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10 } } }, + { { { 0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f } }, + { { 0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f } } }, + { { { 0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37 } }, + { { 0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c } }, + { { 0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c } } }, + { { { 0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a } }, + { { 0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49 } } }, + { { { 0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25 } }, + { { 0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67 } } }, + { { { 0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04 } }, + { { 0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60 } }, + { { 0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22 } } }, + { { { 0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48 } }, + { { 0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55 } } }, + { { { 0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13 } }, + { { 0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29 } } }, + { { { 0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37 } }, + { { 0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24 } }, + { { 0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65 } } }, + { { { 0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72 } }, + { { 0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e } } }, + { { { 0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d } }, + { { 0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c } } }, + { { { 0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a } }, + { { 0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e } }, + { { 0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e } } }, + { { { 0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e } }, + { { 0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b } } }, + { { { 0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20 } }, + { { 0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79 } } }, + { { { 0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56 } }, + { { 0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14 } }, + { { 0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44 } } }, + { { { 0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a } }, + { { 0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73 } } }, + { { { 0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13 } }, + { { 0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c } } }, + { { { 0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f } }, + { { 0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b } }, + { { 0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c } } }, + { { { 0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a } }, + { { 0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65 } } }, + { { { 0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53 } }, + { { 0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09 } } }, + { { { 0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f } }, + { { 0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b } }, + { { 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61 } } }, + { { { 0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06 } }, + { { 0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d } } }, + { { { 0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76 } }, + { { 0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e } } }, + { { { 0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a } }, + { { 0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07 } }, + { { 0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16 } } }, + { { { 0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46 } }, + { { 0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b } } }, + { { { 0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16 } }, + { { 0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08 } } }, + { { { 0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59 } }, + { { 0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10 } }, + { { 0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13 } } }, + { { { 0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b } }, + { { 0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c } } }, + { { { 0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70 } }, + { { 0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65 } } }, + { { { 0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e } }, + { { 0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e } }, + { { 0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c } } }, + { { { 0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c } }, + { { 0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26 } } }, + { { { 0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72 } }, + { { 0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c } } }, + { { { 0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59 } }, + { { 0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11 } }, + { { 0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43 } } }, + { { { 0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06 } }, + { { 0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10 } } }, + { { { 0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48 } }, + { { 0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e } } }, + { { { 0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e } }, + { { 0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e } }, + { { 0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70 } } }, + { { { 0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33 } }, + { { 0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b } } }, + { { { 0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f } }, + { { 0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56 } } }, + { { { 0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36 } }, + { { 0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c } }, + { { 0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74 } } }, + { { { 0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53 } }, + { { 0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c } } }, + { { { 0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76 } }, + { { 0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20 } } }, + { { { 0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b } }, + { { 0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e } }, + { { 0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30 } } }, + { { { 0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49 } }, + { { 0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f } } }, + { { { 0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46 } }, + { { 0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20 } } }, + { { { 0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07 } }, + { { 0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10 } }, + { { 0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29 } } }, + { { { 0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e } }, + { { 0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35 } } }, + { { { 0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e } }, + { { 0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c } } }, + { { { 0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31 } }, + { { 0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b } }, + { { 0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f } } }, + { { { 0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25 } }, + { { 0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17 } } }, + { { { 0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35 } }, + { { 0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27 } } }, + { { { 0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71 } }, + { { 0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76 } }, + { { 0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24 } } }, + { { { 0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d } }, + { { 0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45 } } }, + { { { 0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04 } }, + { { 0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45 } } }, + { { { 0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75 } }, + { { 0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d } }, + { { 0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d } } }, + { { { 0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16 } }, + { { 0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23 } } }, + { { { 0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45 } }, + { { 0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57 } } }, + { { { 0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66 } }, + { { 0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d } }, + { { 0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10 } } }, + { { { 0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c } }, + { { 0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30 } } }, + { { { 0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43 } }, + { { 0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11 } } }, + { { { 0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27 } }, + { { 0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46 } }, + { { 0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d } } }, + { { { 0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75 } }, + { { 0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60 } } }, + { { { 0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d } }, + { { 0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04 } } }, + { { { 0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66 } }, + { { 0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50 } }, + { { 0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50 } } }, + { { { 0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07 } }, + { { 0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a } } }, + { { { 0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d } }, + { { 0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b } } }, + { { { 0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25 } }, + { { 0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24 } }, + { { 0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02 } } }, + { { { 0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05 } }, + { { 0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58 } } }, + { { { 0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67 } }, + { { 0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e } } }, + { { { 0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d } }, + { { 0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28 } }, + { { 0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55 } } }, + { { { 0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e } }, + { { 0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d } } }, + { { { 0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19 } }, + { { 0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a } } }, + { { { 0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39 } }, + { { 0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e } }, + { { 0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e } } }, + { { { 0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59 } }, + { { 0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c } } }, + { { { 0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68 } }, + { { 0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e } } }, + { { { 0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b } }, + { { 0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a } }, + { { 0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40 } } }, + { { { 0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24 } }, + { { 0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b } } }, + { { { 0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c } }, + { { 0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a } } }, + { { { 0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58 } }, + { { 0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19 } }, + { { 0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52 } } }, + { { { 0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08 } }, + { { 0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09 } } }, + { { { 0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e } }, + { { 0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e } } }, + { { { 0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03 } }, + { { 0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15 } } }, + { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { { { 0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a } }, + { { 0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f } } }, + { { { 0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34 } }, + { { 0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09 } } }, + { { { 0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06 } }, + { { 0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f } } }, + { { { 0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05 } }, + { { 0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51 } } } }; -static inline void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) +static inline void p1p1_to_p2(ge25519_p2* r, const ge25519_p1p1* p) { fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->z, &p->z, &p->t); } -static inline void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p) +static inline void p1p1_to_p2_2(ge25519_p3* r, const ge25519_p1p1* p) { fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->z, &p->z, &p->t); } -static inline void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) +static inline void p1p1_to_p3(ge25519_p3* r, const ge25519_p1p1* p) { p1p1_to_p2_2(r, p); fe25519_mul(&r->t, &p->x, &p->y); } -static inline void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q) +static inline void ge25519_mixadd2(ge25519_p3* r, const ge25519_aff* q) { - fe25519 a,b,t1,t2,c,d,e,f,g,h,qt; + fe25519 a, b, t1, t2, c, d, e, f, g, h, qt; fe25519_mul(&qt, &q->x, &q->y); fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */ fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */ @@ -2258,20 +2188,20 @@ static inline void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q) fe25519_add(&t2, &q->y, &q->x); fe25519_mul(&a, &a, &t1); fe25519_mul(&b, &b, &t2); - fe25519_sub(&e, &b, &a); /* E = B-A */ - fe25519_add(&h, &b, &a); /* H = B+A */ + fe25519_sub(&e, &b, &a); /* E = B-A */ + fe25519_add(&h, &b, &a); /* H = B+A */ fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */ fe25519_mul(&c, &c, &ge25519_ec2d); fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */ - fe25519_sub(&f, &d, &c); /* F = D-C */ - fe25519_add(&g, &d, &c); /* G = D+C */ + fe25519_sub(&f, &d, &c); /* F = D-C */ + fe25519_add(&g, &d, &c); /* G = D+C */ fe25519_mul(&r->x, &e, &f); fe25519_mul(&r->y, &h, &g); fe25519_mul(&r->z, &g, &f); fe25519_mul(&r->t, &e, &h); } -static inline void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q) +static inline void add_p1p1(ge25519_p1p1* r, const ge25519_p3* p, const ge25519_p3* q) { fe25519 a, b, c, d, t; @@ -2292,9 +2222,9 @@ static inline void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_ } /* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ -static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) +static inline void dbl_p1p1(ge25519_p1p1* r, const ge25519_p2* p) { - fe25519 a,b,c,d; + fe25519 a, b, c, d; fe25519_square(&a, &p->x); fe25519_square(&b, &p->y); fe25519_square(&c, &p->z); @@ -2311,44 +2241,44 @@ static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) } /* Constant-time version of: if(b) r = p */ -static inline void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) +static inline void cmov_aff(ge25519_aff* r, const ge25519_aff* p, unsigned char b) { fe25519_cmov(&r->x, &p->x, b); fe25519_cmov(&r->y, &p->y, b); } -static inline unsigned char equal(signed char b,signed char c) +static inline unsigned char equal(signed char b, signed char c) { unsigned char ub = b; unsigned char uc = c; unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - crypto_uint32 y = x; /* 0: yes; 1..255: no */ - y -= 1; /* 4294967295: yes; 0..254: no */ - y >>= 31; /* 1: yes; 0: no */ + crypto_uint32 y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ return (unsigned char)y; } static inline unsigned char negative(signed char b) { unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - x >>= 63; /* 1: yes; 0: no */ + x >>= 63; /* 1: yes; 0: no */ return (unsigned char)x; } -static inline void choose_t(ge25519_aff *t, unsigned long long pos, signed char b) +static inline void choose_t(ge25519_aff* t, unsigned long long pos, signed char b) { /* constant time */ fe25519 v; - *t = ge25519_base_multiples_affine[5*pos+0]; - cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1)); - cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2)); - cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3)); - cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4)); + *t = ge25519_base_multiples_affine[5 * pos + 0]; + cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 1], equal(b, 1) | equal(b, -1)); + cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 2], equal(b, 2) | equal(b, -2)); + cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 3], equal(b, 3) | equal(b, -3)); + cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 4], equal(b, -4)); fe25519_neg(&v, &t->x); fe25519_cmov(&t->x, &v, negative(b)); } -static inline void setneutral(ge25519 *r) +static inline void setneutral(ge25519* r) { fe25519_setzero(&r->x); fe25519_setone(&r->y); @@ -2357,17 +2287,17 @@ static inline void setneutral(ge25519 *r) } /* return 0 on success, -1 otherwise */ -static inline int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) +static inline int ge25519_unpackneg_vartime(ge25519_p3* r, const unsigned char p[32]) { unsigned char par; fe25519 t, chk, num, den, den2, den4, den6; fe25519_setone(&r->z); par = p[31] >> 7; fe25519_unpack(&r->y, p); - fe25519_square(&num, &r->y); /* x = y^2 */ + fe25519_square(&num, &r->y); /* x = y^2 */ fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */ - fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ - fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ + fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ + fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ /* Computation of sqrt(num/den) */ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ @@ -2387,19 +2317,19 @@ static inline int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */ fe25519_square(&chk, &r->x); fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) { + if (! fe25519_iseq_vartime(&chk, &num)) { fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1); } /* 4. Now we have one of the two square roots, except if input was not a square */ fe25519_square(&chk, &r->x); fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) { + if (! fe25519_iseq_vartime(&chk, &num)) { return -1; } /* 5. Choose the desired square root according to parity: */ - if(fe25519_getparity(&r->x) != (1-par)) { + if (fe25519_getparity(&r->x) != (1 - par)) { fe25519_neg(&r->x, &r->x); } @@ -2407,7 +2337,7 @@ static inline int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p return 0; } -static inline void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) +static inline void ge25519_pack(unsigned char r[32], const ge25519_p3* p) { fe25519 tx, ty, zi; fe25519_invert(&zi, &p->z); @@ -2418,119 +2348,133 @@ static inline void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) } /* computes [s1]p1 + [s2]p2 */ -static inline void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2) +static inline void ge25519_double_scalarmult_vartime(ge25519_p3* r, const ge25519_p3* p1, const sc25519* s1, const ge25519_p3* p2, const sc25519* s2) { ge25519_p1p1 tp1p1; ge25519_p3 pre[16]; - char *pre5 = (char *)(&(pre[5])); // eliminate type punning warning + char* pre5 = (char*)(&(pre[5])); // eliminate type punning warning unsigned char b[127]; int i; /* precomputation s2 s1 */ - setneutral(pre); /* 00 00 */ - pre[1] = *p1; /* 00 01 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */ - add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */ - pre[4] = *p2; /* 01 00 */ - add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */ - add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */ - add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */ - add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)pre5); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */ - add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */ - add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */ - add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */ - add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */ - add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */ + setneutral(pre); /* 00 00 */ + pre[1] = *p1; /* 00 01 */ + dbl_p1p1(&tp1p1, (ge25519_p2*)p1); + p1p1_to_p3(&pre[2], &tp1p1); /* 00 10 */ + add_p1p1(&tp1p1, &pre[1], &pre[2]); + p1p1_to_p3(&pre[3], &tp1p1); /* 00 11 */ + pre[4] = *p2; /* 01 00 */ + add_p1p1(&tp1p1, &pre[1], &pre[4]); + p1p1_to_p3(&pre[5], &tp1p1); /* 01 01 */ + add_p1p1(&tp1p1, &pre[2], &pre[4]); + p1p1_to_p3(&pre[6], &tp1p1); /* 01 10 */ + add_p1p1(&tp1p1, &pre[3], &pre[4]); + p1p1_to_p3(&pre[7], &tp1p1); /* 01 11 */ + dbl_p1p1(&tp1p1, (ge25519_p2*)p2); + p1p1_to_p3(&pre[8], &tp1p1); /* 10 00 */ + add_p1p1(&tp1p1, &pre[1], &pre[8]); + p1p1_to_p3(&pre[9], &tp1p1); /* 10 01 */ + dbl_p1p1(&tp1p1, (ge25519_p2*)pre5); + p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */ + add_p1p1(&tp1p1, &pre[3], &pre[8]); + p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */ + add_p1p1(&tp1p1, &pre[4], &pre[8]); + p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */ + add_p1p1(&tp1p1, &pre[1], &pre[12]); + p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */ + add_p1p1(&tp1p1, &pre[2], &pre[12]); + p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */ + add_p1p1(&tp1p1, &pre[3], &pre[12]); + p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */ - sc25519_2interleave2(b,s1,s2); + sc25519_2interleave2(b, s1, s2); /* scalar multiplication */ *r = pre[b[126]]; - for(i=125;i>=0;i--) { - dbl_p1p1(&tp1p1, (ge25519_p2 *)r); - p1p1_to_p2((ge25519_p2 *) r, &tp1p1); - dbl_p1p1(&tp1p1, (ge25519_p2 *)r); - if(b[i]!=0) { + for (i = 125; i >= 0; i--) { + dbl_p1p1(&tp1p1, (ge25519_p2*)r); + p1p1_to_p2((ge25519_p2*)r, &tp1p1); + dbl_p1p1(&tp1p1, (ge25519_p2*)r); + if (b[i] != 0) { p1p1_to_p3(r, &tp1p1); add_p1p1(&tp1p1, r, &pre[b[i]]); } if (i != 0) { - p1p1_to_p2((ge25519_p2 *)r, &tp1p1); - } else { + p1p1_to_p2((ge25519_p2*)r, &tp1p1); + } + else { p1p1_to_p3(r, &tp1p1); } } } -static inline void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) +static inline void ge25519_scalarmult_base(ge25519_p3* r, const sc25519* s) { signed char b[85]; int i; ge25519_aff t; - sc25519_window3(b,s); + sc25519_window3(b, s); - choose_t((ge25519_aff *)r, 0, b[0]); + choose_t((ge25519_aff*)r, 0, b[0]); fe25519_setone(&r->z); fe25519_mul(&r->t, &r->x, &r->y); - for(i=1;i<85;i++) { - choose_t(&t, (unsigned long long) i, b[i]); + for (i = 1; i < 85; i++) { + choose_t(&t, (unsigned long long)i, b[i]); ge25519_mixadd2(r, &t); } } -static inline void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) +static inline void get_hram(unsigned char* hram, const unsigned char* sm, const unsigned char* pk, unsigned char* playground, unsigned long long smlen) { unsigned long long i; - for (i = 0;i < 32;++i) { + for (i = 0; i < 32; ++i) { playground[i] = sm[i]; } - for (i = 32;i < 64;++i) { - playground[i] = pk[i-32]; + for (i = 32; i < 64; ++i) { + playground[i] = pk[i - 32]; } - for (i = 64;i < smlen;++i) { + for (i = 64; i < smlen; ++i) { playground[i] = sm[i]; } - ZeroTier::SHA512(hram,playground,(unsigned int)smlen); + ZeroTier::SHA512(hram, playground, (unsigned int)smlen); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -} // anonymous namespace +} // anonymous namespace #ifdef ZT_USE_FAST_X64_ED25519 -extern "C" void ed25519_amd64_asm_sign(const unsigned char *sk,const unsigned char *pk,const unsigned char *digest,unsigned char *sig); +extern "C" void ed25519_amd64_asm_sign(const unsigned char* sk, const unsigned char* pk, const unsigned char* digest, unsigned char* sig); #endif namespace ZeroTier { -void C25519::agree(const C25519::Private &mine,const C25519::Public &their,void *keybuf,unsigned int keylen) +void C25519::agree(const C25519::Private& mine, const C25519::Public& their, void* keybuf, unsigned int keylen) { unsigned char rawkey[32]; unsigned char digest[64]; - crypto_scalarmult(rawkey,mine.data,their.data); - SHA512(digest,rawkey,32); - for(unsigned int i=0,k=0;i - static inline Pair generateSatisfying(F cond) + template static inline Pair generateSatisfying(F cond) { Pair kp; - void *const priv = (void *)kp.priv.data; - Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN); - _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv + void* const priv = (void*)kp.priv.data; + Utils::getSecureRandom(priv, ZT_C25519_PRIVATE_KEY_LEN); + _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv do { - ++(((uint64_t *)priv)[1]); - --(((uint64_t *)priv)[2]); - _calcPubDH(kp); // keep regenerating bytes 0-31 until satisfied - } while (!cond(kp)); + ++(((uint64_t*)priv)[1]); + --(((uint64_t*)priv)[2]); + _calcPubDH(kp); // keep regenerating bytes 0-31 until satisfied + } while (! cond(kp)); return kp; } @@ -84,8 +91,11 @@ public: * @param keybuf Buffer to fill * @param keylen Number of key bytes to generate */ - static void agree(const Private &mine,const Public &their,void *keybuf,unsigned int keylen); - static inline void agree(const Pair &mine,const Public &their,void *keybuf,unsigned int keylen) { agree(mine.priv,their,keybuf,keylen); } + static void agree(const Private& mine, const Public& their, void* keybuf, unsigned int keylen); + static inline void agree(const Pair& mine, const Public& their, void* keybuf, unsigned int keylen) + { + agree(mine.priv, their, keybuf, keylen); + } /** * Sign a message with a sender's key pair @@ -106,8 +116,11 @@ public: * @param len Length of message in bytes * @param signature Buffer to fill with signature -- MUST be 96 bytes in length */ - static void sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len,void *signature); - static inline void sign(const Pair &mine,const void *msg,unsigned int len,void *signature) { sign(mine.priv,mine.pub,msg,len,signature); } + static void sign(const Private& myPrivate, const Public& myPublic, const void* msg, unsigned int len, void* signature); + static inline void sign(const Pair& mine, const void* msg, unsigned int len, void* signature) + { + sign(mine.priv, mine.pub, msg, len, signature); + } /** * Sign a message with a sender's key pair @@ -118,16 +131,16 @@ public: * @param len Length of message in bytes * @return Signature */ - static inline Signature sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len) + static inline Signature sign(const Private& myPrivate, const Public& myPublic, const void* msg, unsigned int len) { Signature sig; - sign(myPrivate,myPublic,msg,len,sig.data); + sign(myPrivate, myPublic, msg, len, sig.data); return sig; } - static inline Signature sign(const Pair &mine,const void *msg,unsigned int len) + static inline Signature sign(const Pair& mine, const void* msg, unsigned int len) { Signature sig; - sign(mine.priv,mine.pub,msg,len,sig.data); + sign(mine.priv, mine.pub, msg, len, sig.data); return sig; } @@ -140,7 +153,7 @@ public: * @param signature 96-byte signature * @return True if signature is valid and the message is authentic and unmodified */ - static bool verify(const Public &their,const void *msg,unsigned int len,const void *signature); + static bool verify(const Public& their, const void* msg, unsigned int len, const void* signature); /** * Verify a message's signature @@ -151,21 +164,21 @@ public: * @param signature 96-byte signature * @return True if signature is valid and the message is authentic and unmodified */ - static inline bool verify(const Public &their,const void *msg,unsigned int len,const Signature &signature) + static inline bool verify(const Public& their, const void* msg, unsigned int len, const Signature& signature) { - return verify(their,msg,len,signature.data); + return verify(their, msg, len, signature.data); } -private: + private: // derive first 32 bytes of kp.pub from first 32 bytes of kp.priv // this is the ECDH key - static void _calcPubDH(Pair &kp); + static void _calcPubDH(Pair& kp); // derive 2nd 32 bytes of kp.pub from 2nd 32 bytes of kp.priv // this is the Ed25519 sign/verify key - static void _calcPubED(Pair &kp); + static void _calcPubED(Pair& kp); }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Capability.cpp b/node/Capability.cpp index 6e19fca30..b7ee3f9f7 100644 --- a/node/Capability.cpp +++ b/node/Capability.cpp @@ -12,54 +12,60 @@ /****/ #include "Capability.hpp" -#include "RuntimeEnvironment.hpp" + #include "Identity.hpp" -#include "Topology.hpp" -#include "Switch.hpp" #include "Network.hpp" #include "Node.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" namespace ZeroTier { -int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const +int Capability::verify(const RuntimeEnvironment* RR, void* tPtr) const { try { // There must be at least one entry, and sanity check for bad chain max length - if ((_maxCustodyChainLength < 1)||(_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { + if ((_maxCustodyChainLength < 1) || (_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { return -1; } // Validate all entries in chain of custody Buffer<(sizeof(Capability) * 2)> tmp; - this->serialize(tmp,true); - for(unsigned int c=0;c<_maxCustodyChainLength;++c) { + this->serialize(tmp, true); + for (unsigned int c = 0; c < _maxCustodyChainLength; ++c) { if (c == 0) { - if ((!_custody[c].to)||(!_custody[c].from)||(_custody[c].from != Network::controllerFor(_nwid))) { - return -1; // the first entry must be present and from the network's controller + if ((! _custody[c].to) || (! _custody[c].from) || (_custody[c].from != Network::controllerFor(_nwid))) { + return -1; // the first entry must be present and from the network's controller } - } else { - if (!_custody[c].to) { - return 0; // all previous entries were valid, so we are valid - } else if ((!_custody[c].from)||(_custody[c].from != _custody[c-1].to)) { - return -1; // otherwise if we have another entry it must be from the previous holder in the chain + } + else { + if (! _custody[c].to) { + return 0; // all previous entries were valid, so we are valid + } + else if ((! _custody[c].from) || (_custody[c].from != _custody[c - 1].to)) { + return -1; // otherwise if we have another entry it must be from the previous holder in the chain } } - const Identity id(RR->topology->getIdentity(tPtr,_custody[c].from)); + const Identity id(RR->topology->getIdentity(tPtr, _custody[c].from)); if (id) { - if (!id.verify(tmp.data(),tmp.size(),_custody[c].signature)) { + if (! id.verify(tmp.data(), tmp.size(), _custody[c].signature)) { return -1; } - } else { - RR->sw->requestWhois(tPtr,RR->node->now(),_custody[c].from); + } + else { + RR->sw->requestWhois(tPtr, RR->node->now(), _custody[c].from); return 1; } } // We reached max custody chain length and everything was valid return 0; - } catch ( ... ) {} + } + catch (...) { + } return -1; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Capability.hpp b/node/Capability.hpp index e57eec5bc..798f09e48 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -14,19 +14,19 @@ #ifndef ZT_CAPABILITY_HPP #define ZT_CAPABILITY_HPP +#include "../include/ZeroTierOne.h" +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" +#include "Constants.hpp" +#include "Credential.hpp" +#include "Identity.hpp" +#include "Utils.hpp" + #include #include #include -#include "Constants.hpp" -#include "Credential.hpp" -#include "Address.hpp" -#include "C25519.hpp" -#include "Utils.hpp" -#include "Buffer.hpp" -#include "Identity.hpp" -#include "../include/ZeroTierOne.h" - namespace ZeroTier { class RuntimeEnvironment; @@ -54,20 +54,17 @@ class RuntimeEnvironment; * handed off between nodes. Limited transferability of capabilities is * a feature of true capability based security. */ -class Capability : public Credential -{ -public: - static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; } - - Capability() : - _nwid(0), - _ts(0), - _id(0), - _maxCustodyChainLength(0), - _ruleCount(0) +class Capability : public Credential { + public: + static inline Credential::Type credentialType() { - memset(_rules,0,sizeof(_rules)); - memset(_custody,0,sizeof(_custody)); + return Credential::CREDENTIAL_TYPE_CAPABILITY; + } + + Capability() : _nwid(0), _ts(0), _id(0), _maxCustodyChainLength(0), _ruleCount(0) + { + memset(_rules, 0, sizeof(_rules)); + memset(_custody, 0, sizeof(_custody)); } /** @@ -78,42 +75,57 @@ public: * @param rules Network flow rules for this capability * @param ruleCount Number of flow rules */ - Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) : - _nwid(nwid), - _ts(ts), - _id(id), - _maxCustodyChainLength((mccl > 0) ? ((mccl < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) ? mccl : (unsigned int)ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) : 1), - _ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES) + Capability(uint32_t id, uint64_t nwid, int64_t ts, unsigned int mccl, const ZT_VirtualNetworkRule* rules, unsigned int ruleCount) + : _nwid(nwid) + , _ts(ts) + , _id(id) + , _maxCustodyChainLength((mccl > 0) ? ((mccl < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) ? mccl : (unsigned int)ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) : 1) + , _ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES) { if (_ruleCount > 0) { - memcpy(_rules,rules,sizeof(ZT_VirtualNetworkRule) * _ruleCount); + memcpy(_rules, rules, sizeof(ZT_VirtualNetworkRule) * _ruleCount); } } /** * @return Rules -- see ruleCount() for size of array */ - inline const ZT_VirtualNetworkRule *rules() const { return _rules; } + inline const ZT_VirtualNetworkRule* rules() const + { + return _rules; + } /** * @return Number of rules in rules() */ - inline unsigned int ruleCount() const { return _ruleCount; } + inline unsigned int ruleCount() const + { + return _ruleCount; + } /** * @return ID and evaluation order of this capability in network */ - inline uint32_t id() const { return _id; } + inline uint32_t id() const + { + return _id; + } /** * @return Network ID for which this capability was issued */ - inline uint64_t networkId() const { return _nwid; } + inline uint64_t networkId() const + { + return _nwid; + } /** * @return Timestamp */ - inline int64_t timestamp() const { return _ts; } + inline int64_t timestamp() const + { + return _ts; + } /** * @return Last 'to' address in chain of custody @@ -121,10 +133,11 @@ public: inline Address issuedTo() const { Address i2; - for(unsigned int i=0;i tmp; - this->serialize(tmp,true); + this->serialize(tmp, true); _custody[i].to = to; _custody[i].from = from.address(); - _custody[i].signature = from.sign(tmp.data(),tmp.size()); + _custody[i].signature = from.sign(tmp.data(), tmp.size()); return true; } } - } catch ( ... ) {} + } + catch (...) { + } return false; } @@ -167,17 +182,16 @@ public: * @param RR Runtime environment to provide for peer lookup, etc. * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; + int verify(const RuntimeEnvironment* RR, void* tPtr) const; - template - static inline void serializeRules(Buffer &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) + template static inline void serializeRules(Buffer& b, const ZT_VirtualNetworkRule* rules, unsigned int ruleCount) { - for(unsigned int i=0;i - static inline void deserializeRules(const Buffer &b,unsigned int &p,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,const unsigned int maxRuleCount) + template static inline void deserializeRules(const Buffer& b, unsigned int& p, ZT_VirtualNetworkRule* rules, unsigned int& ruleCount, const unsigned int maxRuleCount) { - while ((ruleCount < maxRuleCount)&&(p < b.size())) { + while ((ruleCount < maxRuleCount) && (p < b.size())) { rules[ruleCount].t = (uint8_t)b[p++]; const unsigned int fieldLen = (unsigned int)b[p++]; - switch((ZT_VirtualNetworkRuleType)(rules[ruleCount].t & 0x3f)) { + switch ((ZT_VirtualNetworkRuleType)(rules[ruleCount].t & 0x3f)) { default: break; case ZT_NETWORK_RULE_ACTION_TEE: @@ -302,7 +315,7 @@ public: break; case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS: case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS: - rules[ruleCount].v.zt = Address(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH).toInt(); + rules[ruleCount].v.zt = Address(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH).toInt(); break; case ZT_NETWORK_RULE_MATCH_VLAN_ID: rules[ruleCount].v.vlanId = b.template at(p); @@ -315,22 +328,22 @@ public: break; case ZT_NETWORK_RULE_MATCH_MAC_SOURCE: case ZT_NETWORK_RULE_MATCH_MAC_DEST: - memcpy(rules[ruleCount].v.mac,b.field(p,6),6); + memcpy(rules[ruleCount].v.mac, b.field(p, 6), 6); break; case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE: case ZT_NETWORK_RULE_MATCH_IPV4_DEST: - memcpy(&(rules[ruleCount].v.ipv4.ip),b.field(p,4),4); + memcpy(&(rules[ruleCount].v.ipv4.ip), b.field(p, 4), 4); rules[ruleCount].v.ipv4.mask = (uint8_t)b[p + 4]; break; case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE: case ZT_NETWORK_RULE_MATCH_IPV6_DEST: - memcpy(rules[ruleCount].v.ipv6.ip,b.field(p,16),16); + memcpy(rules[ruleCount].v.ipv6.ip, b.field(p, 16), 16); rules[ruleCount].v.ipv6.mask = (uint8_t)b[p + 16]; break; case ZT_NETWORK_RULE_MATCH_IP_TOS: rules[ruleCount].v.ipTos.mask = (uint8_t)b[p]; - rules[ruleCount].v.ipTos.value[0] = (uint8_t)b[p+1]; - rules[ruleCount].v.ipTos.value[1] = (uint8_t)b[p+2]; + rules[ruleCount].v.ipTos.value[0] = (uint8_t)b[p + 1]; + rules[ruleCount].v.ipTos.value[1] = (uint8_t)b[p + 2]; break; case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL: rules[ruleCount].v.ipProtocol = (uint8_t)b[p]; @@ -340,8 +353,8 @@ public: break; case ZT_NETWORK_RULE_MATCH_ICMP: rules[ruleCount].v.icmp.type = (uint8_t)b[p]; - rules[ruleCount].v.icmp.code = (uint8_t)b[p+1]; - rules[ruleCount].v.icmp.flags = (uint8_t)b[p+2]; + rules[ruleCount].v.icmp.code = (uint8_t)b[p + 1]; + rules[ruleCount].v.icmp.flags = (uint8_t)b[p + 2]; break; case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE: case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE: @@ -380,8 +393,7 @@ public: } } - template - inline void serialize(Buffer &b,const bool forSign = false) const + template inline void serialize(Buffer& b, const bool forSign = false) const { if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); @@ -393,19 +405,20 @@ public: b.append(_id); b.append((uint16_t)_ruleCount); - serializeRules(b,_rules,_ruleCount); + serializeRules(b, _rules, _ruleCount); b.append((uint8_t)_maxCustodyChainLength); - if (!forSign) { - for(unsigned int i=0;;++i) { - if ((i < _maxCustodyChainLength)&&(i < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)&&(_custody[i].to)) { + if (! forSign) { + for (unsigned int i = 0;; ++i) { + if ((i < _maxCustodyChainLength) && (i < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) && (_custody[i].to)) { _custody[i].to.appendTo(b); _custody[i].from.appendTo(b); - b.append((uint8_t)1); // 1 == Ed25519 signature - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature - b.append(_custody[i].signature.data,ZT_C25519_SIGNATURE_LEN); - } else { - b.append((unsigned char)0,ZT_ADDRESS_LENGTH); // zero 'to' terminates chain + b.append((uint8_t)1); // 1 == Ed25519 signature + b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature + b.append(_custody[i].signature.data, ZT_C25519_SIGNATURE_LEN); + } + else { + b.append((unsigned char)0, ZT_ADDRESS_LENGTH); // zero 'to' terminates chain break; } } @@ -419,8 +432,7 @@ public: } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { *this = Capability(); @@ -438,33 +450,34 @@ public: if (rc > ZT_MAX_CAPABILITY_RULES) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } - deserializeRules(b,p,_rules,_ruleCount,rc); + deserializeRules(b, p, _rules, _ruleCount, rc); _maxCustodyChainLength = (unsigned int)b[p++]; - if ((_maxCustodyChainLength < 1)||(_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { + if ((_maxCustodyChainLength < 1) || (_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } - for(unsigned int i=0;;++i) { - const Address to(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + for (unsigned int i = 0;; ++i) { + const Address to(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; - if (!to) { + if (! to) { break; } - if ((i >= _maxCustodyChainLength)||(i >= ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { + if ((i >= _maxCustodyChainLength) || (i >= ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } _custody[i].to = to; - _custody[i].from.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _custody[i].from.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] == 1) { if (b.template at(p) != ZT_C25519_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_custody[i].signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_custody[i].signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; - } else { + } + else { p += 2 + b.template at(p); } } @@ -478,12 +491,21 @@ public: } // Provides natural sort order by ID - inline bool operator<(const Capability &c) const { return (_id < c._id); } + inline bool operator<(const Capability& c) const + { + return (_id < c._id); + } - inline bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); } - inline bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); } + inline bool operator==(const Capability& c) const + { + return (memcmp(this, &c, sizeof(Capability)) == 0); + } + inline bool operator!=(const Capability& c) const + { + return (memcmp(this, &c, sizeof(Capability)) != 0); + } -private: + private: uint64_t _nwid; int64_t _ts; uint32_t _id; @@ -500,6 +522,6 @@ private: } _custody[ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH]; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index 65820c29d..b1dcafcfd 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -12,15 +12,16 @@ /****/ #include "CertificateOfMembership.hpp" -#include "RuntimeEnvironment.hpp" -#include "Topology.hpp" -#include "Switch.hpp" + #include "Network.hpp" #include "Node.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" namespace ZeroTier { -CertificateOfMembership::CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Identity &issuedTo) +CertificateOfMembership::CertificateOfMembership(uint64_t timestamp, uint64_t timestampMaxDelta, uint64_t nwid, const Identity& issuedTo) { _qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP; _qualifiers[0].value = timestamp; @@ -36,34 +37,34 @@ CertificateOfMembership::CertificateOfMembership(uint64_t timestamp,uint64_t tim // using the original COM format. Format may be revised in the future to make this cleaner. uint64_t idHash[6]; issuedTo.publicKeyHash(idHash); - for(unsigned long i=0;i<4;++i) { + for (unsigned long i = 0; i < 4; ++i) { _qualifiers[i + 3].id = (uint64_t)(i + 3); _qualifiers[i + 3].value = Utils::ntoh(idHash[i]); _qualifiers[i + 3].maxDelta = 0xffffffffffffffffULL; } _qualifierCount = 7; - memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN); + memset(_signature.data, 0, ZT_C25519_SIGNATURE_LEN); } -bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other, const Identity &otherIdentity) const +bool CertificateOfMembership::agreesWith(const CertificateOfMembership& other, const Identity& otherIdentity) const { - if ((_qualifierCount == 0)||(other._qualifierCount == 0)) { + if ((_qualifierCount == 0) || (other._qualifierCount == 0)) { return false; } - std::map< uint64_t, uint64_t > otherFields; - for(unsigned int i=0;i otherFields; + for (unsigned int i = 0; i < other._qualifierCount; ++i) { otherFields[other._qualifiers[i].id] = other._qualifiers[i].value; } bool fullIdentityVerification = false; - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { const uint64_t qid = _qualifiers[i].id; - if ((qid >= 3)&&(qid <= 6)) { + if ((qid >= 3) && (qid <= 6)) { fullIdentityVerification = true; } - std::map< uint64_t, uint64_t >::iterator otherQ(otherFields.find(qid)); + std::map::iterator otherQ(otherFields.find(qid)); if (otherQ == otherFields.end()) { return false; } @@ -79,8 +80,8 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other, c if (fullIdentityVerification) { uint64_t idHash[6]; otherIdentity.publicKeyHash(idHash); - for(unsigned long i=0;i<4;++i) { - std::map< uint64_t, uint64_t >::iterator otherQ(otherFields.find((uint64_t)(i + 3))); + for (unsigned long i = 0; i < 4; ++i) { + std::map::iterator otherQ(otherFields.find((uint64_t)(i + 3))); if (otherQ == otherFields.end()) { return false; } @@ -93,46 +94,47 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other, c return true; } -bool CertificateOfMembership::sign(const Identity &with) +bool CertificateOfMembership::sign(const Identity& with) { uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; unsigned int ptr = 0; - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { buf[ptr++] = Utils::hton(_qualifiers[i].id); buf[ptr++] = Utils::hton(_qualifiers[i].value); buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); } try { - _signature = with.sign(buf,ptr * sizeof(uint64_t)); + _signature = with.sign(buf, ptr * sizeof(uint64_t)); _signedBy = with.address(); return true; - } catch ( ... ) { + } + catch (...) { _signedBy.zero(); return false; } } -int CertificateOfMembership::verify(const RuntimeEnvironment *RR,void *tPtr) const +int CertificateOfMembership::verify(const RuntimeEnvironment* RR, void* tPtr) const { - if ((!_signedBy)||(_signedBy != Network::controllerFor(networkId()))||(_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS)) { + if ((! _signedBy) || (_signedBy != Network::controllerFor(networkId())) || (_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS)) { return -1; } - const Identity id(RR->topology->getIdentity(tPtr,_signedBy)); - if (!id) { - RR->sw->requestWhois(tPtr,RR->node->now(),_signedBy); + const Identity id(RR->topology->getIdentity(tPtr, _signedBy)); + if (! id) { + RR->sw->requestWhois(tPtr, RR->node->now(), _signedBy); return 1; } uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; unsigned int ptr = 0; - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { buf[ptr++] = Utils::hton(_qualifiers[i].id); buf[ptr++] = Utils::hton(_qualifiers[i].value); buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); } - return (id.verify(buf,ptr * sizeof(uint64_t),_signature) ? 0 : -1); + return (id.verify(buf, ptr * sizeof(uint64_t), _signature) ? 0 : -1); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 2c289bfa7..70c9570ff 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -14,21 +14,20 @@ #ifndef ZT_CERTIFICATEOFMEMBERSHIP_HPP #define ZT_CERTIFICATEOFMEMBERSHIP_HPP -#include -#include - -#include -#include -#include - +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" -#include "Buffer.hpp" -#include "Address.hpp" -#include "C25519.hpp" #include "Identity.hpp" #include "Utils.hpp" +#include +#include +#include +#include +#include + /** * Maximum number of qualifiers allowed in a COM (absolute max: 65535) */ @@ -64,10 +63,12 @@ class RuntimeEnvironment; * This is a memcpy()'able structure and is safe (in a crash sense) to modify * without locks. */ -class CertificateOfMembership : public Credential -{ -public: - static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; } +class CertificateOfMembership : public Credential { + public: + static inline Credential::Type credentialType() + { + return Credential::CREDENTIAL_TYPE_COM; + } /** * Reserved qualifier IDs @@ -78,8 +79,7 @@ public: * Addition of new required fields requires that code in hasRequiredFields * be updated as well. */ - enum ReservedId - { + enum ReservedId { /** * Timestamp of certificate */ @@ -101,8 +101,9 @@ public: /** * Create an empty certificate of membership */ - CertificateOfMembership() : - _qualifierCount(0) {} + CertificateOfMembership() : _qualifierCount(0) + { + } /** * Create from required fields common to all networks @@ -112,7 +113,7 @@ public: * @param nwid Network ID * @param issuedTo Certificate recipient */ - CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Identity &issuedTo); + CertificateOfMembership(uint64_t timestamp, uint64_t timestampMaxDelta, uint64_t nwid, const Identity& issuedTo); /** * Create from binary-serialized COM in buffer @@ -120,28 +121,33 @@ public: * @param b Buffer to deserialize from * @param startAt Position to start in buffer */ - template - CertificateOfMembership(const Buffer &b,unsigned int startAt = 0) + template CertificateOfMembership(const Buffer& b, unsigned int startAt = 0) { - deserialize(b,startAt); + deserialize(b, startAt); } /** * @return True if there's something here */ - inline operator bool() const { return (_qualifierCount != 0); } + inline operator bool() const + { + return (_qualifierCount != 0); + } /** * @return Credential ID, always 0 for COMs */ - inline uint32_t id() const { return 0; } + inline uint32_t id() const + { + return 0; + } /** * @return Timestamp for this cert and maximum delta for timestamp */ inline int64_t timestamp() const { - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { if (_qualifiers[i].id == COM_RESERVED_ID_TIMESTAMP) { return _qualifiers[i].value; } @@ -154,7 +160,7 @@ public: */ inline Address issuedTo() const { - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { if (_qualifiers[i].id == COM_RESERVED_ID_ISSUED_TO) { return Address(_qualifiers[i].value); } @@ -167,7 +173,7 @@ public: */ inline uint64_t networkId() const { - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { if (_qualifiers[i].id == COM_RESERVED_ID_NETWORK_ID) { return _qualifiers[i].value; } @@ -189,7 +195,7 @@ public: * @param otherIdentity Identity of other node * @return True if certs agree and 'other' may be communicated with */ - bool agreesWith(const CertificateOfMembership &other, const Identity &otherIdentity) const; + bool agreesWith(const CertificateOfMembership& other, const Identity& otherIdentity) const; /** * Sign this certificate @@ -197,7 +203,7 @@ public: * @param with Identity to sign with, must include private key * @return True if signature was successful */ - bool sign(const Identity &with); + bool sign(const Identity& with); /** * Verify this COM and its signature @@ -206,36 +212,40 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or credential */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; + int verify(const RuntimeEnvironment* RR, void* tPtr) const; /** * @return True if signed */ - inline bool isSigned() const { return (_signedBy); } + inline bool isSigned() const + { + return (_signedBy); + } /** * @return Address that signed this certificate or null address if none */ - inline const Address &signedBy() const { return _signedBy; } + inline const Address& signedBy() const + { + return _signedBy; + } - template - inline void serialize(Buffer &b) const + template inline void serialize(Buffer& b) const { b.append((uint8_t)1); b.append((uint16_t)_qualifierCount); - for(unsigned int i=0;i<_qualifierCount;++i) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { b.append(_qualifiers[i].id); b.append(_qualifiers[i].value); b.append(_qualifiers[i].maxDelta); } _signedBy.appendTo(b); if (_signedBy) { - b.append(_signature.data,ZT_C25519_SIGNATURE_LEN); + b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { unsigned int p = startAt; @@ -249,11 +259,12 @@ public: unsigned int numq = b.template at(p); p += sizeof(uint16_t); uint64_t lastId = 0; - for(unsigned int i=0;i(p); if (qid < lastId) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING; - } else { + } + else { lastId = qid; } if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) { @@ -262,23 +273,24 @@ public: _qualifiers[_qualifierCount].maxDelta = b.template at(p + 16); p += 24; ++_qualifierCount; - } else { + } + else { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } } - _signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _signedBy.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (_signedBy) { - memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; } return (p - startAt); } - inline bool operator==(const CertificateOfMembership &c) const + inline bool operator==(const CertificateOfMembership& c) const { if (_signedBy != c._signedBy) { return false; @@ -286,25 +298,32 @@ public: if (_qualifierCount != c._qualifierCount) { return false; } - for(unsigned int i=0;i<_qualifierCount;++i) { - const _Qualifier &a = _qualifiers[i]; - const _Qualifier &b = c._qualifiers[i]; - if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta)) { + for (unsigned int i = 0; i < _qualifierCount; ++i) { + const _Qualifier& a = _qualifiers[i]; + const _Qualifier& b = c._qualifiers[i]; + if ((a.id != b.id) || (a.value != b.value) || (a.maxDelta != b.maxDelta)) { return false; } } - return (memcmp(_signature.data,c._signature.data,ZT_C25519_SIGNATURE_LEN) == 0); + return (memcmp(_signature.data, c._signature.data, ZT_C25519_SIGNATURE_LEN) == 0); } - inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); } - -private: - struct _Qualifier + inline bool operator!=(const CertificateOfMembership& c) const { - _Qualifier() : id(0),value(0),maxDelta(0) {} + return (! (*this == c)); + } + + private: + struct _Qualifier { + _Qualifier() : id(0), value(0), maxDelta(0) + { + } uint64_t id; uint64_t value; uint64_t maxDelta; - inline bool operator<(const _Qualifier &q) const { return (id < q.id); } // sort order + inline bool operator<(const _Qualifier& q) const + { + return (id < q.id); + } // sort order }; Address _signedBy; @@ -313,6 +332,6 @@ private: C25519::Signature _signature; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/CertificateOfOwnership.cpp b/node/CertificateOfOwnership.cpp index db5b2eb00..5a1cbf343 100644 --- a/node/CertificateOfOwnership.cpp +++ b/node/CertificateOfOwnership.cpp @@ -12,41 +12,43 @@ /****/ #include "CertificateOfOwnership.hpp" -#include "RuntimeEnvironment.hpp" + #include "Identity.hpp" -#include "Topology.hpp" -#include "Switch.hpp" #include "Network.hpp" #include "Node.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" namespace ZeroTier { -int CertificateOfOwnership::verify(const RuntimeEnvironment *RR,void *tPtr) const +int CertificateOfOwnership::verify(const RuntimeEnvironment* RR, void* tPtr) const { - if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId))) { + if ((! _signedBy) || (_signedBy != Network::controllerFor(_networkId))) { return -1; } - const Identity id(RR->topology->getIdentity(tPtr,_signedBy)); - if (!id) { - RR->sw->requestWhois(tPtr,RR->node->now(),_signedBy); + const Identity id(RR->topology->getIdentity(tPtr, _signedBy)); + if (! id) { + RR->sw->requestWhois(tPtr, RR->node->now(), _signedBy); return 1; } try { Buffer<(sizeof(CertificateOfOwnership) + 64)> tmp; - this->serialize(tmp,true); - return (id.verify(tmp.data(),tmp.size(),_signature) ? 0 : -1); - } catch ( ... ) { + this->serialize(tmp, true); + return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1); + } + catch (...) { return -1; } } -bool CertificateOfOwnership::_owns(const CertificateOfOwnership::Thing &t,const void *v,unsigned int l) const +bool CertificateOfOwnership::_owns(const CertificateOfOwnership::Thing& t, const void* v, unsigned int l) const { - for(unsigned int i=0,j=_thingCount;i(v)[k] != _thingValues[i][k]) { + if (reinterpret_cast(v)[k] != _thingValues[i][k]) { break; } ++k; @@ -59,4 +61,4 @@ bool CertificateOfOwnership::_owns(const CertificateOfOwnership::Thing &t,const return false; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/CertificateOfOwnership.hpp b/node/CertificateOfOwnership.hpp index e7b80f72c..aa18e188d 100644 --- a/node/CertificateOfOwnership.hpp +++ b/node/CertificateOfOwnership.hpp @@ -14,20 +14,20 @@ #ifndef ZT_CERTIFICATEOFOWNERSHIP_HPP #define ZT_CERTIFICATEOFOWNERSHIP_HPP +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" +#include "Constants.hpp" +#include "Credential.hpp" +#include "Identity.hpp" +#include "InetAddress.hpp" +#include "MAC.hpp" + #include #include #include #include -#include "Constants.hpp" -#include "Credential.hpp" -#include "C25519.hpp" -#include "Address.hpp" -#include "Identity.hpp" -#include "Buffer.hpp" -#include "InetAddress.hpp" -#include "MAC.hpp" - // Max things per CertificateOfOwnership #define ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS 16 @@ -41,84 +41,102 @@ class RuntimeEnvironment; /** * Certificate indicating ownership of a network identifier */ -class CertificateOfOwnership : public Credential -{ -public: - static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; } - - enum Thing +class CertificateOfOwnership : public Credential { + public: + static inline Credential::Type credentialType() { - THING_NULL = 0, - THING_MAC_ADDRESS = 1, - THING_IPV4_ADDRESS = 2, - THING_IPV6_ADDRESS = 3 - }; + return Credential::CREDENTIAL_TYPE_COO; + } + + enum Thing { THING_NULL = 0, THING_MAC_ADDRESS = 1, THING_IPV4_ADDRESS = 2, THING_IPV6_ADDRESS = 3 }; CertificateOfOwnership() { - memset(reinterpret_cast(this),0,sizeof(CertificateOfOwnership)); + memset(reinterpret_cast(this), 0, sizeof(CertificateOfOwnership)); } - CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id) + CertificateOfOwnership(const uint64_t nwid, const int64_t ts, const Address& issuedTo, const uint32_t id) { - memset(reinterpret_cast(this),0,sizeof(CertificateOfOwnership)); + memset(reinterpret_cast(this), 0, sizeof(CertificateOfOwnership)); _networkId = nwid; _ts = ts; _id = id; _issuedTo = issuedTo; } - inline uint64_t networkId() const { return _networkId; } - inline int64_t timestamp() const { return _ts; } - inline uint32_t id() const { return _id; } - inline unsigned int thingCount() const { return (unsigned int)_thingCount; } + inline uint64_t networkId() const + { + return _networkId; + } + inline int64_t timestamp() const + { + return _ts; + } + inline uint32_t id() const + { + return _id; + } + inline unsigned int thingCount() const + { + return (unsigned int)_thingCount; + } - inline Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; } - inline const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; } + inline Thing thingType(const unsigned int i) const + { + return (Thing)_thingTypes[i]; + } + inline const uint8_t* thingValue(const unsigned int i) const + { + return _thingValues[i]; + } - inline const Address &issuedTo() const { return _issuedTo; } + inline const Address& issuedTo() const + { + return _issuedTo; + } - inline bool owns(const InetAddress &ip) const + inline bool owns(const InetAddress& ip) const { if (ip.ss_family == AF_INET) { - return this->_owns(THING_IPV4_ADDRESS,&(reinterpret_cast(&ip)->sin_addr.s_addr),4); + return this->_owns(THING_IPV4_ADDRESS, &(reinterpret_cast(&ip)->sin_addr.s_addr), 4); } if (ip.ss_family == AF_INET6) { - return this->_owns(THING_IPV6_ADDRESS,reinterpret_cast(&ip)->sin6_addr.s6_addr,16); + return this->_owns(THING_IPV6_ADDRESS, reinterpret_cast(&ip)->sin6_addr.s6_addr, 16); } return false; } - inline bool owns(const MAC &mac) const + inline bool owns(const MAC& mac) const { uint8_t tmp[6]; - mac.copyTo(tmp,6); - return this->_owns(THING_MAC_ADDRESS,tmp,6); + mac.copyTo(tmp, 6); + return this->_owns(THING_MAC_ADDRESS, tmp, 6); } - inline void addThing(const InetAddress &ip) + inline void addThing(const InetAddress& ip) { if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) { return; } if (ip.ss_family == AF_INET) { _thingTypes[_thingCount] = THING_IPV4_ADDRESS; - memcpy(_thingValues[_thingCount],&(reinterpret_cast(&ip)->sin_addr.s_addr),4); + memcpy(_thingValues[_thingCount], &(reinterpret_cast(&ip)->sin_addr.s_addr), 4); ++_thingCount; - } else if (ip.ss_family == AF_INET6) { + } + else if (ip.ss_family == AF_INET6) { _thingTypes[_thingCount] = THING_IPV6_ADDRESS; - memcpy(_thingValues[_thingCount],reinterpret_cast(&ip)->sin6_addr.s6_addr,16); + memcpy(_thingValues[_thingCount], reinterpret_cast(&ip)->sin6_addr.s6_addr, 16); ++_thingCount; } } - inline void addThing(const MAC &mac) + inline void addThing(const MAC& mac) { if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) { return; } _thingTypes[_thingCount] = THING_MAC_ADDRESS; - mac.copyTo(_thingValues[_thingCount],6); + mac.copyTo(_thingValues[_thingCount], 6); ++_thingCount; } @@ -126,13 +144,13 @@ public: * @param signer Signing identity, must have private key * @return True if signature was successful */ - inline bool sign(const Identity &signer) + inline bool sign(const Identity& signer) { if (signer.hasPrivate()) { Buffer tmp; _signedBy = signer.address(); - this->serialize(tmp,true); - _signature = signer.sign(tmp.data(),tmp.size()); + this->serialize(tmp, true); + _signature = signer.sign(tmp.data(), tmp.size()); return true; } return false; @@ -143,10 +161,9 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; + int verify(const RuntimeEnvironment* RR, void* tPtr) const; - template - inline void serialize(Buffer &b,const bool forSign = false) const + template inline void serialize(Buffer& b, const bool forSign = false) const { if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); @@ -157,28 +174,27 @@ public: b.append(_flags); b.append(_id); b.append((uint16_t)_thingCount); - for(unsigned int i=0,j=_thingCount;i - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { unsigned int p = startAt; @@ -194,26 +210,27 @@ public: p += 4; _thingCount = b.template at(p); p += 2; - for(unsigned int i=0,j=_thingCount;i(p) != ZT_C25519_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; - } else { + } + else { p += 2 + b.template at(p); } @@ -226,13 +243,22 @@ public: } // Provides natural sort order by ID - inline bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); } + inline bool operator<(const CertificateOfOwnership& coo) const + { + return (_id < coo._id); + } - inline bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); } - inline bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); } + inline bool operator==(const CertificateOfOwnership& coo) const + { + return (memcmp(this, &coo, sizeof(CertificateOfOwnership)) == 0); + } + inline bool operator!=(const CertificateOfOwnership& coo) const + { + return (memcmp(this, &coo, sizeof(CertificateOfOwnership)) != 0); + } -private: - bool _owns(const Thing &t,const void *v,unsigned int l) const; + private: + bool _owns(const Thing& t, const void* v, unsigned int l) const; uint64_t _networkId; int64_t _ts; @@ -246,6 +272,6 @@ private: C25519::Signature _signature; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Constants.hpp b/node/Constants.hpp index 95f093b3e..66621ec49 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -61,8 +61,8 @@ #ifdef ZT_SSO_SUPPORTED #define ZT_SSO_ENABLED 1 #endif -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) +#define likely(x) __builtin_expect((x), 1) +#define unlikely(x) __builtin_expect((x), 0) #include #ifndef __UNIX_LIKE__ #define __UNIX_LIKE__ @@ -85,9 +85,9 @@ #endif #include #ifndef __BYTE_ORDER -#define __BYTE_ORDER _BYTE_ORDER +#define __BYTE_ORDER _BYTE_ORDER #define __LITTLE_ENDIAN _LITTLE_ENDIAN -#define __BIG_ENDIAN _BIG_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN #endif #endif @@ -106,25 +106,25 @@ #pragma warning(disable : 4101) #undef __UNIX_LIKE__ #undef __BSD__ -#include #include +#include #endif #ifdef __NetBSD__ #ifndef RTF_MULTICAST -#define RTF_MULTICAST 0x20000000 +#define RTF_MULTICAST 0x20000000 #endif #endif #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64)) #define ZT_ARCH_X64 1 -#include #include #include +#include #endif #if (defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON)) -#if (defined(__APPLE__) && !defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__)) +#if (defined(__APPLE__) && ! defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__)) #ifdef ZT_ARCH_ARM_HAS_NEON #undef ZT_ARCH_ARM_HAS_NEON #endif @@ -145,7 +145,8 @@ #endif // Define ZT_NO_TYPE_PUNNING to disable reckless casts on anything other than x86/x64. -#if (!(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386))) +#if (! (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) \ + || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386))) #ifndef ZT_NO_TYPE_PUNNING #define ZT_NO_TYPE_PUNNING 1 #endif @@ -157,23 +158,23 @@ #endif // Assume little endian if not defined -#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER)) +#if (defined(__APPLE__) || defined(__WINDOWS__)) && (! defined(__BYTE_ORDER)) #undef __BYTE_ORDER #undef __LITTLE_ENDIAN #undef __BIG_ENDIAN -#define __BIG_ENDIAN 4321 +#define __BIG_ENDIAN 4321 #define __LITTLE_ENDIAN 1234 -#define __BYTE_ORDER 1234 +#define __BYTE_ORDER 1234 #endif #ifdef __WINDOWS__ -#define ZT_PATH_SEPARATOR '\\' +#define ZT_PATH_SEPARATOR '\\' #define ZT_PATH_SEPARATOR_S "\\" -#define ZT_EOL_S "\r\n" +#define ZT_EOL_S "\r\n" #else -#define ZT_PATH_SEPARATOR '/' +#define ZT_PATH_SEPARATOR '/' #define ZT_PATH_SEPARATOR_S "/" -#define ZT_EOL_S "\n" +#define ZT_EOL_S "\n" #endif #ifndef __BYTE_ORDER @@ -182,10 +183,10 @@ #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) #ifndef likely -#define likely(x) __builtin_expect((x),1) +#define likely(x) __builtin_expect((x), 1) #endif #ifndef unlikely -#define unlikely(x) __builtin_expect((x),0) +#define unlikely(x) __builtin_expect((x), 0) #endif #else #ifndef likely @@ -197,43 +198,43 @@ #endif #ifdef __WINDOWS__ -#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop)) +#define ZT_PACKED_STRUCT(D) __pragma(pack(push, 1)) D __pragma(pack(pop)) #else #define ZT_PACKED_STRUCT(D) D __attribute__((packed)) #endif #if defined(_WIN32) -#define ZT_PLATFORM_NAME "windows" // Windows +#define ZT_PLATFORM_NAME "windows" // Windows #elif defined(_WIN64) -#define ZT_PLATFORM_NAME "windows" // Windows +#define ZT_PLATFORM_NAME "windows" // Windows #elif defined(__CYGWIN__) -#define ZT_PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window) +#define ZT_PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window) #elif defined(__ANDROID__) -#define ZT_PLATFORM_NAME "android" // Android (implies Linux, so it must come first) +#define ZT_PLATFORM_NAME "android" // Android (implies Linux, so it must come first) #elif defined(__linux__) -#define ZT_PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other -#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__) +#define ZT_PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other +#elif defined(__unix__) || ! defined(__APPLE__) && defined(__MACH__) #include #if defined(BSD) -#define ZT_PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD +#define ZT_PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD #endif #elif defined(__hpux) -#define ZT_PLATFORM_NAME "hp-ux" // HP-UX +#define ZT_PLATFORM_NAME "hp-ux" // HP-UX #elif defined(_AIX) -#define ZT_PLATFORM_NAME "aix" // IBM AIX -#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) +#define ZT_PLATFORM_NAME "aix" // IBM AIX +#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) #include #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR == 1 -#define ZT_PLATFORM_NAME "ios_sim" // Apple iOS +#define ZT_PLATFORM_NAME "ios_sim" // Apple iOS #elif defined(TARGET_OS_IPAD) && TARGET_OS_IPAD == 1 #define ZT_PLATFORM_NAME "ios_ipad" #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1 -#define ZT_PLATFORM_NAME "ios_iphone" // Apple iOS +#define ZT_PLATFORM_NAME "ios_iphone" // Apple iOS #elif defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1 -#define ZT_PLATFORM_NAME "macos" // Apple OSX +#define ZT_PLATFORM_NAME "macos" // Apple OSX #endif #elif defined(__sun) && defined(__SVR4) -#define ZT_PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana +#define ZT_PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana #else #define ZT_PLATFORM_NAME "unknown" #endif @@ -255,7 +256,7 @@ #define ZT_ARCH_NAME "mips" #elif defined(__riscv) || defined(__riscv_xlen) #define ZT_ARCH_NAME "riscv" -#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) || defined (_M_PPC) +#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) #define ZT_ARCH_NAME "powerpc" #elif defined(__s390__) || defined(__s390x__) || defined(__zarch__) #define ZT_ARCH_NAME "s390" @@ -580,23 +581,23 @@ /** * Drainage constants for VERB_ECHO rate-limiters */ -#define ZT_ECHO_CUTOFF_LIMIT ((1000 / ZT_CORE_TIMER_TASK_GRANULARITY) * ZT_MAX_PEER_NETWORK_PATHS) +#define ZT_ECHO_CUTOFF_LIMIT ((1000 / ZT_CORE_TIMER_TASK_GRANULARITY) * ZT_MAX_PEER_NETWORK_PATHS) #define ZT_ECHO_DRAINAGE_DIVISOR (1000 / ZT_ECHO_CUTOFF_LIMIT) /** * Drainage constants for VERB_QOS rate-limiters */ -#define ZT_QOS_CUTOFF_LIMIT ((1000 / ZT_CORE_TIMER_TASK_GRANULARITY) * ZT_MAX_PEER_NETWORK_PATHS) +#define ZT_QOS_CUTOFF_LIMIT ((1000 / ZT_CORE_TIMER_TASK_GRANULARITY) * ZT_MAX_PEER_NETWORK_PATHS) #define ZT_QOS_DRAINAGE_DIVISOR (1000 / ZT_QOS_CUTOFF_LIMIT) /** * Drainage constants for VERB_ACK rate-limiters */ -#define ZT_ACK_CUTOFF_LIMIT 128 +#define ZT_ACK_CUTOFF_LIMIT 128 #define ZT_ACK_DRAINAGE_DIVISOR (1000 / ZT_ACK_CUTOFF_LIMIT) #define ZT_BOND_DEFAULT_REFRACTORY_PERIOD 8000 -#define ZT_BOND_MAX_REFRACTORY_PERIOD 600000 +#define ZT_BOND_MAX_REFRACTORY_PERIOD 600000 /** * Maximum number of direct path pushes within cutoff time @@ -632,7 +633,6 @@ */ #define ZT_PEER_GENERAL_RATE_LIMIT 1000 - /** * Minimum allowed amount of time between flow/path optimizations (anti-flapping) */ @@ -709,8 +709,8 @@ * Artificially inflates the failover score for paths which meet * certain non-performance-related policy ranking criteria. */ -#define ZT_BOND_FAILOVER_HANDICAP_PREFERRED 500 -#define ZT_BOND_FAILOVER_HANDICAP_PRIMARY 1000 +#define ZT_BOND_FAILOVER_HANDICAP_PREFERRED 500 +#define ZT_BOND_FAILOVER_HANDICAP_PRIMARY 1000 #define ZT_BOND_FAILOVER_HANDICAP_NEGOTIATED 5000 /** @@ -754,14 +754,14 @@ #define ZT_THREAD_MIN_STACK_SIZE 1048576 // Exceptions thrown in core ZT code -#define ZT_EXCEPTION_OUT_OF_BOUNDS 100 -#define ZT_EXCEPTION_OUT_OF_MEMORY 101 -#define ZT_EXCEPTION_PRIVATE_KEY_REQUIRED 102 -#define ZT_EXCEPTION_INVALID_ARGUMENT 103 -#define ZT_EXCEPTION_INVALID_IDENTITY 104 -#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE 200 -#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW 201 +#define ZT_EXCEPTION_OUT_OF_BOUNDS 100 +#define ZT_EXCEPTION_OUT_OF_MEMORY 101 +#define ZT_EXCEPTION_PRIVATE_KEY_REQUIRED 102 +#define ZT_EXCEPTION_INVALID_ARGUMENT 103 +#define ZT_EXCEPTION_INVALID_IDENTITY 104 +#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE 200 +#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW 201 #define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN 202 -#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING 203 +#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING 203 #endif diff --git a/node/Credential.hpp b/node/Credential.hpp index 7fb98ba79..d1300a78b 100644 --- a/node/Credential.hpp +++ b/node/Credential.hpp @@ -14,39 +14,36 @@ #ifndef ZT_CREDENTIAL_HPP #define ZT_CREDENTIAL_HPP -#include +#include "Constants.hpp" + #include #include - +#include #include #include -#include #include - -#include "Constants.hpp" +#include namespace ZeroTier { /** * Base class for credentials */ -class Credential -{ -public: +class Credential { + public: /** * Do not change type code IDs -- these are used in Revocation objects and elsewhere */ - enum Type - { + enum Type { CREDENTIAL_TYPE_NULL = 0, - CREDENTIAL_TYPE_COM = 1, // CertificateOfMembership + CREDENTIAL_TYPE_COM = 1, // CertificateOfMembership CREDENTIAL_TYPE_CAPABILITY = 2, CREDENTIAL_TYPE_TAG = 3, - CREDENTIAL_TYPE_COO = 4, // CertificateOfOwnership + CREDENTIAL_TYPE_COO = 4, // CertificateOfOwnership CREDENTIAL_TYPE_REVOCATION = 6 }; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/DNS.hpp b/node/DNS.hpp index 3c28c69fb..79e422e8f 100644 --- a/node/DNS.hpp +++ b/node/DNS.hpp @@ -13,45 +13,43 @@ #ifndef ZT_DNS_HPP #define ZT_DNS_HPP +#include "../include/ZeroTierOne.h" +#include "Buffer.hpp" +#include "InetAddress.hpp" + #include #include #include -#include "Buffer.hpp" -#include "InetAddress.hpp" -#include "../include/ZeroTierOne.h" - namespace ZeroTier { /** * DNS data serialization methods */ class DNS { -public: - template - static inline void serializeDNS(Buffer &b, const ZT_VirtualNetworkDNS *dns) - { - 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); - } - } + public: + template static inline void serializeDNS(Buffer& b, const ZT_VirtualNetworkDNS* dns) + { + 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) - { - char *d = (char*)b.data()+p; - memset(dns, 0, sizeof(ZT_VirtualNetworkDNS)); - memcpy(dns->domain, d, 128); - dns->domain[127] = 0; - p += 128; - for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { - p += reinterpret_cast(&(dns->server_addr[j]))->deserialize(b, p); - } - } + template static inline void deserializeDNS(const Buffer& b, unsigned int& p, ZT_VirtualNetworkDNS* dns) + { + char* d = (char*)b.data() + p; + memset(dns, 0, sizeof(ZT_VirtualNetworkDNS)); + memcpy(dns->domain, d, 128); + dns->domain[127] = 0; + p += 128; + for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) { + p += reinterpret_cast(&(dns->server_addr[j]))->deserialize(b, p); + } + } }; -} +} // namespace ZeroTier -#endif // ZT_DNS_HPP +#endif // ZT_DNS_HPP diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp index 746c2b852..1c6b52620 100644 --- a/node/Dictionary.hpp +++ b/node/Dictionary.hpp @@ -14,10 +14,10 @@ #ifndef ZT_DICTIONARY_HPP #define ZT_DICTIONARY_HPP +#include "Address.hpp" +#include "Buffer.hpp" #include "Constants.hpp" #include "Utils.hpp" -#include "Buffer.hpp" -#include "Address.hpp" #include @@ -45,36 +45,48 @@ namespace ZeroTier { * * @tparam C Dictionary max capacity in bytes */ -template -class Dictionary -{ -public: - Dictionary() { memset(_d,0,sizeof(_d)); } - Dictionary(const char *s) { this->load(s); } - Dictionary(const char *s,unsigned int len) +template class Dictionary { + public: + Dictionary() { - for(unsigned int i=0;iload(s); + } + Dictionary(const char* s, unsigned int len) + { + for (unsigned int i = 0; i < C; ++i) { + if ((s) && (i < len)) { + if (! (_d[i] = *s)) { + s = (const char*)0; + } + else { ++s; } - } else { + } + else { _d[i] = (char)0; } } _d[C - 1] = (char)0; } - Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); } - - inline Dictionary &operator=(const Dictionary &d) + Dictionary(const Dictionary& d) { - memcpy(_d,d._d,C); + memcpy(_d, d._d, C); + } + + inline Dictionary& operator=(const Dictionary& d) + { + memcpy(_d, d._d, C); return *this; } - inline operator bool() const { return (_d[0] != 0); } + inline operator bool() const + { + return (_d[0] != 0); + } /** * Load a dictionary from a C-string @@ -82,21 +94,23 @@ public: * @param s Dictionary in string form * @return False if 's' was longer than our capacity */ - inline bool load(const char *s) + inline bool load(const char* s) { - for(unsigned int i=0;i - inline bool get(const char *key,Buffer &dest) const + template inline bool get(const char* key, Buffer& dest) const { - const int r = this->get(key,const_cast(reinterpret_cast(dest.data())),BC); + const int r = this->get(key, const_cast(reinterpret_cast(dest.data())), BC); if (r >= 0) { dest.setSize((unsigned int)r); return true; - } else { + } + else { dest.clear(); return false; } @@ -261,11 +279,11 @@ public: * @param dfl Default value if not found in dictionary * @return Boolean value of key or 'dfl' if not found */ - bool getB(const char *key,bool dfl = false) const + bool getB(const char* key, bool dfl = false) const { char tmp[4]; - if (this->get(key,tmp,sizeof(tmp)) >= 0) { - return ((*tmp == '1')||(*tmp == 't')||(*tmp == 'T')); + if (this->get(key, tmp, sizeof(tmp)) >= 0) { + return ((*tmp == '1') || (*tmp == 't') || (*tmp == 'T')); } return dfl; } @@ -277,10 +295,10 @@ public: * @param dfl Default value or 0 if unspecified * @return Decoded hex UInt value or 'dfl' if not found */ - inline uint64_t getUI(const char *key,uint64_t dfl = 0) const + inline uint64_t getUI(const char* key, uint64_t dfl = 0) const { char tmp[128]; - if (this->get(key,tmp,sizeof(tmp)) >= 1) { + if (this->get(key, tmp, sizeof(tmp)) >= 1) { return Utils::hexStrToU64(tmp); } return dfl; @@ -293,10 +311,10 @@ public: * @param dfl Default value or 0 if unspecified * @return Decoded hex UInt value or 'dfl' if not found */ - inline int64_t getI(const char *key,int64_t dfl = 0) const + inline int64_t getI(const char* key, int64_t dfl = 0) const { char tmp[128]; - if (this->get(key,tmp,sizeof(tmp)) >= 1) { + if (this->get(key, tmp, sizeof(tmp)) >= 1) { return Utils::hexStrTo64(tmp); } return dfl; @@ -316,10 +334,10 @@ public: * @param vlen Length of value in bytes or -1 to treat value[] as a C-string and look for terminating 0 * @return True if there was enough room to add this key=value pair */ - inline bool add(const char *key,const char *value,int vlen = -1) + inline bool add(const char* key, const char* value, int vlen = -1) { - for(unsigned int i=0;i 0) { @@ -330,7 +348,7 @@ public: } } - const char *p = key; + const char* p = key; while (*p) { _d[j++] = *(p++); if (j == C) { @@ -347,8 +365,8 @@ public: p = value; int k = 0; - while ( ((vlen < 0)&&(*p)) || (k < vlen) ) { - switch(*p) { + while (((vlen < 0) && (*p)) || (k < vlen)) { + switch (*p) { case 0: case 13: case 10: @@ -359,7 +377,7 @@ public: _d[i] = (char)0; return false; } - switch(*p) { + switch (*p) { case 0: _d[j++] = '0'; break; @@ -404,41 +422,42 @@ public: /** * Add a boolean as a '1' or a '0' */ - inline bool add(const char *key,bool value) + inline bool add(const char* key, bool value) { - return this->add(key,(value) ? "1" : "0",1); + return this->add(key, (value) ? "1" : "0", 1); } /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,uint64_t value) + inline bool add(const char* key, uint64_t value) { char tmp[32]; - return this->add(key,Utils::hex(value,tmp),-1); + return this->add(key, Utils::hex(value, tmp), -1); } /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,int64_t value) + inline bool add(const char* key, int64_t value) { char tmp[32]; if (value >= 0) { - return this->add(key,Utils::hex((uint64_t)value,tmp),-1); - } else { + return this->add(key, Utils::hex((uint64_t)value, tmp), -1); + } + else { tmp[0] = '-'; - return this->add(key,Utils::hex((uint64_t)(value * -1),tmp+1),-1); + return this->add(key, Utils::hex((uint64_t)(value * -1), tmp + 1), -1); } } /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,const Address &a) + inline bool add(const char* key, const Address& a) { char tmp[32]; - return this->add(key,Utils::hex(a.toInt(),tmp),-1); + return this->add(key, Utils::hex(a.toInt(), tmp), -1); } /** @@ -446,34 +465,42 @@ public: * * @tparam BC Buffer capacity (usually inferred) */ - template - inline bool add(const char *key,const Buffer &value) + template inline bool add(const char* key, const Buffer& value) { - return this->add(key,(const char *)value.data(),(int)value.size()); + return this->add(key, (const char*)value.data(), (int)value.size()); } /** * @param key Key to check * @return True if key is present */ - inline bool contains(const char *key) const + inline bool contains(const char* key) const { char tmp[2]; - return (this->get(key,tmp,2) >= 0); + return (this->get(key, tmp, 2) >= 0); } /** * @return Value of C template parameter */ - inline unsigned int capacity() const { return C; } + inline unsigned int capacity() const + { + return C; + } - inline const char *data() const { return _d; } - inline char *unsafeData() { return _d; } + inline const char* data() const + { + return _d; + } + inline char* unsafeData() + { + return _d; + } -private: + private: char _d[C]; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 0656246be..5073f6029 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -16,36 +16,43 @@ #include "Constants.hpp" +#include +#include #include #include #include - -#include -#include #include -#include +#include namespace ZeroTier { /** * A minimal hash table implementation for the ZeroTier core */ -template -class Hashtable -{ -private: - struct _Bucket - { - _Bucket(const K &k,const V &v) : k(k),v(v) {} - _Bucket(const K &k) : k(k),v() {} - _Bucket(const _Bucket &b) : k(b.k),v(b.v) {} - inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; } +template class Hashtable { + private: + struct _Bucket { + _Bucket(const K& k, const V& v) : k(k), v(v) + { + } + _Bucket(const K& k) : k(k), v() + { + } + _Bucket(const _Bucket& b) : k(b.k), v(b.v) + { + } + inline _Bucket& operator=(const _Bucket& b) + { + k = b.k; + v = b.v; + return *this; + } K k; V v; - _Bucket *next; // must be set manually for each _Bucket + _Bucket* next; // must be set manually for each _Bucket }; -public: + public: /** * A simple forward iterator (different from STL) * @@ -53,16 +60,12 @@ public: * may rehash and invalidate the iterator. Note the erasing the key will destroy * the targets of the pointers returned by next(). */ - class Iterator - { - public: + class Iterator { + public: /** * @param ht Hash table to iterate over */ - Iterator(Hashtable &ht) : - _idx(0), - _ht(&ht), - _b(ht._t[0]) + Iterator(Hashtable& ht) : _idx(0), _ht(&ht), _b(ht._t[0]) { } @@ -71,9 +74,9 @@ public: * @param vptr Pointer to set to point to next value * @return True if kptr and vptr are set, false if no more entries */ - inline bool next(K *&kptr,V *&vptr) + inline bool next(K*& kptr, V*& vptr) { - for(;;) { + for (;;) { if (_b) { kptr = &(_b->k); vptr = &(_b->v); @@ -88,44 +91,38 @@ public: } } - private: + private: unsigned long _idx; - Hashtable *_ht; - _Bucket *_b; + Hashtable* _ht; + _Bucket* _b; }; - //friend class Hashtable::Iterator; + // friend class Hashtable::Iterator; /** * @param bc Initial capacity in buckets (default: 64, must be nonzero) */ - Hashtable(unsigned long bc = 64) : - _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))), - _bc(bc), - _s(0) + Hashtable(unsigned long bc = 64) : _t(reinterpret_cast<_Bucket**>(::malloc(sizeof(_Bucket*) * bc))), _bc(bc), _s(0) { - if (!_t) { + if (! _t) { throw ZT_EXCEPTION_OUT_OF_MEMORY; } - for(unsigned long i=0;i &ht) : - _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * ht._bc))), - _bc(ht._bc), - _s(ht._s) + Hashtable(const Hashtable& ht) : _t(reinterpret_cast<_Bucket**>(::malloc(sizeof(_Bucket*) * ht._bc))), _bc(ht._bc), _s(ht._s) { - if (!_t) { + if (! _t) { throw ZT_EXCEPTION_OUT_OF_MEMORY; } - for(unsigned long i=0;i<_bc;++i) { - _t[i] = (_Bucket *)0; + for (unsigned long i = 0; i < _bc; ++i) { + _t[i] = (_Bucket*)0; } - for(unsigned long i=0;i<_bc;++i) { - const _Bucket *b = ht._t[i]; + for (unsigned long i = 0; i < _bc; ++i) { + const _Bucket* b = ht._t[i]; while (b) { - _Bucket *nb = new _Bucket(*b); + _Bucket* nb = new _Bucket(*b); nb->next = _t[i]; _t[i] = nb; b = b->next; @@ -139,14 +136,14 @@ public: ::free(_t); } - inline Hashtable &operator=(const Hashtable &ht) + inline Hashtable& operator=(const Hashtable& ht) { this->clear(); if (ht._s) { - for(unsigned long i=0;iset(b->k,b->v); + this->set(b->k, b->v); b = b->next; } } @@ -160,14 +157,14 @@ public: inline void clear() { if (_s) { - for(unsigned long i=0;i<_bc;++i) { - _Bucket *b = _t[i]; + for (unsigned long i = 0; i < _bc; ++i) { + _Bucket* b = _t[i]; while (b) { - _Bucket *const nb = b->next; + _Bucket* const nb = b->next; delete b; b = nb; } - _t[i] = (_Bucket *)0; + _t[i] = (_Bucket*)0; } _s = 0; } @@ -181,8 +178,8 @@ public: typename std::vector k; if (_s) { k.reserve(_s); - for(unsigned long i=0;i<_bc;++i) { - _Bucket *b = _t[i]; + for (unsigned long i = 0; i < _bc; ++i) { + _Bucket* b = _t[i]; while (b) { k.push_back(b->k); b = b->next; @@ -198,12 +195,11 @@ public: * @param v Vector, list, or other compliant container * @tparam Type of V (generally inferred) */ - template - inline void appendKeys(C &v) const + template inline void appendKeys(C& v) const { if (_s) { - for(unsigned long i=0;i<_bc;++i) { - _Bucket *b = _t[i]; + for (unsigned long i = 0; i < _bc; ++i) { + _Bucket* b = _t[i]; while (b) { v.push_back(b->k); b = b->next; @@ -215,15 +211,15 @@ public: /** * @return Vector of all entries (pairs of K,V) */ - inline typename std::vector< std::pair > entries() const + inline typename std::vector > entries() const { - typename std::vector< std::pair > k; + typename std::vector > k; if (_s) { k.reserve(_s); - for(unsigned long i=0;i<_bc;++i) { - _Bucket *b = _t[i]; + for (unsigned long i = 0; i < _bc; ++i) { + _Bucket* b = _t[i]; while (b) { - k.push_back(std::pair(b->k,b->v)); + k.push_back(std::pair(b->k, b->v)); b = b->next; } } @@ -235,27 +231,30 @@ public: * @param k Key * @return Pointer to value or NULL if not found */ - inline V *get(const K &k) + inline V* get(const K& k) { - _Bucket *b = _t[_hc(k) % _bc]; + _Bucket* b = _t[_hc(k) % _bc]; while (b) { if (b->k == k) { return &(b->v); } b = b->next; } - return (V *)0; + return (V*)0; + } + inline const V* get(const K& k) const + { + return const_cast(this)->get(k); } - inline const V *get(const K &k) const { return const_cast(this)->get(k); } /** * @param k Key * @param v Value to fill with result * @return True if value was found and set (if false, v is not modified) */ - inline bool get(const K &k,V &v) const + inline bool get(const K& k, V& v) const { - _Bucket *b = _t[_hc(k) % _bc]; + _Bucket* b = _t[_hc(k) % _bc]; while (b) { if (b->k == k) { v = b->v; @@ -270,9 +269,9 @@ public: * @param k Key to check * @return True if key is present */ - inline bool contains(const K &k) const + inline bool contains(const K& k) const { - _Bucket *b = _t[_hc(k) % _bc]; + _Bucket* b = _t[_hc(k) % _bc]; while (b) { if (b->k == k) { return true; @@ -286,16 +285,17 @@ public: * @param k Key * @return True if value was present */ - inline bool erase(const K &k) + inline bool erase(const K& k) { const unsigned long bidx = _hc(k) % _bc; - _Bucket *lastb = (_Bucket *)0; - _Bucket *b = _t[bidx]; + _Bucket* lastb = (_Bucket*)0; + _Bucket* b = _t[bidx]; while (b) { if (b->k == k) { if (lastb) { lastb->next = b->next; - } else { + } + else { _t[bidx] = b->next; } delete b; @@ -313,12 +313,12 @@ public: * @param v Value * @return Reference to value in table */ - inline V &set(const K &k,const V &v) + inline V& set(const K& k, const V& v) { const unsigned long h = _hc(k); unsigned long bidx = h % _bc; - _Bucket *b = _t[bidx]; + _Bucket* b = _t[bidx]; while (b) { if (b->k == k) { b->v = v; @@ -332,7 +332,7 @@ public: bidx = h % _bc; } - b = new _Bucket(k,v); + b = new _Bucket(k, v); b->next = _t[bidx]; _t[bidx] = b; ++_s; @@ -343,12 +343,12 @@ public: * @param k Key * @return Value, possibly newly created */ - inline V &operator[](const K &k) + inline V& operator[](const K& k) { const unsigned long h = _hc(k); unsigned long bidx = h % _bc; - _Bucket *b = _t[bidx]; + _Bucket* b = _t[bidx]; while (b) { if (b->k == k) { return b->v; @@ -371,22 +371,27 @@ public: /** * @return Number of entries */ - inline unsigned long size() const { return _s; } + inline unsigned long size() const + { + return _s; + } /** * @return True if table is empty */ - inline bool empty() const { return (_s == 0); } + inline bool empty() const + { + return (_s == 0); + } -private: - template - static inline unsigned long _hc(const O &obj) + private: + template static inline unsigned long _hc(const O& obj) { return (unsigned long)obj.hashCode(); } static inline unsigned long _hc(const uint64_t i) { - return (unsigned long)(i ^ (i >> 32)); // good for network IDs and addresses + return (unsigned long)(i ^ (i >> 32)); // good for network IDs and addresses } static inline unsigned long _hc(const uint32_t i) { @@ -404,15 +409,15 @@ private: inline void _grow() { const unsigned long nc = _bc * 2; - _Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc)); + _Bucket** nt = reinterpret_cast<_Bucket**>(::malloc(sizeof(_Bucket*) * nc)); if (nt) { - for(unsigned long i=0;inext; + _Bucket* const nb = b->next; const unsigned long nidx = _hc(b->k) % nc; b->next = nt[nidx]; nt[nidx] = b; @@ -425,11 +430,11 @@ private: } } - _Bucket **_t; + _Bucket** _t; unsigned long _bc; unsigned long _s; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Identity.cpp b/node/Identity.cpp index f47de79c1..8105d2a58 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -11,94 +11,98 @@ */ /****/ -#include -#include -#include -#include +#include "Identity.hpp" #include "Constants.hpp" -#include "Identity.hpp" #include "SHA512.hpp" #include "Salsa20.hpp" #include "Utils.hpp" +#include +#include +#include +#include + // These can't be changed without a new identity type. They define the // parameters of the hashcash hashing/searching algorithm. #define ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN 17 -#define ZT_IDENTITY_GEN_MEMORY 2097152 +#define ZT_IDENTITY_GEN_MEMORY 2097152 namespace ZeroTier { // A memory-hard composition of SHA-512 and Salsa20 for hashcash hashing -static inline void _computeMemoryHardHash(const void *publicKey,unsigned int publicKeyBytes,void *digest,void *genmem) +static inline void _computeMemoryHardHash(const void* publicKey, unsigned int publicKeyBytes, void* digest, void* genmem) { // Digest publicKey[] to obtain initial digest - SHA512(digest,publicKey,publicKeyBytes); + SHA512(digest, publicKey, publicKeyBytes); // Initialize genmem[] using Salsa20 in a CBC-like configuration since // ordinary Salsa20 is randomly seek-able. This is good for a cipher // but is not what we want for sequential memory-hardness. - memset(genmem,0,ZT_IDENTITY_GEN_MEMORY); - Salsa20 s20(digest,(char *)digest + 32); - s20.crypt20((char *)genmem,(char *)genmem,64); - for(unsigned long i=64;idata,ZT_C25519_PRIVATE_KEY_LEN,p); + Utils::hex(_privateKey->data, ZT_C25519_PRIVATE_KEY_LEN, p); p += ZT_C25519_PRIVATE_KEY_LEN * 2; } *p = (char)0; return buf; } -bool Identity::fromString(const char *str) +bool Identity::fromString(const char* str) { - if (!str) { + if (! str) { _address.zero(); return false; } char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH]; - if (!Utils::scopy(tmp,sizeof(tmp),str)) { + if (! Utils::scopy(tmp, sizeof(tmp), str)) { _address.zero(); return false; } delete _privateKey; - _privateKey = (C25519::Private *)0; + _privateKey = (C25519::Private*)0; int fno = 0; - char *saveptr = (char *)0; - for(char *f=Utils::stok(tmp,":",&saveptr);(f);f=Utils::stok((char *)0,":",&saveptr)) { - switch(fno++) { + char* saveptr = (char*)0; + for (char* f = Utils::stok(tmp, ":", &saveptr); (f); f = Utils::stok((char*)0, ":", &saveptr)) { + switch (fno++) { case 0: _address = Address(Utils::hexStrToU64(f)); if (_address.isReserved()) { @@ -170,20 +168,20 @@ bool Identity::fromString(const char *str) } break; case 1: - if ((f[0] != '0')||(f[1])) { + if ((f[0] != '0') || (f[1])) { _address.zero(); return false; } break; case 2: - if (Utils::unhex(f,_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) { + if (Utils::unhex(f, _publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) { _address.zero(); return false; } break; case 3: _privateKey = new C25519::Private(); - if (Utils::unhex(f,_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) { + if (Utils::unhex(f, _privateKey->data, ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) { _address.zero(); return false; } @@ -201,4 +199,4 @@ bool Identity::fromString(const char *str) return true; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Identity.hpp b/node/Identity.hpp index b7580a802..9a7f0cc5b 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -14,16 +14,16 @@ #ifndef ZT_IDENTITY_HPP #define ZT_IDENTITY_HPP +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" +#include "Constants.hpp" +#include "SHA512.hpp" +#include "Utils.hpp" + #include #include -#include "Constants.hpp" -#include "Utils.hpp" -#include "Address.hpp" -#include "C25519.hpp" -#include "Buffer.hpp" -#include "SHA512.hpp" - #define ZT_IDENTITY_STRING_BUFFER_LENGTH 384 namespace ZeroTier { @@ -38,56 +38,49 @@ namespace ZeroTier { * search for a different public key that duplicates an existing address. (See * code for deriveAddress() for this algorithm.) */ -class Identity -{ -public: - Identity() : - _privateKey((C25519::Private *)0) +class Identity { + public: + Identity() : _privateKey((C25519::Private*)0) { } - Identity(const Identity &id) : - _address(id._address), - _publicKey(id._publicKey), - _privateKey((id._privateKey) ? new C25519::Private(*(id._privateKey)) : (C25519::Private *)0) + Identity(const Identity& id) : _address(id._address), _publicKey(id._publicKey), _privateKey((id._privateKey) ? new C25519::Private(*(id._privateKey)) : (C25519::Private*)0) { } - Identity(const char *str) : - _privateKey((C25519::Private *)0) + Identity(const char* str) : _privateKey((C25519::Private*)0) { - if (!fromString(str)) { + if (! fromString(str)) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; } } - template - Identity(const Buffer &b,unsigned int startAt = 0) : - _privateKey((C25519::Private *)0) + template Identity(const Buffer& b, unsigned int startAt = 0) : _privateKey((C25519::Private*)0) { - deserialize(b,startAt); + deserialize(b, startAt); } ~Identity() { if (_privateKey) { - Utils::burn(_privateKey,sizeof(C25519::Private)); + Utils::burn(_privateKey, sizeof(C25519::Private)); delete _privateKey; } } - inline Identity &operator=(const Identity &id) + inline Identity& operator=(const Identity& id) { _address = id._address; _publicKey = id._publicKey; if (id._privateKey) { - if (!_privateKey) { + if (! _privateKey) { _privateKey = new C25519::Private(); } *_privateKey = *(id._privateKey); - } else { + } + else { delete _privateKey; - _privateKey = (C25519::Private *)0; + _privateKey = (C25519::Private*)0; } return *this; } @@ -109,14 +102,17 @@ public: /** * @return True if this identity contains a private key */ - inline bool hasPrivate() const { return (_privateKey != (C25519::Private *)0); } + inline bool hasPrivate() const + { + return (_privateKey != (C25519::Private*)0); + } /** * Compute a SHA384 hash of this identity's address and public key(s). - * + * * @param sha384buf Buffer with 48 bytes of space to receive hash */ - inline void publicKeyHash(void *sha384buf) const + inline void publicKeyHash(void* sha384buf) const { uint8_t address[ZT_ADDRESS_LENGTH]; _address.copyTo(address, ZT_ADDRESS_LENGTH); @@ -129,10 +125,10 @@ public: * @param sha Buffer to receive SHA512 (MUST be ZT_SHA512_DIGEST_LEN (64) bytes in length) * @return True on success, false if no private key */ - inline bool sha512PrivateKey(void *sha) const + inline bool sha512PrivateKey(void* sha) const { if (_privateKey) { - SHA512(sha,_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN); + SHA512(sha, _privateKey->data, ZT_C25519_PRIVATE_KEY_LEN); return true; } return false; @@ -144,10 +140,10 @@ public: * @param data Data to sign * @param len Length of data */ - inline C25519::Signature sign(const void *data,unsigned int len) const + inline C25519::Signature sign(const void* data, unsigned int len) const { if (_privateKey) { - return C25519::sign(*_privateKey,_publicKey,data,len); + return C25519::sign(*_privateKey, _publicKey, data, len); } throw ZT_EXCEPTION_PRIVATE_KEY_REQUIRED; } @@ -161,12 +157,12 @@ public: * @param siglen Length of signature in bytes * @return True if signature validates and data integrity checks */ - inline bool verify(const void *data,unsigned int len,const void *signature,unsigned int siglen) const + inline bool verify(const void* data, unsigned int len, const void* signature, unsigned int siglen) const { if (siglen != ZT_C25519_SIGNATURE_LEN) { return false; } - return C25519::verify(_publicKey,data,len,signature); + return C25519::verify(_publicKey, data, len, signature); } /** @@ -177,9 +173,9 @@ public: * @param signature Signature * @return True if signature validates and data integrity checks */ - inline bool verify(const void *data,unsigned int len,const C25519::Signature &signature) const + inline bool verify(const void* data, unsigned int len, const C25519::Signature& signature) const { - return C25519::verify(_publicKey,data,len,signature); + return C25519::verify(_publicKey, data, len, signature); } /** @@ -191,10 +187,10 @@ public: * @param key Result parameter to fill with key bytes * @return Was agreement successful? */ - inline bool agree(const Identity &id,void *const key) const + inline bool agree(const Identity& id, void* const key) const { if (_privateKey) { - C25519::agree(*_privateKey,id._publicKey,key,ZT_SYMMETRIC_KEY_SIZE); + C25519::agree(*_privateKey, id._publicKey, key, ZT_SYMMETRIC_KEY_SIZE); return true; } return false; @@ -203,7 +199,10 @@ public: /** * @return This identity's address */ - inline const Address &address() const { return _address; } + inline const Address& address() const + { + return _address; + } /** * Serialize this identity (binary) @@ -212,16 +211,16 @@ public: * @param includePrivate If true, include private key component (if present) (default: false) * @throws std::out_of_range Buffer too small */ - template - inline void serialize(Buffer &b,bool includePrivate = false) const + template inline void serialize(Buffer& b, bool includePrivate = false) const { _address.appendTo(b); - b.append((uint8_t)0); // C25519/Ed25519 identity type - b.append(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN); - if ((_privateKey)&&(includePrivate)) { + b.append((uint8_t)0); // C25519/Ed25519 identity type + b.append(_publicKey.data, ZT_C25519_PUBLIC_KEY_LEN); + if ((_privateKey) && (includePrivate)) { b.append((unsigned char)ZT_C25519_PRIVATE_KEY_LEN); - b.append(_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN); - } else { + b.append(_privateKey->data, ZT_C25519_PRIVATE_KEY_LEN); + } + else { b.append((unsigned char)0); } } @@ -238,22 +237,21 @@ public: * @throws std::out_of_range Serialized data invalid * @throws std::invalid_argument Serialized data invalid */ - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { delete _privateKey; - _privateKey = (C25519::Private *)0; + _privateKey = (C25519::Private*)0; unsigned int p = startAt; - _address.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _address.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] != 0) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; } - memcpy(_publicKey.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(_publicKey.data, b.field(p, ZT_C25519_PUBLIC_KEY_LEN), ZT_C25519_PUBLIC_KEY_LEN); p += ZT_C25519_PUBLIC_KEY_LEN; unsigned int privateKeyLength = (unsigned int)b[p++]; @@ -262,7 +260,7 @@ public: throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } _privateKey = new C25519::Private(); - memcpy(_privateKey->data,b.field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN); + memcpy(_privateKey->data, b.field(p, ZT_C25519_PRIVATE_KEY_LEN), ZT_C25519_PRIVATE_KEY_LEN); p += ZT_C25519_PRIVATE_KEY_LEN; } @@ -276,7 +274,7 @@ public: * @param buf Buffer to store string * @return ASCII string representation of identity */ - char *toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const; + char* toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const; /** * Deserialize a human-friendly string @@ -287,12 +285,15 @@ public: * @param str String to deserialize * @return True if deserialization appears successful */ - bool fromString(const char *str); + bool fromString(const char* str); /** * @return C25519 public key */ - inline const C25519::Public &publicKey() const { return _publicKey; } + inline const C25519::Public& publicKey() const + { + return _publicKey; + } /** * @return C25519 key pair (only returns valid pair if private key is present in this Identity object) @@ -303,8 +304,9 @@ public: pair.pub = _publicKey; if (_privateKey) { pair.priv = *_privateKey; - } else { - memset(pair.priv.data,0,ZT_C25519_PRIVATE_KEY_LEN); + } + else { + memset(pair.priv.data, 0, ZT_C25519_PRIVATE_KEY_LEN); } return pair; } @@ -312,21 +314,42 @@ public: /** * @return True if this identity contains something */ - inline operator bool() const { return (_address); } + inline operator bool() const + { + return (_address); + } - inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) == 0)); } - inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) < 0))); } - inline bool operator!=(const Identity &id) const { return !(*this == id); } - inline bool operator>(const Identity &id) const { return (id < *this); } - inline bool operator<=(const Identity &id) const { return !(id < *this); } - inline bool operator>=(const Identity &id) const { return !(*this < id); } + inline bool operator==(const Identity& id) const + { + return ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) == 0)); + } + inline bool operator<(const Identity& id) const + { + return ((_address < id._address) || ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) < 0))); + } + inline bool operator!=(const Identity& id) const + { + return ! (*this == id); + } + inline bool operator>(const Identity& id) const + { + return (id < *this); + } + inline bool operator<=(const Identity& id) const + { + return ! (id < *this); + } + inline bool operator>=(const Identity& id) const + { + return ! (*this < id); + } -private: + private: Address _address; C25519::Public _publicKey; - C25519::Private *_privateKey; + C25519::Private* _privateKey; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 2537c0fb6..af1e7930d 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -11,38 +11,38 @@ */ /****/ -#include -#include -#include - -#include "../version.h" -#include "../include/ZeroTierOne.h" - -#include "Constants.hpp" -#include "RuntimeEnvironment.hpp" #include "IncomingPacket.hpp" -#include "Topology.hpp" -#include "Switch.hpp" -#include "Peer.hpp" -#include "NetworkController.hpp" -#include "SelfAwareness.hpp" -#include "Salsa20.hpp" -#include "SHA512.hpp" -#include "World.hpp" -#include "Node.hpp" -#include "CertificateOfMembership.hpp" -#include "Capability.hpp" -#include "Tag.hpp" -#include "Revocation.hpp" -#include "Trace.hpp" -#include "Path.hpp" + +#include "../include/ZeroTierOne.h" +#include "../version.h" #include "Bond.hpp" +#include "Capability.hpp" +#include "CertificateOfMembership.hpp" +#include "Constants.hpp" #include "Metrics.hpp" +#include "NetworkController.hpp" +#include "Node.hpp" #include "PacketMultiplexer.hpp" +#include "Path.hpp" +#include "Peer.hpp" +#include "Revocation.hpp" +#include "RuntimeEnvironment.hpp" +#include "SHA512.hpp" +#include "Salsa20.hpp" +#include "SelfAwareness.hpp" +#include "Switch.hpp" +#include "Tag.hpp" +#include "Topology.hpp" +#include "Trace.hpp" +#include "World.hpp" + +#include +#include +#include namespace ZeroTier { -bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t flowId) +bool IncomingPacket::tryDecode(const RuntimeEnvironment* RR, void* tPtr, int32_t flowId) { const Address sourceAddress(source()); @@ -54,29 +54,31 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f // Obviously if no trusted paths are configured this always returns false and such // packets are dropped on the floor. const uint64_t tpid = trustedPathId(); - if (RR->topology->shouldInboundPathBeTrusted(_path->address(),tpid)) { + if (RR->topology->shouldInboundPathBeTrusted(_path->address(), tpid)) { _authenticated = true; - } else { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"path not trusted"); + } + else { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, packetId(), sourceAddress, hops(), "path not trusted"); return true; } - } else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) { + } + else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE) && (verb() == Packet::VERB_HELLO)) { // Only HELLO is allowed in the clear, but will still have a MAC - return _doHELLO(RR,tPtr,false); + return _doHELLO(RR, tPtr, false); } - const SharedPtr peer(RR->topology->getPeer(tPtr,sourceAddress)); + const SharedPtr peer(RR->topology->getPeer(tPtr, sourceAddress)); if (peer) { - if (!_authenticated) { - if (!dearmor(peer->key(), peer->aesKeys())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"invalid MAC"); + if (! _authenticated) { + if (! dearmor(peer->key(), peer->aesKeys())) { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, packetId(), sourceAddress, hops(), "invalid MAC"); peer->recordIncomingInvalidPacket(_path); return true; } } - if (!uncompress()) { - RR->t->incomingPacketInvalid(tPtr,_path,packetId(),sourceAddress,hops(),Packet::VERB_NOP,"LZ4 decompression failed"); + if (! uncompress()) { + RR->t->incomingPacketInvalid(tPtr, _path, packetId(), sourceAddress, hops(), Packet::VERB_NOP, "LZ4 decompression failed"); return true; } @@ -84,11 +86,11 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f const Packet::Verb v = verb(); bool r = true; - switch(v) { - //case Packet::VERB_NOP: - default: // ignore unknown verbs, but if they pass auth check they are "received" + switch (v) { + // case Packet::VERB_NOP: + default: // ignore unknown verbs, but if they pass auth check they are "received" Metrics::pkt_nop_in++; - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),v,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), v, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); break; case Packet::VERB_HELLO: r = _doHELLO(RR, tPtr, true); @@ -152,21 +154,23 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f break; } if (r) { - RR->node->statsLogVerb((unsigned int)v,(unsigned int)size()); + RR->node->statsLogVerb((unsigned int)v, (unsigned int)size()); return true; } return false; - } else { - RR->sw->requestWhois(tPtr,RR->node->now(),sourceAddress); + } + else { + RR->sw->requestWhois(tPtr, RR->node->now(), sourceAddress); return false; } - } catch ( ... ) { - RR->t->incomingPacketInvalid(tPtr,_path,packetId(),sourceAddress,hops(),verb(),"unexpected exception in tryDecode()"); + } + catch (...) { + RR->t->incomingPacketInvalid(tPtr, _path, packetId(), sourceAddress, hops(), verb(), "unexpected exception in tryDecode()"); return true; } } -bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doERROR(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { const Packet::Verb inReVerb = (Packet::Verb)(*this)[ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB]; const uint64_t inRePacketId = at(ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID); @@ -181,13 +185,12 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar * error handler. In most cases these are only trusted in specific * circumstances. */ - switch(errorCode) { - + switch (errorCode) { case Packet::ERROR_OBJ_NOT_FOUND: // Object not found, currently only meaningful from network controllers. if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == peer->address())) { + if ((network) && (network->controller() == peer->address())) { network->setNotFound(tPtr); } } @@ -200,7 +203,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar // that the queried node does not support acting as a controller. if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == peer->address())) { + if ((network) && (network->controller() == peer->address())) { network->setNotFound(tPtr); } } @@ -210,7 +213,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar case Packet::ERROR_IDENTITY_COLLISION: // FIXME: for federation this will need a payload with a signature or something. if (RR->topology->isUpstream(peer->identity())) { - RR->node->postEvent(tPtr,ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION); + RR->node->postEvent(tPtr, ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION); } Metrics::pkt_error_identity_collision_in++; break; @@ -220,43 +223,43 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar networkId = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD); const SharedPtr network(RR->node->network(networkId)); const int64_t now = RR->node->now(); - if ((network)&&(network->config().com)) { - network->peerRequestedCredentials(tPtr,peer->address(),now); + if ((network) && (network->config().com)) { + network->peerRequestedCredentials(tPtr, peer->address(), now); } Metrics::pkt_error_need_membership_cert_in++; - } break; + } break; case Packet::ERROR_NETWORK_ACCESS_DENIED_: { // Network controller: network access denied. const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == peer->address())) { + if ((network) && (network->controller() == peer->address())) { network->setAccessDenied(tPtr); } Metrics::pkt_error_network_access_denied_in++; - } break; + } break; case Packet::ERROR_UNWANTED_MULTICAST: { // Members of networks can use this error to indicate that they no longer // want to receive multicasts on a given channel. networkId = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD); const SharedPtr network(RR->node->network(networkId)); - if ((network)&&(network->gate(tPtr,peer))) { - const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14)); - RR->mc->remove(network->id(),mg,peer->address()); + if ((network) && (network->gate(tPtr, peer))) { + const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8, 6), 6), at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14)); + RR->mc->remove(network->id(), mg, peer->address()); } Metrics::pkt_error_unwanted_multicast_in++; - } break; + } break; case Packet::ERROR_NETWORK_AUTHENTICATION_REQUIRED: { - //fprintf(stderr, "\nPacket::ERROR_NETWORK_AUTHENTICATION_REQUIRED\n\n"); + // fprintf(stderr, "\nPacket::ERROR_NETWORK_AUTHENTICATION_REQUIRED\n\n"); const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == peer->address())) { + if ((network) && (network->controller() == peer->address())) { int s = (int)size() - (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8); if (s > 2) { const uint16_t errorDataSize = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8); s -= 2; if (s >= (int)errorDataSize) { - Dictionary<8192> authInfo(((const char *)this->data()) + (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 10), errorDataSize); + Dictionary<8192> authInfo(((const char*)this->data()) + (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 10), errorDataSize); uint64_t authVer = authInfo.getUI(ZT_AUTHINFO_DICT_KEY_VERSION, 0ULL); @@ -264,21 +267,22 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar char authenticationURL[2048]; if (authInfo.get(ZT_AUTHINFO_DICT_KEY_AUTHENTICATION_URL, authenticationURL, sizeof(authenticationURL)) > 0) { - authenticationURL[sizeof(authenticationURL) - 1] = 0; // ensure always zero terminated + authenticationURL[sizeof(authenticationURL) - 1] = 0; // ensure always zero terminated network->setAuthenticationRequired(tPtr, authenticationURL); } - } else if (authVer == 1) { + } + else if (authVer == 1) { char issuerURL[2048] = { 0 }; char centralAuthURL[2048] = { 0 }; char ssoNonce[64] = { 0 }; - char ssoState[128] = {0}; + char ssoState[128] = { 0 }; char ssoClientID[256] = { 0 }; char ssoProvider[64] = { 0 }; if (authInfo.get(ZT_AUTHINFO_DICT_KEY_ISSUER_URL, issuerURL, sizeof(issuerURL)) > 0) { issuerURL[sizeof(issuerURL) - 1] = 0; } - if (authInfo.get(ZT_AUTHINFO_DICT_KEY_CENTRAL_ENDPOINT_URL, centralAuthURL, sizeof(centralAuthURL))>0) { + if (authInfo.get(ZT_AUTHINFO_DICT_KEY_CENTRAL_ENDPOINT_URL, centralAuthURL, sizeof(centralAuthURL)) > 0) { centralAuthURL[sizeof(centralAuthURL) - 1] = 0; } if (authInfo.get(ZT_AUTHINFO_DICT_KEY_NONCE, ssoNonce, sizeof(ssoNonce)) > 0) { @@ -290,27 +294,29 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar if (authInfo.get(ZT_AUTHINFO_DICT_KEY_CLIENT_ID, ssoClientID, sizeof(ssoClientID)) > 0) { ssoClientID[sizeof(ssoClientID) - 1] = 0; } - if (authInfo.get(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, ssoProvider, sizeof(ssoProvider)) > 0 ) { + if (authInfo.get(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, ssoProvider, sizeof(ssoProvider)) > 0) { ssoProvider[sizeof(ssoProvider) - 1] = 0; - } else { + } + else { strncpy(ssoProvider, "default", sizeof(ssoProvider)); } network->setAuthenticationRequired(tPtr, issuerURL, centralAuthURL, ssoClientID, ssoProvider, ssoNonce, ssoState); } } - } else { + } + else { network->setAuthenticationRequired(tPtr, ""); } } Metrics::pkt_error_authentication_required_in++; - } break; + } break; default: break; } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_ERROR,inRePacketId,inReVerb,false,networkId,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_ERROR, inRePacketId, inReVerb, false, networkId, ZT_QOS_NO_FLOW); return true; } @@ -360,7 +366,7 @@ bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment* RR, void* tPtr return true; } -bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated) +bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bool alreadyAuthenticated) { Metrics::pkt_hello_in++; const int64_t now = RR->node->now(); @@ -373,89 +379,93 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool const unsigned int vRevision = at(ZT_PROTO_VERB_HELLO_IDX_REVISION); const int64_t timestamp = at(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP); Identity id; - unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY); + unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this, ZT_PROTO_VERB_HELLO_IDX_IDENTITY); if (protoVersion < ZT_PROTO_VERSION_MIN) { - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"protocol version too old"); + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "protocol version too old"); return true; } if (fromAddress != id.address()) { - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"identity/address mismatch"); + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "identity/address mismatch"); return true; } - SharedPtr peer(RR->topology->getPeer(tPtr,id.address())); + SharedPtr peer(RR->topology->getPeer(tPtr, id.address())); if (peer) { // We already have an identity with this address -- check for collisions - if (!alreadyAuthenticated) { + if (! alreadyAuthenticated) { if (peer->identity() != id) { // Identity is different from the one we already have -- address collision // Check rate limits - if (!RR->node->rateGateIdentityVerification(now,_path->address())) { + if (! RR->node->rateGateIdentityVerification(now, _path->address())) { return true; } uint8_t key[ZT_SYMMETRIC_KEY_SIZE]; - if (RR->identity.agree(id,key)) { - if (dearmor(key, peer->aesKeysIfSupported())) { // ensure packet is authentic, otherwise drop - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"address collision"); - Packet outp(id.address(),RR->identity.address(),Packet::VERB_ERROR); + if (RR->identity.agree(id, key)) { + if (dearmor(key, peer->aesKeysIfSupported())) { // ensure packet is authentic, otherwise drop + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "address collision"); + Packet outp(id.address(), RR->identity.address(), Packet::VERB_ERROR); outp.append((uint8_t)Packet::VERB_HELLO); outp.append((uint64_t)pid); outp.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION); - outp.armor(key,true,peer->aesKeysIfSupported()); + outp.armor(key, true, peer->aesKeysIfSupported()); Metrics::pkt_error_out++; Metrics::pkt_error_identity_collision_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); - } else { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } - } else { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid identity"); + else { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC"); + } + } + else { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid identity"); } return true; - } else { + } + else { // Identity is the same as the one we already have -- check packet integrity - if (!dearmor(peer->key(), peer->aesKeysIfSupported())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); + if (! dearmor(peer->key(), peer->aesKeysIfSupported())) { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC"); return true; } // Continue at // VALID } - } // else if alreadyAuthenticated then continue at // VALID - } else { + } // else if alreadyAuthenticated then continue at // VALID + } + else { // We don't already have an identity with this address -- validate and learn it // Sanity check: this basically can't happen if (alreadyAuthenticated) { - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"illegal alreadyAuthenticated state"); + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "illegal alreadyAuthenticated state"); return true; } // Check rate limits - if (!RR->node->rateGateIdentityVerification(now,_path->address())) { - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"rate limit exceeded"); + if (! RR->node->rateGateIdentityVerification(now, _path->address())) { + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "rate limit exceeded"); return true; } // Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap) - SharedPtr newPeer(new Peer(RR,RR->identity,id)); - if (!dearmor(newPeer->key(), newPeer->aesKeysIfSupported())) { - RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); + SharedPtr newPeer(new Peer(RR, RR->identity, id)); + if (! dearmor(newPeer->key(), newPeer->aesKeysIfSupported())) { + RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC"); return true; } // Check that identity's address is valid as per the derivation function - if (!id.locallyValidate()) { - RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"invalid identity"); + if (! id.locallyValidate()) { + RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "invalid identity"); return true; } - peer = RR->topology->addPeer(tPtr,newPeer); + peer = RR->topology->addPeer(tPtr, newPeer); // Continue at // VALID } @@ -465,9 +475,9 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool // Get external surface address if present (was not in old versions) InetAddress externalSurfaceAddress; if (ptr < size()) { - ptr += externalSurfaceAddress.deserialize(*this,ptr); - if ((externalSurfaceAddress)&&(hops() == 0)) { - RR->sa->iam(tPtr,id.address(),_path->localSocket(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(id),now); + ptr += externalSurfaceAddress.deserialize(*this, ptr); + if ((externalSurfaceAddress) && (hops() == 0)) { + RR->sa->iam(tPtr, id.address(), _path->localSocket(), _path->address(), externalSurfaceAddress, RR->topology->isUpstream(id), now); } } @@ -481,18 +491,18 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool ptr += 8; } - std::vector< std::pair > moonIdsAndTimestamps; + std::vector > moonIdsAndTimestamps; if (ptr < size()) { // Remainder of packet, if present, is encrypted - cryptField(peer->key(),ptr,size() - ptr); + cryptField(peer->key(), ptr, size() - ptr); // Get moon IDs and timestamps if present if ((ptr + 2) <= size()) { const unsigned int numMoons = at(ptr); ptr += 2; - for(unsigned int i=0;i(at(ptr),at(ptr + 8))); + moonIdsAndTimestamps.push_back(std::pair(at(ptr), at(ptr + 8))); } ptr += 16; } @@ -502,7 +512,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool // Send OK(HELLO) with an echo of the packet's timestamp and some of the same // information about us: version, sent-to address, etc. - Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK); + Packet outp(id.address(), RR->identity.address(), Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_HELLO); outp.append((uint64_t)pid); outp.append((uint64_t)timestamp); @@ -513,7 +523,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool if (protoVersion >= 5) { _path->address().serialize(outp); - } else { + } + else { /* LEGACY COMPATIBILITY HACK: * * For a while now (since 1.0.3), ZeroTier has recognized changes in @@ -543,49 +554,48 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool } const unsigned int worldUpdateSizeAt = outp.size(); - outp.addSize(2); // make room for 16-bit size field - if ((planetWorldId)&&(RR->topology->planetWorldTimestamp() > planetWorldTimestamp)&&(planetWorldId == RR->topology->planetWorldId())) { - RR->topology->planet().serialize(outp,false); + outp.addSize(2); // make room for 16-bit size field + if ((planetWorldId) && (RR->topology->planetWorldTimestamp() > planetWorldTimestamp) && (planetWorldId == RR->topology->planetWorldId())) { + RR->topology->planet().serialize(outp, false); } - if (!moonIdsAndTimestamps.empty()) { + if (! moonIdsAndTimestamps.empty()) { std::vector moons(RR->topology->moons()); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { - for(std::vector< std::pair >::const_iterator i(moonIdsAndTimestamps.begin());i!=moonIdsAndTimestamps.end();++i) { + for (std::vector::const_iterator m(moons.begin()); m != moons.end(); ++m) { + for (std::vector >::const_iterator i(moonIdsAndTimestamps.begin()); i != moonIdsAndTimestamps.end(); ++i) { if (i->first == m->id()) { if (m->timestamp() > i->second) { - m->serialize(outp,false); + m->serialize(outp, false); } break; } } } } - outp.setAt(worldUpdateSizeAt,(uint16_t)(outp.size() - (worldUpdateSizeAt + 2))); + outp.setAt(worldUpdateSizeAt, (uint16_t)(outp.size() - (worldUpdateSizeAt + 2))); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),now); + _path->send(RR, tPtr, outp.data(), outp.size(), now); - peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version - peer->received(tPtr,_path,hops(),pid,payloadLength(),Packet::VERB_HELLO,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->setRemoteVersion(protoVersion, vMajor, vMinor, vRevision); // important for this to go first so received() knows the version + peer->received(tPtr, _path, hops(), pid, payloadLength(), Packet::VERB_HELLO, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doOK(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_ok_in++; const Packet::Verb inReVerb = (Packet::Verb)(*this)[ZT_PROTO_VERB_OK_IDX_IN_RE_VERB]; const uint64_t inRePacketId = at(ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID); uint64_t networkId = 0; - if (!RR->node->expectingReplyTo(inRePacketId)) { + if (! RR->node->expectingReplyTo(inRePacketId)) { return true; } - switch(inReVerb) { - + switch (inReVerb) { case Packet::VERB_HELLO: { const uint64_t latency = RR->node->now() - at(ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP); const unsigned int vProto = (*this)[ZT_PROTO_VERB_HELLO__OK__IDX_PROTOCOL_VERSION]; @@ -601,7 +611,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP // Get reported external surface address if present if (ptr < size()) { - ptr += externalSurfaceAddress.deserialize(*this,ptr); + ptr += externalSurfaceAddress.deserialize(*this, ptr); } // Handle planet or moon updates if present @@ -612,29 +622,30 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP const unsigned int endOfWorlds = ptr + worldsLen; while (ptr < endOfWorlds) { World w; - ptr += w.deserialize(*this,ptr); - RR->topology->addWorld(tPtr,w,false); + ptr += w.deserialize(*this, ptr); + RR->topology->addWorld(tPtr, w, false); } - } else { + } + else { ptr += worldsLen; } } - if (!hops()) { - _path->updateLatency((unsigned int)latency,RR->node->now()); + if (! hops()) { + _path->updateLatency((unsigned int)latency, RR->node->now()); } - peer->setRemoteVersion(vProto,vMajor,vMinor,vRevision); + peer->setRemoteVersion(vProto, vMajor, vMinor, vRevision); - if ((externalSurfaceAddress)&&(hops() == 0)) { - RR->sa->iam(tPtr,peer->address(),_path->localSocket(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(peer->identity()),RR->node->now()); + if ((externalSurfaceAddress) && (hops() == 0)) { + RR->sa->iam(tPtr, peer->address(), _path->localSocket(), _path->address(), externalSurfaceAddress, RR->topology->isUpstream(peer->identity()), RR->node->now()); } - } break; + } break; case Packet::VERB_WHOIS: if (RR->topology->isUpstream(peer->identity())) { - const Identity id(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY); - RR->sw->doAnythingWaitingForPeer(tPtr,RR->topology->addPeer(tPtr,SharedPtr(new Peer(RR,RR->identity,id)))); + const Identity id(*this, ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY); + RR->sw->doAnythingWaitingForPeer(tPtr, RR->topology->addPeer(tPtr, SharedPtr(new Peer(RR, RR->identity, id)))); } break; @@ -642,34 +653,34 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP networkId = at(ZT_PROTO_VERB_OK_IDX_PAYLOAD); const SharedPtr network(RR->node->network(networkId)); if (network) { - network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD); + network->handleConfigChunk(tPtr, packetId(), source(), *this, ZT_PROTO_VERB_OK_IDX_PAYLOAD); } - } break; + } break; case Packet::VERB_MULTICAST_GATHER: { networkId = at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID); const SharedPtr network(RR->node->network(networkId)); if (network) { - const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC,6),6),at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI)); + const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC, 6), 6), at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI)); const unsigned int count = at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 4); - RR->mc->addMultiple(tPtr,RR->node->now(),networkId,mg,field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6,count * 5),count,at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS)); + RR->mc->addMultiple(tPtr, RR->node->now(), networkId, mg, field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6, count * 5), count, at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS)); } - } break; + } break; case Packet::VERB_MULTICAST_FRAME: { const unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS]; networkId = at(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID); - const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC,6),6),at(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI)); + const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC, 6), 6), at(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI)); const SharedPtr network(RR->node->network(networkId)); if (network) { unsigned int offset = 0; - if ((flags & 0x01) != 0) { // deprecated but still used by older peers + if ((flags & 0x01) != 0) { // deprecated but still used by older peers CertificateOfMembership com; - offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS); + offset += com.deserialize(*this, ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS); if (com) { - network->addCredential(tPtr,com); + network->addCredential(tPtr, com); } } @@ -680,86 +691,87 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP offset += 4; unsigned int count = at(offset); offset += 2; - RR->mc->addMultiple(tPtr,RR->node->now(),networkId,mg,field(offset,count * 5),count,totalKnown); + RR->mc->addMultiple(tPtr, RR->node->now(), networkId, mg, field(offset, count * 5), count, totalKnown); } } - } break; + } break; default: break; } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_OK,inRePacketId,inReVerb,false,networkId,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_OK, inRePacketId, inReVerb, false, networkId, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doWHOIS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { - if ((!RR->topology->amUpstream())&&(!peer->rateGateInboundWhoisRequest(RR->node->now()))) { + if ((! RR->topology->amUpstream()) && (! peer->rateGateInboundWhoisRequest(RR->node->now()))) { return true; } Metrics::pkt_whois_in++; - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_WHOIS); outp.append(packetId()); unsigned int count = 0; unsigned int ptr = ZT_PACKET_IDX_PAYLOAD; while ((ptr + ZT_ADDRESS_LENGTH) <= size()) { - const Address addr(field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + const Address addr(field(ptr, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); ptr += ZT_ADDRESS_LENGTH; - const Identity id(RR->topology->getIdentity(tPtr,addr)); + const Identity id(RR->topology->getIdentity(tPtr, addr)); if (id) { - id.serialize(outp,false); + id.serialize(outp, false); ++count; - } else { + } + else { // Request unknown WHOIS from upstream from us (if we have one) - RR->sw->requestWhois(tPtr,RR->node->now(),addr); + RR->sw->requestWhois(tPtr, RR->node->now(), addr); } } if (count > 0) { Metrics::pkt_ok_out++; - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_WHOIS,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_WHOIS, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_rendezvous_in++; if (RR->topology->isUpstream(peer->identity())) { - const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); - const SharedPtr rendezvousWith(RR->topology->getPeer(tPtr,with)); + const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + const SharedPtr rendezvousWith(RR->topology->getPeer(tPtr, with)); if (rendezvousWith) { const unsigned int port = at(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT); const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN]; - if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { - InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); - if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,with,_path->localSocket(),atAddr)) { + if ((port > 0) && ((addrlen == 4) || (addrlen == 16))) { + InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS, addrlen), addrlen, port); + if (RR->node->shouldUsePathForZeroTierTraffic(tPtr, with, _path->localSocket(), atAddr)) { const uint64_t junk = RR->node->prng(); - RR->node->putPacket(tPtr,_path->localSocket(),atAddr,&junk,4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls - rendezvousWith->attemptToContactAt(tPtr,_path->localSocket(),atAddr,RR->node->now(),false); + RR->node->putPacket(tPtr, _path->localSocket(), atAddr, &junk, 4, 2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls + rendezvousWith->attemptToContactAt(tPtr, _path->localSocket(), atAddr, RR->node->now(), false); } } } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_RENDEZVOUS, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } // Returns true if packet appears valid; pos and proto will be set -static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsigned int &pos,unsigned int &proto) +static bool _ipv6GetPayload(const uint8_t* frameData, unsigned int frameLen, unsigned int& pos, unsigned int& proto) { if (frameLen < 40) { return false; @@ -767,29 +779,29 @@ static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsig pos = 40; proto = frameData[6]; while (pos <= frameLen) { - switch(proto) { - case 0: // hop-by-hop options - case 43: // routing - case 60: // destination options - case 135: // mobility options + switch (proto) { + case 0: // hop-by-hop options + case 43: // routing + case 60: // destination options + case 135: // mobility options if ((pos + 8) > frameLen) { - return false; // invalid! + return false; // invalid! } proto = frameData[pos]; pos += ((unsigned int)frameData[pos + 1] * 8) + 8; break; - //case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway - //case 50: - //case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff + // case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway + // case 50: + // case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff default: return true; } } - return false; // overflow == invalid + return false; // overflow == invalid } -bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId) +bool IncomingPacket::_doFRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, int32_t flowId) { Metrics::pkt_frame_in++; int32_t _flowId = ZT_QOS_NO_FLOW; @@ -797,29 +809,29 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar if (size() > ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD) { const unsigned int etherType = at(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE); const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; - const uint8_t *const frameData = reinterpret_cast(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; + const uint8_t* const frameData = reinterpret_cast(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; if (etherType == ZT_ETHERTYPE_IPV4 && (frameLen >= 20)) { uint16_t srcPort = 0; uint16_t dstPort = 0; - uint8_t proto = (reinterpret_cast(frameData)[9]); - const unsigned int headerLen = 4 * (reinterpret_cast(frameData)[0] & 0xf); - switch(proto) { - case 0x01: // ICMP - //flowId = 0x01; + uint8_t proto = (reinterpret_cast(frameData)[9]); + const unsigned int headerLen = 4 * (reinterpret_cast(frameData)[0] & 0xf); + switch (proto) { + case 0x01: // ICMP + // flowId = 0x01; break; // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (frameLen > (headerLen + 4)) { unsigned int pos = headerLen + 0; - srcPort = (reinterpret_cast(frameData)[pos++]) << 8; - srcPort |= (reinterpret_cast(frameData)[pos]); + srcPort = (reinterpret_cast(frameData)[pos++]) << 8; + srcPort |= (reinterpret_cast(frameData)[pos]); pos++; - dstPort = (reinterpret_cast(frameData)[pos++]) << 8; - dstPort |= (reinterpret_cast(frameData)[pos]); + dstPort = (reinterpret_cast(frameData)[pos++]) << 8; + dstPort |= (reinterpret_cast(frameData)[pos]); _flowId = dstPort ^ srcPort ^ proto; } break; @@ -831,22 +843,22 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar uint16_t dstPort = 0; unsigned int pos; unsigned int proto; - _ipv6GetPayload((const uint8_t *)frameData, frameLen, pos, proto); - switch(proto) { - case 0x3A: // ICMPv6 - //flowId = 0x3A; + _ipv6GetPayload((const uint8_t*)frameData, frameLen, pos, proto); + switch (proto) { + case 0x3A: // ICMPv6 + // flowId = 0x3A; break; // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (frameLen > (pos + 4)) { - srcPort = (reinterpret_cast(frameData)[pos++]) << 8; - srcPort |= (reinterpret_cast(frameData)[pos]); + srcPort = (reinterpret_cast(frameData)[pos++]) << 8; + srcPort |= (reinterpret_cast(frameData)[pos]); pos++; - dstPort = (reinterpret_cast(frameData)[pos++]) << 8; - dstPort |= (reinterpret_cast(frameData)[pos]); + dstPort = (reinterpret_cast(frameData)[pos++]) << 8; + dstPort |= (reinterpret_cast(frameData)[pos]); _flowId = dstPort ^ srcPort ^ proto; } break; @@ -860,28 +872,29 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar const SharedPtr network(RR->node->network(nwid)); bool trustEstablished = false; if (network) { - if (network->gate(tPtr,peer)) { + if (network->gate(tPtr, peer)) { trustEstablished = true; if (size() > ZT_PROTO_VERB_FRAME_IDX_PAYLOAD) { const unsigned int etherType = at(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE); - const MAC sourceMac(peer->address(),nwid); + const MAC sourceMac(peer->address(), nwid); const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; - const uint8_t *const frameData = reinterpret_cast(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; - if (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),sourceMac,network->mac(),frameData,frameLen,etherType,0) > 0) { - RR->pm->putFrame(tPtr,nwid,network->userPtr(),sourceMac,network->mac(),etherType,0,(const void *)frameData,frameLen, _flowId); + const uint8_t* const frameData = reinterpret_cast(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; + if (network->filterIncomingPacket(tPtr, peer, RR->identity.address(), sourceMac, network->mac(), frameData, frameLen, etherType, 0) > 0) { + RR->pm->putFrame(tPtr, nwid, network->userPtr(), sourceMac, network->mac(), etherType, 0, (const void*)frameData, frameLen, _flowId); } } - } else { - _sendErrorNeedCredentials(RR,tPtr,peer,nwid); + } + else { + _sendErrorNeedCredentials(RR, tPtr, peer, nwid); return false; } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_FRAME,0,Packet::VERB_NOP,trustEstablished,nwid,_flowId); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_FRAME, 0, Packet::VERB_NOP, trustEstablished, nwid, _flowId); return true; } -bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId) +bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, int32_t flowId) { Metrics::pkt_ext_frame_in++; const uint64_t nwid = at(ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID); @@ -890,108 +903,112 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const const unsigned int flags = (*this)[ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS]; unsigned int comLen = 0; - if ((flags & 0x01) != 0) { // inline COM with EXT_FRAME is deprecated but still used with old peers + if ((flags & 0x01) != 0) { // inline COM with EXT_FRAME is deprecated but still used with old peers CertificateOfMembership com; - comLen = com.deserialize(*this,ZT_PROTO_VERB_EXT_FRAME_IDX_COM); + comLen = com.deserialize(*this, ZT_PROTO_VERB_EXT_FRAME_IDX_COM); if (com) { - network->addCredential(tPtr,com); + network->addCredential(tPtr, com); } } - if (!network->gate(tPtr,peer)) { - RR->t->incomingNetworkAccessDenied(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_EXT_FRAME,true); - _sendErrorNeedCredentials(RR,tPtr,peer,nwid); + if (! network->gate(tPtr, peer)) { + RR->t->incomingNetworkAccessDenied(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, true); + _sendErrorNeedCredentials(RR, tPtr, peer, nwid); return false; } if (size() > ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD) { const unsigned int etherType = at(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_ETHERTYPE); - const MAC to(field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_TO,ZT_PROTO_VERB_EXT_FRAME_LEN_TO),ZT_PROTO_VERB_EXT_FRAME_LEN_TO); - const MAC from(field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_FROM,ZT_PROTO_VERB_EXT_FRAME_LEN_FROM),ZT_PROTO_VERB_EXT_FRAME_LEN_FROM); + const MAC to(field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_TO, ZT_PROTO_VERB_EXT_FRAME_LEN_TO), ZT_PROTO_VERB_EXT_FRAME_LEN_TO); + const MAC from(field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_FROM, ZT_PROTO_VERB_EXT_FRAME_LEN_FROM), ZT_PROTO_VERB_EXT_FRAME_LEN_FROM); const unsigned int frameLen = size() - (comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD); - const uint8_t *const frameData = (const uint8_t *)field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,frameLen); + const uint8_t* const frameData = (const uint8_t*)field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD, frameLen); - if ((!from)||(from == network->mac())) { - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true,nwid,flowId); // trustEstablished because COM is okay + if ((! from) || (from == network->mac())) { + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay return true; } - switch (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),from,to,frameData,frameLen,etherType,0)) { + switch (network->filterIncomingPacket(tPtr, peer, RR->identity.address(), from, to, frameData, frameLen, etherType, 0)) { case 1: - if (from != MAC(peer->address(),nwid)) { + if (from != MAC(peer->address(), nwid)) { if (network->config().permitsBridging(peer->address())) { - network->learnBridgeRoute(from,peer->address()); - } else { - RR->t->incomingNetworkFrameDropped(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_EXT_FRAME,from,to,"bridging not allowed (remote)"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true,nwid,flowId); // trustEstablished because COM is okay + network->learnBridgeRoute(from, peer->address()); + } + else { + RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "bridging not allowed (remote)"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay return true; } - } else if (to != network->mac()) { + } + else if (to != network->mac()) { if (to.isMulticast()) { if (network->config().multicastLimit == 0) { - RR->t->incomingNetworkFrameDropped(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_EXT_FRAME,from,to,"multicast disabled"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true,nwid,flowId); // trustEstablished because COM is okay + RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "multicast disabled"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay return true; } - } else if (!network->config().permitsBridging(RR->identity.address())) { - RR->t->incomingNetworkFrameDropped(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_EXT_FRAME,from,to,"bridging not allowed (local)"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true,nwid,flowId); // trustEstablished because COM is okay + } + else if (! network->config().permitsBridging(RR->identity.address())) { + RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_EXT_FRAME, from, to, "bridging not allowed (local)"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); // trustEstablished because COM is okay return true; } } // fall through -- 2 means accept regardless of bridging checks or other restrictions case 2: - RR->pm->putFrame(tPtr,nwid,network->userPtr(),from,to,etherType,0,(const void *)frameData,frameLen, flowId); + RR->pm->putFrame(tPtr, nwid, network->userPtr(), from, to, etherType, 0, (const void*)frameData, frameLen, flowId); break; } } - if ((flags & 0x10) != 0) { // ACK requested - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + if ((flags & 0x10) != 0) { // ACK requested + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((uint8_t)Packet::VERB_EXT_FRAME); outp.append((uint64_t)packetId()); outp.append((uint64_t)nwid); const int64_t now = RR->node->now(); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true,nwid,flowId); - } else { - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,false,nwid,flowId); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, true, nwid, flowId); + } + else { + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_EXT_FRAME, 0, Packet::VERB_NOP, false, nwid, flowId); } return true; } -bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doECHO(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_echo_in++; uint64_t now = RR->node->now(); - if (!_path->rateGateEchoRequest(now)) { + if (! _path->rateGateEchoRequest(now)) { return true; } const uint64_t pid = packetId(); - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_ECHO); outp.append((uint64_t)pid); if (size() > ZT_PACKET_IDX_PAYLOAD) { - outp.append(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); + outp.append(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD, size() - ZT_PACKET_IDX_PAYLOAD); } - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); - peer->received(tPtr,_path,hops(),pid,payloadLength(),Packet::VERB_ECHO,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), pid, payloadLength(), Packet::VERB_ECHO, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_multicast_like_in++; const int64_t now = RR->node->now(); @@ -999,31 +1016,31 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,c uint64_t lastNwid = 0; // Packet contains a series of 18-byte network,MAC,ADI tuples - for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptr(ptr); if (nwid != lastNwid) { lastNwid = nwid; SharedPtr network(RR->node->network(nwid)); if (network) { - authorized = network->gate(tPtr,peer); + authorized = network->gate(tPtr, peer); } - if (!authorized) { - authorized = ((RR->topology->amUpstream())||(RR->node->localControllerHasAuthorized(now,nwid,peer->address()))); + if (! authorized) { + authorized = ((RR->topology->amUpstream()) || (RR->node->localControllerHasAuthorized(now, nwid, peer->address()))); } } if (authorized) { - RR->mc->add(tPtr,now,nwid,MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),peer->address()); + RR->mc->add(tPtr, now, nwid, MulticastGroup(MAC(field(ptr + 8, 6), 6), at(ptr + 14)), peer->address()); } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_LIKE, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_network_credentials_in++; - if (!peer->rateGateCredentialsReceived(RR->node->now())) { + if (! peer->rateGateCredentialsReceived(RR->node->now())) { return true; } @@ -1036,12 +1053,12 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t SharedPtr network; unsigned int p = ZT_PACKET_IDX_PAYLOAD; - while ((p < size())&&((*this)[p] != 0)) { - p += com.deserialize(*this,p); + while ((p < size()) && ((*this)[p] != 0)) { + p += com.deserialize(*this, p); if (com) { network = RR->node->network(com.networkId()); if (network) { - switch (network->addCredential(tPtr,com)) { + switch (network->addCredential(tPtr, com)) { case Membership::ADD_REJECTED: break; case Membership::ADD_ACCEPTED_NEW: @@ -1054,18 +1071,18 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t } } } - ++p; // skip trailing 0 after COMs if present + ++p; // skip trailing 0 after COMs if present - if (p < size()) { // older ZeroTier versions do not send capabilities, tags, or revocations + if (p < size()) { // older ZeroTier versions do not send capabilities, tags, or revocations const unsigned int numCapabilities = at(p); p += 2; - for(unsigned int i=0;iid() != cap.networkId())) { + for (unsigned int i = 0; i < numCapabilities; ++i) { + p += cap.deserialize(*this, p); + if ((! network) || (network->id() != cap.networkId())) { network = RR->node->network(cap.networkId()); } if (network) { - switch (network->addCredential(tPtr,cap)) { + switch (network->addCredential(tPtr, cap)) { case Membership::ADD_REJECTED: break; case Membership::ADD_ACCEPTED_NEW: @@ -1084,13 +1101,13 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t const unsigned int numTags = at(p); p += 2; - for(unsigned int i=0;iid() != tag.networkId())) { + for (unsigned int i = 0; i < numTags; ++i) { + p += tag.deserialize(*this, p); + if ((! network) || (network->id() != tag.networkId())) { network = RR->node->network(tag.networkId()); } if (network) { - switch (network->addCredential(tPtr,tag)) { + switch (network->addCredential(tPtr, tag)) { case Membership::ADD_REJECTED: break; case Membership::ADD_ACCEPTED_NEW: @@ -1109,13 +1126,13 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t const unsigned int numRevocations = at(p); p += 2; - for(unsigned int i=0;iid() != revocation.networkId())) { + for (unsigned int i = 0; i < numRevocations; ++i) { + p += revocation.deserialize(*this, p); + if ((! network) || (network->id() != revocation.networkId())) { network = RR->node->network(revocation.networkId()); } if (network) { - switch(network->addCredential(tPtr,peer->address(),revocation)) { + switch (network->addCredential(tPtr, peer->address(), revocation)) { case Membership::ADD_REJECTED: break; case Membership::ADD_ACCEPTED_NEW: @@ -1134,13 +1151,13 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t const unsigned int numCoos = at(p); p += 2; - for(unsigned int i=0;iid() != coo.networkId())) { + for (unsigned int i = 0; i < numCoos; ++i) { + p += coo.deserialize(*this, p); + if ((! network) || (network->id() != coo.networkId())) { network = RR->node->network(coo.networkId()); } if (network) { - switch(network->addCredential(tPtr,coo)) { + switch (network->addCredential(tPtr, coo)) { case Membership::ADD_REJECTED: break; case Membership::ADD_ACCEPTED_NEW: @@ -1154,12 +1171,12 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_NETWORK_CREDENTIALS,0,Packet::VERB_NOP,trustEstablished,(network) ? network->id() : 0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_NETWORK_CREDENTIALS, 0, Packet::VERB_NOP, trustEstablished, (network) ? network->id() : 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_network_config_request_in++; const uint64_t nwid = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID); @@ -1168,32 +1185,33 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void if (RR->localNetworkController) { const unsigned int metaDataLength = (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN <= size()) ? at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN) : 0; - const char *metaDataBytes = (metaDataLength != 0) ? (const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength) : (const char *)0; - const Dictionary metaData(metaDataBytes,metaDataLength); - RR->localNetworkController->request(nwid,(hopCount > 0) ? InetAddress() : _path->address(),requestPacketId,peer->identity(),metaData); - } else { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); + const char* metaDataBytes = (metaDataLength != 0) ? (const char*)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT, metaDataLength) : (const char*)0; + const Dictionary metaData(metaDataBytes, metaDataLength); + RR->localNetworkController->request(nwid, (hopCount > 0) ? InetAddress() : _path->address(), requestPacketId, peer->identity(), metaData); + } + else { + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append(requestPacketId); outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); Metrics::pkt_error_out++; Metrics::pkt_error_unsupported_op_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } - peer->received(tPtr,_path,hopCount,requestPacketId,payloadLength(),Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP,false,nwid,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hopCount, requestPacketId, payloadLength(), Packet::VERB_NETWORK_CONFIG_REQUEST, 0, Packet::VERB_NOP, false, nwid, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_network_config_in++; const SharedPtr network(RR->node->network(at(ZT_PACKET_IDX_PAYLOAD))); if (network) { - const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD); + const uint64_t configUpdateId = network->handleConfigChunk(tPtr, packetId(), source(), *this, ZT_PACKET_IDX_PAYLOAD); if (configUpdateId) { Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((uint8_t)Packet::VERB_ECHO); @@ -1201,24 +1219,24 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c outp.append((uint64_t)network->id()); outp.append((uint64_t)configUpdateId); const int64_t now = RR->node->now(); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_NETWORK_CONFIG,0,Packet::VERB_NOP,false,(network) ? network->id() : 0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_NETWORK_CONFIG, 0, Packet::VERB_NOP, false, (network) ? network->id() : 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_multicast_gather_in++; const uint64_t nwid = at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID); const unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS]; - const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC,6),6),at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI)); + const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC, 6), 6), at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI)); const unsigned int gatherLimit = at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT); const SharedPtr network(RR->node->network(nwid)); @@ -1226,37 +1244,39 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr if ((flags & 0x01) != 0) { try { CertificateOfMembership com; - com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM); - if ((com)&&(network)) { - network->addCredential(tPtr,com); + com.deserialize(*this, ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM); + if ((com) && (network)) { + network->addCredential(tPtr, com); } - } catch ( ... ) {} // discard invalid COMs + } + catch (...) { + } // discard invalid COMs } - const bool trustEstablished = (network) ? network->gate(tPtr,peer) : false; + const bool trustEstablished = (network) ? network->gate(tPtr, peer) : false; const int64_t now = RR->node->now(); - if ((gatherLimit > 0)&&((trustEstablished)||(RR->topology->amUpstream())||(RR->node->localControllerHasAuthorized(now,nwid,peer->address())))) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + if ((gatherLimit > 0) && ((trustEstablished) || (RR->topology->amUpstream()) || (RR->node->localControllerHasAuthorized(now, nwid, peer->address())))) { + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_MULTICAST_GATHER); outp.append(packetId()); outp.append(nwid); mg.mac().appendTo(outp); outp.append((uint32_t)mg.adi()); - const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit); + const unsigned int gatheredLocally = RR->mc->gather(peer->address(), nwid, mg, outp, gatherLimit); if (gatheredLocally > 0) { - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),now); + _path->send(RR, tPtr, outp.data(), outp.size(), now); } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP,trustEstablished,nwid,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_GATHER, 0, Packet::VERB_NOP, trustEstablished, nwid, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_multicast_frame_in++; const uint64_t nwid = at(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID); @@ -1270,14 +1290,14 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr, if ((flags & 0x01) != 0) { // This is deprecated but may still be sent by old peers CertificateOfMembership com; - offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM); + offset += com.deserialize(*this, ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM); if (com) { - network->addCredential(tPtr,com); + network->addCredential(tPtr, com); } } - if (!network->gate(tPtr,peer)) { - _sendErrorNeedCredentials(RR,tPtr,peer,nwid); + if (! network->gate(tPtr, peer)) { + _sendErrorNeedCredentials(RR, tPtr, peer, nwid); return false; } @@ -1289,189 +1309,191 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr, MAC from; if ((flags & 0x04) != 0) { - from.setTo(field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC,6),6); + from.setTo(field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC, 6), 6); offset += 6; - } else { - from.fromAddress(peer->address(),nwid); + } + else { + from.fromAddress(peer->address(), nwid); } - const MulticastGroup to(MAC(field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC,6),6),at(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI)); + const MulticastGroup to(MAC(field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC, 6), 6), at(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI)); const unsigned int etherType = at(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE); const unsigned int frameLen = size() - (offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME); if (network->config().multicastLimit == 0) { - RR->t->incomingNetworkFrameDropped(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_MULTICAST_FRAME,from,to.mac(),"multicast disabled"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false,nwid,ZT_QOS_NO_FLOW); + RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_MULTICAST_FRAME, from, to.mac(), "multicast disabled"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, false, nwid, ZT_QOS_NO_FLOW); return true; } - if ((frameLen > 0)&&(frameLen <= ZT_MAX_MTU)) { - if (!to.mac().isMulticast()) { - RR->t->incomingPacketInvalid(tPtr,_path,packetId(),source(),hops(),Packet::VERB_MULTICAST_FRAME,"destination not multicast"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true,nwid,ZT_QOS_NO_FLOW); // trustEstablished because COM is okay + if ((frameLen > 0) && (frameLen <= ZT_MAX_MTU)) { + if (! to.mac().isMulticast()) { + RR->t->incomingPacketInvalid(tPtr, _path, packetId(), source(), hops(), Packet::VERB_MULTICAST_FRAME, "destination not multicast"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, true, nwid, ZT_QOS_NO_FLOW); // trustEstablished because COM is okay return true; } - if ((!from)||(from.isMulticast())||(from == network->mac())) { - RR->t->incomingPacketInvalid(tPtr,_path,packetId(),source(),hops(),Packet::VERB_MULTICAST_FRAME,"invalid source MAC"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true,nwid,ZT_QOS_NO_FLOW); // trustEstablished because COM is okay + if ((! from) || (from.isMulticast()) || (from == network->mac())) { + RR->t->incomingPacketInvalid(tPtr, _path, packetId(), source(), hops(), Packet::VERB_MULTICAST_FRAME, "invalid source MAC"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, true, nwid, ZT_QOS_NO_FLOW); // trustEstablished because COM is okay return true; } - const uint8_t *const frameData = (const uint8_t *)field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME,frameLen); + const uint8_t* const frameData = (const uint8_t*)field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME, frameLen); - if ((flags & 0x08)&&(network->config().isMulticastReplicator(RR->identity.address()))) { - RR->mc->send(tPtr,RR->node->now(),network,peer->address(),to,from,etherType,frameData,frameLen); + if ((flags & 0x08) && (network->config().isMulticastReplicator(RR->identity.address()))) { + RR->mc->send(tPtr, RR->node->now(), network, peer->address(), to, from, etherType, frameData, frameLen); } - if (from != MAC(peer->address(),nwid)) { + if (from != MAC(peer->address(), nwid)) { if (network->config().permitsBridging(peer->address())) { - network->learnBridgeRoute(from,peer->address()); - } else { - RR->t->incomingNetworkFrameDropped(tPtr,network,_path,packetId(),size(),peer->address(),Packet::VERB_MULTICAST_FRAME,from,to.mac(),"bridging not allowed (remote)"); - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true,nwid,ZT_QOS_NO_FLOW); // trustEstablished because COM is okay + network->learnBridgeRoute(from, peer->address()); + } + else { + RR->t->incomingNetworkFrameDropped(tPtr, network, _path, packetId(), size(), peer->address(), Packet::VERB_MULTICAST_FRAME, from, to.mac(), "bridging not allowed (remote)"); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, true, nwid, ZT_QOS_NO_FLOW); // trustEstablished because COM is okay return true; } } - if (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),from,to.mac(),frameData,frameLen,etherType,0) > 0) { - RR->node->putFrame(tPtr,nwid,network->userPtr(),from,to.mac(),etherType,0,(const void *)frameData,frameLen); + if (network->filterIncomingPacket(tPtr, peer, RR->identity.address(), from, to.mac(), frameData, frameLen, etherType, 0) > 0) { + RR->node->putFrame(tPtr, nwid, network->userPtr(), from, to.mac(), etherType, 0, (const void*)frameData, frameLen); } } if (gatherLimit) { - Packet outp(source(),RR->identity.address(),Packet::VERB_OK); + Packet outp(source(), RR->identity.address(), Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_MULTICAST_FRAME); outp.append(packetId()); outp.append(nwid); to.mac().appendTo(outp); outp.append((uint32_t)to.adi()); - outp.append((unsigned char)0x02); // flag 0x02 = contains gather results - if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { + outp.append((unsigned char)0x02); // flag 0x02 = contains gather results + if (RR->mc->gather(peer->address(), nwid, to, outp, gatherLimit)) { const int64_t now = RR->node->now(); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true,nwid,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_MULTICAST_FRAME, 0, Packet::VERB_NOP, true, nwid, ZT_QOS_NO_FLOW); } return true; } -bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_push_direct_paths_in++; const int64_t now = RR->node->now(); - if (!peer->rateGatePushDirectPaths(now)) { - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + if (! peer->rateGatePushDirectPaths(now)) { + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_PUSH_DIRECT_PATHS, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } // Second, limit addresses by scope and type - uint8_t countPerScope[ZT_INETADDRESS_MAX_SCOPE+1][2]; // [][0] is v4, [][1] is v6 - memset(countPerScope,0,sizeof(countPerScope)); + uint8_t countPerScope[ZT_INETADDRESS_MAX_SCOPE + 1][2]; // [][0] is v4, [][1] is v6 + memset(countPerScope, 0, sizeof(countPerScope)); unsigned int count = at(ZT_PACKET_IDX_PAYLOAD); unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2; - while (count--) { // if ptr overflows Buffer will throw + while (count--) { // if ptr overflows Buffer will throw unsigned int flags = (*this)[ptr++]; unsigned int extLen = at(ptr); ptr += 2; - ptr += extLen; // unused right now + ptr += extLen; // unused right now unsigned int addrType = (*this)[ptr++]; unsigned int addrLen = (*this)[ptr++]; - switch(addrType) { + switch (addrType) { case 4: { - const InetAddress a(field(ptr,4),4,at(ptr + 4)); - if ( - ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget - (!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known - (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localSocket(),a)) ) // should use path + const InetAddress a(field(ptr, 4), 4, at(ptr + 4)); + if (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget + (! (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now, a)))) && // not already known + (RR->node->shouldUsePathForZeroTierTraffic(tPtr, peer->address(), _path->localSocket(), a))) // should use path { if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) { - peer->clusterRedirect(tPtr,_path,a,now); - } else if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { - peer->attemptToContactAt(tPtr,InetAddress(),a,now,false); + peer->clusterRedirect(tPtr, _path, a, now); + } + else if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { + peer->attemptToContactAt(tPtr, InetAddress(), a, now, false); } } - } break; + } break; case 6: { - - const InetAddress a(field(ptr,16),16,at(ptr + 16)); - if ( - ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget - (!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known - (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localSocket(),a)) ) // should use path + const InetAddress a(field(ptr, 16), 16, at(ptr + 16)); + if (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget + (! (((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now, a)))) && // not already known + (RR->node->shouldUsePathForZeroTierTraffic(tPtr, peer->address(), _path->localSocket(), a))) // should use path { if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0) { - peer->clusterRedirect(tPtr,_path,a,now); - } else if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { - peer->attemptToContactAt(tPtr,InetAddress(),a,now,false); + peer->clusterRedirect(tPtr, _path, a, now); + } + else if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { + peer->attemptToContactAt(tPtr, InetAddress(), a, now, false); } } - } break; + } break; } ptr += addrLen; } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_PUSH_DIRECT_PATHS, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_user_message_in++; if (likely(size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) { ZT_UserMessage um; um.origin = peer->address().toInt(); um.typeId = at(ZT_PACKET_IDX_PAYLOAD); - um.data = reinterpret_cast(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD + 8); + um.data = reinterpret_cast(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD + 8); um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8); - RR->node->postEvent(tPtr,ZT_EVENT_USER_MESSAGE,reinterpret_cast(&um)); + RR->node->postEvent(tPtr, ZT_EVENT_USER_MESSAGE, reinterpret_cast(&um)); } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_USER_MESSAGE,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_USER_MESSAGE, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_remote_trace_in++; ZT_RemoteTrace rt; - const char *ptr = reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD; - const char *const eof = reinterpret_cast(data()) + size(); + const char* ptr = reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD; + const char* const eof = reinterpret_cast(data()) + size(); rt.origin = peer->address().toInt(); - rt.data = const_cast(ptr); // start of first string + rt.data = const_cast(ptr); // start of first string while (ptr < eof) { - if (!*ptr) { // end of string + if (! *ptr) { // end of string rt.len = (unsigned int)(ptr - rt.data); - if ((rt.len > 0)&&(rt.len <= ZT_MAX_REMOTE_TRACE_SIZE)) { - RR->node->postEvent(tPtr,ZT_EVENT_REMOTE_TRACE,&rt); + if ((rt.len > 0) && (rt.len <= ZT_MAX_REMOTE_TRACE_SIZE)) { + RR->node->postEvent(tPtr, ZT_EVENT_REMOTE_TRACE, &rt); } - rt.data = const_cast(++ptr); // start of next string, if any - } else { + rt.data = const_cast(++ptr); // start of next string, if any + } + else { ++ptr; } } - peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_REMOTE_TRACE,0,Packet::VERB_NOP,false,0,ZT_QOS_NO_FLOW); + peer->received(tPtr, _path, hops(), packetId(), payloadLength(), Packet::VERB_REMOTE_TRACE, 0, Packet::VERB_NOP, false, 0, ZT_QOS_NO_FLOW); return true; } -bool IncomingPacket::_doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) +bool IncomingPacket::_doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { Metrics::pkt_path_negotiation_request_in++; uint64_t now = RR->node->now(); - if (!peer->rateGatePathNegotiation(now, _path)) { + if (! peer->rateGatePathNegotiation(now, _path)) { return true; } if (payloadLength() != sizeof(int16_t)) { @@ -1483,17 +1505,17 @@ bool IncomingPacket::_doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment *RR,vo return true; } -void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,const uint64_t nwid) +void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, const uint64_t nwid) { - Packet outp(source(),RR->identity.address(),Packet::VERB_ERROR); + Packet outp(source(), RR->identity.address(), Packet::VERB_ERROR); outp.append((uint8_t)verb()); outp.append(packetId()); outp.append((uint8_t)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); Metrics::pkt_error_out++; Metrics::pkt_error_need_membership_cert_out++; - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp index aa5936ff2..ebca8f220 100644 --- a/node/IncomingPacket.hpp +++ b/node/IncomingPacket.hpp @@ -14,13 +14,13 @@ #ifndef ZT_INCOMINGPACKET_HPP #define ZT_INCOMINGPACKET_HPP -#include - +#include "MulticastGroup.hpp" #include "Packet.hpp" #include "Path.hpp" -#include "Utils.hpp" -#include "MulticastGroup.hpp" #include "Peer.hpp" +#include "Utils.hpp" + +#include /* * The big picture: @@ -46,14 +46,9 @@ class Network; /** * Subclass of packet that handles the decoding of it */ -class IncomingPacket : public Packet -{ -public: - IncomingPacket() : - Packet(), - _receiveTime(0), - _path(), - _authenticated(false) +class IncomingPacket : public Packet { + public: + IncomingPacket() : Packet(), _receiveTime(0), _path(), _authenticated(false) { } @@ -66,11 +61,7 @@ public: * @param now Current time * @throws std::out_of_range Range error processing packet */ - IncomingPacket(const void *data,unsigned int len,const SharedPtr &path,int64_t now) : - Packet(data,len), - _receiveTime(now), - _path(path), - _authenticated(false) + IncomingPacket(const void* data, unsigned int len, const SharedPtr& path, int64_t now) : Packet(data, len), _receiveTime(now), _path(path), _authenticated(false) { } @@ -83,9 +74,9 @@ public: * @param now Current time * @throws std::out_of_range Range error processing packet */ - inline void init(const void *data,unsigned int len,const SharedPtr &path,int64_t now) + inline void init(const void* data, unsigned int len, const SharedPtr& path, int64_t now) { - copyFrom(data,len); + copyFrom(data, len); _receiveTime = now; _path = path; _authenticated = false; @@ -104,44 +95,47 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @return True if decoding and processing is complete, false if caller should try again */ - bool tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t flowId); + bool tryDecode(const RuntimeEnvironment* RR, void* tPtr, int32_t flowId); /** * @return Time of packet receipt / start of decode */ - inline uint64_t receiveTime() const { return _receiveTime; } + inline uint64_t receiveTime() const + { + return _receiveTime; + } -private: + private: // These are called internally to handle packet contents once it has // been authenticated, decrypted, decompressed, and classified. - bool _doERROR(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated); - bool _doACK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doQOS_MEASUREMENT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId); - bool _doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId); - bool _doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); - bool _doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer); + bool _doERROR(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bool alreadyAuthenticated); + bool _doACK(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doQOS_MEASUREMENT(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doOK(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doWHOIS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doRENDEZVOUS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doFRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, int32_t flowId); + bool _doEXT_FRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, int32_t flowId); + bool _doECHO(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doMULTICAST_LIKE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doNETWORK_CONFIG(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doMULTICAST_GATHER(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doMULTICAST_FRAME(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doUSER_MESSAGE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doREMOTE_TRACE(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); + bool _doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer); - void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,const uint64_t nwid); + void _sendErrorNeedCredentials(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer, const uint64_t nwid); uint64_t _receiveTime; SharedPtr _path; bool _authenticated; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 31100d643..17e297d6c 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -11,132 +11,132 @@ */ /****/ -#include -#include -#include - -#include +#include "InetAddress.hpp" #include "Constants.hpp" -#include "InetAddress.hpp" #include "Utils.hpp" +#include +#include +#include +#include + namespace ZeroTier { -const InetAddress InetAddress::LO4((const void *)("\x7f\x00\x00\x01"),4,0); -const InetAddress InetAddress::LO6((const void *)("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"),16,0); +const InetAddress InetAddress::LO4((const void*)("\x7f\x00\x00\x01"), 4, 0); +const InetAddress InetAddress::LO6((const void*)("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), 16, 0); InetAddress::IpScope InetAddress::ipScope() const { - switch(ss_family) { - + switch (ss_family) { case AF_INET: { - const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); - switch(ip >> 24) { + const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); + switch (ip >> 24) { case 0x00: - return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used) + return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used) case 0x06: - return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army) + return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army) case 0x0a: - return IP_SCOPE_PRIVATE; // 10.0.0.0/8 + return IP_SCOPE_PRIVATE; // 10.0.0.0/8 case 0x0b: - return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD) + return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD) case 0x15: - return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN) + return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN) case 0x16: - return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA) + return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA) case 0x19: - return IP_SCOPE_PSEUDOPRIVATE; // 25.0.0.0/8 (UK Ministry of Defense) + return IP_SCOPE_PSEUDOPRIVATE; // 25.0.0.0/8 (UK Ministry of Defense) case 0x1a: - return IP_SCOPE_PSEUDOPRIVATE; // 26.0.0.0/8 (US DISA) + return IP_SCOPE_PSEUDOPRIVATE; // 26.0.0.0/8 (US DISA) case 0x1c: - return IP_SCOPE_PSEUDOPRIVATE; // 28.0.0.0/8 (US DSI-North) + return IP_SCOPE_PSEUDOPRIVATE; // 28.0.0.0/8 (US DSI-North) case 0x1d: - return IP_SCOPE_PSEUDOPRIVATE; // 29.0.0.0/8 (US DISA) + return IP_SCOPE_PSEUDOPRIVATE; // 29.0.0.0/8 (US DISA) case 0x1e: - return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA) + return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA) case 0x33: - return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security) + return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security) case 0x37: - return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD) + return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD) case 0x38: - return IP_SCOPE_PSEUDOPRIVATE; // 56.0.0.0/8 (US Postal Service) + return IP_SCOPE_PSEUDOPRIVATE; // 56.0.0.0/8 (US Postal Service) case 0x64: if ((ip & 0xffc00000) == 0x64400000) { - return IP_SCOPE_PRIVATE; // 100.64.0.0/10 + return IP_SCOPE_PRIVATE; // 100.64.0.0/10 } break; case 0x7f: - return IP_SCOPE_LOOPBACK; // 127.0.0.0/8 + return IP_SCOPE_LOOPBACK; // 127.0.0.0/8 case 0xa9: if ((ip & 0xffff0000) == 0xa9fe0000) { - return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16 + return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16 } break; case 0xac: if ((ip & 0xfff00000) == 0xac100000) { - return IP_SCOPE_PRIVATE; // 172.16.0.0/12 + return IP_SCOPE_PRIVATE; // 172.16.0.0/12 } break; case 0xc0: if ((ip & 0xffff0000) == 0xc0a80000) { - return IP_SCOPE_PRIVATE; // 192.168.0.0/16 + return IP_SCOPE_PRIVATE; // 192.168.0.0/16 } if ((ip & 0xffffff00) == 0xc0000200) { - return IP_SCOPE_PRIVATE; // 192.0.2.0/24 + return IP_SCOPE_PRIVATE; // 192.0.2.0/24 } break; case 0xc6: if ((ip & 0xfffe0000) == 0xc6120000) { - return IP_SCOPE_PRIVATE; // 198.18.0.0/15 + return IP_SCOPE_PRIVATE; // 198.18.0.0/15 } if ((ip & 0xffffff00) == 0xc6336400) { - return IP_SCOPE_PRIVATE; // 198.51.100.0/24 + return IP_SCOPE_PRIVATE; // 198.51.100.0/24 } break; case 0xcb: if ((ip & 0xffffff00) == 0xcb007100) { - return IP_SCOPE_PRIVATE; // 203.0.113.0/24 + return IP_SCOPE_PRIVATE; // 203.0.113.0/24 } break; case 0xff: - return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable) + return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable) } - switch(ip >> 28) { + switch (ip >> 28) { case 0xe: - return IP_SCOPE_MULTICAST; // 224.0.0.0/4 + return IP_SCOPE_MULTICAST; // 224.0.0.0/4 case 0xf: - return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable) + return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable) } return IP_SCOPE_GLOBAL; - } break; + } break; case AF_INET6: { - const unsigned char *ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + const unsigned char* ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); if ((ip[0] & 0xf0) == 0xf0) { if (ip[0] == 0xff) { - return IP_SCOPE_MULTICAST; // ff00::/8 + return IP_SCOPE_MULTICAST; // ff00::/8 } - if ((ip[0] == 0xfe)&&((ip[1] & 0xc0) == 0x80)) { + if ((ip[0] == 0xfe) && ((ip[1] & 0xc0) == 0x80)) { unsigned int k = 2; - while ((!ip[k])&&(k < 15)) { + while ((! ip[k]) && (k < 15)) { ++k; } - if ((k == 15)&&(ip[15] == 0x01)) { - return IP_SCOPE_LOOPBACK; // fe80::1/128 - } else { - return IP_SCOPE_LINK_LOCAL; // fe80::/10 + if ((k == 15) && (ip[15] == 0x01)) { + return IP_SCOPE_LOOPBACK; // fe80::1/128 + } + else { + return IP_SCOPE_LINK_LOCAL; // fe80::/10 } } if ((ip[0] & 0xfe) == 0xfc) { - return IP_SCOPE_PRIVATE; // fc00::/7 + return IP_SCOPE_PRIVATE; // fc00::/7 } } // :::ffff:127.0.0.1 // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1 unsigned int k = 0; - while ((!ip[k])&&(k < 9)) { + while ((! ip[k]) && (k < 9)) { ++k; } if (k == 9) { @@ -146,92 +146,92 @@ InetAddress::IpScope InetAddress::ipScope() const } k = 0; - while ((!ip[k])&&(k < 15)) { + while ((! ip[k]) && (k < 15)) { ++k; } - if (k == 15) { // all 0's except last byte + if (k == 15) { // all 0's except last byte if (ip[15] == 0x01) { - return IP_SCOPE_LOOPBACK; // ::1/128 + return IP_SCOPE_LOOPBACK; // ::1/128 } if (ip[15] == 0x00) { - return IP_SCOPE_NONE; // ::/128 + return IP_SCOPE_NONE; // ::/128 } } return IP_SCOPE_GLOBAL; - } break; - + } break; } return IP_SCOPE_NONE; } -void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) +void InetAddress::set(const void* ipBytes, unsigned int ipLen, unsigned int port) { - memset(this,0,sizeof(InetAddress)); + memset(this, 0, sizeof(InetAddress)); if (ipLen == 4) { uint32_t ipb[1]; - memcpy(ipb,ipBytes,4); + memcpy(ipb, ipBytes, 4); ss_family = AF_INET; - reinterpret_cast(this)->sin_addr.s_addr = ipb[0]; - reinterpret_cast(this)->sin_port = Utils::hton((uint16_t)port); - } else if (ipLen == 16) { + reinterpret_cast(this)->sin_addr.s_addr = ipb[0]; + reinterpret_cast(this)->sin_port = Utils::hton((uint16_t)port); + } + else if (ipLen == 16) { ss_family = AF_INET6; - memcpy(reinterpret_cast(this)->sin6_addr.s6_addr,ipBytes,16); - reinterpret_cast(this)->sin6_port = Utils::hton((uint16_t)port); + memcpy(reinterpret_cast(this)->sin6_addr.s6_addr, ipBytes, 16); + reinterpret_cast(this)->sin6_port = Utils::hton((uint16_t)port); } } -char *InetAddress::toString(char buf[64]) const +char* InetAddress::toString(char buf[64]) const { - char *p = toIpString(buf); + char* p = toIpString(buf); if (*p) { while (*p) { ++p; } *(p++) = '/'; - Utils::decimal(port(),p); + Utils::decimal(port(), p); } return buf; } -char *InetAddress::toIpString(char buf[64]) const +char* InetAddress::toIpString(char buf[64]) const { buf[0] = (char)0; - switch(ss_family) { + switch (ss_family) { case AF_INET: { #ifdef _WIN32 - inet_ntop(AF_INET, (void*)&reinterpret_cast(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN); + inet_ntop(AF_INET, (void*)&reinterpret_cast(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN); #else - inet_ntop(AF_INET, &reinterpret_cast(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &reinterpret_cast(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN); #endif - } break; + } break; case AF_INET6: { #ifdef _WIN32 - inet_ntop(AF_INET6, (void*)reinterpret_cast(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, (void*)reinterpret_cast(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN); #else - inet_ntop(AF_INET6, reinterpret_cast(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, reinterpret_cast(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN); #endif - } break; + } break; } return buf; } -bool InetAddress::fromString(const char *ipSlashPort) +bool InetAddress::fromString(const char* ipSlashPort) { char buf[64]; - memset(this,0,sizeof(InetAddress)); + memset(this, 0, sizeof(InetAddress)); - if (!*ipSlashPort) { + if (! *ipSlashPort) { return true; } - if (!Utils::scopy(buf,sizeof(buf),ipSlashPort)) { + if (! Utils::scopy(buf, sizeof(buf), ipSlashPort)) { return false; } - char *portAt = buf; - while ((*portAt)&&(*portAt != '/')) { + char* portAt = buf; + while ((*portAt) && (*portAt != '/')) { ++portAt; } unsigned int port = 0; @@ -240,19 +240,21 @@ bool InetAddress::fromString(const char *ipSlashPort) port = Utils::strToUInt(portAt) & 0xffff; } - if (strchr(buf,':')) { - struct sockaddr_in6 *const in6 = reinterpret_cast(this); + if (strchr(buf, ':')) { + struct sockaddr_in6* const in6 = reinterpret_cast(this); inet_pton(AF_INET6, buf, &in6->sin6_addr.s6_addr); in6->sin6_family = AF_INET6; in6->sin6_port = Utils::hton((uint16_t)port); return true; - } else if (strchr(buf,'.')) { - struct sockaddr_in *const in = reinterpret_cast(this); + } + else if (strchr(buf, '.')) { + struct sockaddr_in* const in = reinterpret_cast(this); inet_pton(AF_INET, buf, &in->sin_addr.s_addr); in->sin_family = AF_INET; in->sin_port = Utils::hton((uint16_t)port); return true; - } else { + } + else { return false; } } @@ -260,22 +262,23 @@ bool InetAddress::fromString(const char *ipSlashPort) InetAddress InetAddress::netmask() const { InetAddress r(*this); - switch(r.ss_family) { + switch (r.ss_family) { case AF_INET: - reinterpret_cast(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits()))); + reinterpret_cast(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits()))); break; case AF_INET6: { uint64_t nm[2]; const unsigned int bits = netmaskBits(); - if(bits) { + if (bits) { nm[0] = Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits)))); nm[1] = Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits)))); - } else { + } + else { nm[0] = 0; nm[1] = 0; } - memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr,nm,16); - } break; + memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr, nm, 16); + } break; } return r; } @@ -284,7 +287,7 @@ InetAddress InetAddress::broadcast() const { if (ss_family == AF_INET) { InetAddress r(*this); - reinterpret_cast(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits())); + reinterpret_cast(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffff >> netmaskBits())); return r; } return InetAddress(); @@ -293,34 +296,34 @@ InetAddress InetAddress::broadcast() const InetAddress InetAddress::network() const { InetAddress r(*this); - switch(r.ss_family) { + switch (r.ss_family) { case AF_INET: - reinterpret_cast(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits()))); + reinterpret_cast(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffff << (32 - netmaskBits()))); break; case AF_INET6: { uint64_t nm[2]; const unsigned int bits = netmaskBits(); - memcpy(nm,reinterpret_cast(&r)->sin6_addr.s6_addr,16); + memcpy(nm, reinterpret_cast(&r)->sin6_addr.s6_addr, 16); nm[0] &= Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits)))); nm[1] &= Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits)))); - memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr,nm,16); - } break; + memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr, nm, 16); + } break; } return r; } -bool InetAddress::isEqualPrefix(const InetAddress &addr) const +bool InetAddress::isEqualPrefix(const InetAddress& addr) const { if (addr.ss_family == ss_family) { - switch(ss_family) { + switch (ss_family) { case AF_INET6: { const InetAddress mask(netmask()); InetAddress addr_mask(addr.netmask()); - const uint8_t *n = reinterpret_cast(reinterpret_cast(&addr_mask)->sin6_addr.s6_addr); - const uint8_t *m = reinterpret_cast(reinterpret_cast(&mask)->sin6_addr.s6_addr); - const uint8_t *a = reinterpret_cast(reinterpret_cast(&addr)->sin6_addr.s6_addr); - const uint8_t *b = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); - for(unsigned int i=0;i<16;++i) { + const uint8_t* n = reinterpret_cast(reinterpret_cast(&addr_mask)->sin6_addr.s6_addr); + const uint8_t* m = reinterpret_cast(reinterpret_cast(&mask)->sin6_addr.s6_addr); + const uint8_t* a = reinterpret_cast(reinterpret_cast(&addr)->sin6_addr.s6_addr); + const uint8_t* b = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + for (unsigned int i = 0; i < 16; ++i) { if ((a[i] & m[i]) != (b[i] & n[i])) { return false; } @@ -332,23 +335,24 @@ bool InetAddress::isEqualPrefix(const InetAddress &addr) const return false; } -bool InetAddress::containsAddress(const InetAddress &addr) const +bool InetAddress::containsAddress(const InetAddress& addr) const { if (addr.ss_family == ss_family) { - switch(ss_family) { + switch (ss_family) { case AF_INET: { const unsigned int bits = netmaskBits(); if (bits == 0) { return true; } - return ( (Utils::ntoh((uint32_t)reinterpret_cast(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr) >> (32 - bits)) ); + return ( + (Utils::ntoh((uint32_t)reinterpret_cast(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr) >> (32 - bits))); } case AF_INET6: { const InetAddress mask(netmask()); - const uint8_t *m = reinterpret_cast(reinterpret_cast(&mask)->sin6_addr.s6_addr); - const uint8_t *a = reinterpret_cast(reinterpret_cast(&addr)->sin6_addr.s6_addr); - const uint8_t *b = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); - for(unsigned int i=0;i<16;++i) { + const uint8_t* m = reinterpret_cast(reinterpret_cast(&mask)->sin6_addr.s6_addr); + const uint8_t* a = reinterpret_cast(reinterpret_cast(&addr)->sin6_addr.s6_addr); + const uint8_t* b = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + for (unsigned int i = 0; i < 16; ++i) { if ((a[i] & m[i]) != b[i]) { return false; } @@ -362,7 +366,7 @@ bool InetAddress::containsAddress(const InetAddress &addr) const bool InetAddress::isNetwork() const { - switch(ss_family) { + switch (ss_family) { case AF_INET: { unsigned int bits = netmaskBits(); if (bits <= 0) { @@ -371,7 +375,7 @@ bool InetAddress::isNetwork() const if (bits >= 32) { return false; } - uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); + uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); return ((ip & (0xffffffff >> bits)) == 0); } case AF_INET6: { @@ -382,7 +386,7 @@ bool InetAddress::isNetwork() const if (bits >= 128) { return false; } - const unsigned char *ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + const unsigned char* ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); unsigned int p = bits / 8; if ((ip[p++] & (0xff >> (bits % 8))) != 0) { return false; @@ -398,55 +402,60 @@ bool InetAddress::isNetwork() const return false; } -bool InetAddress::operator==(const InetAddress &a) const +bool InetAddress::operator==(const InetAddress& a) const { if (ss_family == a.ss_family) { - switch(ss_family) { + switch (ss_family) { case AF_INET: return ( - (reinterpret_cast(this)->sin_port == reinterpret_cast(&a)->sin_port)&& - (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr)); + (reinterpret_cast(this)->sin_port == reinterpret_cast(&a)->sin_port) + && (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr)); break; case AF_INET6: return ( - (reinterpret_cast(this)->sin6_port == reinterpret_cast(&a)->sin6_port)&& - (reinterpret_cast(this)->sin6_flowinfo == reinterpret_cast(&a)->sin6_flowinfo)&& - (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr,reinterpret_cast(&a)->sin6_addr.s6_addr,16) == 0)&& - (reinterpret_cast(this)->sin6_scope_id == reinterpret_cast(&a)->sin6_scope_id)); + (reinterpret_cast(this)->sin6_port == reinterpret_cast(&a)->sin6_port) + && (reinterpret_cast(this)->sin6_flowinfo == reinterpret_cast(&a)->sin6_flowinfo) + && (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 16) == 0) + && (reinterpret_cast(this)->sin6_scope_id == reinterpret_cast(&a)->sin6_scope_id)); break; default: - return (memcmp(this,&a,sizeof(InetAddress)) == 0); + return (memcmp(this, &a, sizeof(InetAddress)) == 0); } } return false; } -bool InetAddress::operator<(const InetAddress &a) const +bool InetAddress::operator<(const InetAddress& a) const { if (ss_family < a.ss_family) { return true; - } else if (ss_family == a.ss_family) { - switch(ss_family) { + } + else if (ss_family == a.ss_family) { + switch (ss_family) { case AF_INET: - if (reinterpret_cast(this)->sin_port < reinterpret_cast(&a)->sin_port) { + if (reinterpret_cast(this)->sin_port < reinterpret_cast(&a)->sin_port) { return true; - } else if (reinterpret_cast(this)->sin_port == reinterpret_cast(&a)->sin_port) { - if (reinterpret_cast(this)->sin_addr.s_addr < reinterpret_cast(&a)->sin_addr.s_addr) { + } + else if (reinterpret_cast(this)->sin_port == reinterpret_cast(&a)->sin_port) { + if (reinterpret_cast(this)->sin_addr.s_addr < reinterpret_cast(&a)->sin_addr.s_addr) { return true; } } break; case AF_INET6: - if (reinterpret_cast(this)->sin6_port < reinterpret_cast(&a)->sin6_port) { + if (reinterpret_cast(this)->sin6_port < reinterpret_cast(&a)->sin6_port) { return true; - } else if (reinterpret_cast(this)->sin6_port == reinterpret_cast(&a)->sin6_port) { - if (reinterpret_cast(this)->sin6_flowinfo < reinterpret_cast(&a)->sin6_flowinfo) { + } + else if (reinterpret_cast(this)->sin6_port == reinterpret_cast(&a)->sin6_port) { + if (reinterpret_cast(this)->sin6_flowinfo < reinterpret_cast(&a)->sin6_flowinfo) { return true; - } else if (reinterpret_cast(this)->sin6_flowinfo == reinterpret_cast(&a)->sin6_flowinfo) { - if (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr,reinterpret_cast(&a)->sin6_addr.s6_addr,16) < 0) { + } + else if (reinterpret_cast(this)->sin6_flowinfo == reinterpret_cast(&a)->sin6_flowinfo) { + if (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 16) < 0) { return true; - } else if (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr,reinterpret_cast(&a)->sin6_addr.s6_addr,16) == 0) { - if (reinterpret_cast(this)->sin6_scope_id < reinterpret_cast(&a)->sin6_scope_id) { + } + else if (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 16) == 0) { + if (reinterpret_cast(this)->sin6_scope_id < reinterpret_cast(&a)->sin6_scope_id) { return true; } } @@ -454,13 +463,13 @@ bool InetAddress::operator<(const InetAddress &a) const } break; default: - return (memcmp(this,&a,sizeof(InetAddress)) < 0); + return (memcmp(this, &a, sizeof(InetAddress)) < 0); } } return false; } -InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) +InetAddress InetAddress::makeIpv6LinkLocal(const MAC& mac) { struct sockaddr_in6 sin6; sin6.sin6_family = AF_INET6; @@ -484,10 +493,10 @@ InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) return InetAddress(sin6); } -InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) +InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid, uint64_t zeroTierAddress) { InetAddress r; - struct sockaddr_in6 *const sin6 = reinterpret_cast(&r); + struct sockaddr_in6* const sin6 = reinterpret_cast(&r); sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0xfd; sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 56); @@ -505,15 +514,15 @@ InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) sin6->sin6_addr.s6_addr[13] = (uint8_t)(zeroTierAddress >> 16); sin6->sin6_addr.s6_addr[14] = (uint8_t)(zeroTierAddress >> 8); sin6->sin6_addr.s6_addr[15] = (uint8_t)zeroTierAddress; - sin6->sin6_port = Utils::hton((uint16_t)88); // /88 includes 0xfd + network ID, discriminating by device ID below that + sin6->sin6_port = Utils::hton((uint16_t)88); // /88 includes 0xfd + network ID, discriminating by device ID below that return r; } -InetAddress InetAddress::makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress) +InetAddress InetAddress::makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress) { nwid ^= (nwid >> 32); InetAddress r; - struct sockaddr_in6 *const sin6 = reinterpret_cast(&r); + struct sockaddr_in6* const sin6 = reinterpret_cast(&r); sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0xfc; sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 24); @@ -530,4 +539,4 @@ InetAddress InetAddress::makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress) return r; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 7e2a15db0..4e0b89438 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -14,15 +14,15 @@ #ifndef ZT_INETADDRESS_HPP #define ZT_INETADDRESS_HPP +#include "../include/ZeroTierOne.h" +#include "Buffer.hpp" +#include "Constants.hpp" +#include "MAC.hpp" +#include "Utils.hpp" + +#include #include #include -#include - -#include "Constants.hpp" -#include "../include/ZeroTierOne.h" -#include "Utils.hpp" -#include "MAC.hpp" -#include "Buffer.hpp" namespace ZeroTier { @@ -39,8 +39,7 @@ namespace ZeroTier { * sockaddr_storage and used interchangeably. DO NOT change this by e.g. * adding non-static fields, since much code depends on this identity. */ -struct InetAddress : public sockaddr_storage -{ +struct InetAddress : public sockaddr_storage { /** * Loopback IPv4 address (no port) */ @@ -58,134 +57,177 @@ struct InetAddress : public sockaddr_storage * MUST remain that way or Path must be changed to reflect. Also be sure * to change ZT_INETADDRESS_MAX_SCOPE if the max changes. */ - enum IpScope - { - IP_SCOPE_NONE = 0, // NULL or not an IP address - IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other V4/V6 multicast IPs - IP_SCOPE_LOOPBACK = 2, // 127.0.0.1, ::1, etc. - IP_SCOPE_PSEUDOPRIVATE = 3, // 28.x.x.x, etc. -- unofficially unrouted IPv4 blocks often "bogarted" - IP_SCOPE_GLOBAL = 4, // globally routable IP address (all others) - IP_SCOPE_LINK_LOCAL = 5, // 169.254.x.x, IPv6 LL - IP_SCOPE_SHARED = 6, // currently unused, formerly used for carrier-grade NAT ranges - IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc. + enum IpScope { + IP_SCOPE_NONE = 0, // NULL or not an IP address + IP_SCOPE_MULTICAST = 1, // 224.0.0.0 and other V4/V6 multicast IPs + IP_SCOPE_LOOPBACK = 2, // 127.0.0.1, ::1, etc. + IP_SCOPE_PSEUDOPRIVATE = 3, // 28.x.x.x, etc. -- unofficially unrouted IPv4 blocks often "bogarted" + IP_SCOPE_GLOBAL = 4, // globally routable IP address (all others) + IP_SCOPE_LINK_LOCAL = 5, // 169.254.x.x, IPv6 LL + IP_SCOPE_SHARED = 6, // currently unused, formerly used for carrier-grade NAT ranges + IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc. }; // Can be used with the unordered maps and sets in c++11. We don't use C++11 in the core // but this is safe to put here. - struct Hasher - { - inline std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); } + struct Hasher { + inline std::size_t operator()(const InetAddress& a) const + { + return (std::size_t)a.hashCode(); + } }; - InetAddress() { memset(this,0,sizeof(InetAddress)); } - InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); } - InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); } - InetAddress(const struct sockaddr_storage &ss) { *this = ss; } - InetAddress(const struct sockaddr_storage *ss) { *this = ss; } - InetAddress(const struct sockaddr &sa) { *this = sa; } - InetAddress(const struct sockaddr *sa) { *this = sa; } - InetAddress(const struct sockaddr_in &sa) { *this = sa; } - InetAddress(const struct sockaddr_in *sa) { *this = sa; } - InetAddress(const struct sockaddr_in6 &sa) { *this = sa; } - InetAddress(const struct sockaddr_in6 *sa) { *this = sa; } - InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); } - InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); } - InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); } + InetAddress() + { + memset(this, 0, sizeof(InetAddress)); + } + InetAddress(const InetAddress& a) + { + memcpy(this, &a, sizeof(InetAddress)); + } + InetAddress(const InetAddress* a) + { + memcpy(this, a, sizeof(InetAddress)); + } + InetAddress(const struct sockaddr_storage& ss) + { + *this = ss; + } + InetAddress(const struct sockaddr_storage* ss) + { + *this = ss; + } + InetAddress(const struct sockaddr& sa) + { + *this = sa; + } + InetAddress(const struct sockaddr* sa) + { + *this = sa; + } + InetAddress(const struct sockaddr_in& sa) + { + *this = sa; + } + InetAddress(const struct sockaddr_in* sa) + { + *this = sa; + } + InetAddress(const struct sockaddr_in6& sa) + { + *this = sa; + } + InetAddress(const struct sockaddr_in6* sa) + { + *this = sa; + } + InetAddress(const void* ipBytes, unsigned int ipLen, unsigned int port) + { + this->set(ipBytes, ipLen, port); + } + InetAddress(const uint32_t ipv4, unsigned int port) + { + this->set(&ipv4, 4, port); + } + InetAddress(const char* ipSlashPort) + { + this->fromString(ipSlashPort); + } - inline InetAddress &operator=(const InetAddress &a) + inline InetAddress& operator=(const InetAddress& a) { if (&a != this) { - memcpy(this,&a,sizeof(InetAddress)); + memcpy(this, &a, sizeof(InetAddress)); } return *this; } - inline InetAddress &operator=(const InetAddress *a) + inline InetAddress& operator=(const InetAddress* a) { if (a != this) { - memcpy(this,a,sizeof(InetAddress)); + memcpy(this, a, sizeof(InetAddress)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_storage &ss) + inline InetAddress& operator=(const struct sockaddr_storage& ss) { - if (reinterpret_cast(&ss) != this) { - memcpy(this,&ss,sizeof(InetAddress)); + if (reinterpret_cast(&ss) != this) { + memcpy(this, &ss, sizeof(InetAddress)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_storage *ss) + inline InetAddress& operator=(const struct sockaddr_storage* ss) { - if (reinterpret_cast(ss) != this) { - memcpy(this,ss,sizeof(InetAddress)); + if (reinterpret_cast(ss) != this) { + memcpy(this, ss, sizeof(InetAddress)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_in &sa) + inline InetAddress& operator=(const struct sockaddr_in& sa) { - if (reinterpret_cast(&sa) != this) { - memset(this,0,sizeof(InetAddress)); - memcpy(this,&sa,sizeof(struct sockaddr_in)); + if (reinterpret_cast(&sa) != this) { + memset(this, 0, sizeof(InetAddress)); + memcpy(this, &sa, sizeof(struct sockaddr_in)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_in *sa) + inline InetAddress& operator=(const struct sockaddr_in* sa) { - if (reinterpret_cast(sa) != this) { - memset(this,0,sizeof(InetAddress)); - memcpy(this,sa,sizeof(struct sockaddr_in)); + if (reinterpret_cast(sa) != this) { + memset(this, 0, sizeof(InetAddress)); + memcpy(this, sa, sizeof(struct sockaddr_in)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_in6 &sa) + inline InetAddress& operator=(const struct sockaddr_in6& sa) { - if (reinterpret_cast(&sa) != this) { - memset(this,0,sizeof(InetAddress)); - memcpy(this,&sa,sizeof(struct sockaddr_in6)); + if (reinterpret_cast(&sa) != this) { + memset(this, 0, sizeof(InetAddress)); + memcpy(this, &sa, sizeof(struct sockaddr_in6)); } return *this; } - inline InetAddress &operator=(const struct sockaddr_in6 *sa) + inline InetAddress& operator=(const struct sockaddr_in6* sa) { - if (reinterpret_cast(sa) != this) { - memset(this,0,sizeof(InetAddress)); - memcpy(this,sa,sizeof(struct sockaddr_in6)); + if (reinterpret_cast(sa) != this) { + memset(this, 0, sizeof(InetAddress)); + memcpy(this, sa, sizeof(struct sockaddr_in6)); } return *this; } - inline InetAddress &operator=(const struct sockaddr &sa) + inline InetAddress& operator=(const struct sockaddr& sa) { - if (reinterpret_cast(&sa) != this) { - memset(this,0,sizeof(InetAddress)); - switch(sa.sa_family) { + if (reinterpret_cast(&sa) != this) { + memset(this, 0, sizeof(InetAddress)); + switch (sa.sa_family) { case AF_INET: - memcpy(this,&sa,sizeof(struct sockaddr_in)); + memcpy(this, &sa, sizeof(struct sockaddr_in)); break; case AF_INET6: - memcpy(this,&sa,sizeof(struct sockaddr_in6)); + memcpy(this, &sa, sizeof(struct sockaddr_in6)); break; } } return *this; } - inline InetAddress &operator=(const struct sockaddr *sa) + inline InetAddress& operator=(const struct sockaddr* sa) { - if (reinterpret_cast(sa) != this) { - memset(this,0,sizeof(InetAddress)); - switch(sa->sa_family) { + if (reinterpret_cast(sa) != this) { + memset(this, 0, sizeof(InetAddress)); + switch (sa->sa_family) { case AF_INET: - memcpy(this,sa,sizeof(struct sockaddr_in)); + memcpy(this, sa, sizeof(struct sockaddr_in)); break; case AF_INET6: - memcpy(this,sa,sizeof(struct sockaddr_in6)); + memcpy(this, sa, sizeof(struct sockaddr_in6)); break; } } @@ -204,7 +246,7 @@ struct InetAddress : public sockaddr_storage * @param ipLen Length of IP address: 4 or 16 * @param port Port number or 0 for none */ - void set(const void *ipBytes,unsigned int ipLen,unsigned int port); + void set(const void* ipBytes, unsigned int ipLen, unsigned int port); /** * Set the port component @@ -213,12 +255,12 @@ struct InetAddress : public sockaddr_storage */ inline void setPort(unsigned int port) { - switch(ss_family) { + switch (ss_family) { case AF_INET: - reinterpret_cast(this)->sin_port = Utils::hton((uint16_t)port); + reinterpret_cast(this)->sin_port = Utils::hton((uint16_t)port); break; case AF_INET6: - reinterpret_cast(this)->sin6_port = Utils::hton((uint16_t)port); + reinterpret_cast(this)->sin6_port = Utils::hton((uint16_t)port); break; } } @@ -228,17 +270,17 @@ struct InetAddress : public sockaddr_storage */ inline bool isDefaultRoute() const { - switch(ss_family) { + switch (ss_family) { case AF_INET: - return ( (reinterpret_cast(this)->sin_addr.s_addr == 0) && (reinterpret_cast(this)->sin_port == 0) ); + return ((reinterpret_cast(this)->sin_addr.s_addr == 0) && (reinterpret_cast(this)->sin_port == 0)); case AF_INET6: - const uint8_t *ipb = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); - for(int i=0;i<16;++i) { + const uint8_t* ipb = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + for (int i = 0; i < 16; ++i) { if (ipb[i]) { return false; } } - return (reinterpret_cast(this)->sin6_port == 0); + return (reinterpret_cast(this)->sin6_port == 0); } return false; } @@ -246,29 +288,29 @@ struct InetAddress : public sockaddr_storage /** * @return ASCII IP/port format representation */ - char *toString(char buf[64]) const; + char* toString(char buf[64]) const; /** * @return IP portion only, in ASCII string format */ - char *toIpString(char buf[64]) const; + char* toIpString(char buf[64]) const; /** * @param ipSlashPort IP/port (port is optional, will be 0 if not included) * @return True if address appeared to be valid */ - bool fromString(const char *ipSlashPort); + bool fromString(const char* ipSlashPort); /** * @return Port or 0 if no port component defined */ inline unsigned int port() const { - switch(ss_family) { + switch (ss_family) { case AF_INET: - return Utils::ntoh((uint16_t)(reinterpret_cast(this)->sin_port)); + return Utils::ntoh((uint16_t)(reinterpret_cast(this)->sin_port)); case AF_INET6: - return Utils::ntoh((uint16_t)(reinterpret_cast(this)->sin6_port)); + return Utils::ntoh((uint16_t)(reinterpret_cast(this)->sin6_port)); default: return 0; } @@ -283,7 +325,10 @@ struct InetAddress : public sockaddr_storage * * @return Netmask bits */ - inline unsigned int netmaskBits() const { return port(); } + inline unsigned int netmaskBits() const + { + return port(); + } /** * @return True if netmask bits is valid for the address type @@ -291,7 +336,7 @@ struct InetAddress : public sockaddr_storage inline bool netmaskBitsValid() const { const unsigned int n = port(); - switch(ss_family) { + switch (ss_family) { case AF_INET: return (n <= 32); case AF_INET6: @@ -308,7 +353,10 @@ struct InetAddress : public sockaddr_storage * * @return Gateway metric */ - inline unsigned int metric() const { return port(); } + inline unsigned int metric() const + { + return port(); + } /** * Construct a full netmask as an InetAddress @@ -340,7 +388,7 @@ struct InetAddress : public sockaddr_storage * @param addr Address to check * @return True if this IPv6 prefix matches the prefix of a given IPv6 address */ - bool isEqualPrefix(const InetAddress &addr) const; + bool isEqualPrefix(const InetAddress& addr) const; /** * Test whether this IP/netmask contains this address @@ -348,28 +396,34 @@ struct InetAddress : public sockaddr_storage * @param addr Address to check * @return True if this IP/netmask (route) contains this address */ - bool containsAddress(const InetAddress &addr) const; + bool containsAddress(const InetAddress& addr) const; /** * @return True if this is an IPv4 address */ - inline bool isV4() const { return (ss_family == AF_INET); } + inline bool isV4() const + { + return (ss_family == AF_INET); + } /** * @return True if this is an IPv6 address */ - inline bool isV6() const { return (ss_family == AF_INET6); } + inline bool isV6() const + { + return (ss_family == AF_INET6); + } /** * @return pointer to raw address bytes or NULL if not available */ - inline const void *rawIpData() const + inline const void* rawIpData() const { - switch(ss_family) { + switch (ss_family) { case AF_INET: - return (const void *)&(reinterpret_cast(this)->sin_addr.s_addr); + return (const void*)&(reinterpret_cast(this)->sin_addr.s_addr); case AF_INET6: - return (const void *)(reinterpret_cast(this)->sin6_addr.s6_addr); + return (const void*)(reinterpret_cast(this)->sin6_addr.s6_addr); default: return 0; } @@ -381,14 +435,14 @@ struct InetAddress : public sockaddr_storage inline InetAddress ipOnly() const { InetAddress r; - switch(ss_family) { + switch (ss_family) { case AF_INET: r.ss_family = AF_INET; - reinterpret_cast(&r)->sin_addr.s_addr = reinterpret_cast(this)->sin_addr.s_addr; + reinterpret_cast(&r)->sin_addr.s_addr = reinterpret_cast(this)->sin_addr.s_addr; break; case AF_INET6: r.ss_family = AF_INET6; - memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr,reinterpret_cast(this)->sin6_addr.s6_addr,16); + memcpy(reinterpret_cast(&r)->sin6_addr.s6_addr, reinterpret_cast(this)->sin6_addr.s6_addr, 16); break; } return r; @@ -400,16 +454,16 @@ struct InetAddress : public sockaddr_storage * @param a InetAddress to compare again * @return True if only IP portions are equal (false for non-IP or null addresses) */ - inline bool ipsEqual(const InetAddress &a) const + inline bool ipsEqual(const InetAddress& a) const { if (ss_family == a.ss_family) { if (ss_family == AF_INET) { - return (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr); + return (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr); } if (ss_family == AF_INET6) { - return (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr,reinterpret_cast(&a)->sin6_addr.s6_addr,16) == 0); + return (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 16) == 0); } - return (memcmp(this,&a,sizeof(InetAddress)) == 0); + return (memcmp(this, &a, sizeof(InetAddress)) == 0); } return false; } @@ -422,16 +476,16 @@ struct InetAddress : public sockaddr_storage * @param a InetAddress to compare again * @return True if only IP portions are equal (false for non-IP or null addresses) */ - inline bool ipsEqual2(const InetAddress &a) const + inline bool ipsEqual2(const InetAddress& a) const { if (ss_family == a.ss_family) { if (ss_family == AF_INET) { - return (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr); + return (reinterpret_cast(this)->sin_addr.s_addr == reinterpret_cast(&a)->sin_addr.s_addr); } if (ss_family == AF_INET6) { - return (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 8) == 0); + return (memcmp(reinterpret_cast(this)->sin6_addr.s6_addr, reinterpret_cast(&a)->sin6_addr.s6_addr, 8) == 0); } - return (memcmp(this,&a,sizeof(InetAddress)) == 0); + return (memcmp(this, &a, sizeof(InetAddress)) == 0); } return false; } @@ -439,19 +493,21 @@ struct InetAddress : public sockaddr_storage inline unsigned long hashCode() const { if (ss_family == AF_INET) { - return ((unsigned long)reinterpret_cast(this)->sin_addr.s_addr + (unsigned long)reinterpret_cast(this)->sin_port); - } else if (ss_family == AF_INET6) { - unsigned long tmp = reinterpret_cast(this)->sin6_port; - const uint8_t *a = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); - for(long i=0;i<16;++i) { - reinterpret_cast(&tmp)[i % sizeof(tmp)] ^= a[i]; + return ((unsigned long)reinterpret_cast(this)->sin_addr.s_addr + (unsigned long)reinterpret_cast(this)->sin_port); + } + else if (ss_family == AF_INET6) { + unsigned long tmp = reinterpret_cast(this)->sin6_port; + const uint8_t* a = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + for (long i = 0; i < 16; ++i) { + reinterpret_cast(&tmp)[i % sizeof(tmp)] ^= a[i]; } return tmp; - } else { - unsigned long tmp = reinterpret_cast(this)->sin6_port; - const uint8_t *a = reinterpret_cast(this); - for(long i=0;i<(long)sizeof(InetAddress);++i) { - reinterpret_cast(&tmp)[i % sizeof(tmp)] ^= a[i]; + } + else { + unsigned long tmp = reinterpret_cast(this)->sin6_port; + const uint8_t* a = reinterpret_cast(this); + for (long i = 0; i < (long)sizeof(InetAddress); ++i) { + reinterpret_cast(&tmp)[i % sizeof(tmp)] ^= a[i]; } return tmp; } @@ -460,7 +516,10 @@ struct InetAddress : public sockaddr_storage /** * Set to null/zero */ - inline void zero() { memset(this,0,sizeof(InetAddress)); } + inline void zero() + { + memset(this, 0, sizeof(InetAddress)); + } /** * Check whether this is a network/route rather than an IP assignment @@ -474,18 +533,18 @@ struct InetAddress : public sockaddr_storage /** * Find the total number of prefix bits that match between this IP and another - * + * * @param b Second IP to compare with * @return Number of matching prefix bits or 0 if none match or IPs are of different families (e.g. v4 and v6) */ - inline unsigned int matchingPrefixBits(const InetAddress &b) const + inline unsigned int matchingPrefixBits(const InetAddress& b) const { unsigned int c = 0; if (ss_family == b.ss_family) { - switch(ss_family) { + switch (ss_family) { case AF_INET: { - uint32_t ip0 = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); - uint32_t ip1 = Utils::ntoh((uint32_t)reinterpret_cast(&b)->sin_addr.s_addr); + uint32_t ip0 = Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr); + uint32_t ip1 = Utils::ntoh((uint32_t)reinterpret_cast(&b)->sin_addr.s_addr); while ((ip0 >> 31) == (ip1 >> 31)) { ip0 <<= 1; ip1 <<= 1; @@ -493,14 +552,15 @@ struct InetAddress : public sockaddr_storage break; } } - } break; + } break; case AF_INET6: { - const uint8_t *ip0 = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); - const uint8_t *ip1 = reinterpret_cast(reinterpret_cast(&b)->sin6_addr.s6_addr); - for(unsigned int i=0;i<16;++i) { + const uint8_t* ip0 = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + const uint8_t* ip1 = reinterpret_cast(reinterpret_cast(&b)->sin6_addr.s6_addr); + for (unsigned int i = 0; i < 16; ++i) { if (ip0[i] == ip1[i]) { c += 8; - } else { + } + else { uint8_t ip0b = ip0[i]; uint8_t ip1b = ip1[i]; uint8_t bit = 0x80; @@ -514,7 +574,7 @@ struct InetAddress : public sockaddr_storage break; } } - } break; + } break; } } return c; @@ -526,13 +586,13 @@ struct InetAddress : public sockaddr_storage inline unsigned long rateGateHash() const { unsigned long h = 0; - switch(ss_family) { + switch (ss_family) { case AF_INET: - h = (Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr) & 0xffffff00) >> 8; + h = (Utils::ntoh((uint32_t)reinterpret_cast(this)->sin_addr.s_addr) & 0xffffff00) >> 8; h ^= (h >> 14); break; case AF_INET6: { - const uint8_t *ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); + const uint8_t* ip = reinterpret_cast(reinterpret_cast(this)->sin6_addr.s6_addr); h = ((unsigned long)ip[0]); h <<= 1; h += ((unsigned long)ip[1]); @@ -544,7 +604,7 @@ struct InetAddress : public sockaddr_storage h += ((unsigned long)ip[4]); h <<= 1; h += ((unsigned long)ip[5]); - } break; + } break; } return (h & 0x3fff); } @@ -552,23 +612,25 @@ struct InetAddress : public sockaddr_storage /** * @return True if address family is non-zero */ - inline operator bool() const { return (ss_family != 0); } + inline operator bool() const + { + return (ss_family != 0); + } - template - inline void serialize(Buffer &b) const + template inline void serialize(Buffer& b) const { // This is used in the protocol and must be the same as describe in places // like VERB_HELLO in Packet.hpp. - switch(ss_family) { + switch (ss_family) { case AF_INET: b.append((uint8_t)0x04); - b.append(&(reinterpret_cast(this)->sin_addr.s_addr),4); - b.append((uint16_t)port()); // just in case sin_port != uint16_t + b.append(&(reinterpret_cast(this)->sin_addr.s_addr), 4); + b.append((uint16_t)port()); // just in case sin_port != uint16_t return; case AF_INET6: b.append((uint8_t)0x06); - b.append(reinterpret_cast(this)->sin6_addr.s6_addr,16); - b.append((uint16_t)port()); // just in case sin_port != uint16_t + b.append(reinterpret_cast(this)->sin6_addr.s6_addr, 16); + b.append((uint16_t)port()); // just in case sin_port != uint16_t return; default: b.append((uint8_t)0); @@ -576,12 +638,11 @@ struct InetAddress : public sockaddr_storage } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { - memset(this,0,sizeof(InetAddress)); + memset(this, 0, sizeof(InetAddress)); unsigned int p = startAt; - switch(b[p++]) { + switch (b[p++]) { case 0: return 1; case 0x01: @@ -593,19 +654,19 @@ struct InetAddress : public sockaddr_storage case 0x03: // TODO: Other address types (but accept for forward compatibility) // These could be extended/optional things like AF_UNIX, LTE Direct, shared memory, etc. - return (unsigned int)(b.template at(p) + 3); // other addresses begin with 16-bit non-inclusive length + return (unsigned int)(b.template at(p) + 3); // other addresses begin with 16-bit non-inclusive length case 0x04: ss_family = AF_INET; - memcpy(&(reinterpret_cast(this)->sin_addr.s_addr),b.field(p,4),4); + memcpy(&(reinterpret_cast(this)->sin_addr.s_addr), b.field(p, 4), 4); p += 4; - reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); + reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; break; case 0x06: ss_family = AF_INET6; - memcpy(reinterpret_cast(this)->sin6_addr.s6_addr,b.field(p,16),16); + memcpy(reinterpret_cast(this)->sin6_addr.s6_addr, b.field(p, 16), 16); p += 16; - reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); + reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; break; default: @@ -614,18 +675,30 @@ struct InetAddress : public sockaddr_storage return (p - startAt); } - bool operator==(const InetAddress &a) const; - bool operator<(const InetAddress &a) const; - inline bool operator!=(const InetAddress &a) const { return !(*this == a); } - inline bool operator>(const InetAddress &a) const { return (a < *this); } - inline bool operator<=(const InetAddress &a) const { return !(a < *this); } - inline bool operator>=(const InetAddress &a) const { return !(*this < a); } + bool operator==(const InetAddress& a) const; + bool operator<(const InetAddress& a) const; + inline bool operator!=(const InetAddress& a) const + { + return ! (*this == a); + } + inline bool operator>(const InetAddress& a) const + { + return (a < *this); + } + inline bool operator<=(const InetAddress& a) const + { + return ! (a < *this); + } + inline bool operator>=(const InetAddress& a) const + { + return ! (*this < a); + } /** * @param mac MAC address seed * @return IPv6 link-local address */ - static InetAddress makeIpv6LinkLocal(const MAC &mac); + static InetAddress makeIpv6LinkLocal(const MAC& mac); /** * Compute private IPv6 unicast address from network ID and ZeroTier address @@ -668,14 +741,14 @@ struct InetAddress : public sockaddr_storage * @param zeroTierAddress 40-bit device address (in least significant 40 bits, highest 24 bits ignored) * @return IPv6 private unicast address with /88 netmask */ - static InetAddress makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress); + static InetAddress makeIpv6rfc4193(uint64_t nwid, uint64_t zeroTierAddress); /** * Compute a private IPv6 "6plane" unicast address from network ID and ZeroTier address */ - static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress); + static InetAddress makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress); }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/MAC.hpp b/node/MAC.hpp index 4520adc01..9cf8454da 100644 --- a/node/MAC.hpp +++ b/node/MAC.hpp @@ -14,64 +14,81 @@ #ifndef ZT_MAC_HPP #define ZT_MAC_HPP -#include -#include -#include - -#include "Constants.hpp" -#include "Utils.hpp" #include "Address.hpp" #include "Buffer.hpp" +#include "Constants.hpp" +#include "Utils.hpp" + +#include +#include +#include namespace ZeroTier { /** * 48-byte Ethernet MAC address */ -class MAC -{ -public: - MAC() : _m(0ULL) {} - MAC(const MAC &m) : _m(m._m) {} +class MAC { + public: + MAC() : _m(0ULL) + { + } + MAC(const MAC& m) : _m(m._m) + { + } - MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) : - _m( ((((uint64_t)a) & 0xffULL) << 40) | - ((((uint64_t)b) & 0xffULL) << 32) | - ((((uint64_t)c) & 0xffULL) << 24) | - ((((uint64_t)d) & 0xffULL) << 16) | - ((((uint64_t)e) & 0xffULL) << 8) | - (((uint64_t)f) & 0xffULL) ) {} - MAC(const void *bits,unsigned int len) { setTo(bits,len); } - MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); } - MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {} + MAC(const unsigned char a, const unsigned char b, const unsigned char c, const unsigned char d, const unsigned char e, const unsigned char f) + : _m(((((uint64_t)a) & 0xffULL) << 40) | ((((uint64_t)b) & 0xffULL) << 32) | ((((uint64_t)c) & 0xffULL) << 24) | ((((uint64_t)d) & 0xffULL) << 16) | ((((uint64_t)e) & 0xffULL) << 8) | (((uint64_t)f) & 0xffULL)) + { + } + MAC(const void* bits, unsigned int len) + { + setTo(bits, len); + } + MAC(const Address& ztaddr, uint64_t nwid) + { + fromAddress(ztaddr, nwid); + } + MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) + { + } /** * @return MAC in 64-bit integer */ - inline uint64_t toInt() const { return _m; } + inline uint64_t toInt() const + { + return _m; + } /** * Set MAC to zero */ - inline void zero() { _m = 0ULL; } + inline void zero() + { + _m = 0ULL; + } /** * @return True if MAC is non-zero */ - inline operator bool() const { return (_m != 0ULL); } + inline operator bool() const + { + return (_m != 0ULL); + } /** * @param bits Raw MAC in big-endian byte order * @param len Length, must be >= 6 or result is zero */ - inline void setTo(const void *bits,unsigned int len) + inline void setTo(const void* bits, unsigned int len) { if (len < 6) { _m = 0ULL; return; } - const unsigned char *b = (const unsigned char *)bits; - _m = ((((uint64_t)*b) & 0xff) << 40); + const unsigned char* b = (const unsigned char*)bits; + _m = ((((uint64_t)*b) & 0xff) << 40); ++b; _m |= ((((uint64_t)*b) & 0xff) << 32); ++b; @@ -88,12 +105,12 @@ public: * @param buf Destination buffer for MAC in big-endian byte order * @param len Length of buffer, must be >= 6 or nothing is copied */ - inline void copyTo(void *buf,unsigned int len) const + inline void copyTo(void* buf, unsigned int len) const { if (len < 6) { return; } - unsigned char *b = (unsigned char *)buf; + unsigned char* b = (unsigned char*)buf; *(b++) = (unsigned char)((_m >> 40) & 0xff); *(b++) = (unsigned char)((_m >> 32) & 0xff); *(b++) = (unsigned char)((_m >> 24) & 0xff); @@ -107,10 +124,9 @@ public: * * @param b Buffer to append to */ - template - inline void appendTo(Buffer &b) const + template inline void appendTo(Buffer& b) const { - unsigned char *p = (unsigned char *)b.appendField(6); + unsigned char* p = (unsigned char*)b.appendField(6); *(p++) = (unsigned char)((_m >> 40) & 0xff); *(p++) = (unsigned char)((_m >> 32) & 0xff); *(p++) = (unsigned char)((_m >> 24) & 0xff); @@ -122,17 +138,26 @@ public: /** * @return True if this is broadcast (all 0xff) */ - inline bool isBroadcast() const { return (_m == 0xffffffffffffULL); } + inline bool isBroadcast() const + { + return (_m == 0xffffffffffffULL); + } /** * @return True if this is a multicast MAC */ - inline bool isMulticast() const { return ((_m & 0x010000000000ULL) != 0ULL); } + inline bool isMulticast() const + { + return ((_m & 0x010000000000ULL) != 0ULL); + } /** * @param True if this is a locally-administered MAC */ - inline bool isLocallyAdministered() const { return ((_m & 0x020000000000ULL) != 0ULL); } + inline bool isLocallyAdministered() const + { + return ((_m & 0x020000000000ULL) != 0ULL); + } /** * Set this MAC to a MAC derived from an address and a network ID @@ -140,10 +165,10 @@ public: * @param ztaddr ZeroTier address * @param nwid 64-bit network ID */ - inline void fromAddress(const Address &ztaddr,uint64_t nwid) + inline void fromAddress(const Address& ztaddr, uint64_t nwid) { uint64_t m = ((uint64_t)firstOctetForNetwork(nwid)) << 40; - m |= ztaddr.toInt(); // a is 40 bits + m |= ztaddr.toInt(); // a is 40 bits m ^= ((nwid >> 8) & 0xff) << 32; m ^= ((nwid >> 16) & 0xff) << 24; m ^= ((nwid >> 24) & 0xff) << 16; @@ -161,8 +186,8 @@ public: */ inline Address toAddress(uint64_t nwid) const { - uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address - a ^= ((nwid >> 8) & 0xff) << 32; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it + uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address + a ^= ((nwid >> 8) & 0xff) << 32; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it a ^= ((nwid >> 16) & 0xff) << 24; a ^= ((nwid >> 24) & 0xff) << 16; a ^= ((nwid >> 32) & 0xff) << 8; @@ -176,24 +201,33 @@ public: */ static inline unsigned char firstOctetForNetwork(uint64_t nwid) { - unsigned char a = ((unsigned char)(nwid & 0xfe) | 0x02); // locally administered, not multicast, from LSB of network ID - return ((a == 0x52) ? 0x32 : a); // blacklist 0x52 since it's used by KVM, libvirt, and other popular virtualization engines... seems de-facto standard on Linux + unsigned char a = ((unsigned char)(nwid & 0xfe) | 0x02); // locally administered, not multicast, from LSB of network ID + return ((a == 0x52) ? 0x32 : a); // blacklist 0x52 since it's used by KVM, libvirt, and other popular virtualization engines... seems de-facto standard on Linux } /** * @param i Value from 0 to 5 (inclusive) * @return Byte at said position (address interpreted in big-endian order) */ - inline unsigned char operator[](unsigned int i) const { return (unsigned char)((_m >> (40 - (i * 8))) & 0xff); } + inline unsigned char operator[](unsigned int i) const + { + return (unsigned char)((_m >> (40 - (i * 8))) & 0xff); + } /** * @return 6, which is the number of bytes in a MAC, for container compliance */ - inline unsigned int size() const { return 6; } + inline unsigned int size() const + { + return 6; + } - inline unsigned long hashCode() const { return (unsigned long)_m; } + inline unsigned long hashCode() const + { + return (unsigned long)_m; + } - inline char *toString(char buf[18]) const + inline char* toString(char buf[18]) const { buf[0] = Utils::HEXCHARS[(_m >> 44) & 0xf]; buf[1] = Utils::HEXCHARS[(_m >> 40) & 0xf]; @@ -216,28 +250,46 @@ public: return buf; } - inline MAC &operator=(const MAC &m) + inline MAC& operator=(const MAC& m) { _m = m._m; return *this; } - inline MAC &operator=(const uint64_t m) + inline MAC& operator=(const uint64_t m) { _m = m; return *this; } - inline bool operator==(const MAC &m) const { return (_m == m._m); } - inline bool operator!=(const MAC &m) const { return (_m != m._m); } - inline bool operator<(const MAC &m) const { return (_m < m._m); } - inline bool operator<=(const MAC &m) const { return (_m <= m._m); } - inline bool operator>(const MAC &m) const { return (_m > m._m); } - inline bool operator>=(const MAC &m) const { return (_m >= m._m); } + inline bool operator==(const MAC& m) const + { + return (_m == m._m); + } + inline bool operator!=(const MAC& m) const + { + return (_m != m._m); + } + inline bool operator<(const MAC& m) const + { + return (_m < m._m); + } + inline bool operator<=(const MAC& m) const + { + return (_m <= m._m); + } + inline bool operator>(const MAC& m) const + { + return (_m > m._m); + } + inline bool operator>=(const MAC& m) const + { + return (_m >= m._m); + } -private: + private: uint64_t _m; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Membership.cpp b/node/Membership.cpp index 0c5d9cc7a..f09755ffe 100644 --- a/node/Membership.cpp +++ b/node/Membership.cpp @@ -11,47 +11,41 @@ */ /****/ -#include - #include "Membership.hpp" -#include "RuntimeEnvironment.hpp" -#include "Peer.hpp" -#include "Topology.hpp" -#include "Switch.hpp" -#include "Packet.hpp" + #include "Node.hpp" +#include "Packet.hpp" +#include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" #include "Trace.hpp" +#include + namespace ZeroTier { -Membership::Membership() : - _lastUpdatedMulticast(0), - _comRevocationThreshold(0), - _lastPushedCredentials(0), - _revocations(4), - _remoteTags(4), - _remoteCaps(4), - _remoteCoos(4) +Membership::Membership() : _lastUpdatedMulticast(0), _comRevocationThreshold(0), _lastPushedCredentials(0), _revocations(4), _remoteTags(4), _remoteCaps(4), _remoteCoos(4) { } -void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const int64_t now,const Address &peerAddress,const NetworkConfig &nconf) +void Membership::pushCredentials(const RuntimeEnvironment* RR, void* tPtr, const int64_t now, const Address& peerAddress, const NetworkConfig& nconf) { - const Capability *sendCaps[ZT_MAX_NETWORK_CAPABILITIES]; + const Capability* sendCaps[ZT_MAX_NETWORK_CAPABILITIES]; unsigned int sendCapCount = 0; - for(unsigned int c=0;cidentity.address(),Packet::VERB_NETWORK_CREDENTIALS); + while ((capPtr < sendCapCount) || (tagPtr < sendTagCount) || (cooPtr < sendCooCount) || (sendCom)) { + Packet outp(peerAddress, RR->identity.address(), Packet::VERB_NETWORK_CREDENTIALS); if (sendCom) { sendCom = false; @@ -71,20 +65,20 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i const unsigned int capCountAt = outp.size(); outp.addSize(2); unsigned int thisPacketCapCount = 0; - while ((capPtr < sendCapCount)&&((outp.size() + sizeof(Capability) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { + while ((capPtr < sendCapCount) && ((outp.size() + sizeof(Capability) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { sendCaps[capPtr++]->serialize(outp); ++thisPacketCapCount; } - outp.setAt(capCountAt,(uint16_t)thisPacketCapCount); + outp.setAt(capCountAt, (uint16_t)thisPacketCapCount); const unsigned int tagCountAt = outp.size(); outp.addSize(2); unsigned int thisPacketTagCount = 0; - while ((tagPtr < sendTagCount)&&((outp.size() + sizeof(Tag) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { + while ((tagPtr < sendTagCount) && ((outp.size() + sizeof(Tag) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { sendTags[tagPtr++]->serialize(outp); ++thisPacketTagCount; } - outp.setAt(tagCountAt,(uint16_t)thisPacketTagCount); + outp.setAt(tagCountAt, (uint16_t)thisPacketTagCount); // No revocations, these propagate differently outp.append((uint16_t)0); @@ -92,43 +86,43 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i const unsigned int cooCountAt = outp.size(); outp.addSize(2); unsigned int thisPacketCooCount = 0; - while ((cooPtr < sendCooCount)&&((outp.size() + sizeof(CertificateOfOwnership) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { + while ((cooPtr < sendCooCount) && ((outp.size() + sizeof(CertificateOfOwnership) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { sendCoos[cooPtr++]->serialize(outp); ++thisPacketCooCount; } - outp.setAt(cooCountAt,(uint16_t)thisPacketCooCount); + outp.setAt(cooCountAt, (uint16_t)thisPacketCooCount); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); Metrics::pkt_network_credentials_out++; } _lastPushedCredentials = now; } -Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com) +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const CertificateOfMembership& com) { const int64_t newts = com.timestamp(); if (newts <= _comRevocationThreshold) { - RR->t->credentialRejected(tPtr,com,"revoked"); + RR->t->credentialRejected(tPtr, com, "revoked"); return ADD_REJECTED; } const int64_t oldts = _com.timestamp(); if (newts < oldts) { - RR->t->credentialRejected(tPtr,com,"old"); + RR->t->credentialRejected(tPtr, com, "old"); return ADD_REJECTED; } if (_com == com) { return ADD_ACCEPTED_REDUNDANT; } - switch(com.verify(RR,tPtr)) { + switch (com.verify(RR, tPtr)) { default: - RR->t->credentialRejected(tPtr,com,"invalid"); + RR->t->credentialRejected(tPtr, com, "invalid"); return ADD_REJECTED; case 0: - //printf("%.16llx %.10llx replacing COM %lld with %lld\n", com.networkId(), com.issuedTo().toInt(), _com.timestamp(), com.timestamp()); fflush(stdout); + // printf("%.16llx %.10llx replacing COM %lld with %lld\n", com.networkId(), com.issuedTo().toInt(), _com.timestamp(), com.timestamp()); fflush(stdout); _com = com; return ADD_ACCEPTED_NEW; case 1: @@ -137,13 +131,13 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme } // Template out addCredential() for many cred types to avoid copypasta -template -static Membership::AddCredentialResult _addCredImpl(Hashtable &remoteCreds,const Hashtable &revocations,const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const C &cred) +template +static Membership::AddCredentialResult _addCredImpl(Hashtable& remoteCreds, const Hashtable& revocations, const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const C& cred) { - C *rc = remoteCreds.get(cred.id()); + C* rc = remoteCreds.get(cred.id()); if (rc) { if (rc->timestamp() > cred.timestamp()) { - RR->t->credentialRejected(tPtr,cred,"old"); + RR->t->credentialRejected(tPtr, cred, "old"); return Membership::ADD_REJECTED; } if (*rc == cred) { @@ -151,18 +145,18 @@ static Membership::AddCredentialResult _addCredImpl(Hashtable &remot } } - const int64_t *const rt = revocations.get(Membership::credentialKey(C::credentialType(),cred.id())); - if ((rt)&&(*rt >= cred.timestamp())) { - RR->t->credentialRejected(tPtr,cred,"revoked"); + const int64_t* const rt = revocations.get(Membership::credentialKey(C::credentialType(), cred.id())); + if ((rt) && (*rt >= cred.timestamp())) { + RR->t->credentialRejected(tPtr, cred, "revoked"); return Membership::ADD_REJECTED; } - switch(cred.verify(RR,tPtr)) { + switch (cred.verify(RR, tPtr)) { default: - RR->t->credentialRejected(tPtr,cred,"invalid"); + RR->t->credentialRejected(tPtr, cred, "invalid"); return Membership::ADD_REJECTED; case 0: - if (!rc) { + if (! rc) { rc = &(remoteCreds[cred.id()]); } *rc = cred; @@ -172,20 +166,29 @@ static Membership::AddCredentialResult _addCredImpl(Hashtable &remot } } -Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag) { return _addCredImpl(_remoteTags,_revocations,RR,tPtr,nconf,tag); } -Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap) { return _addCredImpl(_remoteCaps,_revocations,RR,tPtr,nconf,cap); } -Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo) { return _addCredImpl(_remoteCoos,_revocations,RR,tPtr,nconf,coo); } - -Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev) +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Tag& tag) { - int64_t *rt; - switch(rev.verify(RR,tPtr)) { + return _addCredImpl(_remoteTags, _revocations, RR, tPtr, nconf, tag); +} +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Capability& cap) +{ + return _addCredImpl(_remoteCaps, _revocations, RR, tPtr, nconf, cap); +} +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const CertificateOfOwnership& coo) +{ + return _addCredImpl(_remoteCoos, _revocations, RR, tPtr, nconf, coo); +} + +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Revocation& rev) +{ + int64_t* rt; + switch (rev.verify(RR, tPtr)) { default: - RR->t->credentialRejected(tPtr,rev,"invalid"); + RR->t->credentialRejected(tPtr, rev, "invalid"); return ADD_REJECTED; case 0: { const Credential::Type ct = rev.type(); - switch(ct) { + switch (ct) { case Credential::CREDENTIAL_TYPE_COM: if (rev.threshold() > _comRevocationThreshold) { _comRevocationThreshold = rev.threshold(); @@ -195,7 +198,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme case Credential::CREDENTIAL_TYPE_CAPABILITY: case Credential::CREDENTIAL_TYPE_TAG: case Credential::CREDENTIAL_TYPE_COO: - rt = &(_revocations[credentialKey(ct,rev.credentialId())]); + rt = &(_revocations[credentialKey(ct, rev.credentialId())]); if (*rt < rev.threshold()) { *rt = rev.threshold(); _comRevocationThreshold = rev.threshold(); @@ -203,7 +206,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme } return ADD_ACCEPTED_REDUNDANT; default: - RR->t->credentialRejected(tPtr,rev,"invalid"); + RR->t->credentialRejected(tPtr, rev, "invalid"); return ADD_REJECTED; } } @@ -212,11 +215,11 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme } } -void Membership::clean(const int64_t now,const NetworkConfig &nconf) +void Membership::clean(const int64_t now, const NetworkConfig& nconf) { - _cleanCredImpl(nconf,_remoteTags); - _cleanCredImpl(nconf,_remoteCaps); - _cleanCredImpl(nconf,_remoteCoos); + _cleanCredImpl(nconf, _remoteTags); + _cleanCredImpl(nconf, _remoteCaps); + _cleanCredImpl(nconf, _remoteCoos); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Membership.hpp b/node/Membership.hpp index d7c98e5b3..962fb55db 100644 --- a/node/Membership.hpp +++ b/node/Membership.hpp @@ -14,17 +14,17 @@ #ifndef ZT_MEMBERSHIP_HPP #define ZT_MEMBERSHIP_HPP -#include - -#include "Constants.hpp" #include "../include/ZeroTierOne.h" +#include "Capability.hpp" +#include "CertificateOfMembership.hpp" +#include "Constants.hpp" #include "Credential.hpp" #include "Hashtable.hpp" -#include "CertificateOfMembership.hpp" -#include "Capability.hpp" -#include "Tag.hpp" -#include "Revocation.hpp" #include "NetworkConfig.hpp" +#include "Revocation.hpp" +#include "Tag.hpp" + +#include #define ZT_MEMBERSHIP_CRED_ID_UNUSED 0xffffffffffffffffULL @@ -40,16 +40,9 @@ class Network; * * This class is not thread safe. It must be locked externally. */ -class Membership -{ -public: - enum AddCredentialResult - { - ADD_REJECTED, - ADD_ACCEPTED_NEW, - ADD_ACCEPTED_REDUNDANT, - ADD_DEFERRED_FOR_WHOIS - }; +class Membership { + public: + enum AddCredentialResult { ADD_REJECTED, ADD_ACCEPTED_NEW, ADD_ACCEPTED_REDUNDANT, ADD_DEFERRED_FOR_WHOIS }; Membership(); @@ -62,11 +55,20 @@ public: * @param peerAddress Address of member peer (the one that this Membership describes) * @param nconf My network config */ - void pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const int64_t now,const Address &peerAddress,const NetworkConfig &nconf); + void pushCredentials(const RuntimeEnvironment* RR, void* tPtr, const int64_t now, const Address& peerAddress, const NetworkConfig& nconf); - inline int64_t lastPushedCredentials() { return _lastPushedCredentials; } - inline int64_t comTimestamp() { return _com.timestamp(); } - inline int64_t comRevocationThreshold() { return _comRevocationThreshold; } + inline int64_t lastPushedCredentials() + { + return _lastPushedCredentials; + } + inline int64_t comTimestamp() + { + return _com.timestamp(); + } + inline int64_t comRevocationThreshold() + { + return _comRevocationThreshold; + } /** * Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true @@ -90,14 +92,14 @@ public: * @param otherNodeIdentity Identity of remote node * @return True if this peer is allowed on this network at all */ - inline bool isAllowedOnNetwork(const NetworkConfig &thisNodeNetworkConfig, const Identity &otherNodeIdentity) const + inline bool isAllowedOnNetwork(const NetworkConfig& thisNodeNetworkConfig, const Identity& otherNodeIdentity) const { return thisNodeNetworkConfig.isPublic() || (((_com.timestamp() > _comRevocationThreshold) && (thisNodeNetworkConfig.com.agreesWith(_com, otherNodeIdentity)))); } inline bool recentlyAssociated(const int64_t now) const { - return ((_com)&&((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); + return ((_com) && ((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); } /** @@ -108,18 +110,17 @@ public: * @param r Resource to check * @return True if this peer has a certificate of ownership for the given resource */ - template - inline bool hasCertificateOfOwnershipFor(const NetworkConfig &nconf,const T &r) const + template inline bool hasCertificateOfOwnershipFor(const NetworkConfig& nconf, const T& r) const { - uint32_t *k = (uint32_t *)0; - CertificateOfOwnership *v = (CertificateOfOwnership *)0; - Hashtable< uint32_t,CertificateOfOwnership >::Iterator i(*(const_cast< Hashtable< uint32_t,CertificateOfOwnership> *>(&_remoteCoos))); - while (i.next(k,v)) { - if (_isCredentialTimestampValid(nconf,*v)&&(v->owns(r))) { + uint32_t* k = (uint32_t*)0; + CertificateOfOwnership* v = (CertificateOfOwnership*)0; + Hashtable::Iterator i(*(const_cast*>(&_remoteCoos))); + while (i.next(k, v)) { + if (_isCredentialTimestampValid(nconf, *v) && (v->owns(r))) { return true; } } - return _isV6NDPEmulated(nconf,r); + return _isV6NDPEmulated(nconf, r); } /** @@ -129,36 +130,36 @@ public: * @param id Tag ID * @return Pointer to tag or NULL if not found */ - inline const Tag *getTag(const NetworkConfig &nconf,const uint32_t id) const + inline const Tag* getTag(const NetworkConfig& nconf, const uint32_t id) const { - const Tag *const t = _remoteTags.get(id); - return (((t)&&(_isCredentialTimestampValid(nconf,*t))) ? t : (Tag *)0); + const Tag* const t = _remoteTags.get(id); + return (((t) && (_isCredentialTimestampValid(nconf, *t))) ? t : (Tag*)0); } /** * Validate and add a credential if signature is okay and it's otherwise good */ - AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com); + AddCredentialResult addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const CertificateOfMembership& com); /** * Validate and add a credential if signature is okay and it's otherwise good */ - AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag); + AddCredentialResult addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Tag& tag); /** * Validate and add a credential if signature is okay and it's otherwise good */ - AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap); + AddCredentialResult addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Capability& cap); /** * Validate and add a credential if signature is okay and it's otherwise good */ - AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo); + AddCredentialResult addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const CertificateOfOwnership& coo); /** * Validate and add a credential if signature is okay and it's otherwise good */ - AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev); + AddCredentialResult addCredential(const RuntimeEnvironment* RR, void* tPtr, const NetworkConfig& nconf, const Revocation& rev); /** * Clean internal databases of stale entries @@ -166,24 +167,30 @@ public: * @param now Current time * @param nconf Current network configuration */ - void clean(const int64_t now,const NetworkConfig &nconf); + void clean(const int64_t now, const NetworkConfig& nconf); /** * Generates a key for the internal use in indexing credentials by type and credential ID */ - static uint64_t credentialKey(const Credential::Type &t,const uint32_t i) { return (((uint64_t)t << 32) | (uint64_t)i); } - -private: - inline bool _isV6NDPEmulated(const NetworkConfig &nconf,const MAC &m) const { return false; } - inline bool _isV6NDPEmulated(const NetworkConfig &nconf,const InetAddress &ip) const + static uint64_t credentialKey(const Credential::Type& t, const uint32_t i) { - if ((ip.isV6())&&(nconf.ndpEmulation())) { - const InetAddress sixpl(InetAddress::makeIpv66plane(nconf.networkId,nconf.issuedTo.toInt())); - for(unsigned int i=0;isin6_addr.s6_addr)[j] != (((const struct sockaddr_in6 *)&sixpl)->sin6_addr.s6_addr)[j]) { + for (unsigned int j = 0; j < 5; ++j) { // check for match on /40 + if ((((const struct sockaddr_in6*)&ip)->sin6_addr.s6_addr)[j] != (((const struct sockaddr_in6*)&sixpl)->sin6_addr.s6_addr)[j]) { prefixMatches = false; break; } @@ -195,12 +202,12 @@ private: } } - const InetAddress rfc4193(InetAddress::makeIpv6rfc4193(nconf.networkId,nconf.issuedTo.toInt())); - for(unsigned int i=0;isin6_addr.s6_addr)[j] != (((const struct sockaddr_in6 *)&rfc4193)->sin6_addr.s6_addr)[j]) { + for (unsigned int j = 0; j < 11; ++j) { // check for match on /88 + if ((((const struct sockaddr_in6*)&ip)->sin6_addr.s6_addr)[j] != (((const struct sockaddr_in6*)&rfc4193)->sin6_addr.s6_addr)[j]) { prefixMatches = false; break; } @@ -215,25 +222,23 @@ private: return false; } - template - inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const C &remoteCredential) const + template inline bool _isCredentialTimestampValid(const NetworkConfig& nconf, const C& remoteCredential) const { const int64_t ts = remoteCredential.timestamp(); if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) { - const int64_t *threshold = _revocations.get(credentialKey(C::credentialType(),remoteCredential.id())); - return ((!threshold)||(ts > *threshold)); + const int64_t* threshold = _revocations.get(credentialKey(C::credentialType(), remoteCredential.id())); + return ((! threshold) || (ts > *threshold)); } return false; } - template - inline void _cleanCredImpl(const NetworkConfig &nconf,Hashtable &remoteCreds) + template inline void _cleanCredImpl(const NetworkConfig& nconf, Hashtable& remoteCreds) { - uint32_t *k = (uint32_t *)0; - C *v = (C *)0; - typename Hashtable::Iterator i(remoteCreds); - while (i.next(k,v)) { - if (!_isCredentialTimestampValid(nconf,*v)) { + uint32_t* k = (uint32_t*)0; + C* v = (C*)0; + typename Hashtable::Iterator i(remoteCreds); + while (i.next(k, v)) { + if (! _isCredentialTimestampValid(nconf, *v)) { remoteCreds.erase(*k); } } @@ -252,45 +257,39 @@ private: CertificateOfMembership _com; // Revocations by credentialKey() - Hashtable< uint64_t,int64_t > _revocations; + Hashtable _revocations; // Remote credentials that we have received from this member (and that are valid) - Hashtable< uint32_t,Tag > _remoteTags; - Hashtable< uint32_t,Capability > _remoteCaps; - Hashtable< uint32_t,CertificateOfOwnership > _remoteCoos; + Hashtable _remoteTags; + Hashtable _remoteCaps; + Hashtable _remoteCoos; -public: - class CapabilityIterator - { - public: - CapabilityIterator(Membership &m,const NetworkConfig &nconf) : - _hti(m._remoteCaps), - _k((uint32_t *)0), - _c((Capability *)0), - _m(m), - _nconf(nconf) + public: + class CapabilityIterator { + public: + CapabilityIterator(Membership& m, const NetworkConfig& nconf) : _hti(m._remoteCaps), _k((uint32_t*)0), _c((Capability*)0), _m(m), _nconf(nconf) { } - inline Capability *next() + inline Capability* next() { - while (_hti.next(_k,_c)) { - if (_m._isCredentialTimestampValid(_nconf,*_c)) { + while (_hti.next(_k, _c)) { + if (_m._isCredentialTimestampValid(_nconf, *_c)) { return _c; } } - return (Capability *)0; + return (Capability*)0; } - private: - Hashtable< uint32_t,Capability >::Iterator _hti; - uint32_t *_k; - Capability *_c; - Membership &_m; - const NetworkConfig &_nconf; + private: + Hashtable::Iterator _hti; + uint32_t* _k; + Capability* _c; + Membership& _m; + const NetworkConfig& _nconf; }; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Metrics.cpp b/node/Metrics.cpp index b41120bbe..3b1872264 100644 --- a/node/Metrics.cpp +++ b/node/Metrics.cpp @@ -10,263 +10,155 @@ * of this software will be governed by version 2.0 of the Apache License. */ -#include #include +#include namespace prometheus { - namespace simpleapi { - std::shared_ptr registry_ptr = std::make_shared(); - Registry& registry = *registry_ptr; - SaveToFile saver; - } -} +namespace simpleapi { +std::shared_ptr registry_ptr = std::make_shared(); +Registry& registry = *registry_ptr; +SaveToFile saver; +} // namespace simpleapi +} // namespace prometheus namespace ZeroTier { - namespace Metrics { - // Packet Type Counts - prometheus::simpleapi::counter_family_t packets - { "zt_packet", "ZeroTier packet type counts"}; +namespace Metrics { +// Packet Type Counts +prometheus::simpleapi::counter_family_t packets { "zt_packet", "ZeroTier packet type counts" }; - // Incoming packets - prometheus::simpleapi::counter_metric_t pkt_nop_in - { packets.Add({{"packet_type", "nop"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_in - { packets.Add({{"packet_type", "error"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ack_in - { packets.Add({{"packet_type", "ack"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_qos_in - { packets.Add({{"packet_type", "qos"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_hello_in - { packets.Add({{"packet_type", "hello"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ok_in - { packets.Add({{"packet_type", "ok"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_whois_in - { packets.Add({{"packet_type", "whois"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_rendezvous_in - { packets.Add({{"packet_type", "rendezvous"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_frame_in - { packets.Add({{"packet_type", "frame"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ext_frame_in - { packets.Add({{"packet_type", "ext_frame"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_echo_in - { packets.Add({{"packet_type", "echo"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_like_in - { packets.Add({{"packet_type", "multicast_like"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_credentials_in - { packets.Add({{"packet_type", "network_credentials"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_config_request_in - { packets.Add({{"packet_type", "network_config_request"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_config_in - { packets.Add({{"packet_type", "network_config"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in - { packets.Add({{"packet_type", "multicast_gather"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in - { packets.Add({{"packet_type", "multicast_frame"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in - { packets.Add({{"packet_type", "push_direct_paths"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_user_message_in - { packets.Add({{"packet_type", "user_message"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_remote_trace_in - { packets.Add({{"packet_type", "remote_trace"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in - { packets.Add({{"packet_type", "path_negotiation_request"}, {"direction", "rx"}}) }; +// Incoming packets +prometheus::simpleapi::counter_metric_t pkt_nop_in { packets.Add({ { "packet_type", "nop" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_in { packets.Add({ { "packet_type", "error" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ack_in { packets.Add({ { "packet_type", "ack" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_qos_in { packets.Add({ { "packet_type", "qos" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_hello_in { packets.Add({ { "packet_type", "hello" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ok_in { packets.Add({ { "packet_type", "ok" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_whois_in { packets.Add({ { "packet_type", "whois" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_rendezvous_in { packets.Add({ { "packet_type", "rendezvous" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_frame_in { packets.Add({ { "packet_type", "frame" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ext_frame_in { packets.Add({ { "packet_type", "ext_frame" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_echo_in { packets.Add({ { "packet_type", "echo" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_like_in { packets.Add({ { "packet_type", "multicast_like" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_credentials_in { packets.Add({ { "packet_type", "network_credentials" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_config_request_in { packets.Add({ { "packet_type", "network_config_request" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_config_in { packets.Add({ { "packet_type", "network_config" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in { packets.Add({ { "packet_type", "multicast_gather" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in { packets.Add({ { "packet_type", "multicast_frame" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in { packets.Add({ { "packet_type", "push_direct_paths" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_user_message_in { packets.Add({ { "packet_type", "user_message" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_remote_trace_in { packets.Add({ { "packet_type", "remote_trace" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in { packets.Add({ { "packet_type", "path_negotiation_request" }, { "direction", "rx" } }) }; - // Outgoing packets - prometheus::simpleapi::counter_metric_t pkt_nop_out - { packets.Add({{"packet_type", "nop"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_out - { packets.Add({{"packet_type", "error"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ack_out - { packets.Add({{"packet_type", "ack"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_qos_out - { packets.Add({{"packet_type", "qos"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_hello_out - { packets.Add({{"packet_type", "hello"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ok_out - { packets.Add({{"packet_type", "ok"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_whois_out - { packets.Add({{"packet_type", "whois"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_rendezvous_out - { packets.Add({{"packet_type", "rendezvous"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_frame_out - { packets.Add({{"packet_type", "frame"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_ext_frame_out - { packets.Add({{"packet_type", "ext_frame"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_echo_out - { packets.Add({{"packet_type", "echo"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_like_out - { packets.Add({{"packet_type", "multicast_like"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_credentials_out - { packets.Add({{"packet_type", "network_credentials"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_config_request_out - { packets.Add({{"packet_type", "network_config_request"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_network_config_out - { packets.Add({{"packet_type", "network_config"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out - { packets.Add({{"packet_type", "multicast_gather"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out - { packets.Add({{"packet_type", "multicast_frame"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out - { packets.Add({{"packet_type", "push_direct_paths"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_user_message_out - { packets.Add({{"packet_type", "user_message"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_remote_trace_out - { packets.Add({{"packet_type", "remote_trace"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out - { packets.Add({{"packet_type", "path_negotiation_request"}, {"direction", "tx"}}) }; +// Outgoing packets +prometheus::simpleapi::counter_metric_t pkt_nop_out { packets.Add({ { "packet_type", "nop" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_out { packets.Add({ { "packet_type", "error" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ack_out { packets.Add({ { "packet_type", "ack" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_qos_out { packets.Add({ { "packet_type", "qos" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_hello_out { packets.Add({ { "packet_type", "hello" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ok_out { packets.Add({ { "packet_type", "ok" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_whois_out { packets.Add({ { "packet_type", "whois" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_rendezvous_out { packets.Add({ { "packet_type", "rendezvous" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_frame_out { packets.Add({ { "packet_type", "frame" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_ext_frame_out { packets.Add({ { "packet_type", "ext_frame" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_echo_out { packets.Add({ { "packet_type", "echo" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_like_out { packets.Add({ { "packet_type", "multicast_like" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_credentials_out { packets.Add({ { "packet_type", "network_credentials" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_config_request_out { packets.Add({ { "packet_type", "network_config_request" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_network_config_out { packets.Add({ { "packet_type", "network_config" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out { packets.Add({ { "packet_type", "multicast_gather" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out { packets.Add({ { "packet_type", "multicast_frame" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out { packets.Add({ { "packet_type", "push_direct_paths" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_user_message_out { packets.Add({ { "packet_type", "user_message" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_remote_trace_out { packets.Add({ { "packet_type", "remote_trace" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out { packets.Add({ { "packet_type", "path_negotiation_request" }, { "direction", "tx" } }) }; +// Packet Error Counts +prometheus::simpleapi::counter_family_t packet_errors { "zt_packet_error", "ZeroTier packet errors" }; - // Packet Error Counts - prometheus::simpleapi::counter_family_t packet_errors - { "zt_packet_error", "ZeroTier packet errors"}; +// Incoming Error Counts +prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in { packet_errors.Add({ { "error_type", "obj_not_found" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in { packet_errors.Add({ { "error_type", "unsupported_operation" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in { packet_errors.Add({ { "error_type", "identity_collision" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in { packet_errors.Add({ { "error_type", "need_membership_certificate" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in { packet_errors.Add({ { "error_type", "network_access_denied" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in { packet_errors.Add({ { "error_type", "unwanted_multicast" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in { packet_errors.Add({ { "error_type", "authentication_required" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in { packet_errors.Add({ { "error_type", "internal_server_error" }, { "direction", "rx" } }) }; - // Incoming Error Counts - prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in - { packet_errors.Add({{"error_type", "obj_not_found"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in - { packet_errors.Add({{"error_type", "unsupported_operation"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in - { packet_errors.Add({{"error_type", "identity_collision"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in - { packet_errors.Add({{"error_type", "need_membership_certificate"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in - { packet_errors.Add({{"error_type", "network_access_denied"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in - { packet_errors.Add({{"error_type", "unwanted_multicast"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in - { packet_errors.Add({{"error_type", "authentication_required"}, {"direction", "rx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in - { packet_errors.Add({{"error_type", "internal_server_error"}, {"direction", "rx"}}) }; +// Outgoing Error Counts +prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out { packet_errors.Add({ { "error_type", "obj_not_found" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out { packet_errors.Add({ { "error_type", "unsupported_operation" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out { packet_errors.Add({ { "error_type", "identity_collision" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out { packet_errors.Add({ { "error_type", "need_membership_certificate" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out { packet_errors.Add({ { "error_type", "network_access_denied" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out { packet_errors.Add({ { "error_type", "unwanted_multicast" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out { packet_errors.Add({ { "error_type", "authentication_required" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out { packet_errors.Add({ { "error_type", "internal_server_error" }, { "direction", "tx" } }) }; - // Outgoing Error Counts - prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out - { packet_errors.Add({{"error_type", "obj_not_found"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out - { packet_errors.Add({{"error_type", "unsupported_operation"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out - { packet_errors.Add({{"error_type", "identity_collision"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out - { packet_errors.Add({{"error_type", "need_membership_certificate"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out - { packet_errors.Add({{"error_type", "network_access_denied"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out - { packet_errors.Add({{"error_type", "unwanted_multicast"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out - { packet_errors.Add({{"error_type", "authentication_required"}, {"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out - { packet_errors.Add({{"error_type", "internal_server_error"}, {"direction", "tx"}}) }; +// Data Sent/Received Metrics +prometheus::simpleapi::counter_family_t data { "zt_data", "number of bytes ZeroTier has transmitted or received" }; +prometheus::simpleapi::counter_metric_t udp_recv { data.Add({ { "protocol", "udp" }, { "direction", "rx" } }) }; +prometheus::simpleapi::counter_metric_t udp_send { data.Add({ { "protocol", "udp" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t tcp_send { data.Add({ { "protocol", "tcp" }, { "direction", "tx" } }) }; +prometheus::simpleapi::counter_metric_t tcp_recv { data.Add({ { "protocol", "tcp" }, { "direction", "rx" } }) }; - // Data Sent/Received Metrics - prometheus::simpleapi::counter_family_t data - { "zt_data", "number of bytes ZeroTier has transmitted or received" }; - prometheus::simpleapi::counter_metric_t udp_recv - { data.Add({{"protocol","udp"},{"direction","rx"}}) }; - prometheus::simpleapi::counter_metric_t udp_send - { data.Add({{"protocol","udp"},{"direction","tx"}}) }; - prometheus::simpleapi::counter_metric_t tcp_send - { data.Add({{"protocol","tcp"},{"direction", "tx"}}) }; - prometheus::simpleapi::counter_metric_t tcp_recv - { data.Add({{"protocol","tcp"},{"direction", "rx"}}) }; +// Network Metrics +prometheus::simpleapi::gauge_metric_t network_num_joined { "zt_num_networks", "number of networks this instance is joined to" }; +prometheus::simpleapi::gauge_family_t network_num_multicast_groups { "zt_network_multicast_groups_subscribed", "number of multicast groups networks are subscribed to" }; +prometheus::simpleapi::counter_family_t network_packets { "zt_network_packets", "number of incoming/outgoing packets per network" }; - // Network Metrics - prometheus::simpleapi::gauge_metric_t network_num_joined - { "zt_num_networks", "number of networks this instance is joined to" }; - prometheus::simpleapi::gauge_family_t network_num_multicast_groups - { "zt_network_multicast_groups_subscribed", "number of multicast groups networks are subscribed to" }; - prometheus::simpleapi::counter_family_t network_packets - { "zt_network_packets", "number of incoming/outgoing packets per network" }; - #ifndef ZT_NO_PEER_METRICS - // PeerMetrics - prometheus::CustomFamily> &peer_latency = - prometheus::Builder>() - .Name("zt_peer_latency") - .Help("peer latency (ms)") - .Register(prometheus::simpleapi::registry); - - prometheus::simpleapi::gauge_family_t peer_path_count - { "zt_peer_path_count", "number of paths to peer" }; - prometheus::simpleapi::counter_family_t peer_packets - { "zt_peer_packets", "number of packets to/from a peer" }; - prometheus::simpleapi::counter_family_t peer_packet_errors - { "zt_peer_packet_errors" , "number of incoming packet errors from a peer" }; +// PeerMetrics +prometheus::CustomFamily >& peer_latency = prometheus::Builder >().Name("zt_peer_latency").Help("peer latency (ms)").Register(prometheus::simpleapi::registry); + +prometheus::simpleapi::gauge_family_t peer_path_count { "zt_peer_path_count", "number of paths to peer" }; +prometheus::simpleapi::counter_family_t peer_packets { "zt_peer_packets", "number of packets to/from a peer" }; +prometheus::simpleapi::counter_family_t peer_packet_errors { "zt_peer_packet_errors", "number of incoming packet errors from a peer" }; #endif - // General Controller Metrics - prometheus::simpleapi::gauge_metric_t network_count - {"controller_network_count", "number of networks the controller is serving"}; - prometheus::simpleapi::gauge_metric_t member_count - {"controller_member_count", "number of network members the controller is serving"}; - prometheus::simpleapi::counter_metric_t network_changes - {"controller_network_change_count", "number of times a network configuration is changed"}; - prometheus::simpleapi::counter_metric_t member_changes - {"controller_member_change_count", "number of times a network member configuration is changed"}; - prometheus::simpleapi::counter_metric_t member_auths - {"controller_member_auth_count", "number of network member auths"}; - prometheus::simpleapi::counter_metric_t member_deauths - {"controller_member_deauth_count", "number of network member deauths"}; +// General Controller Metrics +prometheus::simpleapi::gauge_metric_t network_count { "controller_network_count", "number of networks the controller is serving" }; +prometheus::simpleapi::gauge_metric_t member_count { "controller_member_count", "number of network members the controller is serving" }; +prometheus::simpleapi::counter_metric_t network_changes { "controller_network_change_count", "number of times a network configuration is changed" }; +prometheus::simpleapi::counter_metric_t member_changes { "controller_member_change_count", "number of times a network member configuration is changed" }; +prometheus::simpleapi::counter_metric_t member_auths { "controller_member_auth_count", "number of network member auths" }; +prometheus::simpleapi::counter_metric_t member_deauths { "controller_member_deauth_count", "number of network member deauths" }; - prometheus::simpleapi::gauge_metric_t network_config_request_queue_size - { "controller_network_config_request_queue", "number of entries in the request queue for network configurations" }; - - prometheus::simpleapi::counter_metric_t sso_expiration_checks - { "controller_sso_expiration_checks", "number of sso expiration checks done" }; +prometheus::simpleapi::gauge_metric_t network_config_request_queue_size { "controller_network_config_request_queue", "number of entries in the request queue for network configurations" }; - prometheus::simpleapi::counter_metric_t sso_member_deauth - { "controller_sso_timeouts", "number of sso timeouts" }; +prometheus::simpleapi::counter_metric_t sso_expiration_checks { "controller_sso_expiration_checks", "number of sso expiration checks done" }; - prometheus::simpleapi::counter_metric_t network_config_request - { "controller_network_config_request", "count of config requests handled" }; - prometheus::simpleapi::gauge_metric_t network_config_request_threads - { "controller_network_config_request_threads", "number of active network config handling threads" }; - prometheus::simpleapi::counter_metric_t db_get_network - { "controller_db_get_network", "counter" }; - prometheus::simpleapi::counter_metric_t db_get_network_and_member - { "controller_db_get_network_and_member", "counter" }; - prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary - { "controller_db_get_networK_and_member_summary", "counter" }; - prometheus::simpleapi::counter_metric_t db_get_member_list - { "controller_db_get_member_list", "counter" }; - prometheus::simpleapi::counter_metric_t db_get_network_list - { "controller_db_get_network_list", "counter" }; - prometheus::simpleapi::counter_metric_t db_member_change - { "controller_db_member_change", "counter" }; - prometheus::simpleapi::counter_metric_t db_network_change - { "controller_db_network_change", "counter" }; +prometheus::simpleapi::counter_metric_t sso_member_deauth { "controller_sso_timeouts", "number of sso timeouts" }; + +prometheus::simpleapi::counter_metric_t network_config_request { "controller_network_config_request", "count of config requests handled" }; +prometheus::simpleapi::gauge_metric_t network_config_request_threads { "controller_network_config_request_threads", "number of active network config handling threads" }; +prometheus::simpleapi::counter_metric_t db_get_network { "controller_db_get_network", "counter" }; +prometheus::simpleapi::counter_metric_t db_get_network_and_member { "controller_db_get_network_and_member", "counter" }; +prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary { "controller_db_get_networK_and_member_summary", "counter" }; +prometheus::simpleapi::counter_metric_t db_get_member_list { "controller_db_get_member_list", "counter" }; +prometheus::simpleapi::counter_metric_t db_get_network_list { "controller_db_get_network_list", "counter" }; +prometheus::simpleapi::counter_metric_t db_member_change { "controller_db_member_change", "counter" }; +prometheus::simpleapi::counter_metric_t db_network_change { "controller_db_network_change", "counter" }; #ifdef ZT_CONTROLLER_USE_LIBPQ - // Central Controller Metrics - prometheus::simpleapi::counter_metric_t pgsql_mem_notification - { "controller_pgsql_member_notifications_received", "number of member change notifications received via pgsql NOTIFY" }; - prometheus::simpleapi::counter_metric_t pgsql_net_notification - { "controller_pgsql_network_notifications_received", "number of network change notifications received via pgsql NOTIFY" }; - prometheus::simpleapi::counter_metric_t pgsql_node_checkin - { "controller_pgsql_node_checkin_count", "number of node check-ins (pgsql)" }; - prometheus::simpleapi::counter_metric_t pgsql_commit_ticks - { "controller_pgsql_commit_ticks", "number of commit ticks run (pgsql)" }; - prometheus::simpleapi::counter_metric_t db_get_sso_info - { "controller_db_get_sso_info", "counter" }; +// Central Controller Metrics +prometheus::simpleapi::counter_metric_t pgsql_mem_notification { "controller_pgsql_member_notifications_received", "number of member change notifications received via pgsql NOTIFY" }; +prometheus::simpleapi::counter_metric_t pgsql_net_notification { "controller_pgsql_network_notifications_received", "number of network change notifications received via pgsql NOTIFY" }; +prometheus::simpleapi::counter_metric_t pgsql_node_checkin { "controller_pgsql_node_checkin_count", "number of node check-ins (pgsql)" }; +prometheus::simpleapi::counter_metric_t pgsql_commit_ticks { "controller_pgsql_commit_ticks", "number of commit ticks run (pgsql)" }; +prometheus::simpleapi::counter_metric_t db_get_sso_info { "controller_db_get_sso_info", "counter" }; - prometheus::simpleapi::counter_metric_t redis_mem_notification - { "controller_redis_member_notifications_received", "number of member change notifications received via redis" }; - prometheus::simpleapi::counter_metric_t redis_net_notification - { "controller_redis_network_notifications_received", "number of network change notifications received via redis" }; - prometheus::simpleapi::counter_metric_t redis_node_checkin - { "controller_redis_node_checkin_count", "number of node check-ins (redis)" }; +prometheus::simpleapi::counter_metric_t redis_mem_notification { "controller_redis_member_notifications_received", "number of member change notifications received via redis" }; +prometheus::simpleapi::counter_metric_t redis_net_notification { "controller_redis_network_notifications_received", "number of network change notifications received via redis" }; +prometheus::simpleapi::counter_metric_t redis_node_checkin { "controller_redis_node_checkin_count", "number of node check-ins (redis)" }; - // Central DB Pool Metrics - prometheus::simpleapi::counter_metric_t conn_counter - { "controller_pgsql_connections_created", "number of pgsql connections created"}; - prometheus::simpleapi::counter_metric_t max_pool_size - { "controller_pgsql_max_conn_pool_size", "max connection pool size for postgres"}; - prometheus::simpleapi::counter_metric_t min_pool_size - { "controller_pgsql_min_conn_pool_size", "minimum connection pool size for postgres" }; - prometheus::simpleapi::gauge_metric_t pool_avail - { "controller_pgsql_available_conns", "number of available postgres connections" }; - prometheus::simpleapi::gauge_metric_t pool_in_use - { "controller_pgsql_in_use_conns", "number of postgres database connections in use" }; - prometheus::simpleapi::counter_metric_t pool_errors - { "controller_pgsql_connection_errors", "number of connection errors the connection pool has seen" }; +// Central DB Pool Metrics +prometheus::simpleapi::counter_metric_t conn_counter { "controller_pgsql_connections_created", "number of pgsql connections created" }; +prometheus::simpleapi::counter_metric_t max_pool_size { "controller_pgsql_max_conn_pool_size", "max connection pool size for postgres" }; +prometheus::simpleapi::counter_metric_t min_pool_size { "controller_pgsql_min_conn_pool_size", "minimum connection pool size for postgres" }; +prometheus::simpleapi::gauge_metric_t pool_avail { "controller_pgsql_available_conns", "number of available postgres connections" }; +prometheus::simpleapi::gauge_metric_t pool_in_use { "controller_pgsql_in_use_conns", "number of postgres database connections in use" }; +prometheus::simpleapi::counter_metric_t pool_errors { "controller_pgsql_connection_errors", "number of connection errors the connection pool has seen" }; #endif - } -} +} // namespace Metrics +} // namespace ZeroTier diff --git a/node/Metrics.hpp b/node/Metrics.hpp index 5906f18e4..ef23ffb56 100644 --- a/node/Metrics.hpp +++ b/node/Metrics.hpp @@ -12,155 +12,152 @@ #ifndef METRICS_H_ #define METRICS_H_ -#include #include +#include namespace prometheus { - namespace simpleapi { - extern std::shared_ptr registry_ptr; - } +namespace simpleapi { +extern std::shared_ptr registry_ptr; } +} // namespace prometheus namespace ZeroTier { - namespace Metrics { - // Packet Type Counts - extern prometheus::simpleapi::counter_family_t packets; +namespace Metrics { +// Packet Type Counts +extern prometheus::simpleapi::counter_family_t packets; - // incoming packets - extern prometheus::simpleapi::counter_metric_t pkt_nop_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_in; - extern prometheus::simpleapi::counter_metric_t pkt_ack_in; - extern prometheus::simpleapi::counter_metric_t pkt_qos_in; - extern prometheus::simpleapi::counter_metric_t pkt_hello_in; - extern prometheus::simpleapi::counter_metric_t pkt_ok_in; - extern prometheus::simpleapi::counter_metric_t pkt_whois_in; - extern prometheus::simpleapi::counter_metric_t pkt_rendezvous_in; - extern prometheus::simpleapi::counter_metric_t pkt_frame_in; - extern prometheus::simpleapi::counter_metric_t pkt_ext_frame_in; - extern prometheus::simpleapi::counter_metric_t pkt_echo_in; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_like_in; - extern prometheus::simpleapi::counter_metric_t pkt_network_credentials_in; - extern prometheus::simpleapi::counter_metric_t pkt_network_config_request_in; - extern prometheus::simpleapi::counter_metric_t pkt_network_config_in; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in; - extern prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in; - extern prometheus::simpleapi::counter_metric_t pkt_user_message_in; - extern prometheus::simpleapi::counter_metric_t pkt_remote_trace_in; - extern prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in; +// incoming packets +extern prometheus::simpleapi::counter_metric_t pkt_nop_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_in; +extern prometheus::simpleapi::counter_metric_t pkt_ack_in; +extern prometheus::simpleapi::counter_metric_t pkt_qos_in; +extern prometheus::simpleapi::counter_metric_t pkt_hello_in; +extern prometheus::simpleapi::counter_metric_t pkt_ok_in; +extern prometheus::simpleapi::counter_metric_t pkt_whois_in; +extern prometheus::simpleapi::counter_metric_t pkt_rendezvous_in; +extern prometheus::simpleapi::counter_metric_t pkt_frame_in; +extern prometheus::simpleapi::counter_metric_t pkt_ext_frame_in; +extern prometheus::simpleapi::counter_metric_t pkt_echo_in; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_like_in; +extern prometheus::simpleapi::counter_metric_t pkt_network_credentials_in; +extern prometheus::simpleapi::counter_metric_t pkt_network_config_request_in; +extern prometheus::simpleapi::counter_metric_t pkt_network_config_in; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_gather_in; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_frame_in; +extern prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_in; +extern prometheus::simpleapi::counter_metric_t pkt_user_message_in; +extern prometheus::simpleapi::counter_metric_t pkt_remote_trace_in; +extern prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_in; - // outgoing packets - extern prometheus::simpleapi::counter_metric_t pkt_nop_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_out; - extern prometheus::simpleapi::counter_metric_t pkt_ack_out; - extern prometheus::simpleapi::counter_metric_t pkt_qos_out; - extern prometheus::simpleapi::counter_metric_t pkt_hello_out; - extern prometheus::simpleapi::counter_metric_t pkt_ok_out; - extern prometheus::simpleapi::counter_metric_t pkt_whois_out; - extern prometheus::simpleapi::counter_metric_t pkt_rendezvous_out; - extern prometheus::simpleapi::counter_metric_t pkt_frame_out; - extern prometheus::simpleapi::counter_metric_t pkt_ext_frame_out; - extern prometheus::simpleapi::counter_metric_t pkt_echo_out; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_like_out; - extern prometheus::simpleapi::counter_metric_t pkt_network_credentials_out; - extern prometheus::simpleapi::counter_metric_t pkt_network_config_request_out; - extern prometheus::simpleapi::counter_metric_t pkt_network_config_out; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out; - extern prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out; - extern prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out; - extern prometheus::simpleapi::counter_metric_t pkt_user_message_out; - extern prometheus::simpleapi::counter_metric_t pkt_remote_trace_out; - extern prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out; +// outgoing packets +extern prometheus::simpleapi::counter_metric_t pkt_nop_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_out; +extern prometheus::simpleapi::counter_metric_t pkt_ack_out; +extern prometheus::simpleapi::counter_metric_t pkt_qos_out; +extern prometheus::simpleapi::counter_metric_t pkt_hello_out; +extern prometheus::simpleapi::counter_metric_t pkt_ok_out; +extern prometheus::simpleapi::counter_metric_t pkt_whois_out; +extern prometheus::simpleapi::counter_metric_t pkt_rendezvous_out; +extern prometheus::simpleapi::counter_metric_t pkt_frame_out; +extern prometheus::simpleapi::counter_metric_t pkt_ext_frame_out; +extern prometheus::simpleapi::counter_metric_t pkt_echo_out; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_like_out; +extern prometheus::simpleapi::counter_metric_t pkt_network_credentials_out; +extern prometheus::simpleapi::counter_metric_t pkt_network_config_request_out; +extern prometheus::simpleapi::counter_metric_t pkt_network_config_out; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_gather_out; +extern prometheus::simpleapi::counter_metric_t pkt_multicast_frame_out; +extern prometheus::simpleapi::counter_metric_t pkt_push_direct_paths_out; +extern prometheus::simpleapi::counter_metric_t pkt_user_message_out; +extern prometheus::simpleapi::counter_metric_t pkt_remote_trace_out; +extern prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request_out; - // Packet Error Counts - extern prometheus::simpleapi::counter_family_t packet_errors; +// Packet Error Counts +extern prometheus::simpleapi::counter_family_t packet_errors; - // incoming errors - extern prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in; - extern prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in; +// incoming errors +extern prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_in; +extern prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_in; - // outgoing errors - extern prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out; - extern prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out; +// outgoing errors +extern prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_identity_collision_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_authentication_required_out; +extern prometheus::simpleapi::counter_metric_t pkt_error_internal_server_error_out; - // Data Sent/Received Metrics - extern prometheus::simpleapi::counter_family_t data; - extern prometheus::simpleapi::counter_metric_t udp_send; - extern prometheus::simpleapi::counter_metric_t udp_recv; - extern prometheus::simpleapi::counter_metric_t tcp_send; - extern prometheus::simpleapi::counter_metric_t tcp_recv; +// Data Sent/Received Metrics +extern prometheus::simpleapi::counter_family_t data; +extern prometheus::simpleapi::counter_metric_t udp_send; +extern prometheus::simpleapi::counter_metric_t udp_recv; +extern prometheus::simpleapi::counter_metric_t tcp_send; +extern prometheus::simpleapi::counter_metric_t tcp_recv; - // Network Metrics - extern prometheus::simpleapi::gauge_metric_t network_num_joined; - extern prometheus::simpleapi::gauge_family_t network_num_multicast_groups; - extern prometheus::simpleapi::counter_family_t network_packets; +// Network Metrics +extern prometheus::simpleapi::gauge_metric_t network_num_joined; +extern prometheus::simpleapi::gauge_family_t network_num_multicast_groups; +extern prometheus::simpleapi::counter_family_t network_packets; #ifndef ZT_NO_PEER_METRICS - // Peer Metrics - extern prometheus::CustomFamily> &peer_latency; - extern prometheus::simpleapi::gauge_family_t peer_path_count; - extern prometheus::simpleapi::counter_family_t peer_packets; - extern prometheus::simpleapi::counter_family_t peer_packet_errors; +// Peer Metrics +extern prometheus::CustomFamily >& peer_latency; +extern prometheus::simpleapi::gauge_family_t peer_path_count; +extern prometheus::simpleapi::counter_family_t peer_packets; +extern prometheus::simpleapi::counter_family_t peer_packet_errors; #endif - // General Controller Metrics - extern prometheus::simpleapi::gauge_metric_t network_count; - extern prometheus::simpleapi::gauge_metric_t member_count; - extern prometheus::simpleapi::counter_metric_t network_changes; - extern prometheus::simpleapi::counter_metric_t member_changes; - extern prometheus::simpleapi::counter_metric_t member_auths; - extern prometheus::simpleapi::counter_metric_t member_deauths; +// General Controller Metrics +extern prometheus::simpleapi::gauge_metric_t network_count; +extern prometheus::simpleapi::gauge_metric_t member_count; +extern prometheus::simpleapi::counter_metric_t network_changes; +extern prometheus::simpleapi::counter_metric_t member_changes; +extern prometheus::simpleapi::counter_metric_t member_auths; +extern prometheus::simpleapi::counter_metric_t member_deauths; - extern prometheus::simpleapi::gauge_metric_t network_config_request_queue_size; - extern prometheus::simpleapi::counter_metric_t sso_expiration_checks; - extern prometheus::simpleapi::counter_metric_t sso_member_deauth; - extern prometheus::simpleapi::counter_metric_t network_config_request; - extern prometheus::simpleapi::gauge_metric_t network_config_request_threads; - - extern prometheus::simpleapi::counter_metric_t db_get_network; - extern prometheus::simpleapi::counter_metric_t db_get_network_and_member; - extern prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary; - extern prometheus::simpleapi::counter_metric_t db_get_member_list; - extern prometheus::simpleapi::counter_metric_t db_get_network_list; - extern prometheus::simpleapi::counter_metric_t db_member_change; - extern prometheus::simpleapi::counter_metric_t db_network_change; +extern prometheus::simpleapi::gauge_metric_t network_config_request_queue_size; +extern prometheus::simpleapi::counter_metric_t sso_expiration_checks; +extern prometheus::simpleapi::counter_metric_t sso_member_deauth; +extern prometheus::simpleapi::counter_metric_t network_config_request; +extern prometheus::simpleapi::gauge_metric_t network_config_request_threads; +extern prometheus::simpleapi::counter_metric_t db_get_network; +extern prometheus::simpleapi::counter_metric_t db_get_network_and_member; +extern prometheus::simpleapi::counter_metric_t db_get_network_and_member_and_summary; +extern prometheus::simpleapi::counter_metric_t db_get_member_list; +extern prometheus::simpleapi::counter_metric_t db_get_network_list; +extern prometheus::simpleapi::counter_metric_t db_member_change; +extern prometheus::simpleapi::counter_metric_t db_network_change; #ifdef ZT_CONTROLLER_USE_LIBPQ - // Central Controller Metrics - extern prometheus::simpleapi::counter_metric_t pgsql_mem_notification; - extern prometheus::simpleapi::counter_metric_t pgsql_net_notification; - extern prometheus::simpleapi::counter_metric_t pgsql_node_checkin; - extern prometheus::simpleapi::counter_metric_t pgsql_commit_ticks; - extern prometheus::simpleapi::counter_metric_t db_get_sso_info; - - extern prometheus::simpleapi::counter_metric_t redis_mem_notification; - extern prometheus::simpleapi::counter_metric_t redis_net_notification; - extern prometheus::simpleapi::counter_metric_t redis_node_checkin; +// Central Controller Metrics +extern prometheus::simpleapi::counter_metric_t pgsql_mem_notification; +extern prometheus::simpleapi::counter_metric_t pgsql_net_notification; +extern prometheus::simpleapi::counter_metric_t pgsql_node_checkin; +extern prometheus::simpleapi::counter_metric_t pgsql_commit_ticks; +extern prometheus::simpleapi::counter_metric_t db_get_sso_info; - +extern prometheus::simpleapi::counter_metric_t redis_mem_notification; +extern prometheus::simpleapi::counter_metric_t redis_net_notification; +extern prometheus::simpleapi::counter_metric_t redis_node_checkin; - // Central DB Pool Metrics - extern prometheus::simpleapi::counter_metric_t conn_counter; - extern prometheus::simpleapi::counter_metric_t max_pool_size; - extern prometheus::simpleapi::counter_metric_t min_pool_size; - extern prometheus::simpleapi::gauge_metric_t pool_avail; - extern prometheus::simpleapi::gauge_metric_t pool_in_use; - extern prometheus::simpleapi::counter_metric_t pool_errors; +// Central DB Pool Metrics +extern prometheus::simpleapi::counter_metric_t conn_counter; +extern prometheus::simpleapi::counter_metric_t max_pool_size; +extern prometheus::simpleapi::counter_metric_t min_pool_size; +extern prometheus::simpleapi::gauge_metric_t pool_avail; +extern prometheus::simpleapi::gauge_metric_t pool_in_use; +extern prometheus::simpleapi::counter_metric_t pool_errors; #endif - } // namespace Metrics -}// namespace ZeroTier +} // namespace Metrics +} // namespace ZeroTier -#endif // METRICS_H_ +#endif // METRICS_H_ diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp index abd6f0aad..53905aa42 100644 --- a/node/MulticastGroup.hpp +++ b/node/MulticastGroup.hpp @@ -14,10 +14,10 @@ #ifndef ZT_MULTICASTGROUP_HPP #define ZT_MULTICASTGROUP_HPP -#include - -#include "MAC.hpp" #include "InetAddress.hpp" +#include "MAC.hpp" + +#include namespace ZeroTier { @@ -36,18 +36,13 @@ namespace ZeroTier { * * MulticastGroup behaves as an immutable value object. */ -class MulticastGroup -{ -public: - MulticastGroup() : - _mac(), - _adi(0) +class MulticastGroup { + public: + MulticastGroup() : _mac(), _adi(0) { } - MulticastGroup(const MAC &m,uint32_t a) : - _mac(m), - _adi(a) + MulticastGroup(const MAC& m, uint32_t a) : _mac(m), _adi(a) { } @@ -57,21 +52,22 @@ public: * @param ip IP address (port field is ignored) * @return Multicast group for ARP/NDP */ - static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip) + static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress& ip) { if (ip.isV4()) { // IPv4 wants broadcast MACs, so we shove the V4 address itself into // the Multicast Group ADI field. Making V4 ARP work is basically why // ADI was added, as well as handling other things that want mindless // Ethernet broadcast to all. - return MulticastGroup(MAC(0xffffffffffffULL),Utils::ntoh(*((const uint32_t *)ip.rawIpData()))); - } else if (ip.isV6()) { + return MulticastGroup(MAC(0xffffffffffffULL), Utils::ntoh(*((const uint32_t*)ip.rawIpData()))); + } + else if (ip.isV6()) { // IPv6 is better designed in this respect. We can compute the IPv6 // multicast address directly from the IP address, and it gives us // 24 bits of uniqueness. Collisions aren't likely to be common enough // to care about. - const unsigned char *a = (const unsigned char *)ip.rawIpData(); - return MulticastGroup(MAC(0x33,0x33,0xff,a[13],a[14],a[15]),0); + const unsigned char* a = (const unsigned char*)ip.rawIpData(); + return MulticastGroup(MAC(0x33, 0x33, 0xff, a[13], a[14], a[15]), 0); } return MulticastGroup(); } @@ -79,35 +75,60 @@ public: /** * @return Multicast address */ - inline const MAC &mac() const { return _mac; } + inline const MAC& mac() const + { + return _mac; + } /** * @return Additional distinguishing information */ - inline uint32_t adi() const { return _adi; } + inline uint32_t adi() const + { + return _adi; + } - inline unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); } + inline unsigned long hashCode() const + { + return (_mac.hashCode() ^ (unsigned long)_adi); + } - inline bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); } - inline bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); } - inline bool operator<(const MulticastGroup &g) const + inline bool operator==(const MulticastGroup& g) const + { + return ((_mac == g._mac) && (_adi == g._adi)); + } + inline bool operator!=(const MulticastGroup& g) const + { + return ((_mac != g._mac) || (_adi != g._adi)); + } + inline bool operator<(const MulticastGroup& g) const { if (_mac < g._mac) { return true; - } else if (_mac == g._mac) { + } + else if (_mac == g._mac) { return (_adi < g._adi); } return false; } - inline bool operator>(const MulticastGroup &g) const { return (g < *this); } - inline bool operator<=(const MulticastGroup &g) const { return !(g < *this); } - inline bool operator>=(const MulticastGroup &g) const { return !(*this < g); } + inline bool operator>(const MulticastGroup& g) const + { + return (g < *this); + } + inline bool operator<=(const MulticastGroup& g) const + { + return ! (g < *this); + } + inline bool operator>=(const MulticastGroup& g) const + { + return ! (*this < g); + } -private: + private: MAC _mac; uint32_t _adi; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 3a771972e..ccade7083 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -11,25 +11,24 @@ */ /****/ -#include - -#include "Constants.hpp" -#include "RuntimeEnvironment.hpp" #include "Multicaster.hpp" -#include "Topology.hpp" -#include "Switch.hpp" -#include "Packet.hpp" -#include "Peer.hpp" + #include "C25519.hpp" #include "CertificateOfMembership.hpp" -#include "Node.hpp" +#include "Constants.hpp" #include "Network.hpp" +#include "Node.hpp" +#include "Packet.hpp" +#include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" + +#include namespace ZeroTier { -Multicaster::Multicaster(const RuntimeEnvironment *renv) : - RR(renv), - _groups(32) +Multicaster::Multicaster(const RuntimeEnvironment* renv) : RR(renv), _groups(32) { } @@ -37,24 +36,24 @@ Multicaster::~Multicaster() { } -void Multicaster::addMultiple(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown) +void Multicaster::addMultiple(void* tPtr, int64_t now, uint64_t nwid, const MulticastGroup& mg, const void* addresses, unsigned int count, unsigned int totalKnown) { - const unsigned char *p = (const unsigned char *)addresses; - const unsigned char *e = p + (5 * count); + const unsigned char* p = (const unsigned char*)addresses; + const unsigned char* e = p + (5 * count); Mutex::Lock _l(_groups_m); - MulticastGroupStatus &gs = _groups[Multicaster::Key(nwid,mg)]; + MulticastGroupStatus& gs = _groups[Multicaster::Key(nwid, mg)]; while (p != e) { - _add(tPtr,now,nwid,mg,gs,Address(p,5)); + _add(tPtr, now, nwid, mg, gs, Address(p, 5)); p += 5; } } -void Multicaster::remove(uint64_t nwid,const MulticastGroup &mg,const Address &member) +void Multicaster::remove(uint64_t nwid, const MulticastGroup& mg, const Address& member) { Mutex::Lock _l(_groups_m); - MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); + MulticastGroupStatus* s = _groups.get(Multicaster::Key(nwid, mg)); if (s) { - for(std::vector::iterator m(s->members.begin());m!=s->members.end();++m) { + for (std::vector::iterator m(s->members.begin()); m != s->members.end(); ++m) { if (m->address == member) { s->members.erase(m); break; @@ -63,26 +62,27 @@ void Multicaster::remove(uint64_t nwid,const MulticastGroup &mg,const Address &m } } -unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const MulticastGroup &mg,Buffer &appendTo,unsigned int limit) const +unsigned int Multicaster::gather(const Address& queryingPeer, uint64_t nwid, const MulticastGroup& mg, Buffer& appendTo, unsigned int limit) const { - unsigned char *p; - unsigned int added = 0,i,k,rptr,totalKnown = 0; - uint64_t a,picked[(ZT_PROTO_MAX_PACKET_LENGTH / 5) + 2]; + unsigned char* p; + unsigned int added = 0, i, k, rptr, totalKnown = 0; + uint64_t a, picked[(ZT_PROTO_MAX_PACKET_LENGTH / 5) + 2]; - if (!limit) { + if (! limit) { return 0; - } else if (limit > 0xffff) { + } + else if (limit > 0xffff) { limit = 0xffff; } const unsigned int totalAt = appendTo.size(); - appendTo.addSize(4); // sizeof(uint32_t) + appendTo.addSize(4); // sizeof(uint32_t) const unsigned int addedAt = appendTo.size(); - appendTo.addSize(2); // sizeof(uint16_t) + appendTo.addSize(2); // sizeof(uint16_t) - { // Return myself if I am a member of this group + { // Return myself if I am a member of this group SharedPtr network(RR->node->network(nwid)); - if ((network)&&(network->subscribedToMulticastGroup(mg,true))) { + if ((network) && (network->subscribedToMulticastGroup(mg, true))) { RR->identity.address().appendTo(appendTo); ++totalKnown; ++added; @@ -91,19 +91,19 @@ unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const Mutex::Lock _l(_groups_m); - const MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); - if ((s)&&(!s->members.empty())) { + const MulticastGroupStatus* s = _groups.get(Multicaster::Key(nwid, mg)); + if ((s) && (! s->members.empty())) { totalKnown += (unsigned int)s->members.size(); // Members are returned in random order so that repeated gather queries // will return different subsets of a large multicast group. k = 0; - while ((added < limit)&&(k < s->members.size())&&((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_PROTO_MAX_PACKET_LENGTH)) { + while ((added < limit) && (k < s->members.size()) && ((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_PROTO_MAX_PACKET_LENGTH)) { rptr = (unsigned int)RR->node->prng(); -restart_member_scan: + restart_member_scan: a = s->members[rptr % (unsigned int)s->members.size()].address.toInt(); - for(i=0;i> 32) & 0xff); *(p++) = (unsigned char)((a >> 24) & 0xff); *(p++) = (unsigned char)((a >> 16) & 0xff); @@ -123,21 +123,21 @@ restart_member_scan: } } - appendTo.setAt(totalAt,(uint32_t)totalKnown); - appendTo.setAt(addedAt,(uint16_t)added); + appendTo.setAt(totalAt, (uint32_t)totalKnown); + appendTo.setAt(addedAt, (uint16_t)added); return added; } -std::vector
Multicaster::getMembers(uint64_t nwid,const MulticastGroup &mg,unsigned int limit) const +std::vector
Multicaster::getMembers(uint64_t nwid, const MulticastGroup& mg, unsigned int limit) const { std::vector
ls; Mutex::Lock _l(_groups_m); - const MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); - if (!s) { + const MulticastGroupStatus* s = _groups.get(Multicaster::Key(nwid, mg)); + if (! s) { return ls; } - for(std::vector::const_reverse_iterator m(s->members.rbegin());m!=s->members.rend();++m) { + for (std::vector::const_reverse_iterator m(s->members.rbegin()); m != s->members.rend(); ++m) { ls.push_back(m->address); if (ls.size() >= limit) { break; @@ -146,19 +146,10 @@ std::vector
Multicaster::getMembers(uint64_t nwid,const MulticastGroup return ls; } -void Multicaster::send( - void *tPtr, - int64_t now, - const SharedPtr &network, - const Address &origin, - const MulticastGroup &mg, - const MAC &src, - unsigned int etherType, - const void *data, - unsigned int len) +void Multicaster::send(void* tPtr, int64_t now, const SharedPtr& network, const Address& origin, const MulticastGroup& mg, const MAC& src, unsigned int etherType, const void* data, unsigned int len) { unsigned long idxbuf[4096]; - unsigned long *indexes = idxbuf; + unsigned long* indexes = idxbuf; // If we're in hub-and-spoke designated multicast replication mode, see if we // have a multicast replicator active. If so, pick the best and send it @@ -168,19 +159,19 @@ void Multicaster::send( // the current protocol and could be fixed, but fixing it would add more // complexity than the fix is probably worth. Bridges are generally high // bandwidth nodes. - if (!network->config().isActiveBridge(RR->identity.address())) { + if (! network->config().isActiveBridge(RR->identity.address())) { Address multicastReplicators[ZT_MAX_NETWORK_SPECIALISTS]; const unsigned int multicastReplicatorCount = network->config().multicastReplicators(multicastReplicators); if (multicastReplicatorCount) { - if (std::find(multicastReplicators,multicastReplicators + multicastReplicatorCount,RR->identity.address()) == (multicastReplicators + multicastReplicatorCount)) { + if (std::find(multicastReplicators, multicastReplicators + multicastReplicatorCount, RR->identity.address()) == (multicastReplicators + multicastReplicatorCount)) { SharedPtr bestMulticastReplicator; SharedPtr bestMulticastReplicatorPath; unsigned int bestMulticastReplicatorLatency = 0xffff; - for(unsigned int i=0;i p(RR->topology->getPeerNoCache(multicastReplicators[i])); - if ((p)&&(p->isAlive(now))) { - const SharedPtr pp(p->getAppropriatePath(now,false)); - if ((pp)&&(pp->latency() < bestMulticastReplicatorLatency)) { + if ((p) && (p->isAlive(now))) { + const SharedPtr pp(p->getAppropriatePath(now, false)); + if ((pp) && (pp->latency() < bestMulticastReplicatorLatency)) { bestMulticastReplicatorLatency = pp->latency(); bestMulticastReplicatorPath = pp; bestMulticastReplicator = p; @@ -188,20 +179,20 @@ void Multicaster::send( } } if (bestMulticastReplicator) { - Packet outp(bestMulticastReplicator->address(),RR->identity.address(),Packet::VERB_MULTICAST_FRAME); + Packet outp(bestMulticastReplicator->address(), RR->identity.address(), Packet::VERB_MULTICAST_FRAME); outp.append((uint64_t)network->id()); - outp.append((uint8_t)0x0c); // includes source MAC | please replicate - ((src) ? src : MAC(RR->identity.address(),network->id())).appendTo(outp); + outp.append((uint8_t)0x0c); // includes source MAC | please replicate + ((src) ? src : MAC(RR->identity.address(), network->id())).appendTo(outp); mg.mac().appendTo(outp); outp.append((uint32_t)mg.adi()); outp.append((uint16_t)etherType); - outp.append(data,len); - if (!network->config().disableCompression()) { + outp.append(data, len); + if (! network->config().disableCompression()) { outp.compress(); } - outp.armor(bestMulticastReplicator->key(),true,bestMulticastReplicator->aesKeysIfSupported()); + outp.armor(bestMulticastReplicator->key(), true, bestMulticastReplicator->aesKeysIfSupported()); Metrics::pkt_multicast_frame_out++; - bestMulticastReplicatorPath->send(RR,tPtr,outp.data(),outp.size(),now); + bestMulticastReplicatorPath->send(RR, tPtr, outp.data(), outp.size(), now); return; } } @@ -210,19 +201,19 @@ void Multicaster::send( try { Mutex::Lock _l(_groups_m); - MulticastGroupStatus &gs = _groups[Multicaster::Key(network->id(),mg)]; + MulticastGroupStatus& gs = _groups[Multicaster::Key(network->id(), mg)]; - if (!gs.members.empty()) { + if (! gs.members.empty()) { // Allocate a memory buffer if group is monstrous if (gs.members.size() > (sizeof(idxbuf) / sizeof(unsigned long))) { indexes = new unsigned long[gs.members.size()]; } // Generate a random permutation of member indexes - for(unsigned long i=0;i0;--i) { + for (unsigned long i = (unsigned long)gs.members.size() - 1; i > 0; --i) { unsigned long j = (unsigned long)RR->node->prng() % (i + 1); unsigned long tmp = indexes[j]; indexes[j] = indexes[i]; @@ -244,7 +235,7 @@ void Multicaster::send( network->id(), network->config().disableCompression(), limit, - 1, // we'll still gather a little from peers to keep multicast list fresh + 1, // we'll still gather a little from peers to keep multicast list fresh src, mg, etherType, @@ -253,9 +244,9 @@ void Multicaster::send( unsigned int count = 0; - for(unsigned int i=0;iidentity.address())&&(activeBridges[i] != origin)) { - out.sendOnly(RR,tPtr,activeBridges[i]); // optimization: don't use dedup log if it's a one-pass send + for (unsigned int i = 0; i < activeBridgeCount; ++i) { + if ((activeBridges[i] != RR->identity.address()) && (activeBridges[i] != origin)) { + out.sendOnly(RR, tPtr, activeBridges[i]); // optimization: don't use dedup log if it's a one-pass send if (++count >= limit) { break; } @@ -263,14 +254,15 @@ void Multicaster::send( } unsigned long idx = 0; - while ((count < limit)&&(idx < gs.members.size())) { + while ((count < limit) && (idx < gs.members.size())) { const Address ma(gs.members[indexes[idx++]].address); - if ((std::find(activeBridges,activeBridges + activeBridgeCount,ma) == (activeBridges + activeBridgeCount))&&(ma != origin)) { - out.sendOnly(RR,tPtr,ma); // optimization: don't use dedup log if it's a one-pass send + if ((std::find(activeBridges, activeBridges + activeBridgeCount, ma) == (activeBridges + activeBridgeCount)) && (ma != origin)) { + out.sendOnly(RR, tPtr, ma); // optimization: don't use dedup log if it's a one-pass send ++count; } } - } else { + } + else { while (gs.txQueue.size() >= ZT_TX_QUEUE_SIZE) { gs.txQueue.pop_front(); } @@ -278,7 +270,7 @@ void Multicaster::send( const unsigned int gatherLimit = (limit - (unsigned int)gs.members.size()) + 1; int timerScale = RR->node->lowBandwidthModeEnabled() ? 3 : 1; - if ((gs.members.empty())||((now - gs.lastExplicitGather) >= (ZT_MULTICAST_EXPLICIT_GATHER_DELAY * timerScale))) { + if ((gs.members.empty()) || ((now - gs.lastExplicitGather) >= (ZT_MULTICAST_EXPLICIT_GATHER_DELAY * timerScale))) { gs.lastExplicitGather = now; Address explicitGatherPeers[16]; @@ -294,10 +286,10 @@ void Multicaster::send( Address ac[ZT_MAX_NETWORK_SPECIALISTS]; const unsigned int accnt = network->config().alwaysContactAddresses(ac); unsigned int shuffled[ZT_MAX_NETWORK_SPECIALISTS]; - for(unsigned int i=0;i>1;i> 1; i < k; ++i) { const uint64_t x = RR->node->prng(); const unsigned int x1 = shuffled[(unsigned int)x % accnt]; const unsigned int x2 = shuffled[(unsigned int)(x >> 32) % accnt]; @@ -305,7 +297,7 @@ void Multicaster::send( shuffled[x1] = shuffled[x2]; shuffled[x2] = tmp; } - for(unsigned int i=0;i anchors(network->config().anchors()); - for(std::vector
::const_iterator a(anchors.begin());a!=anchors.end();++a) { + for (std::vector
::const_iterator a(anchors.begin()); a != anchors.end(); ++a) { if (*a != RR->identity.address()) { explicitGatherPeers[numExplicitGatherPeers++] = *a; if (numExplicitGatherPeers == 16) { @@ -322,9 +314,9 @@ void Multicaster::send( } } - for(unsigned int k=0;kconfig().com) ? &(network->config().com) : (const CertificateOfMembership *)0) : (const CertificateOfMembership *)0; - Packet outp(explicitGatherPeers[k],RR->identity.address(),Packet::VERB_MULTICAST_GATHER); + for (unsigned int k = 0; k < numExplicitGatherPeers; ++k) { + const CertificateOfMembership* com = (network) ? ((network->config().com) ? &(network->config().com) : (const CertificateOfMembership*)0) : (const CertificateOfMembership*)0; + Packet outp(explicitGatherPeers[k], RR->identity.address(), Packet::VERB_MULTICAST_GATHER); outp.append(network->id()); outp.append((uint8_t)((com) ? 0x01 : 0x00)); mg.mac().appendTo(outp); @@ -334,26 +326,15 @@ void Multicaster::send( com->serialize(outp); } RR->node->expectReplyTo(outp.packetId()); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); Metrics::pkt_multicast_gather_out++; } } gs.txQueue.push_back(OutboundMulticast()); - OutboundMulticast &out = gs.txQueue.back(); + OutboundMulticast& out = gs.txQueue.back(); - out.init( - RR, - now, - network->id(), - network->config().disableCompression(), - limit, - gatherLimit, - src, - mg, - etherType, - data, - len); + out.init(RR, now, network->id(), network->config().disableCompression(), limit, gatherLimit, src, mg, etherType, data, len); if (origin) { out.logAsSent(origin); @@ -361,9 +342,9 @@ void Multicaster::send( unsigned int count = 0; - for(unsigned int i=0;iidentity.address()) { - out.sendAndLog(RR,tPtr,activeBridges[i]); + out.sendAndLog(RR, tPtr, activeBridges[i]); if (++count >= limit) { break; } @@ -371,33 +352,36 @@ void Multicaster::send( } unsigned long idx = 0; - while ((count < limit)&&(idx < gs.members.size())) { + while ((count < limit) && (idx < gs.members.size())) { Address ma(gs.members[indexes[idx++]].address); - if (std::find(activeBridges,activeBridges + activeBridgeCount,ma) == (activeBridges + activeBridgeCount)) { - out.sendAndLog(RR,tPtr,ma); + if (std::find(activeBridges, activeBridges + activeBridgeCount, ma) == (activeBridges + activeBridgeCount)) { + out.sendAndLog(RR, tPtr, ma); ++count; } } } - } catch ( ... ) {} // this is a sanity check to catch any failures and make sure indexes[] still gets deleted + } + catch (...) { + } // this is a sanity check to catch any failures and make sure indexes[] still gets deleted // Free allocated memory buffer if any if (indexes != idxbuf) { - delete [] indexes; + delete[] indexes; } } void Multicaster::clean(int64_t now) { Mutex::Lock _l(_groups_m); - Multicaster::Key *k = (Multicaster::Key *)0; - MulticastGroupStatus *s = (MulticastGroupStatus *)0; - Hashtable::Iterator mm(_groups); - while (mm.next(k,s)) { - for(std::list::iterator tx(s->txQueue.begin());tx!=s->txQueue.end();) { - if ((tx->expired(now))||(tx->atLimit())) { + Multicaster::Key* k = (Multicaster::Key*)0; + MulticastGroupStatus* s = (MulticastGroupStatus*)0; + Hashtable::Iterator mm(_groups); + while (mm.next(k, s)) { + for (std::list::iterator tx(s->txQueue.begin()); tx != s->txQueue.end();) { + if ((tx->expired(now)) || (tx->atLimit())) { s->txQueue.erase(tx++); - } else { + } + else { ++tx; } } @@ -418,15 +402,17 @@ void Multicaster::clean(int64_t now) if (count) { s->members.resize(count); - } else if (s->txQueue.empty()) { + } + else if (s->txQueue.empty()) { _groups.erase(*k); - } else { + } + else { s->members.clear(); } } } -void Multicaster::_add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member) +void Multicaster::_add(void* tPtr, int64_t now, uint64_t nwid, const MulticastGroup& mg, MulticastGroupStatus& gs, const Address& member) { // assumes _groups_m is locked @@ -435,29 +421,32 @@ void Multicaster::_add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup return; } - std::vector::iterator m(std::lower_bound(gs.members.begin(),gs.members.end(),member)); + std::vector::iterator m(std::lower_bound(gs.members.begin(), gs.members.end(), member)); if (m != gs.members.end()) { if (m->address == member) { m->timestamp = now; return; } - gs.members.insert(m,MulticastGroupMember(member,now)); - } else { - gs.members.push_back(MulticastGroupMember(member,now)); + gs.members.insert(m, MulticastGroupMember(member, now)); + } + else { + gs.members.push_back(MulticastGroupMember(member, now)); } - for(std::list::iterator tx(gs.txQueue.begin());tx!=gs.txQueue.end();) { + for (std::list::iterator tx(gs.txQueue.begin()); tx != gs.txQueue.end();) { if (tx->atLimit()) { gs.txQueue.erase(tx++); - } else { - tx->sendIfNew(RR,tPtr,member); + } + else { + tx->sendIfNew(RR, tPtr, member); if (tx->atLimit()) { gs.txQueue.erase(tx++); - } else { + } + else { ++tx; } } } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index 381171440..0cb6e8f8e 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -14,22 +14,21 @@ #ifndef ZT_MULTICASTER_HPP #define ZT_MULTICASTER_HPP -#include -#include - -#include -#include -#include - +#include "Address.hpp" #include "Constants.hpp" #include "Hashtable.hpp" -#include "Address.hpp" #include "MAC.hpp" #include "MulticastGroup.hpp" -#include "OutboundMulticast.hpp" -#include "Utils.hpp" #include "Mutex.hpp" +#include "OutboundMulticast.hpp" #include "SharedPtr.hpp" +#include "Utils.hpp" + +#include +#include +#include +#include +#include namespace ZeroTier { @@ -41,10 +40,9 @@ class Network; /** * Database of known multicast peers within a network */ -class Multicaster -{ -public: - Multicaster(const RuntimeEnvironment *renv); +class Multicaster { + public: + Multicaster(const RuntimeEnvironment* renv); ~Multicaster(); /** @@ -55,10 +53,10 @@ public: * @param mg Multicast group * @param member New member address */ - inline void add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member) + inline void add(void* tPtr, int64_t now, uint64_t nwid, const MulticastGroup& mg, const Address& member) { Mutex::Lock _l(_groups_m); - _add(tPtr,now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member); + _add(tPtr, now, nwid, mg, _groups[Multicaster::Key(nwid, mg)], member); } /** @@ -74,7 +72,7 @@ public: * @param count Number of addresses * @param totalKnown Total number of known addresses as reported by peer */ - void addMultiple(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown); + void addMultiple(void* tPtr, int64_t now, uint64_t nwid, const MulticastGroup& mg, const void* addresses, unsigned int count, unsigned int totalKnown); /** * Remove a multicast group member (if present) @@ -83,7 +81,7 @@ public: * @param mg Multicast group * @param member Member to unsubscribe */ - void remove(uint64_t nwid,const MulticastGroup &mg,const Address &member); + void remove(uint64_t nwid, const MulticastGroup& mg, const Address& member); /** * Append gather results to a packet by choosing registered multicast recipients at random @@ -103,7 +101,7 @@ public: * @return Number of addresses appended * @throws std::out_of_range Buffer overflow writing to packet */ - unsigned int gather(const Address &queryingPeer,uint64_t nwid,const MulticastGroup &mg,Buffer &appendTo,unsigned int limit) const; + unsigned int gather(const Address& queryingPeer, uint64_t nwid, const MulticastGroup& mg, Buffer& appendTo, unsigned int limit) const; /** * Get subscribers to a multicast group @@ -111,7 +109,7 @@ public: * @param nwid Network ID * @param mg Multicast group */ - std::vector
getMembers(uint64_t nwid,const MulticastGroup &mg,unsigned int limit) const; + std::vector
getMembers(uint64_t nwid, const MulticastGroup& mg, unsigned int limit) const; /** * Send a multicast @@ -126,16 +124,7 @@ public: * @param data Packet data * @param len Length of packet data */ - void send( - void *tPtr, - int64_t now, - const SharedPtr &network, - const Address &origin, - const MulticastGroup &mg, - const MAC &src, - unsigned int etherType, - const void *data, - unsigned int len); + void send(void* tPtr, int64_t now, const SharedPtr& network, const Address& origin, const MulticastGroup& mg, const MAC& src, unsigned int etherType, const void* data, unsigned int len); /** * Clean database @@ -145,53 +134,87 @@ public: */ void clean(int64_t now); -private: - struct Key - { - Key() : nwid(0),mg() {} - Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {} + private: + struct Key { + Key() : nwid(0), mg() + { + } + Key(uint64_t n, const MulticastGroup& g) : nwid(n), mg(g) + { + } uint64_t nwid; MulticastGroup mg; - inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); } - inline bool operator!=(const Key &k) const { return ((nwid != k.nwid)||(mg != k.mg)); } - inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); } + inline bool operator==(const Key& k) const + { + return ((nwid == k.nwid) && (mg == k.mg)); + } + inline bool operator!=(const Key& k) const + { + return ((nwid != k.nwid) || (mg != k.mg)); + } + inline unsigned long hashCode() const + { + return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); + } }; - struct MulticastGroupMember - { - MulticastGroupMember() {} - MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {} + struct MulticastGroupMember { + MulticastGroupMember() + { + } + MulticastGroupMember(const Address& a, uint64_t ts) : address(a), timestamp(ts) + { + } - inline bool operator<(const MulticastGroupMember &a) const { return (address < a.address); } - inline bool operator==(const MulticastGroupMember &a) const { return (address == a.address); } - inline bool operator!=(const MulticastGroupMember &a) const { return (address != a.address); } - inline bool operator<(const Address &a) const { return (address < a); } - inline bool operator==(const Address &a) const { return (address == a); } - inline bool operator!=(const Address &a) const { return (address != a); } + inline bool operator<(const MulticastGroupMember& a) const + { + return (address < a.address); + } + inline bool operator==(const MulticastGroupMember& a) const + { + return (address == a.address); + } + inline bool operator!=(const MulticastGroupMember& a) const + { + return (address != a.address); + } + inline bool operator<(const Address& a) const + { + return (address < a); + } + inline bool operator==(const Address& a) const + { + return (address == a); + } + inline bool operator!=(const Address& a) const + { + return (address != a); + } Address address; - int64_t timestamp; // time of last notification + int64_t timestamp; // time of last notification }; - struct MulticastGroupStatus - { - MulticastGroupStatus() : lastExplicitGather(0) {} + struct MulticastGroupStatus { + MulticastGroupStatus() : lastExplicitGather(0) + { + } int64_t lastExplicitGather; - std::list txQueue; // pending outbound multicasts - std::vector members; // members of this group + std::list txQueue; // pending outbound multicasts + std::vector members; // members of this group }; - void _add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member); + void _add(void* tPtr, int64_t now, uint64_t nwid, const MulticastGroup& mg, MulticastGroupStatus& gs, const Address& member); - const RuntimeEnvironment *const RR; + const RuntimeEnvironment* const RR; - Hashtable _groups; + Hashtable _groups; Mutex _groups_m; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Mutex.hpp b/node/Mutex.hpp index 8c5be7a8f..d708b4571 100644 --- a/node/Mutex.hpp +++ b/node/Mutex.hpp @@ -18,19 +18,18 @@ #ifdef __UNIX_LIKE__ +#include #include #include -#include namespace ZeroTier { // libpthread based mutex lock -class Mutex -{ -public: +class Mutex { + public: Mutex() { - pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); + pthread_mutex_init(&_mh, (const pthread_mutexattr_t*)0); } ~Mutex() @@ -40,25 +39,22 @@ public: inline void lock() const { - pthread_mutex_lock(&((const_cast (this))->_mh)); + pthread_mutex_lock(&((const_cast(this))->_mh)); } inline void unlock() const { - pthread_mutex_unlock(&((const_cast (this))->_mh)); + pthread_mutex_unlock(&((const_cast(this))->_mh)); } - class Lock - { - public: - Lock(Mutex &m) : - _m(&m) + class Lock { + public: + Lock(Mutex& m) : _m(&m) { m.lock(); } - Lock(const Mutex &m) : - _m(const_cast(&m)) + Lock(const Mutex& m) : _m(const_cast(&m)) { _m->lock(); } @@ -68,18 +64,23 @@ public: _m->unlock(); } - private: - Mutex *const _m; + private: + Mutex* const _m; }; -private: - Mutex(const Mutex &) {} - const Mutex &operator=(const Mutex &) { return *this; } + private: + Mutex(const Mutex&) + { + } + const Mutex& operator=(const Mutex&) + { + return *this; + } pthread_mutex_t _mh; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif @@ -91,9 +92,8 @@ private: namespace ZeroTier { // Windows critical section based lock -class Mutex -{ -public: +class Mutex { + public: Mutex() { InitializeCriticalSection(&_cs); @@ -116,25 +116,22 @@ public: inline void lock() const { - (const_cast (this))->lock(); + (const_cast(this))->lock(); } inline void unlock() const { - (const_cast (this))->unlock(); + (const_cast(this))->unlock(); } - class Lock - { - public: - Lock(Mutex &m) : - _m(&m) + class Lock { + public: + Lock(Mutex& m) : _m(&m) { m.lock(); } - Lock(const Mutex &m) : - _m(const_cast(&m)) + Lock(const Mutex& m) : _m(const_cast(&m)) { _m->lock(); } @@ -144,19 +141,24 @@ public: _m->unlock(); } - private: - Mutex *const _m; + private: + Mutex* const _m; }; -private: - Mutex(const Mutex &) {} - const Mutex &operator=(const Mutex &) { return *this; } + private: + Mutex(const Mutex&) + { + } + const Mutex& operator=(const Mutex&) + { + return *this; + } CRITICAL_SECTION _cs; }; -} // namespace ZeroTier +} // namespace ZeroTier -#endif // _WIN32 +#endif // _WIN32 #endif diff --git a/node/Network.cpp b/node/Network.cpp index 1643487fe..70587a51c 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -11,37 +11,36 @@ */ /****/ -#include -#include -#include -#include +#include "Network.hpp" #include "../include/ZeroTierDebug.h" - -#include "Constants.hpp" #include "../version.h" -#include "Network.hpp" -#include "RuntimeEnvironment.hpp" -#include "MAC.hpp" #include "Address.hpp" -#include "InetAddress.hpp" -#include "Switch.hpp" #include "Buffer.hpp" -#include "Packet.hpp" +#include "Constants.hpp" +#include "InetAddress.hpp" +#include "MAC.hpp" +#include "Metrics.hpp" #include "NetworkController.hpp" #include "Node.hpp" +#include "Packet.hpp" #include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" #include "Trace.hpp" -#include "Metrics.hpp" +#include #include +#include +#include +#include namespace ZeroTier { namespace { // Returns true if packet appears valid; pos and proto will be set -static inline bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsigned int &pos,unsigned int &proto) +static inline bool _ipv6GetPayload(const uint8_t* frameData, unsigned int frameLen, unsigned int& pos, unsigned int& proto) { if (frameLen < 40) { return false; @@ -49,57 +48,50 @@ static inline bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLe pos = 40; proto = frameData[6]; while (pos <= frameLen) { - switch(proto) { - case 0: // hop-by-hop options - case 43: // routing - case 60: // destination options - case 135: // mobility options + switch (proto) { + case 0: // hop-by-hop options + case 43: // routing + case 60: // destination options + case 135: // mobility options if ((pos + 8) > frameLen) { - return false; // invalid! + return false; // invalid! } proto = frameData[pos]; pos += ((unsigned int)frameData[pos + 1] * 8) + 8; break; - //case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway - //case 50: - //case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff + // case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway + // case 50: + // case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff default: return true; } } - return false; // overflow == invalid + return false; // overflow == invalid } -enum _doZtFilterResult -{ - DOZTFILTER_NO_MATCH, - DOZTFILTER_DROP, - DOZTFILTER_REDIRECT, - DOZTFILTER_ACCEPT, - DOZTFILTER_SUPER_ACCEPT -}; +enum _doZtFilterResult { DOZTFILTER_NO_MATCH, DOZTFILTER_DROP, DOZTFILTER_REDIRECT, DOZTFILTER_ACCEPT, DOZTFILTER_SUPER_ACCEPT }; static _doZtFilterResult _doZtFilter( - const RuntimeEnvironment *RR, - Trace::RuleResultLog &rrl, - const NetworkConfig &nconf, - const Membership *membership, // can be NULL + const RuntimeEnvironment* RR, + Trace::RuleResultLog& rrl, + const NetworkConfig& nconf, + const Membership* membership, // can be NULL const bool inbound, - const Address &ztSource, - Address &ztDest, // MUTABLE -- is changed on REDIRECT actions - const MAC &macSource, - const MAC &macDest, - const uint8_t *const frameData, + const Address& ztSource, + Address& ztDest, // MUTABLE -- is changed on REDIRECT actions + const MAC& macSource, + const MAC& macDest, + const uint8_t* const frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId, - const ZT_VirtualNetworkRule *rules, // cannot be NULL + const ZT_VirtualNetworkRule* rules, // cannot be NULL const unsigned int ruleCount, - Address &cc, // MUTABLE -- set to TEE destination if TEE action is taken or left alone otherwise - unsigned int &ccLength, // MUTABLE -- set to length of packet payload to TEE - bool &ccWatch, // MUTABLE -- set to true for WATCH target as opposed to normal TEE - uint8_t &qosBucket) // MUTABLE -- set to the value of the argument provided to PRIORITY + Address& cc, // MUTABLE -- set to TEE destination if TEE action is taken or left alone otherwise + unsigned int& ccLength, // MUTABLE -- set to length of packet payload to TEE + bool& ccWatch, // MUTABLE -- set to true for WATCH target as opposed to normal TEE + uint8_t& qosBucket) // MUTABLE -- set to the value of the argument provided to PRIORITY { // Set to true if we are a TEE/REDIRECT/WATCH target bool superAccept = false; @@ -114,68 +106,75 @@ static _doZtFilterResult _doZtFilter( // uncomment for easier debugging fprintf // if (!ztDest) { return DOZTFILTER_ACCEPT; } #ifdef ZT_TRACE - //char buf[40], buf2[40]; - //fprintf(stderr, "\nsrc %s dest %s inbound: %d ethertype %u", ztSource.toString(buf), ztDest.toString(buf2), inbound, etherType); + // char buf[40], buf2[40]; + // fprintf(stderr, "\nsrc %s dest %s inbound: %d ethertype %u", ztSource.toString(buf), ztDest.toString(buf2), inbound, etherType); #endif - for(unsigned int rn=0;rnidentity.address()) { + } + else if (fwdAddr == RR->identity.address()) { if (inbound) { return DOZTFILTER_SUPER_ACCEPT; - } else { } - } else if (fwdAddr == ztDest) { - } else { + else { + } + } + else if (fwdAddr == ztDest) { + } + else { if (rt == ZT_NETWORK_RULE_ACTION_REDIRECT) { ztDest = fwdAddr; return DOZTFILTER_REDIRECT; - } else { + } + else { cc = fwdAddr; ccLength = (rules[rn].v.fwd.length != 0) ? ((frameLen < (unsigned int)rules[rn].v.fwd.length) ? frameLen : (unsigned int)rules[rn].v.fwd.length) : frameLen; ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH); } } - } continue; + } + continue; case ZT_NETWORK_RULE_ACTION_BREAK: return DOZTFILTER_NO_MATCH; @@ -184,12 +183,13 @@ static _doZtFilterResult _doZtFilter( default: continue; } - } else { + } + else { // If this is an incoming packet and we are a TEE or REDIRECT target, we should // super-accept if we accept at all. This will cause us to accept redirected or // tee'd packets in spite of MAC and ZT addressing checks. if (inbound) { - switch(rt) { + switch (rt) { case ZT_NETWORK_RULE_ACTION_TEE: case ZT_NETWORK_RULE_ACTION_WATCH: case ZT_NETWORK_RULE_ACTION_REDIRECT: @@ -202,25 +202,25 @@ static _doZtFilterResult _doZtFilter( } } - thisSetMatches = 1; // reset to default true for next batch of entries + thisSetMatches = 1; // reset to default true for next batch of entries continue; } } // Circuit breaker: no need to evaluate an AND if the set's match state // is currently false since anything AND false is false. - if ((!thisSetMatches)&&(!(rules[rn].t & 0x40))) { - rrl.logSkipped(rn,thisSetMatches); + if ((! thisSetMatches) && (! (rules[rn].t & 0x40))) { + rrl.logSkipped(rn, thisSetMatches); continue; } // If this was not an ACTION evaluate next MATCH and update thisSetMatches with (AND [result]) uint8_t thisRuleMatches = 0; - uint64_t ownershipVerificationMask = 1; // this magic value means it hasn't been computed yet -- this is done lazily the first time it's needed - uint8_t hardYes = (rules[rn].t >> 7) ^ 1; // XOR with the NOT bit of the rule + uint64_t ownershipVerificationMask = 1; // this magic value means it hasn't been computed yet -- this is done lazily the first time it's needed + uint8_t hardYes = (rules[rn].t >> 7) ^ 1; // XOR with the NOT bit of the rule uint8_t hardNo = (rules[rn].t >> 7) ^ 0; - switch(rt) { + switch (rt) { case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS: thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztSource.toInt()); break; @@ -239,61 +239,70 @@ static _doZtFilterResult _doZtFilter( thisRuleMatches = (uint8_t)(rules[rn].v.vlanDei == 0); break; case ZT_NETWORK_RULE_MATCH_MAC_SOURCE: - thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac,6) == macSource); + thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac, 6) == macSource); break; case ZT_NETWORK_RULE_MATCH_MAC_DEST: - thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac,6) == macDest); + thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac, 6) == macDest); break; case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { - thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 12),4,0))); - } else { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { + thisRuleMatches = (uint8_t)(InetAddress((const void*)&(rules[rn].v.ipv4.ip), 4, rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void*)(frameData + 12), 4, 0))); + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IPV4_DEST: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { - thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 16),4,0))); - } else { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { + thisRuleMatches = (uint8_t)(InetAddress((const void*)&(rules[rn].v.ipv4.ip), 4, rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void*)(frameData + 16), 4, 0))); + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE: - if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) { - thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 8),16,0))); - } else { + if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) { + thisRuleMatches = (uint8_t)(InetAddress((const void*)rules[rn].v.ipv6.ip, 16, rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void*)(frameData + 8), 16, 0))); + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IPV6_DEST: - if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) { - thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 24),16,0))); - } else { + if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) { + thisRuleMatches = (uint8_t)(InetAddress((const void*)rules[rn].v.ipv6.ip, 16, rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void*)(frameData + 24), 16, 0))); + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IP_TOS: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { const uint8_t tosMasked = frameData[1] & rules[rn].v.ipTos.mask; - thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1])); - } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) { + thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1])); + } + else if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) { const uint8_t tosMasked = (((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f)) & rules[rn].v.ipTos.mask; - thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1])); - } else { + thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1])); + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == frameData[9]); - } else if (etherType == ZT_ETHERTYPE_IPV6) { - unsigned int pos = 0,proto = 0; - if (_ipv6GetPayload(frameData,frameLen,pos,proto)) { + } + else if (etherType == ZT_ETHERTYPE_IPV6) { + unsigned int pos = 0, proto = 0; + if (_ipv6GetPayload(frameData, frameLen, pos, proto)) { thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto); - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } break; @@ -301,59 +310,69 @@ static _doZtFilterResult _doZtFilter( thisRuleMatches = (uint8_t)(rules[rn].v.etherType == (uint16_t)etherType); break; case ZT_NETWORK_RULE_MATCH_ICMP: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { - if (frameData[9] == 0x01) { // IP protocol == ICMP + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { + if (frameData[9] == 0x01) { // IP protocol == ICMP const unsigned int ihl = (frameData[0] & 0xf) * 4; if (frameLen >= (ihl + 2)) { if (rules[rn].v.icmp.type == frameData[ihl]) { if ((rules[rn].v.icmp.flags & 0x01) != 0) { - thisRuleMatches = (uint8_t)(frameData[ihl+1] == rules[rn].v.icmp.code); - } else { + thisRuleMatches = (uint8_t)(frameData[ihl + 1] == rules[rn].v.icmp.code); + } + else { thisRuleMatches = hardYes; } - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } - } else if (etherType == ZT_ETHERTYPE_IPV6) { - unsigned int pos = 0,proto = 0; - if (_ipv6GetPayload(frameData,frameLen,pos,proto)) { - if ((proto == 0x3a)&&(frameLen >= (pos+2))) { + } + else if (etherType == ZT_ETHERTYPE_IPV6) { + unsigned int pos = 0, proto = 0; + if (_ipv6GetPayload(frameData, frameLen, pos, proto)) { + if ((proto == 0x3a) && (frameLen >= (pos + 2))) { if (rules[rn].v.icmp.type == frameData[pos]) { if ((rules[rn].v.icmp.flags & 0x01) != 0) { - thisRuleMatches = (uint8_t)(frameData[pos+1] == rules[rn].v.icmp.code); - } else { + thisRuleMatches = (uint8_t)(frameData[pos + 1] == rules[rn].v.icmp.code); + } + else { thisRuleMatches = hardYes; } - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } break; case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE: case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE: - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { const unsigned int headerLen = 4 * (frameData[0] & 0xf); int p = -1; - switch(frameData[9]) { // IP protocol number + switch (frameData[9]) { // IP protocol number // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (frameLen > (headerLen + 4)) { unsigned int pos = headerLen + ((rt == ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE) ? 2 : 0); p = (int)frameData[pos++] << 8; @@ -362,17 +381,18 @@ static _doZtFilterResult _doZtFilter( break; } - thisRuleMatches = (p >= 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0; - } else if (etherType == ZT_ETHERTYPE_IPV6) { - unsigned int pos = 0,proto = 0; - if (_ipv6GetPayload(frameData,frameLen,pos,proto)) { + thisRuleMatches = (p >= 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0]) && (p <= (int)rules[rn].v.port[1])) : (uint8_t)0; + } + else if (etherType == ZT_ETHERTYPE_IPV6) { + unsigned int pos = 0, proto = 0; + if (_ipv6GetPayload(frameData, frameLen, pos, proto)) { int p = -1; - switch(proto) { // IP protocol number + switch (proto) { // IP protocol number // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (frameLen > (pos + 4)) { if (rt == ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE) { pos += 2; @@ -382,11 +402,13 @@ static _doZtFilterResult _doZtFilter( } break; } - thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0; - } else { + thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0]) && (p <= (int)rules[rn].v.port[1])) : (uint8_t)0; + } + else { thisRuleMatches = hardNo; } - } else { + } + else { thisRuleMatches = hardNo; } break; @@ -401,39 +423,44 @@ static _doZtFilterResult _doZtFilter( if (ownershipVerificationMask == 1) { ownershipVerificationMask = 0; InetAddress src; - if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) { - src.set((const void *)(frameData + 12),4,0); - } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) { + src.set((const void*)(frameData + 12), 4, 0); + } + else if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) { // IPv6 NDP requires special handling, since the src and dest IPs in the packet are empty or link-local. - if ( (frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87)||(frameData[40] == 0x88)) ) { + if ((frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87) || (frameData[40] == 0x88))) { if (frameData[40] == 0x87) { // Neighbor solicitations contain no reliable source address, so we implement a small // hack by considering them authenticated. Otherwise you would pretty much have to do // this manually in the rule set for IPv6 to work at all. ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED; - } else { - // Neighbor advertisements on the other hand can absolutely be authenticated. - src.set((const void *)(frameData + 40 + 8),16,0); } - } else { - // Other IPv6 packets can be handled normally - src.set((const void *)(frameData + 8),16,0); + else { + // Neighbor advertisements on the other hand can absolutely be authenticated. + src.set((const void*)(frameData + 40 + 8), 16, 0); + } } - } else if ((etherType == ZT_ETHERTYPE_ARP)&&(frameLen >= 28)) { - src.set((const void *)(frameData + 14),4,0); + else { + // Other IPv6 packets can be handled normally + src.set((const void*)(frameData + 8), 16, 0); + } + } + else if ((etherType == ZT_ETHERTYPE_ARP) && (frameLen >= 28)) { + src.set((const void*)(frameData + 14), 4, 0); } if (inbound) { if (membership) { - if ((src)&&(membership->hasCertificateOfOwnershipFor(nconf,src))) { + if ((src) && (membership->hasCertificateOfOwnershipFor(nconf, src))) { ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED; } - if (membership->hasCertificateOfOwnershipFor(nconf,macSource)) { + if (membership->hasCertificateOfOwnershipFor(nconf, macSource)) { ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED; } } - } else { - for(unsigned int i=0;i= 20)&&(frameData[9] == 0x06)) { + if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20) && (frameData[9] == 0x06)) { const unsigned int headerLen = 4 * (frameData[0] & 0xf); cf |= (uint64_t)frameData[headerLen + 13]; cf |= (((uint64_t)(frameData[headerLen + 12] & 0x0f)) << 8); - } else if (etherType == ZT_ETHERTYPE_IPV6) { - unsigned int pos = 0,proto = 0; - if (_ipv6GetPayload(frameData,frameLen,pos,proto)) { - if ((proto == 0x06)&&(frameLen > (pos + 14))) { + } + else if (etherType == ZT_ETHERTYPE_IPV6) { + unsigned int pos = 0, proto = 0; + if (_ipv6GetPayload(frameData, frameLen, pos, proto)) { + if ((proto == 0x06) && (frameLen > (pos + 14))) { cf |= (uint64_t)frameData[pos + 13]; cf |= (((uint64_t)(frameData[pos + 12] & 0x0f)) << 8); } } } thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics) != 0); - } break; + } break; case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE: - thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0])&&(frameLen <= (unsigned int)rules[rn].v.frameSize[1])); + thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0]) && (frameLen <= (unsigned int)rules[rn].v.frameSize[1])); break; case ZT_NETWORK_RULE_MATCH_RANDOM: thisRuleMatches = (uint8_t)((uint32_t)(RR->node->prng() & 0xffffffffULL) <= rules[rn].v.randomProbability); @@ -469,9 +497,9 @@ static _doZtFilterResult _doZtFilter( case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: { - const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate()); - if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) { - const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0); + const Tag* const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, Tag::IdComparePredicate()); + if ((localTag != &(nconf.tags[nconf.tagCount])) && (localTag->id() == rules[rn].v.tag.id)) { + const Tag* const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const Tag*)0); #ifdef ZT_TRACE /*fprintf(stderr, "\tlocal tag [%u: %u] remote tag [%u: %u] match [%u]", !!localTag ? localTag->id() : 0, @@ -486,24 +514,31 @@ static _doZtFilterResult _doZtFilter( if (rt == ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE) { const uint32_t diff = (ltv > rtv) ? (ltv - rtv) : (rtv - ltv); thisRuleMatches = (uint8_t)(diff <= rules[rn].v.tag.value); - } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND) { + } + else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND) { thisRuleMatches = (uint8_t)((ltv & rtv) == rules[rn].v.tag.value); - } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR) { + } + else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR) { thisRuleMatches = (uint8_t)((ltv | rtv) == rules[rn].v.tag.value); - } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) { + } + else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) { thisRuleMatches = (uint8_t)((ltv ^ rtv) == rules[rn].v.tag.value); - } else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) { - thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value)&&(rtv == rules[rn].v.tag.value)); - } else { // sanity check, can't really happen + } + else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) { + thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value) && (rtv == rules[rn].v.tag.value)); + } + else { // sanity check, can't really happen thisRuleMatches = hardNo; } - } else { - if ((inbound)&&(!superAccept)) { + } + else { + if ((inbound) && (! superAccept)) { thisRuleMatches = hardNo; #ifdef ZT_TRACE - //fprintf(stderr, "\tinbound "); + // fprintf(stderr, "\tinbound "); #endif - } else { + } + else { // Outbound side is not strict since if we have to match both tags and // we are sending a first packet to a recipient, we probably do not know // about their tags yet. They will filter on inbound and we will filter @@ -512,55 +547,61 @@ static _doZtFilterResult _doZtFilter( skipDrop = 1; thisRuleMatches = hardYes; #ifdef ZT_TRACE - //fprintf(stderr, "\toutbound "); + // fprintf(stderr, "\toutbound "); #endif } } - } else { + } + else { thisRuleMatches = hardNo; } - } break; + } break; case ZT_NETWORK_RULE_MATCH_TAG_SENDER: case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: { - const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate()); + const Tag* const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, Tag::IdComparePredicate()); #ifdef ZT_TRACE - /*const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0); - fprintf(stderr, "\tlocal tag [%u: %u] remote tag [%u: %u] match [%u]", - !!localTag ? localTag->id() : 0, - !!localTag ? localTag->value() : 0, - !!remoteTag ? remoteTag->id() : 0, - !!remoteTag ? remoteTag->value() : 0, - thisRuleMatches);*/ + /*const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0); + fprintf(stderr, "\tlocal tag [%u: %u] remote tag [%u: %u] match [%u]", + !!localTag ? localTag->id() : 0, + !!localTag ? localTag->value() : 0, + !!remoteTag ? remoteTag->id() : 0, + !!remoteTag ? remoteTag->value() : 0, + thisRuleMatches);*/ #endif if (superAccept) { skipDrop = 1; thisRuleMatches = hardYes; - } else if ( ((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER)&&(inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER)&&(!inbound)) ) { - const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0); + } + else if (((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER) && (inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) && (! inbound))) { + const Tag* const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const Tag*)0); if (remoteTag) { thisRuleMatches = (uint8_t)(remoteTag->value() == rules[rn].v.tag.value); - } else { + } + else { if (rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) { // If we are checking the receiver and this is an outbound packet, we // can't be strict since we may not yet know the receiver's tag. skipDrop = 1; thisRuleMatches = hardYes; - } else { + } + else { thisRuleMatches = hardNo; } } - } else { // sender and outbound or receiver and inbound - if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) { + } + else { // sender and outbound or receiver and inbound + if ((localTag != &(nconf.tags[nconf.tagCount])) && (localTag->id() == rules[rn].v.tag.id)) { thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value); - } else { + } + else { thisRuleMatches = hardNo; } } - } break; + } break; case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: { uint64_t integer = 0; const unsigned int bits = (rules[rn].v.intRange.format & 63) + 1; - const unsigned int bytes = ((bits + 8 - 1) / 8); // integer ceiling of division by 8 + const unsigned int bytes = ((bits + 8 - 1) / 8); // integer ceiling of division by 8 if ((rules[rn].v.intRange.format & 0x80) == 0) { // Big-endian unsigned int idx = rules[rn].v.intRange.idx + (8 - bytes); @@ -572,7 +613,8 @@ static _doZtFilterResult _doZtFilter( } } integer &= 0xffffffffffffffffULL >> (64 - bits); - } else { + } + else { // Little-endian unsigned int idx = rules[rn].v.intRange.idx; const unsigned int eof = idx + bytes; @@ -584,8 +626,8 @@ static _doZtFilterResult _doZtFilter( } integer >>= (64 - bits); } - thisRuleMatches = (uint8_t)((integer >= rules[rn].v.intRange.start)&&(integer <= (rules[rn].v.intRange.start + (uint64_t)rules[rn].v.intRange.end))); - } break; + thisRuleMatches = (uint8_t)((integer >= rules[rn].v.intRange.start) && (integer <= (rules[rn].v.intRange.start + (uint64_t)rules[rn].v.intRange.end))); + } break; // The result of an unsupported MATCH is configurable at the network // level via a flag. @@ -594,11 +636,12 @@ static _doZtFilterResult _doZtFilter( break; } - rrl.log(rn,thisRuleMatches,thisSetMatches); + rrl.log(rn, thisRuleMatches, thisSetMatches); if ((rules[rn].t & 0x40)) { thisSetMatches |= (thisRuleMatches ^ ((rules[rn].t >> 7) & 1)); - } else { + } + else { thisSetMatches &= (thisRuleMatches ^ ((rules[rn].t >> 7) & 1)); } } @@ -606,68 +649,73 @@ static _doZtFilterResult _doZtFilter( return DOZTFILTER_NO_MATCH; } -} // anonymous namespace +} // anonymous namespace -const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL),0); +const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL), 0); -Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr,const NetworkConfig *nconf) : - RR(renv), - _uPtr(uptr), - _id(nwid), - _nwidStr(OSUtils::networkIDStr(nwid)), - _lastAnnouncedMulticastGroupsUpstream(0), - _mac(renv->identity.address(),nwid), - _portInitialized(false), - _lastConfigUpdate(0), - _destroyed(false), - _netconfFailure(NETCONF_FAILURE_NONE), - _portError(0), - _num_multicast_groups{Metrics::network_num_multicast_groups.Add({{"network_id", _nwidStr}})}, - _incoming_packets_accepted{Metrics::network_packets.Add({{"direction","rx"},{"network_id", _nwidStr},{"accepted","yes"}})}, - _incoming_packets_dropped{Metrics::network_packets.Add({{"direction","rx"},{"network_id", _nwidStr},{"accepted","no"}})}, - _outgoing_packets_accepted{Metrics::network_packets.Add({{"direction","tx"},{"network_id", _nwidStr},{"accepted","yes"}})}, - _outgoing_packets_dropped{Metrics::network_packets.Add({{"direction","tx"},{"network_id", _nwidStr},{"accepted","no"}})} +Network::Network(const RuntimeEnvironment* renv, void* tPtr, uint64_t nwid, void* uptr, const NetworkConfig* nconf) + : RR(renv) + , _uPtr(uptr) + , _id(nwid) + , _nwidStr(OSUtils::networkIDStr(nwid)) + , _lastAnnouncedMulticastGroupsUpstream(0) + , _mac(renv->identity.address(), nwid) + , _portInitialized(false) + , _lastConfigUpdate(0) + , _destroyed(false) + , _netconfFailure(NETCONF_FAILURE_NONE) + , _portError(0) + , _num_multicast_groups { Metrics::network_num_multicast_groups.Add({ { "network_id", _nwidStr } }) } + , _incoming_packets_accepted { Metrics::network_packets.Add({ { "direction", "rx" }, { "network_id", _nwidStr }, { "accepted", "yes" } }) } + , _incoming_packets_dropped { Metrics::network_packets.Add({ { "direction", "rx" }, { "network_id", _nwidStr }, { "accepted", "no" } }) } + , _outgoing_packets_accepted { Metrics::network_packets.Add({ { "direction", "tx" }, { "network_id", _nwidStr }, { "accepted", "yes" } }) } + , _outgoing_packets_dropped { Metrics::network_packets.Add({ { "direction", "tx" }, { "network_id", _nwidStr }, { "accepted", "no" } }) } { - for(int i=0;isetConfiguration(tPtr,*nconf,false); - _lastConfigUpdate = 0; // still want to re-request since it's likely outdated - } else { + this->setConfiguration(tPtr, *nconf, false); + _lastConfigUpdate = 0; // still want to re-request since it's likely outdated + } + else { uint64_t tmp[2]; tmp[0] = nwid; tmp[1] = 0; bool got = false; - Dictionary *dict = new Dictionary(); + Dictionary* dict = new Dictionary(); try { - int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,dict->unsafeData(),ZT_NETWORKCONFIG_DICT_CAPACITY - 1); + int n = RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, dict->unsafeData(), ZT_NETWORKCONFIG_DICT_CAPACITY - 1); if (n > 1) { - NetworkConfig *nconf = new NetworkConfig(); + NetworkConfig* nconf = new NetworkConfig(); try { if (nconf->fromDictionary(*dict)) { - this->setConfiguration(tPtr,*nconf,false); - _lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated + this->setConfiguration(tPtr, *nconf, false); + _lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated got = true; } - } catch ( ... ) {} + } + catch (...) { + } delete nconf; } - } catch ( ... ) {} + } + catch (...) { + } delete dict; - if (!got) { - RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1); + if (! got) { + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, "\n", 1); } } - if (!_portInitialized) { + if (! _portInitialized) { ZT_VirtualNetworkConfig ctmp; memset(&ctmp, 0, sizeof(ZT_VirtualNetworkConfig)); _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(tPtr, _id, &_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp); _portInitialized = true; } @@ -681,66 +729,85 @@ Network::~Network() Metrics::network_num_joined--; if (_destroyed) { // This is done in Node::leave() so we can pass tPtr properly - //RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); - } else { - RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); + // RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + } + else { + RR->node->configureVirtualNetworkPort((void*)0, _id, &_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp); } } bool Network::filterOutgoingPacket( - void *tPtr, + void* tPtr, const bool noTee, - const Address &ztSource, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *frameData, + const Address& ztSource, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId, - uint8_t &qosBucket) + uint8_t& qosBucket) { Address ztFinalDest(ztDest); int localCapabilityIndex = -1; int accept = 0; - Trace::RuleResultLog rrl,crrl; + Trace::RuleResultLog rrl, crrl; Address cc; unsigned int ccLength = 0; bool ccWatch = false; Mutex::Lock _l(_lock); - Membership *const membership = (ztDest) ? _memberships.get(ztDest) : (Membership *)0; - - switch(_doZtFilter(RR,rrl,_config,membership,false,ztSource,ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,cc,ccLength,ccWatch,qosBucket)) { + Membership* const membership = (ztDest) ? _memberships.get(ztDest) : (Membership*)0; + switch (_doZtFilter(RR, rrl, _config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, _config.rules, _config.ruleCount, cc, ccLength, ccWatch, qosBucket)) { case DOZTFILTER_NO_MATCH: { - for(unsigned int c=0;c<_config.capabilityCount;++c) { - ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match + for (unsigned int c = 0; c < _config.capabilityCount; ++c) { + ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match Address cc2; unsigned int ccLength2 = 0; bool ccWatch2 = false; - switch (_doZtFilter(RR,crrl,_config,membership,false,ztSource,ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.capabilities[c].rules(),_config.capabilities[c].ruleCount(),cc2,ccLength2,ccWatch2,qosBucket)) { + switch (_doZtFilter( + RR, + crrl, + _config, + membership, + false, + ztSource, + ztFinalDest, + macSource, + macDest, + frameData, + frameLen, + etherType, + vlanId, + _config.capabilities[c].rules(), + _config.capabilities[c].ruleCount(), + cc2, + ccLength2, + ccWatch2, + qosBucket)) { case DOZTFILTER_NO_MATCH: - case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern + case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern break; - case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() + case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() case DOZTFILTER_ACCEPT: - case DOZTFILTER_SUPER_ACCEPT: // no difference in behavior on outbound side in capabilities + case DOZTFILTER_SUPER_ACCEPT: // no difference in behavior on outbound side in capabilities localCapabilityIndex = (int)c; accept = 1; - if ((!noTee)&&(cc2)) { - Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME); + if ((! noTee) && (cc2)) { + Packet outp(cc2, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)(ccWatch2 ? 0x16 : 0x02)); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,ccLength2); + outp.append(frameData, ccLength2); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } break; @@ -749,15 +816,15 @@ bool Network::filterOutgoingPacket( break; } } - } break; + } break; case DOZTFILTER_DROP: if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(Trace::RuleResultLog *)0,(Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,0); + RR->t->networkFilter(tPtr, *this, rrl, (Trace::RuleResultLog*)0, (Capability*)0, ztSource, ztDest, macSource, macDest, frameData, frameLen, etherType, vlanId, noTee, false, 0); } return false; - case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() + case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() case DOZTFILTER_ACCEPT: accept = 1; break; @@ -769,199 +836,250 @@ bool Network::filterOutgoingPacket( if (accept) { _outgoing_packets_accepted++; - if ((!noTee)&&(cc)) { - Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME); + if ((! noTee) && (cc)) { + Packet outp(cc, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)(ccWatch ? 0x16 : 0x02)); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,ccLength); + outp.append(frameData, ccLength); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } - if ((ztDest != ztFinalDest)&&(ztFinalDest)) { - Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME); + if ((ztDest != ztFinalDest) && (ztFinalDest)) { + Packet outp(ztFinalDest, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)0x04); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,frameLen); + outp.append(frameData, frameLen); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,0); + RR->t->networkFilter( + tPtr, + *this, + rrl, + (localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0, + (localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0, + ztSource, + ztDest, + macSource, + macDest, + frameData, + frameLen, + etherType, + vlanId, + noTee, + false, + 0); } - return false; // DROP locally, since we redirected - } else { + return false; // DROP locally, since we redirected + } + else { if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,1); + RR->t->networkFilter( + tPtr, + *this, + rrl, + (localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0, + (localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0, + ztSource, + ztDest, + macSource, + macDest, + frameData, + frameLen, + etherType, + vlanId, + noTee, + false, + 1); } return true; } - } else { + } + else { _outgoing_packets_dropped++; if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog *)0,(localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability *)0,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,noTee,false,0); + RR->t->networkFilter( + tPtr, + *this, + rrl, + (localCapabilityIndex >= 0) ? &crrl : (Trace::RuleResultLog*)0, + (localCapabilityIndex >= 0) ? &(_config.capabilities[localCapabilityIndex]) : (Capability*)0, + ztSource, + ztDest, + macSource, + macDest, + frameData, + frameLen, + etherType, + vlanId, + noTee, + false, + 0); } return false; } } int Network::filterIncomingPacket( - void *tPtr, - const SharedPtr &sourcePeer, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *frameData, + void* tPtr, + const SharedPtr& sourcePeer, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId) { Address ztFinalDest(ztDest); - Trace::RuleResultLog rrl,crrl; + Trace::RuleResultLog rrl, crrl; int accept = 0; Address cc; unsigned int ccLength = 0; bool ccWatch = false; - const Capability *c = (Capability *)0; + const Capability* c = (Capability*)0; - uint8_t qosBucket = 255; // For incoming packets this is a dummy value + uint8_t qosBucket = 255; // For incoming packets this is a dummy value Mutex::Lock _l(_lock); - Membership &membership = _membership(sourcePeer->address()); - - switch (_doZtFilter(RR,rrl,_config,&membership,true,sourcePeer->address(),ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,cc,ccLength,ccWatch,qosBucket)) { + Membership& membership = _membership(sourcePeer->address()); + switch (_doZtFilter(RR, rrl, _config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, _config.rules, _config.ruleCount, cc, ccLength, ccWatch, qosBucket)) { case DOZTFILTER_NO_MATCH: { - Membership::CapabilityIterator mci(membership,_config); + Membership::CapabilityIterator mci(membership, _config); while ((c = mci.next())) { - ztFinalDest = ztDest; // sanity check, should be unmodified if there was no match + ztFinalDest = ztDest; // sanity check, should be unmodified if there was no match Address cc2; unsigned int ccLength2 = 0; bool ccWatch2 = false; - switch(_doZtFilter(RR,crrl,_config,&membership,true,sourcePeer->address(),ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,c->rules(),c->ruleCount(),cc2,ccLength2,ccWatch2,qosBucket)) { + switch (_doZtFilter(RR, crrl, _config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) { case DOZTFILTER_NO_MATCH: - case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern + case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern break; - case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztDest will have been changed in _doZtFilter() + case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztDest will have been changed in _doZtFilter() case DOZTFILTER_ACCEPT: - accept = 1; // ACCEPT + accept = 1; // ACCEPT break; case DOZTFILTER_SUPER_ACCEPT: - accept = 2; // super-ACCEPT + accept = 2; // super-ACCEPT break; } if (accept) { if (cc2) { - Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME); + Packet outp(cc2, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)(ccWatch2 ? 0x1c : 0x08)); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,ccLength2); + outp.append(frameData, ccLength2); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } break; } } - } break; + } break; case DOZTFILTER_DROP: if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(Trace::RuleResultLog *)0,(Capability *)0,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0); + RR->t->networkFilter(tPtr, *this, rrl, (Trace::RuleResultLog*)0, (Capability*)0, sourcePeer->address(), ztDest, macSource, macDest, frameData, frameLen, etherType, vlanId, false, true, 0); } - return 0; // DROP + return 0; // DROP - case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() + case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter() case DOZTFILTER_ACCEPT: - accept = 1; // ACCEPT + accept = 1; // ACCEPT break; case DOZTFILTER_SUPER_ACCEPT: - accept = 2; // super-ACCEPT + accept = 2; // super-ACCEPT break; } if (accept) { _incoming_packets_accepted++; if (cc) { - Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME); + Packet outp(cc, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)(ccWatch ? 0x1c : 0x08)); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,ccLength); + outp.append(frameData, ccLength); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } - if ((ztDest != ztFinalDest)&&(ztFinalDest)) { - Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME); + if ((ztDest != ztFinalDest) && (ztFinalDest)) { + Packet outp(ztFinalDest, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(_id); outp.append((uint8_t)0x0a); macDest.appendTo(outp); macSource.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(frameData,frameLen); + outp.append(frameData, frameLen); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0); + RR->t->networkFilter(tPtr, *this, rrl, (c) ? &crrl : (Trace::RuleResultLog*)0, c, sourcePeer->address(), ztDest, macSource, macDest, frameData, frameLen, etherType, vlanId, false, true, 0); } - return 0; // DROP locally, since we redirected + return 0; // DROP locally, since we redirected } - } else { + } + else { _incoming_packets_dropped++; } if (_config.remoteTraceTarget) { - RR->t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,accept); + RR->t->networkFilter(tPtr, *this, rrl, (c) ? &crrl : (Trace::RuleResultLog*)0, c, sourcePeer->address(), ztDest, macSource, macDest, frameData, frameLen, etherType, vlanId, false, true, accept); } return accept; } -bool Network::subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBridgedGroups) const +bool Network::subscribedToMulticastGroup(const MulticastGroup& mg, bool includeBridgedGroups) const { Mutex::Lock _l(_lock); - if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) { + if (std::binary_search(_myMulticastGroups.begin(), _myMulticastGroups.end(), mg)) { return true; - } else if (includeBridgedGroups) { + } + else if (includeBridgedGroups) { return _multicastGroupsBehindMe.contains(mg); } return false; } -void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg) +void Network::multicastSubscribe(void* tPtr, const MulticastGroup& mg) { Mutex::Lock _l(_lock); - if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) { - _myMulticastGroups.insert(std::upper_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg),mg); - _sendUpdatesToMembers(tPtr,&mg); + if (! std::binary_search(_myMulticastGroups.begin(), _myMulticastGroups.end(), mg)) { + _myMulticastGroups.insert(std::upper_bound(_myMulticastGroups.begin(), _myMulticastGroups.end(), mg), mg); + _sendUpdatesToMembers(tPtr, &mg); _num_multicast_groups++; } } -void Network::multicastUnsubscribe(const MulticastGroup &mg) +void Network::multicastUnsubscribe(const MulticastGroup& mg) { Mutex::Lock _l(_lock); - std::vector::iterator i(std::lower_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)); - if ( (i != _myMulticastGroups.end()) && (*i == mg) ) { + std::vector::iterator i(std::lower_bound(_myMulticastGroups.begin(), _myMulticastGroups.end(), mg)); + if ((i != _myMulticastGroups.end()) && (*i == mg)) { _myMulticastGroups.erase(i); _num_multicast_groups--; } } -uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer &chunk,unsigned int ptr) +uint64_t Network::handleConfigChunk(void* tPtr, const uint64_t packetId, const Address& source, const Buffer& chunk, unsigned int ptr) { if (_destroyed) { return 0; @@ -969,20 +1087,20 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add const unsigned int start = ptr; - ptr += 8; // skip network ID, which is already obviously known + ptr += 8; // skip network ID, which is already obviously known const unsigned int chunkLen = chunk.at(ptr); ptr += 2; - const void *chunkData = chunk.field(ptr,chunkLen); + const void* chunkData = chunk.field(ptr, chunkLen); ptr += chunkLen; - NetworkConfig *nc = (NetworkConfig *)0; + NetworkConfig* nc = (NetworkConfig*)0; uint64_t configUpdateId; { Mutex::Lock _l(_lock); - _IncomingConfigChunk *c = (_IncomingConfigChunk *)0; + _IncomingConfigChunk* c = (_IncomingConfigChunk*)0; uint64_t chunkId = 0; - unsigned long totalLength,chunkIndex; + unsigned long totalLength, chunkIndex; if (ptr < chunk.size()) { const bool fastPropagate = ((chunk[ptr++] & 0x01) != 0); configUpdateId = chunk.at(ptr); @@ -992,59 +1110,61 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add chunkIndex = chunk.at(ptr); ptr += 4; - if (((chunkIndex + chunkLen) > totalLength)||(totalLength >= ZT_NETWORKCONFIG_DICT_CAPACITY)) { // >= since we need room for a null at the end + if (((chunkIndex + chunkLen) > totalLength) || (totalLength >= ZT_NETWORKCONFIG_DICT_CAPACITY)) { // >= since we need room for a null at the end return 0; } - if ((chunk[ptr] != 1)||(chunk.at(ptr + 1) != ZT_C25519_SIGNATURE_LEN)) { + if ((chunk[ptr] != 1) || (chunk.at(ptr + 1) != ZT_C25519_SIGNATURE_LEN)) { return 0; } - const uint8_t *sig = reinterpret_cast(chunk.field(ptr + 3,ZT_C25519_SIGNATURE_LEN)); + const uint8_t* sig = reinterpret_cast(chunk.field(ptr + 3, ZT_C25519_SIGNATURE_LEN)); // We can use the signature, which is unique per chunk, to get a per-chunk ID for local deduplication use - for(unsigned int i=0;i<16;++i) { - reinterpret_cast(&chunkId)[i & 7] ^= sig[i]; + for (unsigned int i = 0; i < 16; ++i) { + reinterpret_cast(&chunkId)[i & 7] ^= sig[i]; } // Find existing or new slot for this update and check if this is a duplicate chunk - for(int i=0;ihaveChunks;++j) { + for (unsigned long j = 0; j < c->haveChunks; ++j) { if (c->haveChunkIds[j] == chunkId) { return 0; } } break; - } else if ((!c)||(_incomingConfigChunks[i].ts < c->ts)) { + } + else if ((! c) || (_incomingConfigChunks[i].ts < c->ts)) { c = &(_incomingConfigChunks[i]); } } // If it's not a duplicate, check chunk signature - const Identity controllerId(RR->topology->getIdentity(tPtr,controller())); - if (!controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time? + const Identity controllerId(RR->topology->getIdentity(tPtr, controller())); + if (! controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time? return 0; } - if (!controllerId.verify(chunk.field(start,ptr - start),ptr - start,sig,ZT_C25519_SIGNATURE_LEN)) { + if (! controllerId.verify(chunk.field(start, ptr - start), ptr - start, sig, ZT_C25519_SIGNATURE_LEN)) { return 0; } // New properly verified chunks can be flooded "virally" through the network if (fastPropagate) { - Address *a = (Address *)0; - Membership *m = (Membership *)0; - Hashtable::Iterator i(_memberships); - while (i.next(a,m)) { - if ((*a != source)&&(*a != controller())) { - Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CONFIG); - outp.append(reinterpret_cast(chunk.data()) + start,chunk.size() - start); - RR->sw->send(tPtr,outp,true); + Address* a = (Address*)0; + Membership* m = (Membership*)0; + Hashtable::Iterator i(_memberships); + while (i.next(a, m)) { + if ((*a != source) && (*a != controller())) { + Packet outp(*a, RR->identity.address(), Packet::VERB_NETWORK_CONFIG); + outp.append(reinterpret_cast(chunk.data()) + start, chunk.size() - start); + RR->sw->send(tPtr, outp, true); } } } - } else if ((source == controller())||(!source)) { // since old chunks aren't signed, only accept from controller itself (or via cluster backplane) + } + else if ((source == controller()) || (! source)) { // since old chunks aren't signed, only accept from controller itself (or via cluster backplane) // Legacy support for OK(NETWORK_CONFIG_REQUEST) from older controllers chunkId = packetId; configUpdateId = chunkId; @@ -1055,17 +1175,18 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add return 0; } - for(int i=0;its)) { + for (int i = 0; i < ZT_NETWORK_MAX_INCOMING_UPDATES; ++i) { + if ((! c) || (_incomingConfigChunks[i].ts < c->ts)) { c = &(_incomingConfigChunks[i]); } } - } else { + } + else { // Single-chunk unsigned legacy configs are only allowed from the controller itself return 0; } - ++c->ts; // newer is higher, that's all we need + ++c->ts; // newer is higher, that's all we need if (c->updateId != configUpdateId) { c->updateId = configUpdateId; @@ -1077,21 +1198,22 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add } c->haveChunkIds[c->haveChunks++] = chunkId; - memcpy(c->data.unsafeData() + chunkIndex,chunkData,chunkLen); + memcpy(c->data.unsafeData() + chunkIndex, chunkData, chunkLen); c->haveBytes += chunkLen; if (c->haveBytes == totalLength) { - c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated + c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated nc = new NetworkConfig(); try { - if (!nc->fromDictionary(c->data)) { + if (! nc->fromDictionary(c->data)) { delete nc; - nc = (NetworkConfig *)0; + nc = (NetworkConfig*)0; } - } catch ( ... ) { + } + catch (...) { delete nc; - nc = (NetworkConfig *)0; + nc = (NetworkConfig*)0; } } } @@ -1100,14 +1222,15 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add this->setConfiguration(tPtr, *nc, true); delete nc; return configUpdateId; - } else { + } + else { return 0; } return 0; } -int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk) +int Network::setConfiguration(void* tPtr, const NetworkConfig& nconf, bool saveToDisk) { if (_destroyed) { return 0; @@ -1115,11 +1238,11 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD // _lock is NOT locked when this is called try { - if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id)) { - return 0; // invalid config that is not for us or not for this network + if ((nconf.issuedTo != RR->identity.address()) || (nconf.networkId != _id)) { + return 0; // invalid config that is not for us or not for this network } if (_config == nconf) { - return 1; // OK config, but duplicate of what we already have + return 1; // OK config, but duplicate of what we already have } ZT_VirtualNetworkConfig ctmp; @@ -1137,28 +1260,32 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD _externalConfig(&ctmp); } - _portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(tPtr, _id, &_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp); _authenticationURL = nconf.authenticationURL; if (saveToDisk) { - Dictionary *const d = new Dictionary(); + Dictionary* const d = new Dictionary(); try { - if (nconf.toDictionary(*d,false)) { + if (nconf.toDictionary(*d, false)) { uint64_t tmp[2]; tmp[0] = _id; tmp[1] = 0; - RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d->data(),d->sizeBytes()); + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, d->data(), d->sizeBytes()); } - } catch ( ... ) {} + } + catch (...) { + } delete d; } - return 2; // OK and configuration has changed - } catch ( ... ) {} // ignore invalid configs + return 2; // OK and configuration has changed + } + catch (...) { + } // ignore invalid configs return 0; } -void Network::requestConfiguration(void *tPtr) +void Network::requestConfiguration(void* tPtr) { if (_destroyed) { return; @@ -1169,7 +1296,7 @@ void Network::requestConfiguration(void *tPtr) const uint16_t startPortRange = (uint16_t)((_id >> 40) & 0xffff); const uint16_t endPortRange = (uint16_t)((_id >> 24) & 0xffff); if (endPortRange >= startPortRange) { - NetworkConfig *const nconf = new NetworkConfig(); + NetworkConfig* const nconf = new NetworkConfig(); nconf->networkId = _id; nconf->timestamp = RR->node->now(); @@ -1181,30 +1308,30 @@ void Network::requestConfiguration(void *tPtr) nconf->multicastLimit = 0; nconf->staticIpCount = 1; nconf->ruleCount = 14; - nconf->staticIps[0] = InetAddress::makeIpv66plane(_id,RR->identity.address().toInt()); + nconf->staticIps[0] = InetAddress::makeIpv66plane(_id, RR->identity.address().toInt()); // Drop everything but IPv6 - nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE | 0x80; // NOT - nconf->rules[0].v.etherType = 0x86dd; // IPv6 + nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE | 0x80; // NOT + nconf->rules[0].v.etherType = 0x86dd; // IPv6 nconf->rules[1].t = (uint8_t)ZT_NETWORK_RULE_ACTION_DROP; // Allow ICMPv6 nconf->rules[2].t = (uint8_t)ZT_NETWORK_RULE_MATCH_IP_PROTOCOL; - nconf->rules[2].v.ipProtocol = 0x3a; // ICMPv6 + nconf->rules[2].v.ipProtocol = 0x3a; // ICMPv6 nconf->rules[3].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT; // Allow destination ports within range nconf->rules[4].t = (uint8_t)ZT_NETWORK_RULE_MATCH_IP_PROTOCOL; - nconf->rules[4].v.ipProtocol = 0x11; // UDP - nconf->rules[5].t = (uint8_t)ZT_NETWORK_RULE_MATCH_IP_PROTOCOL | 0x40; // OR - nconf->rules[5].v.ipProtocol = 0x06; // TCP + nconf->rules[4].v.ipProtocol = 0x11; // UDP + nconf->rules[5].t = (uint8_t)ZT_NETWORK_RULE_MATCH_IP_PROTOCOL | 0x40; // OR + nconf->rules[5].v.ipProtocol = 0x06; // TCP nconf->rules[6].t = (uint8_t)ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE; nconf->rules[6].v.port[0] = startPortRange; nconf->rules[6].v.port[1] = endPortRange; nconf->rules[7].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT; // Allow non-SYN TCP packets to permit non-connection-initiating traffic - nconf->rules[8].t = (uint8_t)ZT_NETWORK_RULE_MATCH_CHARACTERISTICS | 0x80; // NOT + nconf->rules[8].t = (uint8_t)ZT_NETWORK_RULE_MATCH_CHARACTERISTICS | 0x80; // NOT nconf->rules[8].v.characteristics = ZT_RULE_PACKET_CHARACTERISTICS_TCP_SYN; nconf->rules[9].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT; @@ -1225,17 +1352,19 @@ void Network::requestConfiguration(void *tPtr) nconf->name[3] = 'o'; nconf->name[4] = 'c'; nconf->name[5] = '-'; - Utils::hex((uint16_t)startPortRange,nconf->name + 6); + Utils::hex((uint16_t)startPortRange, nconf->name + 6); nconf->name[10] = '-'; - Utils::hex((uint16_t)endPortRange,nconf->name + 11); + Utils::hex((uint16_t)endPortRange, nconf->name + 11); nconf->name[15] = (char)0; - this->setConfiguration(tPtr,*nconf,false); + this->setConfiguration(tPtr, *nconf, false); delete nconf; - } else { + } + else { this->setNotFound(tPtr); } - } else if ((_id & 0xff) == 0x01) { + } + else if ((_id & 0xff) == 0x01) { // ffAAaaaaaaaaaa01 -- where AA is the IPv4 /8 to use and aaaaaaaaaa is the anchor node for multicast gather and replication const uint64_t myAddress = RR->identity.address().toInt(); const uint64_t networkHub = (_id >> 8) & 0xffffffffffULL; @@ -1247,9 +1376,9 @@ void Network::requestConfiguration(void *tPtr) ipv4[3] = (uint8_t)(myAddress & 0xff); char v4ascii[24]; - Utils::decimal(ipv4[0],v4ascii); + Utils::decimal(ipv4[0], v4ascii); - NetworkConfig *const nconf = new NetworkConfig(); + NetworkConfig* const nconf = new NetworkConfig(); nconf->networkId = _id; nconf->timestamp = RR->node->now(); @@ -1267,8 +1396,8 @@ void Network::requestConfiguration(void *tPtr) nconf->specialists[0] = networkHub; } - nconf->staticIps[0] = InetAddress::makeIpv66plane(_id,myAddress); - nconf->staticIps[1].set(ipv4,4,8); + nconf->staticIps[0] = InetAddress::makeIpv66plane(_id, myAddress); + nconf->staticIps[1].set(ipv4, 4, 8); nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT; @@ -1292,7 +1421,7 @@ void Network::requestConfiguration(void *tPtr) nconf->name[nn++] = '0'; nconf->name[nn++] = (char)0; - this->setConfiguration(tPtr,*nconf,false); + this->setConfiguration(tPtr, *nconf, false); delete nconf; } return; @@ -1301,81 +1430,85 @@ void Network::requestConfiguration(void *tPtr) const Address ctrl(controller()); Dictionary rmd; - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_ONE_VERSION_REVISION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH,ZT_TARGET_NAME); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION, (uint64_t)ZT_NETWORKCONFIG_VERSION); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR, (uint64_t)ZT_VENDOR_ZEROTIER); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION, (uint64_t)ZT_PROTO_VERSION); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION, (uint64_t)ZEROTIER_ONE_VERSION_MAJOR); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION, (uint64_t)ZEROTIER_ONE_VERSION_MINOR); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION, (uint64_t)ZEROTIER_ONE_VERSION_REVISION); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES, (uint64_t)ZT_MAX_NETWORK_RULES); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES, (uint64_t)ZT_MAX_NETWORK_CAPABILITIES); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES, (uint64_t)ZT_MAX_CAPABILITY_RULES); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS, (uint64_t)ZT_MAX_NETWORK_TAGS); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS, (uint64_t)0); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV, (uint64_t)ZT_RULES_ENGINE_REVISION); + rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH, ZT_TARGET_NAME); - RR->t->networkConfigRequestSent(tPtr,*this,ctrl); + RR->t->networkConfigRequestSent(tPtr, *this, ctrl); if (ctrl == RR->identity.address()) { if (RR->localNetworkController) { - RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,rmd); - } else { + RR->localNetworkController->request(_id, InetAddress(), 0xffffffffffffffffULL, RR->identity, rmd); + } + else { this->setNotFound(tPtr); } return; } - Packet outp(ctrl,RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST); + Packet outp(ctrl, RR->identity.address(), Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append((uint64_t)_id); const unsigned int rmdSize = rmd.sizeBytes(); outp.append((uint16_t)rmdSize); - outp.append((const void *)rmd.data(),rmdSize); + outp.append((const void*)rmd.data(), rmdSize); if (_config) { outp.append((uint64_t)_config.revision); outp.append((uint64_t)_config.timestamp); - } else { - outp.append((unsigned char)0,16); + } + else { + outp.append((unsigned char)0, 16); } outp.compress(); RR->node->expectReplyTo(outp.packetId()); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } -bool Network::gate(void *tPtr,const SharedPtr &peer) +bool Network::gate(void* tPtr, const SharedPtr& peer) { const int64_t now = RR->node->now(); - //int64_t comTimestamp = 0; - //int64_t comRevocationThreshold = 0; + // int64_t comTimestamp = 0; + // int64_t comRevocationThreshold = 0; Mutex::Lock _l(_lock); try { if (_config) { - Membership *m = _memberships.get(peer->address()); - //if (m) { + Membership* m = _memberships.get(peer->address()); + // if (m) { // comTimestamp = m->comTimestamp(); // comRevocationThreshold = m->comRevocationThreshold(); - //} - if ( (_config.isPublic()) || ((m)&&(m->isAllowedOnNetwork(_config, peer->identity()))) ) { - if (!m) { + // } + if ((_config.isPublic()) || ((m) && (m->isAllowedOnNetwork(_config, peer->identity())))) { + if (! m) { m = &(_membership(peer->address())); } if (m->multicastLikeGate(now)) { - _announceMulticastGroupsTo(tPtr,peer->address(),_allMulticastGroups()); + _announceMulticastGroupsTo(tPtr, peer->address(), _allMulticastGroups()); } return true; } } - } catch ( ... ) {} - //printf("%.16llx %.10llx not allowed, COM ts %lld revocation %lld\n", _id, peer->address().toInt(), comTimestamp, comRevocationThreshold); fflush(stdout); + } + catch (...) { + } + // printf("%.16llx %.10llx not allowed, COM ts %lld revocation %lld\n", _id, peer->address().toInt(), comTimestamp, comRevocationThreshold); fflush(stdout); return false; } -bool Network::recentlyAssociatedWith(const Address &addr) +bool Network::recentlyAssociatedWith(const Address& addr) { Mutex::Lock _l(_lock); - const Membership *m = _memberships.get(addr); - return ((m)&&(m->recentlyAssociated(RR->node->now()))); + const Membership* m = _memberships.get(addr); + return ((m) && (m->recentlyAssociated(RR->node->now()))); } void Network::clean() @@ -1388,10 +1521,10 @@ void Network::clean() } { - Hashtable< MulticastGroup,uint64_t >::Iterator i(_multicastGroupsBehindMe); - MulticastGroup *mg = (MulticastGroup *)0; - uint64_t *ts = (uint64_t *)0; - while (i.next(mg,ts)) { + Hashtable::Iterator i(_multicastGroupsBehindMe); + MulticastGroup* mg = (MulticastGroup*)0; + uint64_t* ts = (uint64_t*)0; + while (i.next(mg, ts)) { if ((now - *ts) > (ZT_MULTICAST_LIKE_EXPIRE * 2)) { _multicastGroupsBehindMe.erase(*mg); } @@ -1399,37 +1532,38 @@ void Network::clean() } { - Address *a = (Address *)0; - Membership *m = (Membership *)0; - Hashtable::Iterator i(_memberships); - while (i.next(a,m)) { - if (!RR->topology->getPeerNoCache(*a)) { + Address* a = (Address*)0; + Membership* m = (Membership*)0; + Hashtable::Iterator i(_memberships); + while (i.next(a, m)) { + if (! RR->topology->getPeerNoCache(*a)) { _memberships.erase(*a); - } else { - m->clean(now,_config); + } + else { + m->clean(now, _config); } } } } -void Network::learnBridgeRoute(const MAC &mac,const Address &addr) +void Network::learnBridgeRoute(const MAC& mac, const Address& addr) { Mutex::Lock _l(_lock); _remoteBridgeRoutes[mac] = addr; // Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) { - Hashtable< Address,unsigned long > counts; + Hashtable counts; Address maxAddr; unsigned long maxCount = 0; - MAC *m = (MAC *)0; - Address *a = (Address *)0; + MAC* m = (MAC*)0; + Address* a = (Address*)0; // Find the address responsible for the most entries { - Hashtable::Iterator i(_remoteBridgeRoutes); - while (i.next(m,a)) { + Hashtable::Iterator i(_remoteBridgeRoutes); + while (i.next(m, a)) { const unsigned long c = ++counts[*a]; if (c > maxCount) { maxCount = c; @@ -1440,8 +1574,8 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr) // Kill this address from our table, since it's most likely spamming us { - Hashtable::Iterator i(_remoteBridgeRoutes); - while (i.next(m,a)) { + Hashtable::Iterator i(_remoteBridgeRoutes); + while (i.next(m, a)) { if (*a == maxAddr) { _remoteBridgeRoutes.erase(*m); } @@ -1450,50 +1584,50 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr) } } -void Network::learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now) +void Network::learnBridgedMulticastGroup(void* tPtr, const MulticastGroup& mg, int64_t now) { Mutex::Lock _l(_lock); const unsigned long tmp = (unsigned long)_multicastGroupsBehindMe.size(); - _multicastGroupsBehindMe.set(mg,now); + _multicastGroupsBehindMe.set(mg, now); if (tmp != _multicastGroupsBehindMe.size()) { - _sendUpdatesToMembers(tPtr,&mg); + _sendUpdatesToMembers(tPtr, &mg); } } -Membership::AddCredentialResult Network::addCredential(void *tPtr,const CertificateOfMembership &com) +Membership::AddCredentialResult Network::addCredential(void* tPtr, const CertificateOfMembership& com) { if (com.networkId() != _id) { return Membership::ADD_REJECTED; } Mutex::Lock _l(_lock); - return _membership(com.issuedTo()).addCredential(RR,tPtr,_config,com); + return _membership(com.issuedTo()).addCredential(RR, tPtr, _config, com); } -Membership::AddCredentialResult Network::addCredential(void *tPtr,const Address &sentFrom,const Revocation &rev) +Membership::AddCredentialResult Network::addCredential(void* tPtr, const Address& sentFrom, const Revocation& rev) { if (rev.networkId() != _id) { return Membership::ADD_REJECTED; } Mutex::Lock _l(_lock); - Membership &m = _membership(rev.target()); + Membership& m = _membership(rev.target()); - const Membership::AddCredentialResult result = m.addCredential(RR,tPtr,_config,rev); + const Membership::AddCredentialResult result = m.addCredential(RR, tPtr, _config, rev); - if ((result == Membership::ADD_ACCEPTED_NEW)&&(rev.fastPropagate())) { - Address *a = (Address *)0; - Membership *m = (Membership *)0; - Hashtable::Iterator i(_memberships); - while (i.next(a,m)) { - if ((*a != sentFrom)&&(*a != rev.signer())) { - Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); - outp.append((uint8_t)0x00); // no COM - outp.append((uint16_t)0); // no capabilities - outp.append((uint16_t)0); // no tags - outp.append((uint16_t)1); // one revocation! + if ((result == Membership::ADD_ACCEPTED_NEW) && (rev.fastPropagate())) { + Address* a = (Address*)0; + Membership* m = (Membership*)0; + Hashtable::Iterator i(_memberships); + while (i.next(a, m)) { + if ((*a != sentFrom) && (*a != rev.signer())) { + Packet outp(*a, RR->identity.address(), Packet::VERB_NETWORK_CREDENTIALS); + outp.append((uint8_t)0x00); // no COM + outp.append((uint16_t)0); // no capabilities + outp.append((uint16_t)0); // no tags + outp.append((uint16_t)1); // one revocation! rev.serialize(outp); - outp.append((uint16_t)0); // no certificates of ownership - RR->sw->send(tPtr,outp,true); + outp.append((uint16_t)0); // no certificates of ownership + RR->sw->send(tPtr, outp, true); } } } @@ -1513,7 +1647,7 @@ ZT_VirtualNetworkStatus Network::_status() const if (_portError) { return ZT_NETWORK_STATUS_PORT_ERROR; } - switch(_netconfFailure) { + switch (_netconfFailure) { case NETCONF_FAILURE_ACCESS_DENIED: return ZT_NETWORK_STATUS_ACCESS_DENIED; case NETCONF_FAILURE_NOT_FOUND: @@ -1527,14 +1661,15 @@ ZT_VirtualNetworkStatus Network::_status() const } } -void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const +void Network::_externalConfig(ZT_VirtualNetworkConfig* ec) const { // assumes _lock is locked ec->nwid = _id; ec->mac = _mac.toInt(); if (_config) { - Utils::scopy(ec->name,sizeof(ec->name),_config.name); - } else { + Utils::scopy(ec->name, sizeof(ec->name), _config.name); + } + else { ec->name[0] = (char)0; } ec->status = _status(); @@ -1542,33 +1677,35 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const ec->mtu = (_config) ? _config.mtu : ZT_DEFAULT_MTU; ec->dhcp = 0; std::vector
ab(_config.activeBridges()); - ec->bridge = (std::find(ab.begin(),ab.end(),RR->identity.address()) != ab.end()) ? 1 : 0; + ec->bridge = (std::find(ab.begin(), ab.end(), RR->identity.address()) != ab.end()) ? 1 : 0; ec->broadcastEnabled = (_config) ? (_config.enableBroadcast() ? 1 : 0) : 0; ec->portError = _portError; ec->netconfRevision = (_config) ? (unsigned long)_config.revision : 0; ec->assignedAddressCount = 0; - for(unsigned int i=0;iassignedAddresses[i]),&(_config.staticIps[i]),sizeof(struct sockaddr_storage)); + memcpy(&(ec->assignedAddresses[i]), &(_config.staticIps[i]), sizeof(struct sockaddr_storage)); ++ec->assignedAddressCount; - } else { - memset(&(ec->assignedAddresses[i]),0,sizeof(struct sockaddr_storage)); + } + else { + memset(&(ec->assignedAddresses[i]), 0, sizeof(struct sockaddr_storage)); } } ec->routeCount = 0; - for(unsigned int i=0;iroutes[i]),&(_config.routes[i]),sizeof(ZT_VirtualNetworkRoute)); + memcpy(&(ec->routes[i]), &(_config.routes[i]), sizeof(ZT_VirtualNetworkRoute)); ++ec->routeCount; - } else { - memset(&(ec->routes[i]),0,sizeof(ZT_VirtualNetworkRoute)); + } + else { + memset(&(ec->routes[i]), 0, sizeof(ZT_VirtualNetworkRoute)); } } ec->multicastSubscriptionCount = (unsigned int)_myMulticastGroups.size(); - for(unsigned long i=0;i<(unsigned long)_myMulticastGroups.size();++i) { + for (unsigned long i = 0; i < (unsigned long)_myMulticastGroups.size(); ++i) { ec->multicastSubscriptions[i].mac = _myMulticastGroups[i].mac().toInt(); ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi(); } @@ -1587,7 +1724,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const Utils::scopy(ec->ssoProvider, sizeof(ec->ssoProvider), _config.ssoProvider); } -void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup) +void Network::_sendUpdatesToMembers(void* tPtr, const MulticastGroup* const newMulticastGroup) { // Assumes _lock is locked const int64_t now = RR->node->now(); @@ -1595,30 +1732,31 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu std::vector groups; if (newMulticastGroup) { groups.push_back(*newMulticastGroup); - } else { + } + else { groups = _allMulticastGroups(); } std::vector
alwaysAnnounceTo; - if ((newMulticastGroup)||((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) { - if (!newMulticastGroup) { + if ((newMulticastGroup) || ((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) { + if (! newMulticastGroup) { _lastAnnouncedMulticastGroupsUpstream = now; } alwaysAnnounceTo = _config.alwaysContactAddresses(); - if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),controller()) == alwaysAnnounceTo.end()) { + if (std::find(alwaysAnnounceTo.begin(), alwaysAnnounceTo.end(), controller()) == alwaysAnnounceTo.end()) { alwaysAnnounceTo.push_back(controller()); } const std::vector
upstreams(RR->topology->upstreamAddresses()); - for(std::vector
::const_iterator a(upstreams.begin());a!=upstreams.end();++a) { - if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a) == alwaysAnnounceTo.end()) { + for (std::vector
::const_iterator a(upstreams.begin()); a != upstreams.end(); ++a) { + if (std::find(alwaysAnnounceTo.begin(), alwaysAnnounceTo.end(), *a) == alwaysAnnounceTo.end()) { alwaysAnnounceTo.push_back(*a); } } - std::sort(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end()); + std::sort(alwaysAnnounceTo.begin(), alwaysAnnounceTo.end()); - for(std::vector
::const_iterator a(alwaysAnnounceTo.begin());a!=alwaysAnnounceTo.end();++a) { + for (std::vector
::const_iterator a(alwaysAnnounceTo.begin()); a != alwaysAnnounceTo.end(); ++a) { /* // push COM to non-members so they can do multicast request auth if ( (_config.com) && (!_memberships.contains(*a)) && (*a != RR->identity.address()) ) { @@ -1632,35 +1770,35 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu RR->sw->send(tPtr,outp,true); } */ - _announceMulticastGroupsTo(tPtr,*a,groups); + _announceMulticastGroupsTo(tPtr, *a, groups); } } { - Address *a = (Address *)0; - Membership *m = (Membership *)0; - Hashtable::Iterator i(_memberships); - while (i.next(a,m)) { + Address* a = (Address*)0; + Membership* m = (Membership*)0; + Hashtable::Iterator i(_memberships); + while (i.next(a, m)) { const Identity remoteIdentity(RR->topology->getIdentity(tPtr, *a)); if (remoteIdentity) { - if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config, remoteIdentity)) && (!std::binary_search(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a)) ) { - _announceMulticastGroupsTo(tPtr,*a,groups); + if ((m->multicastLikeGate(now) || (newMulticastGroup)) && (m->isAllowedOnNetwork(_config, remoteIdentity)) && (! std::binary_search(alwaysAnnounceTo.begin(), alwaysAnnounceTo.end(), *a))) { + _announceMulticastGroupsTo(tPtr, *a, groups); } } } } } -void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector &allMulticastGroups) +void Network::_announceMulticastGroupsTo(void* tPtr, const Address& peer, const std::vector& allMulticastGroups) { // Assumes _lock is locked - Packet *const outp = new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE); + Packet* const outp = new Packet(peer, RR->identity.address(), Packet::VERB_MULTICAST_LIKE); - for(std::vector::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { + for (std::vector::const_iterator mg(allMulticastGroups.begin()); mg != allMulticastGroups.end(); ++mg) { if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) { outp->compress(); - RR->sw->send(tPtr,*outp,true); - outp->reset(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE); + RR->sw->send(tPtr, *outp, true); + outp->reset(peer, RR->identity.address(), Packet::VERB_MULTICAST_LIKE); } // network ID, MAC, ADI @@ -1671,7 +1809,7 @@ void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const st if (outp->size() > ZT_PROTO_MIN_PACKET_LENGTH) { outp->compress(); - RR->sw->send(tPtr,*outp,true); + RR->sw->send(tPtr, *outp, true); } delete outp; @@ -1682,23 +1820,23 @@ std::vector Network::_allMulticastGroups() const // Assumes _lock is locked std::vector mgs; mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1); - mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end()); + mgs.insert(mgs.end(), _myMulticastGroups.begin(), _myMulticastGroups.end()); _multicastGroupsBehindMe.appendKeys(mgs); - if ((_config)&&(_config.enableBroadcast())) { + if ((_config) && (_config.enableBroadcast())) { mgs.push_back(Network::BROADCAST); } - std::sort(mgs.begin(),mgs.end()); - mgs.erase(std::unique(mgs.begin(),mgs.end()),mgs.end()); + std::sort(mgs.begin(), mgs.end()); + mgs.erase(std::unique(mgs.begin(), mgs.end()), mgs.end()); return mgs; } -Membership &Network::_membership(const Address &a) +Membership& Network::_membership(const Address& a) { // assumes _lock is locked return _memberships[a]; } -void Network::setAuthenticationRequired(void *tPtr, const char* issuerURL, const char* centralEndpoint, const char* clientID, const char *ssoProvider, const char* nonce, const char* state) +void Network::setAuthenticationRequired(void* tPtr, const char* issuerURL, const char* centralEndpoint, const char* clientID, const char* ssoProvider, const char* nonce, const char* state) { Mutex::Lock _l(_lock); _netconfFailure = NETCONF_FAILURE_AUTHENTICATION_REQUIRED; @@ -1714,10 +1852,11 @@ void Network::setAuthenticationRequired(void *tPtr, const char* issuerURL, const _sendUpdateEvent(tPtr); } -void Network::_sendUpdateEvent(void *tPtr) { +void Network::_sendUpdateEvent(void* tPtr) +{ ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); RR->node->configureVirtualNetworkPort(tPtr, _id, &_uPtr, (_portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Network.hpp b/node/Network.hpp index cc85b7d1f..a622786c6 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -14,33 +14,31 @@ #ifndef ZT_NETWORK_HPP #define ZT_NETWORK_HPP -#include - #include "../include/ZeroTierOne.h" - -#include -#include -#include -#include -#include - -#include "Constants.hpp" -#include "Hashtable.hpp" #include "Address.hpp" -#include "Mutex.hpp" -#include "SharedPtr.hpp" #include "AtomicCounter.hpp" -#include "MulticastGroup.hpp" -#include "MAC.hpp" -#include "Dictionary.hpp" -#include "Multicaster.hpp" -#include "Membership.hpp" -#include "NetworkConfig.hpp" #include "CertificateOfMembership.hpp" +#include "Constants.hpp" +#include "Dictionary.hpp" +#include "Hashtable.hpp" +#include "MAC.hpp" +#include "Membership.hpp" #include "Metrics.hpp" +#include "MulticastGroup.hpp" +#include "Multicaster.hpp" +#include "Mutex.hpp" +#include "NetworkConfig.hpp" +#include "SharedPtr.hpp" + +#include +#include +#include +#include +#include +#include #define ZT_NETWORK_MAX_INCOMING_UPDATES 3 -#define ZT_NETWORK_MAX_UPDATE_CHUNKS ((ZT_NETWORKCONFIG_DICT_CAPACITY / 1024) + 1) +#define ZT_NETWORK_MAX_UPDATE_CHUNKS ((ZT_NETWORKCONFIG_DICT_CAPACITY / 1024) + 1) namespace ZeroTier { @@ -50,11 +48,10 @@ class Peer; /** * A virtual LAN */ -class Network -{ +class Network { friend class SharedPtr; -public: + public: /** * Broadcast multicast group: ff:ff:ff:ff:ff:ff / 0 */ @@ -63,7 +60,10 @@ public: /** * Compute primary controller device ID from network ID */ - static inline Address controllerFor(uint64_t nwid) { return Address(nwid >> 24); } + static inline Address controllerFor(uint64_t nwid) + { + return Address(nwid >> 24); + } /** * Construct a new network @@ -77,18 +77,43 @@ public: * @param uptr Arbitrary pointer used by externally-facing API (for user use) * @param nconf Network config, if known */ - Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr,const NetworkConfig *nconf); + Network(const RuntimeEnvironment* renv, void* tPtr, uint64_t nwid, void* uptr, const NetworkConfig* nconf); ~Network(); - inline uint64_t id() const { return _id; } - inline Address controller() const { return Address(_id >> 24); } - inline bool multicastEnabled() const { return (_config.multicastLimit > 0); } - inline bool hasConfig() const { return (_config); } - inline uint64_t lastConfigUpdate() const { return _lastConfigUpdate; } - inline ZT_VirtualNetworkStatus status() const { Mutex::Lock _l(_lock); return _status(); } - inline const NetworkConfig &config() const { return _config; } - inline const MAC &mac() const { return _mac; } + inline uint64_t id() const + { + return _id; + } + inline Address controller() const + { + return Address(_id >> 24); + } + inline bool multicastEnabled() const + { + return (_config.multicastLimit > 0); + } + inline bool hasConfig() const + { + return (_config); + } + inline uint64_t lastConfigUpdate() const + { + return _lastConfigUpdate; + } + inline ZT_VirtualNetworkStatus status() const + { + Mutex::Lock _l(_lock); + return _status(); + } + inline const NetworkConfig& config() const + { + return _config; + } + inline const MAC& mac() const + { + return _mac; + } /** * Apply filters to an outgoing packet @@ -111,17 +136,17 @@ public: * @return True if packet should be sent, false if dropped or redirected */ bool filterOutgoingPacket( - void *tPtr, + void* tPtr, const bool noTee, - const Address &ztSource, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *frameData, + const Address& ztSource, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId, - uint8_t &qosBucket); + uint8_t& qosBucket); /** * Apply filters to an incoming packet @@ -143,12 +168,12 @@ public: * @return 0 == drop, 1 == accept, 2 == accept even if bridged */ int filterIncomingPacket( - void *tPtr, - const SharedPtr &sourcePeer, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *frameData, + void* tPtr, + const SharedPtr& sourcePeer, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId); @@ -160,7 +185,7 @@ public: * @param includeBridgedGroups If true, also check groups we've learned via bridging * @return True if this network endpoint / peer is a member */ - bool subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBridgedGroups) const; + bool subscribedToMulticastGroup(const MulticastGroup& mg, bool includeBridgedGroups) const; /** * Subscribe to a multicast group @@ -168,14 +193,14 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param mg New multicast group */ - void multicastSubscribe(void *tPtr,const MulticastGroup &mg); + void multicastSubscribe(void* tPtr, const MulticastGroup& mg); /** * Unsubscribe from a multicast group * * @param mg Multicast group */ - void multicastUnsubscribe(const MulticastGroup &mg); + void multicastUnsubscribe(const MulticastGroup& mg); /** * Handle an inbound network config chunk @@ -191,7 +216,7 @@ public: * @param ptr Index of chunk and related fields in packet * @return Update ID if update was fully assembled and accepted or 0 otherwise */ - uint64_t handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer &chunk,unsigned int ptr); + uint64_t handleConfigChunk(void* tPtr, const uint64_t packetId, const Address& source, const Buffer& chunk, unsigned int ptr); /** * Set network configuration @@ -201,12 +226,12 @@ public: * @param saveToDisk Save to disk? Used during loading, should usually be true otherwise. * @return 0 == bad, 1 == accepted but duplicate/unchanged, 2 == accepted and new */ - int setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk); + int setConfiguration(void* tPtr, const NetworkConfig& nconf, bool saveToDisk); /** * Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this */ - inline void setAccessDenied(void *tPtr) + inline void setAccessDenied(void* tPtr) { Mutex::Lock _l(_lock); _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; @@ -217,7 +242,7 @@ public: /** * Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this */ - inline void setNotFound(void *tPtr) + inline void setNotFound(void* tPtr) { Mutex::Lock _l(_lock); _netconfFailure = NETCONF_FAILURE_NOT_FOUND; @@ -228,7 +253,7 @@ public: /** * Set netconf failure to 'authentication required' possibly with an authorization URL */ - inline void setAuthenticationRequired(void *tPtr, const char *url) + inline void setAuthenticationRequired(void* tPtr, const char* url) { Mutex::Lock _l(_lock); _netconfFailure = NETCONF_FAILURE_AUTHENTICATION_REQUIRED; @@ -242,14 +267,14 @@ public: * set netconf failure to 'authentication required' along with info needed * for sso full flow authentication. */ - void setAuthenticationRequired(void *tPtr, const char* issuerURL, const char* centralEndpoint, const char* clientID, const char *ssoProvider, const char* nonce, const char* state); + void setAuthenticationRequired(void* tPtr, const char* issuerURL, const char* centralEndpoint, const char* clientID, const char* ssoProvider, const char* nonce, const char* state); /** * Causes this network to request an updated configuration from its master node now * * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call */ - void requestConfiguration(void *tPtr); + void requestConfiguration(void* tPtr); /** * Determine whether this peer is permitted to communicate on this network @@ -257,7 +282,7 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param peer Peer to check */ - bool gate(void *tPtr,const SharedPtr &peer); + bool gate(void* tPtr, const SharedPtr& peer); /** * Check whether a given peer has recently had an association with this network @@ -270,7 +295,7 @@ public: * @param addr Peer address * @return True if peer has recently associated */ - bool recentlyAssociatedWith(const Address &addr); + bool recentlyAssociatedWith(const Address& addr); /** * Do periodic cleanup and housekeeping tasks @@ -282,10 +307,10 @@ public: * * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call */ - inline void sendUpdatesToMembers(void *tPtr) + inline void sendUpdatesToMembers(void* tPtr) { Mutex::Lock _l(_lock); - _sendUpdatesToMembers(tPtr,(const MulticastGroup *)0); + _sendUpdatesToMembers(tPtr, (const MulticastGroup*)0); } /** @@ -294,17 +319,20 @@ public: * @param mac MAC address * @return ZeroTier address of bridge to this MAC */ - inline Address findBridgeTo(const MAC &mac) const + inline Address findBridgeTo(const MAC& mac) const { Mutex::Lock _l(_lock); - const Address *const br = _remoteBridgeRoutes.get(mac); + const Address* const br = _remoteBridgeRoutes.get(mac); return ((br) ? *br : Address()); } /** * @return True if QoS is in effect for this network */ - inline bool qosEnabled() { return false; } + inline bool qosEnabled() + { + return false; + } /** * Set a bridge route @@ -312,7 +340,7 @@ public: * @param mac MAC address of destination * @param addr Bridge this MAC is reachable behind */ - void learnBridgeRoute(const MAC &mac,const Address &addr); + void learnBridgeRoute(const MAC& mac, const Address& addr); /** * Learn a multicast group that is bridged to our tap device @@ -321,52 +349,52 @@ public: * @param mg Multicast group * @param now Current time */ - void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now); + void learnBridgedMulticastGroup(void* tPtr, const MulticastGroup& mg, int64_t now); /** * Validate a credential and learn it if it passes certificate and other checks */ - Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com); + Membership::AddCredentialResult addCredential(void* tPtr, const CertificateOfMembership& com); /** * Validate a credential and learn it if it passes certificate and other checks */ - inline Membership::AddCredentialResult addCredential(void *tPtr,const Capability &cap) + inline Membership::AddCredentialResult addCredential(void* tPtr, const Capability& cap) { if (cap.networkId() != _id) { return Membership::ADD_REJECTED; } Mutex::Lock _l(_lock); - return _membership(cap.issuedTo()).addCredential(RR,tPtr,_config,cap); + return _membership(cap.issuedTo()).addCredential(RR, tPtr, _config, cap); } /** * Validate a credential and learn it if it passes certificate and other checks */ - inline Membership::AddCredentialResult addCredential(void *tPtr,const Tag &tag) + inline Membership::AddCredentialResult addCredential(void* tPtr, const Tag& tag) { if (tag.networkId() != _id) { return Membership::ADD_REJECTED; } Mutex::Lock _l(_lock); - return _membership(tag.issuedTo()).addCredential(RR,tPtr,_config,tag); + return _membership(tag.issuedTo()).addCredential(RR, tPtr, _config, tag); } /** * Validate a credential and learn it if it passes certificate and other checks */ - Membership::AddCredentialResult addCredential(void *tPtr,const Address &sentFrom,const Revocation &rev); + Membership::AddCredentialResult addCredential(void* tPtr, const Address& sentFrom, const Revocation& rev); /** * Validate a credential and learn it if it passes certificate and other checks */ - inline Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfOwnership &coo) + inline Membership::AddCredentialResult addCredential(void* tPtr, const CertificateOfOwnership& coo) { if (coo.networkId() != _id) { return Membership::ADD_REJECTED; } Mutex::Lock _l(_lock); - return _membership(coo.issuedTo()).addCredential(RR,tPtr,_config,coo); + return _membership(coo.issuedTo()).addCredential(RR, tPtr, _config, coo); } /** @@ -376,13 +404,13 @@ public: * @param to Destination peer address * @param now Current time */ - inline void peerRequestedCredentials(void *tPtr,const Address &to,const int64_t now) + inline void peerRequestedCredentials(void* tPtr, const Address& to, const int64_t now) { Mutex::Lock _l(_lock); - Membership &m = _membership(to); + Membership& m = _membership(to); const int64_t lastPushed = m.lastPushedCredentials(); - if ((lastPushed < _lastConfigUpdate)||((now - lastPushed) > ZT_PEER_CREDENTIALS_REQUEST_RATE_LIMIT)) { - m.pushCredentials(RR,tPtr,now,to,_config); + if ((lastPushed < _lastConfigUpdate) || ((now - lastPushed) > ZT_PEER_CREDENTIALS_REQUEST_RATE_LIMIT)) { + m.pushCredentials(RR, tPtr, now, to, _config); } } @@ -393,13 +421,13 @@ public: * @param to Destination peer address * @param now Current time */ - inline void pushCredentialsIfNeeded(void *tPtr,const Address &to,const int64_t now) + inline void pushCredentialsIfNeeded(void* tPtr, const Address& to, const int64_t now) { Mutex::Lock _l(_lock); - Membership &m = _membership(to); + Membership& m = _membership(to); const int64_t lastPushed = m.lastPushedCredentials(); - if ((lastPushed < _lastConfigUpdate)||((now - lastPushed) > ZT_PEER_ACTIVITY_TIMEOUT)) { - m.pushCredentials(RR,tPtr,now,to,_config); + if ((lastPushed < _lastConfigUpdate) || ((now - lastPushed) > ZT_PEER_ACTIVITY_TIMEOUT)) { + m.pushCredentials(RR, tPtr, now, to, _config); } } @@ -416,7 +444,7 @@ public: * * @param ec Buffer to fill with externally-visible network configuration */ - inline void externalConfig(ZT_VirtualNetworkConfig *ec) const + inline void externalConfig(ZT_VirtualNetworkConfig* ec) const { Mutex::Lock _l(_lock); _externalConfig(ec); @@ -425,36 +453,41 @@ public: /** * @return Externally usable pointer-to-pointer exported via the core API */ - inline void **userPtr() { return &_uPtr; } + inline void** userPtr() + { + return &_uPtr; + } -private: + private: ZT_VirtualNetworkStatus _status() const; - void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked - bool _gate(const SharedPtr &peer); - void _sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup); - void _announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector &allMulticastGroups); + void _externalConfig(ZT_VirtualNetworkConfig* ec) const; // assumes _lock is locked + bool _gate(const SharedPtr& peer); + void _sendUpdatesToMembers(void* tPtr, const MulticastGroup* const newMulticastGroup); + void _announceMulticastGroupsTo(void* tPtr, const Address& peer, const std::vector& allMulticastGroups); std::vector _allMulticastGroups() const; - Membership &_membership(const Address &a); - void _sendUpdateEvent(void *tPtr); + Membership& _membership(const Address& a); + void _sendUpdateEvent(void* tPtr); - const RuntimeEnvironment *const RR; - void *_uPtr; + const RuntimeEnvironment* const RR; + void* _uPtr; const uint64_t _id; std::string _nwidStr; uint64_t _lastAnnouncedMulticastGroupsUpstream; - MAC _mac; // local MAC address + MAC _mac; // local MAC address bool _portInitialized; - std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap) - Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge) - Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges) + std::vector _myMulticastGroups; // multicast groups that we belong to (according to tap) + Hashtable _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge) + Hashtable _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges) NetworkConfig _config; int64_t _lastConfigUpdate; - struct _IncomingConfigChunk - { - _IncomingConfigChunk() { memset(this,0,sizeof(_IncomingConfigChunk)); } + struct _IncomingConfigChunk { + _IncomingConfigChunk() + { + memset(this, 0, sizeof(_IncomingConfigChunk)); + } uint64_t ts; uint64_t updateId; uint64_t haveChunkIds[ZT_NETWORK_MAX_UPDATE_CHUNKS]; @@ -466,17 +499,11 @@ private: bool _destroyed; - enum { - NETCONF_FAILURE_NONE, - NETCONF_FAILURE_ACCESS_DENIED, - NETCONF_FAILURE_NOT_FOUND, - NETCONF_FAILURE_INIT_FAILED, - NETCONF_FAILURE_AUTHENTICATION_REQUIRED - } _netconfFailure; - int _portError; // return value from port config callback + enum { NETCONF_FAILURE_NONE, NETCONF_FAILURE_ACCESS_DENIED, NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED, NETCONF_FAILURE_AUTHENTICATION_REQUIRED } _netconfFailure; + int _portError; // return value from port config callback std::string _authenticationURL; - Hashtable _memberships; + Hashtable _memberships; Mutex _lock; diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index b1c687c68..a51fe1b29 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -11,88 +11,87 @@ */ /****/ -#include +#include "NetworkConfig.hpp" #include - -#include "NetworkConfig.hpp" +#include namespace ZeroTier { -bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const +bool NetworkConfig::toDictionary(Dictionary& d, bool includeLegacy) const { - Buffer *tmp = new Buffer(); - char tmp2[128] = {0}; + Buffer* tmp = new Buffer(); + char tmp2[128] = { 0 }; try { d.clear(); // Try to put the more human-readable fields first - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION, (uint64_t)ZT_NETWORKCONFIG_VERSION)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID, this->networkId)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP, this->timestamp)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA, this->credentialTimeMaxDelta)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION, this->revision)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, this->issuedTo.toString(tmp2))) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET, this->remoteTraceTarget.toString(tmp2))) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL, (uint64_t)this->remoteTraceLevel)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS, this->flags)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT, (uint64_t)this->multicastLimit)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)this->type)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME, this->name)) { delete tmp; return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU, (uint64_t)this->mtu)) { delete tmp; return false; } #ifdef ZT_SUPPORT_OLD_STYLE_NETCONF if (includeLegacy) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST_OLD,this->enableBroadcast())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST_OLD, this->enableBroadcast())) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD,this->isPrivate())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD, this->isPrivate())) { return false; } std::string v4s; - for(unsigned int i=0;istaticIps[i].ss_family == AF_INET) { if (v4s.length() > 0) { v4s.push_back(','); @@ -102,12 +101,12 @@ bool NetworkConfig::toDictionary(Dictionary &d,b } } if (v4s.length() > 0) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD,v4s.c_str())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD, v4s.c_str())) { return false; } } std::string v6s; - for(unsigned int i=0;istaticIps[i].ss_family == AF_INET6) { if (v6s.length() > 0) { v6s.push_back(','); @@ -117,7 +116,7 @@ bool NetworkConfig::toDictionary(Dictionary &d,b } } if (v6s.length() > 0) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD,v6s.c_str())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD, v6s.c_str())) { return false; } } @@ -125,130 +124,131 @@ bool NetworkConfig::toDictionary(Dictionary &d,b std::string ets; unsigned int et = 0; ZT_VirtualNetworkRuleType lastrt = ZT_NETWORK_RULE_ACTION_ACCEPT; - for(unsigned int i=0;i 0) { ets.push_back(','); } - char tmp2[16] = {0}; - ets.append(Utils::hex((uint16_t)et,tmp2)); + char tmp2[16] = { 0 }; + ets.append(Utils::hex((uint16_t)et, tmp2)); } et = 0; } lastrt = rt; } if (ets.length() > 0) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD,ets.c_str())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD, ets.c_str())) { return false; } } if (this->com) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD,this->com.toString().c_str())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD, this->com.toString().c_str())) { return false; } } std::string ab; - for(unsigned int i=0;ispecialistCount;++i) { + for (unsigned int i = 0; i < this->specialistCount; ++i) { if ((this->specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0) { if (ab.length() > 0) { ab.push_back(','); } - char tmp2[16] = {0}; + char tmp2[16] = { 0 }; ab.append(Address(this->specialists[i]).toString(tmp2)); } } if (ab.length() > 0) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD,ab.c_str())) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD, ab.c_str())) { return false; } } } -#endif // ZT_SUPPORT_OLD_STYLE_NETCONF +#endif // ZT_SUPPORT_OLD_STYLE_NETCONF // Then add binary blobs if (this->com) { tmp->clear(); this->com.serialize(*tmp); - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_COM, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;icapabilityCount;++i) { + for (unsigned int i = 0; i < this->capabilityCount; ++i) { this->capabilities[i].serialize(*tmp); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;itagCount;++i) { + for (unsigned int i = 0; i < this->tagCount; ++i) { this->tags[i].serialize(*tmp); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;icertificateOfOwnershipCount;++i) { + for (unsigned int i = 0; i < this->certificateOfOwnershipCount; ++i) { this->certificatesOfOwnership[i].serialize(*tmp); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;ispecialistCount;++i) { + for (unsigned int i = 0; i < this->specialistCount; ++i) { tmp->append((uint64_t)this->specialists[i]); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;irouteCount;++i) { - reinterpret_cast(&(this->routes[i].target))->serialize(*tmp); - reinterpret_cast(&(this->routes[i].via))->serialize(*tmp); + for (unsigned int i = 0; i < this->routeCount; ++i) { + reinterpret_cast(&(this->routes[i].target))->serialize(*tmp); + reinterpret_cast(&(this->routes[i].via))->serialize(*tmp); tmp->append((uint16_t)this->routes[i].flags); tmp->append((uint16_t)this->routes[i].metric); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES, *tmp)) { return false; } } tmp->clear(); - for(unsigned int i=0;istaticIpCount;++i) { + for (unsigned int i = 0; i < this->staticIpCount; ++i) { this->staticIps[i].serialize(*tmp); } if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS, *tmp)) { return false; } } if (this->ruleCount) { tmp->clear(); - Capability::serializeRules(*tmp,rules,ruleCount); + Capability::serializeRules(*tmp, rules, ruleCount); if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES, *tmp)) { return false; } } @@ -257,59 +257,61 @@ bool NetworkConfig::toDictionary(Dictionary &d,b tmp->clear(); DNS::serializeDNS(*tmp, &dns); if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_DNS,*tmp)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_DNS, *tmp)) { return false; } } if (this->ssoVersion == 0) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION, this->ssoVersion)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION, this->ssoVersion)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_ENABLED, this->ssoEnabled)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_ENABLED, this->ssoEnabled)) { return false; } if (this->ssoEnabled) { if (this->authenticationURL[0]) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL)) { return false; } } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_EXPIRY_TIME, this->authenticationExpiryTime)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_EXPIRY_TIME, this->authenticationExpiryTime)) { return false; } } - } else if(this->ssoVersion == 1) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION, this->ssoVersion)) { + } + else if (this->ssoVersion == 1) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION, this->ssoVersion)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_ENABLED, this->ssoEnabled)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_ENABLED, this->ssoEnabled)) { return false; } - //if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUER_URL, this->issuerURL)) { + // if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL)) return false; + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUER_URL, this->issuerURL)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CENTRAL_ENDPOINT_URL, this->centralAuthURL)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CENTRAL_ENDPOINT_URL, this->centralAuthURL)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NONCE, this->ssoNonce)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_NONCE, this->ssoNonce)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATE, this->ssoState)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_STATE, this->ssoState)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CLIENT_ID, this->ssoClientID)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_CLIENT_ID, this->ssoClientID)) { return false; } - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_PROVIDER, this->ssoProvider)) { + if (! d.add(ZT_NETWORKCONFIG_DICT_KEY_SSO_PROVIDER, this->ssoProvider)) { return false; } } delete tmp; - } catch ( ... ) { + } + catch (...) { delete tmp; throw; } @@ -317,83 +319,84 @@ bool NetworkConfig::toDictionary(Dictionary &d,b return true; } -bool NetworkConfig::fromDictionary(const Dictionary &d) +bool NetworkConfig::fromDictionary(const Dictionary& d) { static const NetworkConfig NIL_NC; - Buffer *tmp = new Buffer(); + Buffer* tmp = new Buffer(); try { *this = NIL_NC; // Fields that are always present, new or old - this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,0); - if (!this->networkId) { + this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID, 0); + if (! this->networkId) { delete tmp; return false; } - this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,0); - this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0); - this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0); - this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0); - if (!this->issuedTo) { + this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP, 0); + this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA, 0); + this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION, 0); + this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, 0); + if (! this->issuedTo) { delete tmp; return false; } this->remoteTraceTarget = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET); this->remoteTraceLevel = (Trace::Level)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL); - this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,0); - d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name,sizeof(this->name)); + this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT, 0); + d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME, this->name, sizeof(this->name)); - this->mtu = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MTU,ZT_DEFAULT_MTU); + this->mtu = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MTU, ZT_DEFAULT_MTU); if (this->mtu < 1280) { - this->mtu = 1280; // minimum MTU allowed by IPv6 standard and others - } else if (this->mtu > ZT_MAX_MTU) { + this->mtu = 1280; // minimum MTU allowed by IPv6 standard and others + } + else if (this->mtu > ZT_MAX_MTU) { this->mtu = ZT_MAX_MTU; } - if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) { - #ifdef ZT_SUPPORT_OLD_STYLE_NETCONF - char tmp2[1024] = {0}; + if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION, 0) < 6) { +#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF + char tmp2[1024] = { 0 }; // Decode legacy fields if version is old if (d.getB(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST_OLD)) { this->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST; } - this->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; // always enable for old-style netconf - this->type = (d.getB(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD,true)) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; + this->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; // always enable for old-style netconf + this->type = (d.getB(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD, true)) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC; - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD,tmp2,sizeof(tmp2)) > 0) { - char *saveptr = (char *)0; - for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD, tmp2, sizeof(tmp2)) > 0) { + char* saveptr = (char*)0; + for (char* f = Utils::stok(tmp2, ",", &saveptr); (f); f = Utils::stok((char*)0, ",", &saveptr)) { if (this->staticIpCount >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) { break; } InetAddress ip(f); - if (!ip.isNetwork()) { + if (! ip.isNetwork()) { this->staticIps[this->staticIpCount++] = ip; } } } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD,tmp2,sizeof(tmp2)) > 0) { - char *saveptr = (char *)0; - for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD, tmp2, sizeof(tmp2)) > 0) { + char* saveptr = (char*)0; + for (char* f = Utils::stok(tmp2, ",", &saveptr); (f); f = Utils::stok((char*)0, ",", &saveptr)) { if (this->staticIpCount >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) { break; } InetAddress ip(f); - if (!ip.isNetwork()) { + if (! ip.isNetwork()) { this->staticIps[this->staticIpCount++] = ip; } } } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD,tmp2,sizeof(tmp2)) > 0) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD, tmp2, sizeof(tmp2)) > 0) { this->com.fromString(tmp2); } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD,tmp2,sizeof(tmp2)) > 0) { - char *saveptr = (char *)0; - for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD, tmp2, sizeof(tmp2)) > 0) { + char* saveptr = (char*)0; + for (char* f = Utils::stok(tmp2, ",", &saveptr); (f); f = Utils::stok((char*)0, ",", &saveptr)) { unsigned int et = Utils::hexStrToUInt(f) & 0xffff; if ((this->ruleCount + 2) > ZT_MAX_NETWORK_RULES) { break; @@ -405,67 +408,74 @@ bool NetworkConfig::fromDictionary(const Dictionaryrules[this->ruleCount++].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT; } - } else { + } + else { this->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT; this->ruleCount = 1; } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD,tmp2,sizeof(tmp2)) > 0) { - char *saveptr = (char *)0; - for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { - this->addSpecialist(Address(Utils::hexStrToU64(f)),ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD, tmp2, sizeof(tmp2)) > 0) { + char* saveptr = (char*)0; + for (char* f = Utils::stok(tmp2, ",", &saveptr); (f); f = Utils::stok((char*)0, ",", &saveptr)) { + this->addSpecialist(Address(Utils::hexStrToU64(f)), ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); } } - #else +#else delete tmp; return false; - #endif // ZT_SUPPORT_OLD_STYLE_NETCONF - } else { +#endif // ZT_SUPPORT_OLD_STYLE_NETCONF + } + else { // Otherwise we can use the new fields - this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,0); - this->type = (ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)ZT_NETWORK_TYPE_PRIVATE); + this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS, 0); + this->type = (ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)ZT_NETWORK_TYPE_PRIVATE); - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) { - this->com.deserialize(*tmp,0); + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_COM, *tmp)) { + this->com.deserialize(*tmp, 0); } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES, *tmp)) { try { unsigned int p = 0; while (p < tmp->size()) { Capability cap; - p += cap.deserialize(*tmp,p); + p += cap.deserialize(*tmp, p); this->capabilities[this->capabilityCount++] = cap; } - } catch ( ... ) {} - std::sort(&(this->capabilities[0]),&(this->capabilities[this->capabilityCount])); + } + catch (...) { + } + std::sort(&(this->capabilities[0]), &(this->capabilities[this->capabilityCount])); } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_TAGS, *tmp)) { try { unsigned int p = 0; while (p < tmp->size()) { Tag tag; - p += tag.deserialize(*tmp,p); + p += tag.deserialize(*tmp, p); this->tags[this->tagCount++] = tag; } - } catch ( ... ) {} - std::sort(&(this->tags[0]),&(this->tags[this->tagCount])); + } + catch (...) { + } + std::sort(&(this->tags[0]), &(this->tags[this->tagCount])); } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP, *tmp)) { unsigned int p = 0; while (p < tmp->size()) { if (certificateOfOwnershipCount < ZT_MAX_CERTIFICATES_OF_OWNERSHIP) { - p += certificatesOfOwnership[certificateOfOwnershipCount++].deserialize(*tmp,p); - } else { + p += certificatesOfOwnership[certificateOfOwnershipCount++].deserialize(*tmp, p); + } + else { CertificateOfOwnership foo; - p += foo.deserialize(*tmp,p); + p += foo.deserialize(*tmp, p); } } } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS, *tmp)) { unsigned int p = 0; while ((p + 8) <= tmp->size()) { if (specialistCount < ZT_MAX_NETWORK_SPECIALISTS) { @@ -475,11 +485,11 @@ bool NetworkConfig::fromDictionary(const Dictionarysize())&&(routeCount < ZT_MAX_NETWORK_ROUTES)) { - p += reinterpret_cast(&(this->routes[this->routeCount].target))->deserialize(*tmp,p); - p += reinterpret_cast(&(this->routes[this->routeCount].via))->deserialize(*tmp,p); + while ((p < tmp->size()) && (routeCount < ZT_MAX_NETWORK_ROUTES)) { + p += reinterpret_cast(&(this->routes[this->routeCount].target))->deserialize(*tmp, p); + p += reinterpret_cast(&(this->routes[this->routeCount].via))->deserialize(*tmp, p); this->routes[this->routeCount].flags = tmp->at(p); p += 2; this->routes[this->routeCount].metric = tmp->at(p); @@ -488,17 +498,17 @@ bool NetworkConfig::fromDictionary(const Dictionarysize())&&(staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { - p += this->staticIps[this->staticIpCount++].deserialize(*tmp,p); + while ((p < tmp->size()) && (staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) { + p += this->staticIps[this->staticIpCount++].deserialize(*tmp, p); } } - if (d.get(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) { + if (d.get(ZT_NETWORKCONFIG_DICT_KEY_RULES, *tmp)) { this->ruleCount = 0; unsigned int p = 0; - Capability::deserializeRules(*tmp,p,this->rules,this->ruleCount,ZT_MAX_NETWORK_RULES); + Capability::deserializeRules(*tmp, p, this->rules, this->ruleCount, ZT_MAX_NETWORK_RULES); } if (d.get(ZT_NETWORKCONFIG_DICT_KEY_DNS, *tmp)) { @@ -513,16 +523,19 @@ bool NetworkConfig::fromDictionary(const DictionaryssoEnabled) { if (d.get(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL, (unsigned int)sizeof(this->authenticationURL)) > 0) { - this->authenticationURL[sizeof(this->authenticationURL) - 1] = 0; // ensure null terminated - } else { + this->authenticationURL[sizeof(this->authenticationURL) - 1] = 0; // ensure null terminated + } + else { this->authenticationURL[0] = 0; } this->authenticationExpiryTime = d.getI(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_EXPIRY_TIME, 0); - } else { + } + else { this->authenticationURL[0] = 0; this->authenticationExpiryTime = 0; } - } else if (this->ssoVersion == 1) { + } + else if (this->ssoVersion == 1) { // full flow if (this->ssoEnabled) { if (d.get(ZT_NETWORKCONFIG_DICT_KEY_AUTHENTICATION_URL, this->authenticationURL, (unsigned int)sizeof(this->authenticationURL)) > 0) { @@ -545,11 +558,13 @@ bool NetworkConfig::fromDictionary(const DictionaryssoProvider, (unsigned int)(sizeof(this->ssoProvider))) > 0) { this->ssoProvider[sizeof(this->ssoProvider) - 1] = 0; - } else { + } + else { strncpy(this->ssoProvider, "default", sizeof(this->ssoProvider)); this->ssoProvider[sizeof(this->ssoProvider) - 1] = 0; } - } else { + } + else { this->authenticationURL[0] = 0; this->authenticationExpiryTime = 0; this->centralAuthURL[0] = 0; @@ -562,16 +577,17 @@ bool NetworkConfig::fromDictionary(const Dictionary -#include -#include - -#include -#include -#include - #include "../include/ZeroTierOne.h" - -#include "Constants.hpp" -#include "Buffer.hpp" -#include "DNS.hpp" -#include "InetAddress.hpp" -#include "MulticastGroup.hpp" #include "Address.hpp" +#include "Buffer.hpp" +#include "Capability.hpp" #include "CertificateOfMembership.hpp" #include "CertificateOfOwnership.hpp" -#include "Capability.hpp" -#include "Tag.hpp" +#include "Constants.hpp" +#include "DNS.hpp" #include "Dictionary.hpp" #include "Hashtable.hpp" #include "Identity.hpp" -#include "Utils.hpp" +#include "InetAddress.hpp" +#include "MulticastGroup.hpp" +#include "Tag.hpp" #include "Trace.hpp" +#include "Utils.hpp" + +#include +#include +#include +#include +#include +#include /** * Default time delta for COMs, tags, and capabilities @@ -93,7 +91,9 @@ namespace ZeroTier { // Dictionary capacity needed for max size network config -#define ZT_NETWORKCONFIG_DICT_CAPACITY (4096 + (sizeof(ZT_VirtualNetworkConfig)) + (sizeof(ZT_VirtualNetworkRule) * ZT_MAX_NETWORK_RULES) + (sizeof(Capability) * ZT_MAX_NETWORK_CAPABILITIES) + (sizeof(Tag) * ZT_MAX_NETWORK_TAGS) + (sizeof(CertificateOfOwnership) * ZT_MAX_CERTIFICATES_OF_OWNERSHIP)) +#define ZT_NETWORKCONFIG_DICT_CAPACITY \ + (4096 + (sizeof(ZT_VirtualNetworkConfig)) + (sizeof(ZT_VirtualNetworkRule) * ZT_MAX_NETWORK_RULES) + (sizeof(Capability) * ZT_MAX_NETWORK_CAPABILITIES) + (sizeof(Tag) * ZT_MAX_NETWORK_TAGS) \ + + (sizeof(CertificateOfOwnership) * ZT_MAX_CERTIFICATES_OF_OWNERSHIP)) // Dictionary capacity needed for max size network meta-data #define ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY 1024 @@ -248,46 +248,45 @@ namespace ZeroTier { * This is a memcpy()'able structure and is safe (in a crash sense) to modify * without locks. */ -class NetworkConfig -{ -public: - NetworkConfig() : - networkId(0), - timestamp(0), - credentialTimeMaxDelta(0), - revision(0), - issuedTo(), - remoteTraceTarget(), - flags(0), - remoteTraceLevel(Trace::LEVEL_NORMAL), - mtu(0), - multicastLimit(0), - specialistCount(0), - routeCount(0), - staticIpCount(0), - ruleCount(0), - capabilityCount(0), - tagCount(0), - certificateOfOwnershipCount(0), - capabilities(), - tags(), - certificatesOfOwnership(), - type(ZT_NETWORK_TYPE_PRIVATE), - dnsCount(0), - ssoEnabled(false), - authenticationURL(), - authenticationExpiryTime(0), - issuerURL(), - centralAuthURL(), - ssoNonce(), - ssoState(), - ssoClientID() +class NetworkConfig { + public: + NetworkConfig() + : networkId(0) + , timestamp(0) + , credentialTimeMaxDelta(0) + , revision(0) + , issuedTo() + , remoteTraceTarget() + , flags(0) + , remoteTraceLevel(Trace::LEVEL_NORMAL) + , mtu(0) + , multicastLimit(0) + , specialistCount(0) + , routeCount(0) + , staticIpCount(0) + , ruleCount(0) + , capabilityCount(0) + , tagCount(0) + , certificateOfOwnershipCount(0) + , capabilities() + , tags() + , certificatesOfOwnership() + , type(ZT_NETWORK_TYPE_PRIVATE) + , dnsCount(0) + , ssoEnabled(false) + , authenticationURL() + , authenticationExpiryTime(0) + , issuerURL() + , centralAuthURL() + , ssoNonce() + , ssoState() + , ssoClientID() { name[0] = 0; - memset(specialists, 0, sizeof(uint64_t)*ZT_MAX_NETWORK_SPECIALISTS); - 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(specialists, 0, sizeof(uint64_t) * ZT_MAX_NETWORK_SPECIALISTS); + 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)); memset(authenticationURL, 0, sizeof(authenticationURL)); memset(issuerURL, 0, sizeof(issuerURL)); @@ -305,7 +304,7 @@ public: * @param includeLegacy If true, include legacy fields for old node versions * @return True if dictionary was successfully created, false if e.g. overflow */ - bool toDictionary(Dictionary &d,bool includeLegacy) const; + bool toDictionary(Dictionary& d, bool includeLegacy) const; /** * Read this network config from a dictionary @@ -313,17 +312,23 @@ public: * @param d Dictionary (non-const since it might be modified during parse, should not be used after call) * @return True if dictionary was valid and network config successfully initialized */ - bool fromDictionary(const Dictionary &d); + bool fromDictionary(const Dictionary& d); /** * @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network */ - inline bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); } + inline bool enableBroadcast() const + { + return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); + } /** * @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns */ - inline bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); } + inline bool ndpEmulation() const + { + return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); + } /** * @return True if frames should not be compressed @@ -344,12 +349,18 @@ public: /** * @return Network type is public (no access control) */ - inline bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); } + inline bool isPublic() const + { + return (this->type == ZT_NETWORK_TYPE_PUBLIC); + } /** * @return Network type is private (certificate access control) */ - inline bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); } + inline bool isPrivate() const + { + return (this->type == ZT_NETWORK_TYPE_PRIVATE); + } /** * @return ZeroTier addresses of devices on this network designated as active bridges @@ -357,7 +368,7 @@ public: inline std::vector
activeBridges() const { std::vector
r; - for(unsigned int i=0;i anchors() const { std::vector
r; - for(unsigned int i=0;i multicastReplicators() const { std::vector
r; - for(unsigned int i=0;i alwaysContactAddresses() const { std::vector
r; - for(unsigned int i=0;i > &a) const + inline void alwaysContactAddresses(Hashtable >& a) const { - for(unsigned int i=0;i - +#include "Address.hpp" #include "Constants.hpp" #include "Dictionary.hpp" #include "NetworkConfig.hpp" #include "Revocation.hpp" -#include "Address.hpp" + +#include namespace ZeroTier { @@ -30,24 +30,15 @@ struct InetAddress; /** * Interface for network controller implementations */ -class NetworkController -{ -public: - enum ErrorCode - { - NC_ERROR_NONE = 0, - NC_ERROR_OBJECT_NOT_FOUND = 1, - NC_ERROR_ACCESS_DENIED = 2, - NC_ERROR_INTERNAL_SERVER_ERROR = 3, - NC_ERROR_AUTHENTICATION_REQUIRED = 4 - }; +class NetworkController { + public: + enum ErrorCode { NC_ERROR_NONE = 0, NC_ERROR_OBJECT_NOT_FOUND = 1, NC_ERROR_ACCESS_DENIED = 2, NC_ERROR_INTERNAL_SERVER_ERROR = 3, NC_ERROR_AUTHENTICATION_REQUIRED = 4 }; /** * Interface for sender used to send pushes and replies */ - class Sender - { - public: + class Sender { + public: /** * Send a configuration to a remote peer * @@ -57,7 +48,7 @@ public: * @param nc Network configuration to send * @param sendLegacyFormatConfig If true, send an old-format network config */ - virtual void ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig) = 0; + virtual void ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig) = 0; /** * Send revocation to a node @@ -65,14 +56,14 @@ public: * @param destination Destination node address * @param rev Revocation to send */ - virtual void ncSendRevocation(const Address &destination,const Revocation &rev) = 0; + virtual void ncSendRevocation(const Address& destination, const Revocation& rev) = 0; /** * Send a network configuration request error * * If errorData/errorDataSize are provided they must point to a valid serialized * Dictionary containing error data. They can be null/zero if not specified. - * + * * @param nwid Network ID * @param requestPacketId Request packet ID or 0 if none * @param destination Destination peer Address @@ -80,11 +71,15 @@ public: * @param errorData Data associated with error or NULL if none * @param errorDataSize Size of errorData in bytes */ - virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode, const void *errorData, unsigned int errorDataSize) = 0; + virtual void ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode, const void* errorData, unsigned int errorDataSize) = 0; }; - NetworkController() {} - virtual ~NetworkController() {} + NetworkController() + { + } + virtual ~NetworkController() + { + } /** * Called when this is added to a Node to initialize and supply info @@ -92,7 +87,7 @@ public: * @param signingId Identity for signing of network configurations, certs, etc. * @param sender Sender implementation for sending replies or config pushes */ - virtual void init(const Identity &signingId,Sender *sender) = 0; + virtual void init(const Identity& signingId, Sender* sender) = 0; /** * Handle a network configuration request @@ -104,14 +99,9 @@ public: * @param metaData Meta-data bundled with request (if any) * @return Returns NETCONF_QUERY_OK if result 'nc' is valid, or an error code on error */ - virtual void request( - uint64_t nwid, - const InetAddress &fromAddr, - uint64_t requestPacketId, - const Identity &identity, - const Dictionary &metaData) = 0; + virtual void request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData) = 0; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Node.cpp b/node/Node.cpp index 1f377c545..4b9911a66 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -11,31 +11,31 @@ */ /****/ -#include -#include -#include -#include -#include +#include "Node.hpp" #include "../version.h" - -#include "Constants.hpp" -#include "SharedPtr.hpp" -#include "Node.hpp" -#include "RuntimeEnvironment.hpp" -#include "NetworkController.hpp" -#include "Switch.hpp" -#include "Multicaster.hpp" -#include "Topology.hpp" -#include "Buffer.hpp" -#include "Packet.hpp" #include "Address.hpp" +#include "Buffer.hpp" +#include "Constants.hpp" #include "Identity.hpp" -#include "SelfAwareness.hpp" -#include "Network.hpp" -#include "Trace.hpp" #include "Metrics.hpp" +#include "Multicaster.hpp" +#include "Network.hpp" +#include "NetworkController.hpp" +#include "Packet.hpp" #include "PacketMultiplexer.hpp" +#include "RuntimeEnvironment.hpp" +#include "SelfAwareness.hpp" +#include "SharedPtr.hpp" +#include "Switch.hpp" +#include "Topology.hpp" +#include "Trace.hpp" + +#include +#include +#include +#include +#include // FIXME: remove this suppression and actually fix warnings #ifdef __GNUC__ @@ -48,72 +48,74 @@ namespace ZeroTier { /* Public Node interface (C++, exposed via CAPI bindings) */ /****************************************************************************/ -Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now) : - _RR(this), - RR(&_RR), - _uPtr(uptr), - _networks(8), - _now(now), - _lastPingCheck(0), - _lastGratuitousPingCheck(0), - _lastHousekeepingRun(0), - _lastMemoizedTraceSettings(0), - _lowBandwidthMode(false) +Node::Node(void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now) + : _RR(this) + , RR(&_RR) + , _uPtr(uptr) + , _networks(8) + , _now(now) + , _lastPingCheck(0) + , _lastGratuitousPingCheck(0) + , _lastHousekeepingRun(0) + , _lastMemoizedTraceSettings(0) + , _lowBandwidthMode(false) { if (callbacks->version != 0) { throw ZT_EXCEPTION_INVALID_ARGUMENT; } - memcpy(&_cb,callbacks,sizeof(ZT_Node_Callbacks)); + memcpy(&_cb, callbacks, sizeof(ZT_Node_Callbacks)); // Initialize non-cryptographic PRNG from a good random source - Utils::getSecureRandom((void *)_prngState,sizeof(_prngState)); + Utils::getSecureRandom((void*)_prngState, sizeof(_prngState)); _online = false; - memset(_expectingRepliesToBucketPtr,0,sizeof(_expectingRepliesToBucketPtr)); - memset(_expectingRepliesTo,0,sizeof(_expectingRepliesTo)); - memset(_lastIdentityVerification,0,sizeof(_lastIdentityVerification)); - memset((void *)(&_stats),0,sizeof(_stats)); + memset(_expectingRepliesToBucketPtr, 0, sizeof(_expectingRepliesToBucketPtr)); + memset(_expectingRepliesTo, 0, sizeof(_expectingRepliesTo)); + memset(_lastIdentityVerification, 0, sizeof(_lastIdentityVerification)); + memset((void*)(&_stats), 0, sizeof(_stats)); uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0; char tmp[2048]; - int n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,tmp,sizeof(tmp) - 1); + int n = stateObjectGet(tptr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, tmp, sizeof(tmp) - 1); if (n > 0) { tmp[n] = (char)0; if (RR->identity.fromString(tmp)) { - RR->identity.toString(false,RR->publicIdentityStr); - RR->identity.toString(true,RR->secretIdentityStr); - } else { + RR->identity.toString(false, RR->publicIdentityStr); + RR->identity.toString(true, RR->secretIdentityStr); + } + else { throw ZT_EXCEPTION_INVALID_IDENTITY; } - if (!RR->identity.locallyValidate()) { + if (! RR->identity.locallyValidate()) { throw ZT_EXCEPTION_INVALID_IDENTITY; } } if (n <= 0) { RR->identity.generate(); - RR->identity.toString(false,RR->publicIdentityStr); - RR->identity.toString(true,RR->secretIdentityStr); + RR->identity.toString(false, RR->publicIdentityStr); + RR->identity.toString(true, RR->secretIdentityStr); idtmp[0] = RR->identity.address().toInt(); idtmp[1] = 0; - stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,RR->secretIdentityStr,(unsigned int)strlen(RR->secretIdentityStr)); - stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr)); - } else { + stateObjectPut(tptr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, RR->secretIdentityStr, (unsigned int)strlen(RR->secretIdentityStr)); + stateObjectPut(tptr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); + } + else { idtmp[0] = RR->identity.address().toInt(); idtmp[1] = 0; - n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,tmp,sizeof(tmp) - 1); - if ((n > 0)&&(n < (int)sizeof(RR->publicIdentityStr))&&(n < (int)sizeof(tmp))) { - if (memcmp(tmp,RR->publicIdentityStr,n)) { - stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr)); + n = stateObjectGet(tptr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, tmp, sizeof(tmp) - 1); + if ((n > 0) && (n < (int)sizeof(RR->publicIdentityStr)) && (n < (int)sizeof(tmp))) { + if (memcmp(tmp, RR->publicIdentityStr, n)) { + stateObjectPut(tptr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); } } } - char *m = (char *)0; + char* m = (char*)0; try { const unsigned long ts = sizeof(Trace) + (((sizeof(Trace) & 0xf) != 0) ? (16 - (sizeof(Trace) & 0xf)) : 0); const unsigned long sws = sizeof(Switch) + (((sizeof(Switch) & 0xf) != 0) ? (16 - (sizeof(Switch) & 0xf)) : 0); @@ -123,8 +125,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64 const unsigned long bcs = sizeof(Bond) + (((sizeof(Bond) & 0xf) != 0) ? (16 - (sizeof(Bond) & 0xf)) : 0); const unsigned long pms = sizeof(PacketMultiplexer) + (((sizeof(PacketMultiplexer) & 0xf) != 0) ? (16 - (sizeof(PacketMultiplexer) & 0xf)) : 0); - m = reinterpret_cast(::malloc(16 + ts + sws + mcs + topologys + sas + bcs + pms)); - if (!m) { + m = reinterpret_cast(::malloc(16 + ts + sws + mcs + topologys + sas + bcs + pms)); + if (! m) { throw std::bad_alloc(); } RR->rtmem = m; @@ -138,14 +140,15 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64 m += sws; RR->mc = new (m) Multicaster(RR); m += mcs; - RR->topology = new (m) Topology(RR,tptr); + RR->topology = new (m) Topology(RR, tptr); m += topologys; RR->sa = new (m) SelfAwareness(RR); m += sas; RR->bc = new (m) Bond(RR); m += bcs; RR->pm = new (m) PacketMultiplexer(RR); - } catch ( ... ) { + } + catch (...) { if (RR->sa) { RR->sa->~SelfAwareness(); } @@ -171,14 +174,14 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64 throw; } - postEvent(tptr,ZT_EVENT_UP); + postEvent(tptr, ZT_EVENT_UP); } Node::~Node() { { Mutex::Lock _l(_networks_m); - _networks.clear(); // destroy all networks before shutdown + _networks.clear(); // destroy all networks before shutdown } if (RR->sa) { RR->sa->~SelfAwareness(); @@ -204,38 +207,32 @@ Node::~Node() ::free(RR->rtmem); } -ZT_ResultCode Node::processWirePacket( - void *tptr, - int64_t now, - int64_t localSocket, - const struct sockaddr_storage *remoteAddress, - const void *packetData, - unsigned int packetLength, - volatile int64_t *nextBackgroundTaskDeadline) +ZT_ResultCode Node::processWirePacket(void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline) { _now = now; - RR->sw->onRemotePacket(tptr,localSocket,*(reinterpret_cast(remoteAddress)),packetData,packetLength); + RR->sw->onRemotePacket(tptr, localSocket, *(reinterpret_cast(remoteAddress)), packetData, packetLength); return ZT_RESULT_OK; } ZT_ResultCode Node::processVirtualNetworkFrame( - void *tptr, + void* tptr, int64_t now, uint64_t nwid, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, - const void *frameData, + const void* frameData, unsigned int frameLength, - volatile int64_t *nextBackgroundTaskDeadline) + volatile int64_t* nextBackgroundTaskDeadline) { _now = now; SharedPtr nw(this->network(nwid)); if (nw) { - RR->sw->onLocalEthernet(tptr,nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength); + RR->sw->onLocalEthernet(tptr, nw, MAC(sourceMac), MAC(destMac), etherType, vlanId, frameData, frameLength); return ZT_RESULT_OK; - } else { + } + else { return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } } @@ -246,23 +243,21 @@ void Node::initMultithreading(unsigned int concurrency, bool cpuPinningEnabled) } // Closure used to ping upstream and active/online peers -class _PingPeersThatNeedPing -{ -public: - _PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector > &alwaysContact,int64_t now) : - RR(renv), - _tPtr(tPtr), - _alwaysContact(alwaysContact), - _now(now), - _bestCurrentUpstream(RR->topology->getUpstreamPeer()) +class _PingPeersThatNeedPing { + public: + _PingPeersThatNeedPing(const RuntimeEnvironment* renv, void* tPtr, Hashtable >& alwaysContact, int64_t now) + : RR(renv) + , _tPtr(tPtr) + , _alwaysContact(alwaysContact) + , _now(now) + , _bestCurrentUpstream(RR->topology->getUpstreamPeer()) { } - inline void operator()(Topology &t,const SharedPtr &p) + inline void operator()(Topology& t, const SharedPtr& p) { - const std::vector *const alwaysContactEndpoints = _alwaysContact.get(p->address()); + const std::vector* const alwaysContactEndpoints = _alwaysContact.get(p->address()); if (alwaysContactEndpoints) { - ZT_PeerRole role = RR->topology->role(p->address()); // Contact upstream peers as infrequently as possible @@ -270,59 +265,60 @@ public: // Unless we don't any have paths to the roots, then we shouldn't wait a long time to contact them bool hasPaths = p->paths(RR->node->now()).size() > 0; - roleBasedTimerScale = (role != ZT_PEER_ROLE_LEAF && !hasPaths) ? 0 : roleBasedTimerScale; + roleBasedTimerScale = (role != ZT_PEER_ROLE_LEAF && ! hasPaths) ? 0 : roleBasedTimerScale; if ((RR->node->now() - p->lastSentFullHello()) <= (ZT_PATH_HEARTBEAT_PERIOD * roleBasedTimerScale)) { return; } - const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now); + const unsigned int sent = p->doPingAndKeepalive(_tPtr, _now); bool contacted = (sent != 0); - if ((sent & 0x1) == 0) { // bit 0x1 == IPv4 sent - for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)alwaysContactEndpoints->size();++k) { - const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()]; + if ((sent & 0x1) == 0) { // bit 0x1 == IPv4 sent + for (unsigned long k = 0, ptr = (unsigned long)RR->node->prng(); k < (unsigned long)alwaysContactEndpoints->size(); ++k) { + const InetAddress& addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()]; if (addr.ss_family == AF_INET) { - p->sendHELLO(_tPtr,-1,addr,_now); + p->sendHELLO(_tPtr, -1, addr, _now); contacted = true; break; } } } - if ((sent & 0x2) == 0) { // bit 0x2 == IPv6 sent - for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)alwaysContactEndpoints->size();++k) { - const InetAddress &addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()]; + if ((sent & 0x2) == 0) { // bit 0x2 == IPv6 sent + for (unsigned long k = 0, ptr = (unsigned long)RR->node->prng(); k < (unsigned long)alwaysContactEndpoints->size(); ++k) { + const InetAddress& addr = (*alwaysContactEndpoints)[ptr++ % alwaysContactEndpoints->size()]; if (addr.ss_family == AF_INET6) { - p->sendHELLO(_tPtr,-1,addr,_now); + p->sendHELLO(_tPtr, -1, addr, _now); contacted = true; break; } } } - if ((!contacted)&&(_bestCurrentUpstream)) { - const SharedPtr up(_bestCurrentUpstream->getAppropriatePath(_now,true)); + if ((! contacted) && (_bestCurrentUpstream)) { + const SharedPtr up(_bestCurrentUpstream->getAppropriatePath(_now, true)); if (up) { - p->sendHELLO(_tPtr,up->localSocket(),up->address(),_now); + p->sendHELLO(_tPtr, up->localSocket(), up->address(), _now); } } - _alwaysContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain - } else if (p->isActive(_now)) { - p->doPingAndKeepalive(_tPtr,_now); + _alwaysContact.erase(p->address()); // after this we'll WHOIS all upstreams that remain + } + else if (p->isActive(_now)) { + p->doPingAndKeepalive(_tPtr, _now); } } -private: - const RuntimeEnvironment *RR; - void *_tPtr; - Hashtable< Address,std::vector > &_alwaysContact; + private: + const RuntimeEnvironment* RR; + void* _tPtr; + Hashtable >& _alwaysContact; const int64_t _now; const SharedPtr _bestCurrentUpstream; }; -ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline) +ZT_ResultCode Node::processBackgroundTasks(void* tptr, int64_t now, volatile int64_t* nextBackgroundTaskDeadline) { _now = now; Mutex::Lock bl(_backgroundTasksLock); @@ -344,7 +340,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 _lastPingCheck = now; // Get designated VL1 upstreams - Hashtable< Address,std::vector > alwaysContact; + Hashtable > alwaysContact; RR->topology->getUpstreamsToContact(alwaysContact); // Uncomment to dump stats @@ -359,13 +355,13 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 // Check last receive time on designated upstreams to see if we seem to be online int64_t lastReceivedFromUpstream = 0; { - Hashtable< Address,std::vector >::Iterator i(alwaysContact); - Address *upstreamAddress = (Address *)0; - std::vector *upstreamStableEndpoints = (std::vector *)0; - while (i.next(upstreamAddress,upstreamStableEndpoints)) { + Hashtable >::Iterator i(alwaysContact); + Address* upstreamAddress = (Address*)0; + std::vector* upstreamStableEndpoints = (std::vector*)0; + while (i.next(upstreamAddress, upstreamStableEndpoints)) { SharedPtr p(RR->topology->getPeerNoCache(*upstreamAddress)); if (p) { - lastReceivedFromUpstream = std::max(p->lastReceive(),lastReceivedFromUpstream); + lastReceivedFromUpstream = std::max(p->lastReceive(), lastReceivedFromUpstream); } } } @@ -373,10 +369,10 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 // Clean up any old local controller auth memorizations. { _localControllerAuthorizations_m.lock(); - Hashtable< _LocalControllerAuth,int64_t >::Iterator i(_localControllerAuthorizations); - _LocalControllerAuth *k = (_LocalControllerAuth *)0; - int64_t *v = (int64_t *)0; - while (i.next(k,v)) { + Hashtable<_LocalControllerAuth, int64_t>::Iterator i(_localControllerAuthorizations); + _LocalControllerAuth* k = (_LocalControllerAuth*)0; + int64_t* v = (int64_t*)0; + while (i.next(k, v)) { if ((*v - now) > (ZT_NETWORK_AUTOCONF_DELAY * 3)) { _localControllerAuthorizations.erase(*k); } @@ -387,34 +383,34 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 // Get peers we should stay connected to according to network configs // Also get networks and whether they need config so we only have to do one pass over networks int timerScale = _lowBandwidthMode ? 64 : 1; - std::vector< std::pair< SharedPtr,bool > > networkConfigNeeded; + std::vector, bool> > networkConfigNeeded; { Mutex::Lock l(_networks_m); - Hashtable< uint64_t,SharedPtr >::Iterator i(_networks); - uint64_t *nwid = (uint64_t *)0; - SharedPtr *network = (SharedPtr *)0; - while (i.next(nwid,network)) { + Hashtable >::Iterator i(_networks); + uint64_t* nwid = (uint64_t*)0; + SharedPtr* network = (SharedPtr*)0; + while (i.next(nwid, network)) { (*network)->config().alwaysContactAddresses(alwaysContact); - networkConfigNeeded.push_back( std::pair< SharedPtr,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY * timerScale)||(!(*network)->hasConfig()))) ); + networkConfigNeeded.push_back(std::pair, bool>(*network, (((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY * timerScale) || (! (*network)->hasConfig())))); } } // Ping active peers, upstreams, and others that we should always contact - _PingPeersThatNeedPing pfunc(RR,tptr,alwaysContact,now); - RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc); + _PingPeersThatNeedPing pfunc(RR, tptr, alwaysContact, now); + RR->topology->eachPeer<_PingPeersThatNeedPing&>(pfunc); // Run WHOIS to create Peer for alwaysContact addresses that could not be contacted { - Hashtable< Address,std::vector >::Iterator i(alwaysContact); - Address *upstreamAddress = (Address *)0; - std::vector *upstreamStableEndpoints = (std::vector *)0; - while (i.next(upstreamAddress,upstreamStableEndpoints)) { - RR->sw->requestWhois(tptr,now,*upstreamAddress); + Hashtable >::Iterator i(alwaysContact); + Address* upstreamAddress = (Address*)0; + std::vector* upstreamStableEndpoints = (std::vector*)0; + while (i.next(upstreamAddress, upstreamStableEndpoints)) { + RR->sw->requestWhois(tptr, now, *upstreamAddress); } } // Refresh network config or broadcast network updates to members as needed - for(std::vector< std::pair< SharedPtr,bool > >::const_iterator n(networkConfigNeeded.begin());n!=networkConfigNeeded.end();++n) { + for (std::vector, bool> >::const_iterator n(networkConfigNeeded.begin()); n != networkConfigNeeded.end(); ++n) { if (n->second) { n->first->requestConfiguration(tptr); } @@ -425,14 +421,16 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 // Update online status, post status change as event const bool oldOnline = _online; - _online = (((now - lastReceivedFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT)||(RR->topology->amUpstream())); + _online = (((now - lastReceivedFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT) || (RR->topology->amUpstream())); if (oldOnline != _online) { - postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); + postEvent(tptr, _online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); } - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } - } else { + } + else { timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck; } @@ -444,42 +442,44 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) { _lastHousekeepingRun = now; try { - RR->topology->doPeriodicTasks(tptr,now); + RR->topology->doPeriodicTasks(tptr, now); RR->sa->clean(now); RR->mc->clean(now); - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } try { - *nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(bondCheckInterval,std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(tptr,now))),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY); - } catch ( ... ) { + *nextBackgroundTaskDeadline = now + (int64_t)std::max(std::min(bondCheckInterval, std::min(timeUntilNextPingCheck, RR->sw->doTimerTasks(tptr, now))), (unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY); + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } return ZT_RESULT_OK; } -ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr) +ZT_ResultCode Node::join(uint64_t nwid, void* uptr, void* tptr) { Mutex::Lock _l(_networks_m); - SharedPtr &nw = _networks[nwid]; - if (!nw) { - nw = SharedPtr(new Network(RR,tptr,nwid,uptr,(const NetworkConfig *)0)); + SharedPtr& nw = _networks[nwid]; + if (! nw) { + nw = SharedPtr(new Network(RR, tptr, nwid, uptr, (const NetworkConfig*)0)); } return ZT_RESULT_OK; } -ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr) +ZT_ResultCode Node::leave(uint64_t nwid, void** uptr, void* tptr) { ZT_VirtualNetworkConfig ctmp; - void **nUserPtr = (void **)0; + void** nUserPtr = (void**)0; { Mutex::Lock _l(_networks_m); - SharedPtr *nw = _networks.get(nwid); + SharedPtr* nw = _networks.get(nwid); RR->sw->removeNetworkQoSControlBlock(nwid); - if (!nw) { + if (! nw) { return ZT_RESULT_OK; } if (uptr) { @@ -491,7 +491,7 @@ ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr) } if (nUserPtr) { - RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + RR->node->configureVirtualNetworkPort(tptr, nwid, nUserPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp); } { @@ -502,42 +502,44 @@ ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr) uint64_t tmp[2]; tmp[0] = nwid; tmp[1] = 0; - RR->node->stateObjectDelete(tptr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp); + RR->node->stateObjectDelete(tptr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp); return ZT_RESULT_OK; } -ZT_ResultCode Node::multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +ZT_ResultCode Node::multicastSubscribe(void* tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi) { SharedPtr nw(this->network(nwid)); if (nw) { - nw->multicastSubscribe(tptr,MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); + nw->multicastSubscribe(tptr, MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff))); return ZT_RESULT_OK; - } else { + } + else { return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } } -ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi) { SharedPtr nw(this->network(nwid)); if (nw) { - nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); + nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff))); return ZT_RESULT_OK; - } else { + } + else { return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } } -ZT_ResultCode Node::orbit(void *tptr,uint64_t moonWorldId,uint64_t moonSeed) +ZT_ResultCode Node::orbit(void* tptr, uint64_t moonWorldId, uint64_t moonSeed) { - RR->topology->addMoon(tptr,moonWorldId,Address(moonSeed)); + RR->topology->addMoon(tptr, moonWorldId, Address(moonSeed)); return ZT_RESULT_OK; } -ZT_ResultCode Node::deorbit(void *tptr,uint64_t moonWorldId) +ZT_ResultCode Node::deorbit(void* tptr, uint64_t moonWorldId) { - RR->topology->removeMoon(tptr,moonWorldId); + RR->topology->removeMoon(tptr, moonWorldId); return ZT_RESULT_OK; } @@ -546,7 +548,7 @@ uint64_t Node::address() const return RR->identity.address().toInt(); } -void Node::status(ZT_NodeStatus *status) const +void Node::status(ZT_NodeStatus* status) const { status->address = RR->identity.address().toInt(); status->publicIdentity = RR->publicIdentityStr; @@ -554,28 +556,29 @@ void Node::status(ZT_NodeStatus *status) const status->online = _online ? 1 : 0; } -ZT_PeerList *Node::peers() const +ZT_PeerList* Node::peers() const { - std::vector< std::pair< Address,SharedPtr > > peers(RR->topology->allPeers()); - std::sort(peers.begin(),peers.end()); + std::vector > > peers(RR->topology->allPeers()); + std::sort(peers.begin(), peers.end()); - char *buf = (char *)::malloc(sizeof(ZT_PeerList) + (sizeof(ZT_Peer) * peers.size())); - if (!buf) { - return (ZT_PeerList *)0; + char* buf = (char*)::malloc(sizeof(ZT_PeerList) + (sizeof(ZT_Peer) * peers.size())); + if (! buf) { + return (ZT_PeerList*)0; } - ZT_PeerList *pl = (ZT_PeerList *)buf; - pl->peers = (ZT_Peer *)(buf + sizeof(ZT_PeerList)); + ZT_PeerList* pl = (ZT_PeerList*)buf; + pl->peers = (ZT_Peer*)(buf + sizeof(ZT_PeerList)); pl->peerCount = 0; - for(std::vector< std::pair< Address,SharedPtr > >::iterator pi(peers.begin());pi!=peers.end();++pi) { - ZT_Peer *p = &(pl->peers[pl->peerCount++]); + for (std::vector > >::iterator pi(peers.begin()); pi != peers.end(); ++pi) { + ZT_Peer* p = &(pl->peers[pl->peerCount++]); p->address = pi->second->address().toInt(); p->isBonded = 0; if (pi->second->remoteVersionKnown()) { p->versionMajor = pi->second->remoteVersionMajor(); p->versionMinor = pi->second->remoteVersionMinor(); p->versionRev = pi->second->remoteVersionRevision(); - } else { + } + else { p->versionMajor = -1; p->versionMinor = -1; p->versionRev = -1; @@ -586,12 +589,12 @@ ZT_PeerList *Node::peers() const } p->role = RR->topology->role(pi->second->identity().address()); - std::vector< SharedPtr > paths(pi->second->paths(_now)); - SharedPtr bestp(pi->second->getAppropriatePath(_now,false)); + std::vector > paths(pi->second->paths(_now)); + SharedPtr bestp(pi->second->getAppropriatePath(_now, false)); p->pathCount = 0; - for(std::vector< SharedPtr >::iterator path(paths.begin());path!=paths.end();++path) { - if((*path)->valid()) { - memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage)); + for (std::vector >::iterator path(paths.begin()); path != paths.end(); ++path) { + if ((*path)->valid()) { + memcpy(&(p->paths[p->pathCount].address), &((*path)->address()), sizeof(struct sockaddr_storage)); p->paths[p->pathCount].localSocket = (*path)->localSocket(); p->paths[p->pathCount].localPort = (*path)->localPort(); p->paths[p->pathCount].lastSend = (*path)->lastOut(); @@ -628,53 +631,53 @@ ZT_PeerList *Node::peers() const return pl; } -ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const +ZT_VirtualNetworkConfig* Node::networkConfig(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - const SharedPtr *nw = _networks.get(nwid); + const SharedPtr* nw = _networks.get(nwid); if (nw) { - ZT_VirtualNetworkConfig *nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig)); + ZT_VirtualNetworkConfig* nc = (ZT_VirtualNetworkConfig*)::malloc(sizeof(ZT_VirtualNetworkConfig)); (*nw)->externalConfig(nc); return nc; } - return (ZT_VirtualNetworkConfig *)0; + return (ZT_VirtualNetworkConfig*)0; } -ZT_VirtualNetworkList *Node::networks() const +ZT_VirtualNetworkList* Node::networks() const { Mutex::Lock _l(_networks_m); - char *buf = (char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * _networks.size())); - if (!buf) { - return (ZT_VirtualNetworkList *)0; + char* buf = (char*)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * _networks.size())); + if (! buf) { + return (ZT_VirtualNetworkList*)0; } - ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf; - nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList)); + ZT_VirtualNetworkList* nl = (ZT_VirtualNetworkList*)buf; + nl->networks = (ZT_VirtualNetworkConfig*)(buf + sizeof(ZT_VirtualNetworkList)); nl->networkCount = 0; - Hashtable< uint64_t,SharedPtr >::Iterator i(*const_cast< Hashtable< uint64_t,SharedPtr > *>(&_networks)); - uint64_t *k = (uint64_t *)0; - SharedPtr *v = (SharedPtr *)0; - while (i.next(k,v)) { + Hashtable >::Iterator i(*const_cast >*>(&_networks)); + uint64_t* k = (uint64_t*)0; + SharedPtr* v = (SharedPtr*)0; + while (i.next(k, v)) { (*v)->externalConfig(&(nl->networks[nl->networkCount++])); } return nl; } -void Node::freeQueryResult(void *qr) +void Node::freeQueryResult(void* qr) { if (qr) { ::free(qr); } } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage* addr) { - if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { + if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); - if (std::find(_directPaths.begin(),_directPaths.end(),*(reinterpret_cast(addr))) == _directPaths.end()) { - _directPaths.push_back(*(reinterpret_cast(addr))); + if (std::find(_directPaths.begin(), _directPaths.end(), *(reinterpret_cast(addr))) == _directPaths.end()) { + _directPaths.push_back(*(reinterpret_cast(addr))); return 1; } } @@ -687,24 +690,26 @@ void Node::clearLocalInterfaceAddresses() _directPaths.clear(); } -int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len) +int Node::sendUserMessage(void* tptr, uint64_t dest, uint64_t typeId, const void* data, unsigned int len) { try { if (RR->identity.address().toInt() != dest) { - Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE); + Packet outp(Address(dest), RR->identity.address(), Packet::VERB_USER_MESSAGE); outp.append(typeId); - outp.append(data,len); + outp.append(data, len); outp.compress(); - RR->sw->send(tptr,outp,true); + RR->sw->send(tptr, outp, true); return 1; } - } catch ( ... ) {} + } + catch (...) { + } return 0; } -void Node::setNetconfMaster(void *networkControllerInstance) +void Node::setNetconfMaster(void* networkControllerInstance) { - RR->localNetworkController = reinterpret_cast(networkControllerInstance); + RR->localNetworkController = reinterpret_cast(networkControllerInstance); if (networkControllerInstance) { RR->localNetworkController->init(RR->identity, this); } @@ -714,24 +719,24 @@ void Node::setNetconfMaster(void *networkControllerInstance) /* Node methods used only within node/ */ /****************************************************************************/ -bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress) +bool Node::shouldUsePathForZeroTierTraffic(void* tPtr, const Address& ztaddr, const int64_t localSocket, const InetAddress& remoteAddress) { - if (!Path::isAddressValidForPath(remoteAddress)) { + if (! Path::isAddressValidForPath(remoteAddress)) { return false; } - if (RR->topology->isProhibitedEndpoint(ztaddr,remoteAddress)) { + if (RR->topology->isProhibitedEndpoint(ztaddr, remoteAddress)) { return false; } { Mutex::Lock _l(_networks_m); - Hashtable< uint64_t,SharedPtr >::Iterator i(_networks); - uint64_t *k = (uint64_t *)0; - SharedPtr *v = (SharedPtr *)0; - while (i.next(k,v)) { + Hashtable >::Iterator i(_networks); + uint64_t* k = (uint64_t*)0; + SharedPtr* v = (SharedPtr*)0; + while (i.next(k, v)) { if ((*v)->hasConfig()) { - for(unsigned int k=0;k<(*v)->config().staticIpCount;++k) { + for (unsigned int k = 0; k < (*v)->config().staticIpCount; ++k) { if ((*v)->config().staticIps[k].containsAddress(remoteAddress)) { return false; } @@ -740,7 +745,7 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons } } - return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast(&remoteAddress)) != 0) : true); + return ((_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast(this), _uPtr, tPtr, ztaddr.toInt(), localSocket, reinterpret_cast(&remoteAddress)) != 0) : true); } uint64_t Node::prng() @@ -755,9 +760,9 @@ uint64_t Node::prng() return z + y; } -ZT_ResultCode Node::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork, const ZT_PhysicalPathConfiguration *pathConfig) +ZT_ResultCode Node::setPhysicalPathConfiguration(const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig) { - RR->topology->setPhysicalPathConfiguration(pathNetwork,pathConfig); + RR->topology->setPhysicalPathConfiguration(pathNetwork, pathConfig); return ZT_RESULT_OK; } @@ -771,32 +776,33 @@ std::vector Node::moons() const return RR->topology->moons(); } -void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig) +void Node::ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig) { _localControllerAuthorizations_m.lock(); - _localControllerAuthorizations[_LocalControllerAuth(nwid,destination)] = now(); + _localControllerAuthorizations[_LocalControllerAuth(nwid, destination)] = now(); _localControllerAuthorizations_m.unlock(); if (destination == RR->identity.address()) { SharedPtr n(network(nwid)); - if (!n) { + if (! n) { return; } - n->setConfiguration((void *)0,nc,true); - } else { - Dictionary *dconf = new Dictionary(); + n->setConfiguration((void*)0, nc, true); + } + else { + Dictionary* dconf = new Dictionary(); try { - if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) { + if (nc.toDictionary(*dconf, sendLegacyFormatConfig)) { uint64_t configUpdateId = prng(); - if (!configUpdateId) { + if (! configUpdateId) { ++configUpdateId; } const unsigned int totalSize = dconf->sizeBytes(); unsigned int chunkIndex = 0; while (chunkIndex < totalSize) { - const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256))); - Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG); + const unsigned int chunkLen = std::min(totalSize - chunkIndex, (unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256))); + Packet outp(destination, RR->identity.address(), (requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG); if (requestPacketId) { outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append(requestPacketId); @@ -805,59 +811,61 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de const unsigned int sigStart = outp.size(); outp.append(nwid); outp.append((uint16_t)chunkLen); - outp.append((const void *)(dconf->data() + chunkIndex),chunkLen); + outp.append((const void*)(dconf->data() + chunkIndex), chunkLen); - outp.append((uint8_t)0); // no flags + outp.append((uint8_t)0); // no flags outp.append((uint64_t)configUpdateId); outp.append((uint32_t)totalSize); outp.append((uint32_t)chunkIndex); - C25519::Signature sig(RR->identity.sign(reinterpret_cast(outp.data()) + sigStart,outp.size() - sigStart)); + C25519::Signature sig(RR->identity.sign(reinterpret_cast(outp.data()) + sigStart, outp.size() - sigStart)); outp.append((uint8_t)1); outp.append((uint16_t)ZT_C25519_SIGNATURE_LEN); - outp.append(sig.data,ZT_C25519_SIGNATURE_LEN); + outp.append(sig.data, ZT_C25519_SIGNATURE_LEN); outp.compress(); - RR->sw->send((void *)0,outp,true); + RR->sw->send((void*)0, outp, true); chunkIndex += chunkLen; } } delete dconf; - } catch ( ... ) { + } + catch (...) { delete dconf; throw; } } } -void Node::ncSendRevocation(const Address &destination,const Revocation &rev) +void Node::ncSendRevocation(const Address& destination, const Revocation& rev) { if (destination == RR->identity.address()) { SharedPtr n(network(rev.networkId())); - if (!n) { + if (! n) { return; } - n->addCredential((void *)0,RR->identity.address(),rev); - } else { - Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); + n->addCredential((void*)0, RR->identity.address(), rev); + } + else { + Packet outp(destination, RR->identity.address(), Packet::VERB_NETWORK_CREDENTIALS); outp.append((uint8_t)0x00); outp.append((uint16_t)0); outp.append((uint16_t)0); outp.append((uint16_t)1); rev.serialize(outp); outp.append((uint16_t)0); - RR->sw->send((void *)0,outp,true); + RR->sw->send((void*)0, outp, true); } } -void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode, const void *errorData, unsigned int errorDataSize) +void Node::ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode, const void* errorData, unsigned int errorDataSize) { if (destination == RR->identity.address()) { SharedPtr n(network(nwid)); - if (!n) { + if (! n) { return; } - switch(errorCode) { + switch (errorCode) { case NetworkController::NC_ERROR_OBJECT_NOT_FOUND: case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR: n->setNotFound(nullptr); @@ -866,20 +874,21 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des n->setAccessDenied(nullptr); break; case NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED: { - //fprintf(stderr, "\n\nGot auth required\n\n"); + // fprintf(stderr, "\n\nGot auth required\n\n"); break; } default: break; } - } else if (requestPacketId) { - Packet outp(destination,RR->identity.address(),Packet::VERB_ERROR); + } + else if (requestPacketId) { + Packet outp(destination, RR->identity.address(), Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append(requestPacketId); - switch(errorCode) { - //case NetworkController::NC_ERROR_OBJECT_NOT_FOUND: - //case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR: + switch (errorCode) { + // case NetworkController::NC_ERROR_OBJECT_NOT_FOUND: + // case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR: default: outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); Metrics::pkt_error_obj_not_found_out++; @@ -896,16 +905,16 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des outp.append(nwid); - if ((errorData)&&(errorDataSize > 0)&&(errorDataSize <= 0xffff)) { + if ((errorData) && (errorDataSize > 0) && (errorDataSize <= 0xffff)) { outp.append((uint16_t)errorDataSize); outp.append(errorData, errorDataSize); } - RR->sw->send((void *)0,outp,true); - } // else we can't send an ERROR() in response to nothing, so discard + RR->sw->send((void*)0, outp, true); + } // else we can't send an ERROR() in response to nothing, so discard } -} // namespace ZeroTier +} // namespace ZeroTier /****************************************************************************/ /* CAPI bindings */ @@ -913,230 +922,258 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des extern "C" { -enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now) +enum ZT_ResultCode ZT_Node_new(ZT_Node** node, void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now) { - *node = (ZT_Node *)0; + *node = (ZT_Node*)0; try { - *node = reinterpret_cast(new ZeroTier::Node(uptr,tptr,callbacks,now)); + *node = reinterpret_cast(new ZeroTier::Node(uptr, tptr, callbacks, now)); return ZT_RESULT_OK; - } catch (std::bad_alloc &exc) { + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch (std::runtime_error &exc) { + } + catch (std::runtime_error& exc) { return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -void ZT_Node_delete(ZT_Node *node) +void ZT_Node_delete(ZT_Node* node) { try { - delete (reinterpret_cast(node)); - } catch ( ... ) {} + delete (reinterpret_cast(node)); + } + catch (...) { + } } -enum ZT_ResultCode ZT_Node_processWirePacket( - ZT_Node *node, - void *tptr, - int64_t now, - int64_t localSocket, - const struct sockaddr_storage *remoteAddress, - const void *packetData, - unsigned int packetLength, - volatile int64_t *nextBackgroundTaskDeadline) +enum ZT_ResultCode +ZT_Node_processWirePacket(ZT_Node* node, void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processWirePacket(tptr,now,localSocket,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->processWirePacket(tptr, now, localSocket, remoteAddress, packetData, packetLength, nextBackgroundTaskDeadline); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { - return ZT_RESULT_OK; // "OK" since invalid packets are simply dropped, but the system is still up + } + catch (...) { + return ZT_RESULT_OK; // "OK" since invalid packets are simply dropped, but the system is still up } } enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( - ZT_Node *node, - void *tptr, + ZT_Node* node, + void* tptr, int64_t now, uint64_t nwid, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, - const void *frameData, + const void* frameData, unsigned int frameLength, - volatile int64_t *nextBackgroundTaskDeadline) + volatile int64_t* nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processVirtualNetworkFrame(tptr,now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->processVirtualNetworkFrame(tptr, now, nwid, sourceMac, destMac, etherType, vlanId, frameData, frameLength, nextBackgroundTaskDeadline); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline) +enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node* node, void* tptr, int64_t now, volatile int64_t* nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processBackgroundTasks(tptr,now,nextBackgroundTaskDeadline); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr) +enum ZT_ResultCode ZT_Node_join(ZT_Node* node, uint64_t nwid, void* uptr, void* tptr) { try { - return reinterpret_cast(node)->join(nwid,uptr,tptr); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->join(nwid, uptr, tptr); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr) +enum ZT_ResultCode ZT_Node_leave(ZT_Node* node, uint64_t nwid, void** uptr, void* tptr) { try { - return reinterpret_cast(node)->leave(nwid,uptr,tptr); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->leave(nwid, uptr, tptr); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node* node, void* tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi) { try { - return reinterpret_cast(node)->multicastSubscribe(tptr,nwid,multicastGroup,multicastAdi); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node* node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi) { try { - return reinterpret_cast(node)->multicastUnsubscribe(nwid,multicastGroup,multicastAdi); - } catch (std::bad_alloc &exc) { + return reinterpret_cast(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi); + } + catch (std::bad_alloc& exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; - } catch ( ... ) { + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,uint64_t moonSeed) +enum ZT_ResultCode ZT_Node_orbit(ZT_Node* node, void* tptr, uint64_t moonWorldId, uint64_t moonSeed) { try { - return reinterpret_cast(node)->orbit(tptr,moonWorldId,moonSeed); - } catch ( ... ) { + return reinterpret_cast(node)->orbit(tptr, moonWorldId, moonSeed); + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId) +enum ZT_ResultCode ZT_Node_deorbit(ZT_Node* node, void* tptr, uint64_t moonWorldId) { try { - return reinterpret_cast(node)->deorbit(tptr,moonWorldId); - } catch ( ... ) { + return reinterpret_cast(node)->deorbit(tptr, moonWorldId); + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -uint64_t ZT_Node_address(ZT_Node *node) +uint64_t ZT_Node_address(ZT_Node* node) { - return reinterpret_cast(node)->address(); + return reinterpret_cast(node)->address(); } -void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status) +void ZT_Node_status(ZT_Node* node, ZT_NodeStatus* status) { try { - reinterpret_cast(node)->status(status); - } catch ( ... ) {} -} - -ZT_PeerList *ZT_Node_peers(ZT_Node *node) -{ - try { - return reinterpret_cast(node)->peers(); - } catch ( ... ) { - return (ZT_PeerList *)0; + reinterpret_cast(node)->status(status); + } + catch (...) { } } -ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid) +ZT_PeerList* ZT_Node_peers(ZT_Node* node) { try { - return reinterpret_cast(node)->networkConfig(nwid); - } catch ( ... ) { - return (ZT_VirtualNetworkConfig *)0; + return reinterpret_cast(node)->peers(); + } + catch (...) { + return (ZT_PeerList*)0; } } -ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node) +ZT_VirtualNetworkConfig* ZT_Node_networkConfig(ZT_Node* node, uint64_t nwid) { try { - return reinterpret_cast(node)->networks(); - } catch ( ... ) { - return (ZT_VirtualNetworkList *)0; + return reinterpret_cast(node)->networkConfig(nwid); + } + catch (...) { + return (ZT_VirtualNetworkConfig*)0; } } -void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) +ZT_VirtualNetworkList* ZT_Node_networks(ZT_Node* node) { try { - reinterpret_cast(node)->freeQueryResult(qr); - } catch ( ... ) {} + return reinterpret_cast(node)->networks(); + } + catch (...) { + return (ZT_VirtualNetworkList*)0; + } } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr) +void ZT_Node_freeQueryResult(ZT_Node* node, void* qr) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr); - } catch ( ... ) { + reinterpret_cast(node)->freeQueryResult(qr); + } + catch (...) { + } +} + +int ZT_Node_addLocalInterfaceAddress(ZT_Node* node, const struct sockaddr_storage* addr) +{ + try { + return reinterpret_cast(node)->addLocalInterfaceAddress(addr); + } + catch (...) { return 0; } } -void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node) +void ZT_Node_clearLocalInterfaceAddresses(ZT_Node* node) { try { - reinterpret_cast(node)->clearLocalInterfaceAddresses(); - } catch ( ... ) {} + reinterpret_cast(node)->clearLocalInterfaceAddresses(); + } + catch (...) { + } } -int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len) +int ZT_Node_sendUserMessage(ZT_Node* node, void* tptr, uint64_t dest, uint64_t typeId, const void* data, unsigned int len) { try { - return reinterpret_cast(node)->sendUserMessage(tptr,dest,typeId,data,len); - } catch ( ... ) { + return reinterpret_cast(node)->sendUserMessage(tptr, dest, typeId, data, len); + } + catch (...) { return 0; } } -void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance) +void ZT_Node_setNetconfMaster(ZT_Node* node, void* networkControllerInstance) { try { - reinterpret_cast(node)->setNetconfMaster(networkControllerInstance); - } catch ( ... ) {} + reinterpret_cast(node)->setNetconfMaster(networkControllerInstance); + } + catch (...) { + } } -enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node,const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig) +enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node* node, const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig) { try { - return reinterpret_cast(node)->setPhysicalPathConfiguration(pathNetwork,pathConfig); - } catch ( ... ) { + return reinterpret_cast(node)->setPhysicalPathConfiguration(pathNetwork, pathConfig); + } + catch (...) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -void ZT_version(int *major,int *minor,int *revision) +void ZT_version(int* major, int* minor, int* revision) { if (major) { *major = ZEROTIER_ONE_VERSION_MAJOR; @@ -1149,4 +1186,4 @@ void ZT_version(int *major,int *minor,int *revision) } } -} // extern "C" +} // extern "C" diff --git a/node/Node.hpp b/node/Node.hpp index f9d05483a..2f1075337 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -14,29 +14,26 @@ #ifndef ZT_NODE_HPP #define ZT_NODE_HPP +#include "../include/ZeroTierOne.h" +#include "Bond.hpp" +#include "Constants.hpp" +#include "Hashtable.hpp" +#include "InetAddress.hpp" +#include "MAC.hpp" +#include "Mutex.hpp" +#include "Network.hpp" +#include "NetworkController.hpp" +#include "Path.hpp" +#include "RuntimeEnvironment.hpp" +#include "Salsa20.hpp" +#include "SelfAwareness.hpp" + +#include #include #include #include - -#include #include -#include "Constants.hpp" - -#include "../include/ZeroTierOne.h" - -#include "RuntimeEnvironment.hpp" -#include "InetAddress.hpp" -#include "Mutex.hpp" -#include "MAC.hpp" -#include "Network.hpp" -#include "Path.hpp" -#include "Salsa20.hpp" -#include "NetworkController.hpp" -#include "Hashtable.hpp" -#include "Bond.hpp" -#include "SelfAwareness.hpp" - // Bit mask for "expecting reply" hash #define ZT_EXPECTING_REPLIES_BUCKET_MASK1 255 #define ZT_EXPECTING_REPLIES_BUCKET_MASK2 31 @@ -50,94 +47,76 @@ class World; * * The pointer returned by ZT_Node_new() is an instance of this class. */ -class Node : public NetworkController::Sender -{ -public: - Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now); +class Node : public NetworkController::Sender { + public: + Node(void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now); virtual ~Node(); // Get rid of alignment warnings on 32-bit Windows and possibly improve performance #ifdef __WINDOWS__ - void * operator new(size_t i) { return _mm_malloc(i,16); } - void operator delete(void* p) { _mm_free(p); } + void* operator new(size_t i) + { + return _mm_malloc(i, 16); + } + void operator delete(void* p) + { + _mm_free(p); + } #endif // Public API Functions ---------------------------------------------------- - ZT_ResultCode processWirePacket( - void *tptr, - int64_t now, - int64_t localSocket, - const struct sockaddr_storage *remoteAddress, - const void *packetData, - unsigned int packetLength, - volatile int64_t *nextBackgroundTaskDeadline); + ZT_ResultCode processWirePacket(void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline); ZT_ResultCode processVirtualNetworkFrame( - void *tptr, + void* tptr, int64_t now, uint64_t nwid, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, - const void *frameData, + const void* frameData, unsigned int frameLength, - volatile int64_t *nextBackgroundTaskDeadline); - ZT_ResultCode processBackgroundTasks(void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline); - ZT_ResultCode join(uint64_t nwid,void *uptr,void *tptr); - ZT_ResultCode leave(uint64_t nwid,void **uptr,void *tptr); - ZT_ResultCode multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); - ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); - ZT_ResultCode orbit(void *tptr,uint64_t moonWorldId,uint64_t moonSeed); - ZT_ResultCode deorbit(void *tptr,uint64_t moonWorldId); + volatile int64_t* nextBackgroundTaskDeadline); + ZT_ResultCode processBackgroundTasks(void* tptr, int64_t now, volatile int64_t* nextBackgroundTaskDeadline); + ZT_ResultCode join(uint64_t nwid, void* uptr, void* tptr); + ZT_ResultCode leave(uint64_t nwid, void** uptr, void* tptr); + ZT_ResultCode multicastSubscribe(void* tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi); + ZT_ResultCode multicastUnsubscribe(uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi); + ZT_ResultCode orbit(void* tptr, uint64_t moonWorldId, uint64_t moonSeed); + ZT_ResultCode deorbit(void* tptr, uint64_t moonWorldId); uint64_t address() const; - void status(ZT_NodeStatus *status) const; - ZT_PeerList *peers() const; - ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; - ZT_VirtualNetworkList *networks() const; - void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr); + void status(ZT_NodeStatus* status) const; + ZT_PeerList* peers() const; + ZT_VirtualNetworkConfig* networkConfig(uint64_t nwid) const; + ZT_VirtualNetworkList* networks() const; + void freeQueryResult(void* qr); + int addLocalInterfaceAddress(const struct sockaddr_storage* addr); void clearLocalInterfaceAddresses(); - int sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len); - void setNetconfMaster(void *networkControllerInstance); + int sendUserMessage(void* tptr, uint64_t dest, uint64_t typeId, const void* data, unsigned int len); + void setNetconfMaster(void* networkControllerInstance); // Internal functions ------------------------------------------------------ - inline int64_t now() const { return _now; } - - inline bool putPacket(void *tPtr,const int64_t localSocket,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0) + inline int64_t now() const { - return (_cb.wirePacketSendFunction( - reinterpret_cast(this), - _uPtr, - tPtr, - localSocket, - reinterpret_cast(&addr), - data, - len, - ttl) == 0); + return _now; } - inline void putFrame(void *tPtr,uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + inline bool putPacket(void* tPtr, const int64_t localSocket, const InetAddress& addr, const void* data, unsigned int len, unsigned int ttl = 0) { - _cb.virtualNetworkFrameFunction( - reinterpret_cast(this), - _uPtr, - tPtr, - nwid, - nuptr, - source.toInt(), - dest.toInt(), - etherType, - vlanId, - data, - len); + return (_cb.wirePacketSendFunction(reinterpret_cast(this), _uPtr, tPtr, localSocket, reinterpret_cast(&addr), data, len, ttl) == 0); + } + + inline void putFrame(void* tPtr, uint64_t nwid, void** nuptr, const MAC& source, const MAC& dest, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) + { + _cb.virtualNetworkFrameFunction(reinterpret_cast(this), _uPtr, tPtr, nwid, nuptr, source.toInt(), dest.toInt(), etherType, vlanId, data, len); } inline SharedPtr network(uint64_t nwid) const { Mutex::Lock _l(_networks_m); - const SharedPtr *n = _networks.get(nwid); + const SharedPtr* n = _networks.get(nwid); if (n) { return *n; } @@ -150,14 +129,14 @@ public: return _networks.contains(nwid); } - inline std::vector< SharedPtr > allNetworks() const + inline std::vector > allNetworks() const { - std::vector< SharedPtr > nw; + std::vector > nw; Mutex::Lock _l(_networks_m); - Hashtable< uint64_t,SharedPtr >::Iterator i(*const_cast< Hashtable< uint64_t,SharedPtr > * >(&_networks)); - uint64_t *k = (uint64_t *)0; - SharedPtr *v = (SharedPtr *)0; - while (i.next(k,v)) { + Hashtable >::Iterator i(*const_cast >*>(&_networks)); + uint64_t* k = (uint64_t*)0; + SharedPtr* v = (SharedPtr*)0; + while (i.next(k, v)) { nw.push_back(*v); } return nw; @@ -169,30 +148,60 @@ public: return _directPaths; } - inline void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast(this),_uPtr,tPtr,ev,md); } + inline void postEvent(void* tPtr, ZT_Event ev, const void* md = (const void*)0) + { + _cb.eventCallback(reinterpret_cast(this), _uPtr, tPtr, ev, md); + } - inline int configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,tPtr,nwid,nuptr,op,nc); } + inline int configureVirtualNetworkPort(void* tPtr, uint64_t nwid, void** nuptr, ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig* nc) + { + return _cb.virtualNetworkConfigFunction(reinterpret_cast(this), _uPtr, tPtr, nwid, nuptr, op, nc); + } - inline bool online() const { return _online; } + inline bool online() const + { + return _online; + } - inline int stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],void *const data,const unsigned int maxlen) { return _cb.stateGetFunction(reinterpret_cast(this),_uPtr,tPtr,type,id,data,maxlen); } - inline void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast(this),_uPtr,tPtr,type,id,data,(int)len); } - inline void stateObjectDelete(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2]) { _cb.statePutFunction(reinterpret_cast(this),_uPtr,tPtr,type,id,(const void *)0,-1); } + inline int stateObjectGet(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2], void* const data, const unsigned int maxlen) + { + return _cb.stateGetFunction(reinterpret_cast(this), _uPtr, tPtr, type, id, data, maxlen); + } + inline void stateObjectPut(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2], const void* const data, const unsigned int len) + { + _cb.statePutFunction(reinterpret_cast(this), _uPtr, tPtr, type, id, data, (int)len); + } + inline void stateObjectDelete(void* const tPtr, ZT_StateObjectType type, const uint64_t id[2]) + { + _cb.statePutFunction(reinterpret_cast(this), _uPtr, tPtr, type, id, (const void*)0, -1); + } - bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress); - inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast(&addr)) != 0) : false ); } + bool shouldUsePathForZeroTierTraffic(void* tPtr, const Address& ztaddr, const int64_t localSocket, const InetAddress& remoteAddress); + inline bool externalPathLookup(void* tPtr, const Address& ztaddr, int family, InetAddress& addr) + { + return ((_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast(this), _uPtr, tPtr, ztaddr.toInt(), family, reinterpret_cast(&addr)) != 0) : false); + } uint64_t prng(); - ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig); + ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig); World planet() const; std::vector moons() const; - inline const Identity &identity() const { return _RR.identity; } + inline const Identity& identity() const + { + return _RR.identity; + } - inline const std::vector SurfaceAddresses() const { return _RR.sa->whoami(); } + inline const std::vector SurfaceAddresses() const + { + return _RR.sa->whoami(); + } - inline Bond *bondController() const { return _RR.bc; } + inline Bond* bondController() const + { + return _RR.bc; + } /** * Register that we are expecting a reply to a packet ID @@ -224,7 +233,7 @@ public: { const uint32_t pid2 = (uint32_t)(packetId >> 32); const unsigned long bucket = (unsigned long)(pid2 & ZT_EXPECTING_REPLIES_BUCKET_MASK1); - for(unsigned long i=0;i<=ZT_EXPECTING_REPLIES_BUCKET_MASK2;++i) { + for (unsigned long i = 0; i <= ZT_EXPECTING_REPLIES_BUCKET_MASK2; ++i) { if (_expectingRepliesTo[bucket][i] == pid2) { return true; } @@ -239,7 +248,7 @@ public: * @param from Source address of packet * @return True if within rate limits */ - inline bool rateGateIdentityVerification(const int64_t now,const InetAddress &from) + inline bool rateGateIdentityVerification(const int64_t now, const InetAddress& from) { unsigned long iph = from.rateGateHash(); if ((now - _lastIdentityVerification[iph]) >= ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT) { @@ -249,17 +258,23 @@ public: return false; } - virtual void ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig); - virtual void ncSendRevocation(const Address &destination,const Revocation &rev); - virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode, const void *errorData, unsigned int errorDataSize); + virtual void ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig); + virtual void ncSendRevocation(const Address& destination, const Revocation& rev); + virtual void ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode, const void* errorData, unsigned int errorDataSize); - inline const Address &remoteTraceTarget() const { return _remoteTraceTarget; } - inline Trace::Level remoteTraceLevel() const { return _remoteTraceLevel; } + inline const Address& remoteTraceTarget() const + { + return _remoteTraceTarget; + } + inline Trace::Level remoteTraceLevel() const + { + return _remoteTraceLevel; + } - inline bool localControllerHasAuthorized(const int64_t now,const uint64_t nwid,const Address &addr) const + inline bool localControllerHasAuthorized(const int64_t now, const uint64_t nwid, const Address& addr) const { _localControllerAuthorizations_m.lock(); - const int64_t *const at = _localControllerAuthorizations.get(_LocalControllerAuth(nwid,addr)); + const int64_t* const at = _localControllerAuthorizations.get(_LocalControllerAuth(nwid, addr)); _localControllerAuthorizations_m.unlock(); if (at) { return ((now - *at) < (ZT_NETWORK_AUTOCONF_DELAY * 3)); @@ -267,7 +282,7 @@ public: return false; } - inline void statsLogVerb(const unsigned int v,const unsigned int bytes) + inline void statsLogVerb(const unsigned int v, const unsigned int bytes) { ++_stats.inVerbCounts[v]; _stats.inVerbBytes[v] += (uint64_t)bytes; @@ -285,11 +300,10 @@ public: void initMultithreading(unsigned int concurrency, bool cpuPinningEnabled); - -public: + public: RuntimeEnvironment _RR; - RuntimeEnvironment *RR; - void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P + RuntimeEnvironment* RR; + void* _uPtr; // _uptr (lower case) is reserved in Visual Studio :P ZT_Node_Callbacks _cb; // For tracking packet IDs to filter out OK/ERROR replies to packets we did not send @@ -304,18 +318,28 @@ public: // Map that remembers if we have recently sent a network config to someone // querying us as a controller. - struct _LocalControllerAuth - { - uint64_t nwid,address; - _LocalControllerAuth(const uint64_t nwid_,const Address &address_) : nwid(nwid_),address(address_.toInt()) {} - inline unsigned long hashCode() const { return (unsigned long)(nwid ^ address); } - inline bool operator==(const _LocalControllerAuth &a) const { return ((a.nwid == nwid)&&(a.address == address)); } - inline bool operator!=(const _LocalControllerAuth &a) const { return ((a.nwid != nwid)||(a.address != address)); } + struct _LocalControllerAuth { + uint64_t nwid, address; + _LocalControllerAuth(const uint64_t nwid_, const Address& address_) : nwid(nwid_), address(address_.toInt()) + { + } + inline unsigned long hashCode() const + { + return (unsigned long)(nwid ^ address); + } + inline bool operator==(const _LocalControllerAuth& a) const + { + return ((a.nwid == nwid) && (a.address == address)); + } + inline bool operator!=(const _LocalControllerAuth& a) const + { + return ((a.nwid != nwid) || (a.address != address)); + } }; - Hashtable< _LocalControllerAuth,int64_t > _localControllerAuthorizations; + Hashtable<_LocalControllerAuth, int64_t> _localControllerAuthorizations; Mutex _localControllerAuthorizations_m; - Hashtable< uint64_t,SharedPtr > _networks; + Hashtable > _networks; Mutex _networks_m; std::vector _directPaths; @@ -336,6 +360,6 @@ public: bool _lowBandwidthMode; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/OutboundMulticast.cpp b/node/OutboundMulticast.cpp index 754c48536..702a0333e 100644 --- a/node/OutboundMulticast.cpp +++ b/node/OutboundMulticast.cpp @@ -11,28 +11,29 @@ */ /****/ -#include "Constants.hpp" -#include "RuntimeEnvironment.hpp" #include "OutboundMulticast.hpp" -#include "Switch.hpp" + +#include "Constants.hpp" #include "Network.hpp" #include "Node.hpp" #include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" #include "Topology.hpp" namespace ZeroTier { void OutboundMulticast::init( - const RuntimeEnvironment *RR, + const RuntimeEnvironment* RR, uint64_t timestamp, uint64_t nwid, bool disableCompression, unsigned int limit, unsigned int gatherLimit, - const MAC &src, - const MulticastGroup &dest, + const MAC& src, + const MulticastGroup& dest, unsigned int etherType, - const void *payload, + const void* payload, unsigned int len) { uint8_t flags = 0; @@ -42,8 +43,9 @@ void OutboundMulticast::init( if (src) { _macSrc = src; flags |= 0x04; - } else { - _macSrc.fromAddress(RR->identity.address(),nwid); + } + else { + _macSrc.fromAddress(RR->identity.address(), nwid); } _macDest = dest.mac(); _limit = limit; @@ -67,26 +69,26 @@ void OutboundMulticast::init( dest.mac().appendTo(_packet); _packet.append((uint32_t)dest.adi()); _packet.append((uint16_t)etherType); - _packet.append(payload,_frameLen); - if (!disableCompression) { + _packet.append(payload, _frameLen); + if (! disableCompression) { _packet.compress(); } - memcpy(_frameData,payload,_frameLen); + memcpy(_frameData, payload, _frameLen); } -void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr) +void OutboundMulticast::sendOnly(const RuntimeEnvironment* RR, void* tPtr, const Address& toAddr) { const SharedPtr nw(RR->node->network(_nwid)); - uint8_t QoSBucket = 255; // Dummy value - if ((nw)&&(nw->filterOutgoingPacket(tPtr,true,RR->identity.address(),toAddr,_macSrc,_macDest,_frameData,_frameLen,_etherType,0,QoSBucket))) { - nw->pushCredentialsIfNeeded(tPtr,toAddr,RR->node->now()); + uint8_t QoSBucket = 255; // Dummy value + if ((nw) && (nw->filterOutgoingPacket(tPtr, true, RR->identity.address(), toAddr, _macSrc, _macDest, _frameData, _frameLen, _etherType, 0, QoSBucket))) { + nw->pushCredentialsIfNeeded(tPtr, toAddr, RR->node->now()); _packet.newInitializationVector(); _packet.setDestination(toAddr); RR->node->expectReplyTo(_packet.packetId()); _tmp = _packet; - RR->sw->send(tPtr,_tmp,true); + RR->sw->send(tPtr, _tmp, true); } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/OutboundMulticast.hpp b/node/OutboundMulticast.hpp index 38c8043ec..542151e2a 100644 --- a/node/OutboundMulticast.hpp +++ b/node/OutboundMulticast.hpp @@ -14,17 +14,16 @@ #ifndef ZT_OUTBOUNDMULTICAST_HPP #define ZT_OUTBOUNDMULTICAST_HPP -#include - -#include -#include - +#include "Address.hpp" #include "Constants.hpp" #include "MAC.hpp" #include "MulticastGroup.hpp" -#include "Address.hpp" #include "Packet.hpp" +#include +#include +#include + namespace ZeroTier { class CertificateOfMembership; @@ -35,15 +34,16 @@ class RuntimeEnvironment; * * This object isn't guarded by a mutex; caller must synchronize access. */ -class OutboundMulticast -{ -public: +class OutboundMulticast { + public: /** * Create an uninitialized outbound multicast * * It must be initialized with init(). */ - OutboundMulticast() {} + OutboundMulticast() + { + } /** * Initialize outbound multicast @@ -62,33 +62,42 @@ public: * @throws std::out_of_range Data too large to fit in a MULTICAST_FRAME */ void init( - const RuntimeEnvironment *RR, + const RuntimeEnvironment* RR, uint64_t timestamp, uint64_t nwid, bool disableCompression, unsigned int limit, unsigned int gatherLimit, - const MAC &src, - const MulticastGroup &dest, + const MAC& src, + const MulticastGroup& dest, unsigned int etherType, - const void *payload, + const void* payload, unsigned int len); /** * @return Multicast creation time */ - inline uint64_t timestamp() const { return _timestamp; } + inline uint64_t timestamp() const + { + return _timestamp; + } /** * @param now Current time * @return True if this multicast is expired (has exceeded transmit timeout) */ - inline bool expired(int64_t now) const { return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); } + inline bool expired(int64_t now) const + { + return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); + } /** * @return True if this outbound multicast has been sent to enough peers */ - inline bool atLimit() const { return (_alreadySentTo.size() >= _limit); } + inline bool atLimit() const + { + return (_alreadySentTo.size() >= _limit); + } /** * Just send without checking log @@ -97,7 +106,7 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param toAddr Destination address */ - void sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr); + void sendOnly(const RuntimeEnvironment* RR, void* tPtr, const Address& toAddr); /** * Just send and log but do not check sent log @@ -106,10 +115,10 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param toAddr Destination address */ - inline void sendAndLog(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr) + inline void sendAndLog(const RuntimeEnvironment* RR, void* tPtr, const Address& toAddr) { _alreadySentTo.push_back(toAddr); - sendOnly(RR,tPtr,toAddr); + sendOnly(RR, tPtr, toAddr); } /** @@ -117,7 +126,7 @@ public: * * @param toAddr Address to log as sent */ - inline void logAsSent(const Address &toAddr) + inline void logAsSent(const Address& toAddr) { _alreadySentTo.push_back(toAddr); } @@ -130,17 +139,18 @@ public: * @param toAddr Destination address * @return True if address is new and packet was sent to switch, false if duplicate */ - inline bool sendIfNew(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr) + inline bool sendIfNew(const RuntimeEnvironment* RR, void* tPtr, const Address& toAddr) { - if (std::find(_alreadySentTo.begin(),_alreadySentTo.end(),toAddr) == _alreadySentTo.end()) { - sendAndLog(RR,tPtr,toAddr); + if (std::find(_alreadySentTo.begin(), _alreadySentTo.end(), toAddr) == _alreadySentTo.end()) { + sendAndLog(RR, tPtr, toAddr); return true; - } else { + } + else { return false; } } -private: + private: uint64_t _timestamp; uint64_t _nwid; MAC _macSrc; @@ -148,11 +158,11 @@ private: unsigned int _limit; unsigned int _frameLen; unsigned int _etherType; - Packet _packet,_tmp; + Packet _packet, _tmp; std::vector
_alreadySentTo; uint8_t _frameData[ZT_MAX_MTU]; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Packet.cpp b/node/Packet.cpp index f0430c297..b0967af1d 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -11,14 +11,14 @@ */ /****/ -#include -#include -#include -#include -#include - #include "Packet.hpp" +#include +#include +#include +#include +#include + #if defined(ZT_USE_X64_ASM_SALSA2012) && defined(ZT_ARCH_X64) #include "../ext/x64-salsa2012-asm/salsa2012.h" #endif @@ -29,8 +29,8 @@ #ifdef _MSC_VER #define FORCE_INLINE static __forceinline #include -#pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -#pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ +#pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ #else #define FORCE_INLINE static inline #endif @@ -43,27 +43,30 @@ namespace ZeroTier { // x64 SSE crypto #if defined(ZT_USE_X64_ASM_SALSA2012) && defined(ZT_ARCH_X64) -#define ZT_HAS_FAST_CRYPTO() (true) -#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) zt_salsa2012_amd64_xmm6(reinterpret_cast(b),(l),reinterpret_cast(n),reinterpret_cast(k)) +#define ZT_HAS_FAST_CRYPTO() (true) +#define ZT_FAST_SINGLE_PASS_SALSA2012(b, l, n, k) zt_salsa2012_amd64_xmm6(reinterpret_cast(b), (l), reinterpret_cast(n), reinterpret_cast(k)) #endif // ARM (32-bit) NEON crypto (must be detected) #ifdef ZT_USE_ARM32_NEON_ASM_SALSA2012 -class _FastCryptoChecker -{ -public: - _FastCryptoChecker() : canHas(zt_arm_has_neon()) {} +class _FastCryptoChecker { + public: + _FastCryptoChecker() : canHas(zt_arm_has_neon()) + { + } bool canHas; }; static const _FastCryptoChecker _ZT_FAST_CRYPTO_CHECK; -#define ZT_HAS_FAST_CRYPTO() (_ZT_FAST_CRYPTO_CHECK.canHas) -#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) zt_salsa2012_armneon3_xor(reinterpret_cast(b),(const unsigned char *)0,(l),reinterpret_cast(n),reinterpret_cast(k)) +#define ZT_HAS_FAST_CRYPTO() (_ZT_FAST_CRYPTO_CHECK.canHas) +#define ZT_FAST_SINGLE_PASS_SALSA2012(b, l, n, k) zt_salsa2012_armneon3_xor(reinterpret_cast(b), (const unsigned char*)0, (l), reinterpret_cast(n), reinterpret_cast(k)) #endif // No fast crypto available #ifndef ZT_HAS_FAST_CRYPTO #define ZT_HAS_FAST_CRYPTO() (false) -#define ZT_FAST_SINGLE_PASS_SALSA2012(b,l,n,k) {} +#define ZT_FAST_SINGLE_PASS_SALSA2012(b, l, n, k) \ + { \ + } #endif /************************************************************************** */ @@ -142,32 +145,32 @@ namespace { A library is provided to take care of it, see lz4frame.h. */ -#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ -#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ -#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ -#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) -#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE -#define LZ4_QUOTE(str) #str +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR * 100 * 100 + LZ4_VERSION_MINOR * 100 + LZ4_VERSION_RELEASE) +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str #define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) -#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) -#define LZ4_MEMORY_USAGE 14 -#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ -#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) +#define LZ4_MEMORY_USAGE 14 +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize) / 255) + 16) -typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ -static inline void LZ4_resetStream (LZ4_stream_t* streamPtr); +static inline void LZ4_resetStream(LZ4_stream_t* streamPtr); -#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE - 2) #define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) -#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ typedef struct { uint32_t hashTable[LZ4_HASH_SIZE_U32]; uint32_t currentOffset; uint32_t initCheck; const uint8_t* dictionary; - uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */ + uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */ uint32_t dictSize; } LZ4_stream_t_internal; @@ -178,19 +181,19 @@ typedef struct { size_t prefixSize; } LZ4_streamDecode_t_internal; -#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) -#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE - 3)) + 4) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) union LZ4_stream_u { unsigned long long table[LZ4_STREAMSIZE_U64]; LZ4_stream_t_internal internal_donotuse; -} ; /* previously typedef'd to LZ4_stream_t */ +}; /* previously typedef'd to LZ4_stream_t */ -#define LZ4_STREAMDECODESIZE_U64 4 +#define LZ4_STREAMDECODESIZE_U64 4 #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) union LZ4_streamDecode_u { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; LZ4_streamDecode_t_internal internal_donotuse; -} ; /* previously typedef'd to LZ4_streamDecode_t */ +}; /* previously typedef'd to LZ4_streamDecode_t */ #ifndef HEAPMODE #define HEAPMODE 0 @@ -202,7 +205,7 @@ union LZ4_streamDecode_u { #define LZ4_FORCE_MEMORY_ACCESS 2 #endif -#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ +#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ #define LZ4_FORCE_SW_BITCOUNT #endif @@ -210,49 +213,92 @@ union LZ4_streamDecode_u { #define FORCE_INLINE static inline #endif -#define ALLOCATOR(n,s) calloc(n,s) -#define FREEMEM free -#define MEM_INIT memset +#define ALLOCATOR(n, s) calloc(n, s) +#define FREEMEM free +#define MEM_INIT memset -typedef uint8_t BYTE; +typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; -typedef int32_t S32; +typedef int32_t S32; typedef uint64_t U64; typedef uintptr_t uptrval; typedef uintptr_t reg_t; static inline unsigned LZ4_isLittleEndian(void) { - const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + const union { + U32 u; + BYTE c[4]; + } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } -#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) -static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } -static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } -static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } -static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } -static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } -#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) -typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign; -static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } -static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } -static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; } -static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } -static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } +#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 2) +static U16 LZ4_read16(const void* memPtr) +{ + return *(const U16*)memPtr; +} +static U32 LZ4_read32(const void* memPtr) +{ + return *(const U32*)memPtr; +} +static reg_t LZ4_read_ARCH(const void* memPtr) +{ + return *(const reg_t*)memPtr; +} +static void LZ4_write16(void* memPtr, U16 value) +{ + *(U16*)memPtr = value; +} +static void LZ4_write32(void* memPtr, U32 value) +{ + *(U32*)memPtr = value; +} +#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 1) +typedef union { + U16 u16; + U32 u32; + reg_t uArch; +} __attribute__((packed)) unalign; +static U16 LZ4_read16(const void* ptr) +{ + return ((const unalign*)ptr)->u16; +} +static U32 LZ4_read32(const void* ptr) +{ + return ((const unalign*)ptr)->u32; +} +static reg_t LZ4_read_ARCH(const void* ptr) +{ + return ((const unalign*)ptr)->uArch; +} +static void LZ4_write16(void* memPtr, U16 value) +{ + ((unalign*)memPtr)->u16 = value; +} +static void LZ4_write32(void* memPtr, U32 value) +{ + ((unalign*)memPtr)->u32 = value; +} #else /* safe and portable access through memcpy() */ static inline U16 LZ4_read16(const void* memPtr) { - U16 val; memcpy(&val, memPtr, sizeof(val)); return val; + U16 val; + memcpy(&val, memPtr, sizeof(val)); + return val; } static inline U32 LZ4_read32(const void* memPtr) { - U32 val; memcpy(&val, memPtr, sizeof(val)); return val; + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; } static inline reg_t LZ4_read_ARCH(const void* memPtr) { - reg_t val; memcpy(&val, memPtr, sizeof(val)); return val; + reg_t val; + memcpy(&val, memPtr, sizeof(val)); + return val; } static inline void LZ4_write16(void* memPtr, U16 value) { @@ -268,9 +314,10 @@ static inline U16 LZ4_readLE16(const void* memPtr) { if (LZ4_isLittleEndian()) { return LZ4_read16(memPtr); - } else { + } + else { const BYTE* p = (const BYTE*)memPtr; - return (U16)((U16)p[0] + (p[1]<<8)); + return (U16)((U16)p[0] + (p[1] << 8)); } } @@ -278,16 +325,17 @@ static inline void LZ4_writeLE16(void* memPtr, U16 value) { if (LZ4_isLittleEndian()) { LZ4_write16(memPtr, value); - } else { + } + else { BYTE* p = (BYTE*)memPtr; - p[0] = (BYTE) value; - p[1] = (BYTE)(value>>8); + p[0] = (BYTE)value; + p[1] = (BYTE)(value >> 8); } } static inline void LZ4_copy8(void* dst, const void* src) { - memcpy(dst,src,8); + memcpy(dst, src, 8); } static inline void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) @@ -296,103 +344,113 @@ static inline void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) const BYTE* s = (const BYTE*)srcPtr; BYTE* const e = (BYTE*)dstEnd; do { - LZ4_copy8(d,s); - d+=8; - s+=8; - } while (d>3); -# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + _BitScanForward64(&r, (U64)val); + return (int)(r >> 3); +#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll((U64)val) >> 3); -# else - static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; +#else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, + 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; -# endif - } else /* 32 bits */ { -# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +#endif + } + else /* 32 bits */ { +#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; - _BitScanForward( &r, (U32)val ); - return (int)(r>>3); -# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + _BitScanForward(&r, (U32)val); + return (int)(r >> 3); +#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz((U32)val) >> 3); -# else +#else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; -# endif +#endif } - } else /* Big Endian CPU */ { - if (sizeof(val)==8) { -# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + } + else /* Big Endian CPU */ { + if (sizeof(val) == 8) { +#if defined(_MSC_VER) && defined(_WIN64) && ! defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; - _BitScanReverse64( &r, val ); - return (unsigned)(r>>3); -# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + _BitScanReverse64(&r, val); + return (unsigned)(r >> 3); +#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll((U64)val) >> 3); -# else +#else unsigned r; - if (!(val>>32)) { - r=4; - } else { - r=0; - val>>=32; + if (! (val >> 32)) { + r = 4; } - if (!(val>>16)) { - r+=2; - val>>=8; - } else { - val>>=24; + else { + r = 0; + val >>= 32; } - r += (!val); + if (! (val >> 16)) { + r += 2; + val >>= 8; + } + else { + val >>= 24; + } + r += (! val); return r; -# endif - } else /* 32 bits */ { -# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) +#endif + } + else /* 32 bits */ { +#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; - _BitScanReverse( &r, (unsigned long)val ); - return (unsigned)(r>>3); -# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + _BitScanReverse(&r, (unsigned long)val); + return (unsigned)(r >> 3); +#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz((U32)val) >> 3); -# else +#else unsigned r; - if (!(val>>16)) { - r=2; - val>>=8; - } else { - r=0; - val>>=24; + if (! (val >> 16)) { + r = 2; + val >>= 8; } - r += (!val); + else { + r = 0; + val >>= 24; + } + r += (! val); return r; -# endif +#endif } } } @@ -402,30 +460,33 @@ static inline unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE { const BYTE* const pStart = pIn; - while (likely(pIn compression run slower on incompressible data */ +static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT - 1)); +static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */ typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; typedef enum { byPtr, byU32, byU16 } tableType_t; @@ -436,14 +497,18 @@ typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; typedef enum { full = 0, partial = 1 } earlyEnd_directive; -static inline int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } +static inline int LZ4_compressBound(int isize) +{ + return LZ4_COMPRESSBOUND(isize); +} static inline U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { if (tableType == byU16) { - return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); - } else { - return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); + return ((sequence * 2654435761U) >> ((MINMATCH * 8) - (LZ4_HASHLOG + 1))); + } + else { + return ((sequence * 2654435761U) >> ((MINMATCH * 8) - LZ4_HASHLOG)); } } @@ -451,17 +516,18 @@ static inline U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { static const U64 prime5bytes = 889523592379ULL; static const U64 prime8bytes = 11400714785074694791ULL; - const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; + const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG + 1 : LZ4_HASHLOG; if (LZ4_isLittleEndian()) { return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); - } else { + } + else { return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); } } FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) { - if ((sizeof(reg_t)==8) && (tableType != byU16)) { + if ((sizeof(reg_t) == 8) && (tableType != byU16)) { return LZ4_hash5(LZ4_read_ARCH(p), tableType); } return LZ4_hash4(LZ4_read32(p), tableType); @@ -470,18 +536,21 @@ FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableTy static inline void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) { switch (tableType) { - case byPtr: { - const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; - return; - } - case byU32: { - U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); - return; - } - case byU16: { - U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); - return; - } + case byPtr: { + const BYTE** hashTable = (const BYTE**)tableBase; + hashTable[h] = p; + return; + } + case byU32: { + U32* hashTable = (U32*)tableBase; + hashTable[h] = (U32)(p - srcBase); + return; + } + case byU16: { + U16* hashTable = (U16*)tableBase; + hashTable[h] = (U16)(p - srcBase); + return; + } } } @@ -494,15 +563,15 @@ FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t ta static inline const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { - const BYTE** hashTable = (const BYTE**) tableBase; + const BYTE** hashTable = (const BYTE**)tableBase; return hashTable[h]; } if (tableType == byU32) { - const U32* const hashTable = (U32*) tableBase; + const U32* const hashTable = (U32*)tableBase; return hashTable[h] + srcBase; } { /* default, to ensure a return */ - const U16* const hashTable = (U16*) tableBase; + const U16* const hashTable = (U16*)tableBase; return hashTable[h] + srcBase; } } @@ -514,58 +583,58 @@ FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableTy } FORCE_INLINE int LZ4_compress_generic( - LZ4_stream_t_internal* const cctx, - const char* const source, - char* const dest, - const int inputSize, - const int maxOutputSize, - const limitedOutput_directive outputLimited, - const tableType_t tableType, - const dict_directive dict, - const dictIssue_directive dictIssue, - const U32 acceleration) + LZ4_stream_t_internal* const cctx, + const char* const source, + char* const dest, + const int inputSize, + const int maxOutputSize, + const limitedOutput_directive outputLimited, + const tableType_t tableType, + const dict_directive dict, + const dictIssue_directive dictIssue, + const U32 acceleration) { - const BYTE* ip = (const BYTE*) source; + const BYTE* ip = (const BYTE*)source; const BYTE* base; const BYTE* lowLimit; const BYTE* const lowRefLimit = ip - cctx->dictSize; const BYTE* const dictionary = cctx->dictionary; const BYTE* const dictEnd = dictionary + cctx->dictSize; const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source; - const BYTE* anchor = (const BYTE*) source; + const BYTE* anchor = (const BYTE*)source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = iend - LASTLITERALS; - BYTE* op = (BYTE*) dest; + BYTE* op = (BYTE*)dest; BYTE* const olimit = op + maxOutputSize; U32 forwardH; /* Init conditions */ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) { - return 0; /* Unsupported inputSize, too large (or negative) */ + return 0; /* Unsupported inputSize, too large (or negative) */ } - switch(dict) { - case noDict: - default: - base = (const BYTE*)source; - lowLimit = (const BYTE*)source; - break; - case withPrefix64k: - base = (const BYTE*)source - cctx->currentOffset; - lowLimit = (const BYTE*)source - cctx->dictSize; - break; - case usingExtDict: - base = (const BYTE*)source - cctx->currentOffset; - lowLimit = (const BYTE*)source; - break; + switch (dict) { + case noDict: + default: + base = (const BYTE*)source; + lowLimit = (const BYTE*)source; + break; + case withPrefix64k: + base = (const BYTE*)source - cctx->currentOffset; + lowLimit = (const BYTE*)source - cctx->dictSize; + break; + case usingExtDict: + base = (const BYTE*)source - cctx->currentOffset; + lowLimit = (const BYTE*)source; + break; } - if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) { - return 0; /* Size too large (not within 64K limit) */ + if ((tableType == byU16) && (inputSize >= LZ4_64Klimit)) { + return 0; /* Size too large (not within 64K limit) */ } - if (inputSizehashTable, tableType, base); - if (dict==usingExtDict) { + if (dict == usingExtDict) { if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } else { + } + else { refDelta = 0; lowLimit = (const BYTE*)source; } @@ -607,13 +677,11 @@ FORCE_INLINE int LZ4_compress_generic( forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); - } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) - || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) - || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); + } while (((dictIssue == dictSmall) ? (match < lowRefLimit) : 0) || ((tableType == byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match + refDelta) != LZ4_read32(ip))); } /* Catch up */ - while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { + while (((ip > anchor) & (match + refDelta > lowLimit)) && (unlikely(ip[-1] == match[refDelta - 1]))) { ip--; match--; } @@ -622,70 +690,73 @@ FORCE_INLINE int LZ4_compress_generic( { unsigned const litLength = (unsigned)(ip - anchor); token = op++; - if ((outputLimited) && /* Check output buffer overflow */ - (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) { + if ((outputLimited) && /* Check output buffer overflow */ + (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength / 255) > olimit))) { return 0; } if (litLength >= RUN_MASK) { - int len = (int)litLength-RUN_MASK; - *token = (RUN_MASK<= 255 ; len-=255) { + int len = (int)litLength - RUN_MASK; + *token = (RUN_MASK << ML_BITS); + for (; len >= 255; len -= 255) { *op++ = 255; } *op++ = (BYTE)len; - } else { - *token = (BYTE)(litLength< matchlimit) { limit = matchlimit; } - matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, limit); ip += MINMATCH + matchCode; - if (ip==limit) { + if (ip == limit) { unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit); matchCode += more; ip += more; } - } else { - matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + } + else { + matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit); ip += MINMATCH + matchCode; } - if ( outputLimited && /* Check output buffer overflow */ - (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) { + if (outputLimited && /* Check output buffer overflow */ + (unlikely(op + (1 + LASTLITERALS) + (matchCode >> 8) > olimit))) { return 0; } if (matchCode >= ML_MASK) { *token += ML_MASK; matchCode -= ML_MASK; LZ4_write32(op, 0xFFFFFFFF); - while (matchCode >= 4*255) { - op+=4; + while (matchCode >= 4 * 255) { + op += 4; LZ4_write32(op, 0xFFFFFFFF); - matchCode -= 4*255; + matchCode -= 4 * 255; } op += matchCode / 255; *op++ = (BYTE)(matchCode % 255); - } else { + } + else { *token += (BYTE)(matchCode); } } @@ -698,25 +769,24 @@ _next_match: } /* Fill table */ - LZ4_putPosition(ip-2, cctx->hashTable, tableType, base); + LZ4_putPosition(ip - 2, cctx->hashTable, tableType, base); /* Test next position */ match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); - if (dict==usingExtDict) { + if (dict == usingExtDict) { if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } else { + } + else { refDelta = 0; lowLimit = (const BYTE*)source; } } LZ4_putPosition(ip, cctx->hashTable, tableType, base); - if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) - && (match+MAX_DISTANCE>=ip) - && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) { - token=op++; - *token=0; + if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1) && (match + MAX_DISTANCE >= ip) && (LZ4_read32(match + refDelta) == LZ4_read32(ip))) { + token = op++; + *token = 0; goto _next_match; } @@ -728,45 +798,49 @@ _last_literals: /* Encode Last Literals */ { size_t const lastRun = (size_t)(iend - anchor); - if ( (outputLimited) && /* Check output buffer overflow */ - ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) ) { + if ((outputLimited) && /* Check output buffer overflow */ + ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > (U32)maxOutputSize)) { return 0; } if (lastRun >= RUN_MASK) { size_t accumulator = lastRun - RUN_MASK; *op++ = RUN_MASK << ML_BITS; - for(; accumulator >= 255 ; accumulator-=255) { + for (; accumulator >= 255; accumulator -= 255) { *op++ = 255; } - *op++ = (BYTE) accumulator; - } else { - *op++ = (BYTE)(lastRun<internal_donotuse; LZ4_resetStream((LZ4_stream_t*)state); - //if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + // if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; if (maxOutputSize >= LZ4_compressBound(inputSize)) { if (inputSize < LZ4_64Klimit) { - return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); - } else { - return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); } - } else { + else { + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); + } + } + else { if (inputSize < LZ4_64Klimit) { - return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); - } else { - return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + } + else { + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); } } } @@ -774,7 +848,7 @@ static inline int LZ4_compress_fast_extState(void* state, const char* source, ch static inline int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { #if (HEAPMODE) - void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctx; void* const ctxPtr = &ctx; @@ -788,53 +862,52 @@ static inline int LZ4_compress_fast(const char* source, char* dest, int inputSiz return result; } -static inline void LZ4_resetStream (LZ4_stream_t* LZ4_stream) +static inline void LZ4_resetStream(LZ4_stream_t* LZ4_stream) { MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); } FORCE_INLINE int LZ4_decompress_generic( - const char* const source, - char* const dest, - int inputSize, - int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ + const char* const source, + char* const dest, + int inputSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ - int endOnInput, /* endOnOutputSize, endOnInputSize */ - int partialDecoding, /* full, partial */ - int targetOutputSize, /* only used if partialDecoding==partial */ - int dict, /* noDict, withPrefix64k, usingExtDict */ - const BYTE* const lowPrefix, /* == dest when no prefix */ - const BYTE* const dictStart, /* only if dict==usingExtDict */ - const size_t dictSize /* note : = 0 if noDict */ - ) + int endOnInput, /* endOnOutputSize, endOnInputSize */ + int partialDecoding, /* full, partial */ + int targetOutputSize, /* only used if partialDecoding==partial */ + int dict, /* noDict, withPrefix64k, usingExtDict */ + const BYTE* const lowPrefix, /* == dest when no prefix */ + const BYTE* const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note : = 0 if noDict */ +) { /* Local Variables */ - const BYTE* ip = (const BYTE*) source; + const BYTE* ip = (const BYTE*)source; const BYTE* const iend = ip + inputSize; - BYTE* op = (BYTE*) dest; + BYTE* op = (BYTE*)dest; BYTE* const oend = op + outputSize; BYTE* cpy; BYTE* oexit = op + targetOutputSize; const BYTE* const lowLimit = lowPrefix - dictSize; const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; - const unsigned dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; - const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3}; + const unsigned dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; + const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; - const int safeDecode = (endOnInput==endOnInputSize); + const int safeDecode = (endOnInput == endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); - /* Special cases */ - if ((partialDecoding) && (oexit > oend-MFLIMIT)) { - oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ + if ((partialDecoding) && (oexit > oend - MFLIMIT)) { + oexit = oend - MFLIMIT; /* targetOutputSize too high => decode everything */ } - if ((endOnInput) && (unlikely(outputSize==0))) { - return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ + if ((endOnInput) && (unlikely(outputSize == 0))) { + return ((inputSize == 1) && (*ip == 0)) ? 0 : -1; /* Empty output buffer */ } - if ((!endOnInput) && (unlikely(outputSize==0))) { - return (*ip==0?1:-1); + if ((! endOnInput) && (unlikely(outputSize == 0))) { + return (*ip == 0 ? 1 : -1); } /* Main Loop : decode sequences */ @@ -845,43 +918,43 @@ FORCE_INLINE int LZ4_decompress_generic( /* get literal length */ unsigned const token = *ip++; - if ((length=(token>>ML_BITS)) == RUN_MASK) { + if ((length = (token >> ML_BITS)) == RUN_MASK) { unsigned s; do { s = *ip++; length += s; - } while ( likely(endOnInput ? ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) - || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) ) { + cpy = op + length; + if (((endOnInput) && ((cpy > (partialDecoding ? oexit : oend - MFLIMIT)) || (ip + length > iend - (2 + 1 + LASTLITERALS)))) || ((! endOnInput) && (cpy > oend - WILDCOPYLENGTH))) { if (partialDecoding) { if (cpy > oend) { - goto _output_error; /* Error : write attempt beyond end of output buffer */ + goto _output_error; /* Error : write attempt beyond end of output buffer */ } - if ((endOnInput) && (ip+length > iend)) { - goto _output_error; /* Error : read attempt beyond end of input buffer */ + if ((endOnInput) && (ip + length > iend)) { + goto _output_error; /* Error : read attempt beyond end of input buffer */ } - } else { - if ((!endOnInput) && (cpy != oend)) { - goto _output_error; /* Error : block decoding must stop exactly there */ + } + else { + if ((! endOnInput) && (cpy != oend)) { + goto _output_error; /* Error : block decoding must stop exactly there */ } - if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) { - goto _output_error; /* Error : input must be consumed */ + if ((endOnInput) && ((ip + length != iend) || (cpy > oend))) { + goto _output_error; /* Error : input must be consumed */ } } memcpy(op, ip, length); ip += length; op += length; - break; /* Necessarily EOF, due to parsing restrictions */ + break; /* Necessarily EOF, due to parsing restrictions */ } LZ4_wildCopy(op, ip, cpy); ip += length; @@ -892,9 +965,9 @@ FORCE_INLINE int LZ4_decompress_generic( ip += 2; match = op - offset; if ((checkOffset) && (unlikely(match < lowLimit))) { - goto _output_error; /* Error : offset outside buffers */ + goto _output_error; /* Error : offset outside buffers */ } - LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ + LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ /* get matchlength */ length = token & ML_MASK; @@ -902,40 +975,42 @@ FORCE_INLINE int LZ4_decompress_generic( unsigned s; do { s = *ip++; - if ((endOnInput) && (ip > iend-LASTLITERALS)) { + if ((endOnInput) && (ip > iend - LASTLITERALS)) { goto _output_error; } length += s; - } while (s==255); - if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) { - goto _output_error; /* overflow detection */ + } while (s == 255); + if ((safeDecode) && unlikely((uptrval)(op) + length < (uptrval)op)) { + goto _output_error; /* overflow detection */ } } length += MINMATCH; /* check external dictionary */ - if ((dict==usingExtDict) && (match < lowPrefix)) { - if (unlikely(op+length > oend-LASTLITERALS)) { - goto _output_error; /* doesn't respect parsing restriction */ + if ((dict == usingExtDict) && (match < lowPrefix)) { + if (unlikely(op + length > oend - LASTLITERALS)) { + goto _output_error; /* doesn't respect parsing restriction */ } - if (length <= (size_t)(lowPrefix-match)) { + if (length <= (size_t)(lowPrefix - match)) { /* match can be copied as a single segment from external dictionary */ - memmove(op, dictEnd - (lowPrefix-match), length); + memmove(op, dictEnd - (lowPrefix - match), length); op += length; - } else { + } + else { /* match encompass external dictionary and current block */ - size_t const copySize = (size_t)(lowPrefix-match); + size_t const copySize = (size_t)(lowPrefix - match); size_t const restSize = length - copySize; memcpy(op, dictEnd - copySize, copySize); op += copySize; - if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */ + if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ BYTE* const endOfMatch = op + restSize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) { *op++ = *copyFrom++; } - } else { + } + else { memcpy(op, lowPrefix, restSize); op += restSize; } @@ -945,52 +1020,55 @@ FORCE_INLINE int LZ4_decompress_generic( /* copy match within block */ cpy = op + length; - if (unlikely(offset<8)) { + if (unlikely(offset < 8)) { const int dec64 = dec64table[offset]; op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; match += dec32table[offset]; - memcpy(op+4, match, 4); + memcpy(op + 4, match, 4); match -= dec64; - } else { + } + else { LZ4_copy8(op, match); - match+=8; + match += 8; } op += 8; - if (unlikely(cpy>oend-12)) { - BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1); - if (cpy > oend-LASTLITERALS) { - goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ + if (unlikely(cpy > oend - 12)) { + BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH - 1); + if (cpy > oend - LASTLITERALS) { + goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ } if (op < oCopyLimit) { LZ4_wildCopy(op, match, oCopyLimit); match += oCopyLimit - op; op = oCopyLimit; } - while (op16) { - LZ4_wildCopy(op+8, match+8, cpy); + if (length > 16) { + LZ4_wildCopy(op + 8, match + 8, cpy); } } - op=cpy; /* correction */ + op = cpy; /* correction */ } /* end of decoding */ if (endOnInput) { - return (int) (((char*)op)-dest); /* Nb of output bytes decoded */ - } else { - return (int) (((const char*)ip)-source); /* Nb of input bytes read */ + return (int)(((char*)op) - dest); /* Nb of output bytes decoded */ + } + else { + return (int)(((const char*)ip) - source); /* Nb of input bytes read */ } /* Overflow error detected */ _output_error: - return (int) (-(((const char*)ip)-source))-1; + return (int)(-(((const char*)ip) - source)) - 1; } static inline int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) @@ -998,80 +1076,82 @@ static inline int LZ4_decompress_safe(const char* source, char* dest, int compre return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0); } -} // anonymous namespace +} // anonymous namespace /************************************************************************** */ /************************************************************************** */ -const unsigned char Packet::ZERO_KEY[32] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +const unsigned char Packet::ZERO_KEY[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -void Packet::armor(const void *key,bool encryptPayload,const AES aesKeys[2]) +void Packet::armor(const void* key, bool encryptPayload, const AES aesKeys[2]) { - uint8_t *const data = reinterpret_cast(unsafeData()); + uint8_t* const data = reinterpret_cast(unsafeData()); if ((aesKeys) && (encryptPayload)) { - //char tmp0[16],tmp1[16]; + // char tmp0[16],tmp1[16]; setCipher(ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV); - uint8_t *const payload = data + ZT_PACKET_IDX_VERB; + uint8_t* const payload = data + ZT_PACKET_IDX_VERB; const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; - AES::GMACSIVEncryptor enc(aesKeys[0],aesKeys[1]); - enc.init(Utils::loadMachineEndian(data + ZT_PACKET_IDX_IV),payload); - enc.aad(data + ZT_PACKET_IDX_DEST,11); - enc.update1(payload,payloadLen); + AES::GMACSIVEncryptor enc(aesKeys[0], aesKeys[1]); + enc.init(Utils::loadMachineEndian(data + ZT_PACKET_IDX_IV), payload); + enc.aad(data + ZT_PACKET_IDX_DEST, 11); + enc.update1(payload, payloadLen); enc.finish1(); - enc.update2(payload,payloadLen); - const uint64_t *const tag = enc.finish2(); + enc.update2(payload, payloadLen); + const uint64_t* const tag = enc.finish2(); #ifdef ZT_NO_UNALIGNED_ACCESS - Utils::copy<8>(data,tag); - Utils::copy<8>(data + ZT_PACKET_IDX_MAC,tag + 1); + Utils::copy<8>(data, tag); + Utils::copy<8>(data + ZT_PACKET_IDX_MAC, tag + 1); #else - *reinterpret_cast(data + ZT_PACKET_IDX_IV) = tag[0]; - *reinterpret_cast(data + ZT_PACKET_IDX_MAC) = tag[1]; + *reinterpret_cast(data + ZT_PACKET_IDX_IV) = tag[0]; + *reinterpret_cast(data + ZT_PACKET_IDX_MAC) = tag[1]; #endif - } else { + } + else { setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE); uint8_t mangledKey[32]; - _salsa20MangleKey((const unsigned char *)key,mangledKey); + _salsa20MangleKey((const unsigned char*)key, mangledKey); if (ZT_HAS_FAST_CRYPTO()) { const unsigned int payloadLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0; uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8]; - ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,payloadLen + 64,(data + ZT_PACKET_IDX_IV),mangledKey); - Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast(keyStream + 8),payloadLen); + ZT_FAST_SINGLE_PASS_SALSA2012(keyStream, payloadLen + 64, (data + ZT_PACKET_IDX_IV), mangledKey); + Salsa20::memxor(data + ZT_PACKET_IDX_VERB, reinterpret_cast(keyStream + 8), payloadLen); uint64_t mac[2]; - Poly1305::compute(mac,data + ZT_PACKET_IDX_VERB,size() - ZT_PACKET_IDX_VERB,keyStream); + Poly1305::compute(mac, data + ZT_PACKET_IDX_VERB, size() - ZT_PACKET_IDX_VERB, keyStream); #ifdef ZT_NO_TYPE_PUNNING - memcpy(data + ZT_PACKET_IDX_MAC,mac,8); + memcpy(data + ZT_PACKET_IDX_MAC, mac, 8); #else - (*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) = mac[0]; + (*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) = mac[0]; #endif - } else { - Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV); + } + else { + Salsa20 s20(mangledKey, data + ZT_PACKET_IDX_IV); uint64_t macKey[4]; - s20.crypt12(ZERO_KEY,macKey,sizeof(macKey)); + s20.crypt12(ZERO_KEY, macKey, sizeof(macKey)); - uint8_t *const payload = data + ZT_PACKET_IDX_VERB; + uint8_t* const payload = data + ZT_PACKET_IDX_VERB; const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; if (encryptPayload) { - s20.crypt12(payload,payload,payloadLen); + s20.crypt12(payload, payload, payloadLen); } uint64_t mac[2]; - Poly1305::compute(mac,payload,payloadLen,macKey); - memcpy(data + ZT_PACKET_IDX_MAC,mac,8); + Poly1305::compute(mac, payload, payloadLen, macKey); + memcpy(data + ZT_PACKET_IDX_MAC, mac, 8); } } } -bool Packet::dearmor(const void *key,const AES aesKeys[2]) +bool Packet::dearmor(const void* key, const AES aesKeys[2]) { - uint8_t *const data = reinterpret_cast(unsafeData()); + uint8_t* const data = reinterpret_cast(unsafeData()); const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; - unsigned char *const payload = data + ZT_PACKET_IDX_VERB; + unsigned char* const payload = data + ZT_PACKET_IDX_VERB; const unsigned int cs = cipher(); if (cs == ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV) { @@ -1081,56 +1161,58 @@ bool Packet::dearmor(const void *key,const AES aesKeys[2]) Utils::copy<8>(tag, data); Utils::copy<8>(tag + 1, data + ZT_PACKET_IDX_MAC); #else - tag[0] = *reinterpret_cast(data + ZT_PACKET_IDX_IV); - tag[1] = *reinterpret_cast(data + ZT_PACKET_IDX_MAC); + tag[0] = *reinterpret_cast(data + ZT_PACKET_IDX_IV); + tag[1] = *reinterpret_cast(data + ZT_PACKET_IDX_MAC); #endif - AES::GMACSIVDecryptor dec(aesKeys[0],aesKeys[1]); + AES::GMACSIVDecryptor dec(aesKeys[0], aesKeys[1]); dec.init(tag, payload); const uint8_t oldFlags = data[ZT_PACKET_IDX_FLAGS]; data[ZT_PACKET_IDX_FLAGS] &= 0xf8; - dec.aad(data + ZT_PACKET_IDX_DEST,11); + dec.aad(data + ZT_PACKET_IDX_DEST, 11); data[ZT_PACKET_IDX_FLAGS] = oldFlags; dec.update(payload, payloadLen); return dec.finish(); } - } else if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) { + } + else if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE) || (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) { uint8_t mangledKey[32]; - _salsa20MangleKey((const unsigned char *)key,mangledKey); + _salsa20MangleKey((const unsigned char*)key, mangledKey); if (ZT_HAS_FAST_CRYPTO()) { uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8]; - ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) ? (payloadLen + 64) : 64),(data + ZT_PACKET_IDX_IV),mangledKey); + ZT_FAST_SINGLE_PASS_SALSA2012(keyStream, ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) ? (payloadLen + 64) : 64), (data + ZT_PACKET_IDX_IV), mangledKey); uint64_t mac[2]; - Poly1305::compute(mac,payload,payloadLen,keyStream); + Poly1305::compute(mac, payload, payloadLen, keyStream); #ifdef ZT_NO_TYPE_PUNNING - if (!Utils::secureEq(mac,data + ZT_PACKET_IDX_MAC,8)) { + if (! Utils::secureEq(mac, data + ZT_PACKET_IDX_MAC, 8)) { return false; } #else - if ((*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) != mac[0]) { // also secure, constant time + if ((*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) != mac[0]) { // also secure, constant time return false; } #endif if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) { - Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast(keyStream + 8),payloadLen); + Salsa20::memxor(data + ZT_PACKET_IDX_VERB, reinterpret_cast(keyStream + 8), payloadLen); } - } else { - Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV); + } + else { + Salsa20 s20(mangledKey, data + ZT_PACKET_IDX_IV); uint64_t macKey[4]; - s20.crypt12(ZERO_KEY,macKey,sizeof(macKey)); + s20.crypt12(ZERO_KEY, macKey, sizeof(macKey)); uint64_t mac[2]; - Poly1305::compute(mac,payload,payloadLen,macKey); + Poly1305::compute(mac, payload, payloadLen, macKey); #ifdef ZT_NO_TYPE_PUNNING - if (!Utils::secureEq(mac,data + ZT_PACKET_IDX_MAC,8)) { + if (! Utils::secureEq(mac, data + ZT_PACKET_IDX_MAC, 8)) { return false; } #else - if ((*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) != mac[0]) { // also secure, constant time + if ((*reinterpret_cast(data + ZT_PACKET_IDX_MAC)) != mac[0]) { // also secure, constant time return false; } #endif if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) { - s20.crypt12(payload,payload,payloadLen); + s20.crypt12(payload, payload, payloadLen); } } return true; @@ -1139,30 +1221,30 @@ bool Packet::dearmor(const void *key,const AES aesKeys[2]) return false; } -void Packet::cryptField(const void *key,unsigned int start,unsigned int len) +void Packet::cryptField(const void* key, unsigned int start, unsigned int len) { - uint8_t *const data = reinterpret_cast(unsafeData()); + uint8_t* const data = reinterpret_cast(unsafeData()); uint8_t iv[8]; - for(int i=0;i<8;++i) { + for (int i = 0; i < 8; ++i) { iv[i] = data[i]; } - iv[7] &= 0xf8; // mask off least significant 3 bits of packet ID / IV since this is unset when this function gets called - Salsa20 s20(key,iv); - s20.crypt12(data + start,data + start,len); + iv[7] &= 0xf8; // mask off least significant 3 bits of packet ID / IV since this is unset when this function gets called + Salsa20 s20(key, iv); + s20.crypt12(data + start, data + start, len); } bool Packet::compress() { - char *const data = reinterpret_cast(unsafeData()); + char* const data = reinterpret_cast(unsafeData()); char buf[ZT_PROTO_MAX_PACKET_LENGTH * 2]; - if ((!compressed())&&(size() > (ZT_PACKET_IDX_PAYLOAD + 64))) { // don't bother compressing tiny packets + if ((! compressed()) && (size() > (ZT_PACKET_IDX_PAYLOAD + 64))) { // don't bother compressing tiny packets int pl = (int)(size() - ZT_PACKET_IDX_PAYLOAD); - int cl = LZ4_compress_fast(data + ZT_PACKET_IDX_PAYLOAD,buf,pl,ZT_PROTO_MAX_PACKET_LENGTH * 2,1); - if ((cl > 0)&&(cl < pl)) { + int cl = LZ4_compress_fast(data + ZT_PACKET_IDX_PAYLOAD, buf, pl, ZT_PROTO_MAX_PACKET_LENGTH * 2, 1); + if ((cl > 0) && (cl < pl)) { data[ZT_PACKET_IDX_VERB] |= (char)ZT_PROTO_VERB_FLAG_COMPRESSED; setSize((unsigned int)cl + ZT_PACKET_IDX_PAYLOAD); - memcpy(data + ZT_PACKET_IDX_PAYLOAD,buf,cl); + memcpy(data + ZT_PACKET_IDX_PAYLOAD, buf, cl); return true; } } @@ -1173,17 +1255,18 @@ bool Packet::compress() bool Packet::uncompress() { - char *const data = reinterpret_cast(unsafeData()); + char* const data = reinterpret_cast(unsafeData()); char buf[ZT_PROTO_MAX_PACKET_LENGTH]; - if ((compressed())&&(size() >= ZT_PROTO_MIN_PACKET_LENGTH)) { + if ((compressed()) && (size() >= ZT_PROTO_MIN_PACKET_LENGTH)) { if (size() > ZT_PACKET_IDX_PAYLOAD) { unsigned int compLen = size() - ZT_PACKET_IDX_PAYLOAD; - int ucl = LZ4_decompress_safe((const char *)data + ZT_PACKET_IDX_PAYLOAD,buf,compLen,sizeof(buf)); - if ((ucl > 0)&&(ucl <= (int)(capacity() - ZT_PACKET_IDX_PAYLOAD))) { + int ucl = LZ4_decompress_safe((const char*)data + ZT_PACKET_IDX_PAYLOAD, buf, compLen, sizeof(buf)); + if ((ucl > 0) && (ucl <= (int)(capacity() - ZT_PACKET_IDX_PAYLOAD))) { setSize((unsigned int)ucl + ZT_PACKET_IDX_PAYLOAD); - memcpy(data + ZT_PACKET_IDX_PAYLOAD,buf,ucl); - } else { + memcpy(data + ZT_PACKET_IDX_PAYLOAD, buf, ucl); + } + else { return false; } } @@ -1193,4 +1276,4 @@ bool Packet::uncompress() return true; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Packet.hpp b/node/Packet.hpp index f607d1f52..f038c05dc 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -14,21 +14,19 @@ #ifndef ZT_N_PACKET_HPP #define ZT_N_PACKET_HPP -#include -#include -#include - -#include -#include - -#include "Constants.hpp" - +#include "AES.hpp" #include "Address.hpp" +#include "Buffer.hpp" +#include "Constants.hpp" #include "Poly1305.hpp" #include "Salsa20.hpp" -#include "AES.hpp" #include "Utils.hpp" -#include "Buffer.hpp" + +#include +#include +#include +#include +#include /** * Protocol version -- incremented only for major changes @@ -221,12 +219,12 @@ #define ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT 0x02 // Field indexes in packet header -#define ZT_PACKET_IDX_IV 0 -#define ZT_PACKET_IDX_DEST 8 -#define ZT_PACKET_IDX_SOURCE 13 -#define ZT_PACKET_IDX_FLAGS 18 -#define ZT_PACKET_IDX_MAC 19 -#define ZT_PACKET_IDX_VERB 27 +#define ZT_PACKET_IDX_IV 0 +#define ZT_PACKET_IDX_DEST 8 +#define ZT_PACKET_IDX_SOURCE 13 +#define ZT_PACKET_IDX_FLAGS 18 +#define ZT_PACKET_IDX_MAC 19 +#define ZT_PACKET_IDX_VERB 27 #define ZT_PACKET_IDX_PAYLOAD 28 /** @@ -240,12 +238,12 @@ #define ZT_PROTO_MIN_PACKET_LENGTH ZT_PACKET_IDX_PAYLOAD // Indexes of fields in fragment header -#define ZT_PACKET_FRAGMENT_IDX_PACKET_ID 0 -#define ZT_PACKET_FRAGMENT_IDX_DEST 8 +#define ZT_PACKET_FRAGMENT_IDX_PACKET_ID 0 +#define ZT_PACKET_FRAGMENT_IDX_DEST 8 #define ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR 13 -#define ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO 14 -#define ZT_PACKET_FRAGMENT_IDX_HOPS 15 -#define ZT_PACKET_FRAGMENT_IDX_PAYLOAD 16 +#define ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO 14 +#define ZT_PACKET_FRAGMENT_IDX_HOPS 15 +#define ZT_PACKET_FRAGMENT_IDX_PAYLOAD 16 /** * Magic number found at ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR @@ -264,89 +262,89 @@ // See their respective handler functions. #define ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION + 1) -#define ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION + 1) -#define ZT_PROTO_VERB_HELLO_IDX_REVISION (ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION + 1) -#define ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP (ZT_PROTO_VERB_HELLO_IDX_REVISION + 2) -#define ZT_PROTO_VERB_HELLO_IDX_IDENTITY (ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP + 8) +#define ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION + 1) +#define ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION (ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION + 1) +#define ZT_PROTO_VERB_HELLO_IDX_REVISION (ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION + 1) +#define ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP (ZT_PROTO_VERB_HELLO_IDX_REVISION + 2) +#define ZT_PROTO_VERB_HELLO_IDX_IDENTITY (ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP + 8) -#define ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD) +#define ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD) #define ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID (ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB + 1) -#define ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE (ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID + 8) -#define ZT_PROTO_VERB_ERROR_IDX_PAYLOAD (ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE + 1) +#define ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE (ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID + 8) +#define ZT_PROTO_VERB_ERROR_IDX_PAYLOAD (ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE + 1) -#define ZT_PROTO_VERB_OK_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD) +#define ZT_PROTO_VERB_OK_IDX_IN_RE_VERB (ZT_PACKET_IDX_PAYLOAD) #define ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID (ZT_PROTO_VERB_OK_IDX_IN_RE_VERB + 1) -#define ZT_PROTO_VERB_OK_IDX_PAYLOAD (ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID + 8) +#define ZT_PROTO_VERB_OK_IDX_PAYLOAD (ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID + 8) #define ZT_PROTO_VERB_WHOIS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_RENDEZVOUS_IDX_FLAGS (ZT_PACKET_IDX_PAYLOAD) +#define ZT_PROTO_VERB_RENDEZVOUS_IDX_FLAGS (ZT_PACKET_IDX_PAYLOAD) #define ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_FLAGS + 1) -#define ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT (ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS + 5) -#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN (ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT + 2) -#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN + 1) +#define ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT (ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS + 5) +#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN (ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT + 2) +#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN + 1) #define ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE + 2) +#define ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE + 2) #define ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) #define ZT_PROTO_VERB_EXT_FRAME_LEN_NETWORK_ID 8 -#define ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS (ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID + ZT_PROTO_VERB_EXT_FRAME_LEN_NETWORK_ID) -#define ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS 1 -#define ZT_PROTO_VERB_EXT_FRAME_IDX_COM (ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS + ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS) -#define ZT_PROTO_VERB_EXT_FRAME_IDX_TO (ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS + ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS) -#define ZT_PROTO_VERB_EXT_FRAME_LEN_TO 6 -#define ZT_PROTO_VERB_EXT_FRAME_IDX_FROM (ZT_PROTO_VERB_EXT_FRAME_IDX_TO + ZT_PROTO_VERB_EXT_FRAME_LEN_TO) -#define ZT_PROTO_VERB_EXT_FRAME_LEN_FROM 6 -#define ZT_PROTO_VERB_EXT_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_EXT_FRAME_IDX_FROM + ZT_PROTO_VERB_EXT_FRAME_LEN_FROM) -#define ZT_PROTO_VERB_EXT_FRAME_LEN_ETHERTYPE 2 -#define ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_EXT_FRAME_IDX_ETHERTYPE + ZT_PROTO_VERB_EXT_FRAME_LEN_ETHERTYPE) +#define ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS (ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID + ZT_PROTO_VERB_EXT_FRAME_LEN_NETWORK_ID) +#define ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS 1 +#define ZT_PROTO_VERB_EXT_FRAME_IDX_COM (ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS + ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS) +#define ZT_PROTO_VERB_EXT_FRAME_IDX_TO (ZT_PROTO_VERB_EXT_FRAME_IDX_FLAGS + ZT_PROTO_VERB_EXT_FRAME_LEN_FLAGS) +#define ZT_PROTO_VERB_EXT_FRAME_LEN_TO 6 +#define ZT_PROTO_VERB_EXT_FRAME_IDX_FROM (ZT_PROTO_VERB_EXT_FRAME_IDX_TO + ZT_PROTO_VERB_EXT_FRAME_LEN_TO) +#define ZT_PROTO_VERB_EXT_FRAME_LEN_FROM 6 +#define ZT_PROTO_VERB_EXT_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_EXT_FRAME_IDX_FROM + ZT_PROTO_VERB_EXT_FRAME_LEN_FROM) +#define ZT_PROTO_VERB_EXT_FRAME_LEN_ETHERTYPE 2 +#define ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_EXT_FRAME_IDX_ETHERTYPE + ZT_PROTO_VERB_EXT_FRAME_LEN_ETHERTYPE) #define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN + 2) +#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN + 2) -#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS + 1) -#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC + 6) +#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) +#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS + 1) +#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC + 6) #define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI + 4) -#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT + 4) +#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT + 4) // Note: COM, GATHER_LIMIT, and SOURCE_MAC are optional, and so are specified without size -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) #define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GATHER_LIMIT (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC + 6) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI + 4) -#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE + 2) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC + 6) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI + 4) +#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE + 2) -#define ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP (ZT_PROTO_VERB_OK_IDX_PAYLOAD) +#define ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP (ZT_PROTO_VERB_OK_IDX_PAYLOAD) #define ZT_PROTO_VERB_HELLO__OK__IDX_PROTOCOL_VERSION (ZT_PROTO_VERB_HELLO__OK__IDX_TIMESTAMP + 8) -#define ZT_PROTO_VERB_HELLO__OK__IDX_MAJOR_VERSION (ZT_PROTO_VERB_HELLO__OK__IDX_PROTOCOL_VERSION + 1) -#define ZT_PROTO_VERB_HELLO__OK__IDX_MINOR_VERSION (ZT_PROTO_VERB_HELLO__OK__IDX_MAJOR_VERSION + 1) -#define ZT_PROTO_VERB_HELLO__OK__IDX_REVISION (ZT_PROTO_VERB_HELLO__OK__IDX_MINOR_VERSION + 1) +#define ZT_PROTO_VERB_HELLO__OK__IDX_MAJOR_VERSION (ZT_PROTO_VERB_HELLO__OK__IDX_PROTOCOL_VERSION + 1) +#define ZT_PROTO_VERB_HELLO__OK__IDX_MINOR_VERSION (ZT_PROTO_VERB_HELLO__OK__IDX_MAJOR_VERSION + 1) +#define ZT_PROTO_VERB_HELLO__OK__IDX_REVISION (ZT_PROTO_VERB_HELLO__OK__IDX_MINOR_VERSION + 1) #define ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY (ZT_PROTO_VERB_OK_IDX_PAYLOAD) #define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) -#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN + 2) +#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN + 2) -#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) -#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC (ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI (ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC + 6) +#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) +#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC (ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI (ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC + 6) #define ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS (ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI + 4) -#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) -#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID + 8) -#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC + 6) -#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI + 4) +#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) +#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID + 8) +#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC + 6) +#define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI + 4) #define ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS (ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS + 1) // --------------------------------------------------------------------------- @@ -388,9 +386,8 @@ namespace ZeroTier { * For unencrypted packets, MAC is computed on plaintext. Only HELLO is ever * sent in the clear, as it's the "here is my public key" message. */ -class Packet : public Buffer -{ -public: +class Packet : public Buffer { + public: /** * A packet fragment * @@ -417,22 +414,17 @@ public: * receipt to authenticate and decrypt; there is no per-fragment MAC. (But if * fragments are corrupt, the MAC will fail for the whole assembled packet.) */ - class Fragment : public Buffer - { - public: - Fragment() : - Buffer() + class Fragment : public Buffer { + public: + Fragment() : Buffer() { } - template - Fragment(const Buffer &b) : - Buffer(b) + template Fragment(const Buffer& b) : Buffer(b) { } - Fragment(const void *data,unsigned int len) : - Buffer(data,len) + Fragment(const void* data, unsigned int len) : Buffer(data, len) { } @@ -445,9 +437,9 @@ public: * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off) * @param fragTotal Total number of fragments (including 0) */ - Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal) + Fragment(const Packet& p, unsigned int fragStart, unsigned int fragLen, unsigned int fragNo, unsigned int fragTotal) { - init(p,fragStart,fragLen,fragNo,fragTotal); + init(p, fragStart, fragLen, fragNo, fragTotal); } /** @@ -459,7 +451,7 @@ public: * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off) * @param fragTotal Total number of fragments (including 0) */ - inline void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal) + inline void init(const Packet& p, unsigned int fragStart, unsigned int fragLen, unsigned int fragNo, unsigned int fragTotal) { if ((fragStart + fragLen) > p.size()) { throw ZT_EXCEPTION_OUT_OF_BOUNDS; @@ -467,13 +459,13 @@ public: setSize(fragLen + ZT_PROTO_MIN_FRAGMENT_LENGTH); // NOTE: this copies both the IV/packet ID and the destination address. - memcpy(field(ZT_PACKET_FRAGMENT_IDX_PACKET_ID,13),p.field(ZT_PACKET_IDX_IV,13),13); + memcpy(field(ZT_PACKET_FRAGMENT_IDX_PACKET_ID, 13), p.field(ZT_PACKET_IDX_IV, 13), 13); (*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] = ZT_PACKET_FRAGMENT_INDICATOR; (*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO] = (char)(((fragTotal & 0xf) << 4) | (fragNo & 0xf)); (*this)[ZT_PACKET_FRAGMENT_IDX_HOPS] = 0; - memcpy(field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD,fragLen),p.field(fragStart,fragLen),fragLen); + memcpy(field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD, fragLen), p.field(fragStart, fragLen), fragLen); } /** @@ -481,32 +473,50 @@ public: * * @return Destination ZT address */ - inline Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } + inline Address destination() const + { + return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + } /** * @return True if fragment is of a valid length */ - inline bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); } + inline bool lengthValid() const + { + return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); + } /** * @return ID of packet this is a fragment of */ - inline uint64_t packetId() const { return at(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); } + inline uint64_t packetId() const + { + return at(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); + } /** * @return Total number of fragments in packet */ - inline unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); } + inline unsigned int totalFragments() const + { + return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); + } /** * @return Fragment number of this fragment */ - inline unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); } + inline unsigned int fragmentNumber() const + { + return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); + } /** * @return Fragment ZT hop count */ - inline unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); } + inline unsigned int hops() const + { + return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); + } /** * Increment this packet's hop count @@ -519,14 +529,17 @@ public: /** * @return Length of payload in bytes */ - inline unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); } + inline unsigned int payloadLength() const + { + return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); + } /** * @return Raw packet payload */ - inline const unsigned char *payload() const + inline const unsigned char* payload() const { - return field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD,size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD); + return field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD, size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD); } }; @@ -793,12 +806,12 @@ public: * * ERROR response payload: * <[8] 64-bit network ID> - * <[2] 16-bit length of error-related data (optional)> - * <[...] error-related data (optional)> - * - * Error related data is a Dictionary containing things like a URL - * for authentication or a human-readable error message, and is - * optional and may be absent or empty. + * <[2] 16-bit length of error-related data (optional)> + * <[...] error-related data (optional)> + * + * Error related data is a Dictionary containing things like a URL + * for authentication or a human-readable error message, and is + * optional and may be absent or empty. */ VERB_NETWORK_CONFIG_REQUEST = 0x0b, @@ -1056,8 +1069,7 @@ public: /** * Error codes for VERB_ERROR */ - enum ErrorCode - { + enum ErrorCode { /* No error, not actually used in transit */ ERROR_NONE = 0x00, @@ -1085,18 +1097,15 @@ public: /* Multicasts to this group are not wanted */ ERROR_UNWANTED_MULTICAST = 0x08, - /* Network requires external or 2FA authentication (e.g. SSO). */ - ERROR_NETWORK_AUTHENTICATION_REQUIRED = 0x09 + /* Network requires external or 2FA authentication (e.g. SSO). */ + ERROR_NETWORK_AUTHENTICATION_REQUIRED = 0x09 }; - template - Packet(const Buffer &b) : - Buffer(b) + template Packet(const Buffer& b) : Buffer(b) { } - Packet(const void *data,unsigned int len) : - Buffer(data,len) + Packet(const void* data, unsigned int len) : Buffer(data, len) { } @@ -1107,11 +1116,10 @@ public: * Use the header access methods (setDestination() and friends) to fill out * the header. Payload should be appended; initial size is header size. */ - Packet() : - Buffer(ZT_PROTO_MIN_PACKET_LENGTH) + Packet() : Buffer(ZT_PROTO_MIN_PACKET_LENGTH) { - Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); - (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags, cipher ID, and hops + Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8); + (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags, cipher ID, and hops } /** @@ -1123,10 +1131,9 @@ public: * @param prototype Prototype packet * @param dest Destination ZeroTier address for new packet */ - Packet(const Packet &prototype,const Address &dest) : - Buffer(prototype) + Packet(const Packet& prototype, const Address& dest) : Buffer(prototype) { - Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); + Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8); setDestination(dest); } @@ -1137,13 +1144,12 @@ public: * @param source Source ZT address * @param v Verb */ - Packet(const Address &dest,const Address &source,const Verb v) : - Buffer(ZT_PROTO_MIN_PACKET_LENGTH) + Packet(const Address& dest, const Address& source, const Verb v) : Buffer(ZT_PROTO_MIN_PACKET_LENGTH) { - Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); + Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8); setDestination(dest); setSource(source); - (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags and hops + (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags and hops setVerb(v); } @@ -1154,13 +1160,13 @@ public: * @param source Source ZT address * @param v Verb */ - inline void reset(const Address &dest,const Address &source,const Verb v) + inline void reset(const Address& dest, const Address& source, const Verb v) { setSize(ZT_PROTO_MIN_PACKET_LENGTH); - Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); + Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8); setDestination(dest); setSource(source); - (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags, cipher ID, and hops + (*this)[ZT_PACKET_IDX_FLAGS] = 0; // zero flags, cipher ID, and hops setVerb(v); } @@ -1171,45 +1177,66 @@ public: * technically different but otherwise identical copies of the same * packet. */ - inline void newInitializationVector() { Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8); } + inline void newInitializationVector() + { + Utils::getSecureRandom(field(ZT_PACKET_IDX_IV, 8), 8); + } /** * Set this packet's destination * * @param dest ZeroTier address of destination */ - inline void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } + inline void setDestination(const Address& dest) + { + dest.copyTo(field(ZT_PACKET_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + } /** * Set this packet's source * * @param source ZeroTier address of source */ - inline void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } + inline void setSource(const Address& source) + { + source.copyTo(field(ZT_PACKET_IDX_SOURCE, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + } /** * Get this packet's destination * * @return Destination ZT address */ - inline Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } + inline Address destination() const + { + return Address(field(ZT_PACKET_IDX_DEST, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + } /** * Get this packet's source * * @return Source ZT address */ - inline Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } + inline Address source() const + { + return Address(field(ZT_PACKET_IDX_SOURCE, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); + } /** * @return True if packet is of valid length */ - inline bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); } + inline bool lengthValid() const + { + return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); + } /** * @return True if packet is fragmented (expect fragments) */ - inline bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); } + inline bool fragmented() const + { + return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); + } /** * Set this packet's fragmented flag @@ -1220,7 +1247,8 @@ public: { if (f) { (*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_FRAGMENTED; - } else { + } + else { (*this)[ZT_PACKET_IDX_FLAGS] &= (char)(~ZT_PROTO_FLAG_FRAGMENTED); } } @@ -1228,19 +1256,25 @@ public: /** * @return True if compressed (result only valid if unencrypted) */ - inline bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); } + inline bool compressed() const + { + return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); + } /** * @return ZeroTier forwarding hops (0 to 7) */ - inline unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); } + inline unsigned int hops() const + { + return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); + } /** * Increment this packet's hop count */ inline void incrementHops() { - unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS]; + unsigned char& b = (*this)[ZT_PACKET_IDX_FLAGS]; b = (b & 0xf8) | ((b + 1) & 0x07); } @@ -1265,12 +1299,13 @@ public: */ inline void setCipher(unsigned int c) { - unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS]; - b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH + unsigned char& b = (*this)[ZT_PACKET_IDX_FLAGS]; + b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH // Set DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers if (c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) { b |= ZT_PROTO_FLAG_ENCRYPTED; - } else { + } + else { b &= (~ZT_PROTO_FLAG_ENCRYPTED); } } @@ -1280,7 +1315,10 @@ public: * * @return Trusted path ID (from MAC field) */ - inline uint64_t trustedPathId() const { return at(ZT_PACKET_IDX_MAC); } + inline uint64_t trustedPathId() const + { + return at(ZT_PACKET_IDX_MAC); + } /** * Set this packet's trusted path ID and set the cipher spec to trusted path @@ -1290,7 +1328,7 @@ public: inline void setTrusted(const uint64_t tpid) { setCipher(ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH); - setAt(ZT_PACKET_IDX_MAC,tpid); + setAt(ZT_PACKET_IDX_MAC, tpid); } /** @@ -1304,7 +1342,10 @@ public: * * @return Packet ID */ - inline uint64_t packetId() const { return at(ZT_PACKET_IDX_IV); } + inline uint64_t packetId() const + { + return at(ZT_PACKET_IDX_IV); + } /** * Set packet verb @@ -1314,22 +1355,34 @@ public: * * @param v New packet verb */ - inline void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; } + inline void setVerb(Verb v) + { + (*this)[ZT_PACKET_IDX_VERB] = (char)v; + } /** * @return Packet verb (not including flag bits) */ - inline Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); } + inline Verb verb() const + { + return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); + } /** * @return Length of packet payload */ - inline unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); } + inline unsigned int payloadLength() const + { + return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); + } /** * @return Raw packet payload */ - inline const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); } + inline const unsigned char* payload() const + { + return field(ZT_PACKET_IDX_PAYLOAD, size() - ZT_PACKET_IDX_PAYLOAD); + } /** * Armor packet for transport @@ -1338,7 +1391,7 @@ public: * @param encryptPayload If true, encrypt packet payload, else just MAC * @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV */ - void armor(const void *key,bool encryptPayload,const AES aesKeys[2]); + void armor(const void* key, bool encryptPayload, const AES aesKeys[2]); /** * Verify and (if encrypted) decrypt packet @@ -1351,7 +1404,7 @@ public: * @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV * @return False if packet is invalid or failed MAC authenticity check */ - bool dearmor(const void *key,const AES aesKeys[2]); + bool dearmor(const void* key, const AES aesKeys[2]); /** * Encrypt/decrypt a separately armored portion of a packet @@ -1366,7 +1419,7 @@ public: * @param start Start of encrypted portion * @param len Length of encrypted portion */ - void cryptField(const void *key,unsigned int start,unsigned int len); + void cryptField(const void* key, unsigned int start, unsigned int len); /** * Attempt to compress payload if not already (must be unencrypted) @@ -1390,7 +1443,7 @@ public: */ bool uncompress(); -private: + private: static const unsigned char ZERO_KEY[32]; /** @@ -1404,13 +1457,13 @@ private: * @param in Input key (32 bytes) * @param out Output buffer (32 bytes) */ - inline void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const + inline void _salsa20MangleKey(const unsigned char* in, unsigned char* out) const { - const unsigned char *d = (const unsigned char *)data(); + const unsigned char* d = (const unsigned char*)data(); // IV and source/destination addresses. Using the addresses divides the // key space into two halves-- A->B and B->A (since order will change). - for(unsigned int i=0;i<18;++i) { // 8 + (ZT_ADDRESS_LENGTH * 2) == 18 + for (unsigned int i = 0; i < 18; ++i) { // 8 + (ZT_ADDRESS_LENGTH * 2) == 18 out[i] = in[i] ^ d[i]; } @@ -1422,15 +1475,15 @@ private: // Raw packet size in bytes -- thus each packet size defines a new // key space. out[19] = in[19] ^ (unsigned char)(size() & 0xff); - out[20] = in[20] ^ (unsigned char)((size() >> 8) & 0xff); // little endian + out[20] = in[20] ^ (unsigned char)((size() >> 8) & 0xff); // little endian // Rest of raw key is used unchanged - for(unsigned int i=21;i<32;++i) { + for (unsigned int i = 21; i < 32; ++i) { out[i] = in[i]; } } }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/PacketMultiplexer.cpp b/node/PacketMultiplexer.cpp index a1dc835a1..f6f3dc847 100644 --- a/node/PacketMultiplexer.cpp +++ b/node/PacketMultiplexer.cpp @@ -13,9 +13,9 @@ #include "PacketMultiplexer.hpp" +#include "Constants.hpp" #include "Node.hpp" #include "RuntimeEnvironment.hpp" -#include "Constants.hpp" #include #include @@ -30,12 +30,12 @@ PacketMultiplexer::PacketMultiplexer(const RuntimeEnvironment* renv) void PacketMultiplexer::putFrame(void* tPtr, uint64_t nwid, void** nuptr, const MAC& source, const MAC& dest, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len, unsigned int flowId) { #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__WINDOWS__) - RR->node->putFrame(tPtr,nwid,nuptr,source,dest,etherType,vlanId,(const void *)data,len); + RR->node->putFrame(tPtr, nwid, nuptr, source, dest, etherType, vlanId, (const void*)data, len); return; #endif - if (!_enabled) { - RR->node->putFrame(tPtr,nwid,nuptr,source,dest,etherType,vlanId,(const void *)data,len); + if (! _enabled) { + RR->node->putFrame(tPtr, nwid, nuptr, source, dest, etherType, vlanId, (const void*)data, len); return; } diff --git a/node/Path.cpp b/node/Path.cpp index 00ea90f9d..875f05b4a 100644 --- a/node/Path.cpp +++ b/node/Path.cpp @@ -12,18 +12,19 @@ /****/ #include "Path.hpp" -#include "RuntimeEnvironment.hpp" + #include "Node.hpp" +#include "RuntimeEnvironment.hpp" namespace ZeroTier { -bool Path::send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,int64_t now) +bool Path::send(const RuntimeEnvironment* RR, void* tPtr, const void* data, unsigned int len, int64_t now) { - if (RR->node->putPacket(tPtr,_localSocket,_addr,data,len)) { + if (RR->node->putPacket(tPtr, _localSocket, _addr, data, len)) { _lastOut = now; return true; } return false; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index d6167ce84..2639173ee 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -14,20 +14,19 @@ #ifndef ZT_PATH_HPP #define ZT_PATH_HPP -#include -#include -#include - -#include -#include - +#include "AtomicCounter.hpp" #include "Constants.hpp" #include "InetAddress.hpp" -#include "SharedPtr.hpp" -#include "AtomicCounter.hpp" -#include "Utils.hpp" #include "Packet.hpp" #include "RingBuffer.hpp" +#include "SharedPtr.hpp" +#include "Utils.hpp" + +#include +#include +#include +#include +#include /** * Maximum return value of preferenceRank() @@ -41,89 +40,102 @@ class RuntimeEnvironment; /** * A path across the physical network */ -class Path -{ +class Path { friend class SharedPtr; friend class Bond; -public: + public: /** * Efficient unique key for paths in a Hashtable */ - class HashKey - { - public: - HashKey() {} + class HashKey { + public: + HashKey() + { + } - HashKey(const int64_t l,const InetAddress &r) + HashKey(const int64_t l, const InetAddress& r) { if (r.ss_family == AF_INET) { - _k[0] = (uint64_t)reinterpret_cast(&r)->sin_addr.s_addr; - _k[1] = (uint64_t)reinterpret_cast(&r)->sin_port; + _k[0] = (uint64_t)reinterpret_cast(&r)->sin_addr.s_addr; + _k[1] = (uint64_t)reinterpret_cast(&r)->sin_port; _k[2] = (uint64_t)l; - } else if (r.ss_family == AF_INET6) { - memcpy(_k,reinterpret_cast(&r)->sin6_addr.s6_addr,16); - _k[2] = ((uint64_t)reinterpret_cast(&r)->sin6_port << 32) ^ (uint64_t)l; - } else { - memcpy(_k,&r,std::min(sizeof(_k),sizeof(InetAddress))); + } + else if (r.ss_family == AF_INET6) { + memcpy(_k, reinterpret_cast(&r)->sin6_addr.s6_addr, 16); + _k[2] = ((uint64_t)reinterpret_cast(&r)->sin6_port << 32) ^ (uint64_t)l; + } + else { + memcpy(_k, &r, std::min(sizeof(_k), sizeof(InetAddress))); _k[2] += (uint64_t)l; } } - inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); } + inline unsigned long hashCode() const + { + return (unsigned long)(_k[0] + _k[1] + _k[2]); + } - inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); } - inline bool operator!=(const HashKey &k) const { return (!(*this == k)); } + inline bool operator==(const HashKey& k) const + { + return ((_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2])); + } + inline bool operator!=(const HashKey& k) const + { + return (! (*this == k)); + } - private: + private: uint64_t _k[3]; }; - Path() : - _lastOut(0), - _lastIn(0), - _lastTrustEstablishedPacketReceived(0), - _lastEchoRequestReceived(0), - _localPort(0), - _localSocket(-1), - _latencyMean(0.0), - _latencyVariance(0.0), - _packetLossRatio(0.0), - _packetErrorRatio(0.0), - _assignedFlowCount(0), - _valid(true), - _eligible(false), - _bonded(false), - _mtu(0), - _givenLinkSpeed(0), - _relativeQuality(0), - _latency(0xffff), - _addr(), - _ipScope(InetAddress::IP_SCOPE_NONE) - {} + Path() + : _lastOut(0) + , _lastIn(0) + , _lastTrustEstablishedPacketReceived(0) + , _lastEchoRequestReceived(0) + , _localPort(0) + , _localSocket(-1) + , _latencyMean(0.0) + , _latencyVariance(0.0) + , _packetLossRatio(0.0) + , _packetErrorRatio(0.0) + , _assignedFlowCount(0) + , _valid(true) + , _eligible(false) + , _bonded(false) + , _mtu(0) + , _givenLinkSpeed(0) + , _relativeQuality(0) + , _latency(0xffff) + , _addr() + , _ipScope(InetAddress::IP_SCOPE_NONE) + { + } - Path(const int64_t localSocket,const InetAddress &addr) : - _lastOut(0), - _lastIn(0), - _lastTrustEstablishedPacketReceived(0), - _lastEchoRequestReceived(0), - _localPort(0), - _localSocket(localSocket), - _latencyMean(0.0), - _latencyVariance(0.0), - _packetLossRatio(0.0), - _packetErrorRatio(0.0), - _assignedFlowCount(0), - _valid(true), - _eligible(false), - _bonded(false), - _mtu(0), - _givenLinkSpeed(0), - _relativeQuality(0), - _latency(0xffff), - _addr(addr), - _ipScope(addr.ipScope()) - {} + Path(const int64_t localSocket, const InetAddress& addr) + : _lastOut(0) + , _lastIn(0) + , _lastTrustEstablishedPacketReceived(0) + , _lastEchoRequestReceived(0) + , _localPort(0) + , _localSocket(localSocket) + , _latencyMean(0.0) + , _latencyVariance(0.0) + , _packetLossRatio(0.0) + , _packetErrorRatio(0.0) + , _assignedFlowCount(0) + , _valid(true) + , _eligible(false) + , _bonded(false) + , _mtu(0) + , _givenLinkSpeed(0) + , _relativeQuality(0) + , _latency(0xffff) + , _addr(addr) + , _ipScope(addr.ipScope()) + { + } /** * Called when a packet is received from this remote path, regardless of content @@ -138,7 +150,10 @@ public: /** * Set time last trusted packet was received (done in Peer::received()) */ - inline void trustedPacketReceived(const uint64_t t) { _lastTrustEstablishedPacketReceived = t; } + inline void trustedPacketReceived(const uint64_t t) + { + _lastTrustEstablishedPacketReceived = t; + } /** * Send a packet via this path (last out time is also updated) @@ -150,14 +165,17 @@ public: * @param now Current time * @return True if transport reported success */ - bool send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,int64_t now); + bool send(const RuntimeEnvironment* RR, void* tPtr, const void* data, unsigned int len, int64_t now); /** * Manually update last sent time * * @param t Time of send */ - inline void sent(const int64_t t) { _lastOut = t; } + inline void sent(const int64_t t) + { + _lastOut = t; + } /** * Update path latency with a new measurement @@ -169,7 +187,8 @@ public: unsigned int pl = _latency; if (pl < 0xffff) { _latency = (pl + l) / 2; - } else { + } + else { _latency = l; } } @@ -177,27 +196,42 @@ public: /** * @return Local socket as specified by external code */ - inline int64_t localSocket() const { return _localSocket; } + inline int64_t localSocket() const + { + return _localSocket; + } /** * @return Local port corresponding to the localSocket */ - inline int64_t localPort() const { return _localPort; } + inline int64_t localPort() const + { + return _localPort; + } /** * @return Physical address */ - inline const InetAddress &address() const { return _addr; } + inline const InetAddress& address() const + { + return _addr; + } /** * @return IP scope -- faster shortcut for address().ipScope() */ - inline InetAddress::IpScope ipScope() const { return _ipScope; } + inline InetAddress::IpScope ipScope() const + { + return _ipScope; + } /** * @return True if path has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms */ - inline bool trustEstablished(const int64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); } + inline bool trustEstablished(const int64_t now) const + { + return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); + } /** * @return Preference rank, higher == better @@ -206,7 +240,7 @@ public: { // This causes us to rank paths in order of IP scope rank (see InetAddress.hpp) but // within each IP scope class to prefer IPv6 over IPv4. - return ( ((unsigned int)_ipScope << 1) | (unsigned int)(_addr.ss_family == AF_INET6) ); + return (((unsigned int)_ipScope << 1) | (unsigned int)(_addr.ss_family == AF_INET6)); } /** @@ -218,10 +252,10 @@ public: * @param a Address to check * @return True if address is good for ZeroTier path use */ - static inline bool isAddressValidForPath(const InetAddress &a) + static inline bool isAddressValidForPath(const InetAddress& a) { - if ((a.ss_family == AF_INET)||(a.ss_family == AF_INET6)) { - switch(a.ipScope()) { + if ((a.ss_family == AF_INET) || (a.ss_family == AF_INET6)) { + switch (a.ipScope()) { /* Note: we don't do link-local at the moment. Unfortunately these * cause several issues. The first is that they usually require a * device qualifier, which we don't handle yet and can't portably @@ -237,8 +271,8 @@ public: // TEMPORARY HACK: for now, we are going to blacklist he.net IPv6 // tunnels due to very spotty performance and low MTU issues over // these IPv6 tunnel links. - const uint8_t *ipd = reinterpret_cast(reinterpret_cast(&a)->sin6_addr.s6_addr); - if ((ipd[0] == 0x20)&&(ipd[1] == 0x01)&&(ipd[2] == 0x04)&&(ipd[3] == 0x70)) { + const uint8_t* ipd = reinterpret_cast(reinterpret_cast(&a)->sin6_addr.s6_addr); + if ((ipd[0] == 0x20) && (ipd[1] == 0x01) && (ipd[2] == 0x04) && (ipd[3] == 0x70)) { return false; } } @@ -253,7 +287,10 @@ public: /** * @return Latency or 0xffff if unknown */ - inline unsigned int latency() const { return _latency; } + inline unsigned int latency() const + { + return _latency; + } /** * @return Path quality -- lower is better @@ -261,41 +298,57 @@ public: inline long quality(const int64_t now) const { const int l = (long)_latency; - const int age = (long)std::min((now - _lastIn),(int64_t)(ZT_PATH_HEARTBEAT_PERIOD * 10)); // set an upper sanity limit to avoid overflow + const int age = (long)std::min((now - _lastIn), (int64_t)(ZT_PATH_HEARTBEAT_PERIOD * 10)); // set an upper sanity limit to avoid overflow return (((age < (ZT_PATH_HEARTBEAT_PERIOD + 5000)) ? l : (l + 0xffff + age)) * (long)((ZT_INETADDRESS_MAX_SCOPE - _ipScope) + 1)); } /** * @return True if this path is alive (receiving heartbeats) */ - inline bool alive(const int64_t now) const { + inline bool alive(const int64_t now) const + { return (now - _lastIn) < (ZT_PATH_HEARTBEAT_PERIOD + 5000); } /** * @return True if this path needs a heartbeat */ - inline bool needsHeartbeat(const int64_t now) const { return ((now - _lastOut) >= ZT_PATH_HEARTBEAT_PERIOD); } + inline bool needsHeartbeat(const int64_t now) const + { + return ((now - _lastOut) >= ZT_PATH_HEARTBEAT_PERIOD); + } /** * @return Last time we sent something */ - inline int64_t lastOut() const { return _lastOut; } + inline int64_t lastOut() const + { + return _lastOut; + } /** * @return Last time we received anything */ - inline int64_t lastIn() const { return _lastIn; } + inline int64_t lastIn() const + { + return _lastIn; + } /** * @return the age of the path in terms of receiving packets */ - inline int64_t age(int64_t now) { return (now - _lastIn); } + inline int64_t age(int64_t now) + { + return (now - _lastIn); + } /** * @return Time last trust-established packet was received */ - inline int64_t lastTrustEstablishedPacketReceived() const { return _lastTrustEstablishedPacketReceived; } + inline int64_t lastTrustEstablishedPacketReceived() const + { + return _lastTrustEstablishedPacketReceived; + } /** * Rate limit gate for inbound ECHO requests @@ -312,69 +365,102 @@ public: /** * @return Mean latency as reported by the bonding layer */ - inline float latencyMean() const { return _latencyMean; } + inline float latencyMean() const + { + return _latencyMean; + } /** * @return Latency variance as reported by the bonding layer */ - inline float latencyVariance() const { return _latencyVariance; } + inline float latencyVariance() const + { + return _latencyVariance; + } /** * @return Packet Loss Ratio as reported by the bonding layer */ - inline float packetLossRatio() const { return _packetLossRatio; } + inline float packetLossRatio() const + { + return _packetLossRatio; + } /** * @return Packet Error Ratio as reported by the bonding layer */ - inline float packetErrorRatio() const { return _packetErrorRatio; } + inline float packetErrorRatio() const + { + return _packetErrorRatio; + } /** * @return Number of flows assigned to this path */ - inline unsigned int assignedFlowCount() const { return _assignedFlowCount; } + inline unsigned int assignedFlowCount() const + { + return _assignedFlowCount; + } /** * @return Whether this path is valid as reported by the bonding layer. The bonding layer * actually checks with Phy to see if the interface is still up */ - inline bool valid() const { return _valid; } + inline bool valid() const + { + return _valid; + } /** * @return Whether this path is eligible for use in a bond as reported by the bonding layer */ - inline bool eligible() const { return _eligible; } + inline bool eligible() const + { + return _eligible; + } /** * @return Whether this path is bonded as reported by the bonding layer */ - inline bool bonded() const { return _bonded; } + inline bool bonded() const + { + return _bonded; + } /** * @return Whether the user-specified MTU for this path (determined by MTU for parent link) */ - inline uint16_t mtu() const { return _mtu; } + inline uint16_t mtu() const + { + return _mtu; + } /** * @return Given link capacity as reported by the bonding layer */ - inline uint32_t givenLinkSpeed() const { return _givenLinkSpeed; } + inline uint32_t givenLinkSpeed() const + { + return _givenLinkSpeed; + } /** * @return Path's quality as reported by the bonding layer */ - inline float relativeQuality() const { return _relativeQuality; } + inline float relativeQuality() const + { + return _relativeQuality; + } /** * @return Physical interface name that this path lives on */ - char *ifname() { + char* ifname() + { return _ifname; } -private: - - char _ifname[ZT_MAX_PHYSIFNAME] = { }; + private: + char _ifname[ZT_MAX_PHYSIFNAME] = {}; volatile int64_t _lastOut; volatile int64_t _lastIn; @@ -399,10 +485,10 @@ private: volatile unsigned int _latency; InetAddress _addr; - InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often + InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often AtomicCounter __refCount; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Peer.cpp b/node/Peer.cpp index f77b4e6fd..ec8521c4b 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -11,24 +11,25 @@ */ /****/ +#include "Peer.hpp" + #include "../version.h" #include "Constants.hpp" -#include "Peer.hpp" -#include "Switch.hpp" -#include "Network.hpp" -#include "SelfAwareness.hpp" -#include "Packet.hpp" -#include "Trace.hpp" #include "InetAddress.hpp" -#include "RingBuffer.hpp" -#include "Utils.hpp" #include "Metrics.hpp" +#include "Network.hpp" +#include "Packet.hpp" +#include "RingBuffer.hpp" +#include "SelfAwareness.hpp" +#include "Switch.hpp" +#include "Trace.hpp" +#include "Utils.hpp" namespace ZeroTier { static unsigned char s_freeRandomByteCounter = 0; -Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Identity &peerIdentity) +Peer::Peer(const RuntimeEnvironment* renv, const Identity& myIdentity, const Identity& peerIdentity) : RR(renv) , _lastReceive(0) , _lastNontrivialReceive(0) @@ -52,29 +53,29 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident , _localMultipathSupported(false) , _lastComputedAggregateMeanLatency(0) #ifndef ZT_NO_PEER_METRICS - , _peer_latency{Metrics::peer_latency.Add({{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())}}, std::vector{1,3,6,10,30,60,100,300,600,1000})} - , _alive_path_count{Metrics::peer_path_count.Add({{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())},{"status","alive"}})} - , _dead_path_count{Metrics::peer_path_count.Add({{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())},{"status","dead"}})} - , _incoming_packet{Metrics::peer_packets.Add({{"direction", "rx"},{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())}})} - , _outgoing_packet{Metrics::peer_packets.Add({{"direction", "tx"},{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())}})} - , _packet_errors{Metrics::peer_packet_errors.Add({{"node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt())}})} + , _peer_latency { Metrics::peer_latency.Add({ { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) } }, std::vector { 1, 3, 6, 10, 30, 60, 100, 300, 600, 1000 }) } + , _alive_path_count { Metrics::peer_path_count.Add({ { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) }, { "status", "alive" } }) } + , _dead_path_count { Metrics::peer_path_count.Add({ { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) }, { "status", "dead" } }) } + , _incoming_packet { Metrics::peer_packets.Add({ { "direction", "rx" }, { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) } }) } + , _outgoing_packet { Metrics::peer_packets.Add({ { "direction", "tx" }, { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) } }) } + , _packet_errors { Metrics::peer_packet_errors.Add({ { "node_id", OSUtils::nodeIDStr(peerIdentity.address().toInt()) } }) } #endif { - if (!myIdentity.agree(peerIdentity,_key)) { + if (! myIdentity.agree(peerIdentity, _key)) { throw ZT_EXCEPTION_INVALID_ARGUMENT; } uint8_t ktmp[ZT_SYMMETRIC_KEY_SIZE]; - KBKDFHMACSHA384(_key,ZT_KBKDF_LABEL_AES_GMAC_SIV_K0,0,0,ktmp); + KBKDFHMACSHA384(_key, ZT_KBKDF_LABEL_AES_GMAC_SIV_K0, 0, 0, ktmp); _aesKeys[0].init(ktmp); - KBKDFHMACSHA384(_key,ZT_KBKDF_LABEL_AES_GMAC_SIV_K1,0,0,ktmp); + KBKDFHMACSHA384(_key, ZT_KBKDF_LABEL_AES_GMAC_SIV_K1, 0, 0, ktmp); _aesKeys[1].init(ktmp); - Utils::burn(ktmp,ZT_SYMMETRIC_KEY_SIZE); + Utils::burn(ktmp, ZT_SYMMETRIC_KEY_SIZE); } void Peer::received( - void *tPtr, - const SharedPtr &path, + void* tPtr, + const SharedPtr& path, const unsigned int hops, const uint64_t packetId, const unsigned int payloadLength, @@ -114,7 +115,7 @@ void Peer::received( bool havePath = false; { Mutex::Lock _l(_paths_m); - for(unsigned int i=0;iaddress().ipsEqual(path->address()) && _paths[i].p->localSocket() == path->localSocket()) { - if (_paths[i].p->alive(now) && !_bond) { + if (_paths[i].p->alive(now) && ! _bond) { havePath = true; break; } } - } else { + } + else { break; } } } - if ( (!havePath) && RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localSocket(),path->address()) ) { + if ((! havePath) && RR->node->shouldUsePathForZeroTierTraffic(tPtr, _id.address(), path->localSocket(), path->address())) { if (verb == Packet::VERB_OK) { Mutex::Lock _l(_paths_m); unsigned int oldestPathIdx = ZT_MAX_PEER_NETWORK_PATHS; unsigned int oldestPathAge = 0; unsigned int replacePath = ZT_MAX_PEER_NETWORK_PATHS; - for(unsigned int i=0;iage(now); @@ -151,13 +153,14 @@ void Peer::received( } if (_paths[i].p->address().ipsEqual(path->address())) { if (_paths[i].p->localSocket() == path->localSocket()) { - if (!_paths[i].p->alive(now)) { + if (! _paths[i].p->alive(now)) { replacePath = i; break; } } } - } else { + } + else { replacePath = i; break; } @@ -171,30 +174,33 @@ void Peer::received( _paths[replacePath].p = path; _paths[replacePath].priority = 1; Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { _bond->nominatePathToBond(_paths[replacePath].p, now); } } - } else { + } + else { Mutex::Lock ltl(_lastTriedPath_m); bool triedTooRecently = false; - for(std::list< std::pair< Path *, int64_t > >::iterator i(_lastTriedPath.begin());i!=_lastTriedPath.end();) { + for (std::list >::iterator i(_lastTriedPath.begin()); i != _lastTriedPath.end();) { if ((now - i->second) > 1000) { _lastTriedPath.erase(i++); - } else if (i->first == path.ptr()) { + } + else if (i->first == path.ptr()) { ++i; triedTooRecently = true; - } else { + } + else { ++i; } } - if (!triedTooRecently) { - _lastTriedPath.push_back(std::pair< Path *, int64_t >(path.ptr(), now)); - attemptToContactAt(tPtr,path->localSocket(),path->address(),now,true); + if (! triedTooRecently) { + _lastTriedPath.push_back(std::pair(path.ptr(), now)); + attemptToContactAt(tPtr, path->localSocket(), path->address(), now, true); path->sent(now); - RR->t->peerConfirmingUnknownPath(tPtr,networkId,*this,path,packetId,verb); + RR->t->peerConfirmingUnknownPath(tPtr, networkId, *this, path, packetId, verb); } } } @@ -212,30 +218,30 @@ void Peer::received( std::vector pathsToPush(RR->node->directPaths()); std::vector ma = RR->sa->whoami(); pathsToPush.insert(pathsToPush.end(), ma.begin(), ma.end()); - if (!pathsToPush.empty()) { + if (! pathsToPush.empty()) { std::vector::const_iterator p(pathsToPush.begin()); while (p != pathsToPush.end()) { - Packet *const outp = new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); - outp->addSize(2); // leave room for count + Packet* const outp = new Packet(_id.address(), RR->identity.address(), Packet::VERB_PUSH_DIRECT_PATHS); + outp->addSize(2); // leave room for count unsigned int count = 0; - while ((p != pathsToPush.end())&&((outp->size() + 24) < 1200)) { + while ((p != pathsToPush.end()) && ((outp->size() + 24) < 1200)) { uint8_t addressType = 4; - switch(p->ss_family) { + switch (p->ss_family) { case AF_INET: break; case AF_INET6: addressType = 6; break; - default: // we currently only push IP addresses + default: // we currently only push IP addresses ++p; continue; } - outp->append((uint8_t)0); // no flags - outp->append((uint16_t)0); // no extensions + outp->append((uint8_t)0); // no flags + outp->append((uint16_t)0); // no extensions outp->append(addressType); outp->append((uint8_t)((addressType == 4) ? 6 : 18)); - outp->append(p->rawIpData(),((addressType == 4) ? 4 : 16)); + outp->append(p->rawIpData(), ((addressType == 4) ? 4 : 16)); outp->append((uint16_t)p->port()); ++count; @@ -243,11 +249,11 @@ void Peer::received( } if (count) { Metrics::pkt_push_direct_paths_out++; - outp->setAt(ZT_PACKET_IDX_PAYLOAD,(uint16_t)count); + outp->setAt(ZT_PACKET_IDX_PAYLOAD, (uint16_t)count); outp->compress(); - outp->armor(_key,true,aesKeysIfSupported()); + outp->armor(_key, true, aesKeysIfSupported()); Metrics::pkt_push_direct_paths_out++; - path->send(RR,tPtr,outp->data(),outp->size(),now); + path->send(RR, tPtr, outp->data(), outp->size(), now); } delete outp; } @@ -260,7 +266,7 @@ SharedPtr Peer::getAppropriatePath(int64_t now, bool includeExpired, int32 { Mutex::Lock _l(_paths_m); Mutex::Lock _lb(_bond_m); - if(_bond && _bond->isReady()) { + if (_bond && _bond->isReady()) { return _bond->getAppropriatePath(now, flowId); } unsigned int bestPath = ZT_MAX_PEER_NETWORK_PATHS; @@ -269,16 +275,17 @@ SharedPtr Peer::getAppropriatePath(int64_t now, bool includeExpired, int32 * use the old path quality metric from protocol version 9. */ long bestPathQuality = 2147483647; - for(unsigned int i=0;iquality(now) / _paths[i].priority; if (q <= bestPathQuality) { bestPathQuality = q; bestPath = i; } } - } else { + } + else { break; } } @@ -288,17 +295,17 @@ SharedPtr Peer::getAppropriatePath(int64_t now, bool includeExpired, int32 return SharedPtr(); } -void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &other) const +void Peer::introduce(void* const tPtr, const int64_t now, const SharedPtr& other) const { - unsigned int myBestV4ByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - unsigned int myBestV6ByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - long myBestV4QualityByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - long myBestV6QualityByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - unsigned int theirBestV4ByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - unsigned int theirBestV6ByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - long theirBestV4QualityByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - long theirBestV6QualityByScope[ZT_INETADDRESS_MAX_SCOPE+1]; - for(int i=0;i<=ZT_INETADDRESS_MAX_SCOPE;++i) { + unsigned int myBestV4ByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + unsigned int myBestV6ByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + long myBestV4QualityByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + long myBestV6QualityByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + unsigned int theirBestV4ByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + unsigned int theirBestV6ByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + long theirBestV4QualityByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + long theirBestV6QualityByScope[ZT_INETADDRESS_MAX_SCOPE + 1]; + for (int i = 0; i <= ZT_INETADDRESS_MAX_SCOPE; ++i) { myBestV4ByScope[i] = ZT_MAX_PEER_NETWORK_PATHS; myBestV6ByScope[i] = ZT_MAX_PEER_NETWORK_PATHS; myBestV4QualityByScope[i] = 2147483647; @@ -311,11 +318,11 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &o Mutex::Lock _l1(_paths_m); - for(unsigned int i=0;iquality(now) / _paths[i].priority; const unsigned int s = (unsigned int)_paths[i].p->ipScope(); - switch(_paths[i].p->address().ss_family) { + switch (_paths[i].p->address().ss_family) { case AF_INET: if (q <= myBestV4QualityByScope[s]) { myBestV4QualityByScope[s] = q; @@ -329,18 +336,19 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &o } break; } - } else { + } + else { break; } } Mutex::Lock _l2(other->_paths_m); - for(unsigned int i=0;i_paths[i].p) { const long q = other->_paths[i].p->quality(now) / other->_paths[i].priority; const unsigned int s = (unsigned int)other->_paths[i].p->ipScope(); - switch(other->_paths[i].p->address().ss_family) { + switch (other->_paths[i].p->address().ss_family) { case AF_INET: if (q <= theirBestV4QualityByScope[s]) { theirBestV4QualityByScope[s] = q; @@ -354,7 +362,8 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &o } break; } - } else { + } + else { break; } } @@ -362,13 +371,13 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &o unsigned int mine = ZT_MAX_PEER_NETWORK_PATHS; unsigned int theirs = ZT_MAX_PEER_NETWORK_PATHS; - for(int s=ZT_INETADDRESS_MAX_SCOPE;s>=0;--s) { - if ((myBestV6ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)&&(theirBestV6ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)) { + for (int s = ZT_INETADDRESS_MAX_SCOPE; s >= 0; --s) { + if ((myBestV6ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS) && (theirBestV6ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)) { mine = myBestV6ByScope[s]; theirs = theirBestV6ByScope[s]; break; } - if ((myBestV4ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)&&(theirBestV4ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)) { + if ((myBestV4ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS) && (theirBestV4ByScope[s] != ZT_MAX_PEER_NETWORK_PATHS)) { mine = myBestV4ByScope[s]; theirs = theirBestV4ByScope[s]; break; @@ -376,55 +385,58 @@ void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &o } if (mine != ZT_MAX_PEER_NETWORK_PATHS) { - unsigned int alt = (unsigned int)RR->node->prng() & 1; // randomize which hint we send first for black magickal NAT-t reasons + unsigned int alt = (unsigned int)RR->node->prng() & 1; // randomize which hint we send first for black magickal NAT-t reasons const unsigned int completed = alt + 2; while (alt != completed) { if ((alt & 1) == 0) { - Packet outp(_id.address(),RR->identity.address(),Packet::VERB_RENDEZVOUS); + Packet outp(_id.address(), RR->identity.address(), Packet::VERB_RENDEZVOUS); outp.append((uint8_t)0); other->_id.address().appendTo(outp); outp.append((uint16_t)other->_paths[theirs].p->address().port()); if (other->_paths[theirs].p->address().ss_family == AF_INET6) { outp.append((uint8_t)16); - outp.append(other->_paths[theirs].p->address().rawIpData(),16); - } else { - outp.append((uint8_t)4); - outp.append(other->_paths[theirs].p->address().rawIpData(),4); + outp.append(other->_paths[theirs].p->address().rawIpData(), 16); } - outp.armor(_key,true,aesKeysIfSupported()); + else { + outp.append((uint8_t)4); + outp.append(other->_paths[theirs].p->address().rawIpData(), 4); + } + outp.armor(_key, true, aesKeysIfSupported()); Metrics::pkt_rendezvous_out++; - _paths[mine].p->send(RR,tPtr,outp.data(),outp.size(),now); - } else { - Packet outp(other->_id.address(),RR->identity.address(),Packet::VERB_RENDEZVOUS); + _paths[mine].p->send(RR, tPtr, outp.data(), outp.size(), now); + } + else { + Packet outp(other->_id.address(), RR->identity.address(), Packet::VERB_RENDEZVOUS); outp.append((uint8_t)0); _id.address().appendTo(outp); outp.append((uint16_t)_paths[mine].p->address().port()); if (_paths[mine].p->address().ss_family == AF_INET6) { outp.append((uint8_t)16); - outp.append(_paths[mine].p->address().rawIpData(),16); - } else { - outp.append((uint8_t)4); - outp.append(_paths[mine].p->address().rawIpData(),4); + outp.append(_paths[mine].p->address().rawIpData(), 16); } - outp.armor(other->_key,true,other->aesKeysIfSupported()); + else { + outp.append((uint8_t)4); + outp.append(_paths[mine].p->address().rawIpData(), 4); + } + outp.armor(other->_key, true, other->aesKeysIfSupported()); Metrics::pkt_rendezvous_out++; - other->_paths[theirs].p->send(RR,tPtr,outp.data(),outp.size(),now); + other->_paths[theirs].p->send(RR, tPtr, outp.data(), outp.size(), now); } ++alt; } } } -void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now) +void Peer::sendHELLO(void* tPtr, const int64_t localSocket, const InetAddress& atAddress, int64_t now) { - Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); + Packet outp(_id.address(), RR->identity.address(), Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); outp.append(now); - RR->identity.serialize(outp,false); + RR->identity.serialize(outp, false); atAddress.serialize(outp); outp.append((uint64_t)RR->topology->planetWorldId()); @@ -435,56 +447,58 @@ void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atA std::vector moons(RR->topology->moons()); std::vector moonsWanted(RR->topology->moonsWanted()); outp.append((uint16_t)(moons.size() + moonsWanted.size())); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { + for (std::vector::const_iterator m(moons.begin()); m != moons.end(); ++m) { outp.append((uint8_t)m->type()); outp.append((uint64_t)m->id()); outp.append((uint64_t)m->timestamp()); } - for(std::vector::const_iterator m(moonsWanted.begin());m!=moonsWanted.end();++m) { + for (std::vector::const_iterator m(moonsWanted.begin()); m != moonsWanted.end(); ++m) { outp.append((uint8_t)World::TYPE_MOON); outp.append(*m); outp.append((uint64_t)0); } - outp.cryptField(_key,startCryptedPortionAt,outp.size() - startCryptedPortionAt); + outp.cryptField(_key, startCryptedPortionAt, outp.size() - startCryptedPortionAt); Metrics::pkt_hello_out++; if (atAddress) { - outp.armor(_key,false,nullptr); // false == don't encrypt full payload, but add MAC + outp.armor(_key, false, nullptr); // false == don't encrypt full payload, but add MAC RR->node->expectReplyTo(outp.packetId()); - RR->node->putPacket(tPtr,RR->node->lowBandwidthModeEnabled() ? localSocket : -1,atAddress,outp.data(),outp.size()); - } else { + RR->node->putPacket(tPtr, RR->node->lowBandwidthModeEnabled() ? localSocket : -1, atAddress, outp.data(), outp.size()); + } + else { RR->node->expectReplyTo(outp.packetId()); - RR->sw->send(tPtr,outp,false); // false == don't encrypt full payload, but add MAC + RR->sw->send(tPtr, outp, false); // false == don't encrypt full payload, but add MAC } } -void Peer::attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now,bool sendFullHello) +void Peer::attemptToContactAt(void* tPtr, const int64_t localSocket, const InetAddress& atAddress, int64_t now, bool sendFullHello) { - if ( (!sendFullHello) && (_vProto >= 5) && (!((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0))) ) { - Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO); - outp.armor(_key,true,aesKeysIfSupported()); + if ((! sendFullHello) && (_vProto >= 5) && (! ((_vMajor == 1) && (_vMinor == 1) && (_vRevision == 0)))) { + Packet outp(_id.address(), RR->identity.address(), Packet::VERB_ECHO); + outp.armor(_key, true, aesKeysIfSupported()); Metrics::pkt_echo_out++; RR->node->expectReplyTo(outp.packetId()); - RR->node->putPacket(tPtr,localSocket,atAddress,outp.data(),outp.size()); - } else { - sendHELLO(tPtr,localSocket,atAddress,now); + RR->node->putPacket(tPtr, localSocket, atAddress, outp.data(), outp.size()); + } + else { + sendHELLO(tPtr, localSocket, atAddress, now); } } -void Peer::tryMemorizedPath(void *tPtr,int64_t now) +void Peer::tryMemorizedPath(void* tPtr, int64_t now) { if ((now - _lastTriedMemorizedPath) >= ZT_TRY_MEMORIZED_PATH_INTERVAL) { _lastTriedMemorizedPath = now; InetAddress mp; - if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp)) { - attemptToContactAt(tPtr,-1,mp,now,true); + if (RR->node->externalPathLookup(tPtr, _id.address(), -1, mp)) { + attemptToContactAt(tPtr, -1, mp, now, true); } } } -void Peer::performMultipathStateCheck(void *tPtr, int64_t now) +void Peer::performMultipathStateCheck(void* tPtr, int64_t now) { Mutex::Lock _l(_bond_m); /** @@ -493,9 +507,9 @@ void Peer::performMultipathStateCheck(void *tPtr, int64_t now) */ int numAlivePaths = 0; bool atLeastOneNonExpired = false; - for(unsigned int i=0;ialive(now)) { + if (_paths[i].p->alive(now)) { numAlivePaths++; } if ((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION) { @@ -504,21 +518,21 @@ void Peer::performMultipathStateCheck(void *tPtr, int64_t now) } } if (_bond) { - if (numAlivePaths == 0 && !atLeastOneNonExpired) { + if (numAlivePaths == 0 && ! atLeastOneNonExpired) { _bond = SharedPtr(); RR->bc->destroyBond(_id.address().toInt()); } return; } _localMultipathSupported = ((numAlivePaths >= 1) && (RR->bc->inUse()) && (ZT_PROTO_VERSION > 9)); - if (_localMultipathSupported && !_bond) { + if (_localMultipathSupported && ! _bond) { if (RR->bc) { _bond = RR->bc->createBond(RR, this); /** * Allow new bond to retroactively learn all paths known to this peer */ if (_bond) { - for (unsigned int i=0;inominatePathToBond(_paths[i].p, now); } @@ -528,7 +542,7 @@ void Peer::performMultipathStateCheck(void *tPtr, int64_t now) } } -unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now) +unsigned int Peer::doPingAndKeepalive(void* tPtr, int64_t now) { unsigned int sent = 0; { @@ -546,31 +560,33 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now) // redirects us its redirect target links override all other links and we // let those old links expire. long maxPriority = 0; - for(unsigned int i=0;ineedsHeartbeat(now))) { - attemptToContactAt(tPtr,_paths[i].p->localSocket(),_paths[i].p->address(),now,sendFullHello); + if (((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION) && (_paths[i].priority == maxPriority)) { + if ((sendFullHello) || (_paths[i].p->needsHeartbeat(now))) { + attemptToContactAt(tPtr, _paths[i].p->localSocket(), _paths[i].p->address(), now, sendFullHello); _paths[i].p->sent(now); sent |= (_paths[i].p->address().ss_family == AF_INET) ? 0x1 : 0x2; } - } else { + } + else { _paths[i] = _PeerPath(); deletionOccurred = true; } } - if (!_paths[i].p || deletionOccurred) { - for(unsigned int j=i;jalive(now)) { alive_path_count_tmp++; @@ -602,25 +618,26 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now) return sent; } -void Peer::clusterRedirect(void *tPtr,const SharedPtr &originatingPath,const InetAddress &remoteAddress,const int64_t now) +void Peer::clusterRedirect(void* tPtr, const SharedPtr& originatingPath, const InetAddress& remoteAddress, const int64_t now) { - SharedPtr np(RR->topology->getPath(originatingPath->localSocket(),remoteAddress)); - RR->t->peerRedirected(tPtr,0,*this,np); + SharedPtr np(RR->topology->getPath(originatingPath->localSocket(), remoteAddress)); + RR->t->peerRedirected(tPtr, 0, *this, np); - attemptToContactAt(tPtr,originatingPath->localSocket(),remoteAddress,now,true); + attemptToContactAt(tPtr, originatingPath->localSocket(), remoteAddress, now, true); { Mutex::Lock _l(_paths_m); // New priority is higher than the priority of the originating path (if known) long newPriority = 1; - for(unsigned int i=0;i &originatingPath,con // Erase any paths with lower priority than this one or that are duplicate // IPs and add this path. unsigned int j = 0; - for(unsigned int i=0;i= newPriority)&&(!_paths[i].p->address().ipsEqual2(remoteAddress))) { + if ((_paths[i].priority >= newPriority) && (! _paths[i].p->address().ipsEqual2(remoteAddress))) { if (i != j) { _paths[j] = _paths[i]; } @@ -654,24 +671,24 @@ void Peer::clusterRedirect(void *tPtr,const SharedPtr &originatingPath,con } } -void Peer::resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,int64_t now) +void Peer::resetWithinScope(void* tPtr, InetAddress::IpScope scope, int inetAddressFamily, int64_t now) { Mutex::Lock _l(_paths_m); - for(unsigned int i=0;iaddress().ss_family == inetAddressFamily)&&(_paths[i].p->ipScope() == scope)) { - attemptToContactAt(tPtr,_paths[i].p->localSocket(),_paths[i].p->address(),now,false); + if ((_paths[i].p->address().ss_family == inetAddressFamily) && (_paths[i].p->ipScope() == scope)) { + attemptToContactAt(tPtr, _paths[i].p->localSocket(), _paths[i].p->address(), now, false); _paths[i].p->sent(now); - _paths[i].lr = 0; // path will not be used unless it speaks again + _paths[i].lr = 0; // path will not be used unless it speaks again } - } else { + } + else { break; } } } -void Peer::recordOutgoingPacket(const SharedPtr &path, const uint64_t packetId, - uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now) +void Peer::recordOutgoingPacket(const SharedPtr& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now) { #ifndef ZT_NO_PEER_METRICS _outgoing_packet++; @@ -691,12 +708,11 @@ void Peer::recordIncomingInvalidPacket(const SharedPtr& path) } } -void Peer::recordIncomingPacket(const SharedPtr &path, const uint64_t packetId, - uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now) +void Peer::recordIncomingPacket(const SharedPtr& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now) { if (_localMultipathSupported && _bond) { _bond->recordIncomingPacket(path, packetId, payloadLength, verb, flowId, now); } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 777a1e966..62524dee1 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -14,27 +14,26 @@ #ifndef ZT_PEER_HPP #define ZT_PEER_HPP -#include -#include - #include "../include/ZeroTierOne.h" - -#include "Constants.hpp" -#include "RuntimeEnvironment.hpp" -#include "Node.hpp" -#include "Path.hpp" +#include "AES.hpp" #include "Address.hpp" -#include "Utils.hpp" +#include "AtomicCounter.hpp" +#include "Bond.hpp" +#include "Constants.hpp" +#include "Hashtable.hpp" #include "Identity.hpp" #include "InetAddress.hpp" -#include "Packet.hpp" -#include "SharedPtr.hpp" -#include "AtomicCounter.hpp" -#include "Hashtable.hpp" -#include "Mutex.hpp" -#include "Bond.hpp" -#include "AES.hpp" #include "Metrics.hpp" +#include "Mutex.hpp" +#include "Node.hpp" +#include "Packet.hpp" +#include "Path.hpp" +#include "RuntimeEnvironment.hpp" +#include "SharedPtr.hpp" +#include "Utils.hpp" + +#include +#include #define ZT_PEER_MAX_SERIALIZED_STATE_SIZE (sizeof(Peer) + 32 + (sizeof(Path) * 2)) @@ -43,19 +42,19 @@ namespace ZeroTier { /** * Peer on P2P Network (virtual layer 1) */ -class Peer -{ +class Peer { friend class SharedPtr; friend class SharedPtr; friend class Switch; friend class Bond; -private: - Peer() = delete; // disabled to prevent bugs -- should not be constructed uninitialized + private: + Peer() = delete; // disabled to prevent bugs -- should not be constructed uninitialized -public: - ~Peer() { - Utils::burn(_key,sizeof(_key)); + public: + ~Peer() + { + Utils::burn(_key, sizeof(_key)); } /** @@ -66,17 +65,23 @@ public: * @param peerIdentity Identity of peer * @throws std::runtime_error Key agreement with peer's identity failed */ - Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Identity &peerIdentity); + Peer(const RuntimeEnvironment* renv, const Identity& myIdentity, const Identity& peerIdentity); /** * @return This peer's ZT address (short for identity().address()) */ - inline const Address &address() const { return _id.address(); } + inline const Address& address() const + { + return _id.address(); + } /** * @return This peer's identity */ - inline const Identity &identity() const { return _id; } + inline const Identity& identity() const + { + return _id; + } /** * Log receipt of an authenticated packet @@ -95,8 +100,8 @@ public: * @param networkId Network ID if this pertains to a network, or 0 otherwise */ void received( - void *tPtr, - const SharedPtr &path, + void* tPtr, + const SharedPtr& path, const unsigned int hops, const uint64_t packetId, const unsigned int payloadLength, @@ -114,15 +119,16 @@ public: * @param addr Remote address * @return True if we have an active path to this destination */ - inline bool hasActivePathTo(int64_t now,const InetAddress &addr) const + inline bool hasActivePathTo(int64_t now, const InetAddress& addr) const { Mutex::Lock _l(_paths_m); - for(unsigned int i=0;iaddress() == addr)) { + if (((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION) && (_paths[i].p->address() == addr)) { return true; } - } else { + } + else { break; } } @@ -139,11 +145,11 @@ public: * @param force If true, send even if path is not alive * @return True if we actually sent something */ - inline bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force) + inline bool sendDirect(void* tPtr, const void* data, unsigned int len, int64_t now, bool force) { - SharedPtr bp(getAppropriatePath(now,force)); + SharedPtr bp(getAppropriatePath(now, force)); if (bp) { - return bp->send(RR,tPtr,data,len,now); + return bp->send(RR, tPtr, data, len, now); } return false; } @@ -159,8 +165,7 @@ public: * @param flowId Flow ID * @param now Current time */ - void recordIncomingPacket(const SharedPtr &path, const uint64_t packetId, - uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now); + void recordIncomingPacket(const SharedPtr& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now); /** * @@ -171,8 +176,7 @@ public: * @param flowId Flow ID * @param now Current time */ - void recordOutgoingPacket(const SharedPtr &path, const uint64_t packetId, - uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now); + void recordOutgoingPacket(const SharedPtr& path, const uint64_t packetId, uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now); /** * Record an invalid incoming packet. This packet failed @@ -195,7 +199,7 @@ public: /** * Send VERB_RENDEZVOUS to this and another peer via the best common IP scope and path */ - void introduce(void *const tPtr,const int64_t now,const SharedPtr &other) const; + void introduce(void* const tPtr, const int64_t now, const SharedPtr& other) const; /** * Send a HELLO to this peer at a specified physical address @@ -207,7 +211,7 @@ public: * @param atAddress Destination address * @param now Current time */ - void sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now); + void sendHELLO(void* tPtr, const int64_t localSocket, const InetAddress& atAddress, int64_t now); /** * Send ECHO (or HELLO for older peers) to this peer at the given address @@ -220,7 +224,7 @@ public: * @param now Current time * @param sendFullHello If true, always send a full HELLO instead of just an ECHO */ - void attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,int64_t now,bool sendFullHello); + void attemptToContactAt(void* tPtr, const int64_t localSocket, const InetAddress& atAddress, int64_t now, bool sendFullHello); /** * Try a memorized or statically defined path if any are known @@ -230,14 +234,14 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param now Current time */ - void tryMemorizedPath(void *tPtr,int64_t now); + void tryMemorizedPath(void* tPtr, int64_t now); /** * A check to be performed periodically which determines whether multipath communication is * possible with this peer. This check should be performed early in the life-cycle of the peer * as well as during the process of learning new paths. */ - void performMultipathStateCheck(void *tPtr, int64_t now); + void performMultipathStateCheck(void* tPtr, int64_t now); /** * Send pings or keepalives depending on configured timeouts @@ -249,7 +253,7 @@ public: * @param inetAddressFamily Keep this address family alive, or -1 for any * @return 0 if nothing sent or bit mask: bit 0x1 if IPv4 sent, bit 0x2 if IPv6 sent (0x3 means both sent) */ - unsigned int doPingAndKeepalive(void *tPtr,int64_t now); + unsigned int doPingAndKeepalive(void* tPtr, int64_t now); /** * Process a cluster redirect sent by this peer @@ -259,7 +263,7 @@ public: * @param remoteAddress Remote address * @param now Current time */ - void clusterRedirect(void *tPtr,const SharedPtr &originatingPath,const InetAddress &remoteAddress,const int64_t now); + void clusterRedirect(void* tPtr, const SharedPtr& originatingPath, const InetAddress& remoteAddress, const int64_t now); /** * Reset paths within a given IP scope and address family @@ -274,18 +278,18 @@ public: * @param inetAddressFamily Family e.g. AF_INET * @param now Current time */ - void resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,int64_t now); + void resetWithinScope(void* tPtr, InetAddress::IpScope scope, int inetAddressFamily, int64_t now); /** * @param now Current time * @return All known paths to this peer */ - inline std::vector< SharedPtr > paths(const int64_t now) const + inline std::vector > paths(const int64_t now) const { - std::vector< SharedPtr > pp; + std::vector > pp; Mutex::Lock _l(_paths_m); - for(unsigned int i=0;i bp(getAppropriatePath(now,false)); + } + else { + SharedPtr bp(getAppropriatePath(now, false)); if (bp) { return (unsigned int)bp->latency(); } @@ -344,7 +361,7 @@ public: return (~(unsigned int)0); } unsigned int l = latency(now); - if (!l) { + if (! l) { l = 0xffff; } return (l * (((unsigned int)tsr / (ZT_PEER_PING_PERIOD + 1000)) + 1)); @@ -353,7 +370,10 @@ public: /** * @return 256-bit secret symmetric encryption key */ - inline const unsigned char *key() const { return _key; } + inline const unsigned char* key() const + { + return _key; + } /** * Set the currently known remote version of this peer's client @@ -363,7 +383,7 @@ public: * @param vmin Minor version * @param vrev Revision */ - inline void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev) + inline void setRemoteVersion(unsigned int vproto, unsigned int vmaj, unsigned int vmin, unsigned int vrev) { _vProto = (uint16_t)vproto; _vMajor = (uint16_t)vmaj; @@ -371,17 +391,35 @@ public: _vRevision = (uint16_t)vrev; } - inline unsigned int remoteVersionProtocol() const { return _vProto; } - inline unsigned int remoteVersionMajor() const { return _vMajor; } - inline unsigned int remoteVersionMinor() const { return _vMinor; } - inline unsigned int remoteVersionRevision() const { return _vRevision; } + inline unsigned int remoteVersionProtocol() const + { + return _vProto; + } + inline unsigned int remoteVersionMajor() const + { + return _vMajor; + } + inline unsigned int remoteVersionMinor() const + { + return _vMinor; + } + inline unsigned int remoteVersionRevision() const + { + return _vRevision; + } - inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); } + inline bool remoteVersionKnown() const + { + return ((_vMajor > 0) || (_vMinor > 0) || (_vRevision > 0)); + } /** * @return True if peer has received a trust established packet (e.g. common network membership) in the past ZT_TRUST_EXPIRATION ms */ - inline bool trustEstablished(const int64_t now) const { return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); } + inline bool trustEstablished(const int64_t now) const + { + return ((now - _lastTrustEstablishedPacketReceived) < ZT_TRUST_EXPIRATION); + } /** * Rate limit gate for VERB_PUSH_DIRECT_PATHS @@ -390,7 +428,8 @@ public: { if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME) { ++_directPathPushCutoffCount; - } else { + } + else { _directPathPushCutoffCount = 0; } _lastDirectPathPushReceive = now; @@ -439,10 +478,10 @@ public: inline bool rateGateQoS(int64_t now, SharedPtr& path) { Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { return _bond->rateGateQoS(now, path); } - return false; // Default behavior. If there is no bond, we drop these + return false; // Default behavior. If there is no bond, we drop these } /** @@ -451,7 +490,7 @@ public: void receivedQoS(const SharedPtr& path, int64_t now, int count, uint64_t* rx_id, uint16_t* rx_ts) { Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { _bond->receivedQoS(path, now, count, rx_id, rx_ts); } } @@ -462,7 +501,7 @@ public: void processIncomingPathNegotiationRequest(uint64_t now, SharedPtr& path, int16_t remoteUtility) { Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { _bond->processIncomingPathNegotiationRequest(now, path, remoteUtility); } } @@ -473,10 +512,10 @@ public: inline bool rateGatePathNegotiation(int64_t now, SharedPtr& path) { Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { return _bond->rateGatePathNegotiation(now, path); } - return false; // Default behavior. If there is no bond, we drop these + return false; // Default behavior. If there is no bond, we drop these } /** @@ -485,7 +524,7 @@ public: bool flowHashingSupported() { Mutex::Lock _l(_bond_m); - if(_bond) { + if (_bond) { return _bond->flowHashingSupported(); } return false; @@ -496,8 +535,7 @@ public: * * This does not serialize everything, just non-ephemeral information. */ - template - inline void serializeForCache(Buffer &b) const + template inline void serializeForCache(Buffer& b) const { b.append((uint8_t)2); @@ -511,22 +549,22 @@ public: { Mutex::Lock _l(_paths_m); unsigned int pc = 0; - for(unsigned int i=0;iaddress().serialize(b); } } } - template - inline static SharedPtr deserializeFromCache(int64_t now,void *tPtr,Buffer &b,const RuntimeEnvironment *renv) + template inline static SharedPtr deserializeFromCache(int64_t now, void* tPtr, Buffer& b, const RuntimeEnvironment* renv) { try { unsigned int ptr = 0; @@ -535,12 +573,12 @@ public: } Identity id; - ptr += id.deserialize(b,ptr); - if (!id) { + ptr += id.deserialize(b, ptr); + if (! id) { return SharedPtr(); } - SharedPtr p(new Peer(renv,renv->identity,id)); + SharedPtr p(new Peer(renv, renv->identity, id)); p->_vProto = b.template at(ptr); ptr += 2; @@ -556,20 +594,22 @@ public: // Paths are fairly ephemeral in the real world in most cases. const unsigned int tryPathCount = b.template at(ptr); ptr += 2; - for(unsigned int i=0;iattemptToContactAt(tPtr,-1,inaddr,now,true); + p->attemptToContactAt(tPtr, -1, inaddr, now, true); } - } catch ( ... ) { + } + catch (...) { break; } } return p; - } catch ( ... ) { + } + catch (...) { return SharedPtr(); } } @@ -577,12 +617,16 @@ public: /** * @return The bonding policy used to reach this peer */ - SharedPtr bond() { return _bond; } + SharedPtr bond() + { + return _bond; + } /** * @return The bonding policy used to reach this peer */ - inline int8_t bondingPolicy() { + inline int8_t bondingPolicy() + { Mutex::Lock _l(_bond_m); if (_bond) { return _bond->policy(); @@ -593,7 +637,8 @@ public: /** * @return the number of links in this bond which are considered alive */ - inline uint8_t getNumAliveLinks() { + inline uint8_t getNumAliveLinks() + { Mutex::Lock _l(_paths_m); if (_bond) { return _bond->getNumAliveLinks(); @@ -604,7 +649,8 @@ public: /** * @return the number of links in this bond */ - inline uint8_t getNumTotalLinks() { + inline uint8_t getNumTotalLinks() + { Mutex::Lock _l(_paths_m); if (_bond) { return _bond->getNumTotalLinks(); @@ -612,31 +658,36 @@ public: return 0; } - //inline const AES *aesKeysIfSupported() const + // inline const AES *aesKeysIfSupported() const //{ return (const AES *)0; } - inline const AES *aesKeysIfSupported() const - { return (_vProto >= 12) ? _aesKeys : (const AES *)0; } - - inline const AES *aesKeys() const - { return _aesKeys; } - -private: - struct _PeerPath + inline const AES* aesKeysIfSupported() const { - _PeerPath() : lr(0),p(),priority(1) {} - int64_t lr; // time of last valid ZeroTier packet + return (_vProto >= 12) ? _aesKeys : (const AES*)0; + } + + inline const AES* aesKeys() const + { + return _aesKeys; + } + + private: + struct _PeerPath { + _PeerPath() : lr(0), p(), priority(1) + { + } + int64_t lr; // time of last valid ZeroTier packet SharedPtr p; - long priority; // >= 1, higher is better + long priority; // >= 1, higher is better }; uint8_t _key[ZT_SYMMETRIC_KEY_SIZE]; AES _aesKeys[2]; - const RuntimeEnvironment *RR; + const RuntimeEnvironment* RR; - int64_t _lastReceive; // direct or indirect - int64_t _lastNontrivialReceive; // frames, things like netconf, etc. + int64_t _lastReceive; // direct or indirect + int64_t _lastNontrivialReceive; // frames, things like netconf, etc. int64_t _lastTriedMemorizedPath; int64_t _lastDirectPathPushSent; int64_t _lastDirectPathPushReceive; @@ -654,7 +705,7 @@ private: uint16_t _vMinor; uint16_t _vRevision; - std::list< std::pair< Path *, int64_t > > _lastTriedPath; + std::list > _lastTriedPath; Mutex _lastTriedPath_m; _PeerPath _paths[ZT_MAX_PEER_NETWORK_PATHS]; @@ -679,7 +730,7 @@ private: SharedPtr _bond; #ifndef ZT_NO_PEER_METRICS - prometheus::Histogram &_peer_latency; + prometheus::Histogram& _peer_latency; prometheus::simpleapi::gauge_metric_t _alive_path_count; prometheus::simpleapi::gauge_metric_t _dead_path_count; prometheus::simpleapi::counter_metric_t _incoming_packet; @@ -688,15 +739,14 @@ private: #endif }; -} // namespace ZeroTier +} // namespace ZeroTier // Add a swap() for shared ptr's to peers to speed up peer sorts namespace std { - template<> - inline void swap(ZeroTier::SharedPtr &a,ZeroTier::SharedPtr &b) - { - a.swap(b); - } +template <> inline void swap(ZeroTier::SharedPtr& a, ZeroTier::SharedPtr& b) +{ + a.swap(b); } +} // namespace std #endif diff --git a/node/Poly1305.cpp b/node/Poly1305.cpp index 382465135..78d1c1da4 100644 --- a/node/Poly1305.cpp +++ b/node/Poly1305.cpp @@ -4,16 +4,17 @@ D. J. Bernstein Public domain. */ -#include "Constants.hpp" #include "Poly1305.hpp" -#include +#include "Constants.hpp" + #include +#include #include #include #ifdef __WINDOWS__ -#pragma warning(disable: 4146) +#pragma warning(disable : 4146) #endif namespace ZeroTier { @@ -21,8 +22,8 @@ namespace ZeroTier { namespace { typedef struct poly1305_context { - size_t aligner; - unsigned char opaque[136]; + size_t aligner; + unsigned char opaque[136]; } poly1305_context; #if (defined(_MSC_VER) || defined(__GNUC__)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64)) @@ -31,32 +32,42 @@ typedef struct poly1305_context { // 128-bit implementation for MSC and GCC from Poly1305-donna #if defined(_MSC_VER) - #include +#include - typedef struct uint128_t { - unsigned long long lo; - unsigned long long hi; - } uint128_t; +typedef struct uint128_t { + unsigned long long lo; + unsigned long long hi; +} uint128_t; - #define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi) - #define ADD(out, in) { unsigned long long t = out.lo; out.lo += in.lo; out.hi += (out.lo < t) + in.hi; } - #define ADDLO(out, in) { unsigned long long t = out.lo; out.lo += in; out.hi += (out.lo < t); } - #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift))) - #define LO(in) (in.lo) +#define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi) +#define ADD(out, in) \ + { \ + unsigned long long t = out.lo; \ + out.lo += in.lo; \ + out.hi += (out.lo < t) + in.hi; \ + } +#define ADDLO(out, in) \ + { \ + unsigned long long t = out.lo; \ + out.lo += in; \ + out.hi += (out.lo < t); \ + } +#define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift))) +#define LO(in) (in.lo) // #define POLY1305_NOINLINE __declspec(noinline) #elif defined(__GNUC__) - #if defined(__SIZEOF_INT128__) - typedef unsigned __int128 uint128_t; - #else - typedef unsigned uint128_t __attribute__((mode(TI))); - #endif +#if defined(__SIZEOF_INT128__) +typedef unsigned __int128 uint128_t; +#else +typedef unsigned uint128_t __attribute__((mode(TI))); +#endif - #define MUL(out, x, y) out = ((uint128_t)x * y) - #define ADD(out, in) out += in - #define ADDLO(out, in) out += in - #define SHR(in, shift) (unsigned long long)(in >> (shift)) - #define LO(in) (unsigned long long)(in) +#define MUL(out, x, y) out = ((uint128_t)x * y) +#define ADD(out, in) out += in +#define ADDLO(out, in) out += in +#define SHR(in, shift) (unsigned long long)(in >> (shift)) +#define LO(in) (unsigned long long)(in) // #define POLY1305_NOINLINE __attribute__((noinline)) #endif @@ -65,192 +76,228 @@ typedef struct poly1305_context { /* 17 + sizeof(size_t) + 8*sizeof(unsigned long long) */ typedef struct poly1305_state_internal_t { - unsigned long long r[3]; - unsigned long long h[3]; - unsigned long long pad[2]; - size_t leftover; - unsigned char buffer[poly1305_block_size]; - unsigned char final; + unsigned long long r[3]; + unsigned long long h[3]; + unsigned long long pad[2]; + size_t leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; } poly1305_state_internal_t; #if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN) -static inline unsigned long long U8TO64(const unsigned char *p) +static inline unsigned long long U8TO64(const unsigned char* p) { - return - (((unsigned long long)(p[0] & 0xff) ) | - ((unsigned long long)(p[1] & 0xff) << 8) | - ((unsigned long long)(p[2] & 0xff) << 16) | - ((unsigned long long)(p[3] & 0xff) << 24) | - ((unsigned long long)(p[4] & 0xff) << 32) | - ((unsigned long long)(p[5] & 0xff) << 40) | - ((unsigned long long)(p[6] & 0xff) << 48) | - ((unsigned long long)(p[7] & 0xff) << 56)); + return ( + ((unsigned long long)(p[0] & 0xff)) | ((unsigned long long)(p[1] & 0xff) << 8) | ((unsigned long long)(p[2] & 0xff) << 16) | ((unsigned long long)(p[3] & 0xff) << 24) | ((unsigned long long)(p[4] & 0xff) << 32) + | ((unsigned long long)(p[5] & 0xff) << 40) | ((unsigned long long)(p[6] & 0xff) << 48) | ((unsigned long long)(p[7] & 0xff) << 56)); } #else -#define U8TO64(p) (*reinterpret_cast(p)) +#define U8TO64(p) (*reinterpret_cast(p)) #endif #if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN) -static inline void U64TO8(unsigned char *p, unsigned long long v) +static inline void U64TO8(unsigned char* p, unsigned long long v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; - p[4] = (v >> 32) & 0xff; - p[5] = (v >> 40) & 0xff; - p[6] = (v >> 48) & 0xff; - p[7] = (v >> 56) & 0xff; + p[0] = (v) & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; + p[4] = (v >> 32) & 0xff; + p[5] = (v >> 40) & 0xff; + p[6] = (v >> 48) & 0xff; + p[7] = (v >> 56) & 0xff; } #else -#define U64TO8(p,v) ((*reinterpret_cast(p)) = (v)) +#define U64TO8(p, v) ((*reinterpret_cast(p)) = (v)) #endif -static inline void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - unsigned long long t0,t1; +static inline void poly1305_init(poly1305_context* ctx, const unsigned char key[32]) +{ + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + unsigned long long t0, t1; - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - t0 = U8TO64(&key[0]); - t1 = U8TO64(&key[8]); + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + t0 = U8TO64(&key[0]); + t1 = U8TO64(&key[8]); - st->r[0] = ( t0 ) & 0xffc0fffffff; - st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; - st->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f; + st->r[0] = (t0) & 0xffc0fffffff; + st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; + st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f; - /* h = 0 */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; - /* save pad for later */ - st->pad[0] = U8TO64(&key[16]); - st->pad[1] = U8TO64(&key[24]); + /* save pad for later */ + st->pad[0] = U8TO64(&key[16]); + st->pad[1] = U8TO64(&key[24]); - st->leftover = 0; - st->final = 0; + st->leftover = 0; + st->final = 0; } -static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { - const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */ - unsigned long long r0,r1,r2; - unsigned long long s1,s2; - unsigned long long h0,h1,h2; - unsigned long long c; - uint128_t d0,d1,d2,d; +static inline void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes) +{ + const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */ + unsigned long long r0, r1, r2; + unsigned long long s1, s2; + unsigned long long h0, h1, h2; + unsigned long long c; + uint128_t d0, d1, d2, d; - r0 = st->r[0]; - r1 = st->r[1]; - r2 = st->r[2]; + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; - s1 = r1 * (5 << 2); - s2 = r2 * (5 << 2); + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); - while (bytes >= poly1305_block_size) { - unsigned long long t0,t1; + while (bytes >= poly1305_block_size) { + unsigned long long t0, t1; - /* h += m[i] */ - t0 = U8TO64(&m[0]); - t1 = U8TO64(&m[8]); + /* h += m[i] */ + t0 = U8TO64(&m[0]); + t1 = U8TO64(&m[8]); - h0 += (( t0 ) & 0xfffffffffff); - h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); - h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit; + h0 += ((t0) & 0xfffffffffff); + h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); + h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit; - /* h *= r */ - MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d); - MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d); - MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d); + /* h *= r */ + MUL(d0, h0, r0); + MUL(d, h1, s2); + ADD(d0, d); + MUL(d, h2, s1); + ADD(d0, d); + MUL(d1, h0, r1); + MUL(d, h1, r0); + ADD(d1, d); + MUL(d, h2, s2); + ADD(d1, d); + MUL(d2, h0, r2); + MUL(d, h1, r1); + ADD(d2, d); + MUL(d, h2, r0); + ADD(d2, d); - /* (partial) h %= p */ - c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff; - ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff; - ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff; - h1 += c; + /* (partial) h %= p */ + c = SHR(d0, 44); + h0 = LO(d0) & 0xfffffffffff; + ADDLO(d1, c); + c = SHR(d1, 44); + h1 = LO(d1) & 0xfffffffffff; + ADDLO(d2, c); + c = SHR(d2, 42); + h2 = LO(d2) & 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 = h0 & 0xfffffffffff; + h1 += c; - m += poly1305_block_size; - bytes -= poly1305_block_size; - } + m += poly1305_block_size; + bytes -= poly1305_block_size; + } - st->h[0] = h0; - st->h[1] = h1; - st->h[2] = h2; + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; } -static inline void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - unsigned long long h0,h1,h2,c; - unsigned long long g0,g1,g2; - unsigned long long t0,t1; +static inline void poly1305_finish(poly1305_context* ctx, unsigned char mac[16]) +{ + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + unsigned long long h0, h1, h2, c; + unsigned long long g0, g1, g2; + unsigned long long t0, t1; - /* process the remaining block */ - if (st->leftover) { - size_t i = st->leftover; - st->buffer[i] = 1; - for (i = i + 1; i < poly1305_block_size; i++) { - st->buffer[i] = 0; - } - st->final = 1; - poly1305_blocks(st, st->buffer, poly1305_block_size); - } + /* process the remaining block */ + if (st->leftover) { + size_t i = st->leftover; + st->buffer[i] = 1; + for (i = i + 1; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } - /* fully carry h */ - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; - c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; - /* compute h + -p */ - g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff; - g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff; - g2 = h2 + c - ((unsigned long long)1 << 42); + /* compute h + -p */ + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((unsigned long long)1 << 42); - /* select h if h < p, or h + -p if h >= p */ - c = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; - g0 &= c; - g1 &= c; - g2 &= c; - c = ~c; - h0 = (h0 & c) | g0; - h1 = (h1 & c) | g1; - h2 = (h2 & c) | g2; + /* select h if h < p, or h + -p if h >= p */ + c = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; + g0 &= c; + g1 &= c; + g2 &= c; + c = ~c; + h0 = (h0 & c) | g0; + h1 = (h1 & c) | g1; + h2 = (h2 & c) | g2; - /* h = (h + pad) */ - t0 = st->pad[0]; - t1 = st->pad[1]; + /* h = (h + pad) */ + t0 = st->pad[0]; + t1 = st->pad[1]; - h0 += (( t0 ) & 0xfffffffffff) ; c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c; h2 &= 0x3ffffffffff; + h0 += ((t0) & 0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += (((t1 >> 24)) & 0x3ffffffffff) + c; + h2 &= 0x3ffffffffff; - /* mac = h % (2^128) */ - h0 = ((h0 ) | (h1 << 44)); - h1 = ((h1 >> 20) | (h2 << 24)); + /* mac = h % (2^128) */ + h0 = ((h0) | (h1 << 44)); + h1 = ((h1 >> 20) | (h2 << 24)); - U64TO8(&mac[0], h0); - U64TO8(&mac[8], h1); + U64TO8(&mac[0], h0); + U64TO8(&mac[8], h1); - /* zero out the state */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->r[0] = 0; - st->r[1] = 0; - st->r[2] = 0; - st->pad[0] = 0; - st->pad[1] = 0; + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->pad[0] = 0; + st->pad[1] = 0; } ////////////////////////////////////////////////////////////////////////////// @@ -264,262 +311,291 @@ static inline void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) /* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ typedef struct poly1305_state_internal_t { - unsigned long r[5]; - unsigned long h[5]; - unsigned long pad[4]; - size_t leftover; - unsigned char buffer[poly1305_block_size]; - unsigned char final; + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + size_t leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; } poly1305_state_internal_t; /* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ -static unsigned long -U8TO32(const unsigned char *p) { - return - (((unsigned long)(p[0] & 0xff) ) | - ((unsigned long)(p[1] & 0xff) << 8) | - ((unsigned long)(p[2] & 0xff) << 16) | - ((unsigned long)(p[3] & 0xff) << 24)); +static unsigned long U8TO32(const unsigned char* p) +{ + return (((unsigned long)(p[0] & 0xff)) | ((unsigned long)(p[1] & 0xff) << 8) | ((unsigned long)(p[2] & 0xff) << 16) | ((unsigned long)(p[3] & 0xff) << 24)); } /* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ -static void -U32TO8(unsigned char *p, unsigned long v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; +static void U32TO8(unsigned char* p, unsigned long v) +{ + p[0] = (v) & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; } -static inline void -poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; +static inline void poly1305_init(poly1305_context* ctx, const unsigned char key[32]) +{ + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff; - st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03; - st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff; - st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff; - st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + st->r[0] = (U8TO32(&key[0])) & 0x3ffffff; + st->r[1] = (U8TO32(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (U8TO32(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (U8TO32(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; - /* h = 0 */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; - /* save pad for later */ - st->pad[0] = U8TO32(&key[16]); - st->pad[1] = U8TO32(&key[20]); - st->pad[2] = U8TO32(&key[24]); - st->pad[3] = U8TO32(&key[28]); + /* save pad for later */ + st->pad[0] = U8TO32(&key[16]); + st->pad[1] = U8TO32(&key[20]); + st->pad[2] = U8TO32(&key[24]); + st->pad[3] = U8TO32(&key[28]); - st->leftover = 0; - st->final = 0; + st->leftover = 0; + st->final = 0; } -static inline void -poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { - const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */ - unsigned long r0,r1,r2,r3,r4; - unsigned long s1,s2,s3,s4; - unsigned long h0,h1,h2,h3,h4; - unsigned long long d0,d1,d2,d3,d4; - unsigned long c; +static inline void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes) +{ + const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; - r0 = st->r[0]; - r1 = st->r[1]; - r2 = st->r[2]; - r3 = st->r[3]; - r4 = st->r[4]; + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; - s1 = r1 * 5; - s2 = r2 * 5; - s3 = r3 * 5; - s4 = r4 * 5; + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; - while (bytes >= poly1305_block_size) { - /* h += m[i] */ - h0 += (U8TO32(m+ 0) ) & 0x3ffffff; - h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; - h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; - h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; - h4 += (U8TO32(m+12) >> 8) | hibit; + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (U8TO32(m + 0)) & 0x3ffffff; + h1 += (U8TO32(m + 3) >> 2) & 0x3ffffff; + h2 += (U8TO32(m + 6) >> 4) & 0x3ffffff; + h3 += (U8TO32(m + 9) >> 6) & 0x3ffffff; + h4 += (U8TO32(m + 12) >> 8) | hibit; - /* h *= r */ - d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1); - d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2); - d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3); - d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4); - d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0); + /* h *= r */ + d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1); + d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2); + d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3); + d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4); + d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0); - /* (partial) h %= p */ - c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff; - d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff; - d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff; - d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff; - d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff; - h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; - h1 += c; + /* (partial) h %= p */ + c = (unsigned long)(d0 >> 26); + h0 = (unsigned long)d0 & 0x3ffffff; + d1 += c; + c = (unsigned long)(d1 >> 26); + h1 = (unsigned long)d1 & 0x3ffffff; + d2 += c; + c = (unsigned long)(d2 >> 26); + h2 = (unsigned long)d2 & 0x3ffffff; + d3 += c; + c = (unsigned long)(d3 >> 26); + h3 = (unsigned long)d3 & 0x3ffffff; + d4 += c; + c = (unsigned long)(d4 >> 26); + h4 = (unsigned long)d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; - m += poly1305_block_size; - bytes -= poly1305_block_size; - } + m += poly1305_block_size; + bytes -= poly1305_block_size; + } - st->h[0] = h0; - st->h[1] = h1; - st->h[2] = h2; - st->h[3] = h3; - st->h[4] = h4; + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; } -static inline void -poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - unsigned long h0,h1,h2,h3,h4,c; - unsigned long g0,g1,g2,g3,g4; - unsigned long long f; - unsigned long mask; +static inline void poly1305_finish(poly1305_context* ctx, unsigned char mac[16]) +{ + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; - /* process the remaining block */ - if (st->leftover) { - size_t i = st->leftover; - st->buffer[i++] = 1; - for (; i < poly1305_block_size; i++) { - st->buffer[i] = 0; - } - st->final = 1; - poly1305_blocks(st, st->buffer, poly1305_block_size); - } + /* process the remaining block */ + if (st->leftover) { + size_t i = st->leftover; + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } - /* fully carry h */ - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; - c = h1 >> 26; h1 = h1 & 0x3ffffff; - h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; - h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; - h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; - h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; - h1 += c; + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; - /* compute h + -p */ - g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; - g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; - g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; - g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; - g4 = h4 + c - (1 << 26); + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1 << 26); - /* select h if h < p, or h + -p if h >= p */ - mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; - g0 &= mask; - g1 &= mask; - g2 &= mask; - g3 &= mask; - g4 &= mask; - mask = ~mask; - h0 = (h0 & mask) | g0; - h1 = (h1 & mask) | g1; - h2 = (h2 & mask) | g2; - h3 = (h3 & mask) | g3; - h4 = (h4 & mask) | g4; + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; - /* h = h % (2^128) */ - h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; - h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; - h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; - h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; - /* mac = (h + pad) % (2^128) */ - f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f; - f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f; - f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f; - f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f; + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long)h0 + st->pad[0]; + h0 = (unsigned long)f; + f = (unsigned long long)h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long)f; + f = (unsigned long long)h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long)f; + f = (unsigned long long)h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long)f; - U32TO8(mac + 0, h0); - U32TO8(mac + 4, h1); - U32TO8(mac + 8, h2); - U32TO8(mac + 12, h3); + U32TO8(mac + 0, h0); + U32TO8(mac + 4, h1); + U32TO8(mac + 8, h2); + U32TO8(mac + 12, h3); - /* zero out the state */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; - st->r[0] = 0; - st->r[1] = 0; - st->r[2] = 0; - st->r[3] = 0; - st->r[4] = 0; - st->pad[0] = 0; - st->pad[1] = 0; - st->pad[2] = 0; - st->pad[3] = 0; + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; } ////////////////////////////////////////////////////////////////////////////// -#endif // MSC/GCC or not +#endif // MSC/GCC or not -static inline void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - size_t i; - - /* handle leftover */ - if (st->leftover) { - size_t want = (poly1305_block_size - st->leftover); - if (want > bytes) { - want = bytes; - } - for (i = 0; i < want; i++) { - st->buffer[st->leftover + i] = m[i]; - } - bytes -= want; - m += want; - st->leftover += want; - if (st->leftover < poly1305_block_size) { - return; - } - poly1305_blocks(st, st->buffer, poly1305_block_size); - st->leftover = 0; - } - - /* process full blocks */ - if (bytes >= poly1305_block_size) { - size_t want = (bytes & ~(poly1305_block_size - 1)); - poly1305_blocks(st, m, want); - m += want; - bytes -= want; - } - - /* store leftover */ - if (bytes) { - for (i = 0; i < bytes; i++) { - st->buffer[st->leftover + i] = m[i]; - } - st->leftover += bytes; - } -} - -} // anonymous namespace - -void Poly1305::compute(void *auth,const void *data,unsigned int len,const void *key) +static inline void poly1305_update(poly1305_context* ctx, const unsigned char* m, size_t bytes) { - poly1305_context ctx; - poly1305_init(&ctx,reinterpret_cast(key)); - poly1305_update(&ctx,reinterpret_cast(data),(size_t)len); - poly1305_finish(&ctx,reinterpret_cast(auth)); + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + size_t i; + + /* handle leftover */ + if (st->leftover) { + size_t want = (poly1305_block_size - st->leftover); + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + size_t want = (bytes & ~(poly1305_block_size - 1)); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } } -} // namespace ZeroTier +} // anonymous namespace + +void Poly1305::compute(void* auth, const void* data, unsigned int len, const void* key) +{ + poly1305_context ctx; + poly1305_init(&ctx, reinterpret_cast(key)); + poly1305_update(&ctx, reinterpret_cast(data), (size_t)len); + poly1305_finish(&ctx, reinterpret_cast(auth)); +} + +} // namespace ZeroTier diff --git a/node/Poly1305.hpp b/node/Poly1305.hpp index 2ba57f040..e5c3a8547 100644 --- a/node/Poly1305.hpp +++ b/node/Poly1305.hpp @@ -30,9 +30,8 @@ namespace ZeroTier { * keystream as a one-time-use key. These 32 bytes are then discarded and * the packet is encrypted with the next N bytes. */ -class Poly1305 -{ -public: +class Poly1305 { + public: /** * Compute a one-time authentication code * @@ -41,9 +40,9 @@ public: * @param len Length of data to authenticate in bytes * @param key 32-byte one-time use key to authenticate data (must not be reused) */ - static void compute(void *auth,const void *data,unsigned int len,const void *key); + static void compute(void* auth, const void* data, unsigned int len, const void* key); }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Revocation.cpp b/node/Revocation.cpp index 44e22e365..6da98f269 100644 --- a/node/Revocation.cpp +++ b/node/Revocation.cpp @@ -12,32 +12,34 @@ /****/ #include "Revocation.hpp" -#include "RuntimeEnvironment.hpp" + #include "Identity.hpp" -#include "Topology.hpp" -#include "Switch.hpp" #include "Network.hpp" #include "Node.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" namespace ZeroTier { -int Revocation::verify(const RuntimeEnvironment *RR,void *tPtr) const +int Revocation::verify(const RuntimeEnvironment* RR, void* tPtr) const { - if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId))) { + if ((! _signedBy) || (_signedBy != Network::controllerFor(_networkId))) { return -1; } - const Identity id(RR->topology->getIdentity(tPtr,_signedBy)); - if (!id) { - RR->sw->requestWhois(tPtr,RR->node->now(),_signedBy); + const Identity id(RR->topology->getIdentity(tPtr, _signedBy)); + if (! id) { + RR->sw->requestWhois(tPtr, RR->node->now(), _signedBy); return 1; } try { Buffer tmp; - this->serialize(tmp,true); - return (id.verify(tmp.data(),tmp.size(),_signature) ? 0 : -1); - } catch ( ... ) { + this->serialize(tmp, true); + return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1); + } + catch (...) { return -1; } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Revocation.hpp b/node/Revocation.hpp index 7c4523cd7..671b87043 100644 --- a/node/Revocation.hpp +++ b/node/Revocation.hpp @@ -14,19 +14,19 @@ #ifndef ZT_REVOCATION_HPP #define ZT_REVOCATION_HPP +#include "../include/ZeroTierOne.h" +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" +#include "Constants.hpp" +#include "Credential.hpp" +#include "Identity.hpp" +#include "Utils.hpp" + +#include #include #include #include -#include - -#include "Constants.hpp" -#include "../include/ZeroTierOne.h" -#include "Credential.hpp" -#include "Address.hpp" -#include "C25519.hpp" -#include "Utils.hpp" -#include "Buffer.hpp" -#include "Identity.hpp" /** * Flag: fast propagation via rumor mill algorithm @@ -40,22 +40,16 @@ class RuntimeEnvironment; /** * Revocation certificate to instantaneously revoke a COM, capability, or tag */ -class Revocation : public Credential -{ -public: - static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_REVOCATION; } - - Revocation() : - _id(0), - _credentialId(0), - _networkId(0), - _threshold(0), - _flags(0), - _target(), - _signedBy(), - _type(Credential::CREDENTIAL_TYPE_NULL) +class Revocation : public Credential { + public: + static inline Credential::Type credentialType() { - memset(_signature.data,0,sizeof(_signature.data)); + return Credential::CREDENTIAL_TYPE_REVOCATION; + } + + Revocation() : _id(0), _credentialId(0), _networkId(0), _threshold(0), _flags(0), _target(), _signedBy(), _type(Credential::CREDENTIAL_TYPE_NULL) + { + memset(_signature.data, 0, sizeof(_signature.data)); } /** @@ -67,40 +61,64 @@ public: * @param tgt Target node whose credential(s) are being revoked * @param ct Credential type being revoked */ - Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const int64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) : - _id(i), - _credentialId(cid), - _networkId(nwid), - _threshold(thr), - _flags(fl), - _target(tgt), - _signedBy(), - _type(ct) + Revocation(const uint32_t i, const uint64_t nwid, const uint32_t cid, const int64_t thr, const uint64_t fl, const Address& tgt, const Credential::Type ct) + : _id(i) + , _credentialId(cid) + , _networkId(nwid) + , _threshold(thr) + , _flags(fl) + , _target(tgt) + , _signedBy() + , _type(ct) { - memset(_signature.data,0,sizeof(_signature.data)); + memset(_signature.data, 0, sizeof(_signature.data)); } - inline uint32_t id() const { return _id; } - inline uint32_t credentialId() const { return _credentialId; } - inline uint64_t networkId() const { return _networkId; } - inline int64_t threshold() const { return _threshold; } - inline const Address &target() const { return _target; } - inline const Address &signer() const { return _signedBy; } - inline Credential::Type type() const { return _type; } + inline uint32_t id() const + { + return _id; + } + inline uint32_t credentialId() const + { + return _credentialId; + } + inline uint64_t networkId() const + { + return _networkId; + } + inline int64_t threshold() const + { + return _threshold; + } + inline const Address& target() const + { + return _target; + } + inline const Address& signer() const + { + return _signedBy; + } + inline Credential::Type type() const + { + return _type; + } - inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); } + inline bool fastPropagate() const + { + return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); + } /** * @param signer Signing identity, must have private key * @return True if signature was successful */ - inline bool sign(const Identity &signer) + inline bool sign(const Identity& signer) { if (signer.hasPrivate()) { Buffer tmp; _signedBy = signer.address(); - this->serialize(tmp,true); - _signature = signer.sign(tmp.data(),tmp.size()); + this->serialize(tmp, true); + _signature = signer.sign(tmp.data(), tmp.size()); return true; } return false; @@ -113,19 +131,18 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; + int verify(const RuntimeEnvironment* RR, void* tPtr) const; - template - inline void serialize(Buffer &b,const bool forSign = false) const + template inline void serialize(Buffer& b, const bool forSign = false) const { if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); } - b.append((uint32_t)0); // 4 unused bytes, currently set to 0 + b.append((uint32_t)0); // 4 unused bytes, currently set to 0 b.append(_id); b.append(_networkId); - b.append((uint32_t)0); // 4 unused bytes, currently set to 0 + b.append((uint32_t)0); // 4 unused bytes, currently set to 0 b.append(_credentialId); b.append(_threshold); b.append(_flags); @@ -133,10 +150,10 @@ public: _signedBy.appendTo(b); b.append((uint8_t)_type); - if (!forSign) { - b.append((uint8_t)1); // 1 == Ed25519 signature + if (! forSign) { + b.append((uint8_t)1); // 1 == Ed25519 signature b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); - b.append(_signature.data,ZT_C25519_SIGNATURE_LEN); + b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); } // This is the size of any additional fields, currently 0. @@ -147,40 +164,41 @@ public: } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { *this = Revocation(); unsigned int p = startAt; - p += 4; // 4 bytes, currently unused + p += 4; // 4 bytes, currently unused _id = b.template at(p); p += 4; _networkId = b.template at(p); p += 8; - p += 4; // 4 bytes, currently unused + p += 4; // 4 bytes, currently unused _credentialId = b.template at(p); p += 4; _threshold = (int64_t)b.template at(p); p += 8; _flags = b.template at(p); p += 8; - _target.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _target.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; - _signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _signedBy.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; _type = (Credential::Type)b[p++]; if (b[p++] == 1) { if (b.template at(p) == ZT_C25519_SIGNATURE_LEN) { p += 2; - memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; - } else { + } + else { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } - } else { + } + else { p += 2 + b.template at(p); } @@ -192,7 +210,7 @@ public: return (p - startAt); } -private: + private: uint32_t _id; uint32_t _credentialId; uint64_t _networkId; @@ -204,6 +222,6 @@ private: C25519::Signature _signature; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/RingBuffer.hpp b/node/RingBuffer.hpp index ac4cb2c08..f99562894 100644 --- a/node/RingBuffer.hpp +++ b/node/RingBuffer.hpp @@ -14,12 +14,12 @@ #ifndef ZT_RINGBUFFER_H #define ZT_RINGBUFFER_H -#include -#include -#include -#include #include +#include #include +#include +#include +#include namespace ZeroTier { @@ -34,28 +34,23 @@ namespace ZeroTier { * to reduce the complexity of code needed to interact with this type of buffer. */ -template -class RingBuffer -{ -private: +template class RingBuffer { + private: T buf[S]; size_t begin; size_t end; bool wrap; -public: - RingBuffer() : - begin(0), - end(0), - wrap(false) + public: + RingBuffer() : begin(0), end(0), wrap(false) { - memset(buf,0,sizeof(T)*S); + memset(buf, 0, sizeof(T) * S); } /** * @return A pointer to the underlying buffer */ - inline T *get_buf() + inline T* get_buf() { return buf + begin; } @@ -87,7 +82,10 @@ public: * Fast erase, O(1). * Merely reset the buffer pointer, doesn't erase contents */ - inline void reset() { consume(count()); } + inline void reset() + { + consume(count()); + } /** * adjust buffer index pointer as if we copied data out @@ -116,7 +114,7 @@ public: * @param data Buffer that is to be written to the ring * @param n Number of elements to write to the buffer */ - inline size_t write(const T * data, size_t n) + inline size_t write(const T* data, size_t n) { n = std::min(n, getFree()); if (n == 0) { @@ -157,14 +155,17 @@ public: /** * @return The most recently pushed element on the buffer */ - inline T get_most_recent() { return *(buf + end); } + inline T get_most_recent() + { + return *(buf + end); + } /** * @param dest Destination buffer * @param n Size (in terms of number of elements) of the destination buffer * @return Number of elements read from the buffer */ - inline size_t read(T *dest,size_t n) + inline size_t read(T* dest, size_t n) { n = std::min(n, count()); if (n == 0) { @@ -193,9 +194,11 @@ public: { if (end == begin) { return wrap ? S : 0; - } else if (end > begin) { + } + else if (end > begin) { return end - begin; - } else { + } + else { return S + end - begin; } } @@ -203,7 +206,10 @@ public: /** * @return The number of slots that are unused in the buffer */ - inline size_t getFree() { return S - count(); } + inline size_t getFree() + { + return S - count(); + } /** * @return The arithmetic mean of the contents of the buffer @@ -213,7 +219,7 @@ public: size_t iterator = begin; float subtotal = 0; size_t curr_cnt = count(); - for (size_t i=0; i - #include "Constants.hpp" -#include "Utils.hpp" #include "Identity.hpp" +#include "Utils.hpp" + +#include namespace ZeroTier { @@ -36,17 +36,9 @@ class PacketMultiplexer; /** * Holds global state for an instance of ZeroTier::Node */ -class RuntimeEnvironment -{ -public: - RuntimeEnvironment(Node *n) : - node(n) - ,localNetworkController((NetworkController *)0) - ,rtmem((void *)0) - ,sw((Switch *)0) - ,mc((Multicaster *)0) - ,topology((Topology *)0) - ,sa((SelfAwareness *)0) +class RuntimeEnvironment { + public: + RuntimeEnvironment(Node* n) : node(n), localNetworkController((NetworkController*)0), rtmem((void*)0), sw((Switch*)0), mc((Multicaster*)0), topology((Topology*)0), sa((SelfAwareness*)0) { publicIdentityStr[0] = (char)0; secretIdentityStr[0] = (char)0; @@ -54,17 +46,17 @@ public: ~RuntimeEnvironment() { - Utils::burn(secretIdentityStr,sizeof(secretIdentityStr)); + Utils::burn(secretIdentityStr, sizeof(secretIdentityStr)); } // Node instance that owns this RuntimeEnvironment - Node *const node; + Node* const node; // This is set externally to an instance of this base class - NetworkController *localNetworkController; + NetworkController* localNetworkController; // Memory actually occupied by Trace, Switch, etc. - void *rtmem; + void* rtmem; /* Order matters a bit here. These are constructed in this order * and then deleted in the opposite order on Node exit. The order ensures @@ -72,13 +64,13 @@ public: * * These are constant and never null after startup unless indicated. */ - Trace *t; - Switch *sw; - Multicaster *mc; - Topology *topology; - SelfAwareness *sa; - Bond *bc; - PacketMultiplexer *pm; + Trace* t; + Switch* sw; + Multicaster* mc; + Topology* topology; + SelfAwareness* sa; + Bond* bc; + PacketMultiplexer* pm; // This node's identity and string representations thereof Identity identity; @@ -86,6 +78,6 @@ public: char secretIdentityStr[ZT_IDENTITY_STRING_BUFFER_LENGTH]; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/SHA512.cpp b/node/SHA512.cpp index bd81647d0..8b3ae9189 100644 --- a/node/SHA512.cpp +++ b/node/SHA512.cpp @@ -1,10 +1,11 @@ // This code is public domain, taken from a PD crypto source file on GitHub. -#include - #include "SHA512.hpp" + #include "Utils.hpp" +#include + namespace ZeroTier { #ifndef ZT_HAVE_NATIVE_SHA512 @@ -12,48 +13,35 @@ namespace ZeroTier { namespace { struct sha512_state { - uint64_t length,state[8]; + uint64_t length, state[8]; unsigned long curlen; uint8_t buf[128]; }; -static const uint64_t K[80] = { - 0x428a2f98d728ae22ULL,0x7137449123ef65cdULL,0xb5c0fbcfec4d3b2fULL,0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL,0x59f111f1b605d019ULL,0x923f82a4af194f9bULL,0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL,0x12835b0145706fbeULL,0x243185be4ee4b28cULL,0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL,0x80deb1fe3b1696b1ULL,0x9bdc06a725c71235ULL,0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL,0xefbe4786384f25e3ULL,0x0fc19dc68b8cd5b5ULL,0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL,0x4a7484aa6ea6e483ULL,0x5cb0a9dcbd41fbd4ULL,0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL,0xa831c66d2db43210ULL,0xb00327c898fb213fULL,0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL,0xd5a79147930aa725ULL,0x06ca6351e003826fULL,0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL,0x2e1b21385c26c926ULL,0x4d2c6dfc5ac42aedULL,0x53380d139d95b3dfULL, - 0x650a73548baf63deULL,0x766a0abb3c77b2a8ULL,0x81c2c92e47edaee6ULL,0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL,0xa81a664bbc423001ULL,0xc24b8b70d0f89791ULL,0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL,0xd69906245565a910ULL,0xf40e35855771202aULL,0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL,0x1e376c085141ab53ULL,0x2748774cdf8eeb99ULL,0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL,0x4ed8aa4ae3418acbULL,0x5b9cca4f7763e373ULL,0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL,0x78a5636f43172f60ULL,0x84c87814a1f0ab72ULL,0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL,0xa4506cebde82bde9ULL,0xbef9a3f7b2c67915ULL,0xc67178f2e372532bULL, - 0xca273eceea26619cULL,0xd186b8c721c0c207ULL,0xeada7dd6cde0eb1eULL,0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL,0x0a637dc5a2c898a6ULL,0x113f9804bef90daeULL,0x1b710b35131c471bULL, - 0x28db77f523047d84ULL,0x32caab7b40c72493ULL,0x3c9ebe0a15c9bebcULL,0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL,0x597f299cfc657e2aULL,0x5fcb6fab3ad6faecULL,0x6c44198c4a475817ULL -}; +static const uint64_t K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; -#define STORE64H(x, y) Utils::storeBigEndian(y,x) -#define LOAD64H(x, y) x = Utils::loadBigEndian(y) -#define ROL64c(x,y) (((x)<<(y)) | ((x)>>(64-(y)))) -#define ROR64c(x,y) (((x)>>(y)) | ((x)<<(64-(y)))) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR64c(x, n) -#define R(x, n) ((x)>>(n)) -#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) -#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) -#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) -#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) +#define STORE64H(x, y) Utils::storeBigEndian(y, x) +#define LOAD64H(x, y) x = Utils::loadBigEndian(y) +#define ROL64c(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#define ROR64c(x, y) (((x) >> (y)) | ((x) << (64 - (y)))) +#define Ch(x, y, z) (z ^ (x & (y ^ z))) +#define Maj(x, y, z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64c(x, n) +#define R(x, n) ((x) >> (n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) -static ZT_INLINE void sha512_compress(sha512_state *const md,uint8_t *const buf) +static ZT_INLINE void sha512_compress(sha512_state* const md, uint8_t* const buf) { uint64_t S[8], W[80], t0, t1; int i; @@ -62,27 +50,27 @@ static ZT_INLINE void sha512_compress(sha512_state *const md,uint8_t *const buf) S[i] = md->state[i]; } for (i = 0; i < 16; i++) { - LOAD64H(W[i], buf + (8*i)); + LOAD64H(W[i], buf + (8 * i)); } for (i = 16; i < 80; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; } -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; +#define RND(a, b, c, d, e, f, g, h, i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; for (i = 0; i < 80; i += 8) { - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0); + RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1); + RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2); + RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3); + RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4); + RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5); + RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6); + RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7); } for (i = 0; i < 8; i++) { @@ -90,7 +78,7 @@ static ZT_INLINE void sha512_compress(sha512_state *const md,uint8_t *const buf) } } -static ZT_INLINE void sha384_init(sha512_state *const md) +static ZT_INLINE void sha384_init(sha512_state* const md) { md->curlen = 0; md->length = 0; @@ -104,7 +92,7 @@ static ZT_INLINE void sha384_init(sha512_state *const md) md->state[7] = 0x47b5481dbefa4fa4ULL; } -static ZT_INLINE void sha512_init(sha512_state *const md) +static ZT_INLINE void sha512_init(sha512_state* const md) { md->curlen = 0; md->length = 0; @@ -118,30 +106,31 @@ static ZT_INLINE void sha512_init(sha512_state *const md) md->state[7] = 0x5be0cd19137e2179ULL; } -static void sha512_process(sha512_state *const md,const uint8_t *in,unsigned long inlen) +static void sha512_process(sha512_state* const md, const uint8_t* in, unsigned long inlen) { while (inlen > 0) { if (md->curlen == 0 && inlen >= 128) { - sha512_compress(md,(uint8_t *)in); - md->length += 128 * 8; - in += 128; - inlen -= 128; - } else { - unsigned long n = std::min(inlen,(128 - md->curlen)); - Utils::copy(md->buf + md->curlen,in,n); + sha512_compress(md, (uint8_t*)in); + md->length += 128 * 8; + in += 128; + inlen -= 128; + } + else { + unsigned long n = std::min(inlen, (128 - md->curlen)); + Utils::copy(md->buf + md->curlen, in, n); md->curlen += n; - in += n; - inlen -= n; + in += n; + inlen -= n; if (md->curlen == 128) { - sha512_compress(md,md->buf); - md->length += 8*128; + sha512_compress(md, md->buf); + md->length += 8 * 128; md->curlen = 0; } } } } -static ZT_INLINE void sha512_done(sha512_state *const md,uint8_t *out) +static ZT_INLINE void sha512_done(sha512_state* const md, uint8_t* out) { int i; @@ -160,58 +149,58 @@ static ZT_INLINE void sha512_done(sha512_state *const md,uint8_t *out) md->buf[md->curlen++] = (uint8_t)0; } - STORE64H(md->length, md->buf+120); + STORE64H(md->length, md->buf + 120); sha512_compress(md, md->buf); for (i = 0; i < 8; i++) { - STORE64H(md->state[i], out+(8*i)); + STORE64H(md->state[i], out + (8 * i)); } } -} // anonymous namespace +} // anonymous namespace -void SHA512(void *digest,const void *data,unsigned int len) +void SHA512(void* digest, const void* data, unsigned int len) { sha512_state state; sha512_init(&state); - sha512_process(&state,(uint8_t *)data,(unsigned long)len); - sha512_done(&state,(uint8_t *)digest); + sha512_process(&state, (uint8_t*)data, (unsigned long)len); + sha512_done(&state, (uint8_t*)digest); } -void SHA384(void *digest,const void *data,unsigned int len) +void SHA384(void* digest, const void* data, unsigned int len) { uint8_t tmp[64]; sha512_state state; sha384_init(&state); - sha512_process(&state,(uint8_t *)data,(unsigned long)len); - sha512_done(&state,tmp); - Utils::copy<48>(digest,tmp); + sha512_process(&state, (uint8_t*)data, (unsigned long)len); + sha512_done(&state, tmp); + Utils::copy<48>(digest, tmp); } -void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) +void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1) { uint8_t tmp[64]; sha512_state state; sha384_init(&state); - sha512_process(&state,(uint8_t *)data0,(unsigned long)len0); - sha512_process(&state,(uint8_t *)data1,(unsigned long)len1); - sha512_done(&state,tmp); - Utils::copy<48>(digest,tmp); + sha512_process(&state, (uint8_t*)data0, (unsigned long)len0); + sha512_process(&state, (uint8_t*)data1, (unsigned long)len1); + sha512_done(&state, tmp); + Utils::copy<48>(digest, tmp); } -#endif // !ZT_HAVE_NATIVE_SHA512 +#endif // !ZT_HAVE_NATIVE_SHA512 -void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const void *msg,const unsigned int msglen,uint8_t mac[48]) +void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, const unsigned int msglen, uint8_t mac[48]) { - uint64_t kInPadded[16]; // input padded key - uint64_t outer[22]; // output padded key | H(input padded key | msg) + uint64_t kInPadded[16]; // input padded key + uint64_t outer[22]; // output padded key | H(input padded key | msg) - const uint64_t k0 = Utils::loadMachineEndian< uint64_t >(key); - const uint64_t k1 = Utils::loadMachineEndian< uint64_t >(key + 8); - const uint64_t k2 = Utils::loadMachineEndian< uint64_t >(key + 16); - const uint64_t k3 = Utils::loadMachineEndian< uint64_t >(key + 24); - const uint64_t k4 = Utils::loadMachineEndian< uint64_t >(key + 32); - const uint64_t k5 = Utils::loadMachineEndian< uint64_t >(key + 40); + const uint64_t k0 = Utils::loadMachineEndian(key); + const uint64_t k1 = Utils::loadMachineEndian(key + 8); + const uint64_t k2 = Utils::loadMachineEndian(key + 16); + const uint64_t k3 = Utils::loadMachineEndian(key + 24); + const uint64_t k4 = Utils::loadMachineEndian(key + 32); + const uint64_t k5 = Utils::loadMachineEndian(key + 40); const uint64_t ipad = 0x3636363636363636ULL; kInPadded[0] = k0 ^ ipad; @@ -250,18 +239,18 @@ void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const void *msg,const u outer[15] = opad; // H(output padded key | H(input padded key | msg)) - SHA384(reinterpret_cast(outer) + 128,kInPadded,128,msg,msglen); - SHA384(mac,outer,176); + SHA384(reinterpret_cast(outer) + 128, kInPadded, 128, msg, msglen); + SHA384(mac, outer, 176); } -void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const char label,const char context,const uint32_t iter,uint8_t out[ZT_SYMMETRIC_KEY_SIZE]) +void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const char label, const char context, const uint32_t iter, uint8_t out[ZT_SYMMETRIC_KEY_SIZE]) { uint8_t kbkdfMsg[13]; - Utils::storeBigEndian(kbkdfMsg,(uint32_t)iter); + Utils::storeBigEndian(kbkdfMsg, (uint32_t)iter); kbkdfMsg[4] = (uint8_t)'Z'; - kbkdfMsg[5] = (uint8_t)'T'; // preface our labels with something ZT-specific + kbkdfMsg[5] = (uint8_t)'T'; // preface our labels with something ZT-specific kbkdfMsg[6] = (uint8_t)label; kbkdfMsg[7] = 0; @@ -273,13 +262,15 @@ void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const char label,c kbkdfMsg[11] = 0x01; kbkdfMsg[12] = 0x80; - static_assert(ZT_SYMMETRIC_KEY_SIZE == ZT_SHA384_DIGEST_SIZE,"sizeof(out) != ZT_SHA384_DIGEST_SIZE"); - HMACSHA384(key,&kbkdfMsg,sizeof(kbkdfMsg),out); + static_assert(ZT_SYMMETRIC_KEY_SIZE == ZT_SHA384_DIGEST_SIZE, "sizeof(out) != ZT_SHA384_DIGEST_SIZE"); + HMACSHA384(key, &kbkdfMsg, sizeof(kbkdfMsg), out); } -} // namespace ZeroTier +} // namespace ZeroTier // Internally re-export to included C code, which includes some fast crypto code ported in on some platforms. // This eliminates the need to link against a third party SHA512() from this code -extern "C" void ZT_sha512internal(void *digest,const void *data,unsigned int len) -{ ZeroTier::SHA512(digest,data,len); } +extern "C" void ZT_sha512internal(void* digest, const void* data, unsigned int len) +{ + ZeroTier::SHA512(digest, data, len); +} diff --git a/node/SHA512.hpp b/node/SHA512.hpp index 93236a853..3849856ef 100644 --- a/node/SHA512.hpp +++ b/node/SHA512.hpp @@ -22,8 +22,8 @@ #define ZT_SHA512_DIGEST_SIZE 64 #define ZT_SHA384_DIGEST_SIZE 48 -#define ZT_SHA512_BLOCK_SIZE 128 -#define ZT_SHA384_BLOCK_SIZE 128 +#define ZT_SHA512_BLOCK_SIZE 128 +#define ZT_SHA384_BLOCK_SIZE 128 #define ZT_HMACSHA384_LEN 48 @@ -32,34 +32,34 @@ namespace ZeroTier { // SHA384 and SHA512 are actually in the standard libraries on MacOS and iOS #ifdef __APPLE__ #define ZT_HAVE_NATIVE_SHA512 1 -static ZT_INLINE void SHA512(void *digest,const void *data,unsigned int len) +static ZT_INLINE void SHA512(void* digest, const void* data, unsigned int len) { CC_SHA512_CTX ctx; CC_SHA512_Init(&ctx); - CC_SHA512_Update(&ctx,data,len); - CC_SHA512_Final(reinterpret_cast(digest),&ctx); + CC_SHA512_Update(&ctx, data, len); + CC_SHA512_Final(reinterpret_cast(digest), &ctx); } -static ZT_INLINE void SHA384(void *digest,const void *data,unsigned int len) +static ZT_INLINE void SHA384(void* digest, const void* data, unsigned int len) { CC_SHA512_CTX ctx; CC_SHA384_Init(&ctx); - CC_SHA384_Update(&ctx,data,len); - CC_SHA384_Final(reinterpret_cast(digest),&ctx); + CC_SHA384_Update(&ctx, data, len); + CC_SHA384_Final(reinterpret_cast(digest), &ctx); } -static ZT_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) +static ZT_INLINE void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1) { CC_SHA512_CTX ctx; CC_SHA384_Init(&ctx); - CC_SHA384_Update(&ctx,data0,len0); - CC_SHA384_Update(&ctx,data1,len1); - CC_SHA384_Final(reinterpret_cast(digest),&ctx); + CC_SHA384_Update(&ctx, data0, len0); + CC_SHA384_Update(&ctx, data1, len1); + CC_SHA384_Final(reinterpret_cast(digest), &ctx); } #endif #ifndef ZT_HAVE_NATIVE_SHA512 -void SHA512(void *digest,const void *data,unsigned int len); -void SHA384(void *digest,const void *data,unsigned int len); -void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1); +void SHA512(void* digest, const void* data, unsigned int len); +void SHA384(void* digest, const void* data, unsigned int len); +void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1); #endif /** @@ -70,7 +70,7 @@ void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,u * @param msglen Length of message * @param mac Buffer to fill with result */ -void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const void *msg,unsigned int msglen,uint8_t mac[48]); +void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, unsigned int msglen, uint8_t mac[48]); /** * Compute KBKDF (key-based key derivation function) using HMAC-SHA-384 as a PRF @@ -81,8 +81,8 @@ void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const void *msg,unsigne * @param iter Key iteration for generation of multiple keys for the same label/context * @param out Output to receive derived key */ -void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],char label,char context,uint32_t iter,uint8_t out[ZT_SYMMETRIC_KEY_SIZE]); +void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], char label, char context, uint32_t iter, uint8_t out[ZT_SYMMETRIC_KEY_SIZE]); -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Salsa20.cpp b/node/Salsa20.cpp index 63573546e..ad7ad5289 100644 --- a/node/Salsa20.cpp +++ b/node/Salsa20.cpp @@ -7,12 +7,13 @@ * Since the original was public domain, this is too. */ -#include "Constants.hpp" #include "Salsa20.hpp" -#define ROTATE(v,c) (((v) << (c)) | ((v) >> (32 - (c)))) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) ((uint32_t)((v) + (w))) +#include "Constants.hpp" + +#define ROTATE(v, c) (((v) << (c)) | ((v) >> (32 - (c)))) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) ((uint32_t)((v) + (w))) // Set up load/store macros with appropriate endianness (we don't use these in SSE mode) #ifndef ZT_SALSA20_SSE @@ -21,55 +22,66 @@ #ifdef ZT_NO_TYPE_PUNNING // Slower version that does not use type punning -#define U8TO32_LITTLE(p) ( ((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24) ) -static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (uint8_t)v; c[1] = (uint8_t)(v >> 8); c[2] = (uint8_t)(v >> 16); c[3] = (uint8_t)(v >> 24); } +#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24)) +static inline void U32TO8_LITTLE(uint8_t* const c, const uint32_t v) +{ + c[0] = (uint8_t)v; + c[1] = (uint8_t)(v >> 8); + c[2] = (uint8_t)(v >> 16); + c[3] = (uint8_t)(v >> 24); +} #else // Fast version that just does 32-bit load/store -#define U8TO32_LITTLE(p) (*((const uint32_t *)((const void *)(p)))) -#define U32TO8_LITTLE(c,v) *((uint32_t *)((void *)(c))) = (v) -#endif // ZT_NO_TYPE_PUNNING +#define U8TO32_LITTLE(p) (*((const uint32_t*)((const void*)(p)))) +#define U32TO8_LITTLE(c, v) *((uint32_t*)((void*)(c))) = (v) +#endif // ZT_NO_TYPE_PUNNING -#else // __BYTE_ORDER == __BIG_ENDIAN (we don't support anything else... does MIDDLE_ENDIAN even still exist?) +#else // __BYTE_ORDER == __BIG_ENDIAN (we don't support anything else... does MIDDLE_ENDIAN even still exist?) #ifdef __GNUC__ // Use GNUC builtin bswap macros on big-endian machines if available -#define U8TO32_LITTLE(p) __builtin_bswap32(*((const uint32_t *)((const void *)(p)))) -#define U32TO8_LITTLE(c,v) *((uint32_t *)((void *)(c))) = __builtin_bswap32((v)) +#define U8TO32_LITTLE(p) __builtin_bswap32(*((const uint32_t*)((const void*)(p)))) +#define U32TO8_LITTLE(c, v) *((uint32_t*)((void*)(c))) = __builtin_bswap32((v)) -#else // no __GNUC__ +#else // no __GNUC__ // Otherwise do it the slow, manual way on BE machines -#define U8TO32_LITTLE(p) ( ((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24) ) -static inline void U32TO8_LITTLE(uint8_t *const c,const uint32_t v) { c[0] = (uint8_t)v; c[1] = (uint8_t)(v >> 8); c[2] = (uint8_t)(v >> 16); c[3] = (uint8_t)(v >> 24); } +#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24)) +static inline void U32TO8_LITTLE(uint8_t* const c, const uint32_t v) +{ + c[0] = (uint8_t)v; + c[1] = (uint8_t)(v >> 8); + c[2] = (uint8_t)(v >> 16); + c[3] = (uint8_t)(v >> 24); +} -#endif // __GNUC__ or not +#endif // __GNUC__ or not -#endif // __BYTE_ORDER little or big? +#endif // __BYTE_ORDER little or big? -#endif // !ZT_SALSA20_SSE +#endif // !ZT_SALSA20_SSE // Statically compute and define SSE constants #ifdef ZT_SALSA20_SSE -class _s20sseconsts -{ -public: +class _s20sseconsts { + public: _s20sseconsts() { maskLo32 = _mm_shuffle_epi32(_mm_cvtsi32_si128(-1), _MM_SHUFFLE(1, 0, 1, 0)); maskHi32 = _mm_slli_epi64(maskLo32, 32); } - __m128i maskLo32,maskHi32; + __m128i maskLo32, maskHi32; }; static const _s20sseconsts _S20SSECONSTANTS; #endif namespace ZeroTier { -void Salsa20::init(const void *key,const void *iv) +void Salsa20::init(const void* key, const void* iv) { #ifdef ZT_SALSA20_SSE - const uint32_t *const k = (const uint32_t *)key; + const uint32_t* const k = (const uint32_t*)key; _state.i[0] = 0x61707865; _state.i[1] = 0x3320646e; _state.i[2] = 0x79622d32; @@ -81,22 +93,22 @@ void Salsa20::init(const void *key,const void *iv) _state.i[8] = 0; _state.i[9] = k[6]; _state.i[10] = k[1]; - _state.i[11] = ((const uint32_t *)iv)[1]; + _state.i[11] = ((const uint32_t*)iv)[1]; _state.i[12] = k[5]; _state.i[13] = k[0]; - _state.i[14] = ((const uint32_t *)iv)[0]; + _state.i[14] = ((const uint32_t*)iv)[0]; _state.i[15] = k[4]; #else - const char *const constants = "expand 32-byte k"; - const uint8_t *const k = (const uint8_t *)key; + const char* const constants = "expand 32-byte k"; + const uint8_t* const k = (const uint8_t*)key; _state.i[0] = U8TO32_LITTLE(constants + 0); _state.i[1] = U8TO32_LITTLE(k + 0); _state.i[2] = U8TO32_LITTLE(k + 4); _state.i[3] = U8TO32_LITTLE(k + 8); _state.i[4] = U8TO32_LITTLE(k + 12); _state.i[5] = U8TO32_LITTLE(constants + 4); - _state.i[6] = U8TO32_LITTLE(((const uint8_t *)iv) + 0); - _state.i[7] = U8TO32_LITTLE(((const uint8_t *)iv) + 4); + _state.i[6] = U8TO32_LITTLE(((const uint8_t*)iv) + 0); + _state.i[7] = U8TO32_LITTLE(((const uint8_t*)iv) + 4); _state.i[8] = 0; _state.i[9] = 0; _state.i[10] = U8TO32_LITTLE(constants + 8); @@ -108,12 +120,12 @@ void Salsa20::init(const void *key,const void *iv) #endif } -void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) +void Salsa20::crypt12(const void* in, void* out, unsigned int bytes) { uint8_t tmp[64]; - const uint8_t *m = (const uint8_t *)in; - uint8_t *c = (uint8_t *)out; - uint8_t *ctarget = c; + const uint8_t* m = (const uint8_t*)in; + uint8_t* c = (uint8_t*)out; + uint8_t* ctarget = c; unsigned int i; #ifndef ZT_SALSA20_SSE @@ -121,7 +133,7 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; #endif - if (!bytes) { + if (! bytes) { return; } @@ -146,7 +158,7 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) for (;;) { if (bytes < 64) { - for (i = 0;i < bytes;++i) { + for (i = 0; i < bytes; ++i) { tmp[i] = m[i]; } m = tmp; @@ -155,10 +167,10 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) } #ifdef ZT_SALSA20_SSE - __m128i X0 = _mm_loadu_si128((const __m128i *)&(_state.v[0])); - __m128i X1 = _mm_loadu_si128((const __m128i *)&(_state.v[1])); - __m128i X2 = _mm_loadu_si128((const __m128i *)&(_state.v[2])); - __m128i X3 = _mm_loadu_si128((const __m128i *)&(_state.v[3])); + __m128i X0 = _mm_loadu_si128((const __m128i*)&(_state.v[0])); + __m128i X1 = _mm_loadu_si128((const __m128i*)&(_state.v[1])); + __m128i X2 = _mm_loadu_si128((const __m128i*)&(_state.v[2])); + __m128i X3 = _mm_loadu_si128((const __m128i*)&(_state.v[3])); __m128i T; __m128i X0s = X0; __m128i X1s = X1; @@ -309,23 +321,23 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) X2 = _mm_shuffle_epi32(X2, 0x4E); X3 = _mm_shuffle_epi32(X3, 0x93); - X0 = _mm_add_epi32(X0s,X0); - X1 = _mm_add_epi32(X1s,X1); - X2 = _mm_add_epi32(X2s,X2); - X3 = _mm_add_epi32(X3s,X3); + X0 = _mm_add_epi32(X0s, X0); + X1 = _mm_add_epi32(X1s, X1); + X2 = _mm_add_epi32(X2s, X2); + X3 = _mm_add_epi32(X3s, X3); __m128i k02 = _mm_shuffle_epi32(_mm_or_si128(_mm_slli_epi64(X0, 32), _mm_srli_epi64(X3, 32)), _MM_SHUFFLE(0, 1, 2, 3)); __m128i k13 = _mm_shuffle_epi32(_mm_or_si128(_mm_slli_epi64(X1, 32), _mm_srli_epi64(X0, 32)), _MM_SHUFFLE(0, 1, 2, 3)); __m128i k20 = _mm_or_si128(_mm_and_si128(X2, _S20SSECONSTANTS.maskLo32), _mm_and_si128(X1, _S20SSECONSTANTS.maskHi32)); __m128i k31 = _mm_or_si128(_mm_and_si128(X3, _S20SSECONSTANTS.maskLo32), _mm_and_si128(X2, _S20SSECONSTANTS.maskHi32)); - _mm_storeu_ps(reinterpret_cast(c),_mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k02,k20),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m)))))); - _mm_storeu_ps(reinterpret_cast(c) + 4,_mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k13,k31),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 4))))); - _mm_storeu_ps(reinterpret_cast(c) + 8,_mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k20,k02),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 8))))); - _mm_storeu_ps(reinterpret_cast(c) + 12,_mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k31,k13),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 12))))); + _mm_storeu_ps(reinterpret_cast(c), _mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k02, k20), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m)))))); + _mm_storeu_ps(reinterpret_cast(c) + 4, _mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k13, k31), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 4))))); + _mm_storeu_ps(reinterpret_cast(c) + 8, _mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k20, k02), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 8))))); + _mm_storeu_ps(reinterpret_cast(c) + 12, _mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k31, k13), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 12))))); - if (!(++_state.i[8])) { - ++_state.i[5]; // state reordered for SSE - /* stopping at 2^70 bytes per nonce is user's responsibility */ + if (! (++_state.i[8])) { + ++_state.i[5]; // state reordered for SSE + /* stopping at 2^70 bytes per nonce is user's responsibility */ } #else x0 = j0; @@ -346,244 +358,244 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) x15 = j15; // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); - U32TO8_LITTLE(c + 0,XOR(x0,U8TO32_LITTLE(m + 0))); - U32TO8_LITTLE(c + 4,XOR(x1,U8TO32_LITTLE(m + 4))); - U32TO8_LITTLE(c + 8,XOR(x2,U8TO32_LITTLE(m + 8))); - U32TO8_LITTLE(c + 12,XOR(x3,U8TO32_LITTLE(m + 12))); - U32TO8_LITTLE(c + 16,XOR(x4,U8TO32_LITTLE(m + 16))); - U32TO8_LITTLE(c + 20,XOR(x5,U8TO32_LITTLE(m + 20))); - U32TO8_LITTLE(c + 24,XOR(x6,U8TO32_LITTLE(m + 24))); - U32TO8_LITTLE(c + 28,XOR(x7,U8TO32_LITTLE(m + 28))); - U32TO8_LITTLE(c + 32,XOR(x8,U8TO32_LITTLE(m + 32))); - U32TO8_LITTLE(c + 36,XOR(x9,U8TO32_LITTLE(m + 36))); - U32TO8_LITTLE(c + 40,XOR(x10,U8TO32_LITTLE(m + 40))); - U32TO8_LITTLE(c + 44,XOR(x11,U8TO32_LITTLE(m + 44))); - U32TO8_LITTLE(c + 48,XOR(x12,U8TO32_LITTLE(m + 48))); - U32TO8_LITTLE(c + 52,XOR(x13,U8TO32_LITTLE(m + 52))); - U32TO8_LITTLE(c + 56,XOR(x14,U8TO32_LITTLE(m + 56))); - U32TO8_LITTLE(c + 60,XOR(x15,U8TO32_LITTLE(m + 60))); + U32TO8_LITTLE(c + 0, XOR(x0, U8TO32_LITTLE(m + 0))); + U32TO8_LITTLE(c + 4, XOR(x1, U8TO32_LITTLE(m + 4))); + U32TO8_LITTLE(c + 8, XOR(x2, U8TO32_LITTLE(m + 8))); + U32TO8_LITTLE(c + 12, XOR(x3, U8TO32_LITTLE(m + 12))); + U32TO8_LITTLE(c + 16, XOR(x4, U8TO32_LITTLE(m + 16))); + U32TO8_LITTLE(c + 20, XOR(x5, U8TO32_LITTLE(m + 20))); + U32TO8_LITTLE(c + 24, XOR(x6, U8TO32_LITTLE(m + 24))); + U32TO8_LITTLE(c + 28, XOR(x7, U8TO32_LITTLE(m + 28))); + U32TO8_LITTLE(c + 32, XOR(x8, U8TO32_LITTLE(m + 32))); + U32TO8_LITTLE(c + 36, XOR(x9, U8TO32_LITTLE(m + 36))); + U32TO8_LITTLE(c + 40, XOR(x10, U8TO32_LITTLE(m + 40))); + U32TO8_LITTLE(c + 44, XOR(x11, U8TO32_LITTLE(m + 44))); + U32TO8_LITTLE(c + 48, XOR(x12, U8TO32_LITTLE(m + 48))); + U32TO8_LITTLE(c + 52, XOR(x13, U8TO32_LITTLE(m + 52))); + U32TO8_LITTLE(c + 56, XOR(x14, U8TO32_LITTLE(m + 56))); + U32TO8_LITTLE(c + 60, XOR(x15, U8TO32_LITTLE(m + 60))); - if (!(++j8)) { + if (! (++j8)) { ++j9; /* stopping at 2^70 bytes per nonce is user's responsibility */ } @@ -591,7 +603,7 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) if (bytes <= 64) { if (bytes < 64) { - for (i = 0;i < bytes;++i) { + for (i = 0; i < bytes; ++i) { ctarget[i] = c[i]; } } @@ -610,12 +622,12 @@ void Salsa20::crypt12(const void *in,void *out,unsigned int bytes) } } -void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) +void Salsa20::crypt20(const void* in, void* out, unsigned int bytes) { uint8_t tmp[64]; - const uint8_t *m = (const uint8_t *)in; - uint8_t *c = (uint8_t *)out; - uint8_t *ctarget = c; + const uint8_t* m = (const uint8_t*)in; + uint8_t* c = (uint8_t*)out; + uint8_t* ctarget = c; unsigned int i; #ifndef ZT_SALSA20_SSE @@ -623,7 +635,7 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; #endif - if (!bytes) { + if (! bytes) { return; } @@ -648,7 +660,7 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) for (;;) { if (bytes < 64) { - for (i = 0;i < bytes;++i) { + for (i = 0; i < bytes; ++i) { tmp[i] = m[i]; } m = tmp; @@ -657,10 +669,10 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) } #ifdef ZT_SALSA20_SSE - __m128i X0 = _mm_loadu_si128((const __m128i *)&(_state.v[0])); - __m128i X1 = _mm_loadu_si128((const __m128i *)&(_state.v[1])); - __m128i X2 = _mm_loadu_si128((const __m128i *)&(_state.v[2])); - __m128i X3 = _mm_loadu_si128((const __m128i *)&(_state.v[3])); + __m128i X0 = _mm_loadu_si128((const __m128i*)&(_state.v[0])); + __m128i X1 = _mm_loadu_si128((const __m128i*)&(_state.v[1])); + __m128i X2 = _mm_loadu_si128((const __m128i*)&(_state.v[2])); + __m128i X3 = _mm_loadu_si128((const __m128i*)&(_state.v[3])); __m128i T; __m128i X0s = X0; __m128i X1s = X1; @@ -907,23 +919,23 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) X2 = _mm_shuffle_epi32(X2, 0x4E); X3 = _mm_shuffle_epi32(X3, 0x93); - X0 = _mm_add_epi32(X0s,X0); - X1 = _mm_add_epi32(X1s,X1); - X2 = _mm_add_epi32(X2s,X2); - X3 = _mm_add_epi32(X3s,X3); + X0 = _mm_add_epi32(X0s, X0); + X1 = _mm_add_epi32(X1s, X1); + X2 = _mm_add_epi32(X2s, X2); + X3 = _mm_add_epi32(X3s, X3); __m128i k02 = _mm_shuffle_epi32(_mm_or_si128(_mm_slli_epi64(X0, 32), _mm_srli_epi64(X3, 32)), _MM_SHUFFLE(0, 1, 2, 3)); __m128i k13 = _mm_shuffle_epi32(_mm_or_si128(_mm_slli_epi64(X1, 32), _mm_srli_epi64(X0, 32)), _MM_SHUFFLE(0, 1, 2, 3)); __m128i k20 = _mm_or_si128(_mm_and_si128(X2, _S20SSECONSTANTS.maskLo32), _mm_and_si128(X1, _S20SSECONSTANTS.maskHi32)); __m128i k31 = _mm_or_si128(_mm_and_si128(X3, _S20SSECONSTANTS.maskLo32), _mm_and_si128(X2, _S20SSECONSTANTS.maskHi32)); - _mm_storeu_ps(reinterpret_cast(c),_mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k02,k20),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m)))))); - _mm_storeu_ps(reinterpret_cast(c) + 4,_mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k13,k31),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 4))))); - _mm_storeu_ps(reinterpret_cast(c) + 8,_mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k20,k02),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 8))))); - _mm_storeu_ps(reinterpret_cast(c) + 12,_mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k31,k13),_mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 12))))); + _mm_storeu_ps(reinterpret_cast(c), _mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k02, k20), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m)))))); + _mm_storeu_ps(reinterpret_cast(c) + 4, _mm_castsi128_ps(_mm_xor_si128(_mm_unpackhi_epi64(k13, k31), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 4))))); + _mm_storeu_ps(reinterpret_cast(c) + 8, _mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k20, k02), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 8))))); + _mm_storeu_ps(reinterpret_cast(c) + 12, _mm_castsi128_ps(_mm_xor_si128(_mm_unpacklo_epi64(k31, k13), _mm_castps_si128(_mm_loadu_ps(reinterpret_cast(m) + 12))))); - if (!(++_state.i[8])) { - ++_state.i[5]; // state reordered for SSE - /* stopping at 2^70 bytes per nonce is user's responsibility */ + if (! (++_state.i[8])) { + ++_state.i[5]; // state reordered for SSE + /* stopping at 2^70 bytes per nonce is user's responsibility */ } #else x0 = j0; @@ -944,380 +956,380 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) x15 = j15; // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); // 2X round ------------------------------------------------------------- - x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); - x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); - x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); - x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); - x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); - x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); - x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); - x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); - x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); - x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); - x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); - x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); - x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); - x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); - x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); - x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); - x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); - x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); - x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); - x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); - x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); - x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); - x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); - x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); - x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); - x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); - x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); - x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); - x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); - x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); - x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); - x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7)); + x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9)); + x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13)); + x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18)); + x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7)); + x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9)); + x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13)); + x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18)); + x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7)); + x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9)); + x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13)); + x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18)); + x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7)); + x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9)); + x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13)); + x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18)); + x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7)); + x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9)); + x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13)); + x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18)); + x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7)); + x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9)); + x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13)); + x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18)); + x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7)); + x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9)); + x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13)); + x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18)); + x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7)); + x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9)); + x14 = XOR(x14, ROTATE(PLUS(x13, x12), 13)); + x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18)); - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); - U32TO8_LITTLE(c + 0,XOR(x0,U8TO32_LITTLE(m + 0))); - U32TO8_LITTLE(c + 4,XOR(x1,U8TO32_LITTLE(m + 4))); - U32TO8_LITTLE(c + 8,XOR(x2,U8TO32_LITTLE(m + 8))); - U32TO8_LITTLE(c + 12,XOR(x3,U8TO32_LITTLE(m + 12))); - U32TO8_LITTLE(c + 16,XOR(x4,U8TO32_LITTLE(m + 16))); - U32TO8_LITTLE(c + 20,XOR(x5,U8TO32_LITTLE(m + 20))); - U32TO8_LITTLE(c + 24,XOR(x6,U8TO32_LITTLE(m + 24))); - U32TO8_LITTLE(c + 28,XOR(x7,U8TO32_LITTLE(m + 28))); - U32TO8_LITTLE(c + 32,XOR(x8,U8TO32_LITTLE(m + 32))); - U32TO8_LITTLE(c + 36,XOR(x9,U8TO32_LITTLE(m + 36))); - U32TO8_LITTLE(c + 40,XOR(x10,U8TO32_LITTLE(m + 40))); - U32TO8_LITTLE(c + 44,XOR(x11,U8TO32_LITTLE(m + 44))); - U32TO8_LITTLE(c + 48,XOR(x12,U8TO32_LITTLE(m + 48))); - U32TO8_LITTLE(c + 52,XOR(x13,U8TO32_LITTLE(m + 52))); - U32TO8_LITTLE(c + 56,XOR(x14,U8TO32_LITTLE(m + 56))); - U32TO8_LITTLE(c + 60,XOR(x15,U8TO32_LITTLE(m + 60))); + U32TO8_LITTLE(c + 0, XOR(x0, U8TO32_LITTLE(m + 0))); + U32TO8_LITTLE(c + 4, XOR(x1, U8TO32_LITTLE(m + 4))); + U32TO8_LITTLE(c + 8, XOR(x2, U8TO32_LITTLE(m + 8))); + U32TO8_LITTLE(c + 12, XOR(x3, U8TO32_LITTLE(m + 12))); + U32TO8_LITTLE(c + 16, XOR(x4, U8TO32_LITTLE(m + 16))); + U32TO8_LITTLE(c + 20, XOR(x5, U8TO32_LITTLE(m + 20))); + U32TO8_LITTLE(c + 24, XOR(x6, U8TO32_LITTLE(m + 24))); + U32TO8_LITTLE(c + 28, XOR(x7, U8TO32_LITTLE(m + 28))); + U32TO8_LITTLE(c + 32, XOR(x8, U8TO32_LITTLE(m + 32))); + U32TO8_LITTLE(c + 36, XOR(x9, U8TO32_LITTLE(m + 36))); + U32TO8_LITTLE(c + 40, XOR(x10, U8TO32_LITTLE(m + 40))); + U32TO8_LITTLE(c + 44, XOR(x11, U8TO32_LITTLE(m + 44))); + U32TO8_LITTLE(c + 48, XOR(x12, U8TO32_LITTLE(m + 48))); + U32TO8_LITTLE(c + 52, XOR(x13, U8TO32_LITTLE(m + 52))); + U32TO8_LITTLE(c + 56, XOR(x14, U8TO32_LITTLE(m + 56))); + U32TO8_LITTLE(c + 60, XOR(x15, U8TO32_LITTLE(m + 60))); - if (!(++j8)) { + if (! (++j8)) { ++j9; /* stopping at 2^70 bytes per nonce is user's responsibility */ } @@ -1325,7 +1337,7 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) if (bytes <= 64) { if (bytes < 64) { - for (i = 0;i < bytes;++i) { + for (i = 0; i < bytes; ++i) { ctarget[i] = c[i]; } } @@ -1344,4 +1356,4 @@ void Salsa20::crypt20(const void *in,void *out,unsigned int bytes) } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Salsa20.hpp b/node/Salsa20.hpp index 893553866..9efaa1b9f 100644 --- a/node/Salsa20.hpp +++ b/node/Salsa20.hpp @@ -7,32 +7,36 @@ #ifndef ZT_SALSA20_HPP #define ZT_SALSA20_HPP -#include -#include -#include -#include - #include "Constants.hpp" #include "Utils.hpp" -#if (!defined(ZT_SALSA20_SSE)) && (defined(__SSE2__) || (defined(__WINDOWS__) && !defined(__MINGW32__) && !defined(_M_ARM64))) +#include +#include +#include +#include + +#if (! defined(ZT_SALSA20_SSE)) && (defined(__SSE2__) || (defined(__WINDOWS__) && ! defined(__MINGW32__) && ! defined(_M_ARM64))) #define ZT_SALSA20_SSE 1 #endif #ifdef ZT_SALSA20_SSE #include -#endif // ZT_SALSA20_SSE +#endif // ZT_SALSA20_SSE namespace ZeroTier { /** * Salsa20 stream cipher */ -class Salsa20 -{ -public: - Salsa20() {} - ~Salsa20() { Utils::burn(&_state,sizeof(_state)); } +class Salsa20 { + public: + Salsa20() + { + } + ~Salsa20() + { + Utils::burn(&_state, sizeof(_state)); + } /** * XOR d with s @@ -45,48 +49,48 @@ public: * @param s Source bytes to XOR with destination * @param len Length of s and d */ - static inline void memxor(uint8_t *d,const uint8_t *s,unsigned int len) + static inline void memxor(uint8_t* d, const uint8_t* s, unsigned int len) { #ifdef ZT_SALSA20_SSE while (len >= 128) { - __m128i s0 = _mm_loadu_si128(reinterpret_cast(s)); - __m128i s1 = _mm_loadu_si128(reinterpret_cast(s + 16)); - __m128i s2 = _mm_loadu_si128(reinterpret_cast(s + 32)); - __m128i s3 = _mm_loadu_si128(reinterpret_cast(s + 48)); - __m128i s4 = _mm_loadu_si128(reinterpret_cast(s + 64)); - __m128i s5 = _mm_loadu_si128(reinterpret_cast(s + 80)); - __m128i s6 = _mm_loadu_si128(reinterpret_cast(s + 96)); - __m128i s7 = _mm_loadu_si128(reinterpret_cast(s + 112)); - __m128i d0 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d)); - __m128i d1 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 16)); - __m128i d2 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 32)); - __m128i d3 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 48)); - __m128i d4 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 64)); - __m128i d5 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 80)); - __m128i d6 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 96)); - __m128i d7 = _mm_loadu_si128(reinterpret_cast<__m128i *>(d + 112)); - d0 = _mm_xor_si128(d0,s0); - d1 = _mm_xor_si128(d1,s1); - d2 = _mm_xor_si128(d2,s2); - d3 = _mm_xor_si128(d3,s3); - d4 = _mm_xor_si128(d4,s4); - d5 = _mm_xor_si128(d5,s5); - d6 = _mm_xor_si128(d6,s6); - d7 = _mm_xor_si128(d7,s7); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d),d0); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 16),d1); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 32),d2); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 48),d3); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 64),d4); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 80),d5); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 96),d6); - _mm_storeu_si128(reinterpret_cast<__m128i *>(d + 112),d7); + __m128i s0 = _mm_loadu_si128(reinterpret_cast(s)); + __m128i s1 = _mm_loadu_si128(reinterpret_cast(s + 16)); + __m128i s2 = _mm_loadu_si128(reinterpret_cast(s + 32)); + __m128i s3 = _mm_loadu_si128(reinterpret_cast(s + 48)); + __m128i s4 = _mm_loadu_si128(reinterpret_cast(s + 64)); + __m128i s5 = _mm_loadu_si128(reinterpret_cast(s + 80)); + __m128i s6 = _mm_loadu_si128(reinterpret_cast(s + 96)); + __m128i s7 = _mm_loadu_si128(reinterpret_cast(s + 112)); + __m128i d0 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d)); + __m128i d1 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 16)); + __m128i d2 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 32)); + __m128i d3 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 48)); + __m128i d4 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 64)); + __m128i d5 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 80)); + __m128i d6 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 96)); + __m128i d7 = _mm_loadu_si128(reinterpret_cast<__m128i*>(d + 112)); + d0 = _mm_xor_si128(d0, s0); + d1 = _mm_xor_si128(d1, s1); + d2 = _mm_xor_si128(d2, s2); + d3 = _mm_xor_si128(d3, s3); + d4 = _mm_xor_si128(d4, s4); + d5 = _mm_xor_si128(d5, s5); + d6 = _mm_xor_si128(d6, s6); + d7 = _mm_xor_si128(d7, s7); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d), d0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 16), d1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 32), d2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 48), d3); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 64), d4); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 80), d5); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 96), d6); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d + 112), d7); s += 128; d += 128; len -= 128; } while (len >= 16) { - _mm_storeu_si128(reinterpret_cast<__m128i *>(d),_mm_xor_si128(_mm_loadu_si128(reinterpret_cast<__m128i *>(d)),_mm_loadu_si128(reinterpret_cast(s)))); + _mm_storeu_si128(reinterpret_cast<__m128i*>(d), _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<__m128i*>(d)), _mm_loadu_si128(reinterpret_cast(s)))); s += 16; d += 16; len -= 16; @@ -94,10 +98,10 @@ public: #else #ifndef ZT_NO_TYPE_PUNNING while (len >= 16) { - (*reinterpret_cast(d)) ^= (*reinterpret_cast(s)); + (*reinterpret_cast(d)) ^= (*reinterpret_cast(s)); s += 8; d += 8; - (*reinterpret_cast(d)) ^= (*reinterpret_cast(s)); + (*reinterpret_cast(d)) ^= (*reinterpret_cast(s)); s += 8; d += 8; len -= 16; @@ -114,9 +118,9 @@ public: * @param key 256-bit (32 byte) key * @param iv 64-bit initialization vector */ - Salsa20(const void *key,const void *iv) + Salsa20(const void* key, const void* iv) { - init(key,iv); + init(key, iv); } /** @@ -125,7 +129,7 @@ public: * @param key Key bits * @param iv 64-bit initialization vector */ - void init(const void *key,const void *iv); + void init(const void* key, const void* iv); /** * Encrypt/decrypt data using Salsa20/12 @@ -134,7 +138,7 @@ public: * @param out Output buffer * @param bytes Length of data */ - void crypt12(const void *in,void *out,unsigned int bytes); + void crypt12(const void* in, void* out, unsigned int bytes); /** * Encrypt/decrypt data using Salsa20/20 @@ -143,17 +147,17 @@ public: * @param out Output buffer * @param bytes Length of data */ - void crypt20(const void *in,void *out,unsigned int bytes); + void crypt20(const void* in, void* out, unsigned int bytes); -private: + private: union { #ifdef ZT_SALSA20_SSE __m128i v[4]; -#endif // ZT_SALSA20_SSE +#endif // ZT_SALSA20_SSE uint32_t i[16]; } _state; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index dab19c6b2..c73dd4b05 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -11,66 +11,64 @@ */ /****/ +#include "SelfAwareness.hpp" + +#include "Constants.hpp" +#include "Node.hpp" +#include "Packet.hpp" +#include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" +#include "Trace.hpp" + +#include #include #include #include - -#include #include -#include "Constants.hpp" -#include "SelfAwareness.hpp" -#include "RuntimeEnvironment.hpp" -#include "Node.hpp" -#include "Topology.hpp" -#include "Packet.hpp" -#include "Peer.hpp" -#include "Switch.hpp" -#include "Trace.hpp" - // Entry timeout -- make it fairly long since this is just to prevent stale buildup #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 600000 namespace ZeroTier { -class _ResetWithinScope -{ -public: - _ResetWithinScope(void *tPtr,int64_t now,int inetAddressFamily,InetAddress::IpScope scope) : - _now(now), - _tPtr(tPtr), - _family(inetAddressFamily), - _scope(scope) {} +class _ResetWithinScope { + public: + _ResetWithinScope(void* tPtr, int64_t now, int inetAddressFamily, InetAddress::IpScope scope) : _now(now), _tPtr(tPtr), _family(inetAddressFamily), _scope(scope) + { + } - inline void operator()(Topology &t,const SharedPtr &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); } + inline void operator()(Topology& t, const SharedPtr& p) + { + p->resetWithinScope(_tPtr, _scope, _family, _now); + } -private: + private: uint64_t _now; - void *_tPtr; + void* _tPtr; int _family; InetAddress::IpScope _scope; }; -SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) : - RR(renv), - _phy(128) +SelfAwareness::SelfAwareness(const RuntimeEnvironment* renv) : RR(renv), _phy(128) { } -void SelfAwareness::iam(void *tPtr,const Address &reporter,const int64_t receivedOnLocalSocket,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,int64_t now) +void SelfAwareness::iam(void* tPtr, const Address& reporter, const int64_t receivedOnLocalSocket, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, bool trusted, int64_t now) { const InetAddress::IpScope scope = myPhysicalAddress.ipScope(); - if ((scope != reporterPhysicalAddress.ipScope())||(scope == InetAddress::IP_SCOPE_NONE)||(scope == InetAddress::IP_SCOPE_LOOPBACK)||(scope == InetAddress::IP_SCOPE_MULTICAST)) { + if ((scope != reporterPhysicalAddress.ipScope()) || (scope == InetAddress::IP_SCOPE_NONE) || (scope == InetAddress::IP_SCOPE_LOOPBACK) || (scope == InetAddress::IP_SCOPE_MULTICAST)) { return; } Mutex::Lock _l(_phy_m); - PhySurfaceEntry &entry = _phy[PhySurfaceKey(reporter,receivedOnLocalSocket,reporterPhysicalAddress,scope)]; + PhySurfaceEntry& entry = _phy[PhySurfaceKey(reporter, receivedOnLocalSocket, reporterPhysicalAddress, scope)]; - if ( (trusted) && ((now - entry.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (!entry.mySurface.ipsEqual(myPhysicalAddress)) ) { + if ((trusted) && ((now - entry.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (! entry.mySurface.ipsEqual(myPhysicalAddress))) { // Changes to external surface reported by trusted peers causes path reset in this scope - RR->t->resettingPathsInScope(tPtr,reporter,reporterPhysicalAddress,myPhysicalAddress,scope); + RR->t->resettingPathsInScope(tPtr, reporter, reporterPhysicalAddress, myPhysicalAddress, scope); entry.mySurface = myPhysicalAddress; entry.ts = now; @@ -80,20 +78,21 @@ void SelfAwareness::iam(void *tPtr,const Address &reporter,const int64_t receive // due to multiple reports of endpoint change. // Don't use 'entry' after this since hash table gets modified. { - Hashtable< PhySurfaceKey,PhySurfaceEntry >::Iterator i(_phy); - PhySurfaceKey *k = (PhySurfaceKey *)0; - PhySurfaceEntry *e = (PhySurfaceEntry *)0; - while (i.next(k,e)) { - if ((k->reporterPhysicalAddress != reporterPhysicalAddress)&&(k->scope == scope)) { + Hashtable::Iterator i(_phy); + PhySurfaceKey* k = (PhySurfaceKey*)0; + PhySurfaceEntry* e = (PhySurfaceEntry*)0; + while (i.next(k, e)) { + if ((k->reporterPhysicalAddress != reporterPhysicalAddress) && (k->scope == scope)) { _phy.erase(*k); } } } // Reset all paths within this scope and address family - _ResetWithinScope rset(tPtr,now,myPhysicalAddress.ss_family,(InetAddress::IpScope)scope); - RR->topology->eachPeer<_ResetWithinScope &>(rset); - } else { + _ResetWithinScope rset(tPtr, now, myPhysicalAddress.ss_family, (InetAddress::IpScope)scope); + RR->topology->eachPeer<_ResetWithinScope&>(rset); + } + else { // Otherwise just update DB to use to determine external surface info entry.mySurface = myPhysicalAddress; entry.ts = now; @@ -105,10 +104,10 @@ std::vector SelfAwareness::whoami() { std::vector surfaceAddresses; Mutex::Lock _l(_phy_m); - Hashtable< PhySurfaceKey,PhySurfaceEntry >::Iterator i(_phy); - PhySurfaceKey *k = (PhySurfaceKey *)0; - PhySurfaceEntry *e = (PhySurfaceEntry *)0; - while (i.next(k,e)) { + Hashtable::Iterator i(_phy); + PhySurfaceKey* k = (PhySurfaceKey*)0; + PhySurfaceEntry* e = (PhySurfaceEntry*)0; + while (i.next(k, e)) { if (std::find(surfaceAddresses.begin(), surfaceAddresses.end(), e->mySurface) == surfaceAddresses.end()) { surfaceAddresses.push_back(e->mySurface); } @@ -119,14 +118,14 @@ std::vector SelfAwareness::whoami() void SelfAwareness::clean(int64_t now) { Mutex::Lock _l(_phy_m); - Hashtable< PhySurfaceKey,PhySurfaceEntry >::Iterator i(_phy); - PhySurfaceKey *k = (PhySurfaceKey *)0; - PhySurfaceEntry *e = (PhySurfaceEntry *)0; - while (i.next(k,e)) { + Hashtable::Iterator i(_phy); + PhySurfaceKey* k = (PhySurfaceKey*)0; + PhySurfaceEntry* e = (PhySurfaceEntry*)0; + while (i.next(k, e)) { if ((now - e->ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT) { _phy.erase(*k); } } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/SelfAwareness.hpp b/node/SelfAwareness.hpp index 2f7352825..527537003 100644 --- a/node/SelfAwareness.hpp +++ b/node/SelfAwareness.hpp @@ -14,10 +14,10 @@ #ifndef ZT_SELFAWARENESS_HPP #define ZT_SELFAWARENESS_HPP -#include "Constants.hpp" -#include "InetAddress.hpp" -#include "Hashtable.hpp" #include "Address.hpp" +#include "Constants.hpp" +#include "Hashtable.hpp" +#include "InetAddress.hpp" #include "Mutex.hpp" namespace ZeroTier { @@ -27,10 +27,9 @@ class RuntimeEnvironment; /** * Tracks changes to this peer's real world addresses */ -class SelfAwareness -{ -public: - SelfAwareness(const RuntimeEnvironment *renv); +class SelfAwareness { + public: + SelfAwareness(const RuntimeEnvironment* renv); /** * Called when a trusted remote peer informs us of our external network address @@ -42,7 +41,7 @@ public: * @param trusted True if this peer is trusted as an authority to inform us of external address changes * @param now Current time */ - void iam(void *tPtr,const Address &reporter,const int64_t receivedOnLocalSocket,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,int64_t now); + void iam(void* tPtr, const Address& reporter, const int64_t receivedOnLocalSocket, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, bool trusted, int64_t now); /** * Return all known external surface addresses reported by peers @@ -58,36 +57,48 @@ public: */ void clean(int64_t now); -private: - struct PhySurfaceKey - { + private: + struct PhySurfaceKey { Address reporter; int64_t receivedOnLocalSocket; InetAddress reporterPhysicalAddress; InetAddress::IpScope scope; - PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {} - PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {} + PhySurfaceKey() : reporter(), scope(InetAddress::IP_SCOPE_NONE) + { + } + PhySurfaceKey(const Address& r, const int64_t rol, const InetAddress& ra, InetAddress::IpScope s) : reporter(r), receivedOnLocalSocket(rol), reporterPhysicalAddress(ra), scope(s) + { + } - inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); } - inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); } + inline unsigned long hashCode() const + { + return ((unsigned long)reporter.toInt() + (unsigned long)scope); + } + inline bool operator==(const PhySurfaceKey& k) const + { + return ((reporter == k.reporter) && (receivedOnLocalSocket == k.receivedOnLocalSocket) && (reporterPhysicalAddress == k.reporterPhysicalAddress) && (scope == k.scope)); + } }; - struct PhySurfaceEntry - { + struct PhySurfaceEntry { InetAddress mySurface; uint64_t ts; bool trusted; - PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {} - PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {} + PhySurfaceEntry() : mySurface(), ts(0), trusted(false) + { + } + PhySurfaceEntry(const InetAddress& a, const uint64_t t) : mySurface(a), ts(t), trusted(false) + { + } }; - const RuntimeEnvironment *RR; + const RuntimeEnvironment* RR; - Hashtable< PhySurfaceKey,PhySurfaceEntry > _phy; + Hashtable _phy; Mutex _phy_m; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/SharedPtr.hpp b/node/SharedPtr.hpp index e172b578d..ef720cab8 100644 --- a/node/SharedPtr.hpp +++ b/node/SharedPtr.hpp @@ -14,8 +14,8 @@ #ifndef ZT_SHAREDPTR_HPP #define ZT_SHAREDPTR_HPP -#include "Mutex.hpp" #include "AtomicCounter.hpp" +#include "Mutex.hpp" namespace ZeroTier { @@ -26,13 +26,18 @@ namespace ZeroTier { * counted must list this as a 'friend' and must have a private instance of * AtomicCounter called __refCount. */ -template -class SharedPtr -{ -public: - SharedPtr() : _ptr((T *)0) {} - SharedPtr(T *obj) : _ptr(obj) { ++obj->__refCount; } - SharedPtr(const SharedPtr &sp) : _ptr(sp._getAndInc()) {} +template class SharedPtr { + public: + SharedPtr() : _ptr((T*)0) + { + } + SharedPtr(T* obj) : _ptr(obj) + { + ++obj->__refCount; + } + SharedPtr(const SharedPtr& sp) : _ptr(sp._getAndInc()) + { + } ~SharedPtr() { @@ -43,10 +48,10 @@ public: } } - inline SharedPtr &operator=(const SharedPtr &sp) + inline SharedPtr& operator=(const SharedPtr& sp) { if (_ptr != sp._ptr) { - T *p = sp._getAndInc(); + T* p = sp._getAndInc(); if (_ptr) { if (--_ptr->__refCount <= 0) { delete _ptr; @@ -65,7 +70,7 @@ public: * * @param ptr Naked pointer to assign */ - inline void set(T *ptr) + inline void set(T* ptr) { zero(); ++ptr->__refCount; @@ -77,21 +82,33 @@ public: * * @param with Pointer to swap with */ - inline void swap(SharedPtr &with) + inline void swap(SharedPtr& with) { - T *tmp = _ptr; + T* tmp = _ptr; _ptr = with._ptr; with._ptr = tmp; } - inline operator bool() const { return (_ptr != (T *)0); } - inline T &operator*() const { return *_ptr; } - inline T *operator->() const { return _ptr; } + inline operator bool() const + { + return (_ptr != (T*)0); + } + inline T& operator*() const + { + return *_ptr; + } + inline T* operator->() const + { + return _ptr; + } /** * @return Raw pointer to held object */ - inline T *ptr() const { return _ptr; } + inline T* ptr() const + { + return _ptr; + } /** * Set this pointer to NULL @@ -102,7 +119,7 @@ public: if (--_ptr->__refCount <= 0) { delete _ptr; } - _ptr = (T *)0; + _ptr = (T*)0; } } @@ -117,24 +134,42 @@ public: return 0; } - inline bool operator==(const SharedPtr &sp) const { return (_ptr == sp._ptr); } - inline bool operator!=(const SharedPtr &sp) const { return (_ptr != sp._ptr); } - inline bool operator>(const SharedPtr &sp) const { return (_ptr > sp._ptr); } - inline bool operator<(const SharedPtr &sp) const { return (_ptr < sp._ptr); } - inline bool operator>=(const SharedPtr &sp) const { return (_ptr >= sp._ptr); } - inline bool operator<=(const SharedPtr &sp) const { return (_ptr <= sp._ptr); } + inline bool operator==(const SharedPtr& sp) const + { + return (_ptr == sp._ptr); + } + inline bool operator!=(const SharedPtr& sp) const + { + return (_ptr != sp._ptr); + } + inline bool operator>(const SharedPtr& sp) const + { + return (_ptr > sp._ptr); + } + inline bool operator<(const SharedPtr& sp) const + { + return (_ptr < sp._ptr); + } + inline bool operator>=(const SharedPtr& sp) const + { + return (_ptr >= sp._ptr); + } + inline bool operator<=(const SharedPtr& sp) const + { + return (_ptr <= sp._ptr); + } -private: - inline T *_getAndInc() const + private: + inline T* _getAndInc() const { if (_ptr) { ++_ptr->__refCount; } return _ptr; } - T *_ptr; + T* _ptr; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Switch.cpp b/node/Switch.cpp index 7664f7a48..ec651bbd5 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -11,40 +11,35 @@ */ /****/ -#include -#include +#include "Switch.hpp" + +#include "../include/ZeroTierOne.h" +#include "../version.h" +#include "Constants.hpp" +#include "InetAddress.hpp" +#include "Metrics.hpp" +#include "Node.hpp" +#include "Packet.hpp" +#include "Peer.hpp" +#include "RuntimeEnvironment.hpp" +#include "SelfAwareness.hpp" +#include "Topology.hpp" +#include "Trace.hpp" #include -#include #include - -#include "../version.h" -#include "../include/ZeroTierOne.h" - -#include "Constants.hpp" -#include "RuntimeEnvironment.hpp" -#include "Switch.hpp" -#include "Node.hpp" -#include "InetAddress.hpp" -#include "Topology.hpp" -#include "Peer.hpp" -#include "SelfAwareness.hpp" -#include "Packet.hpp" -#include "Trace.hpp" -#include "Metrics.hpp" +#include +#include +#include namespace ZeroTier { -Switch::Switch(const RuntimeEnvironment *renv) : - RR(renv), - _lastBeaconResponse(0), - _lastCheckedQueues(0), - _lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine +Switch::Switch(const RuntimeEnvironment* renv) : RR(renv), _lastBeaconResponse(0), _lastCheckedQueues(0), _lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine { } // Returns true if packet appears valid; pos and proto will be set -static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsigned int &pos,unsigned int &proto) +static bool _ipv6GetPayload(const uint8_t* frameData, unsigned int frameLen, unsigned int& pos, unsigned int& proto) { if (frameLen < 40) { return false; @@ -52,35 +47,35 @@ static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsig pos = 40; proto = frameData[6]; while (pos <= frameLen) { - switch(proto) { - case 0: // hop-by-hop options - case 43: // routing - case 60: // destination options - case 135: // mobility options + switch (proto) { + case 0: // hop-by-hop options + case 43: // routing + case 60: // destination options + case 135: // mobility options if ((pos + 8) > frameLen) { - return false; // invalid! + return false; // invalid! } proto = frameData[pos]; pos += ((unsigned int)frameData[pos + 1] * 8) + 8; break; - //case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway - //case 50: - //case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff + // case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway + // case 50: + // case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff default: return true; } } - return false; // overflow == invalid + return false; // overflow == invalid } -void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::onRemotePacket(void* tPtr, const int64_t localSocket, const InetAddress& fromAddr, const void* data, unsigned int len) { int32_t flowId = ZT_QOS_NO_FLOW; try { const int64_t now = RR->node->now(); - const SharedPtr path(RR->topology->getPath(localSocket,fromAddr)); + const SharedPtr path(RR->topology->getPath(localSocket, fromAddr)); path->received(now); if (len == 13) { @@ -89,33 +84,33 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre * no longer send these, but we'll listen for them for a while to * locate peers with versions <1.0.4. */ - const Address beaconAddr(reinterpret_cast(data) + 8,5); + const Address beaconAddr(reinterpret_cast(data) + 8, 5); if (beaconAddr == RR->identity.address()) { return; } - if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localSocket,fromAddr)) { + if (! RR->node->shouldUsePathForZeroTierTraffic(tPtr, beaconAddr, localSocket, fromAddr)) { return; } - const SharedPtr peer(RR->topology->getPeer(tPtr,beaconAddr)); - if (peer) { // we'll only respond to beacons from known peers - if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses + const SharedPtr peer(RR->topology->getPeer(tPtr, beaconAddr)); + if (peer) { // we'll only respond to beacons from known peers + if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses _lastBeaconResponse = now; - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_NOP); + outp.armor(peer->key(), true, peer->aesKeysIfSupported()); Metrics::pkt_nop_out++; - path->send(RR,tPtr,outp.data(),outp.size(),now); + path->send(RR, tPtr, outp.data(), outp.size(), now); } } - - } else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below! - if (reinterpret_cast(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { + } + else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below! + if (reinterpret_cast(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { // Handle fragment ---------------------------------------------------- - Packet::Fragment fragment(data,len); + Packet::Fragment fragment(data, len); const Address destination(fragment.destination()); if (destination != RR->identity.address()) { - if ( (!RR->topology->amUpstream()) && (!path->trustEstablished(now)) ) { + if ((! RR->topology->amUpstream()) && (! path->trustEstablished(now))) { return; } @@ -124,28 +119,29 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre // Note: we don't bother initiating NAT-t for fragments, since heads will set that off. // It wouldn't hurt anything, just redundant and unnecessary. - SharedPtr relayTo = RR->topology->getPeer(tPtr,destination); - if ((!relayTo)||(!relayTo->sendDirect(tPtr,fragment.data(),fragment.size(),now,false))) { + SharedPtr relayTo = RR->topology->getPeer(tPtr, destination); + if ((! relayTo) || (! relayTo->sendDirect(tPtr, fragment.data(), fragment.size(), now, false))) { // Don't know peer or no direct path -- so relay via someone upstream relayTo = RR->topology->getUpstreamPeer(); if (relayTo) { - relayTo->sendDirect(tPtr,fragment.data(),fragment.size(),now,true); + relayTo->sendDirect(tPtr, fragment.data(), fragment.size(), now, true); } } } - } else { + } + else { // Fragment looks like ours const uint64_t fragmentPacketId = fragment.packetId(); const unsigned int fragmentNumber = fragment.fragmentNumber(); const unsigned int totalFragments = fragment.totalFragments(); - if ((totalFragments <= ZT_MAX_PACKET_FRAGMENTS)&&(fragmentNumber < ZT_MAX_PACKET_FRAGMENTS)&&(fragmentNumber > 0)&&(totalFragments > 1)) { + if ((totalFragments <= ZT_MAX_PACKET_FRAGMENTS) && (fragmentNumber < ZT_MAX_PACKET_FRAGMENTS) && (fragmentNumber > 0) && (totalFragments > 1)) { // Fragment appears basically sane. Its fragment number must be // 1 or more, since a Packet with fragmented bit set is fragment 0. // Total fragments must be more than 1, otherwise why are we // seeing a Packet::Fragment? - RXQueueEntry *const rq = _findRXQueueEntry(fragmentPacketId); + RXQueueEntry* const rq = _findRXQueueEntry(fragmentPacketId); Mutex::Lock rql(rq->lock); if (rq->packetId != fragmentPacketId) { // No packet found, so we received a fragment without its head. @@ -154,10 +150,11 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre rq->timestamp = now; rq->packetId = fragmentPacketId; rq->frags[fragmentNumber - 1] = fragment; - rq->totalFragments = totalFragments; // total fragment count is known - rq->haveFragments = 1 << fragmentNumber; // we have only this fragment + rq->totalFragments = totalFragments; // total fragment count is known + rq->haveFragments = 1 << fragmentNumber; // we have only this fragment rq->complete = false; - } else if (!(rq->haveFragments & (1 << fragmentNumber))) { + } + else if (! (rq->haveFragments & (1 << fragmentNumber))) { // We have other fragments and maybe the head, so add this one and check rq->frags[fragmentNumber - 1] = fragment; @@ -166,75 +163,73 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre if (Utils::countBits(rq->haveFragments |= (1 << fragmentNumber)) == totalFragments) { // We have all fragments -- assemble and process full Packet - for(unsigned int f=1;ffrag0.append(rq->frags[f - 1].payload(),rq->frags[f - 1].payloadLength()); + for (unsigned int f = 1; f < totalFragments; ++f) { + rq->frag0.append(rq->frags[f - 1].payload(), rq->frags[f - 1].payloadLength()); } - if (rq->frag0.tryDecode(RR,tPtr,flowId)) { - rq->timestamp = 0; // packet decoded, free entry - } else { - rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something + if (rq->frag0.tryDecode(RR, tPtr, flowId)) { + rq->timestamp = 0; // packet decoded, free entry + } + else { + rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something } } - } // else this is a duplicate fragment, ignore + } // else this is a duplicate fragment, ignore } } // -------------------------------------------------------------------- - } else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { // min length check is important! + } + else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { // min length check is important! // Handle packet head ------------------------------------------------- - const Address destination(reinterpret_cast(data) + 8,ZT_ADDRESS_LENGTH); - const Address source(reinterpret_cast(data) + 13,ZT_ADDRESS_LENGTH); + const Address destination(reinterpret_cast(data) + 8, ZT_ADDRESS_LENGTH); + const Address source(reinterpret_cast(data) + 13, ZT_ADDRESS_LENGTH); if (source == RR->identity.address()) { return; } if (destination != RR->identity.address()) { - if ( (!RR->topology->amUpstream()) && (!path->trustEstablished(now)) && (source != RR->identity.address()) ) { + if ((! RR->topology->amUpstream()) && (! path->trustEstablished(now)) && (source != RR->identity.address())) { return; } - Packet packet(data,len); + Packet packet(data, len); if (packet.hops() < ZT_RELAY_MAX_HOPS) { packet.incrementHops(); - SharedPtr relayTo = RR->topology->getPeer(tPtr,destination); - if ((relayTo)&&(relayTo->sendDirect(tPtr,packet.data(),packet.size(),now,false))) { - if ((source != RR->identity.address())&&(_shouldUnite(now,source,destination))) { - const SharedPtr sourcePeer(RR->topology->getPeer(tPtr,source)); + SharedPtr relayTo = RR->topology->getPeer(tPtr, destination); + if ((relayTo) && (relayTo->sendDirect(tPtr, packet.data(), packet.size(), now, false))) { + if ((source != RR->identity.address()) && (_shouldUnite(now, source, destination))) { + const SharedPtr sourcePeer(RR->topology->getPeer(tPtr, source)); if (sourcePeer) { - relayTo->introduce(tPtr,now,sourcePeer); + relayTo->introduce(tPtr, now, sourcePeer); } } - } else { + } + else { relayTo = RR->topology->getUpstreamPeer(); - if ((relayTo)&&(relayTo->address() != source)) { - if (relayTo->sendDirect(tPtr,packet.data(),packet.size(),now,true)) { - const SharedPtr sourcePeer(RR->topology->getPeer(tPtr,source)); + if ((relayTo) && (relayTo->address() != source)) { + if (relayTo->sendDirect(tPtr, packet.data(), packet.size(), now, true)) { + const SharedPtr sourcePeer(RR->topology->getPeer(tPtr, source)); if (sourcePeer) { - relayTo->introduce(tPtr,now,sourcePeer); + relayTo->introduce(tPtr, now, sourcePeer); } } } } } - } else if ((reinterpret_cast(data)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0) { + } + else if ((reinterpret_cast(data)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0) { // Packet is the head of a fragmented packet series - const uint64_t packetId = ( - (((uint64_t)reinterpret_cast(data)[0]) << 56) | - (((uint64_t)reinterpret_cast(data)[1]) << 48) | - (((uint64_t)reinterpret_cast(data)[2]) << 40) | - (((uint64_t)reinterpret_cast(data)[3]) << 32) | - (((uint64_t)reinterpret_cast(data)[4]) << 24) | - (((uint64_t)reinterpret_cast(data)[5]) << 16) | - (((uint64_t)reinterpret_cast(data)[6]) << 8) | - ((uint64_t)reinterpret_cast(data)[7]) - ); + const uint64_t packetId = + ((((uint64_t)reinterpret_cast(data)[0]) << 56) | (((uint64_t)reinterpret_cast(data)[1]) << 48) | (((uint64_t)reinterpret_cast(data)[2]) << 40) + | (((uint64_t)reinterpret_cast(data)[3]) << 32) | (((uint64_t)reinterpret_cast(data)[4]) << 24) | (((uint64_t)reinterpret_cast(data)[5]) << 16) + | (((uint64_t)reinterpret_cast(data)[6]) << 8) | ((uint64_t)reinterpret_cast(data)[7])); - RXQueueEntry *const rq = _findRXQueueEntry(packetId); + RXQueueEntry* const rq = _findRXQueueEntry(packetId); Mutex::Lock rql(rq->lock); if (rq->packetId != packetId) { // If we have no other fragments yet, create an entry and save the head @@ -242,36 +237,40 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre rq->flowId = flowId; rq->timestamp = now; rq->packetId = packetId; - rq->frag0.init(data,len,path,now); + rq->frag0.init(data, len, path, now); rq->totalFragments = 0; rq->haveFragments = 1; rq->complete = false; - } else if (!(rq->haveFragments & 1)) { + } + else if (! (rq->haveFragments & 1)) { // If we have other fragments but no head, see if we are complete with the head - if ((rq->totalFragments > 1)&&(Utils::countBits(rq->haveFragments |= 1) == rq->totalFragments)) { + if ((rq->totalFragments > 1) && (Utils::countBits(rq->haveFragments |= 1) == rq->totalFragments)) { // We have all fragments -- assemble and process full Packet - rq->frag0.init(data,len,path,now); - for(unsigned int f=1;ftotalFragments;++f) { - rq->frag0.append(rq->frags[f - 1].payload(),rq->frags[f - 1].payloadLength()); + rq->frag0.init(data, len, path, now); + for (unsigned int f = 1; f < rq->totalFragments; ++f) { + rq->frag0.append(rq->frags[f - 1].payload(), rq->frags[f - 1].payloadLength()); } - if (rq->frag0.tryDecode(RR,tPtr,flowId)) { - rq->timestamp = 0; // packet decoded, free entry - } else { - rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something + if (rq->frag0.tryDecode(RR, tPtr, flowId)) { + rq->timestamp = 0; // packet decoded, free entry + } + else { + rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something } - } else { - // Still waiting on more fragments, but keep the head - rq->frag0.init(data,len,path,now); } - } // else this is a duplicate head, ignore - } else { + else { + // Still waiting on more fragments, but keep the head + rq->frag0.init(data, len, path, now); + } + } // else this is a duplicate head, ignore + } + else { // Packet is unfragmented, so just process it - IncomingPacket packet(data,len,path,now); - if (!packet.tryDecode(RR,tPtr,flowId)) { - RXQueueEntry *const rq = _nextRXQueueEntry(); + IncomingPacket packet(data, len, path, now); + if (! packet.tryDecode(RR, tPtr, flowId)) { + RXQueueEntry* const rq = _nextRXQueueEntry(); Mutex::Lock rql(rq->lock); rq->flowId = flowId; rq->timestamp = now; @@ -286,20 +285,22 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre // -------------------------------------------------------------------- } } - } catch ( ... ) {} // sanity check, should be caught elsewhere + } + catch (...) { + } // sanity check, should be caught elsewhere } -void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) +void Switch::onLocalEthernet(void* tPtr, const SharedPtr& network, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) { - if (!network->hasConfig()) { + if (! network->hasConfig()) { return; } // Check if this packet is from someone other than the tap -- i.e. bridged in bool fromBridged; if ((fromBridged = (from != network->mac()))) { - if (!network->config().permitsBridging(RR->identity.address())) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"not a bridge"); + if (! network->config().permitsBridging(RR->identity.address())) { + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "not a bridge"); return; } } @@ -321,24 +322,24 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const if (etherType == ZT_ETHERTYPE_IPV4 && (len >= 20)) { uint16_t srcPort = 0; uint16_t dstPort = 0; - uint8_t proto = (reinterpret_cast(data)[9]); - const unsigned int headerLen = 4 * (reinterpret_cast(data)[0] & 0xf); - switch(proto) { - case 0x01: // ICMP - //flowId = 0x01; + uint8_t proto = (reinterpret_cast(data)[9]); + const unsigned int headerLen = 4 * (reinterpret_cast(data)[0] & 0xf); + switch (proto) { + case 0x01: // ICMP + // flowId = 0x01; break; // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (len > (headerLen + 4)) { unsigned int pos = headerLen + 0; - srcPort = (reinterpret_cast(data)[pos++]) << 8; - srcPort |= (reinterpret_cast(data)[pos]); + srcPort = (reinterpret_cast(data)[pos++]) << 8; + srcPort |= (reinterpret_cast(data)[pos]); pos++; - dstPort = (reinterpret_cast(data)[pos++]) << 8; - dstPort |= (reinterpret_cast(data)[pos]); + dstPort = (reinterpret_cast(data)[pos++]) << 8; + dstPort |= (reinterpret_cast(data)[pos]); flowId = dstPort ^ srcPort ^ proto; } break; @@ -350,22 +351,22 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const uint16_t dstPort = 0; unsigned int pos; unsigned int proto; - _ipv6GetPayload((const uint8_t *)data, len, pos, proto); - switch(proto) { - case 0x3A: // ICMPv6 - //flowId = 0x3A; + _ipv6GetPayload((const uint8_t*)data, len, pos, proto); + switch (proto) { + case 0x3A: // ICMPv6 + // flowId = 0x3A; break; // All these start with 16-bit source and destination port in that order - case 0x06: // TCP - case 0x11: // UDP - case 0x84: // SCTP - case 0x88: // UDPLite + case 0x06: // TCP + case 0x11: // UDP + case 0x84: // SCTP + case 0x88: // UDPLite if (len > (pos + 4)) { - srcPort = (reinterpret_cast(data)[pos++]) << 8; - srcPort |= (reinterpret_cast(data)[pos]); + srcPort = (reinterpret_cast(data)[pos++]) << 8; + srcPort |= (reinterpret_cast(data)[pos]); pos++; - dstPort = (reinterpret_cast(data)[pos++]) << 8; - dstPort |= (reinterpret_cast(data)[pos]); + dstPort = (reinterpret_cast(data)[pos++]) << 8; + dstPort |= (reinterpret_cast(data)[pos]); flowId = dstPort ^ srcPort ^ proto; } break; @@ -375,10 +376,11 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const } if (to.isMulticast()) { - MulticastGroup multicastGroup(to,0); + MulticastGroup multicastGroup(to, 0); if (to.isBroadcast()) { - if ( (etherType == ZT_ETHERTYPE_ARP) && (len >= 28) && ((((const uint8_t *)data)[2] == 0x08)&&(((const uint8_t *)data)[3] == 0x00)&&(((const uint8_t *)data)[4] == 6)&&(((const uint8_t *)data)[5] == 4)&&(((const uint8_t *)data)[7] == 0x01)) ) { + if ((etherType == ZT_ETHERTYPE_ARP) && (len >= 28) + && ((((const uint8_t*)data)[2] == 0x08) && (((const uint8_t*)data)[3] == 0x00) && (((const uint8_t*)data)[4] == 6) && (((const uint8_t*)data)[5] == 4) && (((const uint8_t*)data)[7] == 0x01))) { /* IPv4 ARP is one of the few special cases that we impose upon what is * otherwise a straightforward Ethernet switch emulation. Vanilla ARP * is dumb old broadcast and simply doesn't scale. ZeroTier multicast @@ -388,18 +390,20 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const * them into multicasts by stuffing the IP address being queried into * the 32-bit ADI field. In practice this uses our multicast pub/sub * system to implement a kind of extended/distributed ARP table. */ - multicastGroup = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(((const unsigned char *)data) + 24,4,0)); - } else if (!network->config().enableBroadcast()) { + multicastGroup = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(((const unsigned char*)data) + 24, 4, 0)); + } + else if (! network->config().enableBroadcast()) { // Don't transmit broadcasts if this network doesn't want them - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"broadcast disabled"); + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "broadcast disabled"); return; } - } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(len >= (40 + 8 + 16))) { + } + else if ((etherType == ZT_ETHERTYPE_IPV6) && (len >= (40 + 8 + 16))) { // IPv6 NDP emulation for certain very special patterns of private IPv6 addresses -- if enabled - if ((network->config().ndpEmulation())&&(reinterpret_cast(data)[6] == 0x3a)&&(reinterpret_cast(data)[40] == 0x87)) { // ICMPv6 neighbor solicitation + if ((network->config().ndpEmulation()) && (reinterpret_cast(data)[6] == 0x3a) && (reinterpret_cast(data)[40] == 0x87)) { // ICMPv6 neighbor solicitation Address v6EmbeddedAddress; - const uint8_t *const pkt6 = reinterpret_cast(data) + 40 + 8; - const uint8_t *my6 = (const uint8_t *)0; + const uint8_t* const pkt6 = reinterpret_cast(data) + 40 + 8; + const uint8_t* my6 = (const uint8_t*)0; // ZT-RFC4193 address: fdNN:NNNN:NNNN:NNNN:NN99:93DD:DDDD:DDDD / 88 (one /128 per actual host) @@ -408,12 +412,12 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const // For these to work, we must have a ZT-managed address assigned in one of the // above formats, and the query must match its prefix. - for(unsigned int sipk=0;sipkconfig().staticIpCount;++sipk) { - const InetAddress *const sip = &(network->config().staticIps[sipk]); + for (unsigned int sipk = 0; sipk < network->config().staticIpCount; ++sipk) { + const InetAddress* const sip = &(network->config().staticIps[sipk]); if (sip->ss_family == AF_INET6) { - my6 = reinterpret_cast(reinterpret_cast(&(*sip))->sin6_addr.s6_addr); - const unsigned int sipNetmaskBits = Utils::ntoh((uint16_t)reinterpret_cast(&(*sip))->sin6_port); - if ((sipNetmaskBits == 88)&&(my6[0] == 0xfd)&&(my6[9] == 0x99)&&(my6[10] == 0x93)) { // ZT-RFC4193 /88 ??? + my6 = reinterpret_cast(reinterpret_cast(&(*sip))->sin6_addr.s6_addr); + const unsigned int sipNetmaskBits = Utils::ntoh((uint16_t)reinterpret_cast(&(*sip))->sin6_port); + if ((sipNetmaskBits == 88) && (my6[0] == 0xfd) && (my6[9] == 0x99) && (my6[10] == 0x93)) { // ZT-RFC4193 /88 ??? unsigned int ptr = 0; while (ptr != 11) { if (pkt6[ptr] != my6[ptr]) { @@ -421,13 +425,14 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const } ++ptr; } - if (ptr == 11) { // prefix match! - v6EmbeddedAddress.setTo(pkt6 + ptr,5); + if (ptr == 11) { // prefix match! + v6EmbeddedAddress.setTo(pkt6 + ptr, 5); break; } - } else if (sipNetmaskBits == 40) { // ZT-6PLANE /40 ??? + } + else if (sipNetmaskBits == 40) { // ZT-6PLANE /40 ??? const uint32_t nwid32 = (uint32_t)((network->id() ^ (network->id() >> 32)) & 0xffffffff); - if ( (my6[0] == 0xfc) && (my6[1] == (uint8_t)((nwid32 >> 24) & 0xff)) && (my6[2] == (uint8_t)((nwid32 >> 16) & 0xff)) && (my6[3] == (uint8_t)((nwid32 >> 8) & 0xff)) && (my6[4] == (uint8_t)(nwid32 & 0xff))) { + if ((my6[0] == 0xfc) && (my6[1] == (uint8_t)((nwid32 >> 24) & 0xff)) && (my6[2] == (uint8_t)((nwid32 >> 16) & 0xff)) && (my6[3] == (uint8_t)((nwid32 >> 8) & 0xff)) && (my6[4] == (uint8_t)(nwid32 & 0xff))) { unsigned int ptr = 0; while (ptr != 5) { if (pkt6[ptr] != my6[ptr]) { @@ -435,8 +440,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const } ++ptr; } - if (ptr == 5) { // prefix match! - v6EmbeddedAddress.setTo(pkt6 + ptr,5); + if (ptr == 5) { // prefix match! + v6EmbeddedAddress.setTo(pkt6 + ptr, 5); break; } } @@ -444,8 +449,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const } } - if ((v6EmbeddedAddress)&&(v6EmbeddedAddress != RR->identity.address())) { - const MAC peerMac(v6EmbeddedAddress,network->id()); + if ((v6EmbeddedAddress) && (v6EmbeddedAddress != RR->identity.address())) { + const MAC peerMac(v6EmbeddedAddress, network->id()); uint8_t adv[72]; adv[0] = 0x60; @@ -456,21 +461,21 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const adv[5] = 0x20; adv[6] = 0x3a; adv[7] = 0xff; - for(int i=0;i<16;++i) { + for (int i = 0; i < 16; ++i) { adv[8 + i] = pkt6[i]; } - for(int i=0;i<16;++i) { + for (int i = 0; i < 16; ++i) { adv[24 + i] = my6[i]; } adv[40] = 0x88; adv[41] = 0x00; adv[42] = 0x00; - adv[43] = 0x00; // future home of checksum + adv[43] = 0x00; // future home of checksum adv[44] = 0x60; adv[45] = 0x00; adv[46] = 0x00; adv[47] = 0x00; - for(int i=0;i<16;++i) { + for (int i = 0; i < 16; ++i) { adv[48 + i] = pkt6[i]; } adv[64] = 0x02; @@ -483,8 +488,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const adv[71] = peerMac[5]; uint16_t pseudo_[36]; - uint8_t *const pseudo = reinterpret_cast(pseudo_); - for(int i=0;i<32;++i) { + uint8_t* const pseudo = reinterpret_cast(pseudo_); + for (int i = 0; i < 32; ++i) { pseudo[i] = adv[8 + i]; } pseudo[32] = 0x00; @@ -495,11 +500,11 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const pseudo[37] = 0x00; pseudo[38] = 0x00; pseudo[39] = 0x3a; - for(int i=0;i<32;++i) { + for (int i = 0; i < 32; ++i) { pseudo[40 + i] = adv[40 + i]; } uint32_t checksum = 0; - for(int i=0;i<36;++i) { + for (int i = 0; i < 36; ++i) { checksum += Utils::hton(pseudo_[i]); } while ((checksum >> 16)) { @@ -515,19 +520,17 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const // std::thread([=]() { - RR->node->putFrame(tPtr, network->id(), network->userPtr(), peerMac, from, ZT_ETHERTYPE_IPV6, 0, adv, 72); - }).detach(); - return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query. - } // else no NDP emulation - } // else no NDP emulation + return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query. + } // else no NDP emulation + } // else no NDP emulation } // Check this after NDP emulation, since that has to be allowed in exactly this case if (network->config().multicastLimit == 0) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"multicast disabled"); + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "multicast disabled"); return; } @@ -536,81 +539,72 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const * multicast addresses on bridge interfaces and subscribing each slave. * But in that case this does no harm, as the sets are just merged. */ if (fromBridged) { - network->learnBridgedMulticastGroup(tPtr,multicastGroup,RR->node->now()); + network->learnBridgedMulticastGroup(tPtr, multicastGroup, RR->node->now()); } // First pass sets noTee to false, but noTee is set to true in OutboundMulticast to prevent duplicates. - if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"filter blocked"); + if (! network->filterOutgoingPacket(tPtr, false, RR->identity.address(), Address(), from, to, (const uint8_t*)data, len, etherType, vlanId, qosBucket)) { + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "filter blocked"); return; } - RR->mc->send( - tPtr, - RR->node->now(), - network, - Address(), - multicastGroup, - (fromBridged) ? from : MAC(), - etherType, - data, - len); - } else if (to == network->mac()) { - + RR->mc->send(tPtr, RR->node->now(), network, Address(), multicastGroup, (fromBridged) ? from : MAC(), etherType, data, len); + } + else if (to == network->mac()) { // Destination is this node, so just reinject it // // same pattern as putFrame call above // std::thread([=]() { - RR->node->putFrame(tPtr, network->id(), network->userPtr(), from, to, etherType, vlanId, data, len); - }).detach(); - - } else if (to[0] == MAC::firstOctetForNetwork(network->id())) { + } + else if (to[0] == MAC::firstOctetForNetwork(network->id())) { // Destination is another ZeroTier peer on the same network - Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this - SharedPtr toPeer(RR->topology->getPeer(tPtr,toZT)); + Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this + SharedPtr toPeer(RR->topology->getPeer(tPtr, toZT)); - if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),toZT,from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"filter blocked"); + if (! network->filterOutgoingPacket(tPtr, false, RR->identity.address(), toZT, from, to, (const uint8_t*)data, len, etherType, vlanId, qosBucket)) { + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "filter blocked"); return; } - network->pushCredentialsIfNeeded(tPtr,toZT,RR->node->now()); + network->pushCredentialsIfNeeded(tPtr, toZT, RR->node->now()); - if (!fromBridged) { - Packet outp(toZT,RR->identity.address(),Packet::VERB_FRAME); + if (! fromBridged) { + Packet outp(toZT, RR->identity.address(), Packet::VERB_FRAME); outp.append(network->id()); outp.append((uint16_t)etherType); - outp.append(data,len); + outp.append(data, len); // 1.4.8: disable compression for unicast as it almost never helps - //if (!network->config().disableCompression()) + // if (!network->config().disableCompression()) // outp.compress(); - aqm_enqueue(tPtr,network,outp,true,qosBucket,flowId); - } else { - Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME); + aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId); + } + else { + Packet outp(toZT, RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(network->id()); outp.append((unsigned char)0x00); to.appendTo(outp); from.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(data,len); + outp.append(data, len); // 1.4.8: disable compression for unicast as it almost never helps - //if (!network->config().disableCompression()) + // if (!network->config().disableCompression()) // outp.compress(); - aqm_enqueue(tPtr,network,outp,true,qosBucket,flowId); + aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId); } - } else { + } + else { // Destination is bridged behind a remote peer // We filter with a NULL destination ZeroTier address first. Filtrations // for each ZT destination are also done below. This is the same rationale // and design as for multicast. - if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"filter blocked"); + if (! network->filterOutgoingPacket(tPtr, false, RR->identity.address(), Address(), from, to, (const uint8_t*)data, len, etherType, vlanId, qosBucket)) { + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "filter blocked"); return; } @@ -620,10 +614,11 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const /* Create an array of up to ZT_MAX_BRIDGE_SPAM recipients for this bridged frame. */ bridges[0] = network->findBridgeTo(to); std::vector
activeBridges(network->config().activeBridges()); - if ((bridges[0])&&(bridges[0] != RR->identity.address())&&(network->config().permitsBridging(bridges[0]))) { + if ((bridges[0]) && (bridges[0] != RR->identity.address()) && (network->config().permitsBridging(bridges[0]))) { /* We have a known bridge route for this MAC, send it there. */ ++numBridges; - } else if (!activeBridges.empty()) { + } + else if (! activeBridges.empty()) { /* If there is no known route, spam to up to ZT_MAX_BRIDGE_SPAM active * bridges. If someone responds, we'll learn the route. */ std::vector
::const_iterator ab(activeBridges.begin()); @@ -633,7 +628,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const bridges[numBridges++] = *ab; ++ab; } - } else { + } + else { // Otherwise pick a random set of them while (numBridges < ZT_MAX_BRIDGE_SPAM) { if (ab == activeBridges.end()) { @@ -642,46 +638,48 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const if (((unsigned long)RR->node->prng() % (unsigned long)activeBridges.size()) == 0) { bridges[numBridges++] = *ab; ++ab; - } else { + } + else { ++ab; } } } } - for(unsigned int b=0;bfilterOutgoingPacket(tPtr,true,RR->identity.address(),bridges[b],from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME); + for (unsigned int b = 0; b < numBridges; ++b) { + if (network->filterOutgoingPacket(tPtr, true, RR->identity.address(), bridges[b], from, to, (const uint8_t*)data, len, etherType, vlanId, qosBucket)) { + Packet outp(bridges[b], RR->identity.address(), Packet::VERB_EXT_FRAME); outp.append(network->id()); outp.append((uint8_t)0x00); to.appendTo(outp); from.appendTo(outp); outp.append((uint16_t)etherType); - outp.append(data,len); + outp.append(data, len); // 1.4.8: disable compression for unicast as it almost never helps - //if (!network->config().disableCompression()) + // if (!network->config().disableCompression()) // outp.compress(); - aqm_enqueue(tPtr,network,outp,true,qosBucket,flowId); - } else { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"filter blocked (bridge replication)"); + aqm_enqueue(tPtr, network, outp, true, qosBucket, flowId); + } + else { + RR->t->outgoingNetworkFrameDropped(tPtr, network, from, to, etherType, vlanId, len, "filter blocked (bridge replication)"); } } } } -void Switch::aqm_enqueue(void *tPtr, const SharedPtr &network, Packet &packet,bool encrypt,int qosBucket,int32_t flowId) +void Switch::aqm_enqueue(void* tPtr, const SharedPtr& network, Packet& packet, bool encrypt, int qosBucket, int32_t flowId) { - if(!network->qosEnabled()) { + if (! network->qosEnabled()) { send(tPtr, packet, encrypt, flowId); return; } - NetworkQoSControlBlock *nqcb = _netQueueControlBlock[network->id()]; - if (!nqcb) { + NetworkQoSControlBlock* nqcb = _netQueueControlBlock[network->id()]; + if (! nqcb) { nqcb = new NetworkQoSControlBlock(); _netQueueControlBlock[network->id()] = nqcb; // Initialize ZT_QOS_NUM_BUCKETS queues and place them in the INACTIVE list // These queues will be shuffled between the new/old/inactive lists by the enqueue/dequeue algorithm - for (int i=0; iinactiveQueues.push_back(new ManagedQueue(i)); } } @@ -695,21 +693,21 @@ void Switch::aqm_enqueue(void *tPtr, const SharedPtr &network, Packet & // Enqueue packet and move queue to appropriate list const Address dest(packet.destination()); - TXQueueEntry *txEntry = new TXQueueEntry(dest,RR->node->now(),packet,encrypt,flowId); + TXQueueEntry* txEntry = new TXQueueEntry(dest, RR->node->now(), packet, encrypt, flowId); - ManagedQueue *selectedQueue = nullptr; - for (size_t i=0; ioldQueues.size()) { // search old queues first (I think this is best since old would imply most recent usage of the queue) + ManagedQueue* selectedQueue = nullptr; + for (size_t i = 0; i < ZT_AQM_NUM_BUCKETS; i++) { + if (i < nqcb->oldQueues.size()) { // search old queues first (I think this is best since old would imply most recent usage of the queue) if (nqcb->oldQueues[i]->id == qosBucket) { selectedQueue = nqcb->oldQueues[i]; } } - if (i < nqcb->newQueues.size()) { // search new queues (this would imply not often-used queues) + if (i < nqcb->newQueues.size()) { // search new queues (this would imply not often-used queues) if (nqcb->newQueues[i]->id == qosBucket) { selectedQueue = nqcb->newQueues[i]; } } - if (i < nqcb->inactiveQueues.size()) { // search inactive queues + if (i < nqcb->inactiveQueues.size()) { // search inactive queues if (nqcb->inactiveQueues[i]->id == qosBucket) { selectedQueue = nqcb->inactiveQueues[i]; // move queue to end of NEW queue list @@ -720,23 +718,23 @@ void Switch::aqm_enqueue(void *tPtr, const SharedPtr &network, Packet & } } } - if (!selectedQueue) { + if (! selectedQueue) { _aqm_m.unlock(); return; } selectedQueue->q.push_back(txEntry); - selectedQueue->byteLength+=txEntry->packet.payloadLength(); + selectedQueue->byteLength += txEntry->packet.payloadLength(); nqcb->_currEnqueuedPackets++; // DEBUG_INFO("nq=%2lu, oq=%2lu, iq=%2lu, nqcb.size()=%3d, bucket=%2d, q=%p", nqcb->newQueues.size(), nqcb->oldQueues.size(), nqcb->inactiveQueues.size(), nqcb->_currEnqueuedPackets, qosBucket, selectedQueue); // Drop a packet if necessary - ManagedQueue *selectedQueueToDropFrom = nullptr; + ManagedQueue* selectedQueueToDropFrom = nullptr; if (nqcb->_currEnqueuedPackets > ZT_AQM_MAX_ENQUEUED_PACKETS) { // DEBUG_INFO("too many enqueued packets (%d), finding packet to drop", nqcb->_currEnqueuedPackets); int maxQueueLength = 0; - for (size_t i=0; ioldQueues.size()) { if (nqcb->oldQueues[i]->byteLength > maxQueueLength) { maxQueueLength = nqcb->oldQueues[i]->byteLength; @@ -761,7 +759,7 @@ void Switch::aqm_enqueue(void *tPtr, const SharedPtr &network, Packet & int sizeOfDroppedPacket = selectedQueueToDropFrom->q.front()->packet.payloadLength(); delete selectedQueueToDropFrom->q.front(); selectedQueueToDropFrom->q.pop_front(); - selectedQueueToDropFrom->byteLength-=sizeOfDroppedPacket; + selectedQueueToDropFrom->byteLength -= sizeOfDroppedPacket; nqcb->_currEnqueuedPackets--; } } @@ -774,7 +772,7 @@ uint64_t Switch::control_law(uint64_t t, int count) return (uint64_t)(t + ZT_AQM_INTERVAL / sqrt(count)); } -Switch::dqr Switch::dodequeue(ManagedQueue *q, uint64_t now) +Switch::dqr Switch::dodequeue(ManagedQueue* q, uint64_t now) { dqr r; r.ok_to_drop = false; @@ -788,83 +786,88 @@ Switch::dqr Switch::dodequeue(ManagedQueue *q, uint64_t now) if (sojourn_time < ZT_AQM_TARGET || q->byteLength <= ZT_DEFAULT_MTU) { // went below - stay below for at least interval q->first_above_time = 0; - } else { + } + else { if (q->first_above_time == 0) { // just went above from below. if still above at // first_above_time, will say it's ok to drop. q->first_above_time = now + ZT_AQM_INTERVAL; - } else if (now >= q->first_above_time) { + } + else if (now >= q->first_above_time) { r.ok_to_drop = true; } } return r; } -Switch::TXQueueEntry * Switch::CoDelDequeue(ManagedQueue *q, bool isNew, uint64_t now) +Switch::TXQueueEntry* Switch::CoDelDequeue(ManagedQueue* q, bool isNew, uint64_t now) { dqr r = dodequeue(q, now); if (q->dropping) { - if (!r.ok_to_drop) { + if (! r.ok_to_drop) { q->dropping = false; } while (now >= q->drop_next && q->dropping) { - q->q.pop_front(); // drop + q->q.pop_front(); // drop r = dodequeue(q, now); - if (!r.ok_to_drop) { + if (! r.ok_to_drop) { // leave dropping state q->dropping = false; - } else { + } + else { ++(q->count); // schedule the next drop. q->drop_next = control_law(q->drop_next, q->count); } } - } else if (r.ok_to_drop) { - q->q.pop_front(); // drop + } + else if (r.ok_to_drop) { + q->q.pop_front(); // drop r = dodequeue(q, now); q->dropping = true; - q->count = (q->count > 2 && now - q->drop_next < 8*ZT_AQM_INTERVAL)? - q->count - 2 : 1; + q->count = (q->count > 2 && now - q->drop_next < 8 * ZT_AQM_INTERVAL) ? q->count - 2 : 1; q->drop_next = control_law(now, q->count); } return r.p; } -void Switch::aqm_dequeue(void *tPtr) +void Switch::aqm_dequeue(void* tPtr) { // Cycle through network-specific QoS control blocks - for(std::map::iterator nqcb(_netQueueControlBlock.begin());nqcb!=_netQueueControlBlock.end();) { - if (!(*nqcb).second->_currEnqueuedPackets) { + for (std::map::iterator nqcb(_netQueueControlBlock.begin()); nqcb != _netQueueControlBlock.end();) { + if (! (*nqcb).second->_currEnqueuedPackets) { return; } uint64_t now = RR->node->now(); - TXQueueEntry *entryToEmit = nullptr; - std::vector *currQueues = &((*nqcb).second->newQueues); - std::vector *oldQueues = &((*nqcb).second->oldQueues); - std::vector *inactiveQueues = &((*nqcb).second->inactiveQueues); + TXQueueEntry* entryToEmit = nullptr; + std::vector* currQueues = &((*nqcb).second->newQueues); + std::vector* oldQueues = &((*nqcb).second->oldQueues); + std::vector* inactiveQueues = &((*nqcb).second->inactiveQueues); _aqm_m.lock(); // Attempt dequeue from queues in NEW list bool examiningNewQueues = true; while (currQueues->size()) { - ManagedQueue *queueAtFrontOfList = currQueues->front(); + ManagedQueue* queueAtFrontOfList = currQueues->front(); if (queueAtFrontOfList->byteCredit < 0) { queueAtFrontOfList->byteCredit += ZT_AQM_QUANTUM; // Move to list of OLD queues // DEBUG_INFO("moving q=%p from NEW to OLD list", queueAtFrontOfList); oldQueues->push_back(queueAtFrontOfList); currQueues->erase(currQueues->begin()); - } else { + } + else { entryToEmit = CoDelDequeue(queueAtFrontOfList, examiningNewQueues, now); - if (!entryToEmit) { + if (! entryToEmit) { // Move to end of list of OLD queues // DEBUG_INFO("moving q=%p from NEW to OLD list", queueAtFrontOfList); oldQueues->push_back(queueAtFrontOfList); currQueues->erase(currQueues->begin()); - } else { + } + else { int len = entryToEmit->packet.payloadLength(); queueAtFrontOfList->byteLength -= len; queueAtFrontOfList->byteCredit -= len; @@ -874,7 +877,7 @@ void Switch::aqm_dequeue(void *tPtr) (*nqcb).second->_currEnqueuedPackets--; } if (queueAtFrontOfList) { - //DEBUG_INFO("dequeuing from q=%p, len=%lu in NEW list (byteCredit=%d)", queueAtFrontOfList, queueAtFrontOfList->q.size(), queueAtFrontOfList->byteCredit); + // DEBUG_INFO("dequeuing from q=%p, len=%lu in NEW list (byteCredit=%d)", queueAtFrontOfList, queueAtFrontOfList->q.size(), queueAtFrontOfList->byteCredit); } break; } @@ -884,19 +887,21 @@ void Switch::aqm_dequeue(void *tPtr) examiningNewQueues = false; currQueues = &((*nqcb).second->oldQueues); while (currQueues->size()) { - ManagedQueue *queueAtFrontOfList = currQueues->front(); + ManagedQueue* queueAtFrontOfList = currQueues->front(); if (queueAtFrontOfList->byteCredit < 0) { queueAtFrontOfList->byteCredit += ZT_AQM_QUANTUM; oldQueues->push_back(queueAtFrontOfList); currQueues->erase(currQueues->begin()); - } else { + } + else { entryToEmit = CoDelDequeue(queueAtFrontOfList, examiningNewQueues, now); - if (!entryToEmit) { - //DEBUG_INFO("moving q=%p from OLD to INACTIVE list", queueAtFrontOfList); - // Move to inactive list of queues + if (! entryToEmit) { + // DEBUG_INFO("moving q=%p from OLD to INACTIVE list", queueAtFrontOfList); + // Move to inactive list of queues inactiveQueues->push_back(queueAtFrontOfList); currQueues->erase(currQueues->begin()); - } else { + } + else { int len = entryToEmit->packet.payloadLength(); queueAtFrontOfList->byteLength -= len; queueAtFrontOfList->byteCredit -= len; @@ -905,7 +910,7 @@ void Switch::aqm_dequeue(void *tPtr) (*nqcb).second->_currEnqueuedPackets--; } if (queueAtFrontOfList) { - //DEBUG_INFO("dequeuing from q=%p, len=%lu in OLD list (byteCredit=%d)", queueAtFrontOfList, queueAtFrontOfList->q.size(), queueAtFrontOfList->byteCredit); + // DEBUG_INFO("dequeuing from q=%p, len=%lu in OLD list (byteCredit=%d)", queueAtFrontOfList, queueAtFrontOfList->q.size(), queueAtFrontOfList->byteCredit); } break; } @@ -917,7 +922,7 @@ void Switch::aqm_dequeue(void *tPtr) void Switch::removeNetworkQoSControlBlock(uint64_t nwid) { - NetworkQoSControlBlock *nq = _netQueueControlBlock[nwid]; + NetworkQoSControlBlock* nq = _netQueueControlBlock[nwid]; if (nq) { _netQueueControlBlock.erase(nwid); delete nq; @@ -925,28 +930,28 @@ void Switch::removeNetworkQoSControlBlock(uint64_t nwid) } } -void Switch::send(void *tPtr,Packet &packet,bool encrypt,int32_t flowId) +void Switch::send(void* tPtr, Packet& packet, bool encrypt, int32_t flowId) { const Address dest(packet.destination()); if (dest == RR->identity.address()) { return; } _recordOutgoingPacketMetrics(packet); - if (!_trySend(tPtr,packet,encrypt,flowId)) { + if (! _trySend(tPtr, packet, encrypt, flowId)) { { Mutex::Lock _l(_txQueue_m); if (_txQueue.size() >= ZT_TX_QUEUE_SIZE) { _txQueue.pop_front(); } - _txQueue.push_back(TXQueueEntry(dest,RR->node->now(),packet,encrypt,flowId)); + _txQueue.push_back(TXQueueEntry(dest, RR->node->now(), packet, encrypt, flowId)); } - if (!RR->topology->getPeer(tPtr,dest)) { - requestWhois(tPtr,RR->node->now(),dest); + if (! RR->topology->getPeer(tPtr, dest)) { + requestWhois(tPtr, RR->node->now(), dest); } } } -void Switch::requestWhois(void *tPtr,const int64_t now,const Address &addr) +void Switch::requestWhois(void* tPtr, const int64_t now, const Address& addr) { if (addr == RR->identity.address()) { return; @@ -954,10 +959,11 @@ void Switch::requestWhois(void *tPtr,const int64_t now,const Address &addr) { Mutex::Lock _l(_lastSentWhoisRequest_m); - int64_t &last = _lastSentWhoisRequest[addr]; + int64_t& last = _lastSentWhoisRequest[addr]; if ((now - last) < ZT_WHOIS_RETRY_DELAY) { return; - } else { + } + else { last = now; } } @@ -965,13 +971,13 @@ void Switch::requestWhois(void *tPtr,const int64_t now,const Address &addr) const SharedPtr upstream(RR->topology->getUpstreamPeer()); if (upstream) { int32_t flowId = ZT_QOS_NO_FLOW; - Packet outp(upstream->address(),RR->identity.address(),Packet::VERB_WHOIS); + Packet outp(upstream->address(), RR->identity.address(), Packet::VERB_WHOIS); addr.appendTo(outp); - send(tPtr,outp,true,flowId); + send(tPtr, outp, true, flowId); } } -void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr &peer) +void Switch::doAnythingWaitingForPeer(void* tPtr, const SharedPtr& peer) { { Mutex::Lock _l(_lastSentWhoisRequest_m); @@ -979,11 +985,11 @@ void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr &peer) } const int64_t now = RR->node->now(); - for(unsigned int ptr=0;ptrlock); - if ((rq->timestamp)&&(rq->complete)) { - if ((rq->frag0.tryDecode(RR,tPtr,rq->flowId))||((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) { + if ((rq->timestamp) && (rq->complete)) { + if ((rq->frag0.tryDecode(RR, tPtr, rq->flowId)) || ((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) { rq->timestamp = 0; } } @@ -991,21 +997,23 @@ void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr &peer) { Mutex::Lock _l(_txQueue_m); - for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) { + for (std::list::iterator txi(_txQueue.begin()); txi != _txQueue.end();) { if (txi->dest == peer->address()) { - if (_trySend(tPtr,txi->packet,txi->encrypt,txi->flowId)) { + if (_trySend(tPtr, txi->packet, txi->encrypt, txi->flowId)) { _txQueue.erase(txi++); - } else { + } + else { ++txi; } - } else { + } + else { ++txi; } } } } -unsigned long Switch::doTimerTasks(void *tPtr,int64_t now) +unsigned long Switch::doTimerTasks(void* tPtr, int64_t now) { const uint64_t timeSinceLastCheck = now - _lastCheckedQueues; if (timeSinceLastCheck < ZT_WHOIS_RETRY_DELAY) { @@ -1017,33 +1025,36 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now) { Mutex::Lock _l(_txQueue_m); - for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) { - if (_trySend(tPtr,txi->packet,txi->encrypt,txi->flowId)) { + for (std::list::iterator txi(_txQueue.begin()); txi != _txQueue.end();) { + if (_trySend(tPtr, txi->packet, txi->encrypt, txi->flowId)) { _txQueue.erase(txi++); - } else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) { + } + else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) { _txQueue.erase(txi++); - } else { - if (!RR->topology->getPeer(tPtr,txi->dest)) { + } + else { + if (! RR->topology->getPeer(tPtr, txi->dest)) { needWhois.push_back(txi->dest); } ++txi; } } } - for(std::vector
::const_iterator i(needWhois.begin());i!=needWhois.end();++i) { - requestWhois(tPtr,now,*i); + for (std::vector
::const_iterator i(needWhois.begin()); i != needWhois.end(); ++i) { + requestWhois(tPtr, now, *i); } - for(unsigned int ptr=0;ptrlock); - if ((rq->timestamp)&&(rq->complete)) { - if ((rq->frag0.tryDecode(RR,tPtr,rq->flowId))||((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) { + if ((rq->timestamp) && (rq->complete)) { + if ((rq->frag0.tryDecode(RR, tPtr, rq->flowId)) || ((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) { rq->timestamp = 0; - } else { + } + else { const Address src(rq->frag0.source()); - if (!RR->topology->getPeer(tPtr,src)) { - requestWhois(tPtr,now,src); + if (! RR->topology->getPeer(tPtr, src)) { + requestWhois(tPtr, now, src); } } } @@ -1051,10 +1062,10 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now) { Mutex::Lock _l(_lastUniteAttempt_m); - Hashtable< _LastUniteKey,uint64_t >::Iterator i(_lastUniteAttempt); - _LastUniteKey *k = (_LastUniteKey *)0; - uint64_t *v = (uint64_t *)0; - while (i.next(k,v)) { + Hashtable<_LastUniteKey, uint64_t>::Iterator i(_lastUniteAttempt); + _LastUniteKey* k = (_LastUniteKey*)0; + uint64_t* v = (uint64_t*)0; + while (i.next(k, v)) { if ((now - *v) >= (ZT_MIN_UNITE_INTERVAL * 8)) { _lastUniteAttempt.erase(*k); } @@ -1063,10 +1074,10 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now) { Mutex::Lock _l(_lastSentWhoisRequest_m); - Hashtable< Address,int64_t >::Iterator i(_lastSentWhoisRequest); - Address *a = (Address *)0; - int64_t *ts = (int64_t *)0; - while (i.next(a,ts)) { + Hashtable::Iterator i(_lastSentWhoisRequest); + Address* a = (Address*)0; + int64_t* ts = (int64_t*)0; + while (i.next(a, ts)) { if ((now - *ts) > (ZT_WHOIS_RETRY_DELAY * 2)) { _lastSentWhoisRequest.erase(*a); } @@ -1076,10 +1087,10 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now) return ZT_WHOIS_RETRY_DELAY; } -bool Switch::_shouldUnite(const int64_t now,const Address &source,const Address &destination) +bool Switch::_shouldUnite(const int64_t now, const Address& source, const Address& destination) { Mutex::Lock _l(_lastUniteAttempt_m); - uint64_t &ts = _lastUniteAttempt[_LastUniteKey(source,destination)]; + uint64_t& ts = _lastUniteAttempt[_LastUniteKey(source, destination)]; if ((now - ts) >= ZT_MIN_UNITE_INTERVAL) { ts = now; return true; @@ -1087,39 +1098,39 @@ bool Switch::_shouldUnite(const int64_t now,const Address &source,const Address return false; } -bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId) +bool Switch::_trySend(void* tPtr, Packet& packet, bool encrypt, int32_t flowId) { SharedPtr viaPath; const int64_t now = RR->node->now(); const Address destination(packet.destination()); - const SharedPtr peer(RR->topology->getPeer(tPtr,destination)); + const SharedPtr peer(RR->topology->getPeer(tPtr, destination)); if (peer) { - if ((peer->bondingPolicy() == ZT_BOND_POLICY_BROADCAST) - && (packet.verb() == Packet::VERB_FRAME || packet.verb() == Packet::VERB_EXT_FRAME)) { + if ((peer->bondingPolicy() == ZT_BOND_POLICY_BROADCAST) && (packet.verb() == Packet::VERB_FRAME || packet.verb() == Packet::VERB_EXT_FRAME)) { const SharedPtr relay(RR->topology->getUpstreamPeer()); Mutex::Lock _l(peer->_paths_m); - for(int i=0;i_paths[i].p && peer->_paths[i].p->alive(now)) { uint16_t userSpecifiedMtu = peer->_paths[i].p->mtu(); - _sendViaSpecificPath(tPtr,peer,peer->_paths[i].p, userSpecifiedMtu,now,packet,encrypt,flowId); + _sendViaSpecificPath(tPtr, peer, peer->_paths[i].p, userSpecifiedMtu, now, packet, encrypt, flowId); } } return true; - } else { - viaPath = peer->getAppropriatePath(now,false,flowId); - if (!viaPath) { - peer->tryMemorizedPath(tPtr,now); // periodically attempt memorized or statically defined paths, if any are known + } + else { + viaPath = peer->getAppropriatePath(now, false, flowId); + if (! viaPath) { + peer->tryMemorizedPath(tPtr, now); // periodically attempt memorized or statically defined paths, if any are known const SharedPtr relay(RR->topology->getUpstreamPeer()); - if ( (!relay) || (!(viaPath = relay->getAppropriatePath(now,false,flowId))) ) { - if (!(viaPath = peer->getAppropriatePath(now,true,flowId))) { + if ((! relay) || (! (viaPath = relay->getAppropriatePath(now, false, flowId)))) { + if (! (viaPath = peer->getAppropriatePath(now, true, flowId))) { return false; } } } if (viaPath) { uint16_t userSpecifiedMtu = viaPath->mtu(); - _sendViaSpecificPath(tPtr,peer,viaPath,userSpecifiedMtu,now,packet,encrypt,flowId); + _sendViaSpecificPath(tPtr, peer, viaPath, userSpecifiedMtu, now, packet, encrypt, flowId); return true; } } @@ -1127,30 +1138,31 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId) return false; } -void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr peer,SharedPtr viaPath,uint16_t userSpecifiedMtu, int64_t now,Packet &packet,bool encrypt,int32_t flowId) +void Switch::_sendViaSpecificPath(void* tPtr, SharedPtr peer, SharedPtr viaPath, uint16_t userSpecifiedMtu, int64_t now, Packet& packet, bool encrypt, int32_t flowId) { unsigned int mtu = ZT_DEFAULT_PHYSMTU; uint64_t trustedPathId = 0; - RR->topology->getOutboundPathInfo(viaPath->address(),mtu,trustedPathId); + RR->topology->getOutboundPathInfo(viaPath->address(), mtu, trustedPathId); if (userSpecifiedMtu > 0) { mtu = userSpecifiedMtu; } - unsigned int chunkSize = std::min(packet.size(),mtu); + unsigned int chunkSize = std::min(packet.size(), mtu); packet.setFragmented(chunkSize < packet.size()); if (trustedPathId) { packet.setTrusted(trustedPathId); - } else { - if (!packet.isEncrypted()) { - packet.armor(peer->key(),encrypt,peer->aesKeysIfSupported()); + } + else { + if (! packet.isEncrypted()) { + packet.armor(peer->key(), encrypt, peer->aesKeysIfSupported()); } RR->node->expectReplyTo(packet.packetId()); } peer->recordOutgoingPacket(viaPath, packet.packetId(), packet.payloadLength(), packet.verb(), flowId, now); - if (viaPath->send(RR,tPtr,packet.data(),chunkSize,now)) { + if (viaPath->send(RR, tPtr, packet.data(), chunkSize, now)) { if (chunkSize < packet.size()) { // Too big for one packet, fragment the rest unsigned int fragStart = chunkSize; @@ -1161,10 +1173,10 @@ void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr peer,SharedPtrsend(RR,tPtr,frag.data(),frag.size(),now); + for (unsigned int fno = 1; fno < totalFragments; ++fno) { + chunkSize = std::min(remaining, (unsigned int)(mtu - ZT_PROTO_MIN_FRAGMENT_LENGTH)); + Packet::Fragment frag(packet, fragStart, chunkSize, fno, totalFragments); + viaPath->send(RR, tPtr, frag.data(), frag.size(), now); fragStart += chunkSize; remaining -= chunkSize; } @@ -1172,7 +1184,8 @@ void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr peer,SharedPtr #include #include #include -#include - -#include "Constants.hpp" -#include "Mutex.hpp" -#include "MAC.hpp" -#include "Packet.hpp" -#include "Utils.hpp" -#include "InetAddress.hpp" -#include "Topology.hpp" -#include "Network.hpp" -#include "SharedPtr.hpp" -#include "IncomingPacket.hpp" -#include "Hashtable.hpp" /* Ethernet frame types that might be relevant to us */ -#define ZT_ETHERTYPE_IPV4 0x0800 -#define ZT_ETHERTYPE_ARP 0x0806 -#define ZT_ETHERTYPE_RARP 0x8035 +#define ZT_ETHERTYPE_IPV4 0x0800 +#define ZT_ETHERTYPE_ARP 0x0806 +#define ZT_ETHERTYPE_RARP 0x8035 #define ZT_ETHERTYPE_ATALK 0x809b -#define ZT_ETHERTYPE_AARP 0x80f3 +#define ZT_ETHERTYPE_AARP 0x80f3 #define ZT_ETHERTYPE_IPX_A 0x8137 #define ZT_ETHERTYPE_IPX_B 0x8138 -#define ZT_ETHERTYPE_IPV6 0x86dd +#define ZT_ETHERTYPE_IPV6 0x86dd namespace ZeroTier { @@ -54,20 +54,19 @@ class Peer; * packets from tap devices, and this sends them where they need to go and * wraps/unwraps accordingly. It also handles queues and timeouts and such. */ -class Switch -{ +class Switch { struct ManagedQueue; struct TXQueueEntry; friend class SharedPtr; typedef struct { - TXQueueEntry *p; + TXQueueEntry* p; bool ok_to_drop; } dqr; -public: - Switch(const RuntimeEnvironment *renv); + public: + Switch(const RuntimeEnvironment* renv); /** * Called when a packet is received from the real network @@ -78,7 +77,7 @@ public: * @param data Packet data * @param len Packet length */ - void onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddress &fromAddr,const void *data,unsigned int len); + void onRemotePacket(void* tPtr, const int64_t localSocket, const InetAddress& fromAddr, const void* data, unsigned int len); /** * Returns whether our bonding or balancing policy is aware of flows. @@ -97,7 +96,7 @@ public: * @param data Ethernet payload * @param len Frame length */ - void onLocalEthernet(void *tPtr,const SharedPtr &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); + void onLocalEthernet(void* tPtr, const SharedPtr& network, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len); /** * Determines the next drop schedule for packets in the TX queue @@ -114,7 +113,7 @@ public: * @param q The TX queue that is being dequeued from * @param now Current time */ - dqr dodequeue(ManagedQueue *q, uint64_t now); + dqr dodequeue(ManagedQueue* q, uint64_t now); /** * Presents a packet to the AQM scheduler. @@ -125,14 +124,14 @@ public: * @param encrypt Encrypt packet payload? (always true except for HELLO) * @param qosBucket Which bucket the rule-system determined this packet should fall into */ - void aqm_enqueue(void *tPtr, const SharedPtr &network, Packet &packet,bool encrypt,int qosBucket,int32_t flowId = ZT_QOS_NO_FLOW); + void aqm_enqueue(void* tPtr, const SharedPtr& network, Packet& packet, bool encrypt, int qosBucket, int32_t flowId = ZT_QOS_NO_FLOW); /** * Performs a single AQM cycle and dequeues and transmits all eligible packets on all networks * * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call */ - void aqm_dequeue(void *tPtr); + void aqm_dequeue(void* tPtr); /** * Calls the dequeue mechanism and adjust queue state variables @@ -141,7 +140,7 @@ public: * @param isNew Whether or not this queue is in the NEW list * @param now Current time */ - Switch::TXQueueEntry * CoDelDequeue(ManagedQueue *q, bool isNew, uint64_t now); + Switch::TXQueueEntry* CoDelDequeue(ManagedQueue* q, bool isNew, uint64_t now); /** * Removes QoS Queues and flow state variables for a specific network. These queues are created @@ -171,7 +170,7 @@ public: * @param packet Packet to send (buffer may be modified) * @param encrypt Encrypt packet payload? (always true except for HELLO) */ - void send(void *tPtr,Packet &packet,bool encrypt,int32_t flowId = ZT_QOS_NO_FLOW); + void send(void* tPtr, Packet& packet, bool encrypt, int32_t flowId = ZT_QOS_NO_FLOW); /** * Request WHOIS on a given address @@ -180,7 +179,7 @@ public: * @param now Current time * @param addr Address to look up */ - void requestWhois(void *tPtr,const int64_t now,const Address &addr); + void requestWhois(void* tPtr, const int64_t now, const Address& addr); /** * Run any processes that are waiting for this peer's identity @@ -190,7 +189,7 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param peer New peer */ - void doAnythingWaitingForPeer(void *tPtr,const SharedPtr &peer); + void doAnythingWaitingForPeer(void* tPtr, const SharedPtr& peer); /** * Perform retries and other periodic timer tasks @@ -202,33 +201,34 @@ public: * @param now Current time * @return Number of milliseconds until doTimerTasks() should be run again */ - unsigned long doTimerTasks(void *tPtr,int64_t now); + unsigned long doTimerTasks(void* tPtr, int64_t now); -private: - bool _shouldUnite(const int64_t now,const Address &source,const Address &destination); - bool _trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId = ZT_QOS_NO_FLOW); // packet is modified if return is true - void _sendViaSpecificPath(void *tPtr,SharedPtr peer,SharedPtr viaPath,uint16_t userSpecifiedMtu, int64_t now,Packet &packet,bool encrypt,int32_t flowId); - void _recordOutgoingPacketMetrics(const Packet &p); + private: + bool _shouldUnite(const int64_t now, const Address& source, const Address& destination); + bool _trySend(void* tPtr, Packet& packet, bool encrypt, int32_t flowId = ZT_QOS_NO_FLOW); // packet is modified if return is true + void _sendViaSpecificPath(void* tPtr, SharedPtr peer, SharedPtr viaPath, uint16_t userSpecifiedMtu, int64_t now, Packet& packet, bool encrypt, int32_t flowId); + void _recordOutgoingPacketMetrics(const Packet& p); - const RuntimeEnvironment *const RR; + const RuntimeEnvironment* const RR; int64_t _lastBeaconResponse; volatile int64_t _lastCheckedQueues; // Time we last sent a WHOIS request for each address - Hashtable< Address,int64_t > _lastSentWhoisRequest; + Hashtable _lastSentWhoisRequest; Mutex _lastSentWhoisRequest_m; // Packets waiting for WHOIS replies or other decode info or missing fragments - struct RXQueueEntry - { - RXQueueEntry() : timestamp(0) {} - volatile int64_t timestamp; // 0 if entry is not in use + struct RXQueueEntry { + RXQueueEntry() : timestamp(0) + { + } + volatile int64_t timestamp; // 0 if entry is not in use volatile uint64_t packetId; - IncomingPacket frag0; // head of packet - Packet::Fragment frags[ZT_MAX_PACKET_FRAGMENTS - 1]; // later fragments (if any) - unsigned int totalFragments; // 0 if only frag0 received, waiting for frags - uint32_t haveFragments; // bit mask, LSB to MSB - volatile bool complete; // if true, packet is complete + IncomingPacket frag0; // head of packet + Packet::Fragment frags[ZT_MAX_PACKET_FRAGMENTS - 1]; // later fragments (if any) + unsigned int totalFragments; // 0 if only frag0 received, waiting for frags + uint32_t haveFragments; // bit mask, LSB to MSB + volatile bool complete; // if true, packet is complete volatile int32_t flowId; Mutex lock; }; @@ -236,12 +236,12 @@ private: AtomicCounter _rxQueuePtr; // Returns matching or next available RX queue entry - inline RXQueueEntry *_findRXQueueEntry(uint64_t packetId) + inline RXQueueEntry* _findRXQueueEntry(uint64_t packetId) { const unsigned int current = static_cast(_rxQueuePtr.load()); - for(unsigned int k=1;k<=ZT_RX_QUEUE_SIZE;++k) { - RXQueueEntry *rq = &(_rxQueue[(current - k) % ZT_RX_QUEUE_SIZE]); - if ((rq->packetId == packetId)&&(rq->timestamp)) { + for (unsigned int k = 1; k <= ZT_RX_QUEUE_SIZE; ++k) { + RXQueueEntry* rq = &(_rxQueue[(current - k) % ZT_RX_QUEUE_SIZE]); + if ((rq->packetId == packetId) && (rq->timestamp)) { return rq; } } @@ -250,62 +250,64 @@ private: } // Returns current entry in rx queue ring buffer and increments ring pointer - inline RXQueueEntry *_nextRXQueueEntry() + inline RXQueueEntry* _nextRXQueueEntry() { return &(_rxQueue[static_cast((++_rxQueuePtr) - 1) % ZT_RX_QUEUE_SIZE]); } // ZeroTier-layer TX queue entry - struct TXQueueEntry - { - TXQueueEntry() {} - TXQueueEntry(Address d,uint64_t ct,const Packet &p,bool enc,int32_t fid) : - dest(d), - creationTime(ct), - packet(p), - encrypt(enc), - flowId(fid) {} + struct TXQueueEntry { + TXQueueEntry() + { + } + TXQueueEntry(Address d, uint64_t ct, const Packet& p, bool enc, int32_t fid) : dest(d), creationTime(ct), packet(p), encrypt(enc), flowId(fid) + { + } Address dest; uint64_t creationTime; - Packet packet; // unencrypted/unMAC'd packet -- this is done at send time + Packet packet; // unencrypted/unMAC'd packet -- this is done at send time bool encrypt; int32_t flowId; }; - std::list< TXQueueEntry > _txQueue; + std::list _txQueue; Mutex _txQueue_m; Mutex _aqm_m; // Tracks sending of VERB_RENDEZVOUS to relaying peers - struct _LastUniteKey - { - _LastUniteKey() : x(0),y(0) {} - _LastUniteKey(const Address &a1,const Address &a2) + struct _LastUniteKey { + _LastUniteKey() : x(0), y(0) + { + } + _LastUniteKey(const Address& a1, const Address& a2) { if (a1 > a2) { x = a2.toInt(); y = a1.toInt(); - } else { + } + else { x = a1.toInt(); y = a2.toInt(); } } - inline unsigned long hashCode() const { return ((unsigned long)x ^ (unsigned long)y); } - inline bool operator==(const _LastUniteKey &k) const { return ((x == k.x)&&(y == k.y)); } - uint64_t x,y; + inline unsigned long hashCode() const + { + return ((unsigned long)x ^ (unsigned long)y); + } + inline bool operator==(const _LastUniteKey& k) const + { + return ((x == k.x) && (y == k.y)); + } + uint64_t x, y; }; - Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior + Hashtable<_LastUniteKey, uint64_t> _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior Mutex _lastUniteAttempt_m; // Queue with additional flow state variables - struct ManagedQueue - { - ManagedQueue(int id) : - id(id), - byteCredit(ZT_AQM_QUANTUM), - byteLength(0), - dropping(false) - {} + struct ManagedQueue { + ManagedQueue(int id) : id(id), byteCredit(ZT_AQM_QUANTUM), byteLength(0), dropping(false) + { + } int id; int byteCredit; int byteLength; @@ -314,19 +316,18 @@ private: uint64_t drop_next; bool dropping; uint64_t drop_next_time; - std::list< TXQueueEntry *> q; + std::list q; }; // To implement fq_codel we need to maintain a queue of queues - struct NetworkQoSControlBlock - { + struct NetworkQoSControlBlock { int _currEnqueuedPackets; - std::vector newQueues; - std::vector oldQueues; - std::vector inactiveQueues; + std::vector newQueues; + std::vector oldQueues; + std::vector inactiveQueues; }; - std::map _netQueueControlBlock; + std::map _netQueueControlBlock; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Tag.cpp b/node/Tag.cpp index effb69076..a1ce0c0ed 100644 --- a/node/Tag.cpp +++ b/node/Tag.cpp @@ -12,32 +12,34 @@ /****/ #include "Tag.hpp" -#include "RuntimeEnvironment.hpp" + #include "Identity.hpp" -#include "Topology.hpp" -#include "Switch.hpp" #include "Network.hpp" #include "Node.hpp" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Topology.hpp" namespace ZeroTier { -int Tag::verify(const RuntimeEnvironment *RR,void *tPtr) const +int Tag::verify(const RuntimeEnvironment* RR, void* tPtr) const { - if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId))) { + if ((! _signedBy) || (_signedBy != Network::controllerFor(_networkId))) { return -1; } - const Identity id(RR->topology->getIdentity(tPtr,_signedBy)); - if (!id) { - RR->sw->requestWhois(tPtr,RR->node->now(),_signedBy); + const Identity id(RR->topology->getIdentity(tPtr, _signedBy)); + if (! id) { + RR->sw->requestWhois(tPtr, RR->node->now(), _signedBy); return 1; } try { Buffer<(sizeof(Tag) * 2)> tmp; - this->serialize(tmp,true); - return (id.verify(tmp.data(),tmp.size(),_signature) ? 0 : -1); - } catch ( ... ) { + this->serialize(tmp, true); + return (id.verify(tmp.data(), tmp.size(), _signature) ? 0 : -1); + } + catch (...) { return -1; } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Tag.hpp b/node/Tag.hpp index c3af4725c..24aa00d7b 100644 --- a/node/Tag.hpp +++ b/node/Tag.hpp @@ -14,18 +14,18 @@ #ifndef ZT_TAG_HPP #define ZT_TAG_HPP +#include "Address.hpp" +#include "Buffer.hpp" +#include "C25519.hpp" +#include "Constants.hpp" +#include "Credential.hpp" +#include "Identity.hpp" + #include #include #include #include -#include "Constants.hpp" -#include "Credential.hpp" -#include "C25519.hpp" -#include "Address.hpp" -#include "Identity.hpp" -#include "Buffer.hpp" - namespace ZeroTier { class RuntimeEnvironment; @@ -47,18 +47,16 @@ class RuntimeEnvironment; * Unlike capabilities tags are signed only by the issuer and are never * transferable. */ -class Tag : public Credential -{ -public: - static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; } - - Tag() : - _id(0), - _value(0), - _networkId(0), - _ts(0) +class Tag : public Credential { + public: + static inline Credential::Type credentialType() { - memset(_signature.data,0,sizeof(_signature.data)); + return Credential::CREDENTIAL_TYPE_TAG; + } + + Tag() : _id(0), _value(0), _networkId(0), _ts(0) + { + memset(_signature.data, 0, sizeof(_signature.data)); } /** @@ -68,23 +66,35 @@ public: * @param id Tag ID * @param value Tag value */ - Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) : - _id(id), - _value(value), - _networkId(nwid), - _ts(ts), - _issuedTo(issuedTo), - _signedBy() + Tag(const uint64_t nwid, const int64_t ts, const Address& issuedTo, const uint32_t id, const uint32_t value) : _id(id), _value(value), _networkId(nwid), _ts(ts), _issuedTo(issuedTo), _signedBy() { - memset(_signature.data,0,sizeof(_signature.data)); + memset(_signature.data, 0, sizeof(_signature.data)); } - inline uint32_t id() const { return _id; } - inline const uint32_t &value() const { return _value; } - inline uint64_t networkId() const { return _networkId; } - inline int64_t timestamp() const { return _ts; } - inline const Address &issuedTo() const { return _issuedTo; } - inline const Address &signedBy() const { return _signedBy; } + inline uint32_t id() const + { + return _id; + } + inline const uint32_t& value() const + { + return _value; + } + inline uint64_t networkId() const + { + return _networkId; + } + inline int64_t timestamp() const + { + return _ts; + } + inline const Address& issuedTo() const + { + return _issuedTo; + } + inline const Address& signedBy() const + { + return _signedBy; + } /** * Sign this tag @@ -92,13 +102,13 @@ public: * @param signer Signing identity, must have private key * @return True if signature was successful */ - inline bool sign(const Identity &signer) + inline bool sign(const Identity& signer) { if (signer.hasPrivate()) { Buffer tmp; _signedBy = signer.address(); - this->serialize(tmp,true); - _signature = signer.sign(tmp.data(),tmp.size()); + this->serialize(tmp, true); + _signature = signer.sign(tmp.data(), tmp.size()); return true; } return false; @@ -111,10 +121,9 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or tag */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; + int verify(const RuntimeEnvironment* RR, void* tPtr) const; - template - inline void serialize(Buffer &b,const bool forSign = false) const + template inline void serialize(Buffer& b, const bool forSign = false) const { if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); @@ -127,21 +136,20 @@ public: _issuedTo.appendTo(b); _signedBy.appendTo(b); - if (!forSign) { - b.append((uint8_t)1); // 1 == Ed25519 - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature - b.append(_signature.data,ZT_C25519_SIGNATURE_LEN); + if (! forSign) { + b.append((uint8_t)1); // 1 == Ed25519 + b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature + b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); } - b.append((uint16_t)0); // length of additional fields, currently 0 + b.append((uint16_t)0); // length of additional fields, currently 0 if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { unsigned int p = startAt; @@ -157,18 +165,19 @@ public: _value = b.template at(p); p += 4; - _issuedTo.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _issuedTo.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; - _signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + _signedBy.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] == 1) { if (b.template at(p) != ZT_C25519_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; - } else { + } + else { p += 2 + b.template at(p); } @@ -181,26 +190,61 @@ public: } // Provides natural sort order by ID - inline bool operator<(const Tag &t) const { return (_id < t._id); } + inline bool operator<(const Tag& t) const + { + return (_id < t._id); + } - inline bool operator==(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) == 0); } - inline bool operator!=(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) != 0); } + inline bool operator==(const Tag& t) const + { + return (memcmp(this, &t, sizeof(Tag)) == 0); + } + inline bool operator!=(const Tag& t) const + { + return (memcmp(this, &t, sizeof(Tag)) != 0); + } // For searching sorted arrays or lists of Tags by ID - struct IdComparePredicate - { - inline bool operator()(const Tag &a,const Tag &b) const { return (a.id() < b.id()); } - inline bool operator()(const uint32_t a,const Tag &b) const { return (a < b.id()); } - inline bool operator()(const Tag &a,const uint32_t b) const { return (a.id() < b); } - inline bool operator()(const Tag *a,const Tag *b) const { return (a->id() < b->id()); } - inline bool operator()(const Tag *a,const Tag &b) const { return (a->id() < b.id()); } - inline bool operator()(const Tag &a,const Tag *b) const { return (a.id() < b->id()); } - inline bool operator()(const uint32_t a,const Tag *b) const { return (a < b->id()); } - inline bool operator()(const Tag *a,const uint32_t b) const { return (a->id() < b); } - inline bool operator()(const uint32_t a,const uint32_t b) const { return (a < b); } + struct IdComparePredicate { + inline bool operator()(const Tag& a, const Tag& b) const + { + return (a.id() < b.id()); + } + inline bool operator()(const uint32_t a, const Tag& b) const + { + return (a < b.id()); + } + inline bool operator()(const Tag& a, const uint32_t b) const + { + return (a.id() < b); + } + inline bool operator()(const Tag* a, const Tag* b) const + { + return (a->id() < b->id()); + } + inline bool operator()(const Tag* a, const Tag& b) const + { + return (a->id() < b.id()); + } + inline bool operator()(const Tag& a, const Tag* b) const + { + return (a.id() < b->id()); + } + inline bool operator()(const uint32_t a, const Tag* b) const + { + return (a < b->id()); + } + inline bool operator()(const Tag* a, const uint32_t b) const + { + return (a->id() < b); + } + inline bool operator()(const uint32_t a, const uint32_t b) const + { + return (a < b); + } }; -private: + private: uint32_t _id; uint32_t _value; uint64_t _networkId; @@ -210,6 +254,6 @@ private: C25519::Signature _signature; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Topology.cpp b/node/Topology.cpp index fc272ce54..fc7e4ad1b 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -11,63 +11,79 @@ */ /****/ -#include "Constants.hpp" #include "Topology.hpp" -#include "RuntimeEnvironment.hpp" -#include "Node.hpp" + +#include "Buffer.hpp" +#include "Constants.hpp" #include "Network.hpp" #include "NetworkConfig.hpp" -#include "Buffer.hpp" +#include "Node.hpp" +#include "RuntimeEnvironment.hpp" #include "Switch.hpp" namespace ZeroTier { #define ZT_DEFAULT_WORLD_LENGTH 570 -static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x7e,0xe9,0x57,0x60,0xcd,0xb8,0xb3,0x88,0xa4,0x69,0x22,0x14,0x91,0xaa,0x9a,0xcd,0x66,0xcc,0x76,0x4c,0xde,0xfd,0x56,0x03,0x9f,0x10,0x67,0xae,0x15,0xe6,0x9c,0x6f,0xb4,0x2d,0x7b,0x55,0x33,0x0e,0x3f,0xda,0xac,0x52,0x9c,0x07,0x92,0xfd,0x73,0x40,0xa6,0xaa,0x21,0xab,0xa8,0xa4,0x89,0xfd,0xae,0xa4,0x4a,0x39,0xbf,0x2d,0x00,0x65,0x9a,0xc9,0xc8,0x18,0xeb,0x36,0x00,0x92,0x76,0x37,0xef,0x4d,0x14,0x04,0xa4,0x4d,0x54,0x46,0x84,0x85,0x13,0x79,0x75,0x1f,0xaa,0x79,0xb4,0xc4,0xea,0x85,0x04,0x01,0x75,0xea,0x06,0x58,0x60,0x48,0x24,0x02,0xe1,0xeb,0x34,0x20,0x52,0x00,0x0e,0x62,0x90,0x06,0x1a,0x9b,0xe0,0xcd,0x29,0x3c,0x8b,0x55,0xf1,0xc3,0xd2,0x52,0x48,0x08,0xaf,0xc5,0x49,0x22,0x08,0x0e,0x35,0x39,0xa7,0x5a,0xdd,0xc3,0xce,0xf0,0xf6,0xad,0x26,0x0d,0x58,0x82,0x93,0xbb,0x77,0x86,0xe7,0x1e,0xfa,0x4b,0x90,0x57,0xda,0xd9,0x86,0x7a,0xfe,0x12,0xdd,0x04,0xca,0xfe,0x9e,0xfe,0xb9,0x00,0xcc,0xde,0xf7,0x6b,0xc7,0xb9,0x7d,0xed,0x90,0x4e,0xab,0xc5,0xdf,0x09,0x88,0x6d,0x9c,0x15,0x14,0xa6,0x10,0x03,0x6c,0xb9,0x13,0x9c,0xc2,0x14,0x00,0x1a,0x29,0x58,0x97,0x8e,0xfc,0xec,0x15,0x71,0x2d,0xd3,0x94,0x8c,0x6e,0x6b,0x3a,0x8e,0x89,0x3d,0xf0,0x1f,0xf4,0x93,0xd1,0xf8,0xd9,0x80,0x6a,0x86,0x0c,0x54,0x20,0x57,0x1b,0xf0,0x00,0x02,0x04,0x68,0xc2,0x08,0x86,0x27,0x09,0x06,0x26,0x05,0x98,0x80,0x02,0x00,0x12,0x00,0x00,0x30,0x05,0x71,0x0e,0x34,0x00,0x51,0x27,0x09,0x77,0x8c,0xde,0x71,0x90,0x00,0x3f,0x66,0x81,0xa9,0x9e,0x5a,0xd1,0x89,0x5e,0x9f,0xba,0x33,0xe6,0x21,0x2d,0x44,0x54,0xe1,0x68,0xbc,0xec,0x71,0x12,0x10,0x1b,0xf0,0x00,0x95,0x6e,0xd8,0xe9,0x2e,0x42,0x89,0x2c,0xb6,0xf2,0xec,0x41,0x08,0x81,0xa8,0x4a,0xb1,0x9d,0xa5,0x0e,0x12,0x87,0xba,0x3d,0x92,0x6c,0x3a,0x1f,0x75,0x5c,0xcc,0xf2,0x99,0xa1,0x20,0x70,0x55,0x00,0x02,0x04,0x67,0xc3,0x67,0x42,0x27,0x09,0x06,0x26,0x05,0x98,0x80,0x04,0x00,0x00,0xc3,0x02,0x54,0xf2,0xbc,0xa1,0xf7,0x00,0x19,0x27,0x09,0x62,0xf8,0x65,0xae,0x71,0x00,0xe2,0x07,0x6c,0x57,0xde,0x87,0x0e,0x62,0x88,0xd7,0xd5,0xe7,0x40,0x44,0x08,0xb1,0x54,0x5e,0xfc,0xa3,0x7d,0x67,0xf7,0x7b,0x87,0xe9,0xe5,0x41,0x68,0xc2,0x5d,0x3e,0xf1,0xa9,0xab,0xf2,0x90,0x5e,0xa5,0xe7,0x85,0xc0,0x1d,0xff,0x23,0x88,0x7a,0xd4,0x23,0x2d,0x95,0xc7,0xa8,0xfd,0x2c,0x27,0x11,0x1a,0x72,0xbd,0x15,0x93,0x22,0xdc,0x00,0x02,0x04,0x32,0x07,0xfc,0x8a,0x27,0x09,0x06,0x20,0x01,0x49,0xf0,0xd0,0xdb,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0xca,0xfe,0x04,0xeb,0xa9,0x00,0x6c,0x6a,0x9d,0x1d,0xea,0x55,0xc1,0x61,0x6b,0xfe,0x2a,0x2b,0x8f,0x0f,0xf9,0xa8,0xca,0xca,0xf7,0x03,0x74,0xfb,0x1f,0x39,0xe3,0xbe,0xf8,0x1c,0xbf,0xeb,0xef,0x17,0xb7,0x22,0x82,0x68,0xa0,0xa2,0xa2,0x9d,0x34,0x88,0xc7,0x52,0x56,0x5c,0x6c,0x96,0x5c,0xbd,0x65,0x06,0xec,0x24,0x39,0x7c,0xc8,0xa5,0xd9,0xd1,0x52,0x85,0xa8,0x7f,0x00,0x02,0x04,0x54,0x11,0x35,0x9b,0x27,0x09,0x06,0x2a,0x02,0x6e,0xa0,0xd4,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x93,0x27,0x09}; +static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xea, 0xc9, 0x0a, 0x00, 0x00, 0x01, 0x7e, 0xe9, 0x57, 0x60, 0xcd, 0xb8, 0xb3, 0x88, 0xa4, 0x69, 0x22, 0x14, 0x91, 0xaa, 0x9a, 0xcd, 0x66, 0xcc, 0x76, 0x4c, 0xde, 0xfd, 0x56, 0x03, 0x9f, 0x10, + 0x67, 0xae, 0x15, 0xe6, 0x9c, 0x6f, 0xb4, 0x2d, 0x7b, 0x55, 0x33, 0x0e, 0x3f, 0xda, 0xac, 0x52, 0x9c, 0x07, 0x92, 0xfd, 0x73, 0x40, 0xa6, 0xaa, 0x21, 0xab, 0xa8, 0xa4, 0x89, 0xfd, 0xae, 0xa4, 0x4a, 0x39, 0xbf, 0x2d, 0x00, 0x65, + 0x9a, 0xc9, 0xc8, 0x18, 0xeb, 0x36, 0x00, 0x92, 0x76, 0x37, 0xef, 0x4d, 0x14, 0x04, 0xa4, 0x4d, 0x54, 0x46, 0x84, 0x85, 0x13, 0x79, 0x75, 0x1f, 0xaa, 0x79, 0xb4, 0xc4, 0xea, 0x85, 0x04, 0x01, 0x75, 0xea, 0x06, 0x58, 0x60, 0x48, + 0x24, 0x02, 0xe1, 0xeb, 0x34, 0x20, 0x52, 0x00, 0x0e, 0x62, 0x90, 0x06, 0x1a, 0x9b, 0xe0, 0xcd, 0x29, 0x3c, 0x8b, 0x55, 0xf1, 0xc3, 0xd2, 0x52, 0x48, 0x08, 0xaf, 0xc5, 0x49, 0x22, 0x08, 0x0e, 0x35, 0x39, 0xa7, 0x5a, 0xdd, 0xc3, + 0xce, 0xf0, 0xf6, 0xad, 0x26, 0x0d, 0x58, 0x82, 0x93, 0xbb, 0x77, 0x86, 0xe7, 0x1e, 0xfa, 0x4b, 0x90, 0x57, 0xda, 0xd9, 0x86, 0x7a, 0xfe, 0x12, 0xdd, 0x04, 0xca, 0xfe, 0x9e, 0xfe, 0xb9, 0x00, 0xcc, 0xde, 0xf7, 0x6b, 0xc7, 0xb9, + 0x7d, 0xed, 0x90, 0x4e, 0xab, 0xc5, 0xdf, 0x09, 0x88, 0x6d, 0x9c, 0x15, 0x14, 0xa6, 0x10, 0x03, 0x6c, 0xb9, 0x13, 0x9c, 0xc2, 0x14, 0x00, 0x1a, 0x29, 0x58, 0x97, 0x8e, 0xfc, 0xec, 0x15, 0x71, 0x2d, 0xd3, 0x94, 0x8c, 0x6e, 0x6b, + 0x3a, 0x8e, 0x89, 0x3d, 0xf0, 0x1f, 0xf4, 0x93, 0xd1, 0xf8, 0xd9, 0x80, 0x6a, 0x86, 0x0c, 0x54, 0x20, 0x57, 0x1b, 0xf0, 0x00, 0x02, 0x04, 0x68, 0xc2, 0x08, 0x86, 0x27, 0x09, 0x06, 0x26, 0x05, 0x98, 0x80, 0x02, 0x00, 0x12, 0x00, + 0x00, 0x30, 0x05, 0x71, 0x0e, 0x34, 0x00, 0x51, 0x27, 0x09, 0x77, 0x8c, 0xde, 0x71, 0x90, 0x00, 0x3f, 0x66, 0x81, 0xa9, 0x9e, 0x5a, 0xd1, 0x89, 0x5e, 0x9f, 0xba, 0x33, 0xe6, 0x21, 0x2d, 0x44, 0x54, 0xe1, 0x68, 0xbc, 0xec, 0x71, + 0x12, 0x10, 0x1b, 0xf0, 0x00, 0x95, 0x6e, 0xd8, 0xe9, 0x2e, 0x42, 0x89, 0x2c, 0xb6, 0xf2, 0xec, 0x41, 0x08, 0x81, 0xa8, 0x4a, 0xb1, 0x9d, 0xa5, 0x0e, 0x12, 0x87, 0xba, 0x3d, 0x92, 0x6c, 0x3a, 0x1f, 0x75, 0x5c, 0xcc, 0xf2, 0x99, + 0xa1, 0x20, 0x70, 0x55, 0x00, 0x02, 0x04, 0x67, 0xc3, 0x67, 0x42, 0x27, 0x09, 0x06, 0x26, 0x05, 0x98, 0x80, 0x04, 0x00, 0x00, 0xc3, 0x02, 0x54, 0xf2, 0xbc, 0xa1, 0xf7, 0x00, 0x19, 0x27, 0x09, 0x62, 0xf8, 0x65, 0xae, 0x71, 0x00, + 0xe2, 0x07, 0x6c, 0x57, 0xde, 0x87, 0x0e, 0x62, 0x88, 0xd7, 0xd5, 0xe7, 0x40, 0x44, 0x08, 0xb1, 0x54, 0x5e, 0xfc, 0xa3, 0x7d, 0x67, 0xf7, 0x7b, 0x87, 0xe9, 0xe5, 0x41, 0x68, 0xc2, 0x5d, 0x3e, 0xf1, 0xa9, 0xab, 0xf2, 0x90, 0x5e, + 0xa5, 0xe7, 0x85, 0xc0, 0x1d, 0xff, 0x23, 0x88, 0x7a, 0xd4, 0x23, 0x2d, 0x95, 0xc7, 0xa8, 0xfd, 0x2c, 0x27, 0x11, 0x1a, 0x72, 0xbd, 0x15, 0x93, 0x22, 0xdc, 0x00, 0x02, 0x04, 0x32, 0x07, 0xfc, 0x8a, 0x27, 0x09, 0x06, 0x20, 0x01, + 0x49, 0xf0, 0xd0, 0xdb, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x27, 0x09, 0xca, 0xfe, 0x04, 0xeb, 0xa9, 0x00, 0x6c, 0x6a, 0x9d, 0x1d, 0xea, 0x55, 0xc1, 0x61, 0x6b, 0xfe, 0x2a, 0x2b, 0x8f, 0x0f, 0xf9, 0xa8, + 0xca, 0xca, 0xf7, 0x03, 0x74, 0xfb, 0x1f, 0x39, 0xe3, 0xbe, 0xf8, 0x1c, 0xbf, 0xeb, 0xef, 0x17, 0xb7, 0x22, 0x82, 0x68, 0xa0, 0xa2, 0xa2, 0x9d, 0x34, 0x88, 0xc7, 0x52, 0x56, 0x5c, 0x6c, 0x96, 0x5c, 0xbd, 0x65, 0x06, 0xec, 0x24, + 0x39, 0x7c, 0xc8, 0xa5, 0xd9, 0xd1, 0x52, 0x85, 0xa8, 0x7f, 0x00, 0x02, 0x04, 0x54, 0x11, 0x35, 0x9b, 0x27, 0x09, 0x06, 0x2a, 0x02, 0x6e, 0xa0, 0xd4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x93, 0x27, 0x09 +}; -Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) : - RR(renv), - _numConfiguredPhysicalPaths(0), - _amUpstream(false) +Topology::Topology(const RuntimeEnvironment* renv, void* tPtr) : RR(renv), _numConfiguredPhysicalPaths(0), _amUpstream(false) { uint8_t tmp[ZT_WORLD_MAX_SERIALIZED_LENGTH]; uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0; - int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PLANET,idtmp,tmp,sizeof(tmp)); + int n = RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_PLANET, idtmp, tmp, sizeof(tmp)); if (n > 0) { try { World cachedPlanet; - cachedPlanet.deserialize(Buffer(tmp,(unsigned int)n),0); - addWorld(tPtr,cachedPlanet,false); - } catch ( ... ) {} // ignore invalid cached planets + cachedPlanet.deserialize(Buffer(tmp, (unsigned int)n), 0); + addWorld(tPtr, cachedPlanet, false); + } + catch (...) { + } // ignore invalid cached planets } World defaultPlanet; { - Buffer wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH); - defaultPlanet.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top + Buffer wtmp(ZT_DEFAULT_WORLD, ZT_DEFAULT_WORLD_LENGTH); + defaultPlanet.deserialize(wtmp, 0); // throws on error, which would indicate a bad static variable up top } - addWorld(tPtr,defaultPlanet,false); + addWorld(tPtr, defaultPlanet, false); } Topology::~Topology() { - Hashtable< Address,SharedPtr >::Iterator i(_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; - while (i.next(a,p)) { - _savePeer((void *)0,*p); + Hashtable >::Iterator i(_peers); + Address* a = (Address*)0; + SharedPtr* p = (SharedPtr*)0; + while (i.next(a, p)) { + _savePeer((void*)0, *p); } } -SharedPtr Topology::addPeer(void *tPtr,const SharedPtr &peer) +SharedPtr Topology::addPeer(void* tPtr, const SharedPtr& peer) { SharedPtr np; { Mutex::Lock _l(_peers_m); - SharedPtr &hp = _peers[peer->address()]; - if (!hp) { + SharedPtr& hp = _peers[peer->address()]; + if (! hp) { hp = peer; } np = hp; @@ -75,7 +91,7 @@ SharedPtr Topology::addPeer(void *tPtr,const SharedPtr &peer) return np; } -SharedPtr Topology::getPeer(void *tPtr,const Address &zta) +SharedPtr Topology::getPeer(void* tPtr, const Address& zta) { if (zta == RR->identity.address()) { return SharedPtr(); @@ -83,7 +99,7 @@ SharedPtr Topology::getPeer(void *tPtr,const Address &zta) { Mutex::Lock _l(_peers_m); - const SharedPtr *const ap = _peers.get(zta); + const SharedPtr* const ap = _peers.get(zta); if (ap) { return *ap; } @@ -94,32 +110,35 @@ SharedPtr Topology::getPeer(void *tPtr,const Address &zta) uint64_t idbuf[2]; idbuf[0] = zta.toInt(); idbuf[1] = 0; - int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,idbuf,buf.unsafeData(),ZT_PEER_MAX_SERIALIZED_STATE_SIZE); + int len = RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_PEER, idbuf, buf.unsafeData(), ZT_PEER_MAX_SERIALIZED_STATE_SIZE); if (len > 0) { buf.setSize(len); Mutex::Lock _l(_peers_m); - SharedPtr &ap = _peers[zta]; + SharedPtr& ap = _peers[zta]; if (ap) { return ap; } - ap = Peer::deserializeFromCache(RR->node->now(),tPtr,buf,RR); - if (!ap) { + ap = Peer::deserializeFromCache(RR->node->now(), tPtr, buf, RR); + if (! ap) { _peers.erase(zta); } return SharedPtr(); } - } catch ( ... ) {} // ignore invalid identities or other strange failures + } + catch (...) { + } // ignore invalid identities or other strange failures return SharedPtr(); } -Identity Topology::getIdentity(void *tPtr,const Address &zta) +Identity Topology::getIdentity(void* tPtr, const Address& zta) { if (zta == RR->identity.address()) { return RR->identity; - } else { + } + else { Mutex::Lock _l(_peers_m); - const SharedPtr *const ap = _peers.get(zta); + const SharedPtr* const ap = _peers.get(zta); if (ap) { return (*ap)->identity(); } @@ -131,13 +150,13 @@ SharedPtr Topology::getUpstreamPeer() { const int64_t now = RR->node->now(); unsigned int bestq = ~((unsigned int)0); - const SharedPtr *best = (const SharedPtr *)0; + const SharedPtr* best = (const SharedPtr*)0; Mutex::Lock _l2(_peers_m); Mutex::Lock _l1(_upstreams_m); - for(std::vector
::const_iterator a(_upstreamAddresses.begin());a!=_upstreamAddresses.end();++a) { - const SharedPtr *p = _peers.get(*a); + for (std::vector
::const_iterator a(_upstreamAddresses.begin()); a != _upstreamAddresses.end(); ++a) { + const SharedPtr* p = _peers.get(*a); if (p) { const unsigned int q = (*p)->relayQuality(now); if (q <= bestq) { @@ -147,25 +166,25 @@ SharedPtr Topology::getUpstreamPeer() } } - if (!best) { + if (! best) { return SharedPtr(); } return *best; } -bool Topology::isUpstream(const Identity &id) const +bool Topology::isUpstream(const Identity& id) const { Mutex::Lock _l(_upstreams_m); - return (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) != _upstreamAddresses.end()); + return (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), id.address()) != _upstreamAddresses.end()); } -bool Topology::shouldAcceptWorldUpdateFrom(const Address &addr) const +bool Topology::shouldAcceptWorldUpdateFrom(const Address& addr) const { Mutex::Lock _l(_upstreams_m); - if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),addr) != _upstreamAddresses.end()) { + if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), addr) != _upstreamAddresses.end()) { return true; } - for(std::vector< std::pair< uint64_t,Address> >::const_iterator s(_moonSeeds.begin());s!=_moonSeeds.end();++s) { + for (std::vector >::const_iterator s(_moonSeeds.begin()); s != _moonSeeds.end(); ++s) { if (s->second == addr) { return true; } @@ -173,11 +192,11 @@ bool Topology::shouldAcceptWorldUpdateFrom(const Address &addr) const return false; } -ZT_PeerRole Topology::role(const Address &ztaddr) const +ZT_PeerRole Topology::role(const Address& ztaddr) const { Mutex::Lock _l(_upstreams_m); - if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),ztaddr) != _upstreamAddresses.end()) { - for(std::vector::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { + if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), ztaddr) != _upstreamAddresses.end()) { + for (std::vector::const_iterator i(_planet.roots().begin()); i != _planet.roots().end(); ++i) { if (i->identity.address() == ztaddr) { return ZT_PEER_ROLE_PLANET; } @@ -187,32 +206,32 @@ ZT_PeerRole Topology::role(const Address &ztaddr) const return ZT_PEER_ROLE_LEAF; } -bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const +bool Topology::isProhibitedEndpoint(const Address& ztaddr, const InetAddress& ipaddr) const { Mutex::Lock _l(_upstreams_m); // For roots the only permitted addresses are those defined. This adds just a little // bit of extra security against spoofing, replaying, etc. - if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),ztaddr) != _upstreamAddresses.end()) { - for(std::vector::const_iterator r(_planet.roots().begin());r!=_planet.roots().end();++r) { + if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), ztaddr) != _upstreamAddresses.end()) { + for (std::vector::const_iterator r(_planet.roots().begin()); r != _planet.roots().end(); ++r) { if (r->identity.address() == ztaddr) { if (r->stableEndpoints.empty()) { - return false; // no stable endpoints specified, so allow dynamic paths + return false; // no stable endpoints specified, so allow dynamic paths } - for(std::vector::const_iterator e(r->stableEndpoints.begin());e!=r->stableEndpoints.end();++e) { + for (std::vector::const_iterator e(r->stableEndpoints.begin()); e != r->stableEndpoints.end(); ++e) { if (ipaddr.ipsEqual(*e)) { return false; } } } } - for(std::vector::const_iterator m(_moons.begin());m!=_moons.end();++m) { - for(std::vector::const_iterator r(m->roots().begin());r!=m->roots().end();++r) { + for (std::vector::const_iterator m(_moons.begin()); m != _moons.end(); ++m) { + for (std::vector::const_iterator r(m->roots().begin()); r != m->roots().end(); ++r) { if (r->identity.address() == ztaddr) { if (r->stableEndpoints.empty()) { - return false; // no stable endpoints specified, so allow dynamic paths + return false; // no stable endpoints specified, so allow dynamic paths } - for(std::vector::const_iterator e(r->stableEndpoints.begin());e!=r->stableEndpoints.end();++e) { + for (std::vector::const_iterator e(r->stableEndpoints.begin()); e != r->stableEndpoints.end(); ++e) { if (ipaddr.ipsEqual(*e)) { return false; } @@ -226,22 +245,22 @@ bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipa return false; } -bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew) +bool Topology::addWorld(void* tPtr, const World& newWorld, bool alwaysAcceptNew) { - if ((newWorld.type() != World::TYPE_PLANET)&&(newWorld.type() != World::TYPE_MOON)) { + if ((newWorld.type() != World::TYPE_PLANET) && (newWorld.type() != World::TYPE_MOON)) { return false; } Mutex::Lock _l2(_peers_m); Mutex::Lock _l1(_upstreams_m); - World *existing = (World *)0; - switch(newWorld.type()) { + World* existing = (World*)0; + switch (newWorld.type()) { case World::TYPE_PLANET: existing = &_planet; break; case World::TYPE_MOON: - for(std::vector< World >::iterator m(_moons.begin());m!=_moons.end();++m) { + for (std::vector::iterator m(_moons.begin()); m != _moons.end(); ++m) { if (m->id() == newWorld.id()) { existing = &(*m); break; @@ -255,17 +274,20 @@ bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew) if (existing) { if (existing->shouldBeReplacedBy(newWorld)) { *existing = newWorld; - } else { + } + else { return false; } - } else if (newWorld.type() == World::TYPE_MOON) { + } + else if (newWorld.type() == World::TYPE_MOON) { if (alwaysAcceptNew) { _moons.push_back(newWorld); existing = &(_moons.back()); - } else { - for(std::vector< std::pair >::iterator m(_moonSeeds.begin());m!=_moonSeeds.end();++m) { + } + else { + for (std::vector >::iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) { if (m->first == newWorld.id()) { - for(std::vector::const_iterator r(newWorld.roots().begin());r!=newWorld.roots().end();++r) { + for (std::vector::const_iterator r(newWorld.roots().begin()); r != newWorld.roots().end(); ++r) { if (r->identity.address() == m->second) { _moonSeeds.erase(m); _moons.push_back(newWorld); @@ -279,73 +301,79 @@ bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew) } } } - if (!existing) { + if (! existing) { return false; } - } else { + } + else { return false; } try { Buffer sbuf; - existing->serialize(sbuf,false); + existing->serialize(sbuf, false); uint64_t idtmp[2]; idtmp[0] = existing->id(); idtmp[1] = 0; - RR->node->stateObjectPut(tPtr,(existing->type() == World::TYPE_PLANET) ? ZT_STATE_OBJECT_PLANET : ZT_STATE_OBJECT_MOON,idtmp,sbuf.data(),sbuf.size()); - } catch ( ... ) {} + RR->node->stateObjectPut(tPtr, (existing->type() == World::TYPE_PLANET) ? ZT_STATE_OBJECT_PLANET : ZT_STATE_OBJECT_MOON, idtmp, sbuf.data(), sbuf.size()); + } + catch (...) { + } _memoizeUpstreams(tPtr); return true; } -void Topology::addMoon(void *tPtr,const uint64_t id,const Address &seed) +void Topology::addMoon(void* tPtr, const uint64_t id, const Address& seed) { char tmp[ZT_WORLD_MAX_SERIALIZED_LENGTH]; uint64_t idtmp[2]; idtmp[0] = id; idtmp[1] = 0; - int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_MOON,idtmp,tmp,sizeof(tmp)); + int n = RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_MOON, idtmp, tmp, sizeof(tmp)); if (n > 0) { try { World w; - w.deserialize(Buffer(tmp,(unsigned int)n)); - if ((w.type() == World::TYPE_MOON)&&(w.id() == id)) { - addWorld(tPtr,w,true); + w.deserialize(Buffer(tmp, (unsigned int)n)); + if ((w.type() == World::TYPE_MOON) && (w.id() == id)) { + addWorld(tPtr, w, true); return; } - } catch ( ... ) {} + } + catch (...) { + } } if (seed) { Mutex::Lock _l(_upstreams_m); - if (std::find(_moonSeeds.begin(),_moonSeeds.end(),std::pair(id,seed)) == _moonSeeds.end()) { - _moonSeeds.push_back(std::pair(id,seed)); + if (std::find(_moonSeeds.begin(), _moonSeeds.end(), std::pair(id, seed)) == _moonSeeds.end()) { + _moonSeeds.push_back(std::pair(id, seed)); } } } -void Topology::removeMoon(void *tPtr,const uint64_t id) +void Topology::removeMoon(void* tPtr, const uint64_t id) { Mutex::Lock _l2(_peers_m); Mutex::Lock _l1(_upstreams_m); std::vector nm; - for(std::vector::const_iterator m(_moons.begin());m!=_moons.end();++m) { + for (std::vector::const_iterator m(_moons.begin()); m != _moons.end(); ++m) { if (m->id() != id) { nm.push_back(*m); - } else { + } + else { uint64_t idtmp[2]; idtmp[0] = id; idtmp[1] = 0; - RR->node->stateObjectDelete(tPtr,ZT_STATE_OBJECT_MOON,idtmp); + RR->node->stateObjectDelete(tPtr, ZT_STATE_OBJECT_MOON, idtmp); } } _moons.swap(nm); - std::vector< std::pair > cm; - for(std::vector< std::pair >::const_iterator m(_moonSeeds.begin());m!=_moonSeeds.end();++m) { + std::vector > cm; + for (std::vector >::const_iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) { if (m->first != id) { cm.push_back(*m); } @@ -355,17 +383,17 @@ void Topology::removeMoon(void *tPtr,const uint64_t id) _memoizeUpstreams(tPtr); } -void Topology::doPeriodicTasks(void *tPtr,int64_t now) +void Topology::doPeriodicTasks(void* tPtr, int64_t now) { { Mutex::Lock _l1(_peers_m); Mutex::Lock _l2(_upstreams_m); - Hashtable< Address,SharedPtr >::Iterator i(_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; - while (i.next(a,p)) { - if ( (!(*p)->isAlive(now)) && (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),*a) == _upstreamAddresses.end()) ) { - _savePeer(tPtr,*p); + Hashtable >::Iterator i(_peers); + Address* a = (Address*)0; + SharedPtr* p = (SharedPtr*)0; + while (i.next(a, p)) { + if ((! (*p)->isAlive(now)) && (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), *a) == _upstreamAddresses.end())) { + _savePeer(tPtr, *p); _peers.erase(*a); } } @@ -373,10 +401,10 @@ void Topology::doPeriodicTasks(void *tPtr,int64_t now) { Mutex::Lock _l(_paths_m); - Hashtable< Path::HashKey,SharedPtr >::Iterator i(_paths); - Path::HashKey *k = (Path::HashKey *)0; - SharedPtr *p = (SharedPtr *)0; - while (i.next(k,p)) { + Hashtable >::Iterator i(_paths); + Path::HashKey* k = (Path::HashKey*)0; + SharedPtr* p = (SharedPtr*)0; + while (i.next(k, p)) { if (p->references() <= 1) { _paths.erase(*k); } @@ -384,43 +412,45 @@ void Topology::doPeriodicTasks(void *tPtr,int64_t now) } } -void Topology::_memoizeUpstreams(void *tPtr) +void Topology::_memoizeUpstreams(void* tPtr) { // assumes _upstreams_m and _peers_m are locked _upstreamAddresses.clear(); _amUpstream = false; - for(std::vector::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { - const Identity &id = i->identity; + for (std::vector::const_iterator i(_planet.roots().begin()); i != _planet.roots().end(); ++i) { + const Identity& id = i->identity; if (id == RR->identity) { _amUpstream = true; - } else if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),id.address()) == _upstreamAddresses.end()) { + } + else if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), id.address()) == _upstreamAddresses.end()) { _upstreamAddresses.push_back(id.address()); - SharedPtr &hp = _peers[id.address()]; - if (!hp) { - hp = new Peer(RR,RR->identity,id); + SharedPtr& hp = _peers[id.address()]; + if (! hp) { + hp = new Peer(RR, RR->identity, id); } } } - for(std::vector::const_iterator m(_moons.begin());m!=_moons.end();++m) { - for(std::vector::const_iterator i(m->roots().begin());i!=m->roots().end();++i) { + for (std::vector::const_iterator m(_moons.begin()); m != _moons.end(); ++m) { + for (std::vector::const_iterator i(m->roots().begin()); i != m->roots().end(); ++i) { if (i->identity == RR->identity) { _amUpstream = true; - } else if (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),i->identity.address()) == _upstreamAddresses.end()) { + } + else if (std::find(_upstreamAddresses.begin(), _upstreamAddresses.end(), i->identity.address()) == _upstreamAddresses.end()) { _upstreamAddresses.push_back(i->identity.address()); - SharedPtr &hp = _peers[i->identity.address()]; - if (!hp) { - hp = new Peer(RR,RR->identity,i->identity); + SharedPtr& hp = _peers[i->identity.address()]; + if (! hp) { + hp = new Peer(RR, RR->identity, i->identity); } } } } - std::sort(_upstreamAddresses.begin(),_upstreamAddresses.end()); + std::sort(_upstreamAddresses.begin(), _upstreamAddresses.end()); } -void Topology::_savePeer(void *tPtr,const SharedPtr &peer) +void Topology::_savePeer(void* tPtr, const SharedPtr& peer) { try { Buffer buf; @@ -428,8 +458,10 @@ void Topology::_savePeer(void *tPtr,const SharedPtr &peer) uint64_t tmpid[2]; tmpid[0] = peer->address().toInt(); tmpid[1] = 0; - RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_PEER,tmpid,buf.data(),buf.size()); - } catch ( ... ) {} // sanity check, discard invalid entries + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_PEER, tmpid, buf.data(), buf.size()); + } + catch (...) { + } // sanity check, discard invalid entries } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Topology.hpp b/node/Topology.hpp index 53c2b6d5b..746cb30ce 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -14,25 +14,23 @@ #ifndef ZT_TOPOLOGY_HPP #define ZT_TOPOLOGY_HPP +#include "../include/ZeroTierOne.h" +#include "Address.hpp" +#include "Constants.hpp" +#include "Hashtable.hpp" +#include "Identity.hpp" +#include "InetAddress.hpp" +#include "Mutex.hpp" +#include "Path.hpp" +#include "Peer.hpp" +#include "World.hpp" + +#include +#include #include #include - -#include -#include -#include #include - -#include "Constants.hpp" -#include "../include/ZeroTierOne.h" - -#include "Address.hpp" -#include "Identity.hpp" -#include "Peer.hpp" -#include "Path.hpp" -#include "Mutex.hpp" -#include "InetAddress.hpp" -#include "Hashtable.hpp" -#include "World.hpp" +#include namespace ZeroTier { @@ -41,10 +39,9 @@ class RuntimeEnvironment; /** * Database of network topology */ -class Topology -{ -public: - Topology(const RuntimeEnvironment *renv,void *tPtr); +class Topology { + public: + Topology(const RuntimeEnvironment* renv, void* tPtr); ~Topology(); /** @@ -57,7 +54,7 @@ public: * @param peer Peer to add * @return New or existing peer (should replace 'peer') */ - SharedPtr addPeer(void *tPtr,const SharedPtr &peer); + SharedPtr addPeer(void* tPtr, const SharedPtr& peer); /** * Get a peer from its address @@ -66,14 +63,14 @@ public: * @param zta ZeroTier address of peer * @return Peer or NULL if not found */ - SharedPtr getPeer(void *tPtr,const Address &zta); + SharedPtr getPeer(void* tPtr, const Address& zta); /** * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param zta ZeroTier address of peer * @return Identity or NULL identity if not found */ - Identity getIdentity(void *tPtr,const Address &zta); + Identity getIdentity(void* tPtr, const Address& zta); /** * Get a peer only if it is presently in memory (no disk cache) @@ -85,10 +82,10 @@ public: * * @param zta ZeroTier address */ - inline SharedPtr getPeerNoCache(const Address &zta) + inline SharedPtr getPeerNoCache(const Address& zta) { Mutex::Lock _l(_peers_m); - const SharedPtr *const ap = _peers.get(zta); + const SharedPtr* const ap = _peers.get(zta); if (ap) { return *ap; } @@ -102,12 +99,12 @@ public: * @param r Remote address * @return Pointer to canonicalized Path object */ - inline SharedPtr getPath(const int64_t l,const InetAddress &r) + inline SharedPtr getPath(const int64_t l, const InetAddress& r) { Mutex::Lock _l(_paths_m); - SharedPtr &p = _paths[Path::HashKey(l,r)]; - if (!p) { - p.set(new Path(l,r)); + SharedPtr& p = _paths[Path::HashKey(l, r)]; + if (! p) { + p.set(new Path(l, r)); } return p; } @@ -123,19 +120,19 @@ public: * @param id Identity to check * @return True if this is a root server or a network preferred relay from one of our networks */ - bool isUpstream(const Identity &id) const; + bool isUpstream(const Identity& id) const; /** * @param addr Address to check * @return True if we should accept a world update from this address */ - bool shouldAcceptWorldUpdateFrom(const Address &addr) const; + bool shouldAcceptWorldUpdateFrom(const Address& addr) const; /** * @param ztaddr ZeroTier address * @return Peer role for this device */ - ZT_PeerRole role(const Address &ztaddr) const; + ZT_PeerRole role(const Address& ztaddr) const; /** * Check for prohibited endpoints @@ -151,39 +148,39 @@ public: * @param ipaddr IP address * @return True if this ZT/IP pair should not be allowed to be used */ - bool isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const; + bool isProhibitedEndpoint(const Address& ztaddr, const InetAddress& ipaddr) const; /** * Gets upstreams to contact and their stable endpoints (if known) * * @param eps Hash table to fill with addresses and their stable endpoints */ - inline void getUpstreamsToContact(Hashtable< Address,std::vector > &eps) const + inline void getUpstreamsToContact(Hashtable >& eps) const { Mutex::Lock _l(_upstreams_m); - for(std::vector::const_iterator i(_planet.roots().begin());i!=_planet.roots().end();++i) { + for (std::vector::const_iterator i(_planet.roots().begin()); i != _planet.roots().end(); ++i) { if (i->identity != RR->identity) { - std::vector &ips = eps[i->identity.address()]; - for(std::vector::const_iterator j(i->stableEndpoints.begin());j!=i->stableEndpoints.end();++j) { - if (std::find(ips.begin(),ips.end(),*j) == ips.end()) { + std::vector& ips = eps[i->identity.address()]; + for (std::vector::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) { + if (std::find(ips.begin(), ips.end(), *j) == ips.end()) { ips.push_back(*j); } } } } - for(std::vector::const_iterator m(_moons.begin());m!=_moons.end();++m) { - for(std::vector::const_iterator i(m->roots().begin());i!=m->roots().end();++i) { + for (std::vector::const_iterator m(_moons.begin()); m != _moons.end(); ++m) { + for (std::vector::const_iterator i(m->roots().begin()); i != m->roots().end(); ++i) { if (i->identity != RR->identity) { - std::vector &ips = eps[i->identity.address()]; - for(std::vector::const_iterator j(i->stableEndpoints.begin());j!=i->stableEndpoints.end();++j) { - if (std::find(ips.begin(),ips.end(),*j) == ips.end()) { + std::vector& ips = eps[i->identity.address()]; + for (std::vector::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) { + if (std::find(ips.begin(), ips.end(), *j) == ips.end()) { ips.push_back(*j); } } } } } - for(std::vector< std::pair >::const_iterator m(_moonSeeds.begin());m!=_moonSeeds.end();++m) { + for (std::vector >::const_iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) { eps[m->second]; } } @@ -213,8 +210,8 @@ public: { Mutex::Lock _l(_upstreams_m); std::vector mw; - for(std::vector< std::pair >::const_iterator s(_moonSeeds.begin());s!=_moonSeeds.end();++s) { - if (std::find(mw.begin(),mw.end(),s->first) == mw.end()) { + for (std::vector >::const_iterator s(_moonSeeds.begin()); s != _moonSeeds.end(); ++s) { + if (std::find(mw.begin(), mw.end(), s->first) == mw.end()) { mw.push_back(s->first); } } @@ -235,7 +232,7 @@ public: */ inline uint64_t planetWorldId() const { - return _planet.id(); // safe to read without lock, and used from within eachPeer() so don't lock + return _planet.id(); // safe to read without lock, and used from within eachPeer() so don't lock } /** @@ -243,7 +240,7 @@ public: */ inline uint64_t planetWorldTimestamp() const { - return _planet.timestamp(); // safe to read without lock, and used from within eachPeer() so don't lock + return _planet.timestamp(); // safe to read without lock, and used from within eachPeer() so don't lock } /** @@ -254,7 +251,7 @@ public: * @param alwaysAcceptNew If true, always accept new moons even if we're not waiting for one * @return True if it was valid and newer than current (or totally new for moons) */ - bool addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew); + bool addWorld(void* tPtr, const World& newWorld, bool alwaysAcceptNew); /** * Add a moon @@ -265,7 +262,7 @@ public: * @param id Moon ID * @param seed If non-NULL, an address of any member of the moon to contact */ - void addMoon(void *tPtr,const uint64_t id,const Address &seed); + void addMoon(void* tPtr, const uint64_t id, const Address& seed); /** * Remove a moon @@ -273,12 +270,12 @@ public: * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param id Moon's world ID */ - void removeMoon(void *tPtr,const uint64_t id); + void removeMoon(void* tPtr, const uint64_t id); /** * Clean and flush database */ - void doPeriodicTasks(void *tPtr,int64_t now); + void doPeriodicTasks(void* tPtr, int64_t now); /** * @param now Current time @@ -288,11 +285,11 @@ public: { unsigned long cnt = 0; Mutex::Lock _l(_peers_m); - Hashtable< Address,SharedPtr >::Iterator i(const_cast(this)->_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; - while (i.next(a,p)) { - const SharedPtr pp((*p)->getAppropriatePath(now,false)); + Hashtable >::Iterator i(const_cast(this)->_peers); + Address* a = (Address*)0; + SharedPtr* p = (SharedPtr*)0; + while (i.next(a, p)) { + const SharedPtr pp((*p)->getAppropriatePath(now, false)); if (pp) { ++cnt; } @@ -306,22 +303,21 @@ public: * @param f Function to apply * @tparam F Function or function object type */ - template - inline void eachPeer(F f) + template inline void eachPeer(F f) { Mutex::Lock _l(_peers_m); - Hashtable< Address,SharedPtr >::Iterator i(_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; - while (i.next(a,p)) { - f(*this,*((const SharedPtr *)p)); + Hashtable >::Iterator i(_peers); + Address* a = (Address*)0; + SharedPtr* p = (SharedPtr*)0; + while (i.next(a, p)) { + f(*this, *((const SharedPtr*)p)); } } /** * @return All currently active peers by address (unsorted) */ - inline std::vector< std::pair< Address,SharedPtr > > allPeers() const + inline std::vector > > allPeers() const { Mutex::Lock _l(_peers_m); return _peers.entries(); @@ -330,7 +326,10 @@ public: /** * @return True if I am a root server in a planet or moon */ - inline bool amUpstream() const { return _amUpstream; } + inline bool amUpstream() const + { + return _amUpstream; + } /** * Get info about a path @@ -341,9 +340,9 @@ public: * @param mtu Variable set to MTU * @param trustedPathId Variable set to trusted path ID */ - inline void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId) + inline void getOutboundPathInfo(const InetAddress& physicalAddress, unsigned int& mtu, uint64_t& trustedPathId) { - for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i cpaths; - for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i cpaths; + for (unsigned int i = 0, j = _numConfiguredPhysicalPaths; i < j; ++i) { cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second; } @@ -418,19 +418,22 @@ public: if (pc.mtu <= 0) { pc.mtu = ZT_DEFAULT_PHYSMTU; - } else if (pc.mtu < ZT_MIN_PHYSMTU) { + } + else if (pc.mtu < ZT_MIN_PHYSMTU) { pc.mtu = ZT_MIN_PHYSMTU; - } else if (pc.mtu > ZT_MAX_PHYSMTU) { + } + else if (pc.mtu > ZT_MAX_PHYSMTU) { pc.mtu = ZT_MAX_PHYSMTU; } - cpaths[*(reinterpret_cast(pathNetwork))] = pc; - } else { - cpaths.erase(*(reinterpret_cast(pathNetwork))); + cpaths[*(reinterpret_cast(pathNetwork))] = pc; + } + else { + cpaths.erase(*(reinterpret_cast(pathNetwork))); } unsigned int cnt = 0; - for(std::map::const_iterator i(cpaths.begin());((i!=cpaths.end())&&(cnt::const_iterator i(cpaths.begin()); ((i != cpaths.end()) && (cnt < ZT_MAX_CONFIGURABLE_PATHS)); ++i) { _physicalPathConfig[cnt].first = i->first; _physicalPathConfig[cnt].second = i->second; ++cnt; @@ -439,30 +442,30 @@ public: } } -private: - Identity _getIdentity(void *tPtr,const Address &zta); - void _memoizeUpstreams(void *tPtr); - void _savePeer(void *tPtr,const SharedPtr &peer); + private: + Identity _getIdentity(void* tPtr, const Address& zta); + void _memoizeUpstreams(void* tPtr); + void _savePeer(void* tPtr, const SharedPtr& peer); - const RuntimeEnvironment *const RR; + const RuntimeEnvironment* const RR; - std::pair _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS]; + std::pair _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS]; volatile unsigned int _numConfiguredPhysicalPaths; - Hashtable< Address,SharedPtr > _peers; + Hashtable > _peers; Mutex _peers_m; - Hashtable< Path::HashKey,SharedPtr > _paths; + Hashtable > _paths; Mutex _paths_m; World _planet; std::vector _moons; - std::vector< std::pair > _moonSeeds; + std::vector > _moonSeeds; std::vector
_upstreamAddresses; bool _amUpstream; - Mutex _upstreams_m; // locks worlds, upstream info, moon info, etc. + Mutex _upstreams_m; // locks worlds, upstream info, moon info, etc. }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Trace.cpp b/node/Trace.cpp index b6e72e31b..982047093 100644 --- a/node/Trace.cpp +++ b/node/Trace.cpp @@ -11,374 +11,411 @@ */ /****/ -//#define ZT_TRACE - -#include -#include +// #define ZT_TRACE #include "Trace.hpp" -#include "RuntimeEnvironment.hpp" -#include "Switch.hpp" -#include "Node.hpp" -#include "Utils.hpp" -#include "Dictionary.hpp" + +#include "../include/ZeroTierDebug.h" +#include "Capability.hpp" #include "CertificateOfMembership.hpp" #include "CertificateOfOwnership.hpp" -#include "Tag.hpp" -#include "Capability.hpp" +#include "Dictionary.hpp" +#include "Node.hpp" #include "Revocation.hpp" -#include "../include/ZeroTierDebug.h" +#include "RuntimeEnvironment.hpp" +#include "Switch.hpp" +#include "Tag.hpp" +#include "Utils.hpp" + +#include +#include namespace ZeroTier { #ifdef ZT_TRACE -static void ZT_LOCAL_TRACE(void *const tPtr,const RuntimeEnvironment *const RR,const char *const fmt,...) +static void ZT_LOCAL_TRACE(void* const tPtr, const RuntimeEnvironment* const RR, const char* const fmt, ...) { char traceMsgBuf[1024]; va_list ap; - va_start(ap,fmt); - vsnprintf(traceMsgBuf,sizeof(traceMsgBuf),fmt,ap); + va_start(ap, fmt); + vsnprintf(traceMsgBuf, sizeof(traceMsgBuf), fmt, ap); va_end(ap); traceMsgBuf[sizeof(traceMsgBuf) - 1] = (char)0; - RR->node->postEvent(tPtr,ZT_EVENT_TRACE,traceMsgBuf); + RR->node->postEvent(tPtr, ZT_EVENT_TRACE, traceMsgBuf); } #else #define ZT_LOCAL_TRACE(...) #endif -void Trace::resettingPathsInScope(void *const tPtr,const Address &reporter,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,const InetAddress::IpScope scope) +void Trace::resettingPathsInScope(void* const tPtr, const Address& reporter, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, const InetAddress::IpScope scope) { char tmp[128]; - ZT_LOCAL_TRACE(tPtr,RR,"RESET and revalidate paths in scope %d; new phy address %s reported by trusted peer %.10llx",(int)scope,myPhysicalAddress.toIpString(tmp),reporter.toInt()); + ZT_LOCAL_TRACE(tPtr, RR, "RESET and revalidate paths in scope %d; new phy address %s reported by trusted peer %.10llx", (int)scope, myPhysicalAddress.toIpString(tmp), reporter.toInt()); Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,reporter); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,reporterPhysicalAddress.toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR,myPhysicalAddress.toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__IP_SCOPE,(uint64_t)scope); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, reporter); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, reporterPhysicalAddress.toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR, myPhysicalAddress.toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__IP_SCOPE, (uint64_t)scope); if (_globalTarget) { - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } - _spamToAllNetworks(tPtr,d,Trace::LEVEL_NORMAL); + _spamToAllNetworks(tPtr, d, Trace::LEVEL_NORMAL); } -void Trace::peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &path,const uint64_t packetId,const Packet::Verb verb) +void Trace::peerConfirmingUnknownPath(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& path, const uint64_t packetId, const Packet::Verb verb) { char tmp[128]; - if (!path) { - return; // sanity check + if (! path) { + return; // sanity check } - ZT_LOCAL_TRACE(tPtr,RR,"trying unknown path %s to %.10llx (packet %.16llx verb %d local socket %lld network %.16llx)",path->address().toString(tmp),peer.address().toInt(),packetId,verb,path->localSocket(),networkId); + ZT_LOCAL_TRACE(tPtr, RR, "trying unknown path %s to %.10llx (packet %.16llx verb %d local socket %lld network %.16llx)", path->address().toString(tmp), peer.address().toInt(), packetId, verb, path->localSocket(), networkId); - std::pair byn; + std::pair byn; if (networkId) { Mutex::Lock l(_byNet_m); - _byNet.get(networkId,byn); + _byNet.get(networkId, byn); } - if ((_globalTarget)||(byn.first)) { + if ((_globalTarget) || (byn.first)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb); - if (networkId) { - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,networkId); - } - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,peer.address()); - if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); - } - - if (_globalTarget) { - _send(tPtr,d,_globalTarget); - } - if (byn.first) { - _send(tPtr,d,byn.first); - } - } -} - -void Trace::bondStateMessage(void *const tPtr,char *msg) -{ - ZT_LOCAL_TRACE(tPtr,RR,"%s",msg); -} - -void Trace::peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &newPath,const uint64_t packetId) -{ - char tmp[128]; - if (!newPath) { - return; // sanity check - } - - ZT_LOCAL_TRACE(tPtr,RR,"learned new path %s to %.10llx (packet %.16llx local socket %lld network %.16llx)",newPath->address().toString(tmp),peer.address().toInt(),packetId,newPath->localSocket(),networkId); - - std::pair byn; - if (networkId) { - Mutex::Lock l(_byNet_m); - _byNet.get(networkId,byn); - } - - if ((_globalTarget)||(byn.first)) { - Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB, (uint64_t)verb); if (networkId) { d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, networkId); } - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,peer.address()); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,newPath->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,newPath->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, peer.address()); + if (path) { + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); + } if (_globalTarget) { - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } if (byn.first) { - _send(tPtr,d,byn.first); + _send(tPtr, d, byn.first); } } } -void Trace::peerRedirected(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &newPath) +void Trace::bondStateMessage(void* const tPtr, char* msg) +{ + ZT_LOCAL_TRACE(tPtr, RR, "%s", msg); +} + +void Trace::peerLearnedNewPath(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& newPath, const uint64_t packetId) { char tmp[128]; - if (!newPath) { - return; // sanity check + if (! newPath) { + return; // sanity check } - ZT_LOCAL_TRACE(tPtr,RR,"explicit redirect from %.10llx to path %s",peer.address().toInt(),newPath->address().toString(tmp)); + ZT_LOCAL_TRACE(tPtr, RR, "learned new path %s to %.10llx (packet %.16llx local socket %lld network %.16llx)", newPath->address().toString(tmp), peer.address().toInt(), packetId, newPath->localSocket(), networkId); - std::pair byn; + std::pair byn; if (networkId) { Mutex::Lock l(_byNet_m); - _byNet.get(networkId,byn); + _byNet.get(networkId, byn); } - if ((_globalTarget)||(byn.first)) { + if ((_globalTarget) || (byn.first)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); if (networkId) { - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,networkId); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, networkId); } - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,peer.address()); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,newPath->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,newPath->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, peer.address()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, newPath->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, newPath->localSocket()); if (_globalTarget) { - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } if (byn.first) { - _send(tPtr,d,byn.first); + _send(tPtr, d, byn.first); } } } -void Trace::outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr &network,const MAC &sourceMac,const MAC &destMac,const unsigned int etherType,const unsigned int vlanId,const unsigned int frameLen,const char *reason) +void Trace::peerRedirected(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& newPath) +{ + char tmp[128]; + if (! newPath) { + return; // sanity check + } + + ZT_LOCAL_TRACE(tPtr, RR, "explicit redirect from %.10llx to path %s", peer.address().toInt(), newPath->address().toString(tmp)); + + std::pair byn; + if (networkId) { + Mutex::Lock l(_byNet_m); + _byNet.get(networkId, byn); + } + + if ((_globalTarget) || (byn.first)) { + Dictionary d; + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S); + if (networkId) { + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, networkId); + } + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, peer.address()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, newPath->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, newPath->localSocket()); + + if (_globalTarget) { + _send(tPtr, d, _globalTarget); + } + if (byn.first) { + _send(tPtr, d, byn.first); + } + } +} + +void Trace::outgoingNetworkFrameDropped(void* const tPtr, const SharedPtr& network, const MAC& sourceMac, const MAC& destMac, const unsigned int etherType, const unsigned int vlanId, const unsigned int frameLen, const char* reason) { #ifdef ZT_TRACE - char tmp[128],tmp2[128]; + char tmp[128], tmp2[128]; #endif - if (!network) { - return; // sanity check + if (! network) { + return; // sanity check } - ZT_LOCAL_TRACE(tPtr,RR,"%.16llx DROP frame %s -> %s etherType %.4x size %u (%s)",network->id(),sourceMac.toString(tmp),destMac.toString(tmp2),etherType,frameLen,(reason) ? reason : "unknown reason"); + ZT_LOCAL_TRACE(tPtr, RR, "%.16llx DROP frame %s -> %s etherType %.4x size %u (%s)", network->id(), sourceMac.toString(tmp), destMac.toString(tmp2), etherType, frameLen, (reason) ? reason : "unknown reason"); - std::pair byn; - { Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); } + std::pair byn; + { + Mutex::Lock l(_byNet_m); + _byNet.get(network->id(), byn); + } - if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) { + if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network->id()); - d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC,sourceMac.toInt()); - d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC,destMac.toInt()); - d.add(ZT_REMOTE_TRACE_FIELD__ETHERTYPE,(uint64_t)etherType); - d.add(ZT_REMOTE_TRACE_FIELD__VLAN_ID,(uint64_t)vlanId); - d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH,(uint64_t)frameLen); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, network->id()); + d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC, sourceMac.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC, destMac.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__ETHERTYPE, (uint64_t)etherType); + d.add(ZT_REMOTE_TRACE_FIELD__VLAN_ID, (uint64_t)vlanId); + d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH, (uint64_t)frameLen); if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } - if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,_globalTarget); + if ((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, _globalTarget); } - if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,byn.first); + if ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, byn.first); } } } -void Trace::incomingNetworkAccessDenied(void *const tPtr,const SharedPtr &network,const SharedPtr &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,bool credentialsRequested) +void Trace::incomingNetworkAccessDenied( + void* const tPtr, + const SharedPtr& network, + const SharedPtr& path, + const uint64_t packetId, + const unsigned int packetLength, + const Address& source, + const Packet::Verb verb, + bool credentialsRequested) { char tmp[128]; - if (!network) { - return; // sanity check + if (! network) { + return; // sanity check } - ZT_LOCAL_TRACE(tPtr,RR,"%.16llx DENIED packet from %.10llx(%s) verb %d size %u%s",network->id(),source.toInt(),(path) ? (path->address().toString(tmp)) : "???",(int)verb,packetLength,credentialsRequested ? " (credentials requested)" : " (credentials not requested)"); + ZT_LOCAL_TRACE( + tPtr, + RR, + "%.16llx DENIED packet from %.10llx(%s) verb %d size %u%s", + network->id(), + source.toInt(), + (path) ? (path->address().toString(tmp)) : "???", + (int)verb, + packetLength, + credentialsRequested ? " (credentials requested)" : " (credentials not requested)"); - std::pair byn; - { Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); } + std::pair byn; + { + Mutex::Lock l(_byNet_m); + _byNet.get(network->id(), byn); + } - if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) { + if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB, (uint64_t)verb); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, source); if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); } - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network->id()); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, network->id()); - if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,_globalTarget); + if ((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, _globalTarget); } - if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,byn.first); + if ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, byn.first); } } } -void Trace::incomingNetworkFrameDropped(void *const tPtr,const SharedPtr &network,const SharedPtr &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,const MAC &sourceMac,const MAC &destMac,const char *reason) +void Trace::incomingNetworkFrameDropped( + void* const tPtr, + const SharedPtr& network, + const SharedPtr& path, + const uint64_t packetId, + const unsigned int packetLength, + const Address& source, + const Packet::Verb verb, + const MAC& sourceMac, + const MAC& destMac, + const char* reason) { char tmp[128]; - if (!network) { - return; // sanity check + if (! network) { + return; // sanity check } - ZT_LOCAL_TRACE(tPtr,RR,"%.16llx DROPPED frame from %.10llx(%s) verb %d size %u",network->id(),source.toInt(),(path) ? (path->address().toString(tmp)) : "???",(int)verb,packetLength); + ZT_LOCAL_TRACE(tPtr, RR, "%.16llx DROPPED frame from %.10llx(%s) verb %d size %u", network->id(), source.toInt(), (path) ? (path->address().toString(tmp)) : "???", (int)verb, packetLength); - std::pair byn; - { Mutex::Lock l(_byNet_m); _byNet.get(network->id(),byn); } + std::pair byn; + { + Mutex::Lock l(_byNet_m); + _byNet.get(network->id(), byn); + } - if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) ) { + if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE))) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB, (uint64_t)verb); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, source); if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); } - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network->id()); - d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC,sourceMac.toInt()); - d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC,destMac.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, network->id()); + d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC, sourceMac.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC, destMac.toInt()); if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } - if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,_globalTarget); + if ((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, _globalTarget); } - if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { - _send(tPtr,d,byn.first); + if ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_VERBOSE)) { + _send(tPtr, d, byn.first); } } } -void Trace::incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const unsigned int hops,const char *reason) +void Trace::incomingPacketMessageAuthenticationFailure(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const unsigned int hops, const char* reason) { char tmp[128]; - ZT_LOCAL_TRACE(tPtr,RR,"MAC failed for packet %.16llx from %.10llx(%s)",packetId,source.toInt(),(path) ? path->address().toString(tmp) : "???"); + ZT_LOCAL_TRACE(tPtr, RR, "MAC failed for packet %.16llx from %.10llx(%s)", packetId, source.toInt(), (path) ? path->address().toString(tmp) : "???"); - if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) { + if ((_globalTarget) && ((int)_globalLevel >= Trace::LEVEL_DEBUG)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS, (uint64_t)hops); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, source); if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); } if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } } -void Trace::incomingPacketInvalid(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const unsigned int hops,const Packet::Verb verb,const char *reason) +void Trace::incomingPacketInvalid(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const unsigned int hops, const Packet::Verb verb, const char* reason) { char tmp[128]; - ZT_LOCAL_TRACE(tPtr,RR,"INVALID packet %.16llx from %.10llx(%s) (%s)",packetId,source.toInt(),(path) ? path->address().toString(tmp) : "???",(reason) ? reason : "unknown reason"); + ZT_LOCAL_TRACE(tPtr, RR, "INVALID packet %.16llx from %.10llx(%s) (%s)", packetId, source.toInt(), (path) ? path->address().toString(tmp) : "???", (reason) ? reason : "unknown reason"); - if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) { + if ((_globalTarget) && ((int)_globalLevel >= Trace::LEVEL_DEBUG)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB,(uint64_t)verb); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_VERB, (uint64_t)verb); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, source); if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); } - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS,(uint64_t)hops); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_HOPS, (uint64_t)hops); if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } } -void Trace::incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const char *reason) +void Trace::incomingPacketDroppedHELLO(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const char* reason) { char tmp[128]; - ZT_LOCAL_TRACE(tPtr,RR,"DROPPED HELLO from %.10llx(%s) (%s)",source.toInt(),(path) ? path->address().toString(tmp) : "???",(reason) ? reason : "???"); + ZT_LOCAL_TRACE(tPtr, RR, "DROPPED HELLO from %.10llx(%s) (%s)", source.toInt(), (path) ? path->address().toString(tmp) : "???", (reason) ? reason : "???"); - if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) { + if ((_globalTarget) && ((int)_globalLevel >= Trace::LEVEL_DEBUG)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S); - d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID,packetId); - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR,source); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S); + d.add(ZT_REMOTE_TRACE_FIELD__PACKET_ID, packetId); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR, source); if (path) { - d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR,path->address().toString(tmp)); - d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET,path->localSocket()); + d.add(ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR, path->address().toString(tmp)); + d.add(ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET, path->localSocket()); } if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } } -void Trace::networkConfigRequestSent(void *const tPtr,const Network &network,const Address &controller) +void Trace::networkConfigRequestSent(void* const tPtr, const Network& network, const Address& controller) { - ZT_LOCAL_TRACE(tPtr,RR,"requesting configuration for network %.16llx",network.id()); - if ((_globalTarget)&&((int)_globalLevel >= Trace::LEVEL_DEBUG)) { + ZT_LOCAL_TRACE(tPtr, RR, "requesting configuration for network %.16llx", network.id()); + if ((_globalTarget) && ((int)_globalLevel >= Trace::LEVEL_DEBUG)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network.id()); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID,controller); - _send(tPtr,d,_globalTarget); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, network.id()); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID, controller); + _send(tPtr, d, _globalTarget); } } void Trace::networkFilter( - void *const tPtr, - const Network &network, - const RuleResultLog &primaryRuleSetLog, - const RuleResultLog *const matchingCapabilityRuleSetLog, - const Capability *const matchingCapability, - const Address &ztSource, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *const frameData, + void* const tPtr, + const Network& network, + const RuleResultLog& primaryRuleSetLog, + const RuleResultLog* const matchingCapabilityRuleSetLog, + const Capability* const matchingCapability, + const Address& ztSource, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* const frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId, @@ -386,184 +423,187 @@ void Trace::networkFilter( const bool inbound, const int accept) { - std::pair byn; - { Mutex::Lock l(_byNet_m); _byNet.get(network.id(),byn); } + std::pair byn; + { + Mutex::Lock l(_byNet_m); + _byNet.get(network.id(), byn); + } - if ( ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_RULES)) || ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_RULES)) ) { + if (((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_RULES)) || ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_RULES))) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,network.id()); - d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR,ztSource); - d.add(ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR,ztDest); - d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC,macSource.toInt()); - d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC,macDest.toInt()); - d.add(ZT_REMOTE_TRACE_FIELD__ETHERTYPE,(uint64_t)etherType); - d.add(ZT_REMOTE_TRACE_FIELD__VLAN_ID,(uint64_t)vlanId); - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE,noTee ? "1" : "0"); - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND,inbound ? "1" : "0"); - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_RESULT,(int64_t)accept); - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG,(const char *)primaryRuleSetLog.data(),(int)primaryRuleSetLog.sizeBytes()); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, network.id()); + d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR, ztSource); + d.add(ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR, ztDest); + d.add(ZT_REMOTE_TRACE_FIELD__SOURCE_MAC, macSource.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__DEST_MAC, macDest.toInt()); + d.add(ZT_REMOTE_TRACE_FIELD__ETHERTYPE, (uint64_t)etherType); + d.add(ZT_REMOTE_TRACE_FIELD__VLAN_ID, (uint64_t)vlanId); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE, noTee ? "1" : "0"); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND, inbound ? "1" : "0"); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_RESULT, (int64_t)accept); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG, (const char*)primaryRuleSetLog.data(), (int)primaryRuleSetLog.sizeBytes()); if (matchingCapabilityRuleSetLog) { - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG,(const char *)matchingCapabilityRuleSetLog->data(),(int)matchingCapabilityRuleSetLog->sizeBytes()); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG, (const char*)matchingCapabilityRuleSetLog->data(), (int)matchingCapabilityRuleSetLog->sizeBytes()); } if (matchingCapability) { - d.add(ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID,(uint64_t)matchingCapability->id()); + d.add(ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID, (uint64_t)matchingCapability->id()); } - d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH,(uint64_t)frameLen); + d.add(ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH, (uint64_t)frameLen); if (frameLen > 0) { - d.add(ZT_REMOTE_TRACE_FIELD__FRAME_DATA,(const char *)frameData,(frameLen > 256) ? (int)256 : (int)frameLen); + d.add(ZT_REMOTE_TRACE_FIELD__FRAME_DATA, (const char*)frameData, (frameLen > 256) ? (int)256 : (int)frameLen); } - if ((_globalTarget)&&((int)_globalLevel >= (int)Trace::LEVEL_RULES)) { - _send(tPtr,d,_globalTarget); + if ((_globalTarget) && ((int)_globalLevel >= (int)Trace::LEVEL_RULES)) { + _send(tPtr, d, _globalTarget); } - if ((byn.first)&&((int)byn.second >= (int)Trace::LEVEL_RULES)) { - _send(tPtr,d,byn.first); + if ((byn.first) && ((int)byn.second >= (int)Trace::LEVEL_RULES)) { + _send(tPtr, d, byn.first); } } } -void Trace::credentialRejected(void *const tPtr,const CertificateOfMembership &c,const char *reason) +void Trace::credentialRejected(void* const tPtr, const CertificateOfMembership& c, const char* reason) { - std::pair byn; + std::pair byn; if (c.networkId()) { Mutex::Lock l(_byNet_m); - _byNet.get(c.networkId(),byn); + _byNet.get(c.networkId(), byn); } - if ((_globalTarget)||(byn.first)) { + if ((_globalTarget) || (byn.first)) { Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); - } - - if (_globalTarget) { - _send(tPtr,d,_globalTarget); - } - if (byn.first) { - _send(tPtr,d,byn.first); - } - } -} - -void Trace::credentialRejected(void *const tPtr,const CertificateOfOwnership &c,const char *reason) -{ - std::pair byn; - if (c.networkId()) { - Mutex::Lock l(_byNet_m); - _byNet.get(c.networkId(),byn); - } - - if ((_globalTarget)||(byn.first)) { - Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); - } - - if (_globalTarget) { - _send(tPtr,d,_globalTarget); - } - if (byn.first) { - _send(tPtr,d,byn.first); - } - } -} - -void Trace::credentialRejected(void *const tPtr,const Capability &c,const char *reason) -{ - std::pair byn; - if (c.networkId()) { - Mutex::Lock l(_byNet_m); - _byNet.get(c.networkId(),byn); - } - - if ((_globalTarget)||(byn.first)) { - Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); - } - - if (_globalTarget) { - _send(tPtr,d,_globalTarget); - } - if (byn.first) { - _send(tPtr,d,byn.first); - } - } -} - -void Trace::credentialRejected(void *const tPtr,const Tag &c,const char *reason) -{ - std::pair byn; - if (c.networkId()) { - Mutex::Lock l(_byNet_m); - _byNet.get(c.networkId(),byn); - } - - if ((_globalTarget)||(byn.first)) { - Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP,c.timestamp()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO,c.issuedTo()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO,(uint64_t)c.value()); - if (reason) { - d.add(ZT_REMOTE_TRACE_FIELD__REASON,reason); - } - - if (_globalTarget) { - _send(tPtr,d,_globalTarget); - } - if (byn.first) { - _send(tPtr,d,byn.first); - } - } -} - -void Trace::credentialRejected(void *const tPtr,const Revocation &c,const char *reason) -{ - std::pair byn; - if (c.networkId()) { - Mutex::Lock l(_byNet_m); - _byNet.get(c.networkId(),byn); - } - - if ((_globalTarget)||(byn.first)) { - Dictionary d; - d.add(ZT_REMOTE_TRACE_FIELD__EVENT,ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); - d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID,c.networkId()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE,(uint64_t)c.credentialType()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID,(uint64_t)c.id()); - d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET,c.target()); + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, c.networkId()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE, (uint64_t)c.credentialType()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID, (uint64_t)c.id()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP, c.timestamp()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO, c.issuedTo()); if (reason) { d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); } if (_globalTarget) { - _send(tPtr,d,_globalTarget); + _send(tPtr, d, _globalTarget); } if (byn.first) { - _send(tPtr,d,byn.first); + _send(tPtr, d, byn.first); + } + } +} + +void Trace::credentialRejected(void* const tPtr, const CertificateOfOwnership& c, const char* reason) +{ + std::pair byn; + if (c.networkId()) { + Mutex::Lock l(_byNet_m); + _byNet.get(c.networkId(), byn); + } + + if ((_globalTarget) || (byn.first)) { + Dictionary d; + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, c.networkId()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE, (uint64_t)c.credentialType()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID, (uint64_t)c.id()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP, c.timestamp()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO, c.issuedTo()); + if (reason) { + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); + } + + if (_globalTarget) { + _send(tPtr, d, _globalTarget); + } + if (byn.first) { + _send(tPtr, d, byn.first); + } + } +} + +void Trace::credentialRejected(void* const tPtr, const Capability& c, const char* reason) +{ + std::pair byn; + if (c.networkId()) { + Mutex::Lock l(_byNet_m); + _byNet.get(c.networkId(), byn); + } + + if ((_globalTarget) || (byn.first)) { + Dictionary d; + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, c.networkId()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE, (uint64_t)c.credentialType()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID, (uint64_t)c.id()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP, c.timestamp()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO, c.issuedTo()); + if (reason) { + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); + } + + if (_globalTarget) { + _send(tPtr, d, _globalTarget); + } + if (byn.first) { + _send(tPtr, d, byn.first); + } + } +} + +void Trace::credentialRejected(void* const tPtr, const Tag& c, const char* reason) +{ + std::pair byn; + if (c.networkId()) { + Mutex::Lock l(_byNet_m); + _byNet.get(c.networkId(), byn); + } + + if ((_globalTarget) || (byn.first)) { + Dictionary d; + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, c.networkId()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE, (uint64_t)c.credentialType()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID, (uint64_t)c.id()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP, c.timestamp()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO, c.issuedTo()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO, (uint64_t)c.value()); + if (reason) { + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); + } + + if (_globalTarget) { + _send(tPtr, d, _globalTarget); + } + if (byn.first) { + _send(tPtr, d, byn.first); + } + } +} + +void Trace::credentialRejected(void* const tPtr, const Revocation& c, const char* reason) +{ + std::pair byn; + if (c.networkId()) { + Mutex::Lock l(_byNet_m); + _byNet.get(c.networkId(), byn); + } + + if ((_globalTarget) || (byn.first)) { + Dictionary d; + d.add(ZT_REMOTE_TRACE_FIELD__EVENT, ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S); + d.add(ZT_REMOTE_TRACE_FIELD__NETWORK_ID, c.networkId()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE, (uint64_t)c.credentialType()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID, (uint64_t)c.id()); + d.add(ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET, c.target()); + if (reason) { + d.add(ZT_REMOTE_TRACE_FIELD__REASON, reason); + } + + if (_globalTarget) { + _send(tPtr, d, _globalTarget); + } + if (byn.first) { + _send(tPtr, d, byn.first); } } } @@ -572,14 +612,14 @@ void Trace::updateMemoizedSettings() { _globalTarget = RR->node->remoteTraceTarget(); _globalLevel = RR->node->remoteTraceLevel(); - const std::vector< SharedPtr > nws(RR->node->allNetworks()); + const std::vector > nws(RR->node->allNetworks()); { Mutex::Lock l(_byNet_m); _byNet.clear(); - for(std::vector< SharedPtr >::const_iterator n(nws.begin());n!=nws.end();++n) { + for (std::vector >::const_iterator n(nws.begin()); n != nws.end(); ++n) { const Address dest((*n)->config().remoteTraceTarget); if (dest) { - std::pair &m = _byNet[(*n)->id()]; + std::pair& m = _byNet[(*n)->id()]; m.first = dest; m.second = (*n)->config().remoteTraceLevel; } @@ -587,25 +627,25 @@ void Trace::updateMemoizedSettings() } } -void Trace::_send(void *const tPtr,const Dictionary &d,const Address &dest) +void Trace::_send(void* const tPtr, const Dictionary& d, const Address& dest) { - Packet outp(dest,RR->identity.address(),Packet::VERB_REMOTE_TRACE); + Packet outp(dest, RR->identity.address(), Packet::VERB_REMOTE_TRACE); outp.appendCString(d.data()); outp.compress(); - RR->sw->send(tPtr,outp,true); + RR->sw->send(tPtr, outp, true); } -void Trace::_spamToAllNetworks(void *const tPtr,const Dictionary &d,const Level level) +void Trace::_spamToAllNetworks(void* const tPtr, const Dictionary& d, const Level level) { Mutex::Lock l(_byNet_m); - Hashtable< uint64_t,std::pair< Address,Trace::Level > >::Iterator i(_byNet); - uint64_t *k = (uint64_t *)0; - std::pair *v = (std::pair *)0; - while (i.next(k,v)) { - if ((v)&&(v->first)&&((int)v->second >= (int)level)) { - _send(tPtr,d,v->first); + Hashtable >::Iterator i(_byNet); + uint64_t* k = (uint64_t*)0; + std::pair* v = (std::pair*)0; + while (i.next(k, v)) { + if ((v) && (v->first) && ((int)v->second >= (int)level)) { + _send(tPtr, d, v->first); } } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Trace.hpp b/node/Trace.hpp index 963941d73..991974c50 100644 --- a/node/Trace.hpp +++ b/node/Trace.hpp @@ -14,21 +14,20 @@ #ifndef ZT_TRACE_HPP #define ZT_TRACE_HPP -#include -#include -#include -#include - #include "../include/ZeroTierOne.h" - #include "Constants.hpp" -#include "SharedPtr.hpp" -#include "Packet.hpp" #include "Credential.hpp" -#include "InetAddress.hpp" #include "Dictionary.hpp" -#include "Mutex.hpp" #include "Hashtable.hpp" +#include "InetAddress.hpp" +#include "Mutex.hpp" +#include "Packet.hpp" +#include "SharedPtr.hpp" + +#include +#include +#include +#include namespace ZeroTier { @@ -49,20 +48,12 @@ class Capability; /** * Remote tracing and trace logging handler */ -class Trace -{ -public: +class Trace { + public: /** * Trace verbosity level */ - enum Level - { - LEVEL_NORMAL = 0, - LEVEL_VERBOSE = 10, - LEVEL_RULES = 15, - LEVEL_DEBUG = 20, - LEVEL_INSANE = 30 - }; + enum Level { LEVEL_NORMAL = 0, LEVEL_VERBOSE = 10, LEVEL_RULES = 15, LEVEL_DEBUG = 20, LEVEL_INSANE = 30 }; /** * Filter rule evaluation result log @@ -73,67 +64,90 @@ public: * As with four-bit rules an 00 value here means this was not * evaluated or was not relevant. */ - class RuleResultLog - { - public: - RuleResultLog() {} - - inline void log(const unsigned int rn,const uint8_t thisRuleMatches,const uint8_t thisSetMatches) + class RuleResultLog { + public: + RuleResultLog() { - _l[rn >> 1] |= ( ((thisRuleMatches + 1) << 2) | (thisSetMatches + 1) ) << ((rn & 1) << 2); } - inline void logSkipped(const unsigned int rn,const uint8_t thisSetMatches) + + inline void log(const unsigned int rn, const uint8_t thisRuleMatches, const uint8_t thisSetMatches) + { + _l[rn >> 1] |= (((thisRuleMatches + 1) << 2) | (thisSetMatches + 1)) << ((rn & 1) << 2); + } + inline void logSkipped(const unsigned int rn, const uint8_t thisSetMatches) { _l[rn >> 1] |= (thisSetMatches + 1) << ((rn & 1) << 2); } inline void clear() { - memset(_l,0,sizeof(_l)); + memset(_l, 0, sizeof(_l)); } - inline const uint8_t *data() const { return _l; } - inline unsigned int sizeBytes() const { return (ZT_MAX_NETWORK_RULES / 2); } + inline const uint8_t* data() const + { + return _l; + } + inline unsigned int sizeBytes() const + { + return (ZT_MAX_NETWORK_RULES / 2); + } - private: + private: uint8_t _l[ZT_MAX_NETWORK_RULES / 2]; }; - Trace(const RuntimeEnvironment *renv) : - RR(renv), - _byNet(8) + Trace(const RuntimeEnvironment* renv) : RR(renv), _byNet(8) { } - void resettingPathsInScope(void *const tPtr,const Address &reporter,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,const InetAddress::IpScope scope); + void resettingPathsInScope(void* const tPtr, const Address& reporter, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, const InetAddress::IpScope scope); - void peerConfirmingUnknownPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &path,const uint64_t packetId,const Packet::Verb verb); + void peerConfirmingUnknownPath(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& path, const uint64_t packetId, const Packet::Verb verb); - void bondStateMessage(void *const tPtr,char *msg); + void bondStateMessage(void* const tPtr, char* msg); - void peerLearnedNewPath(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &newPath,const uint64_t packetId); - void peerRedirected(void *const tPtr,const uint64_t networkId,Peer &peer,const SharedPtr &newPath); + void peerLearnedNewPath(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& newPath, const uint64_t packetId); + void peerRedirected(void* const tPtr, const uint64_t networkId, Peer& peer, const SharedPtr& newPath); - void incomingPacketMessageAuthenticationFailure(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const unsigned int hops,const char *reason); - void incomingPacketInvalid(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const unsigned int hops,const Packet::Verb verb,const char *reason); - void incomingPacketDroppedHELLO(void *const tPtr,const SharedPtr &path,const uint64_t packetId,const Address &source,const char *reason); + void incomingPacketMessageAuthenticationFailure(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const unsigned int hops, const char* reason); + void incomingPacketInvalid(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const unsigned int hops, const Packet::Verb verb, const char* reason); + void incomingPacketDroppedHELLO(void* const tPtr, const SharedPtr& path, const uint64_t packetId, const Address& source, const char* reason); - void outgoingNetworkFrameDropped(void *const tPtr,const SharedPtr &network,const MAC &sourceMac,const MAC &destMac,const unsigned int etherType,const unsigned int vlanId,const unsigned int frameLen,const char *reason); - void incomingNetworkAccessDenied(void *const tPtr,const SharedPtr &network,const SharedPtr &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,bool credentialsRequested); - void incomingNetworkFrameDropped(void *const tPtr,const SharedPtr &network,const SharedPtr &path,const uint64_t packetId,const unsigned int packetLength,const Address &source,const Packet::Verb verb,const MAC &sourceMac,const MAC &destMac,const char *reason); + void outgoingNetworkFrameDropped(void* const tPtr, const SharedPtr& network, const MAC& sourceMac, const MAC& destMac, const unsigned int etherType, const unsigned int vlanId, const unsigned int frameLen, const char* reason); + void incomingNetworkAccessDenied( + void* const tPtr, + const SharedPtr& network, + const SharedPtr& path, + const uint64_t packetId, + const unsigned int packetLength, + const Address& source, + const Packet::Verb verb, + bool credentialsRequested); + void incomingNetworkFrameDropped( + void* const tPtr, + const SharedPtr& network, + const SharedPtr& path, + const uint64_t packetId, + const unsigned int packetLength, + const Address& source, + const Packet::Verb verb, + const MAC& sourceMac, + const MAC& destMac, + const char* reason); - void networkConfigRequestSent(void *const tPtr,const Network &network,const Address &controller); + void networkConfigRequestSent(void* const tPtr, const Network& network, const Address& controller); void networkFilter( - void *const tPtr, - const Network &network, - const RuleResultLog &primaryRuleSetLog, - const RuleResultLog *const matchingCapabilityRuleSetLog, - const Capability *const matchingCapability, - const Address &ztSource, - const Address &ztDest, - const MAC &macSource, - const MAC &macDest, - const uint8_t *const frameData, + void* const tPtr, + const Network& network, + const RuleResultLog& primaryRuleSetLog, + const RuleResultLog* const matchingCapabilityRuleSetLog, + const Capability* const matchingCapability, + const Address& ztSource, + const Address& ztDest, + const MAC& macSource, + const MAC& macDest, + const uint8_t* const frameData, const unsigned int frameLen, const unsigned int etherType, const unsigned int vlanId, @@ -141,26 +155,26 @@ public: const bool inbound, const int accept); - void credentialRejected(void *const tPtr,const CertificateOfMembership &c,const char *reason); - void credentialRejected(void *const tPtr,const CertificateOfOwnership &c,const char *reason); - void credentialRejected(void *const tPtr,const Capability &c,const char *reason); - void credentialRejected(void *const tPtr,const Tag &c,const char *reason); - void credentialRejected(void *const tPtr,const Revocation &c,const char *reason); + void credentialRejected(void* const tPtr, const CertificateOfMembership& c, const char* reason); + void credentialRejected(void* const tPtr, const CertificateOfOwnership& c, const char* reason); + void credentialRejected(void* const tPtr, const Capability& c, const char* reason); + void credentialRejected(void* const tPtr, const Tag& c, const char* reason); + void credentialRejected(void* const tPtr, const Revocation& c, const char* reason); void updateMemoizedSettings(); -private: - const RuntimeEnvironment *const RR; + private: + const RuntimeEnvironment* const RR; - void _send(void *const tPtr,const Dictionary &d,const Address &dest); - void _spamToAllNetworks(void *const tPtr,const Dictionary &d,const Level level); + void _send(void* const tPtr, const Dictionary& d, const Address& dest); + void _spamToAllNetworks(void* const tPtr, const Dictionary& d, const Level level); Address _globalTarget; Trace::Level _globalLevel; - Hashtable< uint64_t,std::pair< Address,Trace::Level > > _byNet; + Hashtable > _byNet; Mutex _byNet_m; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/Utils.cpp b/node/Utils.cpp index 4e53cb590..ad838a7fb 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -11,23 +11,23 @@ */ /****/ -#include -#include -#include -#include -#include -#include - #include "Constants.hpp" +#include +#include +#include +#include +#include +#include + #ifdef __UNIX_LIKE__ -#include +#include #include #include -#include #include +#include #include -#include +#include #ifdef ZT_ARCH_ARM_HAS_NEON #ifdef __LINUX__ #include @@ -36,13 +36,13 @@ #endif #ifdef __WINDOWS__ -#include #include +#include #endif -#include "Utils.hpp" #include "Mutex.hpp" #include "Salsa20.hpp" +#include "Utils.hpp" #ifdef __APPLE__ #include @@ -55,8 +55,8 @@ #ifdef ZT_ARCH_ARM_HAS_NEON #ifdef __LINUX__ -#include #include +#include #endif #if defined(__FreeBSD__) @@ -87,36 +87,37 @@ static inline long getauxval(int caps) #define HWCAP_SHA2 0 #endif -#endif // ZT_ARCH_ARM_HAS_NEON +#endif // ZT_ARCH_ARM_HAS_NEON namespace ZeroTier { -const uint64_t Utils::ZERO256[4] = {0ULL,0ULL,0ULL,0ULL}; +const uint64_t Utils::ZERO256[4] = { 0ULL, 0ULL, 0ULL, 0ULL }; -const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; +const char Utils::HEXCHARS[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; #ifdef ZT_ARCH_ARM_HAS_NEON Utils::ARMCapabilities::ARMCapabilities() noexcept { #ifdef __APPLE__ - this->aes = true; - this->crc32 = true; - this->pmull = true; - this->sha1 = true; - this->sha2 = true; + this->aes = true; + this->crc32 = true; + this->pmull = true; + this->sha1 = true; + this->sha2 = true; #else #ifdef HWCAP2_AES - if (sizeof(void *) == 4) { + if (sizeof(void*) == 4) { const long hwcaps2 = getauxval(AT_HWCAP2); this->aes = (hwcaps2 & HWCAP2_AES) != 0; this->crc32 = (hwcaps2 & HWCAP2_CRC32) != 0; this->pmull = (hwcaps2 & HWCAP2_PMULL) != 0; this->sha1 = (hwcaps2 & HWCAP2_SHA1) != 0; this->sha2 = (hwcaps2 & HWCAP2_SHA2) != 0; - } else { + } + else { #endif const long hwcaps = getauxval(AT_HWCAP); this->aes = (hwcaps & HWCAP_AES) != 0; @@ -128,7 +129,7 @@ Utils::ARMCapabilities::ARMCapabilities() noexcept } #endif -#endif // __APPLE__ +#endif // __APPLE__ } const Utils::ARMCapabilities Utils::ARMCAP; @@ -142,17 +143,13 @@ Utils::CPUIDRegisters::CPUIDRegisters() noexcept #ifdef __WINDOWS__ int regs[4]; - __cpuid(regs,1); + __cpuid(regs, 1); eax = (uint32_t)regs[0]; ebx = (uint32_t)regs[1]; ecx = (uint32_t)regs[2]; edx = (uint32_t)regs[3]; #else - __asm__ __volatile__ ( - "cpuid" - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) - : "a"(1), "c"(0) - ); + __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1), "c"(0)); #endif rdrand = ((ecx & (1U << 30U)) != 0); @@ -160,17 +157,13 @@ Utils::CPUIDRegisters::CPUIDRegisters() noexcept avx = ((ecx & (1U << 25U)) != 0); #ifdef __WINDOWS__ - __cpuid(regs,7); + __cpuid(regs, 7); eax = (uint32_t)regs[0]; ebx = (uint32_t)regs[1]; ecx = (uint32_t)regs[2]; edx = (uint32_t)regs[3]; #else - __asm__ __volatile__ ( - "cpuid" - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) - : "a"(7), "c"(0) - ); + __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(7), "c"(0)); #endif vaes = aes && avx && ((ecx & (1U << 9U)) != 0); @@ -185,40 +178,43 @@ const Utils::CPUIDRegisters Utils::CPUID; #endif // Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers. -static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len) +static void _Utils_doBurn(volatile uint8_t* ptr, unsigned int len) { - volatile uint8_t *const end = ptr + len; + volatile uint8_t* const end = ptr + len; while (ptr != end) { *(ptr++) = (uint8_t)0; } } -static void (*volatile _Utils_doBurn_ptr)(volatile uint8_t *,unsigned int) = _Utils_doBurn; -void Utils::burn(void *ptr,unsigned int len) { (_Utils_doBurn_ptr)((volatile uint8_t *)ptr,len); } +static void (*volatile _Utils_doBurn_ptr)(volatile uint8_t*, unsigned int) = _Utils_doBurn; +void Utils::burn(void* ptr, unsigned int len) +{ + (_Utils_doBurn_ptr)((volatile uint8_t*)ptr, len); +} -static unsigned long _Utils_itoa(unsigned long n,char *s) +static unsigned long _Utils_itoa(unsigned long n, char* s) { if (n == 0) { return 0; } - unsigned long pos = _Utils_itoa(n / 10,s); - if (pos >= 22) { // sanity check, should be impossible + unsigned long pos = _Utils_itoa(n / 10, s); + if (pos >= 22) { // sanity check, should be impossible pos = 22; } s[pos] = '0' + (char)(n % 10); return pos + 1; } -char *Utils::decimal(unsigned long n,char s[24]) +char* Utils::decimal(unsigned long n, char s[24]) { if (n == 0) { s[0] = '0'; s[1] = (char)0; return s; } - s[_Utils_itoa(n,s)] = (char)0; + s[_Utils_itoa(n, s)] = (char)0; return s; } -void Utils::getSecureRandom(void *buf,unsigned int bytes) +void Utils::getSecureRandom(void* buf, unsigned int bytes) { static Mutex globalLock; static Salsa20 s20; @@ -235,75 +231,76 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes) * a bit of extra entropy and further randomizing the result, and comes * at almost no cost and with no real downside if the random source is * good. */ - if (!s20Initialized) { + if (! s20Initialized) { s20Initialized = true; uint64_t s20Key[4]; - s20Key[0] = (uint64_t)time(0); // system clock - s20Key[1] = (uint64_t)buf; // address of buf - s20Key[2] = (uint64_t)s20Key; // address of s20Key[] - s20Key[3] = (uint64_t)&s20; // address of s20 - s20.init(s20Key,s20Key); + s20Key[0] = (uint64_t)time(0); // system clock + s20Key[1] = (uint64_t)buf; // address of buf + s20Key[2] = (uint64_t)s20Key; // address of s20Key[] + s20Key[3] = (uint64_t)&s20; // address of s20 + s20.init(s20Key, s20Key); } #ifdef __WINDOWS__ static HCRYPTPROV cryptProvider = NULL; - for(unsigned int i=0;i= sizeof(randomBuf)) { if (cryptProvider == NULL) { - if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { - fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n"); + if (! CryptAcquireContextA(&cryptProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + fprintf(stderr, "FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n"); exit(1); } } - if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomBuf),(BYTE *)randomBuf)) { - fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n"); + if (! CryptGenRandom(cryptProvider, (DWORD)sizeof(randomBuf), (BYTE*)randomBuf)) { + fprintf(stderr, "FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n"); exit(1); } randomPtr = 0; - s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf)); - s20.init(randomBuf,randomBuf); + s20.crypt12(randomBuf, randomBuf, sizeof(randomBuf)); + s20.init(randomBuf, randomBuf); } - ((uint8_t *)buf)[i] = randomBuf[randomPtr++]; + ((uint8_t*)buf)[i] = randomBuf[randomPtr++]; } -#else // not __WINDOWS__ +#else // not __WINDOWS__ static int devURandomFd = -1; if (devURandomFd < 0) { - devURandomFd = ::open("/dev/urandom",O_RDONLY); + devURandomFd = ::open("/dev/urandom", O_RDONLY); if (devURandomFd < 0) { - fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n"); + fprintf(stderr, "FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n"); exit(1); return; } } - for(unsigned int i=0;i= sizeof(randomBuf)) { - for(;;) { - if ((int)::read(devURandomFd,randomBuf,sizeof(randomBuf)) != (int)sizeof(randomBuf)) { + for (;;) { + if ((int)::read(devURandomFd, randomBuf, sizeof(randomBuf)) != (int)sizeof(randomBuf)) { ::close(devURandomFd); - devURandomFd = ::open("/dev/urandom",O_RDONLY); + devURandomFd = ::open("/dev/urandom", O_RDONLY); if (devURandomFd < 0) { - fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n"); + fprintf(stderr, "FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n"); exit(1); return; } - } else { + } + else { break; } } randomPtr = 0; - s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf)); - s20.init(randomBuf,randomBuf); + s20.crypt12(randomBuf, randomBuf, sizeof(randomBuf)); + s20.init(randomBuf, randomBuf); } - ((uint8_t *)buf)[i] = randomBuf[randomPtr++]; + ((uint8_t*)buf)[i] = randomBuf[randomPtr++]; } -#endif // __WINDOWS__ or not +#endif // __WINDOWS__ or not } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/node/Utils.hpp b/node/Utils.hpp index 41809cba0..76241ab56 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -14,17 +14,16 @@ #ifndef ZT_UTILS_HPP #define ZT_UTILS_HPP +#include +#include +#include +#include #include #include -#include #include -#include - #include -#include +#include #include -#include -#include #if defined(__FreeBSD__) #include @@ -34,15 +33,9 @@ #if __BYTE_ORDER == __LITTLE_ENDIAN #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U))) -#define ZT_CONST_TO_BE_UINT64(x) ( \ - (((uint64_t)(x) & 0x00000000000000ffULL) << 56U) | \ - (((uint64_t)(x) & 0x000000000000ff00ULL) << 40U) | \ - (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24U) | \ - (((uint64_t)(x) & 0x00000000ff000000ULL) << 8U) | \ - (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8U) | \ - (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24U) | \ - (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40U) | \ - (((uint64_t)(x) & 0xff00000000000000ULL) >> 56U)) +#define ZT_CONST_TO_BE_UINT64(x) \ + ((((uint64_t)(x) & 0x00000000000000ffULL) << 56U) | (((uint64_t)(x) & 0x000000000000ff00ULL) << 40U) | (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24U) | (((uint64_t)(x) & 0x00000000ff000000ULL) << 8U) \ + | (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8U) | (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24U) | (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40U) | (((uint64_t)(x) & 0xff00000000000000ULL) >> 56U)) #else #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x)) #define ZT_CONST_TO_BE_UINT64(x) ((uint64_t)(x)) @@ -58,14 +51,12 @@ namespace ZeroTier { /** * Miscellaneous utility functions and global constants */ -class Utils -{ -public: +class Utils { + public: static const uint64_t ZERO256[4]; #ifdef ZT_ARCH_ARM_HAS_NEON - struct ARMCapabilities - { + struct ARMCapabilities { ARMCapabilities() noexcept; bool aes; @@ -78,15 +69,14 @@ public: #endif #ifdef ZT_ARCH_X64 - struct CPUIDRegisters - { + struct CPUIDRegisters { CPUIDRegisters() noexcept; bool rdrand; bool aes; bool avx; - bool vaes; // implies AVX - bool vpclmulqdq; // implies AVX + bool vaes; // implies AVX + bool vpclmulqdq; // implies AVX bool avx2; bool avx512f; bool sha; @@ -97,7 +87,7 @@ public: /** * Compute the log2 (most significant bit set) of a 32-bit integer - * + * * @param v Integer to compute * @return log2 or 0 if v is 0 */ @@ -126,11 +116,11 @@ public: * @param len Length of strings * @return True if strings are equal */ - static inline bool secureEq(const void *a,const void *b,unsigned int len) + static inline bool secureEq(const void* a, const void* b, unsigned int len) { uint8_t diff = 0; - for(unsigned int i=0;i(a))[i] ^ (reinterpret_cast(b))[i] ); + for (unsigned int i = 0; i < len; ++i) { + diff |= ((reinterpret_cast(a))[i] ^ (reinterpret_cast(b))[i]); } return (diff == 0); } @@ -138,16 +128,16 @@ public: /** * Securely zero memory, avoiding compiler optimizations and such */ - static void burn(void *ptr,unsigned int len); + static void burn(void* ptr, unsigned int len); /** * @param n Number to convert * @param s Buffer, at least 24 bytes in size * @return String containing 'n' in base 10 form */ - static char *decimal(unsigned long n,char s[24]); + static char* decimal(unsigned long n, char s[24]); - static inline char *hex(uint64_t i,char s[17]) + static inline char* hex(uint64_t i, char s[17]) { s[0] = HEXCHARS[(i >> 60) & 0xf]; s[1] = HEXCHARS[(i >> 56) & 0xf]; @@ -169,7 +159,7 @@ public: return s; } - static inline char *hex10(uint64_t i,char s[11]) + static inline char* hex10(uint64_t i, char s[11]) { s[0] = HEXCHARS[(i >> 36) & 0xf]; s[1] = HEXCHARS[(i >> 32) & 0xf]; @@ -185,7 +175,7 @@ public: return s; } - static inline char *hex(uint32_t i,char s[9]) + static inline char* hex(uint32_t i, char s[9]) { s[0] = HEXCHARS[(i >> 28) & 0xf]; s[1] = HEXCHARS[(i >> 24) & 0xf]; @@ -199,7 +189,7 @@ public: return s; } - static inline char *hex(uint16_t i,char s[5]) + static inline char* hex(uint16_t i, char s[5]) { s[0] = HEXCHARS[(i >> 12) & 0xf]; s[1] = HEXCHARS[(i >> 8) & 0xf]; @@ -209,7 +199,7 @@ public: return s; } - static inline char *hex(uint8_t i,char s[3]) + static inline char* hex(uint8_t i, char s[3]) { s[0] = HEXCHARS[(i >> 4) & 0xf]; s[1] = HEXCHARS[i & 0xf]; @@ -217,11 +207,11 @@ public: return s; } - static inline char *hex(const void *d,unsigned int l,char *s) + static inline char* hex(const void* d, unsigned int l, char* s) { - char *const save = s; - for(unsigned int i=0;i(d)[i]; + char* const save = s; + for (unsigned int i = 0; i < l; ++i) { + const unsigned int b = reinterpret_cast(d)[i]; *(s++) = HEXCHARS[b >> 4]; *(s++) = HEXCHARS[b & 0xf]; } @@ -229,83 +219,91 @@ public: return save; } - static inline unsigned int unhex(const char *h,void *buf,unsigned int buflen) + static inline unsigned int unhex(const char* h, void* buf, unsigned int buflen) { unsigned int l = 0; while (l < buflen) { - uint8_t hc = *(reinterpret_cast(h++)); - if (!hc) { + uint8_t hc = *(reinterpret_cast(h++)); + if (! hc) { break; } uint8_t c = 0; - if ((hc >= 48)&&(hc <= 57)) { // 0..9 + if ((hc >= 48) && (hc <= 57)) { // 0..9 c = hc - 48; - } else if ((hc >= 97)&&(hc <= 102)) { // a..f + } + else if ((hc >= 97) && (hc <= 102)) { // a..f c = hc - 87; - } else if ((hc >= 65)&&(hc <= 70)) { // A..F + } + else if ((hc >= 65) && (hc <= 70)) { // A..F c = hc - 55; } - hc = *(reinterpret_cast(h++)); - if (!hc) { + hc = *(reinterpret_cast(h++)); + if (! hc) { break; } c <<= 4; - if ((hc >= 48)&&(hc <= 57)) { + if ((hc >= 48) && (hc <= 57)) { c |= hc - 48; - } else if ((hc >= 97)&&(hc <= 102)) { + } + else if ((hc >= 97) && (hc <= 102)) { c |= hc - 87; - } else if ((hc >= 65)&&(hc <= 70)) { + } + else if ((hc >= 65) && (hc <= 70)) { c |= hc - 55; } - reinterpret_cast(buf)[l++] = c; + reinterpret_cast(buf)[l++] = c; } return l; } - static inline unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen) + static inline unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buflen) { unsigned int l = 0; - const char *hend = h + hlen; + const char* hend = h + hlen; while (l < buflen) { if (h == hend) { break; } - uint8_t hc = *(reinterpret_cast(h++)); - if (!hc) { + uint8_t hc = *(reinterpret_cast(h++)); + if (! hc) { break; } uint8_t c = 0; - if ((hc >= 48)&&(hc <= 57)) { + if ((hc >= 48) && (hc <= 57)) { c = hc - 48; - } else if ((hc >= 97)&&(hc <= 102)) { + } + else if ((hc >= 97) && (hc <= 102)) { c = hc - 87; - } else if ((hc >= 65)&&(hc <= 70)) { + } + else if ((hc >= 65) && (hc <= 70)) { c = hc - 55; } if (h == hend) { break; } - hc = *(reinterpret_cast(h++)); - if (!hc) { + hc = *(reinterpret_cast(h++)); + if (! hc) { break; } c <<= 4; - if ((hc >= 48)&&(hc <= 57)) { + if ((hc >= 48) && (hc <= 57)) { c |= hc - 48; - } else if ((hc >= 97)&&(hc <= 102)) { + } + else if ((hc >= 97) && (hc <= 102)) { c |= hc - 87; - } else if ((hc >= 65)&&(hc <= 70)) { + } + else if ((hc >= 65) && (hc <= 70)) { c |= hc - 55; } - reinterpret_cast(buf)[l++] = c; + reinterpret_cast(buf)[l++] = c; } return l; } @@ -327,7 +325,7 @@ public: * @param buf Buffer to fill * @param bytes Number of random bytes to generate */ - static void getSecureRandom(void *buf,unsigned int bytes); + static void getSecureRandom(void* buf, unsigned int bytes); /** * Tokenize a string (alias for strtok_r or strtok_s depending on platform) @@ -336,54 +334,81 @@ public: * @param delim Delimiters * @param saveptr Pointer to a char * for temporary reentrant storage */ - static inline char *stok(char *str,const char *delim,char **saveptr) + static inline char* stok(char* str, const char* delim, char** saveptr) { #ifdef __WINDOWS__ - return strtok_s(str,delim,saveptr); + return strtok_s(str, delim, saveptr); #else - return strtok_r(str,delim,saveptr); + return strtok_r(str, delim, saveptr); #endif } - static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); } - static inline int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); } - static inline unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); } - static inline long strToLong(const char *s) { return strtol(s,(char **)0,10); } - static inline double strToDouble(const char *s) { return strtod(s,NULL); } - static inline unsigned long long strToU64(const char *s) + static inline unsigned int strToUInt(const char* s) + { + return (unsigned int)strtoul(s, (char**)0, 10); + } + static inline int strToInt(const char* s) + { + return (int)strtol(s, (char**)0, 10); + } + static inline unsigned long strToULong(const char* s) + { + return strtoul(s, (char**)0, 10); + } + static inline long strToLong(const char* s) + { + return strtol(s, (char**)0, 10); + } + static inline double strToDouble(const char* s) + { + return strtod(s, NULL); + } + static inline unsigned long long strToU64(const char* s) { #ifdef __WINDOWS__ - return (unsigned long long)_strtoui64(s,(char **)0,10); + return (unsigned long long)_strtoui64(s, (char**)0, 10); #else - return strtoull(s,(char **)0,10); + return strtoull(s, (char**)0, 10); #endif } - static inline long long strTo64(const char *s) + static inline long long strTo64(const char* s) { #ifdef __WINDOWS__ - return (long long)_strtoi64(s,(char **)0,10); + return (long long)_strtoi64(s, (char**)0, 10); #else - return strtoll(s,(char **)0,10); + return strtoll(s, (char**)0, 10); #endif } - static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); } - static inline int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); } - static inline unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); } - static inline long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); } - static inline unsigned long long hexStrToU64(const char *s) + static inline unsigned int hexStrToUInt(const char* s) + { + return (unsigned int)strtoul(s, (char**)0, 16); + } + static inline int hexStrToInt(const char* s) + { + return (int)strtol(s, (char**)0, 16); + } + static inline unsigned long hexStrToULong(const char* s) + { + return strtoul(s, (char**)0, 16); + } + static inline long hexStrToLong(const char* s) + { + return strtol(s, (char**)0, 16); + } + static inline unsigned long long hexStrToU64(const char* s) { #ifdef __WINDOWS__ - return (unsigned long long)_strtoui64(s,(char **)0,16); + return (unsigned long long)_strtoui64(s, (char**)0, 16); #else - return strtoull(s,(char **)0,16); + return strtoull(s, (char**)0, 16); #endif } - static inline long long hexStrTo64(const char *s) + static inline long long hexStrTo64(const char* s) { #ifdef __WINDOWS__ - return (long long)_strtoi64(s,(char **)0,16); + return (long long)_strtoi64(s, (char**)0, 16); #else - return strtoll(s,(char **)0,16); + return strtoll(s, (char**)0, 16); #endif } @@ -398,16 +423,16 @@ public: * @param src Source string (if NULL, dest will receive a zero-length string and true is returned) * @return True on success, false on overflow (buffer will still be 0-terminated) */ - static inline bool scopy(char *dest,unsigned int len,const char *src) + static inline bool scopy(char* dest, unsigned int len, const char* src) { - if (!len) { - return false; // sanity check + if (! len) { + return false; // sanity check } - if (!src) { + if (! src) { *dest = (char)0; return true; } - char *end = dest + len; + char* end = dest + len; while ((*dest++ = *src++)) { if (dest == end) { *(--dest) = (char)0; @@ -438,10 +463,10 @@ public: */ static inline uint64_t countBits(uint64_t v) { - v = v - ((v >> 1) & (uint64_t)~(uint64_t)0/3); - v = (v & (uint64_t)~(uint64_t)0/15*3) + ((v >> 2) & (uint64_t)~(uint64_t)0/15*3); - v = (v + (v >> 4)) & (uint64_t)~(uint64_t)0/255*15; - return (uint64_t)(v * ((uint64_t)~(uint64_t)0/255)) >> 56; + v = v - ((v >> 1) & (uint64_t)~(uint64_t)0 / 3); + v = (v & (uint64_t)~(uint64_t)0 / 15 * 3) + ((v >> 2) & (uint64_t)~(uint64_t)0 / 15 * 3); + v = (v + (v >> 4)) & (uint64_t)~(uint64_t)0 / 255 * 15; + return (uint64_t)(v * ((uint64_t)~(uint64_t)0 / 255)) >> 56; } /** @@ -451,10 +476,10 @@ public: * @param len Length of memory * @return True if memory is all zero */ - static inline bool isZero(const void *p,unsigned int len) + static inline bool isZero(const void* p, unsigned int len) { - for(unsigned int i=0;i> 8) | - ((n & 0x0000ff0000000000ULL) >> 24) | - ((n & 0x00ff000000000000ULL) >> 40) | - ((n & 0xff00000000000000ULL) >> 56) - ); - #endif - #endif + ((n & 0x00000000000000ffULL) << 56) | ((n & 0x000000000000ff00ULL) << 40) | ((n & 0x0000000000ff0000ULL) << 24) | ((n & 0x00000000ff000000ULL) << 8) | ((n & 0x000000ff00000000ULL) >> 8) | ((n & 0x0000ff0000000000ULL) >> 24) + | ((n & 0x00ff000000000000ULL) >> 40) | ((n & 0xff00000000000000ULL) >> 56)); +#endif +#endif } /** @@ -497,15 +515,15 @@ public: */ static ZT_INLINE uint32_t swapBytes(const uint32_t n) noexcept { - #if defined(__GNUC__) +#if defined(__GNUC__) return __builtin_bswap32(n); - #else - #ifdef _MSC_VER +#else +#ifdef _MSC_VER return (uint32_t)_byteswap_ulong((unsigned long)n); - #else +#else return htonl(n); - #endif - #endif +#endif +#endif } /** @@ -516,122 +534,119 @@ public: */ static ZT_INLINE uint16_t swapBytes(const uint16_t n) noexcept { - #if defined(__GNUC__) +#if defined(__GNUC__) return __builtin_bswap16(n); - #else - #ifdef _MSC_VER +#else +#ifdef _MSC_VER return (uint16_t)_byteswap_ushort((unsigned short)n); - #else +#else return htons(n); - #endif - #endif +#endif +#endif } // These are helper adapters to load and swap integer types special cased by size // to work with all typedef'd variants, signed/unsigned, etc. - template< typename I, unsigned int S > - class _swap_bytes_bysize; + template class _swap_bytes_bysize; - template< typename I > - class _swap_bytes_bysize< I, 1 > - { - public: + template class _swap_bytes_bysize { + public: static ZT_INLINE I s(const I n) noexcept - { return n; } + { + return n; + } }; - template< typename I > - class _swap_bytes_bysize< I, 2 > - { - public: + template class _swap_bytes_bysize { + public: static ZT_INLINE I s(const I n) noexcept - { return (I)swapBytes((uint16_t)n); } + { + return (I)swapBytes((uint16_t)n); + } }; - template< typename I > - class _swap_bytes_bysize< I, 4 > - { - public: + template class _swap_bytes_bysize { + public: static ZT_INLINE I s(const I n) noexcept - { return (I)swapBytes((uint32_t)n); } + { + return (I)swapBytes((uint32_t)n); + } }; - template< typename I > - class _swap_bytes_bysize< I, 8 > - { - public: + template class _swap_bytes_bysize { + public: static ZT_INLINE I s(const I n) noexcept - { return (I)swapBytes((uint64_t)n); } + { + return (I)swapBytes((uint64_t)n); + } }; - template< typename I, unsigned int S > - class _load_be_bysize; + template class _load_be_bysize; - template< typename I > - class _load_be_bysize< I, 1 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return p[0]; } + template class _load_be_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return p[0]; + } }; - template< typename I > - class _load_be_bysize< I, 2 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]); } + template class _load_be_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]); + } }; - template< typename I > - class _load_be_bysize< I, 4 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]); } + template class _load_be_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]); + } }; - template< typename I > - class _load_be_bysize< I, 8 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]); } + template class _load_be_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]); + } }; - template< typename I, unsigned int S > - class _load_le_bysize; + template class _load_le_bysize; - template< typename I > - class _load_le_bysize< I, 1 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return p[0]; } + template class _load_le_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return p[0]; + } }; - template< typename I > - class _load_le_bysize< I, 2 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U)); } + template class _load_le_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U)); + } }; - template< typename I > - class _load_le_bysize< I, 4 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U)); } + template class _load_le_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U)); + } }; - template< typename I > - class _load_le_bysize< I, 8 > - { - public: - static ZT_INLINE I l(const uint8_t *const p) noexcept - { return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U); } + template class _load_le_bysize { + public: + static ZT_INLINE I l(const uint8_t* const p) noexcept + { + return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U); + } }; /** @@ -641,14 +656,13 @@ public: * @param n Value to convert * @return Value in big-endian order */ - template< typename I > - static ZT_INLINE I hton(const I n) noexcept + template static ZT_INLINE I hton(const I n) noexcept { - #if __BYTE_ORDER == __LITTLE_ENDIAN - return _swap_bytes_bysize< I, sizeof(I) >::s(n); - #else +#if __BYTE_ORDER == __LITTLE_ENDIAN + return _swap_bytes_bysize::s(n); +#else return n; - #endif +#endif } /** @@ -658,14 +672,13 @@ public: * @param n Value to convert * @return Value in host byte order */ - template< typename I > - static ZT_INLINE I ntoh(const I n) noexcept + template static ZT_INLINE I ntoh(const I n) noexcept { - #if __BYTE_ORDER == __LITTLE_ENDIAN - return _swap_bytes_bysize< I, sizeof(I) >::s(n); - #else +#if __BYTE_ORDER == __LITTLE_ENDIAN + return _swap_bytes_bysize::s(n); +#else return n; - #endif +#endif } /** @@ -675,18 +688,17 @@ public: * @param p Byte stream, must be at least sizeof(I) in size * @return Loaded raw integer */ - template< typename I > - static ZT_INLINE I loadMachineEndian(const void *const p) noexcept + template static ZT_INLINE I loadMachineEndian(const void* const p) noexcept { - #ifdef ZT_NO_UNALIGNED_ACCESS +#ifdef ZT_NO_UNALIGNED_ACCESS I tmp; - for(int i=0;i<(int)sizeof(I);++i) { - reinterpret_cast(&tmp)[i] = reinterpret_cast(p)[i]; + for (int i = 0; i < (int)sizeof(I); ++i) { + reinterpret_cast(&tmp)[i] = reinterpret_cast(p)[i]; } return tmp; - #else - return *reinterpret_cast(p); - #endif +#else + return *reinterpret_cast(p); +#endif } /** @@ -696,16 +708,15 @@ public: * @param p Byte array (must be at least sizeof(I)) * @param i Integer to store */ - template< typename I > - static ZT_INLINE void storeMachineEndian(void *const p, const I i) noexcept + template static ZT_INLINE void storeMachineEndian(void* const p, const I i) noexcept { - #ifdef ZT_NO_UNALIGNED_ACCESS - for(unsigned int k=0;k(p)[k] = reinterpret_cast(&i)[k]; +#ifdef ZT_NO_UNALIGNED_ACCESS + for (unsigned int k = 0; k < sizeof(I); ++k) { + reinterpret_cast(p)[k] = reinterpret_cast(&i)[k]; } - #else - *reinterpret_cast(p) = i; - #endif +#else + *reinterpret_cast(p) = i; +#endif } /** @@ -715,14 +726,13 @@ public: * @param p Byte stream, must be at least sizeof(I) in size * @return Decoded integer */ - template< typename I > - static ZT_INLINE I loadBigEndian(const void *const p) noexcept + template static ZT_INLINE I loadBigEndian(const void* const p) noexcept { - #ifdef ZT_NO_UNALIGNED_ACCESS - return _load_be_bysize::l(reinterpret_cast(p)); - #else - return ntoh(*reinterpret_cast(p)); - #endif +#ifdef ZT_NO_UNALIGNED_ACCESS + return _load_be_bysize::l(reinterpret_cast(p)); +#else + return ntoh(*reinterpret_cast(p)); +#endif } /** @@ -732,14 +742,13 @@ public: * @param p Byte stream to write (must be at least sizeof(I)) * #param i Integer to write */ - template< typename I > - static ZT_INLINE void storeBigEndian(void *const p, I i) noexcept + template static ZT_INLINE void storeBigEndian(void* const p, I i) noexcept { - #ifdef ZT_NO_UNALIGNED_ACCESS - storeMachineEndian(p,hton(i)); - #else - *reinterpret_cast(p) = hton(i); - #endif +#ifdef ZT_NO_UNALIGNED_ACCESS + storeMachineEndian(p, hton(i)); +#else + *reinterpret_cast(p) = hton(i); +#endif } /** @@ -749,14 +758,13 @@ public: * @param p Byte stream, must be at least sizeof(I) in size * @return Decoded integer */ - template< typename I > - static ZT_INLINE I loadLittleEndian(const void *const p) noexcept + template static ZT_INLINE I loadLittleEndian(const void* const p) noexcept { - #if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS) - return _load_le_bysize::l(reinterpret_cast(p)); - #else - return *reinterpret_cast(p); - #endif +#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS) + return _load_le_bysize::l(reinterpret_cast(p)); +#else + return *reinterpret_cast(p); +#endif } /** @@ -766,18 +774,17 @@ public: * @param p Byte stream to write (must be at least sizeof(I)) * #param i Integer to write */ - template< typename I > - static ZT_INLINE void storeLittleEndian(void *const p, const I i) noexcept + template static ZT_INLINE void storeLittleEndian(void* const p, const I i) noexcept { - #if __BYTE_ORDER == __BIG_ENDIAN - storeMachineEndian(p,_swap_bytes_bysize::s(i)); - #else - #ifdef ZT_NO_UNALIGNED_ACCESS - storeMachineEndian(p,i); - #else - *reinterpret_cast(p) = i; - #endif - #endif +#if __BYTE_ORDER == __BIG_ENDIAN + storeMachineEndian(p, _swap_bytes_bysize::s(i)); +#else +#ifdef ZT_NO_UNALIGNED_ACCESS + storeMachineEndian(p, i); +#else + *reinterpret_cast(p) = i; +#endif +#endif } /** @@ -787,15 +794,14 @@ public: * @param dest Destination memory * @param src Source memory */ - template< unsigned long L > - static ZT_INLINE void copy(void *dest, const void *src) noexcept + template static ZT_INLINE void copy(void* dest, const void* src) noexcept { - #if defined(ZT_ARCH_X64) && defined(__GNUC__) +#if defined(ZT_ARCH_X64) && defined(__GNUC__) uintptr_t l = L; - __asm__ __volatile__ ("cld ; rep movsb" : "+c"(l), "+S"(src), "+D"(dest) :: "memory"); - #else + __asm__ __volatile__("cld ; rep movsb" : "+c"(l), "+S"(src), "+D"(dest)::"memory"); +#else memcpy(dest, src, L); - #endif +#endif } /** @@ -805,13 +811,13 @@ public: * @param src Source memory * @param len Bytes to copy */ - static ZT_INLINE void copy(void *dest, const void *src, unsigned long len) noexcept + static ZT_INLINE void copy(void* dest, const void* src, unsigned long len) noexcept { - #if defined(ZT_ARCH_X64) && defined(__GNUC__) - __asm__ __volatile__ ("cld ; rep movsb" : "+c"(len), "+S"(src), "+D"(dest) :: "memory"); - #else +#if defined(ZT_ARCH_X64) && defined(__GNUC__) + __asm__ __volatile__("cld ; rep movsb" : "+c"(len), "+S"(src), "+D"(dest)::"memory"); +#else memcpy(dest, src, len); - #endif +#endif } /** @@ -820,15 +826,14 @@ public: * @tparam L Size in bytes * @param dest Memory to zero */ - template< unsigned long L > - static ZT_INLINE void zero(void *dest) noexcept + template static ZT_INLINE void zero(void* dest) noexcept { - #if defined(ZT_ARCH_X64) && defined(__GNUC__) +#if defined(ZT_ARCH_X64) && defined(__GNUC__) uintptr_t l = L; - __asm__ __volatile__ ("cld ; rep stosb" :"+c" (l), "+D" (dest) : "a" (0) : "memory"); - #else + __asm__ __volatile__("cld ; rep stosb" : "+c"(l), "+D"(dest) : "a"(0) : "memory"); +#else memset(dest, 0, L); - #endif +#endif } /** @@ -837,13 +842,13 @@ public: * @param dest Memory to zero * @param len Size in bytes */ - static ZT_INLINE void zero(void *dest, unsigned long len) noexcept + static ZT_INLINE void zero(void* dest, unsigned long len) noexcept { - #if defined(ZT_ARCH_X64) && defined(__GNUC__) - __asm__ __volatile__ ("cld ; rep stosb" :"+c" (len), "+D" (dest) : "a" (0) : "memory"); - #else +#if defined(ZT_ARCH_X64) && defined(__GNUC__) + __asm__ __volatile__("cld ; rep stosb" : "+c"(len), "+D"(dest) : "a"(0) : "memory"); +#else memset(dest, 0, len); - #endif +#endif } /** @@ -855,7 +860,7 @@ public: * Remove `-` and `:` from a MAC address (in-place). * * @param mac The MAC address - */ + */ static inline void cleanMac(std::string& mac) { auto start = mac.begin(); @@ -865,6 +870,6 @@ public: } }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/node/World.hpp b/node/World.hpp index 1c27b85e6..b730543ad 100644 --- a/node/World.hpp +++ b/node/World.hpp @@ -14,14 +14,14 @@ #ifndef ZT_WORLD_HPP #define ZT_WORLD_HPP -#include -#include - -#include "Constants.hpp" -#include "InetAddress.hpp" -#include "Identity.hpp" #include "Buffer.hpp" #include "C25519.hpp" +#include "Constants.hpp" +#include "Identity.hpp" +#include "InetAddress.hpp" + +#include +#include /** * Maximum number of roots (sanity limit, okay to increase) @@ -76,69 +76,92 @@ namespace ZeroTier { * world ID for Mars and nearby space is defined but not yet used, and a test * world ID is provided for testing purposes. */ -class World -{ -public: +class World { + public: /** * World type -- do not change IDs */ - enum Type - { + enum Type { TYPE_NULL = 0, - TYPE_PLANET = 1, // Planets, of which there is currently one (Earth) - TYPE_MOON = 127 // Moons, which are user-created and many + TYPE_PLANET = 1, // Planets, of which there is currently one (Earth) + TYPE_MOON = 127 // Moons, which are user-created and many }; /** * Upstream server definition in world/moon */ - struct Root - { + struct Root { Identity identity; std::vector stableEndpoints; - inline bool operator==(const Root &r) const { return ((identity == r.identity)&&(stableEndpoints == r.stableEndpoints)); } - inline bool operator!=(const Root &r) const { return (!(*this == r)); } - inline bool operator<(const Root &r) const { return (identity < r.identity); } // for sorting + inline bool operator==(const Root& r) const + { + return ((identity == r.identity) && (stableEndpoints == r.stableEndpoints)); + } + inline bool operator!=(const Root& r) const + { + return (! (*this == r)); + } + inline bool operator<(const Root& r) const + { + return (identity < r.identity); + } // for sorting }; /** * Construct an empty / null World */ - World() : - _id(0), - _ts(0), - _type(TYPE_NULL) {} + World() : _id(0), _ts(0), _type(TYPE_NULL) + { + } /** * @return Root servers for this world and their stable endpoints */ - inline const std::vector &roots() const { return _roots; } + inline const std::vector& roots() const + { + return _roots; + } /** * @return World type: planet or moon */ - inline Type type() const { return _type; } + inline Type type() const + { + return _type; + } /** * @return World unique identifier */ - inline uint64_t id() const { return _id; } + inline uint64_t id() const + { + return _id; + } /** * @return World definition timestamp */ - inline uint64_t timestamp() const { return _ts; } + inline uint64_t timestamp() const + { + return _ts; + } /** * @return C25519 signature */ - inline const C25519::Signature &signature() const { return _signature; } + inline const C25519::Signature& signature() const + { + return _signature; + } /** * @return Public key that must sign next update */ - inline const C25519::Public &updatesMustBeSignedBy() const { return _updatesMustBeSignedBy; } + inline const C25519::Public& updatesMustBeSignedBy() const + { + return _updatesMustBeSignedBy; + } /** * Check whether a world update should replace this one @@ -146,15 +169,15 @@ public: * @param update Candidate update * @return True if update is newer than current, matches its ID and type, and is properly signed (or if current is NULL) */ - inline bool shouldBeReplacedBy(const World &update) + inline bool shouldBeReplacedBy(const World& update) { - if ((_id == 0)||(_type == TYPE_NULL)) { + if ((_id == 0) || (_type == TYPE_NULL)) { return true; } - if ((_id == update._id)&&(_ts < update._ts)&&(_type == update._type)) { + if ((_id == update._id) && (_ts < update._ts) && (_type == update._type)) { Buffer tmp; - update.serialize(tmp,true); - return C25519::verify(_updatesMustBeSignedBy,tmp.data(),tmp.size(),update._signature); + update.serialize(tmp, true); + return C25519::verify(_updatesMustBeSignedBy, tmp.data(), tmp.size(), update._signature); } return false; } @@ -162,10 +185,12 @@ public: /** * @return True if this World is non-empty */ - inline operator bool() const { return (_type != TYPE_NULL); } + inline operator bool() const + { + return (_type != TYPE_NULL); + } - template - inline void serialize(Buffer &b,bool forSign = false) const + template inline void serialize(Buffer& b, bool forSign = false) const { if (forSign) { b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); @@ -174,20 +199,20 @@ public: b.append((uint8_t)_type); b.append((uint64_t)_id); b.append((uint64_t)_ts); - b.append(_updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN); - if (!forSign) { - b.append(_signature.data,ZT_C25519_SIGNATURE_LEN); + b.append(_updatesMustBeSignedBy.data, ZT_C25519_PUBLIC_KEY_LEN); + if (! forSign) { + b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); } b.append((uint8_t)_roots.size()); - for(std::vector::const_iterator r(_roots.begin());r!=_roots.end();++r) { + for (std::vector::const_iterator r(_roots.begin()); r != _roots.end(); ++r) { r->identity.serialize(b); b.append((uint8_t)r->stableEndpoints.size()); - for(std::vector::const_iterator ep(r->stableEndpoints.begin());ep!=r->stableEndpoints.end();++ep) { + for (std::vector::const_iterator ep(r->stableEndpoints.begin()); ep != r->stableEndpoints.end(); ++ep) { ep->serialize(b); } } if (_type == TYPE_MOON) { - b.append((uint16_t)0); // no attached dictionary (for future use) + b.append((uint16_t)0); // no attached dictionary (for future use) } if (forSign) { @@ -195,15 +220,14 @@ public: } } - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { unsigned int p = startAt; _roots.clear(); - switch((Type)b[p++]) { - case TYPE_NULL: // shouldn't ever really happen in serialized data but it's not invalid + switch ((Type)b[p++]) { + case TYPE_NULL: // shouldn't ever really happen in serialized data but it's not invalid _type = TYPE_NULL; break; case TYPE_PLANET: @@ -220,25 +244,25 @@ public: p += 8; _ts = b.template at(p); p += 8; - memcpy(_updatesMustBeSignedBy.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(_updatesMustBeSignedBy.data, b.field(p, ZT_C25519_PUBLIC_KEY_LEN), ZT_C25519_PUBLIC_KEY_LEN); p += ZT_C25519_PUBLIC_KEY_LEN; - memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); + memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; const unsigned int numRoots = (unsigned int)b[p++]; if (numRoots > ZT_WORLD_MAX_ROOTS) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } - for(unsigned int k=0;k ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; } - for(unsigned int kk=0;kk &roots,const C25519::Pair &signWith) + static inline World make(World::Type t, uint64_t id, uint64_t ts, const C25519::Public& sk, const std::vector& roots, const C25519::Pair& signWith) { World w; w._id = id; @@ -272,13 +304,13 @@ public: w._roots = roots; Buffer tmp; - w.serialize(tmp,true); - w._signature = C25519::sign(signWith,tmp.data(),tmp.size()); + w.serialize(tmp, true); + w._signature = C25519::sign(signWith, tmp.data(), tmp.size()); return w; } -protected: + protected: uint64_t _id; uint64_t _ts; Type _type; @@ -287,6 +319,6 @@ protected: std::vector _roots; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/Arp.cpp b/osdep/Arp.cpp index 036d7df6d..8b307eb58 100644 --- a/osdep/Arp.cpp +++ b/osdep/Arp.cpp @@ -11,29 +11,28 @@ */ /****/ -#include -#include -#include - #include "Arp.hpp" + #include "OSUtils.hpp" +#include +#include +#include + namespace ZeroTier { -static const uint8_t ARP_REQUEST_HEADER[8] = { 0x00,0x01,0x08,0x00,0x06,0x04,0x00,0x01 }; -static const uint8_t ARP_RESPONSE_HEADER[8] = { 0x00,0x01,0x08,0x00,0x06,0x04,0x00,0x02 }; +static const uint8_t ARP_REQUEST_HEADER[8] = { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01 }; +static const uint8_t ARP_RESPONSE_HEADER[8] = { 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02 }; -Arp::Arp() : - _cache(256), - _lastCleaned(OSUtils::now()) +Arp::Arp() : _cache(256), _lastCleaned(OSUtils::now()) { } -void Arp::addLocal(uint32_t ip,const MAC &mac) +void Arp::addLocal(uint32_t ip, const MAC& mac) { - _ArpEntry &e = _cache[ip]; - e.lastQuerySent = 0; // local IP - e.lastResponseReceived = 0; // local IP + _ArpEntry& e = _cache[ip]; + e.lastQuerySent = 0; // local IP + e.lastResponseReceived = 0; // local IP e.mac = mac; e.local = true; } @@ -43,7 +42,7 @@ void Arp::remove(uint32_t ip) _cache.erase(ip); } -uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response,unsigned int &responseLen,MAC &responseDest) +uint32_t Arp::processIncomingArp(const void* arp, unsigned int len, void* response, unsigned int& responseLen, MAC& responseDest) { const uint64_t now = OSUtils::now(); uint32_t ip = 0; @@ -52,25 +51,26 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response responseDest.zero(); if (len >= 28) { - if (!memcmp(arp,ARP_REQUEST_HEADER,8)) { + if (! memcmp(arp, ARP_REQUEST_HEADER, 8)) { // Respond to ARP requests for locally-known IPs - _ArpEntry *targetEntry = _cache.get(reinterpret_cast(arp)[6]); - if ((targetEntry)&&(targetEntry->local)) { - memcpy(response,ARP_RESPONSE_HEADER,8); - targetEntry->mac.copyTo(reinterpret_cast(response) + 8,6); - memcpy(reinterpret_cast(response) + 14,reinterpret_cast(arp) + 24,4); - memcpy(reinterpret_cast(response) + 18,reinterpret_cast(arp) + 8,10); + _ArpEntry* targetEntry = _cache.get(reinterpret_cast(arp)[6]); + if ((targetEntry) && (targetEntry->local)) { + memcpy(response, ARP_RESPONSE_HEADER, 8); + targetEntry->mac.copyTo(reinterpret_cast(response) + 8, 6); + memcpy(reinterpret_cast(response) + 14, reinterpret_cast(arp) + 24, 4); + memcpy(reinterpret_cast(response) + 18, reinterpret_cast(arp) + 8, 10); responseLen = 28; - responseDest.setTo(reinterpret_cast(arp) + 8,6); + responseDest.setTo(reinterpret_cast(arp) + 8, 6); } - } else if (!memcmp(arp,ARP_RESPONSE_HEADER,8)) { + } + else if (! memcmp(arp, ARP_RESPONSE_HEADER, 8)) { // Learn cache entries for remote IPs from relevant ARP replies uint32_t responseIp = 0; - memcpy(&responseIp,reinterpret_cast(arp) + 14,4); - _ArpEntry *queryEntry = _cache.get(responseIp); - if ((queryEntry)&&(!queryEntry->local)&&((now - queryEntry->lastQuerySent) <= ZT_ARP_QUERY_MAX_TTL)) { + memcpy(&responseIp, reinterpret_cast(arp) + 14, 4); + _ArpEntry* queryEntry = _cache.get(responseIp); + if ((queryEntry) && (! queryEntry->local) && ((now - queryEntry->lastQuerySent) <= ZT_ARP_QUERY_MAX_TTL)) { queryEntry->lastResponseReceived = now; - queryEntry->mac.setTo(reinterpret_cast(arp) + 8,6); + queryEntry->mac.setTo(reinterpret_cast(arp) + 8, 6); ip = responseIp; } } @@ -78,11 +78,11 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response if ((now - _lastCleaned) >= ZT_ARP_EXPIRE) { _lastCleaned = now; - Hashtable< uint32_t,_ArpEntry >::Iterator i(_cache); - uint32_t *k = (uint32_t *)0; - _ArpEntry *v = (_ArpEntry *)0; - while (i.next(k,v)) { - if ((!v->local)&&((now - v->lastResponseReceived) >= ZT_ARP_EXPIRE)) + Hashtable::Iterator i(_cache); + uint32_t* k = (uint32_t*)0; + _ArpEntry* v = (_ArpEntry*)0; + while (i.next(k, v)) { + if ((! v->local) && ((now - v->lastResponseReceived) >= ZT_ARP_EXPIRE)) _cache.erase(*k); } } @@ -90,27 +90,32 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response return ip; } -MAC Arp::query(const MAC &localMac,uint32_t localIp,uint32_t targetIp,void *query,unsigned int &queryLen,MAC &queryDest) +MAC Arp::query(const MAC& localMac, uint32_t localIp, uint32_t targetIp, void* query, unsigned int& queryLen, MAC& queryDest) { const uint64_t now = OSUtils::now(); - _ArpEntry &e = _cache[targetIp]; + _ArpEntry& e = _cache[targetIp]; - if ( ((e.mac)&&((now - e.lastResponseReceived) >= (ZT_ARP_EXPIRE / 3))) || - ((!e.mac)&&((now - e.lastQuerySent) >= ZT_ARP_QUERY_INTERVAL)) ) { + if (((e.mac) && ((now - e.lastResponseReceived) >= (ZT_ARP_EXPIRE / 3))) || ((! e.mac) && ((now - e.lastQuerySent) >= ZT_ARP_QUERY_INTERVAL))) { e.lastQuerySent = now; - uint8_t *q = reinterpret_cast(query); - memcpy(q,ARP_REQUEST_HEADER,8); q += 8; // ARP request header information, always the same - localMac.copyTo(q,6); q += 6; // sending host MAC address - memcpy(q,&localIp,4); q += 4; // sending host IP (IP already in big-endian byte order) - memset(q,0,6); q += 6; // sending zeros for target MAC address as thats what we want to find - memcpy(q,&targetIp,4); // target IP address for resolution (IP already in big-endian byte order) + uint8_t* q = reinterpret_cast(query); + memcpy(q, ARP_REQUEST_HEADER, 8); + q += 8; // ARP request header information, always the same + localMac.copyTo(q, 6); + q += 6; // sending host MAC address + memcpy(q, &localIp, 4); + q += 4; // sending host IP (IP already in big-endian byte order) + memset(q, 0, 6); + q += 6; // sending zeros for target MAC address as thats what we want to find + memcpy(q, &targetIp, 4); // target IP address for resolution (IP already in big-endian byte order) queryLen = 28; if (e.mac) - queryDest = e.mac; // confirmation query, send directly to address holder - else queryDest = (uint64_t)0xffffffffffffULL; // broadcast query - } else { + queryDest = e.mac; // confirmation query, send directly to address holder + else + queryDest = (uint64_t)0xffffffffffffULL; // broadcast query + } + else { queryLen = 0; queryDest.zero(); } @@ -118,4 +123,4 @@ MAC Arp::query(const MAC &localMac,uint32_t localIp,uint32_t targetIp,void *quer return e.mac; } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/Arp.hpp b/osdep/Arp.hpp index 9453997f6..51257ef5e 100644 --- a/osdep/Arp.hpp +++ b/osdep/Arp.hpp @@ -14,14 +14,13 @@ #ifndef ZT_ARP_HPP #define ZT_ARP_HPP -#include - -#include - #include "../node/Constants.hpp" #include "../node/Hashtable.hpp" #include "../node/MAC.hpp" +#include +#include + /** * Maximum possible ARP length * @@ -67,9 +66,8 @@ namespace ZeroTier { * This class is not thread-safe and must be guarded if used in multi-threaded * code. */ -class Arp -{ -public: +class Arp { + public: Arp(); /** @@ -78,7 +76,7 @@ public: * @param mac Our local MAC address * @param ip IP in big-endian byte order (sin_addr.s_addr) */ - void addLocal(uint32_t ip,const MAC &mac); + void addLocal(uint32_t ip, const MAC& mac); /** * Delete a local IP entry or a cached ARP entry @@ -103,7 +101,7 @@ public: * @param responseDest Destination of response, or set to null if no response * @return IP address learned or 0 if no new IPs in cache */ - uint32_t processIncomingArp(const void *arp,unsigned int len,void *response,unsigned int &responseLen,MAC &responseDest); + uint32_t processIncomingArp(const void* arp, unsigned int len, void* response, unsigned int& responseLen, MAC& responseDest); /** * Get the MAC corresponding to an IP, generating a query if needed @@ -115,29 +113,30 @@ public: * MAC returned is non-null. * * @param localMac Local MAC address of host interface - * @param localIp Local IP address of host interface + * @param localIp Local IP address of host interface * @param targetIp IP to look up * @param query Buffer for generated query -- MUST be a minimum of ZT_ARP_BUF_LENGTH in size * @param queryLen Length of generated query, or set to 0 if no query generated * @param queryDest Destination of query, or set to null if no query generated * @return MAC or 0 if no cached entry for this IP */ - MAC query(const MAC &localMac,uint32_t localIp,uint32_t targetIp,void *query,unsigned int &queryLen,MAC &queryDest); + MAC query(const MAC& localMac, uint32_t localIp, uint32_t targetIp, void* query, unsigned int& queryLen, MAC& queryDest); -private: - struct _ArpEntry - { - _ArpEntry() : lastQuerySent(0),lastResponseReceived(0),mac(),local(false) {} - uint64_t lastQuerySent; // Time last query was sent or 0 for local IP - uint64_t lastResponseReceived; // Time of last ARP response or 0 for local IP - MAC mac; // MAC address of device responsible for IP or null if not known yet - bool local; // True if this is a local ARP entry + private: + struct _ArpEntry { + _ArpEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false) + { + } + uint64_t lastQuerySent; // Time last query was sent or 0 for local IP + uint64_t lastResponseReceived; // Time of last ARP response or 0 for local IP + MAC mac; // MAC address of device responsible for IP or null if not known yet + bool local; // True if this is a local ARP entry }; - Hashtable< uint32_t,_ArpEntry > _cache; + Hashtable _cache; uint64_t _lastCleaned; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/BSDEthernetTap.cpp b/osdep/BSDEthernetTap.cpp index b2ea98b3e..e1e0d42e5 100644 --- a/osdep/BSDEthernetTap.cpp +++ b/osdep/BSDEthernetTap.cpp @@ -11,81 +11,78 @@ */ /****/ -#include -#include -#include -#include -#include +#include "BSDEthernetTap.hpp" -#include -#include +#include "../node/Constants.hpp" +#include "../node/Mutex.hpp" +#include "../node/Utils.hpp" +#include "OSUtils.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include #include +#include +#include #include #include #include #include +#include #include - #include -#include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include "../node/Constants.hpp" -#include "../node/Utils.hpp" -#include "../node/Mutex.hpp" -#include "OSUtils.hpp" -#include "BSDEthernetTap.hpp" - #define ZT_BASE32_CHARS "0123456789abcdefghijklmnopqrstuv" #define ZT_TAP_BUF_SIZE (1024 * 16) // ff:ff:ff:ff:ff:ff with no ADI -static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0); namespace ZeroTier { BSDEthernetTap::BSDEthernetTap( - const char *homePath, + const char* homePath, unsigned int concurrency, bool pinning, - const MAC &mac, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg) : - _handler(handler), - _concurrency(concurrency), - _pinning(pinning), - _arg(arg), - _nwid(nwid), - _mtu(mtu), - _metric(metric), - _fd(0), - _enabled(true), - _lastIfAddrsUpdate(0) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg) + : _handler(handler) + , _concurrency(concurrency) + , _pinning(pinning) + , _arg(arg) + , _nwid(nwid) + , _mtu(mtu) + , _metric(metric) + , _fd(0) + , _enabled(true) + , _lastIfAddrsUpdate(0) { static Mutex globalTapCreateLock; - char devpath[64],ethaddr[64],mtustr[32],metstr[32],tmpdevname[32]; + char devpath[64], ethaddr[64], mtustr[32], metstr[32], tmpdevname[32]; Mutex::Lock _gl(globalTapCreateLock); @@ -108,43 +105,51 @@ BSDEthernetTap::BSDEthernetTap( _dev.push_back(ZT_BASE32_CHARS[(unsigned long)(nwid & 0x1f)]); std::vector devFiles(OSUtils::listDirectory("/dev")); - for(int i=9993;i<(9993+128);++i) { - OSUtils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); - OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); - if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { + for (int i = 9993; i < (9993 + 128); ++i) { + OSUtils::ztsnprintf(tmpdevname, sizeof(tmpdevname), "tap%d", i); + OSUtils::ztsnprintf(devpath, sizeof(devpath), "/dev/%s", tmpdevname); + if (std::find(devFiles.begin(), devFiles.end(), std::string(tmpdevname)) == devFiles.end()) { long cpid = (long)vfork(); if (cpid == 0) { #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s create" ZT_EOL_S, tmpdevname); #endif - ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"create",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", tmpdevname, "create", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); - } else throw std::runtime_error("fork() failed"); + ::waitpid(cpid, &exitcode, 0); + } + else + throw std::runtime_error("fork() failed"); struct stat stattmp; - if (!stat(devpath,&stattmp)) { + if (! stat(devpath, &stattmp)) { cpid = (long)vfork(); if (cpid == 0) { #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s name %s" ZT_EOL_S, tmpdevname, _dev.c_str()); #endif - ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"name",_dev.c_str(),(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", tmpdevname, "name", _dev.c_str(), (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); if (exitcode) throw std::runtime_error("ifconfig rename operation failed"); - } else throw std::runtime_error("fork() failed"); + } + else + throw std::runtime_error("fork() failed"); - _fd = ::open(devpath,O_RDWR); + _fd = ::open(devpath, O_RDWR); if (_fd > 0) break; - else throw std::runtime_error("unable to open created tap device"); - } else { + else + throw std::runtime_error("unable to open created tap device"); + } + else { throw std::runtime_error("cannot find /dev node for newly created tap device"); } } @@ -152,10 +157,10 @@ BSDEthernetTap::BSDEthernetTap( #else /* Other BSDs like OpenBSD only have a limited number of tap devices that cannot be renamed */ - for(int i=0;i<64;++i) { - OSUtils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); - OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); - _fd = ::open(devpath,O_RDWR); + for (int i = 0; i < 64; ++i) { + OSUtils::ztsnprintf(tmpdevname, sizeof(tmpdevname), "tap%d", i); + OSUtils::ztsnprintf(devpath, sizeof(devpath), "/dev/%s", tmpdevname); + _fd = ::open(devpath, O_RDWR); if (_fd > 0) { _dev = tmpdevname; break; @@ -166,25 +171,26 @@ BSDEthernetTap::BSDEthernetTap( if (_fd <= 0) throw std::runtime_error("unable to open TAP device or no more devices available"); - if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) { + if (fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL) & ~O_NONBLOCK) == -1) { ::close(_fd); throw std::runtime_error("unable to set flags on file descriptor for TAP device"); } // Configure MAC address and MTU, bring interface up - OSUtils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); - OSUtils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu); - OSUtils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric); + OSUtils::ztsnprintf(ethaddr, sizeof(ethaddr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3], (int)mac[4], (int)mac[5]); + OSUtils::ztsnprintf(mtustr, sizeof(mtustr), "%u", _mtu); + OSUtils::ztsnprintf(metstr, sizeof(metstr), "%u", _metric); long cpid = (long)vfork(); if (cpid == 0) { #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s lladdr %s mtu %s metric %s up" ZT_EOL_S, _dev.c_str(), ethaddr, mtustr, metstr); #endif - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "lladdr", ethaddr, "mtu", mtustr, "metric", metstr, "up", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); if (exitcode) { ::close(_fd); throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface"); @@ -192,7 +198,7 @@ BSDEthernetTap::BSDEthernetTap( } // Set close-on-exec so that devices cannot persist if we fork/exec for update - fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); + fcntl(_fd, F_SETFD, fcntl(_fd, F_GETFD) | FD_CLOEXEC); ::pipe(_shutdownSignalPipe); @@ -201,23 +207,24 @@ BSDEthernetTap::BSDEthernetTap( BSDEthernetTap::~BSDEthernetTap() { - ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit + ::write(_shutdownSignalPipe[1], "\0", 1); // causes thread to exit ::close(_fd); ::close(_shutdownSignalPipe[0]); ::close(_shutdownSignalPipe[1]); long cpid = (long)vfork(); if (cpid == 0) { #ifdef ZT_TRACE - fprintf(stderr, "DEBUG: ifconfig %s destroy" ZT_EOL_S, _dev.c_str()); + fprintf(stderr, "DEBUG: ifconfig %s destroy" ZT_EOL_S, _dev.c_str()); #endif - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"destroy",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "destroy", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); } Thread::join(_thread); - for (std::thread &t : _rxThreads) { + for (std::thread& t : _rxThreads) { t.join(); } } @@ -232,7 +239,7 @@ bool BSDEthernetTap::enabled() const return _enabled; } -static bool ___removeIp(const std::string &_dev,const InetAddress &ip) +static bool ___removeIp(const std::string& _dev, const InetAddress& ip) { long cpid = (long)vfork(); if (cpid == 0) { @@ -240,29 +247,30 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip) #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s inet %s -alias" ZT_EOL_S, _dev.c_str(), ip.toIpString(ipbuf)); #endif - execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString(ipbuf),"-alias",(const char *)0); + execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "inet", ip.toIpString(ipbuf), "-alias", (const char*)0); _exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - waitpid(cpid,&exitcode,0); + waitpid(cpid, &exitcode, 0); return (exitcode == 0); } - return false; // never reached, make compiler shut up about return value + return false; // never reached, make compiler shut up about return value } -bool BSDEthernetTap::addIp(const InetAddress &ip) +bool BSDEthernetTap::addIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; std::vector allIps(ips()); - if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) - return true; // IP/netmask already assigned + if (std::find(allIps.begin(), allIps.end(), ip) != allIps.end()) + return true; // IP/netmask already assigned // Remove and reconfigure if address is the same but netmask is different - for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { - if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) { - if (___removeIp(_dev,*i)) + for (std::vector::iterator i(allIps.begin()); i != allIps.end(); ++i) { + if ((i->ipsEqual(ip)) && (i->netmaskBits() != ip.netmaskBits())) { + if (___removeIp(_dev, *i)) break; } } @@ -273,23 +281,24 @@ bool BSDEthernetTap::addIp(const InetAddress &ip) #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s %s %s alias" ZT_EOL_S, _dev.c_str(), ip.isV4() ? "inet" : "inet6", ip.toString(tmp)); #endif - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString(tmp),"alias",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), ip.isV4() ? "inet" : "inet6", ip.toString(tmp), "alias", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); return (exitcode == 0); } return false; } -bool BSDEthernetTap::removeIp(const InetAddress &ip) +bool BSDEthernetTap::removeIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; std::vector allIps(ips()); - if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) { - if (___removeIp(_dev,ip)) + if (std::find(allIps.begin(), allIps.end(), ip) != allIps.end()) { + if (___removeIp(_dev, ip)) return true; } return false; @@ -304,28 +313,28 @@ std::vector BSDEthernetTap::ips() const } _lastIfAddrsUpdate = now; - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; if (getifaddrs(&ifa)) return std::vector(); std::vector r; - struct ifaddrs *p = ifa; + struct ifaddrs* p = ifa; while (p) { - if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { - switch(p->ifa_addr->sa_family) { + if ((! strcmp(p->ifa_name, _dev.c_str())) && (p->ifa_addr) && (p->ifa_netmask) && (p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { + switch (p->ifa_addr->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; - struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; - r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); - } break; + struct sockaddr_in* sin = (struct sockaddr_in*)p->ifa_addr; + struct sockaddr_in* nm = (struct sockaddr_in*)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr), 4, Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; case AF_INET6: { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; - struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + struct sockaddr_in6* sin = (struct sockaddr_in6*)p->ifa_addr; + struct sockaddr_in6* nm = (struct sockaddr_in6*)p->ifa_netmask; uint32_t b[4]; - memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); - r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); - } break; + memcpy(b, nm->sin6_addr.s6_addr, sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr, 16, Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; } } p = p->ifa_next; @@ -334,24 +343,24 @@ std::vector BSDEthernetTap::ips() const if (ifa) freeifaddrs(ifa); - std::sort(r.begin(),r.end()); - std::unique(r.begin(),r.end()); + std::sort(r.begin(), r.end()); + std::unique(r.begin(), r.end()); _ifaddrs = r; return r; } -void BSDEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void BSDEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { char putBuf[ZT_MAX_MTU + 64]; - if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) { - to.copyTo(putBuf,6); - from.copyTo(putBuf + 6,6); - *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType); - memcpy(putBuf + 14,data,len); + if ((_fd > 0) && (len <= _mtu) && (_enabled)) { + to.copyTo(putBuf, 6); + from.copyTo(putBuf + 6, 6); + *((uint16_t*)(putBuf + 12)) = htons((uint16_t)etherType); + memcpy(putBuf + 14, data, len); len += 14; - ::write(_fd,putBuf,len); + ::write(_fd, putBuf, len); } } @@ -360,44 +369,44 @@ std::string BSDEthernetTap::deviceName() const return _dev; } -void BSDEthernetTap::setFriendlyName(const char *friendlyName) +void BSDEthernetTap::setFriendlyName(const char* friendlyName) { } -void BSDEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void BSDEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { std::vector newGroups; #ifndef __OpenBSD__ - struct ifmaddrs *ifmap = (struct ifmaddrs *)0; - if (!getifmaddrs(&ifmap)) { - struct ifmaddrs *p = ifmap; + struct ifmaddrs* ifmap = (struct ifmaddrs*)0; + if (! getifmaddrs(&ifmap)) { + struct ifmaddrs* p = ifmap; while (p) { if (p->ifma_addr->sa_family == AF_LINK) { - struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; - struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; - if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) - newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + struct sockaddr_dl* in = (struct sockaddr_dl*)p->ifma_name; + struct sockaddr_dl* la = (struct sockaddr_dl*)p->ifma_addr; + if ((la->sdl_alen == 6) && (in->sdl_nlen <= _dev.length()) && (! memcmp(_dev.data(), in->sdl_data, in->sdl_nlen))) + newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen, 6), 0)); } p = p->ifma_next; } freeifmaddrs(ifmap); } -#endif // __OpenBSD__ +#endif // __OpenBSD__ std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - std::unique(newGroups.begin(),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + std::unique(newGroups.begin(), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -411,21 +420,21 @@ void BSDEthernetTap::setMtu(unsigned int mtu) long cpid = (long)vfork(); if (cpid == 0) { char tmp[64]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%u", mtu); #ifdef ZT_TRACE fprintf(stderr, "DEBUG: ifconfig %s mtu %s" ZT_EOL_S, _dev.c_str(), tmp); #endif - execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0); + execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "mtu", tmp, (const char*)0); _exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - waitpid(cpid,&exitcode,0); + waitpid(cpid, &exitcode, 0); } } } -void BSDEthernetTap::threadMain() - throw() +void BSDEthernetTap::threadMain() throw() { // Wait for a moment after startup -- wait for Network to finish // constructing itself. @@ -436,7 +445,6 @@ void BSDEthernetTap::threadMain() for (unsigned int i = 0; i < _concurrency; ++i) { _rxThreads.push_back(std::thread([this, i, pinning] { - if (pinning) { int pinCore = i % _concurrency; fprintf(stderr, "Pinning thread %d to core %d\n", i, pinCore); @@ -444,15 +452,14 @@ void BSDEthernetTap::threadMain() cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(pinCore, &cpuset); - //int rc = sched_setaffinity(self, sizeof(cpu_set_t), &cpuset); + // int rc = sched_setaffinity(self, sizeof(cpu_set_t), &cpuset); int rc = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset); - if (rc != 0) - { + if (rc != 0) { fprintf(stderr, "Failed to pin thread %d to core %d: %s\n", i, pinCore, strerror(errno)); exit(1); } } -#endif // __OpenBSD__ +#endif // __OpenBSD__ uint8_t b[ZT_TAP_BUF_SIZE]; MAC to, from; @@ -461,37 +468,38 @@ void BSDEthernetTap::threadMain() FD_ZERO(&readfds); FD_ZERO(&nullfds); - nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1; + nfds = (int)std::max(_shutdownSignalPipe[0], _fd) + 1; r = 0; - for(;;) { - FD_SET(_shutdownSignalPipe[0],&readfds); - FD_SET(_fd,&readfds); - select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0); + for (;;) { + FD_SET(_shutdownSignalPipe[0], &readfds); + FD_SET(_fd, &readfds); + select(nfds, &readfds, &nullfds, &nullfds, (struct timeval*)0); - if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread + if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) // writes to shutdown pipe terminate thread break; - if (FD_ISSET(_fd,&readfds)) { - n = (int)::read(_fd,b + r,sizeof(b) - r); + if (FD_ISSET(_fd, &readfds)) { + n = (int)::read(_fd, b + r, sizeof(b) - r); if (n < 0) { - if ((errno != EINTR)&&(errno != ETIMEDOUT)) + if ((errno != EINTR) && (errno != ETIMEDOUT)) break; - } else { + } + else { // Some tap drivers like to send the ethernet frame and the // payload in two chunks, so handle that by accumulating // data until we have at least a frame. r += n; if (r > 14) { - if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms + if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms r = _mtu + 14; if (_enabled) { - to.setTo(b,6); - from.setTo(b + 6,6); - unsigned int etherType = ntohs(((const uint16_t *)b)[6]); - _handler(_arg,(void *)0,_nwid,from,to,etherType,0,(const void *)(b + 14),r - 14); + to.setTo(b, 6); + from.setTo(b + 6, 6); + unsigned int etherType = ntohs(((const uint16_t*)b)[6]); + _handler(_arg, (void*)0, _nwid, from, to, etherType, 0, (const void*)(b + 14), r - 14); } r = 0; @@ -502,7 +510,7 @@ void BSDEthernetTap::threadMain() #ifndef __OpenBSD__ })); } -#endif // __OpenBSD__ +#endif // __OpenBSD__ } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/BSDEthernetTap.hpp b/osdep/BSDEthernetTap.hpp index 50e2e6e8b..1f382ba7e 100644 --- a/osdep/BSDEthernetTap.hpp +++ b/osdep/BSDEthernetTap.hpp @@ -14,57 +14,56 @@ #ifndef ZT_BSDETHERNETTAP_HPP #define ZT_BSDETHERNETTAP_HPP +#include "../node/Constants.hpp" +#include "../node/MAC.hpp" +#include "../node/MulticastGroup.hpp" +#include "EthernetTap.hpp" +#include "Thread.hpp" + +#include #include #include - #include -#include -#include #include - -#include "../node/Constants.hpp" -#include "../node/MulticastGroup.hpp" -#include "../node/MAC.hpp" -#include "Thread.hpp" -#include "EthernetTap.hpp" +#include namespace ZeroTier { -class BSDEthernetTap : public EthernetTap -{ -public: +class BSDEthernetTap : public EthernetTap { + public: BSDEthernetTap( - const char *homePath, + const char* homePath, unsigned int concurrency, bool pinning, - const MAC &mac, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~BSDEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); - virtual bool removeIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); + virtual void setFriendlyName(const char* friendlyName); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); virtual void setMtu(unsigned int mtu); - virtual void setDns(const char *domain, const std::vector &servers) {} + virtual void setDns(const char* domain, const std::vector& servers) + { + } - void threadMain() - throw(); + void threadMain() throw(); -private: - void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + private: + void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; unsigned int _concurrency; bool _pinning; uint64_t _nwid; @@ -81,6 +80,6 @@ private: std::vector _rxThreads; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index 23e6393af..b2d8840c4 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -22,11 +22,11 @@ #include #ifdef __WINDOWS__ -#include -#include -#include #include #include +#include +#include +#include #else #include #include @@ -34,13 +34,13 @@ #include #include #ifdef __LINUX__ +#include #include #include -#include #endif #endif -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) +#if (defined(__unix__) || defined(__APPLE__)) && ! defined(__LINUX__) && ! defined(ZT_SDK) #include #if TARGET_OS_OSX #include @@ -131,7 +131,7 @@ class Binder { template void refresh(Phy& phy, unsigned int* ports, unsigned int portCount, const std::vector explicitBind, INTERFACE_CHECKER& ifChecker) { std::map localIfAddrs; - PhySocket *udps; + PhySocket* udps; Mutex::Lock _l(_lock); bool interfacesEnumerated = true; @@ -232,7 +232,7 @@ class Binder { } } - if ( (flags & IFA_F_TEMPORARY) != 0) { + if ((flags & IFA_F_TEMPORARY) != 0) { continue; } if (devname) { @@ -318,11 +318,11 @@ class Binder { // (void)gotViaProc; -#if ! defined(__ANDROID__) // getifaddrs() freeifaddrs() not available on Android +#if ! defined(__ANDROID__) // getifaddrs() freeifaddrs() not available on Android if (! gotViaProc) { struct ifaddrs* ifatbl = (struct ifaddrs*)0; struct ifaddrs* ifa; -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) +#if (defined(__unix__) || defined(__APPLE__)) && ! defined(__LINUX__) && ! defined(ZT_SDK) // set up an IPv6 socket so we can check the state of interfaces via SIOCGIFAFLAG_IN6 int infoSock = socket(AF_INET6, SOCK_DGRAM, 0); #endif @@ -331,7 +331,7 @@ class Binder { while (ifa) { if ((ifa->ifa_name) && (ifa->ifa_addr)) { InetAddress ip = *(ifa->ifa_addr); -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) && TARGET_OS_OSX +#if (defined(__unix__) || defined(__APPLE__)) && ! defined(__LINUX__) && ! defined(ZT_SDK) && TARGET_OS_OSX // Check if the address is an IPv6 Temporary Address, macOS/BSD version if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr; @@ -379,7 +379,7 @@ class Binder { else { interfacesEnumerated = false; } -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) +#if (defined(__unix__) || defined(__APPLE__)) && ! defined(__LINUX__) && ! defined(ZT_SDK) close(infoSock); #endif } diff --git a/osdep/BlockingQueue.hpp b/osdep/BlockingQueue.hpp index c9417b74e..f377aa0bf 100644 --- a/osdep/BlockingQueue.hpp +++ b/osdep/BlockingQueue.hpp @@ -14,11 +14,11 @@ #ifndef ZT_BLOCKINGQUEUE_HPP #define ZT_BLOCKINGQUEUE_HPP -#include -#include -#include -#include #include +#include +#include +#include +#include #include namespace ZeroTier { @@ -28,11 +28,11 @@ namespace ZeroTier { * * Do not use in node/ since we have not gone C++11 there yet. */ -template -class BlockingQueue -{ -public: - BlockingQueue(void) : r(true) {} +template class BlockingQueue { + public: + BlockingQueue(void) : r(true) + { + } inline void post(T t) { @@ -41,16 +41,16 @@ public: c.notify_one(); } - inline void postLimit(T t,const unsigned long limit) + inline void postLimit(T t, const unsigned long limit) { std::unique_lock lock(m); - for(;;) { + for (;;) { if (q.size() < limit) { q.push(t); c.notify_one(); break; } - if (!r) + if (! r) break; gc.wait(lock); } @@ -64,14 +64,14 @@ public: gc.notify_all(); } - inline bool get(T &value) + inline bool get(T& value) { std::unique_lock lock(m); - if (!r) + if (! r) return false; while (q.empty()) { c.wait(lock); - if (!r) { + if (! r) { gc.notify_all(); return false; } @@ -85,30 +85,25 @@ public: inline std::vector drain() { std::vector v; - while (!q.empty()) { + while (! q.empty()) { v.push_back(q.front()); q.pop(); } return v; } - enum TimedWaitResult - { - OK, - TIMED_OUT, - STOP - }; + enum TimedWaitResult { OK, TIMED_OUT, STOP }; - inline TimedWaitResult get(T &value,const unsigned long ms) + inline TimedWaitResult get(T& value, const unsigned long ms) { - const std::chrono::milliseconds ms2{ms}; + const std::chrono::milliseconds ms2 { ms }; std::unique_lock lock(m); - if (!r) + if (! r) return STOP; while (q.empty()) { - if (c.wait_for(lock,ms2) == std::cv_status::timeout) + if (c.wait_for(lock, ms2) == std::cv_status::timeout) return ((r) ? TIMED_OUT : STOP); - else if (!r) + else if (! r) return STOP; } value = q.front(); @@ -116,17 +111,18 @@ public: return OK; } - inline size_t size() const { + inline size_t size() const + { return q.size(); } -private: + private: std::queue q; mutable std::mutex m; - mutable std::condition_variable c,gc; + mutable std::condition_variable c, gc; std::atomic_bool r; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/EthernetTap.cpp b/osdep/EthernetTap.cpp index 6cfc3a9b3..02692d652 100644 --- a/osdep/EthernetTap.cpp +++ b/osdep/EthernetTap.cpp @@ -12,6 +12,7 @@ /****/ #include "EthernetTap.hpp" + #include "OSUtils.hpp" #include @@ -20,82 +21,83 @@ #ifdef ZT_SDK #include "../controller/EmbeddedNetworkController.hpp" -#include "../node/Node.hpp" #include "../include/VirtualTap.hpp" +#include "../node/Node.hpp" #else #ifdef __APPLE__ -#include #include "MacEthernetTap.hpp" #include "MacKextEthernetTap.hpp" -#endif // __APPLE__ + +#include +#endif // __APPLE__ #ifdef __LINUX__ #include "LinuxEthernetTap.hpp" -#endif // __LINUX__ +#endif // __LINUX__ #ifdef __WINDOWS__ #include "WindowsEthernetTap.hpp" -#endif // __WINDOWS__ +#endif // __WINDOWS__ #ifdef __FreeBSD__ #include "BSDEthernetTap.hpp" -#endif // __FreeBSD__ +#endif // __FreeBSD__ #ifdef __NetBSD__ #include "NetBSDEthernetTap.hpp" -#endif // __NetBSD__ +#endif // __NetBSD__ #ifdef __OpenBSD__ #include "BSDEthernetTap.hpp" -#endif // __OpenBSD__ +#endif // __OpenBSD__ #endif namespace ZeroTier { std::shared_ptr EthernetTap::newInstance( - const char *tapDeviceType, // OS-specific, NULL for default + const char* tapDeviceType, // OS-specific, NULL for default unsigned int concurrency, bool pinning, - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg) { - #ifdef ZT_SDK - return std::shared_ptr(new VirtualTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); + return std::shared_ptr(new VirtualTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg)); -#else // not ZT_SDK +#else // not ZT_SDK #ifdef __APPLE__ char osrelease[256]; size_t size = sizeof(osrelease); - if (sysctlbyname("kern.osrelease",osrelease,&size,nullptr,0) == 0) { - char *dotAt = strchr(osrelease,'.'); + if (sysctlbyname("kern.osrelease", osrelease, &size, nullptr, 0) == 0) { + char* dotAt = strchr(osrelease, '.'); if (dotAt) { *dotAt = (char)0; // The "feth" virtual Ethernet device type appeared in Darwin 17.x.x. Older versions // (Sierra and earlier) must use the a kernel extension. - if (strtol(osrelease,(char **)0,10) < 17) { - return std::shared_ptr(new MacKextEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); - } else { - return std::shared_ptr(new MacEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); + if (strtol(osrelease, (char**)0, 10) < 17) { + return std::shared_ptr(new MacKextEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg)); + } + else { + return std::shared_ptr(new MacEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg)); } } } -#endif // __APPLE__ +#endif // __APPLE__ #ifdef __LINUX__ - return std::shared_ptr(new LinuxEthernetTap(homePath,concurrency,pinning,mac,mtu,metric,nwid,friendlyName,handler,arg)); -#endif // __LINUX__ + return std::shared_ptr(new LinuxEthernetTap(homePath, concurrency, pinning, mac, mtu, metric, nwid, friendlyName, handler, arg)); +#endif // __LINUX__ #ifdef __WINDOWS__ HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); @@ -108,18 +110,8 @@ std::shared_ptr EthernetTap::newInstance( { Mutex::Lock l(_comInit_m); - if (!_comInit) { - hres = CoInitializeSecurity( - NULL, - -1, - NULL, - NULL, - RPC_C_AUTHN_LEVEL_PKT, - RPC_C_IMP_LEVEL_IMPERSONATE, - NULL, - EOAC_NONE, - NULL - ); + if (! _comInit) { + hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (FAILED(hres)) { CoUninitialize(); fprintf(stderr, "WinEthernetTap: Failed to initialize security"); @@ -128,33 +120,37 @@ std::shared_ptr EthernetTap::newInstance( _comInit = true; } } - return std::shared_ptr(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); -#endif // __WINDOWS__ + return std::shared_ptr(new WindowsEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg)); +#endif // __WINDOWS__ #ifdef __FreeBSD__ - return std::shared_ptr(new BSDEthernetTap(homePath,concurrency,pinning,mac,mtu,metric,nwid,friendlyName,handler,arg)); -#endif // __FreeBSD__ + return std::shared_ptr(new BSDEthernetTap(homePath, concurrency, pinning, mac, mtu, metric, nwid, friendlyName, handler, arg)); +#endif // __FreeBSD__ #ifdef __NetBSD__ - return std::shared_ptr(new NetBSDEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); -#endif // __NetBSD__ + return std::shared_ptr(new NetBSDEthernetTap(homePath, mac, mtu, metric, nwid, friendlyName, handler, arg)); +#endif // __NetBSD__ #ifdef __OpenBSD__ - return std::shared_ptr(new BSDEthernetTap(homePath,concurrency,pinning,mac,mtu,metric,nwid,friendlyName,handler,arg)); -#endif // __OpenBSD__ + return std::shared_ptr(new BSDEthernetTap(homePath, concurrency, pinning, mac, mtu, metric, nwid, friendlyName, handler, arg)); +#endif // __OpenBSD__ -#endif // ZT_SDK? +#endif // ZT_SDK? return std::shared_ptr(); } -EthernetTap::EthernetTap() {} -EthernetTap::~EthernetTap() {} +EthernetTap::EthernetTap() +{ +} +EthernetTap::~EthernetTap() +{ +} bool EthernetTap::addIps(std::vector ips) { - for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { - if (!addIp(*i)) + for (std::vector::const_iterator i(ips.begin()); i != ips.end(); ++i) { + if (! addIp(*i)) return false; } return true; @@ -166,4 +162,4 @@ std::string EthernetTap::friendlyName() const return std::string(); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/EthernetTap.hpp b/osdep/EthernetTap.hpp index 1d97f1256..aaabfeb60 100644 --- a/osdep/EthernetTap.hpp +++ b/osdep/EthernetTap.hpp @@ -15,52 +15,51 @@ #define ZT_ETHERNETTAP_HPP #include "../node/Constants.hpp" -#include "../node/MAC.hpp" #include "../node/InetAddress.hpp" +#include "../node/MAC.hpp" #include "../node/MulticastGroup.hpp" -#include #include +#include #include #define GETIFADDRS_CACHE_TIME 1000 namespace ZeroTier { -class EthernetTap -{ -public: +class EthernetTap { + public: static std::shared_ptr newInstance( - const char *tapDeviceType, // OS-specific, NULL for default + const char* tapDeviceType, // OS-specific, NULL for default unsigned int concurrency, bool pinning, - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); EthernetTap(); virtual ~EthernetTap(); virtual void setEnabled(bool en) = 0; virtual bool enabled() const = 0; - virtual bool addIp(const InetAddress &ip) = 0; - virtual bool addIps(std::vector ips); // uses addIp() unless overridden - virtual bool removeIp(const InetAddress &ip) = 0; + virtual bool addIp(const InetAddress& ip) = 0; + virtual bool addIps(std::vector ips); // uses addIp() unless overridden + virtual bool removeIp(const InetAddress& ip) = 0; virtual std::vector ips() const = 0; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) = 0; + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) = 0; virtual std::string deviceName() const = 0; - virtual void setFriendlyName(const char *friendlyName) = 0; + virtual void setFriendlyName(const char* friendlyName) = 0; virtual std::string friendlyName() const; - virtual void scanMulticastGroups(std::vector &added,std::vector &removed) = 0; + virtual void scanMulticastGroups(std::vector& added, std::vector& removed) = 0; virtual void setMtu(unsigned int mtu) = 0; - virtual void setDns(const char *domain, const std::vector &servers) = 0; + virtual void setDns(const char* domain, const std::vector& servers) = 0; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/Http.cpp b/osdep/Http.cpp index d392cd540..4b7879e82 100644 --- a/osdep/Http.cpp +++ b/osdep/Http.cpp @@ -11,15 +11,16 @@ */ /****/ -#include -#include -#include - #include "Http.hpp" -#include "Phy.hpp" -#include "OSUtils.hpp" + #include "../node/Constants.hpp" #include "../node/Utils.hpp" +#include "OSUtils.hpp" +#include "Phy.hpp" + +#include +#include +#include #ifdef ZT_USE_SYSTEM_HTTP_PARSER #include @@ -31,90 +32,87 @@ namespace ZeroTier { namespace { -static int ShttpOnMessageBegin(http_parser *parser); -static int ShttpOnUrl(http_parser *parser,const char *ptr,size_t length); +static int ShttpOnMessageBegin(http_parser* parser); +static int ShttpOnUrl(http_parser* parser, const char* ptr, size_t length); #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2) -static int ShttpOnStatus(http_parser *parser,const char *ptr,size_t length); +static int ShttpOnStatus(http_parser* parser, const char* ptr, size_t length); #else -static int ShttpOnStatus(http_parser *parser); +static int ShttpOnStatus(http_parser* parser); #endif -static int ShttpOnHeaderField(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnValue(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnHeadersComplete(http_parser *parser); -static int ShttpOnBody(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnMessageComplete(http_parser *parser); +static int ShttpOnHeaderField(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnValue(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnHeadersComplete(http_parser* parser); +static int ShttpOnBody(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnMessageComplete(http_parser* parser); #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 1) -static const struct http_parser_settings HTTP_PARSER_SETTINGS = { - ShttpOnMessageBegin, - ShttpOnUrl, - ShttpOnStatus, - ShttpOnHeaderField, - ShttpOnValue, - ShttpOnHeadersComplete, - ShttpOnBody, - ShttpOnMessageComplete -}; +static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnStatus, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete }; #else -static const struct http_parser_settings HTTP_PARSER_SETTINGS = { - ShttpOnMessageBegin, - ShttpOnUrl, - ShttpOnHeaderField, - ShttpOnValue, - ShttpOnHeadersComplete, - ShttpOnBody, - ShttpOnMessageComplete -}; +static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete }; #endif -struct HttpPhyHandler -{ +struct HttpPhyHandler { // not used - inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) {} - inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) {} + inline void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len) + { + } + inline void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from) + { + } - inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) + inline void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success) { if (success) { - phy->setNotifyWritable(sock,true); - } else { + phy->setNotifyWritable(sock, true); + } + else { *responseBody = "connection failed"; error = true; done = true; } } - inline void phyOnTcpClose(PhySocket *sock,void **uptr) + inline void phyOnTcpClose(PhySocket* sock, void** uptr) { done = true; } - inline void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) + inline void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len) { lastActivity = OSUtils::now(); - http_parser_execute(&parser,&HTTP_PARSER_SETTINGS,(const char *)data,len); - if ((parser.upgrade)||(parser.http_errno != HPE_OK)) + http_parser_execute(&parser, &HTTP_PARSER_SETTINGS, (const char*)data, len); + if ((parser.upgrade) || (parser.http_errno != HPE_OK)) phy->close(sock); } - inline void phyOnTcpWritable(PhySocket *sock,void **uptr) + inline void phyOnTcpWritable(PhySocket* sock, void** uptr) { if (writePtr < (unsigned long)writeBuf.length()) { - long n = phy->streamSend(sock,writeBuf.data() + writePtr,(unsigned long)writeBuf.length() - writePtr,true); + long n = phy->streamSend(sock, writeBuf.data() + writePtr, (unsigned long)writeBuf.length() - writePtr, true); if (n > 0) writePtr += n; } if (writePtr >= (unsigned long)writeBuf.length()) - phy->setNotifyWritable(sock,false); + phy->setNotifyWritable(sock, false); } - inline void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) {} + inline void phyOnFileDescriptorActivity(PhySocket* sock, void** uptr, bool readable, bool writable) + { + } #ifdef __UNIX_LIKE__ - inline void phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {} - inline void phyOnUnixClose(PhySocket *sock,void **uptr) {} - inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} - inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {} -#endif // __UNIX_LIKE__ + inline void phyOnUnixAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN) + { + } + inline void phyOnUnixClose(PhySocket* sock, void** uptr) + { + } + inline void phyOnUnixData(PhySocket* sock, void** uptr, void* data, unsigned long len) + { + } + inline void phyOnUnixWritable(PhySocket* sock, void** uptr) + { + } +#endif // __UNIX_LIKE__ http_parser parser; std::string currentHeaderField; @@ -125,27 +123,27 @@ struct HttpPhyHandler std::string writeBuf; unsigned long maxResponseSize; - std::map *responseHeaders; - std::string *responseBody; + std::map* responseHeaders; + std::string* responseBody; bool error; bool done; - Phy *phy; - PhySocket *sock; + Phy* phy; + PhySocket* sock; }; -static int ShttpOnMessageBegin(http_parser *parser) +static int ShttpOnMessageBegin(http_parser* parser) { return 0; } -static int ShttpOnUrl(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnUrl(http_parser* parser, const char* ptr, size_t length) { return 0; } #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2) -static int ShttpOnStatus(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnStatus(http_parser* parser, const char* ptr, size_t length) #else -static int ShttpOnStatus(http_parser *parser) +static int ShttpOnStatus(http_parser* parser) #endif { /* @@ -156,66 +154,66 @@ static int ShttpOnStatus(http_parser *parser) */ return 0; } -static int ShttpOnHeaderField(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnHeaderField(http_parser* parser, const char* ptr, size_t length) { - HttpPhyHandler *hh = reinterpret_cast(parser->data); + HttpPhyHandler* hh = reinterpret_cast(parser->data); hh->messageSize += (unsigned long)length; if (hh->messageSize > hh->maxResponseSize) return -1; - if ((hh->currentHeaderField.length())&&(hh->currentHeaderValue.length())) { + if ((hh->currentHeaderField.length()) && (hh->currentHeaderValue.length())) { (*hh->responseHeaders)[hh->currentHeaderField] = hh->currentHeaderValue; hh->currentHeaderField = ""; hh->currentHeaderValue = ""; } - for(size_t i=0;icurrentHeaderField.push_back(OSUtils::toLower(ptr[i])); return 0; } -static int ShttpOnValue(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnValue(http_parser* parser, const char* ptr, size_t length) { - HttpPhyHandler *hh = reinterpret_cast(parser->data); + HttpPhyHandler* hh = reinterpret_cast(parser->data); hh->messageSize += (unsigned long)length; if (hh->messageSize > hh->maxResponseSize) return -1; - hh->currentHeaderValue.append(ptr,length); + hh->currentHeaderValue.append(ptr, length); return 0; } -static int ShttpOnHeadersComplete(http_parser *parser) +static int ShttpOnHeadersComplete(http_parser* parser) { - HttpPhyHandler *hh = reinterpret_cast(parser->data); - if ((hh->currentHeaderField.length())&&(hh->currentHeaderValue.length())) + HttpPhyHandler* hh = reinterpret_cast(parser->data); + if ((hh->currentHeaderField.length()) && (hh->currentHeaderValue.length())) (*hh->responseHeaders)[hh->currentHeaderField] = hh->currentHeaderValue; return 0; } -static int ShttpOnBody(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnBody(http_parser* parser, const char* ptr, size_t length) { - HttpPhyHandler *hh = reinterpret_cast(parser->data); + HttpPhyHandler* hh = reinterpret_cast(parser->data); hh->messageSize += (unsigned long)length; if (hh->messageSize > hh->maxResponseSize) return -1; - hh->responseBody->append(ptr,length); + hh->responseBody->append(ptr, length); return 0; } -static int ShttpOnMessageComplete(http_parser *parser) +static int ShttpOnMessageComplete(http_parser* parser) { - HttpPhyHandler *hh = reinterpret_cast(parser->data); + HttpPhyHandler* hh = reinterpret_cast(parser->data); hh->phy->close(hh->sock); return 0; } -} // anonymous namespace +} // anonymous namespace unsigned int Http::_do( - const char *method, + const char* method, unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - const void *requestBody, + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + const void* requestBody, unsigned long requestBodyLength, - std::map &responseHeaders, - std::string &responseBody) + std::map& responseHeaders, + std::string& responseBody) { try { responseHeaders.clear(); @@ -223,31 +221,33 @@ unsigned int Http::_do( HttpPhyHandler handler; - http_parser_init(&(handler.parser),HTTP_RESPONSE); - handler.parser.data = (void *)&handler; + http_parser_init(&(handler.parser), HTTP_RESPONSE); + handler.parser.data = (void*)&handler; handler.messageSize = 0; handler.writePtr = 0; handler.lastActivity = OSUtils::now(); try { char tmp[1024]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s %s HTTP/1.1\r\n",method,path); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%s %s HTTP/1.1\r\n", method, path); handler.writeBuf.append(tmp); - for(std::map::const_iterator h(requestHeaders.begin());h!=requestHeaders.end();++h) { - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s: %s\r\n",h->first.c_str(),h->second.c_str()); + for (std::map::const_iterator h(requestHeaders.begin()); h != requestHeaders.end(); ++h) { + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%s: %s\r\n", h->first.c_str(), h->second.c_str()); handler.writeBuf.append(tmp); } handler.writeBuf.append("\r\n"); - if ((requestBody)&&(requestBodyLength)) - handler.writeBuf.append((const char *)requestBody,requestBodyLength); - } catch ( ... ) { + if ((requestBody) && (requestBodyLength)) + handler.writeBuf.append((const char*)requestBody, requestBodyLength); + } + catch (...) { responseBody = "request too large"; return 0; } if (maxResponseSize) { handler.maxResponseSize = maxResponseSize; - } else { + } + else { handler.maxResponseSize = 2147483647; } handler.responseHeaders = &responseHeaders; @@ -255,19 +255,19 @@ unsigned int Http::_do( handler.error = false; handler.done = false; - Phy phy(&handler,true,true); + Phy phy(&handler, true, true); bool instantConnect = false; handler.phy = &phy; - handler.sock = phy.tcpConnect((const struct sockaddr *)remoteAddress,instantConnect,(void *)0,true); - if (!handler.sock) { + handler.sock = phy.tcpConnect((const struct sockaddr*)remoteAddress, instantConnect, (void*)0, true); + if (! handler.sock) { responseBody = "connection failed (2)"; return 0; } - while (!handler.done) { + while (! handler.done) { phy.poll(timeout / 2); - if ((timeout)&&((unsigned long)(OSUtils::now() - handler.lastActivity) > timeout)) { + if ((timeout) && ((unsigned long)(OSUtils::now() - handler.lastActivity) > timeout)) { phy.close(handler.sock); responseBody = "timed out"; return 0; @@ -275,13 +275,15 @@ unsigned int Http::_do( } return ((handler.error) ? 0 : ((handler.parser.http_errno != HPE_OK) ? 0 : handler.parser.status_code)); - } catch (std::exception &exc) { + } + catch (std::exception& exc) { responseBody = exc.what(); return 0; - } catch ( ... ) { + } + catch (...) { responseBody = "unknown exception"; return 0; } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/Http.hpp b/osdep/Http.hpp index 6e669ab25..aebb481fa 100644 --- a/osdep/Http.hpp +++ b/osdep/Http.hpp @@ -14,21 +14,21 @@ #ifndef ZT_HTTP_HPP #define ZT_HTTP_HPP -#include #include #include +#include #if defined(_WIN32) || defined(_WIN64) +#include #include #include -#include #else -#include -#include -#include -#include #include #include +#include +#include +#include +#include #endif namespace ZeroTier { @@ -36,9 +36,8 @@ namespace ZeroTier { /** * Simple synchronous HTTP client used for updater and cli */ -class Http -{ -public: +class Http { + public: /** * Make HTTP GET request * @@ -46,26 +45,16 @@ public: * * @return HTTP status code or 0 on error (responseBody will contain error message) */ - static inline unsigned int GET( - unsigned long maxResponseSize, + static inline unsigned int + GET(unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - std::map &responseHeaders, - std::string &responseBody) + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + std::map& responseHeaders, + std::string& responseBody) { - return _do( - "GET", - maxResponseSize, - timeout, - remoteAddress, - path, - requestHeaders, - (const void *)0, - 0, - responseHeaders, - responseBody); + return _do("GET", maxResponseSize, timeout, remoteAddress, path, requestHeaders, (const void*)0, 0, responseHeaders, responseBody); } /** @@ -75,26 +64,16 @@ public: * * @return HTTP status code or 0 on error (responseBody will contain error message) */ - static inline unsigned int DEL( - unsigned long maxResponseSize, + static inline unsigned int + DEL(unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - std::map &responseHeaders, - std::string &responseBody) + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + std::map& responseHeaders, + std::string& responseBody) { - return _do( - "DELETE", - maxResponseSize, - timeout, - remoteAddress, - path, - requestHeaders, - (const void *)0, - 0, - responseHeaders, - responseBody); + return _do("DELETE", maxResponseSize, timeout, remoteAddress, path, requestHeaders, (const void*)0, 0, responseHeaders, responseBody); } /** @@ -109,25 +88,15 @@ public: static inline unsigned int POST( unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - const void *postData, + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + const void* postData, unsigned long postDataLength, - std::map &responseHeaders, - std::string &responseBody) + std::map& responseHeaders, + std::string& responseBody) { - return _do( - "POST", - maxResponseSize, - timeout, - remoteAddress, - path, - requestHeaders, - postData, - postDataLength, - responseHeaders, - responseBody); + return _do("POST", maxResponseSize, timeout, remoteAddress, path, requestHeaders, postData, postDataLength, responseHeaders, responseBody); } /** @@ -139,44 +108,34 @@ public: * * @return HTTP status code or 0 on error (responseBody will contain error message) */ - static inline unsigned int PUT( - unsigned long maxResponseSize, + static inline unsigned int + PUT(unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - const void *postData, + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + const void* postData, unsigned long postDataLength, - std::map &responseHeaders, - std::string &responseBody) + std::map& responseHeaders, + std::string& responseBody) { - return _do( - "PUT", - maxResponseSize, - timeout, - remoteAddress, - path, - requestHeaders, - postData, - postDataLength, - responseHeaders, - responseBody); + return _do("PUT", maxResponseSize, timeout, remoteAddress, path, requestHeaders, postData, postDataLength, responseHeaders, responseBody); } -private: - static unsigned int _do( - const char *method, + private: + static unsigned int + _do(const char* method, unsigned long maxResponseSize, unsigned long timeout, - const struct sockaddr *remoteAddress, - const char *path, - const std::map &requestHeaders, - const void *requestBody, + const struct sockaddr* remoteAddress, + const char* path, + const std::map& requestHeaders, + const void* requestBody, unsigned long requestBodyLength, - std::map &responseHeaders, - std::string &responseBody); + std::map& responseHeaders, + std::string& responseBody); }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 14929d176..5fe37216d 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -19,42 +19,39 @@ #ifdef __LINUX__ -#include "../node/Utils.hpp" -#include "../node/Mutex.hpp" #include "../node/Dictionary.hpp" -#include "OSUtils.hpp" +#include "../node/Mutex.hpp" +#include "../node/Utils.hpp" #include "LinuxEthernetTap.hpp" #include "LinuxNetLink.hpp" +#include "OSUtils.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include #include - -#include +#include +#include +#include +#include #include - +#include +#include +#include #ifndef IFNAMSIZ #define IFNAMSIZ 16 @@ -63,7 +60,7 @@ #define ZT_TAP_BUF_SIZE (1024 * 16) // ff:ff:ff:ff:ff:ff with no ADI -static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0); namespace ZeroTier { @@ -72,9 +69,10 @@ namespace ZeroTier { // the tap devices. // // Returns true if the kernel major version is < 3 -bool isOldLinuxKernel() { +bool isOldLinuxKernel() +{ struct utsname buffer; - char *p; + char* p; long ver[16]; int i = 0; if (uname(&buffer) != 0) { @@ -84,20 +82,21 @@ bool isOldLinuxKernel() { p = buffer.release; - while (*p) { - if (isdigit(*p)) { - ver[i] = strtol(p, &p, 10); - i++; - } else { - p++; - } - } + while (*p) { + if (isdigit(*p)) { + ver[i] = strtol(p, &p, 10); + i++; + } + else { + p++; + } + } return ver[0] < 3; } -static const char _base32_chars[32] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7' }; -static void _base32_5_to_8(const uint8_t *in,char *out) +static const char _base32_chars[32] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7' }; +static void _base32_5_to_8(const uint8_t* in, char* out) { out[0] = _base32_chars[(in[0]) >> 3]; out[1] = _base32_chars[(in[0] & 0x07) << 2 | (in[1] & 0xc0) >> 6]; @@ -110,87 +109,89 @@ static void _base32_5_to_8(const uint8_t *in,char *out) } LinuxEthernetTap::LinuxEthernetTap( - const char *homePath, + const char* homePath, unsigned int concurrency, bool pinning, - const MAC &mac, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg) : - _handler(handler), - _arg(arg), - _nwid(nwid), - _mac(mac), - _homePath(homePath), - _mtu(mtu), - _fd(0), - _enabled(true), - _run(true), - _lastIfAddrsUpdate(0) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg) + : _handler(handler) + , _arg(arg) + , _nwid(nwid) + , _mac(mac) + , _homePath(homePath) + , _mtu(mtu) + , _fd(0) + , _enabled(true) + , _run(true) + , _lastIfAddrsUpdate(0) { static std::mutex s_tapCreateLock; - char procpath[128],nwids[32]; + char procpath[128], nwids[32]; struct stat sbuf; - // Create only one tap at a time globally. std::lock_guard tapCreateLock(s_tapCreateLock); // Make sure Linux netlink is initialized. (void)LinuxNetLink::getInstance(); - OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid); + OSUtils::ztsnprintf(nwids, sizeof(nwids), "%.16llx", nwid); - _fd = ::open("/dev/net/tun",O_RDWR); + _fd = ::open("/dev/net/tun", O_RDWR); if (_fd <= 0) { - _fd = ::open("/dev/tun",O_RDWR); + _fd = ::open("/dev/tun", O_RDWR); if (_fd <= 0) throw std::runtime_error(std::string("could not open TUN/TAP device: ") + strerror(errno)); } struct ifreq ifr; - memset(&ifr,0,sizeof(ifr)); + memset(&ifr, 0, sizeof(ifr)); // Restore device names from legacy devicemap, but for new devices we use a base32-based // canonical device name. - std::map globalDeviceMap; - FILE *devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),"r"); + std::map globalDeviceMap; + FILE* devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(), "r"); if (devmapf) { char buf[256]; - while (fgets(buf,sizeof(buf),devmapf)) { - char *x = (char *)0; - char *y = (char *)0; - char *saveptr = (char *)0; - for(char *f=Utils::stok(buf,"\r\n=",&saveptr);(f);f=Utils::stok((char *)0,"\r\n=",&saveptr)) { - if (!x) x = f; - else if (!y) y = f; - else break; + while (fgets(buf, sizeof(buf), devmapf)) { + char* x = (char*)0; + char* y = (char*)0; + char* saveptr = (char*)0; + for (char* f = Utils::stok(buf, "\r\n=", &saveptr); (f); f = Utils::stok((char*)0, "\r\n=", &saveptr)) { + if (! x) + x = f; + else if (! y) + y = f; + else + break; } - if ((x)&&(y)&&(x[0])&&(y[0])) + if ((x) && (y) && (x[0]) && (y[0])) globalDeviceMap[x] = y; } fclose(devmapf); } bool recalledDevice = false; - std::map::const_iterator gdmEntry = globalDeviceMap.find(nwids); + std::map::const_iterator gdmEntry = globalDeviceMap.find(nwids); if (gdmEntry != globalDeviceMap.end()) { - Utils::scopy(ifr.ifr_name,sizeof(ifr.ifr_name),gdmEntry->second.c_str()); - OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); - recalledDevice = (stat(procpath,&sbuf) != 0); + Utils::scopy(ifr.ifr_name, sizeof(ifr.ifr_name), gdmEntry->second.c_str()); + OSUtils::ztsnprintf(procpath, sizeof(procpath), "/proc/sys/net/ipv4/conf/%s", ifr.ifr_name); + recalledDevice = (stat(procpath, &sbuf) != 0); } - if (!recalledDevice) { + if (! recalledDevice) { #ifdef __SYNOLOGY__ int devno = 50; do { - OSUtils::ztsnprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++); - OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); - } while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist + OSUtils::ztsnprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth%d", devno++); + OSUtils::ztsnprintf(procpath, sizeof(procpath), "/proc/sys/net/ipv4/conf/%s", ifr.ifr_name); + } while (stat(procpath, &sbuf) == 0); // try zt#++ until we find one that does not exist #else - uint64_t trial = 0; // incremented in the very unlikely event of a name collision with another network + uint64_t trial = 0; // incremented in the very unlikely event of a name collision with another network do { const uint64_t nwid40 = (nwid ^ (nwid >> 24)) + trial++; uint8_t tmp2[5]; @@ -202,29 +203,28 @@ LinuxEthernetTap::LinuxEthernetTap( tmp2[4] = (uint8_t)(nwid40 & 0xff); tmp3[0] = 'z'; tmp3[1] = 't'; - _base32_5_to_8(tmp2,tmp3 + 2); + _base32_5_to_8(tmp2, tmp3 + 2); tmp3[10] = (char)0; - memcpy(ifr.ifr_name,tmp3,11); - OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); - } while (stat(procpath,&sbuf) == 0); + memcpy(ifr.ifr_name, tmp3, 11); + OSUtils::ztsnprintf(procpath, sizeof(procpath), "/proc/sys/net/ipv4/conf/%s", ifr.ifr_name); + } while (stat(procpath, &sbuf) == 0); #endif } ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (ioctl(_fd,TUNSETIFF,(void *)&ifr) < 0) { + if (ioctl(_fd, TUNSETIFF, (void*)&ifr) < 0) { ::close(_fd); throw std::runtime_error("unable to configure TUN/TAP device for TAP operation"); } - ::ioctl(_fd,TUNSETPERSIST,0); // valgrind may generate a false alarm here + ::ioctl(_fd, TUNSETPERSIST, 0); // valgrind may generate a false alarm here _dev = ifr.ifr_name; - ::fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); + ::fcntl(_fd, F_SETFD, fcntl(_fd, F_GETFD) | FD_CLOEXEC); (void)::pipe(_shutdownSignalPipe); for (unsigned int i = 0; i < concurrency; ++i) { _rxThreads.push_back(std::thread([this, i, concurrency, pinning] { - if (pinning) { int pinCore = i % concurrency; fprintf(stderr, "Pinning tap thread %d to core %d\n", i, pinCore); @@ -233,8 +233,7 @@ LinuxEthernetTap::LinuxEthernetTap( CPU_ZERO(&cpuset); CPU_SET(pinCore, &cpuset); int rc = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset); - if (rc != 0) - { + if (rc != 0) { fprintf(stderr, "Failed to pin tap thread %d to core %d: %s\n", i, pinCore, strerror(errno)); exit(1); } @@ -364,11 +363,11 @@ LinuxEthernetTap::LinuxEthernetTap( LinuxEthernetTap::~LinuxEthernetTap() { _run = false; - (void)::write(_shutdownSignalPipe[1],"\0",1); + (void)::write(_shutdownSignalPipe[1], "\0", 1); ::close(_fd); ::close(_shutdownSignalPipe[0]); ::close(_shutdownSignalPipe[1]); - for (std::thread &t : _rxThreads) { + for (std::thread& t : _rxThreads) { t.join(); } } @@ -383,7 +382,7 @@ bool LinuxEthernetTap::enabled() const return _enabled; } -static bool ___removeIp(const std::string &_dev,const InetAddress &ip) +static bool ___removeIp(const std::string& _dev, const InetAddress& ip) { LinuxNetLink::getInstance().removeAddress(ip, _dev.c_str()); return true; @@ -392,55 +391,54 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip) bool LinuxEthernetTap::addIps(std::vector ips) { #ifdef __SYNOLOGY__ - std::string filepath = "/etc/sysconfig/network-scripts/ifcfg-"+_dev; - std::string cfg_contents = "DEVICE="+_dev+"\nBOOTPROTO=static"; - int ip4=0,ip6=0,ip4_tot=0,ip6_tot=0; + std::string filepath = "/etc/sysconfig/network-scripts/ifcfg-" + _dev; + std::string cfg_contents = "DEVICE=" + _dev + "\nBOOTPROTO=static"; + int ip4 = 0, ip6 = 0, ip4_tot = 0, ip6_tot = 0; - for(int i=0; i<(int)ips.size(); i++) { + for (int i = 0; i < (int)ips.size(); i++) { if (ips[i].isV4()) ip4_tot++; else ip6_tot++; } // Assemble and write contents of ifcfg-dev file - for(int i=0; i<(int)ips.size(); i++) { + for (int i = 0; i < (int)ips.size(); i++) { if (ips[i].isV4()) { - char iptmp[64],iptmp2[64]; + char iptmp[64], iptmp2[64]; std::string numstr4 = ip4_tot > 1 ? std::to_string(ip4) : ""; - cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString(iptmp) - + "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString(iptmp2)+"\n"; + cfg_contents += "\nIPADDR" + numstr4 + "=" + ips[i].toIpString(iptmp) + "\nNETMASK" + numstr4 + "=" + ips[i].netmask().toIpString(iptmp2) + "\n"; ip4++; - } else { - char iptmp[64],iptmp2[64]; + } + else { + char iptmp[64], iptmp2[64]; std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : ""; - cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString(iptmp) - + "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString(iptmp2)+"\n"; + cfg_contents += "\nIPV6ADDR" + numstr6 + "=" + ips[i].toIpString(iptmp) + "\nNETMASK" + numstr6 + "=" + ips[i].netmask().toIpString(iptmp2) + "\n"; ip6++; } } OSUtils::writeFile(filepath.c_str(), cfg_contents.c_str(), cfg_contents.length()); // Finally, add IPs - for(int i=0; i<(int)ips.size(); i++){ + for (int i = 0; i < (int)ips.size(); i++) { LinuxNetLink::getInstance().addAddress(ips[i], _dev.c_str()); } return true; -#endif // __SYNOLOGY__ +#endif // __SYNOLOGY__ return false; } -bool LinuxEthernetTap::addIp(const InetAddress &ip) +bool LinuxEthernetTap::addIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; std::vector allIps(ips()); - if (std::binary_search(allIps.begin(),allIps.end(),ip)) + if (std::binary_search(allIps.begin(), allIps.end(), ip)) return true; // Remove and reconfigure if address is the same but netmask is different - for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { + for (std::vector::iterator i(allIps.begin()); i != allIps.end(); ++i) { if (i->ipsEqual(ip)) - ___removeIp(_dev,*i); + ___removeIp(_dev, *i); } LinuxNetLink::getInstance().addAddress(ip, _dev.c_str()); @@ -448,13 +446,13 @@ bool LinuxEthernetTap::addIp(const InetAddress &ip) return true; } -bool LinuxEthernetTap::removeIp(const InetAddress &ip) +bool LinuxEthernetTap::removeIp(const InetAddress& ip) { - if (!ip) + if (! ip) return true; std::vector allIps(ips()); - if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) { - if (___removeIp(_dev,ip)) + if (std::find(allIps.begin(), allIps.end(), ip) != allIps.end()) { + if (___removeIp(_dev, ip)) return true; } return false; @@ -462,7 +460,6 @@ bool LinuxEthernetTap::removeIp(const InetAddress &ip) std::vector LinuxEthernetTap::ips() const { - uint64_t now = OSUtils::now(); if ((now - _lastIfAddrsUpdate) <= GETIFADDRS_CACHE_TIME) { @@ -470,28 +467,28 @@ std::vector LinuxEthernetTap::ips() const } _lastIfAddrsUpdate = now; - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; if (getifaddrs(&ifa)) return std::vector(); std::vector r; - struct ifaddrs *p = ifa; + struct ifaddrs* p = ifa; while (p) { - if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { - switch(p->ifa_addr->sa_family) { + if ((! strcmp(p->ifa_name, _dev.c_str())) && (p->ifa_addr) && (p->ifa_netmask) && (p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { + switch (p->ifa_addr->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; - struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; - r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); - } break; + struct sockaddr_in* sin = (struct sockaddr_in*)p->ifa_addr; + struct sockaddr_in* nm = (struct sockaddr_in*)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr), 4, Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; case AF_INET6: { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; - struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + struct sockaddr_in6* sin = (struct sockaddr_in6*)p->ifa_addr; + struct sockaddr_in6* nm = (struct sockaddr_in6*)p->ifa_netmask; uint32_t b[4]; - memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); - r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); - } break; + memcpy(b, nm->sin6_addr.s6_addr, sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr, 16, Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; } } p = p->ifa_next; @@ -500,24 +497,24 @@ std::vector LinuxEthernetTap::ips() const if (ifa) freeifaddrs(ifa); - std::sort(r.begin(),r.end()); - r.erase(std::unique(r.begin(),r.end()),r.end()); + std::sort(r.begin(), r.end()); + r.erase(std::unique(r.begin(), r.end()), r.end()); _ifaddrs = r; return r; } -void LinuxEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void LinuxEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { char putBuf[ZT_MAX_MTU + 64]; - if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) { - to.copyTo(putBuf,6); - from.copyTo(putBuf + 6,6); - *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType); - memcpy(putBuf + 14,data,len); + if ((_fd > 0) && (len <= _mtu) && (_enabled)) { + to.copyTo(putBuf, 6); + from.copyTo(putBuf + 6, 6); + *((uint16_t*)(putBuf + 12)) = htons((uint16_t)etherType); + memcpy(putBuf + 14, data, len); len += 14; - (void)::write(_fd,putBuf,len); + (void)::write(_fd, putBuf, len); } } @@ -526,53 +523,53 @@ std::string LinuxEthernetTap::deviceName() const return _dev; } -void LinuxEthernetTap::setFriendlyName(const char *friendlyName) +void LinuxEthernetTap::setFriendlyName(const char* friendlyName) { } -void LinuxEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void LinuxEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { - char *ptr,*ptr2; + char *ptr, *ptr2; unsigned char mac[6]; std::vector newGroups; - int fd = ::open("/proc/net/dev_mcast",O_RDONLY); + int fd = ::open("/proc/net/dev_mcast", O_RDONLY); if (fd > 0) { char buf[131072]; - int n = (int)::read(fd,buf,sizeof(buf)); - if ((n > 0)&&(n < (int)sizeof(buf))) { + int n = (int)::read(fd, buf, sizeof(buf)); + if ((n > 0) && (n < (int)sizeof(buf))) { buf[n] = (char)0; - for(char *l=strtok_r(buf,"\r\n",&ptr);(l);l=strtok_r((char *)0,"\r\n",&ptr)) { + for (char* l = strtok_r(buf, "\r\n", &ptr); (l); l = strtok_r((char*)0, "\r\n", &ptr)) { int fno = 0; - char *devname = (char *)0; - char *mcastmac = (char *)0; - for(char *f=strtok_r(l," \t",&ptr2);(f);f=strtok_r((char *)0," \t",&ptr2)) { + char* devname = (char*)0; + char* mcastmac = (char*)0; + for (char* f = strtok_r(l, " \t", &ptr2); (f); f = strtok_r((char*)0, " \t", &ptr2)) { if (fno == 1) devname = f; else if (fno == 4) mcastmac = f; ++fno; } - if ((devname)&&(!strcmp(devname,_dev.c_str()))&&(mcastmac)&&(Utils::unhex(mcastmac,mac,6) == 6)) - newGroups.push_back(MulticastGroup(MAC(mac,6),0)); + if ((devname) && (! strcmp(devname, _dev.c_str())) && (mcastmac) && (Utils::unhex(mcastmac, mac, 6) == 6)) + newGroups.push_back(MulticastGroup(MAC(mac, 6), 0)); } } ::close(fd); } std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - newGroups.erase(std::unique(newGroups.begin(),newGroups.end()),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -583,13 +580,13 @@ void LinuxEthernetTap::setMtu(unsigned int mtu) { if (_mtu != mtu) { _mtu = mtu; - int sock = socket(AF_INET,SOCK_DGRAM,0); + int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock > 0) { struct ifreq ifr; - memset(&ifr,0,sizeof(ifr)); - strcpy(ifr.ifr_name,_dev.c_str()); + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, _dev.c_str()); ifr.ifr_ifru.ifru_mtu = (int)mtu; - if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) { + if (ioctl(sock, SIOCSIFMTU, (void*)&ifr) < 0) { printf("WARNING: ioctl() failed updating existing Linux tap device (set MTU)\n"); } close(sock); @@ -597,6 +594,6 @@ void LinuxEthernetTap::setMtu(unsigned int mtu) } } -} // namespace ZeroTier +} // namespace ZeroTier -#endif // __LINUX__ +#endif // __LINUX__ diff --git a/osdep/LinuxEthernetTap.hpp b/osdep/LinuxEthernetTap.hpp index 41e299823..fe8079360 100644 --- a/osdep/LinuxEthernetTap.hpp +++ b/osdep/LinuxEthernetTap.hpp @@ -14,55 +14,56 @@ #ifndef ZT_LINUXETHERNETTAP_HPP #define ZT_LINUXETHERNETTAP_HPP +#include "../node/MulticastGroup.hpp" +#include "BlockingQueue.hpp" +#include "EthernetTap.hpp" + +#include +#include +#include +#include #include #include - #include -#include -#include -#include -#include #include -#include -#include "../node/MulticastGroup.hpp" -#include "EthernetTap.hpp" -#include "BlockingQueue.hpp" +#include namespace ZeroTier { -class LinuxEthernetTap : public EthernetTap -{ -public: +class LinuxEthernetTap : public EthernetTap { + public: LinuxEthernetTap( - const char *homePath, + const char* homePath, unsigned int concurrency, bool pinning, - const MAC &mac, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~LinuxEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); virtual bool addIps(std::vector ips); - virtual bool removeIp(const InetAddress &ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); + virtual void setFriendlyName(const char* friendlyName); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); virtual void setMtu(unsigned int mtu); - virtual void setDns(const char *domain, const std::vector &servers) {} + virtual void setDns(const char* domain, const std::vector& servers) + { + } -private: - void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + private: + void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; uint64_t _nwid; MAC _mac; std::string _homePath; @@ -78,6 +79,6 @@ private: std::vector _rxThreads; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index 00b79b1a1..5e7ee5a1d 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -15,14 +15,14 @@ #include -//#define ZT_NETLINK_TRACE +// #define ZT_NETLINK_TRACE #ifdef __LINUX__ #include "LinuxNetLink.hpp" -#include #include +#include #ifndef IFNAMSIZ #define IFNAMSIZ 16 @@ -49,21 +49,14 @@ struct nl_adr_req { char buf[8192]; }; -LinuxNetLink::LinuxNetLink() - : _t() - , _running(false) - , _seq(0) - , _interfaces() - , _if_m() - , _fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) - , _la({0}) +LinuxNetLink::LinuxNetLink() : _t(), _running(false), _seq(0), _interfaces(), _if_m(), _fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)), _la({ 0 }) { // set socket timeout to 1 sec so we're not permablocking recv() calls _setSocketTimeout(_fd, 1); _la.nl_family = AF_NETLINK; - _la.nl_pid = 0; //getpid()+1; - _la.nl_groups = RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR|RTMGRP_IPV4_ROUTE|RTMGRP_IPV6_ROUTE|RTMGRP_NOTIFY; + _la.nl_pid = 0; // getpid()+1; + _la.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_NOTIFY; if (bind(_fd, (struct sockaddr*)&_la, sizeof(_la))) { fprintf(stderr, "Error connecting to RTNETLINK: %s\n", strerror(errno)); ::exit(1); @@ -89,7 +82,7 @@ void LinuxNetLink::_setSocketTimeout(int fd, int seconds) struct timeval tv; tv.tv_sec = seconds; tv.tv_usec = 0; - if(setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)) != 0) { + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)) != 0) { #ifdef ZT_NETLINK_TRACE fprintf(stderr, "setsockopt failed: %s\n", strerror(errno)); #endif @@ -99,30 +92,30 @@ void LinuxNetLink::_setSocketTimeout(int fd, int seconds) #define ZT_NL_BUF_SIZE 16384 int LinuxNetLink::_doRecv(int fd) { - char *buf = nullptr; - if (posix_memalign((void **)&buf,16,ZT_NL_BUF_SIZE) != 0) { - fprintf(stderr,"malloc failed!\n"); + char* buf = nullptr; + if (posix_memalign((void**)&buf, 16, ZT_NL_BUF_SIZE) != 0) { + fprintf(stderr, "malloc failed!\n"); ::exit(1); } - if (!buf) { - fprintf(stderr,"malloc failed!\n"); + if (! buf) { + fprintf(stderr, "malloc failed!\n"); ::exit(1); } - char *p = NULL; - struct nlmsghdr *nlp; + char* p = NULL; + struct nlmsghdr* nlp; int nll = 0; int rtn = 0; p = buf; - for(;;) { + for (;;) { rtn = recv(fd, p, ZT_NL_BUF_SIZE - nll, 0); if (rtn > 0) { - nlp = (struct nlmsghdr *)p; + nlp = (struct nlmsghdr*)p; - if(nlp->nlmsg_type == NLMSG_ERROR && (nlp->nlmsg_flags & NLM_F_ACK) != NLM_F_ACK) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(nlp); + if (nlp->nlmsg_type == NLMSG_ERROR && (nlp->nlmsg_flags & NLM_F_ACK) != NLM_F_ACK) { + struct nlmsgerr* err = (struct nlmsgerr*)NLMSG_DATA(nlp); if (err->error != 0) { #ifdef ZT_NETLINK_TRACE fprintf(stderr, "rtnetlink error: %s\n", strerror(-(err->error))); @@ -137,8 +130,7 @@ int LinuxNetLink::_doRecv(int fd) break; } - if( (nlp->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI || (nlp->nlmsg_type == NLMSG_DONE)) - { + if ((nlp->nlmsg_flags & NLM_F_MULTI) == NLM_F_MULTI || (nlp->nlmsg_type == NLMSG_DONE)) { if (nlp->nlmsg_type == NLMSG_DONE) { _processMessage(nlp, nll); p = buf; @@ -165,7 +157,8 @@ int LinuxNetLink::_doRecv(int fd) p = buf; nll = 0; break; - } else { + } + else { break; } } @@ -178,7 +171,7 @@ int LinuxNetLink::_doRecv(int fd) void LinuxNetLink::threadMain() throw() { int rtn = 0; - while(_running) { + while (_running) { rtn = _doRecv(_fd); if (rtn <= 0) { Thread::sleep(250); @@ -187,97 +180,93 @@ void LinuxNetLink::threadMain() throw() } } -void LinuxNetLink::_processMessage(struct nlmsghdr *nlp, int nll) +void LinuxNetLink::_processMessage(struct nlmsghdr* nlp, int nll) { - for(; NLMSG_OK(nlp, nll); nlp=NLMSG_NEXT(nlp, nll)) - { - switch(nlp->nlmsg_type) - { - case RTM_NEWLINK: - _linkAdded(nlp); - break; - case RTM_DELLINK: - _linkDeleted(nlp); - break; - case RTM_NEWADDR: - _ipAddressAdded(nlp); - break; - case RTM_DELADDR: - _ipAddressDeleted(nlp); - break; - case RTM_NEWROUTE: - _routeAdded(nlp); - break; - case RTM_DELROUTE: - _routeDeleted(nlp); - break; - default: - break; + for (; NLMSG_OK(nlp, nll); nlp = NLMSG_NEXT(nlp, nll)) { + switch (nlp->nlmsg_type) { + case RTM_NEWLINK: + _linkAdded(nlp); + break; + case RTM_DELLINK: + _linkDeleted(nlp); + break; + case RTM_NEWADDR: + _ipAddressAdded(nlp); + break; + case RTM_DELADDR: + _ipAddressDeleted(nlp); + break; + case RTM_NEWROUTE: + _routeAdded(nlp); + break; + case RTM_DELROUTE: + _routeDeleted(nlp); + break; + default: + break; } } } -void LinuxNetLink::_ipAddressAdded(struct nlmsghdr *nlp) +void LinuxNetLink::_ipAddressAdded(struct nlmsghdr* nlp) { #ifdef ZT_NETLINK_TRACE - struct ifaddrmsg *ifap = (struct ifaddrmsg *)NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)IFA_RTA(ifap); + struct ifaddrmsg* ifap = (struct ifaddrmsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)IFA_RTA(ifap); int ifal = IFA_PAYLOAD(nlp); - char addr[40] = {0}; - char local[40] = {0}; - char label[40] = {0}; - char bcast[40] = {0}; + char addr[40] = { 0 }; + char local[40] = { 0 }; + char label[40] = { 0 }; + char bcast[40] = { 0 }; - for(;RTA_OK(rtap, ifal); rtap=RTA_NEXT(rtap,ifal)) - { - switch(rtap->rta_type) { - case IFA_ADDRESS: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40); - break; - case IFA_LOCAL: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), local, 40); - break; - case IFA_LABEL: - memcpy(label, RTA_DATA(rtap), 40); - break; - case IFA_BROADCAST: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), bcast, 40); - break; + for (; RTA_OK(rtap, ifal); rtap = RTA_NEXT(rtap, ifal)) { + switch (rtap->rta_type) { + case IFA_ADDRESS: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40); + break; + case IFA_LOCAL: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), local, 40); + break; + case IFA_LABEL: + memcpy(label, RTA_DATA(rtap), 40); + break; + case IFA_BROADCAST: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), bcast, 40); + break; } } - fprintf(stderr,"Added IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); + fprintf(stderr, "Added IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); #endif } -void LinuxNetLink::_ipAddressDeleted(struct nlmsghdr *nlp) +void LinuxNetLink::_ipAddressDeleted(struct nlmsghdr* nlp) { #ifdef ZT_NETLINK_TRACE - struct ifaddrmsg *ifap = (struct ifaddrmsg *)NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)IFA_RTA(ifap); + struct ifaddrmsg* ifap = (struct ifaddrmsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)IFA_RTA(ifap); int ifal = IFA_PAYLOAD(nlp); - char addr[40] = {0}; - char local[40] = {0}; - char label[40] = {0}; - char bcast[40] = {0}; + char addr[40] = { 0 }; + char local[40] = { 0 }; + char label[40] = { 0 }; + char bcast[40] = { 0 }; - for(;RTA_OK(rtap, ifal); rtap=RTA_NEXT(rtap,ifal)) - { - switch(rtap->rta_type) { - case IFA_ADDRESS: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40); - break; - case IFA_LOCAL: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), local, 40); - break; - case IFA_LABEL: - memcpy(label, RTA_DATA(rtap), 40); - break; - case IFA_BROADCAST: - inet_ntop(ifap->ifa_family, RTA_DATA(rtap), bcast, 40); - break; + for (; RTA_OK(rtap, ifal); rtap = RTA_NEXT(rtap, ifal)) { + switch (rtap->rta_type) { + case IFA_ADDRESS: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), addr, 40); + break; + case IFA_LOCAL: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), local, 40); + break; + case IFA_LABEL: + memcpy(label, RTA_DATA(rtap), 40); + break; + case IFA_BROADCAST: + inet_ntop(ifap->ifa_family, RTA_DATA(rtap), bcast, 40); + break; } } @@ -285,80 +274,78 @@ void LinuxNetLink::_ipAddressDeleted(struct nlmsghdr *nlp) #endif } -void LinuxNetLink::_routeAdded(struct nlmsghdr *nlp) +void LinuxNetLink::_routeAdded(struct nlmsghdr* nlp) { - char dsts[40] = {0}; - char gws[40] = {0}; - char srcs[40] = {0}; - char ifs[16] = {0}; - char ms[24] = {0}; + char dsts[40] = { 0 }; + char gws[40] = { 0 }; + char srcs[40] = { 0 }; + char ifs[16] = { 0 }; + char ms[24] = { 0 }; - struct rtmsg *rtp = (struct rtmsg *)NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)RTM_RTA(rtp); + struct rtmsg* rtp = (struct rtmsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)RTM_RTA(rtp); int rtl = RTM_PAYLOAD(nlp); Route r; bool wecare = false; - for(;RTA_OK(rtap, rtl); rtap=RTA_NEXT(rtap, rtl)) - { - switch(rtap->rta_type) - { - case RTA_DST: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); - r.target.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); - r.target.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_SRC: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); - r.src.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); - r.src.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_GATEWAY: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); - r.via.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); - r.via.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_OIF: - switch(rtp->rtm_family) { - case AF_INET: - r.ifidx = *((int*)RTA_DATA(rtap)); - wecare = true; - break; - case AF_INET6: - r.ifidx = *((int*)RTA_DATA(rtap)); - wecare = true; - break; - } - sprintf(ifs, "%d", *((int*)RTA_DATA(rtap))); - break; + for (; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl)) { + switch (rtap->rta_type) { + case RTA_DST: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); + r.target.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); + r.target.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_SRC: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); + r.src.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); + r.src.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_GATEWAY: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); + r.via.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); + r.via.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_OIF: + switch (rtp->rtm_family) { + case AF_INET: + r.ifidx = *((int*)RTA_DATA(rtap)); + wecare = true; + break; + case AF_INET6: + r.ifidx = *((int*)RTA_DATA(rtap)); + wecare = true; + break; + } + sprintf(ifs, "%d", *((int*)RTA_DATA(rtap))); + break; } } @@ -373,80 +360,78 @@ void LinuxNetLink::_routeAdded(struct nlmsghdr *nlp) #endif } -void LinuxNetLink::_routeDeleted(struct nlmsghdr *nlp) +void LinuxNetLink::_routeDeleted(struct nlmsghdr* nlp) { - char dsts[40] = {0}; - char gws[40] = {0}; - char srcs[40] = {0}; - char ifs[16] = {0}; - char ms[24] = {0}; + char dsts[40] = { 0 }; + char gws[40] = { 0 }; + char srcs[40] = { 0 }; + char ifs[16] = { 0 }; + char ms[24] = { 0 }; - struct rtmsg *rtp = (struct rtmsg *) NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)RTM_RTA(rtp); + struct rtmsg* rtp = (struct rtmsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)RTM_RTA(rtp); int rtl = RTM_PAYLOAD(nlp); Route r; bool wecare = false; - for(;RTA_OK(rtap, rtl); rtap=RTA_NEXT(rtap, rtl)) - { - switch(rtap->rta_type) - { - case RTA_DST: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); - r.target.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); - r.target.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_SRC: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); - r.src.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); - r.src.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_GATEWAY: - switch(rtp->rtm_family) { - case AF_INET: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); - r.via.set(RTA_DATA(rtap), 4, 0); - wecare = true; - break; - case AF_INET6: - inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); - r.via.set(RTA_DATA(rtap), 16, 0); - wecare = true; - break; - } - break; - case RTA_OIF: - switch(rtp->rtm_family) { - case AF_INET: - r.ifidx = *((int*)RTA_DATA(rtap)); - wecare = true; - break; - case AF_INET6: - r.ifidx = *((int*)RTA_DATA(rtap)); - wecare = true; - break; - } - sprintf(ifs, "%d", *((int*)RTA_DATA(rtap))); - break; + for (; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl)) { + switch (rtap->rta_type) { + case RTA_DST: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); + r.target.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), dsts, 24); + r.target.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_SRC: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); + r.src.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), srcs, 24); + r.src.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_GATEWAY: + switch (rtp->rtm_family) { + case AF_INET: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); + r.via.set(RTA_DATA(rtap), 4, 0); + wecare = true; + break; + case AF_INET6: + inet_ntop(rtp->rtm_family, RTA_DATA(rtap), gws, 24); + r.via.set(RTA_DATA(rtap), 16, 0); + wecare = true; + break; + } + break; + case RTA_OIF: + switch (rtp->rtm_family) { + case AF_INET: + r.ifidx = *((int*)RTA_DATA(rtap)); + wecare = true; + break; + case AF_INET6: + r.ifidx = *((int*)RTA_DATA(rtap)); + wecare = true; + break; + } + sprintf(ifs, "%d", *((int*)RTA_DATA(rtap))); + break; } } @@ -461,71 +446,78 @@ void LinuxNetLink::_routeDeleted(struct nlmsghdr *nlp) #endif } -void LinuxNetLink::_linkAdded(struct nlmsghdr *nlp) +void LinuxNetLink::_linkAdded(struct nlmsghdr* nlp) { - unsigned char mac_bin[6] = {0}; + unsigned char mac_bin[6] = { 0 }; unsigned int mtu = 0; - char ifname[IFNAMSIZ] = {0}; + char ifname[IFNAMSIZ] = { 0 }; - struct ifinfomsg *ifip = (struct ifinfomsg *)NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)IFLA_RTA(ifip); + struct ifinfomsg* ifip = (struct ifinfomsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)IFLA_RTA(ifip); int ifil = RTM_PAYLOAD(nlp); - const char *ptr = (const char *)0; - for(;RTA_OK(rtap, ifil);rtap=RTA_NEXT(rtap, ifil)) - { - switch(rtap->rta_type) { - case IFLA_ADDRESS: - ptr = (const char *)RTA_DATA(rtap); - memcpy(mac_bin, ptr, 6); - break; - case IFLA_IFNAME: - ptr = (const char *)RTA_DATA(rtap); - memcpy(ifname, ptr, strlen(ptr)); - break; - case IFLA_MTU: - memcpy(&mtu, RTA_DATA(rtap), sizeof(unsigned int)); - break; + const char* ptr = (const char*)0; + for (; RTA_OK(rtap, ifil); rtap = RTA_NEXT(rtap, ifil)) { + switch (rtap->rta_type) { + case IFLA_ADDRESS: + ptr = (const char*)RTA_DATA(rtap); + memcpy(mac_bin, ptr, 6); + break; + case IFLA_IFNAME: + ptr = (const char*)RTA_DATA(rtap); + memcpy(ifname, ptr, strlen(ptr)); + break; + case IFLA_MTU: + memcpy(&mtu, RTA_DATA(rtap), sizeof(unsigned int)); + break; } } { Mutex::Lock l(_if_m); - struct iface_entry &entry = _interfaces[ifip->ifi_index]; + struct iface_entry& entry = _interfaces[ifip->ifi_index]; entry.index = ifip->ifi_index; memcpy(entry.ifacename, ifname, sizeof(ifname)); - snprintf(entry.mac,sizeof(entry.mac),"%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",(unsigned int)mac_bin[0],(unsigned int)mac_bin[1],(unsigned int)mac_bin[2],(unsigned int)mac_bin[3],(unsigned int)mac_bin[4],(unsigned int)mac_bin[5]); + snprintf( + entry.mac, + sizeof(entry.mac), + "%.02x:%.02x:%.02x:%.02x:%.02x:%.02x", + (unsigned int)mac_bin[0], + (unsigned int)mac_bin[1], + (unsigned int)mac_bin[2], + (unsigned int)mac_bin[3], + (unsigned int)mac_bin[4], + (unsigned int)mac_bin[5]); memcpy(entry.mac_bin, mac_bin, 6); entry.mtu = mtu; } } -void LinuxNetLink::_linkDeleted(struct nlmsghdr *nlp) +void LinuxNetLink::_linkDeleted(struct nlmsghdr* nlp) { unsigned int mtu = 0; - char ifname[40] = {0}; + char ifname[40] = { 0 }; - struct ifinfomsg *ifip = (struct ifinfomsg *)NLMSG_DATA(nlp); - struct rtattr *rtap = (struct rtattr *)IFLA_RTA(ifip); + struct ifinfomsg* ifip = (struct ifinfomsg*)NLMSG_DATA(nlp); + struct rtattr* rtap = (struct rtattr*)IFLA_RTA(ifip); int ifil = RTM_PAYLOAD(nlp); - const char *ptr = (const char *)0; - for(;RTA_OK(rtap, ifil);rtap=RTA_NEXT(rtap, ifil)) - { - switch(rtap->rta_type) { - case IFLA_IFNAME: - ptr = (const char*)RTA_DATA(rtap); - memcpy(ifname, ptr, strlen(ptr)); - break; - case IFLA_MTU: - memcpy(&mtu, RTA_DATA(rtap), sizeof(unsigned int)); - break; + const char* ptr = (const char*)0; + for (; RTA_OK(rtap, ifil); rtap = RTA_NEXT(rtap, ifil)) { + switch (rtap->rta_type) { + case IFLA_IFNAME: + ptr = (const char*)RTA_DATA(rtap); + memcpy(ifname, ptr, strlen(ptr)); + break; + case IFLA_MTU: + memcpy(&mtu, RTA_DATA(rtap), sizeof(unsigned int)); + break; } } { Mutex::Lock l(_if_m); - if(_interfaces.contains(ifip->ifi_index)) { + if (_interfaces.contains(ifip->ifi_index)) { _interfaces.erase(ifip->ifi_index); } } @@ -543,9 +535,9 @@ void LinuxNetLink::_requestIPv4Routes() struct sockaddr_nl la; la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); la.nl_groups = RTMGRP_IPV4_ROUTE; - if(bind(fd, (struct sockaddr*)&la, sizeof(la))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(la))) { fprintf(stderr, "Error binding RTNETLINK (_requestIPv4Routes #1): %s\n", strerror(errno)); close(fd); return; @@ -596,9 +588,9 @@ void LinuxNetLink::_requestIPv6Routes() struct sockaddr_nl la; la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); la.nl_groups = RTMGRP_IPV6_ROUTE; - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (_requestIPv6Routes #1): %s\n", strerror(errno)); close(fd); return; @@ -649,9 +641,9 @@ void LinuxNetLink::_requestInterfaceList() struct sockaddr_nl la; la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); la.nl_groups = RTMGRP_LINK; - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (_requestInterfaceList #1): %s\n", strerror(errno)); close(fd); return; @@ -688,9 +680,10 @@ void LinuxNetLink::_requestInterfaceList() close(fd); } -void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName) +void LinuxNetLink::addRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName) { - if (!target) return; + if (! target) + return; int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd == -1) { @@ -703,16 +696,16 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c struct sockaddr_nl la; bzero(&la, sizeof(la)); la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (addRoute #1): %s\n", strerror(errno)); close(fd); return; } #ifdef ZT_NETLINK_TRACE - char tmp[64]; + char tmp[64]; char tmp2[64]; char tmp3[64]; fprintf(stderr, "Adding Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); @@ -722,53 +715,56 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c struct nl_route_req req; bzero(&req, sizeof(req)); - struct rtattr *rtap = (struct rtattr *)req.buf; + struct rtattr* rtap = (struct rtattr*)req.buf; rtap->rta_type = RTA_DST; if (target.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&target)->sin_addr, sizeof(struct in_addr)); - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&target)->sin6_addr, sizeof(struct in6_addr)); } rtl += rtap->rta_len; - if(via) { + if (via) { /* * Setting a metric keeps zerotier routes from taking priority over physical * At best the computer would use zerotier through the router instead of the LAN. * At worst it stops working at all. * - * default via 192.168.82.1 dev eth0 proto dhcp src 192.168.82.169 metric 202 - * 10.147.17.0/24 dev zt5u4uptmb proto kernel scope link src 10.147.17.94 - * 192.168.82.0/24 dev eth0 proto dhcp scope link src 192.168.82.169 metric 202 - * 192.168.82.0/24 via 10.147.17.1 dev zt5u4uptmb proto static metric 5000 - * - */ + * default via 192.168.82.1 dev eth0 proto dhcp src 192.168.82.169 metric 202 + * 10.147.17.0/24 dev zt5u4uptmb proto kernel scope link src 10.147.17.94 + * 192.168.82.0/24 dev eth0 proto dhcp scope link src 192.168.82.169 metric 202 + * 192.168.82.0/24 via 10.147.17.1 dev zt5u4uptmb proto static metric 5000 + * + */ rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_PRIORITY; rtap->rta_len = RTA_LENGTH(sizeof(ZT_RTE_METRIC)); memcpy(RTA_DATA(rtap), &ZT_RTE_METRIC, sizeof(ZT_RTE_METRIC)); rtl += rtap->rta_len; - rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_GATEWAY; - if(via.isV4()) { + if (via.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&via)->sin_addr, sizeof(struct in_addr)); - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&via)->sin6_addr, sizeof(struct in6_addr)); } rtl += rtap->rta_len; - } else if (src) { - rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); + } + else if (src) { + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_SRC; - if(src.isV4()) { + if (src.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&src)->sin_addr, sizeof(struct in_addr)); - - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&src)->sin6_addr, sizeof(struct in6_addr)); } @@ -778,7 +774,7 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c if (ifaceName != NULL) { int interface_index = _indexForInterface(ifaceName); if (interface_index != -1) { - rtap = (struct rtattr *) (((char*)rtap) + rtap->rta_len); + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_OIF; rtap->rta_len = RTA_LENGTH(sizeof(int)); memcpy(RTA_DATA(rtap), &interface_index, sizeof(int)); @@ -821,9 +817,10 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c close(fd); } -void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName) +void LinuxNetLink::delRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName) { - if (!target) return; + if (! target) + return; int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd == -1) { @@ -835,16 +832,16 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c struct sockaddr_nl la; la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (delRoute #1): %s\n", strerror(errno)); close(fd); return; } #ifdef ZT_NETLINK_TRACE - char tmp[64]; + char tmp[64]; char tmp2[64]; char tmp3[64]; fprintf(stderr, "Removing Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); @@ -854,36 +851,39 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c struct nl_route_req req; bzero(&req, sizeof(req)); - struct rtattr *rtap = (struct rtattr *)req.buf; + struct rtattr* rtap = (struct rtattr*)req.buf; rtap->rta_type = RTA_DST; if (target.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&target)->sin_addr, sizeof(struct in_addr)); - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&target)->sin6_addr, sizeof(struct in6_addr)); } rtl += rtap->rta_len; - if(via) { - rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); + if (via) { + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_GATEWAY; - if(via.isV4()) { + if (via.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&via)->sin_addr, sizeof(struct in_addr)); - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&via)->sin6_addr, sizeof(struct in6_addr)); } rtl += rtap->rta_len; - } else if (src) { - rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); + } + else if (src) { + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_SRC; - if(src.isV4()) { + if (src.isV4()) { rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in*)&src)->sin_addr, sizeof(struct in_addr)); - - } else { + } + else { rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &((struct sockaddr_in6*)&src)->sin6_addr, sizeof(struct in6_addr)); } @@ -893,7 +893,7 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c if (ifaceName != NULL) { int interface_index = _indexForInterface(ifaceName); if (interface_index != -1) { - rtap = (struct rtattr *) (((char*)rtap) + rtap->rta_len); + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = RTA_OIF; rtap->rta_len = RTA_LENGTH(sizeof(int)); memcpy(RTA_DATA(rtap), &interface_index, sizeof(int)); @@ -936,7 +936,7 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c close(fd); } -void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) +void LinuxNetLink::addAddress(const InetAddress& addr, const char* iface) { int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd == -1) { @@ -947,16 +947,17 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) _setSocketTimeout(fd); struct sockaddr_nl la; - memset(&la,0,sizeof(la)); + memset(&la, 0, sizeof(la)); la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); if (addr.isV4()) { la.nl_groups = RTMGRP_IPV4_IFADDR; - } else { + } + else { la.nl_groups = RTMGRP_IPV6_IFADDR; } - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (addAddress #1): %s\n", strerror(errno)); close(fd); return; @@ -983,9 +984,10 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) struct nl_adr_req req; bzero(&req, sizeof(struct nl_adr_req)); - struct rtattr *rtap = (struct rtattr *)req.buf;; - if(addr.isV4()) { - struct sockaddr_in *addr_v4 = (struct sockaddr_in*)&addr; + struct rtattr* rtap = (struct rtattr*)req.buf; + ; + if (addr.isV4()) { + struct sockaddr_in* addr_v4 = (struct sockaddr_in*)&addr; rtap->rta_type = IFA_ADDRESS; rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &addr_v4->sin_addr, sizeof(struct in_addr)); @@ -998,24 +1000,25 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) rtl += rtap->rta_len; InetAddress broadcast = addr.broadcast(); - if(broadcast) { - rtap = (struct rtattr*)(((char*)rtap)+rtap->rta_len); - struct sockaddr_in *bcast = (struct sockaddr_in*)&broadcast; + if (broadcast) { + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); + struct sockaddr_in* bcast = (struct sockaddr_in*)&broadcast; rtap->rta_type = IFA_BROADCAST; rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &bcast->sin_addr, sizeof(struct in_addr)); rtl += rtap->rta_len; } - } else { //V6 + } + else { // V6 rtap->rta_type = IFA_ADDRESS; - struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6*)&addr; + struct sockaddr_in6* addr_v6 = (struct sockaddr_in6*)&addr; rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &addr_v6->sin6_addr, sizeof(struct in6_addr)); rtl += rtap->rta_len; } if (iface) { - rtap = (struct rtattr*)(((char*)rtap)+rtap->rta_len); + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = IFA_LABEL; rtap->rta_len = RTA_LENGTH(strlen(iface)); memcpy(RTA_DATA(rtap), iface, strlen(iface)); @@ -1054,7 +1057,7 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) close(fd); } -void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) +void LinuxNetLink::removeAddress(const InetAddress& addr, const char* iface) { int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd == -1) { @@ -1066,13 +1069,14 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) struct sockaddr_nl la; la.nl_family = AF_NETLINK; - la.nl_pid = 0; //getpid(); + la.nl_pid = 0; // getpid(); if (addr.isV4()) { la.nl_groups = RTMGRP_IPV4_IFADDR; - } else { + } + else { la.nl_groups = RTMGRP_IPV6_IFADDR; } - if(bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { + if (bind(fd, (struct sockaddr*)&la, sizeof(struct sockaddr_nl))) { fprintf(stderr, "Error binding RTNETLINK (removeAddress #1): %s\n", strerror(errno)); close(fd); return; @@ -1095,9 +1099,9 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) struct nl_adr_req req; bzero(&req, sizeof(struct nl_adr_req)); - struct rtattr *rtap = (struct rtattr *)req.buf; - if(addr.isV4()) { - struct sockaddr_in *addr_v4 = (struct sockaddr_in*)&addr; + struct rtattr* rtap = (struct rtattr*)req.buf; + if (addr.isV4()) { + struct sockaddr_in* addr_v4 = (struct sockaddr_in*)&addr; rtap->rta_type = IFA_ADDRESS; rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &addr_v4->sin_addr, sizeof(struct in_addr)); @@ -1110,24 +1114,25 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) rtl += rtap->rta_len; InetAddress broadcast = addr.broadcast(); - if(broadcast) { - rtap = (struct rtattr*)(((char*)rtap)+rtap->rta_len); - struct sockaddr_in *bcast = (struct sockaddr_in*)&broadcast; + if (broadcast) { + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); + struct sockaddr_in* bcast = (struct sockaddr_in*)&broadcast; rtap->rta_type = IFA_BROADCAST; rtap->rta_len = RTA_LENGTH(sizeof(struct in_addr)); memcpy(RTA_DATA(rtap), &bcast->sin_addr, sizeof(struct in_addr)); rtl += rtap->rta_len; } - } else { //V6 + } + else { // V6 rtap->rta_type = IFA_ADDRESS; - struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6*)&addr; + struct sockaddr_in6* addr_v6 = (struct sockaddr_in6*)&addr; rtap->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); memcpy(RTA_DATA(rtap), &addr_v6->sin6_addr, sizeof(struct in6_addr)); rtl += rtap->rta_len; } if (iface) { - rtap = (struct rtattr*)(((char*)rtap)+rtap->rta_len); + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); rtap->rta_type = IFA_LABEL; rtap->rta_len = RTA_LENGTH(strlen(iface)); memcpy(RTA_DATA(rtap), iface, strlen(iface)); @@ -1166,18 +1171,19 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) close(fd); } -bool LinuxNetLink::routeIsSet(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifname) +bool LinuxNetLink::routeIsSet(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifname) { Mutex::Lock rl(_routes_m); - const std::set &rs = _routes[target]; - for(std::set::const_iterator ri(rs.begin());ri!=rs.end();++ri) { - if ((ri->via == via)&&(ri->src == src)) { + const std::set& rs = _routes[target]; + for (std::set::const_iterator ri(rs.begin()); ri != rs.end(); ++ri) { + if ((ri->via == via) && (ri->src == src)) { if (ifname) { Mutex::Lock ifl(_if_m); - const iface_entry *ife = _interfaces.get(ri->ifidx); - if ((ife)&&(!strncmp(ife->ifacename,ifname,IFNAMSIZ))) + const iface_entry* ife = _interfaces.get(ri->ifidx); + if ((ife) && (! strncmp(ife->ifacename, ifname, IFNAMSIZ))) return true; - } else { + } + else { return true; } } @@ -1185,15 +1191,15 @@ bool LinuxNetLink::routeIsSet(const InetAddress &target, const InetAddress &via, return false; } -int LinuxNetLink::_indexForInterface(const char *iface) +int LinuxNetLink::_indexForInterface(const char* iface) { Mutex::Lock l(_if_m); int interface_index = -1; Hashtable::Iterator iter(_interfaces); - int *k = NULL; - iface_entry *v = NULL; - while(iter.next(k,v)) { - if(strcmp(iface, v->ifacename) == 0) { + int* k = NULL; + iface_entry* v = NULL; + while (iter.next(k, v)) { + if (strcmp(iface, v->ifacename) == 0) { interface_index = v->index; break; } @@ -1201,6 +1207,6 @@ int LinuxNetLink::_indexForInterface(const char *iface) return interface_index; } -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/LinuxNetLink.hpp b/osdep/LinuxNetLink.hpp index f7d8ba2d4..6f99130ae 100644 --- a/osdep/LinuxNetLink.hpp +++ b/osdep/LinuxNetLink.hpp @@ -18,68 +18,77 @@ #ifdef __LINUX__ -#include -#include -#include - -#include #include #include +#include +#include #include -//#include +#include +// #include +#include "../node/Hashtable.hpp" #include "../node/InetAddress.hpp" #include "../node/MAC.hpp" -#include "Thread.hpp" -#include "../node/Hashtable.hpp" #include "../node/Mutex.hpp" - +#include "Thread.hpp" namespace ZeroTier { /** * Interface with Linux's RTNETLINK */ -class LinuxNetLink -{ -private: +class LinuxNetLink { + private: LinuxNetLink(); ~LinuxNetLink(); -public: + public: struct Route { InetAddress target; InetAddress via; InetAddress src; int ifidx; - inline bool operator==(const Route &r) const - { return ((target == r.target)&&(via == r.via)&&(src == r.src)&&(ifidx == r.ifidx)); } - inline bool operator!=(const Route &r) const - { return (!(*this == r)); } - inline bool operator<(const Route &r) const + inline bool operator==(const Route& r) const + { + return ((target == r.target) && (via == r.via) && (src == r.src) && (ifidx == r.ifidx)); + } + inline bool operator!=(const Route& r) const + { + return (! (*this == r)); + } + inline bool operator<(const Route& r) const { if (target < r.target) { return true; - } else if (target == r.target) { + } + else if (target == r.target) { if (via < r.via) { return true; - } else if (via == r.via) { + } + else if (via == r.via) { if (src < r.src) { return true; - } else if (src == r.src) { + } + else if (src == r.src) { return (ifidx < r.ifidx); } } } return false; } - inline bool operator>(const Route &r) const - { return (r < *this); } - inline bool operator<=(const Route &r) const - { return !(r < *this); } - inline bool operator>=(const Route &r) const - { return !(*this < r); } + inline bool operator>(const Route& r) const + { + return (r < *this); + } + inline bool operator<=(const Route& r) const + { + return ! (r < *this); + } + inline bool operator>=(const Route& r) const + { + return ! (*this < r); + } }; static LinuxNetLink& getInstance() @@ -91,32 +100,32 @@ public: LinuxNetLink(LinuxNetLink const&) = delete; void operator=(LinuxNetLink const&) = delete; - void addRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName); - void delRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName); + void addRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName); + void delRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifaceName); - void addAddress(const InetAddress &addr, const char *iface); - void removeAddress(const InetAddress &addr, const char *iface); + void addAddress(const InetAddress& addr, const char* iface); + void removeAddress(const InetAddress& addr, const char* iface); - bool routeIsSet(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifname); + bool routeIsSet(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* ifname); void threadMain() throw(); -private: + private: int _doRecv(int fd); - void _processMessage(struct nlmsghdr *nlp, int nll); - void _routeAdded(struct nlmsghdr *nlp); - void _routeDeleted(struct nlmsghdr *nlp); - void _linkAdded(struct nlmsghdr *nlp); - void _linkDeleted(struct nlmsghdr *nlp); - void _ipAddressAdded(struct nlmsghdr *nlp); - void _ipAddressDeleted(struct nlmsghdr *nlp); + void _processMessage(struct nlmsghdr* nlp, int nll); + void _routeAdded(struct nlmsghdr* nlp); + void _routeDeleted(struct nlmsghdr* nlp); + void _linkAdded(struct nlmsghdr* nlp); + void _linkDeleted(struct nlmsghdr* nlp); + void _ipAddressAdded(struct nlmsghdr* nlp); + void _ipAddressDeleted(struct nlmsghdr* nlp); void _requestInterfaceList(); void _requestIPv4Routes(); void _requestIPv6Routes(); - int _indexForInterface(const char *iface); + int _indexForInterface(const char* iface); void _setSocketTimeout(int fd, int seconds = 1); @@ -125,14 +134,16 @@ private: uint32_t _seq; - std::map< InetAddress,std::set > _routes; + std::map > _routes; Mutex _routes_m; struct iface_entry { iface_entry() - { memset(this,0,sizeof(iface_entry)); } + { + memset(this, 0, sizeof(iface_entry)); + } int index; - char ifacename[16]; // IFNAMSIZ on Linux == 16 + char ifacename[16]; // IFNAMSIZ on Linux == 16 char mac[18]; char mac_bin[6]; unsigned int mtu; @@ -145,8 +156,8 @@ private: struct sockaddr_nl _la; }; -} +} // namespace ZeroTier #endif -#endif // ZT_LINUX_NETLINK_HPPS \ No newline at end of file +#endif // ZT_LINUX_NETLINK_HPPS \ No newline at end of file diff --git a/osdep/MacDNSHelper.hpp b/osdep/MacDNSHelper.hpp index fafbeec54..69ea58d3b 100644 --- a/osdep/MacDNSHelper.hpp +++ b/osdep/MacDNSHelper.hpp @@ -1,23 +1,23 @@ #ifndef MAC_DNS_HELPER #define MAC_DNS_HELPER -#include #include "../node/InetAddress.hpp" #include "../node/MAC.hpp" +#include + namespace ZeroTier { -class MacDNSHelper -{ -public: - static void setDNS(uint64_t nwid, const char *domain, const std::vector &servers); - static void removeDNS(uint64_t nwid); - static bool addIps4(uint64_t nwid, const MAC mac, const char *dev, const std::vector &addrs); - static bool addIps6(uint64_t nwid, const MAC mac, const char *dev, const std::vector &addrs); - static bool removeIps4(uint64_t nwid); - static bool removeIps6(uint64_t nwid); +class MacDNSHelper { + public: + static void setDNS(uint64_t nwid, const char* domain, const std::vector& servers); + static void removeDNS(uint64_t nwid); + static bool addIps4(uint64_t nwid, const MAC mac, const char* dev, const std::vector& addrs); + static bool addIps6(uint64_t nwid, const MAC mac, const char* dev, const std::vector& addrs); + static bool removeIps4(uint64_t nwid); + static bool removeIps6(uint64_t nwid); }; -} +} // namespace ZeroTier #endif diff --git a/osdep/MacEthernetTap.cpp b/osdep/MacEthernetTap.cpp index fdb584eee..09278855b 100644 --- a/osdep/MacEthernetTap.cpp +++ b/osdep/MacEthernetTap.cpp @@ -15,49 +15,45 @@ #ifdef __APPLE__ -#include "../node/Utils.hpp" -#include "../node/Mutex.hpp" #include "../node/Dictionary.hpp" -#include "OSUtils.hpp" +#include "../node/Mutex.hpp" +#include "../node/Utils.hpp" +#include "MacDNSHelper.hpp" #include "MacEthernetTap.hpp" #include "MacEthernetTapAgent.h" -#include "MacDNSHelper.hpp" +#include "OSUtils.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0); #define MACOS_FETH_MAX_MTU_SYSCTL "net.link.fake.max_mtu" @@ -68,45 +64,45 @@ static bool globalTapInitialized = false; static bool fethMaxMtuAdjusted = false; MacEthernetTap::MacEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *data,unsigned int len), - void *arg) : - _handler(handler), - _arg(arg), - _nwid(nwid), - _homePath(homePath), - _mtu(mtu), - _metric(metric), - _devNo(0), - _agentStdin(-1), - _agentStdout(-1), - _agentStderr(-1), - _agentStdin2(-1), - _agentStdout2(-1), - _agentStderr2(-1), - _agentPid(-1), - _enabled(true), - _lastIfAddrsUpdate(0) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void* data, unsigned int len), + void* arg) + : _handler(handler) + , _arg(arg) + , _nwid(nwid) + , _homePath(homePath) + , _mtu(mtu) + , _metric(metric) + , _devNo(0) + , _agentStdin(-1) + , _agentStdout(-1) + , _agentStderr(-1) + , _agentStdin2(-1) + , _agentStdout2(-1) + , _agentStderr2(-1) + , _agentPid(-1) + , _enabled(true) + , _lastIfAddrsUpdate(0) { - char ethaddr[64],mtustr[16],devnostr[16],devstr[16],metricstr[16]; - OSUtils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); - OSUtils::ztsnprintf(mtustr,sizeof(mtustr),"%u",mtu); - OSUtils::ztsnprintf(metricstr,sizeof(metricstr),"%u",metric); + char ethaddr[64], mtustr[16], devnostr[16], devstr[16], metricstr[16]; + OSUtils::ztsnprintf(ethaddr, sizeof(ethaddr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3], (int)mac[4], (int)mac[5]); + OSUtils::ztsnprintf(mtustr, sizeof(mtustr), "%u", mtu); + OSUtils::ztsnprintf(metricstr, sizeof(metricstr), "%u", metric); std::string agentPath(homePath); agentPath.push_back(ZT_PATH_SEPARATOR); agentPath.append("MacEthernetTapAgent"); - if (!OSUtils::fileExists(agentPath.c_str())) + if (! OSUtils::fileExists(agentPath.c_str())) throw std::runtime_error("MacEthernetTapAgent not present in ZeroTier home"); - Mutex::Lock _gl(globalTapCreateLock); // only make one at a time + Mutex::Lock _gl(globalTapCreateLock); // only make one at a time - if (!fethMaxMtuAdjusted) { + if (! fethMaxMtuAdjusted) { fethMaxMtuAdjusted = true; int old_mtu = 0; size_t old_mtu_len = sizeof(old_mtu); @@ -116,29 +112,30 @@ MacEthernetTap::MacEthernetTap( // Destroy all feth devices on first tap start in case ZeroTier did not exit cleanly last time. // We leave interfaces less than feth100 alone in case something else is messing with feth devices. - if (!globalTapInitialized) { + if (! globalTapInitialized) { globalTapInitialized = true; - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; std::set deleted; - if (!getifaddrs(&ifa)) { - struct ifaddrs *p = ifa; + if (! getifaddrs(&ifa)) { + struct ifaddrs* p = ifa; while (p) { int nameLen = (int)strlen(p->ifa_name); // Delete feth# from feth0 to feth9999, but don't touch >10000. - if ((!strncmp(p->ifa_name,"feth",4))&&(nameLen >= 5)&&(nameLen <= 8)&&(deleted.count(std::string(p->ifa_name)) == 0)) { + if ((! strncmp(p->ifa_name, "feth", 4)) && (nameLen >= 5) && (nameLen <= 8) && (deleted.count(std::string(p->ifa_name)) == 0)) { deleted.insert(std::string(p->ifa_name)); - const char *args[4]; + const char* args[4]; args[0] = "/sbin/ifconfig"; args[1] = p->ifa_name; args[2] = "destroy"; - args[3] = (char *)0; + args[3] = (char*)0; const pid_t pid = vfork(); if (pid == 0) { - execv(args[0],const_cast(args)); + execv(args[0], const_cast(args)); _exit(-1); - } else if (pid > 0) { + } + else if (pid > 0) { int rv = 0; - waitpid(pid,&rv,0); + waitpid(pid, &rv, 0); } } p = p->ifa_next; @@ -148,15 +145,15 @@ MacEthernetTap::MacEthernetTap( } unsigned int devNo = 100 + ((nwid ^ (nwid >> 32) ^ (nwid >> 48)) % 4900); - for(;;) { - OSUtils::ztsnprintf(devnostr,sizeof(devnostr),"%u",devNo); - OSUtils::ztsnprintf(devstr,sizeof(devstr),"feth%u",devNo); + for (;;) { + OSUtils::ztsnprintf(devnostr, sizeof(devnostr), "%u", devNo); + OSUtils::ztsnprintf(devstr, sizeof(devstr), "feth%u", devNo); bool duplicate = false; - struct ifaddrs *ifa = (struct ifaddrs *)0; - if (!getifaddrs(&ifa)) { - struct ifaddrs *p = ifa; + struct ifaddrs* ifa = (struct ifaddrs*)0; + if (! getifaddrs(&ifa)) { + struct ifaddrs* p = ifa; while (p) { - if (!strcmp(p->ifa_name,devstr)) { + if (! strcmp(p->ifa_name, devstr)) { duplicate = true; break; } @@ -168,7 +165,8 @@ MacEthernetTap::MacEthernetTap( devNo = (devNo + 1) % 5000; if (devNo < 100) devNo = 100; - } else { + } + else { _dev = devstr; _devNo = devNo; break; @@ -196,29 +194,31 @@ MacEthernetTap::MacEthernetTap( long apid = (long)fork(); if (apid < 0) { throw std::runtime_error("fork failed"); - } else if (apid == 0) { - ::dup2(agentStdin[0],STDIN_FILENO); - ::dup2(agentStdout[1],STDOUT_FILENO); - ::dup2(agentStderr[1],STDERR_FILENO); + } + else if (apid == 0) { + ::dup2(agentStdin[0], STDIN_FILENO); + ::dup2(agentStdout[1], STDOUT_FILENO); + ::dup2(agentStderr[1], STDERR_FILENO); ::close(agentStdin[0]); ::close(agentStdin[1]); ::close(agentStdout[0]); ::close(agentStdout[1]); ::close(agentStderr[0]); ::close(agentStderr[1]); - ::execl(agentPath.c_str(),agentPath.c_str(),devnostr,ethaddr,mtustr,metricstr,(char *)0); + ::execl(agentPath.c_str(), agentPath.c_str(), devnostr, ethaddr, mtustr, metricstr, (char*)0); ::_exit(-1); - } else { + } + else { _agentPid = apid; // Wait up to 10 seconds for the subprocess to actually create the device. This prevents // things like routes from being created before the device exists. - for(int waitLoops=0;;++waitLoops) { - struct ifaddrs *ifa = (struct ifaddrs *)0; - if (!getifaddrs(&ifa)) { - struct ifaddrs *p = ifa; + for (int waitLoops = 0;; ++waitLoops) { + struct ifaddrs* ifa = (struct ifaddrs*)0; + if (! getifaddrs(&ifa)) { + struct ifaddrs* p = ifa; while (p) { - if ((p->ifa_name)&&(!strcmp(devstr, p->ifa_name))) { + if ((p->ifa_name) && (! strcmp(devstr, p->ifa_name))) { waitLoops = -1; break; } @@ -228,7 +228,8 @@ MacEthernetTap::MacEthernetTap( } if (waitLoops == -1) { break; - } else if (waitLoops >= 100) { // 10 seconds + } + else if (waitLoops >= 100) { // 10 seconds throw std::runtime_error("feth device creation timed out"); } Thread::sleep(100); @@ -241,61 +242,67 @@ MacEthernetTap::MacEthernetTap( MacEthernetTap::~MacEthernetTap() { char tmp[64]; - const char *args[4]; - pid_t pid0,pid1; + const char* args[4]; + pid_t pid0, pid1; MacDNSHelper::removeDNS(_nwid); MacDNSHelper::removeIps4(_nwid); MacDNSHelper::removeIps6(_nwid); Mutex::Lock _gl(globalTapCreateLock); - ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit + ::write(_shutdownSignalPipe[1], "\0", 1); // causes thread to exit int ec = 0; - ::kill(_agentPid,SIGKILL); - ::waitpid(_agentPid,&ec,0); + ::kill(_agentPid, SIGKILL); + ::waitpid(_agentPid, &ec, 0); args[0] = "/sbin/ifconfig"; args[1] = _dev.c_str(); args[2] = "destroy"; - args[3] = (char *)0; + args[3] = (char*)0; pid0 = vfork(); if (pid0 == 0) { - execv(args[0],const_cast(args)); + execv(args[0], const_cast(args)); _exit(-1); } - snprintf(tmp,sizeof(tmp),"feth%u",_devNo + 5000); - //args[0] = "/sbin/ifconfig"; + snprintf(tmp, sizeof(tmp), "feth%u", _devNo + 5000); + // args[0] = "/sbin/ifconfig"; args[1] = tmp; - //args[2] = "destroy"; - //args[3] = (char *)0; + // args[2] = "destroy"; + // args[3] = (char *)0; pid1 = vfork(); if (pid1 == 0) { - execv(args[0],const_cast(args)); + execv(args[0], const_cast(args)); _exit(-1); } if (pid0 > 0) { int rv = 0; - waitpid(pid0,&rv,0); + waitpid(pid0, &rv, 0); } if (pid1 > 0) { int rv = 0; - waitpid(pid1,&rv,0); + waitpid(pid1, &rv, 0); } Thread::join(_thread); } -void MacEthernetTap::setEnabled(bool en) { _enabled = en; } -bool MacEthernetTap::enabled() const { return _enabled; } +void MacEthernetTap::setEnabled(bool en) +{ + _enabled = en; +} +bool MacEthernetTap::enabled() const +{ + return _enabled; +} -bool MacEthernetTap::addIp(const InetAddress &ip) +bool MacEthernetTap::addIp(const InetAddress& ip) { char tmp[128]; - if (!ip) + if (! ip) return false; std::string cmd; @@ -309,18 +316,18 @@ bool MacEthernetTap::addIp(const InetAddress &ip) uint16_t l = (uint16_t)cmd.length(); _putLock.lock(); - write(_agentStdin,&l,2); - write(_agentStdin,cmd.data(),cmd.length()); + write(_agentStdin, &l, 2); + write(_agentStdin, cmd.data(), cmd.length()); _putLock.unlock(); return true; } -bool MacEthernetTap::removeIp(const InetAddress &ip) +bool MacEthernetTap::removeIp(const InetAddress& ip) { char tmp[128]; - if (!ip) + if (! ip) return false; std::string cmd; @@ -334,8 +341,8 @@ bool MacEthernetTap::removeIp(const InetAddress &ip) uint16_t l = (uint16_t)cmd.length(); _putLock.lock(); - write(_agentStdin,&l,2); - write(_agentStdin,cmd.data(),cmd.length()); + write(_agentStdin, &l, 2); + write(_agentStdin, cmd.data(), cmd.length()); _putLock.unlock(); return true; @@ -350,49 +357,49 @@ std::vector MacEthernetTap::ips() const } _lastIfAddrsUpdate = now; - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; std::vector r; - if (!getifaddrs(&ifa)) { - struct ifaddrs *p = ifa; + if (! getifaddrs(&ifa)) { + struct ifaddrs* p = ifa; while (p) { - if ((p->ifa_name)&&(!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)) { - switch(p->ifa_addr->sa_family) { + if ((p->ifa_name) && (! strcmp(p->ifa_name, _dev.c_str())) && (p->ifa_addr)) { + switch (p->ifa_addr->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; - struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; - r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); - } break; + struct sockaddr_in* sin = (struct sockaddr_in*)p->ifa_addr; + struct sockaddr_in* nm = (struct sockaddr_in*)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr), 4, Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; case AF_INET6: { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; - struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + struct sockaddr_in6* sin = (struct sockaddr_in6*)p->ifa_addr; + struct sockaddr_in6* nm = (struct sockaddr_in6*)p->ifa_netmask; uint32_t b[4]; - memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); - r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); - } break; + memcpy(b, nm->sin6_addr.s6_addr, sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr, 16, Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; } } p = p->ifa_next; } freeifaddrs(ifa); } - std::sort(r.begin(),r.end()); - r.erase(std::unique(r.begin(),r.end()),r.end()); + std::sort(r.begin(), r.end()); + r.erase(std::unique(r.begin(), r.end()), r.end()); _ifaddrs = r; return r; } -void MacEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void MacEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { struct iovec iov[3]; unsigned char hdr[15]; uint16_t l; - if ((_agentStdin > 0)&&(len <= _mtu)&&(_enabled)) { + if ((_agentStdin > 0) && (len <= _mtu) && (_enabled)) { hdr[0] = ZT_MACETHERNETTAPAGENT_STDIN_CMD_PACKET; - to.copyTo(hdr + 1,6); - from.copyTo(hdr + 7,6); + to.copyTo(hdr + 1, 6); + from.copyTo(hdr + 7, 6); hdr[13] = (unsigned char)((etherType >> 8) & 0xff); hdr[14] = (unsigned char)(etherType & 0xff); l = (uint16_t)(len + 15); @@ -400,30 +407,35 @@ void MacEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,co iov[0].iov_len = 2; iov[1].iov_base = hdr; iov[1].iov_len = 15; - iov[2].iov_base = const_cast(data); + iov[2].iov_base = const_cast(data); iov[2].iov_len = len; _putLock.lock(); - writev(_agentStdin,iov,3); + writev(_agentStdin, iov, 3); _putLock.unlock(); } } -std::string MacEthernetTap::deviceName() const { return _dev; } -void MacEthernetTap::setFriendlyName(const char *friendlyName) {} +std::string MacEthernetTap::deviceName() const +{ + return _dev; +} +void MacEthernetTap::setFriendlyName(const char* friendlyName) +{ +} -void MacEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void MacEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { std::vector newGroups; - struct ifmaddrs *ifmap = (struct ifmaddrs *)0; - if (!getifmaddrs(&ifmap)) { - struct ifmaddrs *p = ifmap; + struct ifmaddrs* ifmap = (struct ifmaddrs*)0; + if (! getifmaddrs(&ifmap)) { + struct ifmaddrs* p = ifmap; while (p) { if (p->ifma_addr->sa_family == AF_LINK) { - struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; - struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; - if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) - newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + struct sockaddr_dl* in = (struct sockaddr_dl*)p->ifma_name; + struct sockaddr_dl* la = (struct sockaddr_dl*)p->ifma_addr; + if ((la->sdl_alen == 6) && (in->sdl_nlen <= _dev.length()) && (! memcmp(_dev.data(), in->sdl_data, in->sdl_nlen))) + newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen, 6), 0)); } p = p->ifma_next; } @@ -431,18 +443,18 @@ void MacEthernetTap::scanMulticastGroups(std::vector &added,std: } std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - newGroups.erase(std::unique(newGroups.begin(),newGroups.end()),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -457,13 +469,13 @@ void MacEthernetTap::setMtu(unsigned int mtu) cmd.push_back((char)ZT_MACETHERNETTAPAGENT_STDIN_CMD_IFCONFIG); cmd.append("mtu"); cmd.push_back(0); - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%u", mtu); cmd.append(tmp); cmd.push_back(0); uint16_t l = (uint16_t)cmd.length(); _putLock.lock(); - write(_agentStdin,&l,2); - write(_agentStdin,cmd.data(),cmd.length()); + write(_agentStdin, &l, 2); + write(_agentStdin, cmd.data(), cmd.length()); _putLock.unlock(); _mtu = mtu; } @@ -471,61 +483,62 @@ void MacEthernetTap::setMtu(unsigned int mtu) #define ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE 131072 -void MacEthernetTap::threadMain() - throw() +void MacEthernetTap::threadMain() throw() { char agentReadBuf[ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE]; char agentStderrBuf[256]; - fd_set readfds,nullfds; - MAC to,from; + fd_set readfds, nullfds; + MAC to, from; Thread::sleep(250); - const int nfds = std::max(std::max(_shutdownSignalPipe[0],_agentStdout),_agentStderr) + 1; + const int nfds = std::max(std::max(_shutdownSignalPipe[0], _agentStdout), _agentStderr) + 1; long agentReadPtr = 0; - fcntl(_agentStdout,F_SETFL,fcntl(_agentStdout,F_GETFL)|O_NONBLOCK); - fcntl(_agentStderr,F_SETFL,fcntl(_agentStderr,F_GETFL)|O_NONBLOCK); + fcntl(_agentStdout, F_SETFL, fcntl(_agentStdout, F_GETFL) | O_NONBLOCK); + fcntl(_agentStderr, F_SETFL, fcntl(_agentStderr, F_GETFL) | O_NONBLOCK); FD_ZERO(&readfds); FD_ZERO(&nullfds); - for(;;) { - FD_SET(_shutdownSignalPipe[0],&readfds); - FD_SET(_agentStdout,&readfds); - FD_SET(_agentStderr,&readfds); - select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0); + for (;;) { + FD_SET(_shutdownSignalPipe[0], &readfds); + FD_SET(_agentStdout, &readfds); + FD_SET(_agentStderr, &readfds); + select(nfds, &readfds, &nullfds, &nullfds, (struct timeval*)0); - if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) + if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) break; - if (FD_ISSET(_agentStdout,&readfds)) { - long n = (long)read(_agentStdout,agentReadBuf + agentReadPtr,ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE - agentReadPtr); + if (FD_ISSET(_agentStdout, &readfds)) { + long n = (long)read(_agentStdout, agentReadBuf + agentReadPtr, ZT_MACETHERNETTAP_AGENT_READ_BUF_SIZE - agentReadPtr); if (n > 0) { agentReadPtr += n; while (agentReadPtr >= 2) { - long len = *((uint16_t *)agentReadBuf); + long len = *((uint16_t*)agentReadBuf); if (agentReadPtr >= (len + 2)) { - char *msg = agentReadBuf + 2; + char* msg = agentReadBuf + 2; - if ((len > 14)&&(_enabled)) { - to.setTo(msg,6); - from.setTo(msg + 6,6); - _handler(_arg,(void *)0,_nwid,from,to,ntohs(((const uint16_t *)msg)[6]),0,(const void *)(msg + 14),(unsigned int)len - 14); + if ((len > 14) && (_enabled)) { + to.setTo(msg, 6); + from.setTo(msg + 6, 6); + _handler(_arg, (void*)0, _nwid, from, to, ntohs(((const uint16_t*)msg)[6]), 0, (const void*)(msg + 14), (unsigned int)len - 14); } if (agentReadPtr > (len + 2)) { - memmove(agentReadBuf,agentReadBuf + len + 2,agentReadPtr -= (len + 2)); - } else { + memmove(agentReadBuf, agentReadBuf + len + 2, agentReadPtr -= (len + 2)); + } + else { agentReadPtr = 0; } - } else { + } + else { break; } } } } - if (FD_ISSET(_agentStderr,&readfds)) { - read(_agentStderr,agentStderrBuf,sizeof(agentStderrBuf)); + if (FD_ISSET(_agentStderr, &readfds)) { + read(_agentStderr, agentStderrBuf, sizeof(agentStderrBuf)); /* const ssize_t n = read(_agentStderr,agentStderrBuf,sizeof(agentStderrBuf)); if (n > 0) @@ -544,11 +557,11 @@ void MacEthernetTap::threadMain() ::close(_shutdownSignalPipe[1]); } -void MacEthernetTap::setDns(const char *domain, const std::vector &servers) +void MacEthernetTap::setDns(const char* domain, const std::vector& servers) { MacDNSHelper::setDNS(this->_nwid, domain, servers); } -} // namespace ZeroTier +} // namespace ZeroTier -#endif // __APPLE__ +#endif // __APPLE__ diff --git a/osdep/MacEthernetTap.hpp b/osdep/MacEthernetTap.hpp index e9ea0879b..ac774360c 100644 --- a/osdep/MacEthernetTap.hpp +++ b/osdep/MacEthernetTap.hpp @@ -15,55 +15,52 @@ #define ZT_OSXETHERNETTAP_HPP #include "../node/Constants.hpp" -#include "../node/MAC.hpp" #include "../node/InetAddress.hpp" +#include "../node/MAC.hpp" #include "../node/MulticastGroup.hpp" #include "../node/Mutex.hpp" -#include "Thread.hpp" #include "EthernetTap.hpp" - -#include -#include +#include "Thread.hpp" #include +#include +#include #include #include namespace ZeroTier { -class MacEthernetTap : public EthernetTap -{ -public: +class MacEthernetTap : public EthernetTap { + public: MacEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~MacEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); - virtual bool removeIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); + virtual void setFriendlyName(const char* friendlyName); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); virtual void setMtu(unsigned int mtu); - virtual void setDns(const char *domain, const std::vector &servers); + virtual void setDns(const char* domain, const std::vector& servers); - void threadMain() - throw(); + void threadMain() throw(); -private: - void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + private: + void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; uint64_t _nwid; Thread _thread; std::string _homePath; @@ -74,14 +71,13 @@ private: unsigned int _metric; unsigned int _devNo; int _shutdownSignalPipe[2]; - int _agentStdin,_agentStdout,_agentStderr,_agentStdin2,_agentStdout2,_agentStderr2; + int _agentStdin, _agentStdout, _agentStderr, _agentStdin2, _agentStdout2, _agentStderr2; long _agentPid; volatile bool _enabled; mutable std::vector _ifaddrs; mutable uint64_t _lastIfAddrsUpdate; - }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/MacKextEthernetTap.cpp b/osdep/MacKextEthernetTap.cpp index e06560300..b7fa97947 100644 --- a/osdep/MacKextEthernetTap.cpp +++ b/osdep/MacKextEthernetTap.cpp @@ -11,39 +11,36 @@ */ /****/ -#include -#include -#include -#include -#include +#include "MacDNSHelper.hpp" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include +#include #include #include #include #include -#include -#include -#include +#include #include - -#include "MacDNSHelper.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // OSX compile fix... in6_var defines this in a struct which namespaces it for C++ ... why?!? struct prf_ra { @@ -52,15 +49,15 @@ struct prf_ra { u_char reserved : 6; } prf_ra; -#include #include +#include // These are KERNEL_PRIVATE... why? #ifndef SIOCAUTOCONF_START -#define SIOCAUTOCONF_START _IOWR('i', 132, struct in6_ifreq) /* accept rtadvd on this interface */ +#define SIOCAUTOCONF_START _IOWR('i', 132, struct in6_ifreq) /* accept rtadvd on this interface */ #endif #ifndef SIOCAUTOCONF_STOP -#define SIOCAUTOCONF_STOP _IOWR('i', 133, struct in6_ifreq) /* stop accepting rtadv for this interface */ +#define SIOCAUTOCONF_STOP _IOWR('i', 133, struct in6_ifreq) /* stop accepting rtadv for this interface */ #endif // -------------------------------------------------------------------------- @@ -69,33 +66,32 @@ struct prf_ra { // http://www.opensource.apple.com/source/Libinfo/Libinfo-406.17/gen.subproj/getifmaddrs.c?txt // It's here because OSX 10.6 does not have this convenience function. -#define SALIGN (sizeof(uint32_t) - 1) -#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \ -(SALIGN + 1)) -#define MAX_SYSCTL_TRY 5 -#define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA) +#define SALIGN (sizeof(uint32_t) - 1) +#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) +#define MAX_SYSCTL_TRY 5 +#define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA) /* FreeBSD uses NET_RT_IFMALIST and RTM_NEWMADDR from */ /* We can use NET_RT_IFLIST2 and RTM_NEWMADDR2 on Darwin */ -//#define DARWIN_COMPAT +// #define DARWIN_COMPAT -//#ifdef DARWIN_COMPAT +// #ifdef DARWIN_COMPAT #define GIM_SYSCTL_MIB NET_RT_IFLIST2 -#define GIM_RTM_ADDR RTM_NEWMADDR2 -//#else -//#define GIM_SYSCTL_MIB NET_RT_IFMALIST -//#define GIM_RTM_ADDR RTM_NEWMADDR -//#endif +#define GIM_RTM_ADDR RTM_NEWMADDR2 +// #else +// #define GIM_SYSCTL_MIB NET_RT_IFMALIST +// #define GIM_RTM_ADDR RTM_NEWMADDR +// #endif // Not in 10.6 includes so use our own struct _intl_ifmaddrs { - struct _intl_ifmaddrs *ifma_next; - struct sockaddr *ifma_name; - struct sockaddr *ifma_addr; - struct sockaddr *ifma_lladdr; + struct _intl_ifmaddrs* ifma_next; + struct sockaddr* ifma_name; + struct sockaddr* ifma_addr; + struct sockaddr* ifma_lladdr; }; -static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif) +static inline int _intl_getifmaddrs(struct _intl_ifmaddrs** pif) { int icnt = 1; int dcnt = 0; @@ -104,25 +100,25 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif) size_t needed; int mib[6]; int i; - char *buf; - char *data; - char *next; - char *p; - struct ifma_msghdr2 *ifmam; + char* buf; + char* data; + char* next; + char* p; + struct ifma_msghdr2* ifmam; struct _intl_ifmaddrs *ifa, *ift; - struct rt_msghdr *rtm; - struct sockaddr *sa; + struct rt_msghdr* rtm; + struct sockaddr* sa; mib[0] = CTL_NET; mib[1] = PF_ROUTE; - mib[2] = 0; /* protocol */ - mib[3] = 0; /* wildcard address family */ + mib[2] = 0; /* protocol */ + mib[3] = 0; /* wildcard address family */ mib[4] = GIM_SYSCTL_MIB; - mib[5] = 0; /* no flags */ + mib[5] = 0; /* no flags */ do { if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) return (-1); - if ((buf = (char *)malloc(needed)) == NULL) + if ((buf = (char*)malloc(needed)) == NULL) return (-1); if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { @@ -135,21 +131,20 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif) } while (buf == NULL); for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)(void *)next; + rtm = (struct rt_msghdr*)(void*)next; if (rtm->rtm_version != RTM_VERSION) continue; switch (rtm->rtm_type) { case GIM_RTM_ADDR: - ifmam = (struct ifma_msghdr2 *)(void *)rtm; + ifmam = (struct ifma_msghdr2*)(void*)rtm; if ((ifmam->ifmam_addrs & RTA_IFA) == 0) break; icnt++; - p = (char *)(ifmam + 1); + p = (char*)(ifmam + 1); for (i = 0; i < RTAX_MAX; i++) { - if ((RTA_MASKS & ifmam->ifmam_addrs & - (1 << i)) == 0) + if ((RTA_MASKS & ifmam->ifmam_addrs & (1 << i)) == 0) continue; - sa = (struct sockaddr *)(void *)p; + sa = (struct sockaddr*)(void*)p; len = SA_RLEN(sa); dcnt += len; p += len; @@ -158,54 +153,50 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif) } } - data = (char *)malloc(sizeof(struct _intl_ifmaddrs) * icnt + dcnt); + data = (char*)malloc(sizeof(struct _intl_ifmaddrs) * icnt + dcnt); if (data == NULL) { free(buf); return (-1); } - ifa = (struct _intl_ifmaddrs *)(void *)data; + ifa = (struct _intl_ifmaddrs*)(void*)data; data += sizeof(struct _intl_ifmaddrs) * icnt; memset(ifa, 0, sizeof(struct _intl_ifmaddrs) * icnt); ift = ifa; for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)(void *)next; + rtm = (struct rt_msghdr*)(void*)next; if (rtm->rtm_version != RTM_VERSION) continue; switch (rtm->rtm_type) { case GIM_RTM_ADDR: - ifmam = (struct ifma_msghdr2 *)(void *)rtm; + ifmam = (struct ifma_msghdr2*)(void*)rtm; if ((ifmam->ifmam_addrs & RTA_IFA) == 0) break; - p = (char *)(ifmam + 1); + p = (char*)(ifmam + 1); for (i = 0; i < RTAX_MAX; i++) { - if ((RTA_MASKS & ifmam->ifmam_addrs & - (1 << i)) == 0) + if ((RTA_MASKS & ifmam->ifmam_addrs & (1 << i)) == 0) continue; - sa = (struct sockaddr *)(void *)p; + sa = (struct sockaddr*)(void*)p; len = SA_RLEN(sa); switch (i) { case RTAX_GATEWAY: - ift->ifma_lladdr = - (struct sockaddr *)(void *)data; + ift->ifma_lladdr = (struct sockaddr*)(void*)data; memcpy(data, p, len); data += len; break; case RTAX_IFP: - ift->ifma_name = - (struct sockaddr *)(void *)data; + ift->ifma_name = (struct sockaddr*)(void*)data; memcpy(data, p, len); data += len; break; case RTAX_IFA: - ift->ifma_addr = - (struct sockaddr *)(void *)data; + ift->ifma_addr = (struct sockaddr*)(void*)data; memcpy(data, p, len); data += len; break; @@ -228,14 +219,15 @@ static inline int _intl_getifmaddrs(struct _intl_ifmaddrs **pif) ift--; ift->ifma_next = NULL; *pif = ifa; - } else { + } + else { *pif = NULL; free(ifa); } return (0); } -static inline void _intl_freeifmaddrs(struct _intl_ifmaddrs *ifmp) +static inline void _intl_freeifmaddrs(struct _intl_ifmaddrs* ifmp) { free(ifmp); } @@ -243,34 +235,34 @@ static inline void _intl_freeifmaddrs(struct _intl_ifmaddrs *ifmp) // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- -#include +#include "../node/Constants.hpp" +#include "../node/Dictionary.hpp" +#include "../node/Mutex.hpp" +#include "../node/Utils.hpp" +#include "MacKextEthernetTap.hpp" +#include "OSUtils.hpp" + +#include #include #include -#include - -#include "../node/Constants.hpp" -#include "../node/Utils.hpp" -#include "../node/Mutex.hpp" -#include "../node/Dictionary.hpp" -#include "OSUtils.hpp" -#include "MacKextEthernetTap.hpp" +#include // ff:ff:ff:ff:ff:ff with no ADI -static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0); -static inline bool _setIpv6Stuff(const char *ifname,bool performNUD,bool acceptRouterAdverts) +static inline bool _setIpv6Stuff(const char* ifname, bool performNUD, bool acceptRouterAdverts) { struct in6_ndireq nd; struct in6_ifreq ifr; - int s = socket(AF_INET6,SOCK_DGRAM,0); + int s = socket(AF_INET6, SOCK_DGRAM, 0); if (s <= 0) return false; - memset(&nd,0,sizeof(nd)); - strncpy(nd.ifname,ifname,sizeof(nd.ifname)); + memset(&nd, 0, sizeof(nd)); + strncpy(nd.ifname, ifname, sizeof(nd.ifname)); - if (ioctl(s,SIOCGIFINFO_IN6,&nd)) { + if (ioctl(s, SIOCGIFINFO_IN6, &nd)) { close(s); return false; } @@ -279,18 +271,19 @@ static inline bool _setIpv6Stuff(const char *ifname,bool performNUD,bool acceptR if (performNUD) nd.ndi.flags |= ND6_IFF_PERFORMNUD; - else nd.ndi.flags &= ~ND6_IFF_PERFORMNUD; + else + nd.ndi.flags &= ~ND6_IFF_PERFORMNUD; if (oldFlags != (unsigned long)nd.ndi.flags) { - if (ioctl(s,SIOCSIFINFO_FLAGS,&nd)) { + if (ioctl(s, SIOCSIFINFO_FLAGS, &nd)) { close(s); return false; } } - memset(&ifr,0,sizeof(ifr)); - strncpy(ifr.ifr_name,ifname,sizeof(ifr.ifr_name)); - if (ioctl(s,acceptRouterAdverts ? SIOCAUTOCONF_START : SIOCAUTOCONF_STOP,&ifr)) { + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(s, acceptRouterAdverts ? SIOCAUTOCONF_START : SIOCAUTOCONF_STOP, &ifr)) { close(s); return false; } @@ -305,71 +298,76 @@ static long globalTapsRunning = 0; static Mutex globalTapCreateLock; MacKextEthernetTap::MacKextEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *data,unsigned int len), - void *arg) : - _handler(handler), - _arg(arg), - _nwid(nwid), - _homePath(homePath), - _mtu(mtu), - _metric(metric), - _fd(0), - _enabled(true) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void* data, unsigned int len), + void* arg) + : _handler(handler) + , _arg(arg) + , _nwid(nwid) + , _homePath(homePath) + , _mtu(mtu) + , _metric(metric) + , _fd(0) + , _enabled(true) { - char devpath[64],ethaddr[64],mtustr[32],metstr[32],nwids[32]; + char devpath[64], ethaddr[64], mtustr[32], metstr[32], nwids[32]; struct stat stattmp; - OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid); + OSUtils::ztsnprintf(nwids, sizeof(nwids), "%.16llx", nwid); Mutex::Lock _gl(globalTapCreateLock); - if (::stat("/dev/zt0",&stattmp)) { + if (::stat("/dev/zt0", &stattmp)) { long kextpid = (long)fork(); if (kextpid == 0) { ::chdir(homePath); - OSUtils::redirectUnixOutputs("/dev/null",(const char *)0); - ::execl("/sbin/kextload","/sbin/kextload","-q","-repository",homePath,"tap.kext",(const char *)0); + OSUtils::redirectUnixOutputs("/dev/null", (const char*)0); + ::execl("/sbin/kextload", "/sbin/kextload", "-q", "-repository", homePath, "tap.kext", (const char*)0); ::_exit(-1); - } else if (kextpid > 0) { - int exitcode = -1; - ::waitpid(kextpid,&exitcode,0); } - ::usleep(500); // give tap device driver time to start up and try again - if (::stat("/dev/zt0",&stattmp)) + else if (kextpid > 0) { + int exitcode = -1; + ::waitpid(kextpid, &exitcode, 0); + } + ::usleep(500); // give tap device driver time to start up and try again + if (::stat("/dev/zt0", &stattmp)) throw std::runtime_error("/dev/zt# tap devices do not exist and cannot load tap.kext"); } // Try to reopen the last device we had, if we had one and it's still unused. - std::map globalDeviceMap; - FILE *devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),"r"); + std::map globalDeviceMap; + FILE* devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(), "r"); if (devmapf) { char buf[256]; - while (fgets(buf,sizeof(buf),devmapf)) { - char *x = (char *)0; - char *y = (char *)0; - char *saveptr = (char *)0; - for(char *f=Utils::stok(buf,"\r\n=",&saveptr);(f);f=Utils::stok((char *)0,"\r\n=",&saveptr)) { - if (!x) x = f; - else if (!y) y = f; - else break; + while (fgets(buf, sizeof(buf), devmapf)) { + char* x = (char*)0; + char* y = (char*)0; + char* saveptr = (char*)0; + for (char* f = Utils::stok(buf, "\r\n=", &saveptr); (f); f = Utils::stok((char*)0, "\r\n=", &saveptr)) { + if (! x) + x = f; + else if (! y) + y = f; + else + break; } - if ((x)&&(y)&&(x[0])&&(y[0])) + if ((x) && (y) && (x[0]) && (y[0])) globalDeviceMap[x] = y; } fclose(devmapf); } bool recalledDevice = false; - std::map::const_iterator gdmEntry = globalDeviceMap.find(nwids); + std::map::const_iterator gdmEntry = globalDeviceMap.find(nwids); if (gdmEntry != globalDeviceMap.end()) { - std::string devpath("/dev/"); devpath.append(gdmEntry->second); - if (stat(devpath.c_str(),&stattmp) == 0) { - _fd = ::open(devpath.c_str(),O_RDWR); + std::string devpath("/dev/"); + devpath.append(gdmEntry->second); + if (stat(devpath.c_str(), &stattmp) == 0) { + _fd = ::open(devpath.c_str(), O_RDWR); if (_fd > 0) { _dev = gdmEntry->second; recalledDevice = true; @@ -378,15 +376,15 @@ MacKextEthernetTap::MacKextEthernetTap( } // Open the first unused tap device if we didn't recall a previous one. - if (!recalledDevice) { - for(int i=0;i<64;++i) { - OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/zt%d",i); - if (stat(devpath,&stattmp)) + if (! recalledDevice) { + for (int i = 0; i < 64; ++i) { + OSUtils::ztsnprintf(devpath, sizeof(devpath), "/dev/zt%d", i); + if (stat(devpath, &stattmp)) throw std::runtime_error("no more TAP devices available"); - _fd = ::open(devpath,O_RDWR); + _fd = ::open(devpath, O_RDWR); if (_fd > 0) { char foo[16]; - OSUtils::ztsnprintf(foo,sizeof(foo),"zt%d",i); + OSUtils::ztsnprintf(foo, sizeof(foo), "zt%d", i); _dev = foo; break; } @@ -396,43 +394,44 @@ MacKextEthernetTap::MacKextEthernetTap( if (_fd <= 0) throw std::runtime_error("unable to open TAP device or no more devices available"); - if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) { + if (fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL) & ~O_NONBLOCK) == -1) { ::close(_fd); throw std::runtime_error("unable to set flags on file descriptor for TAP device"); } // Configure MAC address and MTU, bring interface up - OSUtils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); - OSUtils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu); - OSUtils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric); + OSUtils::ztsnprintf(ethaddr, sizeof(ethaddr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3], (int)mac[4], (int)mac[5]); + OSUtils::ztsnprintf(mtustr, sizeof(mtustr), "%u", _mtu); + OSUtils::ztsnprintf(metstr, sizeof(metstr), "%u", _metric); long cpid = (long)fork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "lladdr", ethaddr, "mtu", mtustr, "metric", metstr, "up", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); if (exitcode) { ::close(_fd); throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface"); } } - _setIpv6Stuff(_dev.c_str(),true,false); + _setIpv6Stuff(_dev.c_str(), true, false); // Set close-on-exec so that devices cannot persist if we fork/exec for update - fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); + fcntl(_fd, F_SETFD, fcntl(_fd, F_GETFD) | FD_CLOEXEC); ::pipe(_shutdownSignalPipe); ++globalTapsRunning; globalDeviceMap[nwids] = _dev; - devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),"w"); + devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(), "w"); if (devmapf) { gdmEntry = globalDeviceMap.begin(); while (gdmEntry != globalDeviceMap.end()) { - fprintf(devmapf,"%s=%s\n",gdmEntry->first.c_str(),gdmEntry->second.c_str()); + fprintf(devmapf, "%s=%s\n", gdmEntry->first.c_str(), gdmEntry->second.c_str()); ++gdmEntry; } fclose(devmapf); @@ -445,9 +444,9 @@ MacKextEthernetTap::~MacKextEthernetTap() { MacDNSHelper::removeDNS(_nwid); - ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit + ::write(_shutdownSignalPipe[1], "\0", 1); // causes thread to exit Thread::join(_thread); - for (std::thread &t : _rxThreads) { + for (std::thread& t : _rxThreads) { t.join(); } ::close(_fd); @@ -457,18 +456,19 @@ MacKextEthernetTap::~MacKextEthernetTap() { Mutex::Lock _gl(globalTapCreateLock); if (--globalTapsRunning <= 0) { - globalTapsRunning = 0; // sanity check -- should not be possible + globalTapsRunning = 0; // sanity check -- should not be possible char tmp[16384]; - sprintf(tmp,"%s/%s",_homePath.c_str(),"tap.kext"); + sprintf(tmp, "%s/%s", _homePath.c_str(), "tap.kext"); long kextpid = (long)fork(); if (kextpid == 0) { - OSUtils::redirectUnixOutputs("/dev/null",(const char *)0); - ::execl("/sbin/kextunload","/sbin/kextunload",tmp,(const char *)0); + OSUtils::redirectUnixOutputs("/dev/null", (const char*)0); + ::execl("/sbin/kextunload", "/sbin/kextunload", tmp, (const char*)0); ::_exit(-1); - } else if (kextpid > 0) { + } + else if (kextpid > 0) { int exitcode = -1; - ::waitpid(kextpid,&exitcode,0); + ::waitpid(kextpid, &exitcode, 0); } } } @@ -485,40 +485,42 @@ bool MacKextEthernetTap::enabled() const return _enabled; } -bool MacKextEthernetTap::addIp(const InetAddress &ip) +bool MacKextEthernetTap::addIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; long cpid = (long)fork(); if (cpid == 0) { char tmp[128]; - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toString(tmp),"alias",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), (ip.ss_family == AF_INET6) ? "inet6" : "inet", ip.toString(tmp), "alias", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); return (exitcode == 0); - } // else return false... + } // else return false... return false; } -bool MacKextEthernetTap::removeIp(const InetAddress &ip) +bool MacKextEthernetTap::removeIp(const InetAddress& ip) { - if (!ip) + if (! ip) return true; std::vector allIps(ips()); - for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { + for (std::vector::iterator i(allIps.begin()); i != allIps.end(); ++i) { if (*i == ip) { long cpid = (long)fork(); if (cpid == 0) { char tmp[128]; - execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toIpString(tmp),"-alias",(const char *)0); + execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), (ip.ss_family == AF_INET6) ? "inet6" : "inet", ip.toIpString(tmp), "-alias", (const char*)0); _exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - waitpid(cpid,&exitcode,0); + waitpid(cpid, &exitcode, 0); return (exitcode == 0); } } @@ -528,28 +530,28 @@ bool MacKextEthernetTap::removeIp(const InetAddress &ip) std::vector MacKextEthernetTap::ips() const { - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; if (getifaddrs(&ifa)) return std::vector(); std::vector r; - struct ifaddrs *p = ifa; + struct ifaddrs* p = ifa; while (p) { - if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { - switch(p->ifa_addr->sa_family) { + if ((! strcmp(p->ifa_name, _dev.c_str())) && (p->ifa_addr) && (p->ifa_netmask) && (p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { + switch (p->ifa_addr->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; - struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; - r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); - } break; + struct sockaddr_in* sin = (struct sockaddr_in*)p->ifa_addr; + struct sockaddr_in* nm = (struct sockaddr_in*)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr), 4, Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; case AF_INET6: { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; - struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + struct sockaddr_in6* sin = (struct sockaddr_in6*)p->ifa_addr; + struct sockaddr_in6* nm = (struct sockaddr_in6*)p->ifa_netmask; uint32_t b[4]; - memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); - r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); - } break; + memcpy(b, nm->sin6_addr.s6_addr, sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr, 16, Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; } } p = p->ifa_next; @@ -558,22 +560,22 @@ std::vector MacKextEthernetTap::ips() const if (ifa) freeifaddrs(ifa); - std::sort(r.begin(),r.end()); - r.erase(std::unique(r.begin(),r.end()),r.end()); + std::sort(r.begin(), r.end()); + r.erase(std::unique(r.begin(), r.end()), r.end()); return r; } -void MacKextEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void MacKextEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { char putBuf[ZT_MAX_MTU + 64]; - if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) { - to.copyTo(putBuf,6); - from.copyTo(putBuf + 6,6); - *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType); - memcpy(putBuf + 14,data,len); + if ((_fd > 0) && (len <= _mtu) && (_enabled)) { + to.copyTo(putBuf, 6); + from.copyTo(putBuf + 6, 6); + *((uint16_t*)(putBuf + 12)) = htons((uint16_t)etherType); + memcpy(putBuf + 14, data, len); len += 14; - ::write(_fd,putBuf,len); + ::write(_fd, putBuf, len); } } @@ -582,23 +584,23 @@ std::string MacKextEthernetTap::deviceName() const return _dev; } -void MacKextEthernetTap::setFriendlyName(const char *friendlyName) +void MacKextEthernetTap::setFriendlyName(const char* friendlyName) { } -void MacKextEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void MacKextEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { std::vector newGroups; - struct _intl_ifmaddrs *ifmap = (struct _intl_ifmaddrs *)0; - if (!_intl_getifmaddrs(&ifmap)) { - struct _intl_ifmaddrs *p = ifmap; + struct _intl_ifmaddrs* ifmap = (struct _intl_ifmaddrs*)0; + if (! _intl_getifmaddrs(&ifmap)) { + struct _intl_ifmaddrs* p = ifmap; while (p) { if (p->ifma_addr->sa_family == AF_LINK) { - struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; - struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; - if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) - newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + struct sockaddr_dl* in = (struct sockaddr_dl*)p->ifma_name; + struct sockaddr_dl* la = (struct sockaddr_dl*)p->ifma_addr; + if ((la->sdl_alen == 6) && (in->sdl_nlen <= _dev.length()) && (! memcmp(_dev.data(), in->sdl_data, in->sdl_nlen))) + newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen, 6), 0)); } p = p->ifma_next; } @@ -606,18 +608,18 @@ void MacKextEthernetTap::scanMulticastGroups(std::vector &added, } std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - std::unique(newGroups.begin(),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + std::unique(newGroups.begin(), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -631,59 +633,60 @@ void MacKextEthernetTap::setMtu(unsigned int mtu) long cpid = (long)fork(); if (cpid == 0) { char tmp[64]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu); - execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%u", mtu); + execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "mtu", tmp, (const char*)0); _exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - waitpid(cpid,&exitcode,0); + waitpid(cpid, &exitcode, 0); } } } -void MacKextEthernetTap::threadMain() - throw() +void MacKextEthernetTap::threadMain() throw() { - fd_set readfds,nullfds; - MAC to,from; - int n,nfds,r; + fd_set readfds, nullfds; + MAC to, from; + int n, nfds, r; char getBuf[ZT_MAX_MTU + 64]; Thread::sleep(500); FD_ZERO(&readfds); FD_ZERO(&nullfds); - nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1; + nfds = (int)std::max(_shutdownSignalPipe[0], _fd) + 1; r = 0; - for(;;) { - FD_SET(_shutdownSignalPipe[0],&readfds); - FD_SET(_fd,&readfds); - select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0); + for (;;) { + FD_SET(_shutdownSignalPipe[0], &readfds); + FD_SET(_fd, &readfds); + select(nfds, &readfds, &nullfds, &nullfds, (struct timeval*)0); - if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread + if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) // writes to shutdown pipe terminate thread break; - if (FD_ISSET(_fd,&readfds)) { - n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r); + if (FD_ISSET(_fd, &readfds)) { + n = (int)::read(_fd, getBuf + r, sizeof(getBuf) - r); if (n < 0) { - if ((errno != EINTR)&&(errno != ETIMEDOUT)) + if ((errno != EINTR) && (errno != ETIMEDOUT)) break; - } else { + } + else { // Some tap drivers like to send the ethernet frame and the // payload in two chunks, so handle that by accumulating // data until we have at least a frame. r += n; if (r > 14) { - if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms + if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms r = _mtu + 14; if (_enabled) { - to.setTo(getBuf,6); - from.setTo(getBuf + 6,6); - unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]); + to.setTo(getBuf, 6); + from.setTo(getBuf + 6, 6); + unsigned int etherType = ntohs(((const uint16_t*)getBuf)[6]); // TODO: VLAN support - _handler(_arg,(void *)0,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14); + _handler(_arg, (void*)0, _nwid, from, to, etherType, 0, (const void*)(getBuf + 14), r - 14); } r = 0; @@ -693,9 +696,9 @@ void MacKextEthernetTap::threadMain() } } -void MacKextEthernetTap::setDns(const char *domain, const std::vector &servers) +void MacKextEthernetTap::setDns(const char* domain, const std::vector& servers) { MacDNSHelper::setDNS(_nwid, domain, servers); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/MacKextEthernetTap.hpp b/osdep/MacKextEthernetTap.hpp index aede92867..aac51c32f 100644 --- a/osdep/MacKextEthernetTap.hpp +++ b/osdep/MacKextEthernetTap.hpp @@ -14,58 +14,53 @@ #ifndef ZT_MacKextEthernetTap_HPP #define ZT_MacKextEthernetTap_HPP -#include -#include +#include "../node/Constants.hpp" +#include "../node/InetAddress.hpp" +#include "../node/MAC.hpp" +#include "../node/MulticastGroup.hpp" +#include "EthernetTap.hpp" +#include "Thread.hpp" #include +#include +#include #include -#include #include - -#include "../node/Constants.hpp" -#include "../node/MAC.hpp" -#include "../node/InetAddress.hpp" -#include "../node/MulticastGroup.hpp" - -#include "Thread.hpp" -#include "EthernetTap.hpp" +#include namespace ZeroTier { -class MacKextEthernetTap : public EthernetTap -{ -public: +class MacKextEthernetTap : public EthernetTap { + public: MacKextEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~MacKextEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); - virtual bool removeIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); + virtual void setFriendlyName(const char* friendlyName); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); virtual void setMtu(unsigned int mtu); - virtual void setDns(const char *domain, const std::vector &servers); + virtual void setDns(const char* domain, const std::vector& servers); + void threadMain() throw(); - void threadMain() - throw(); - -private: - void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + private: + void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; uint64_t _nwid; Thread _thread; std::string _homePath; @@ -79,6 +74,6 @@ private: std::vector _rxThreads; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 9be2eda11..d5a708c5b 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -20,20 +20,20 @@ #include #ifdef __WINDOWS__ -#include -#include -#include #include +#include +#include +#include #endif #ifdef __UNIX_LIKE__ -#include +#include +#include #include #include #include #include -#include -#include +#include #ifndef ZT_SDK #include #endif @@ -45,11 +45,11 @@ #include #endif -#include +#include "ManagedRoute.hpp" + #include #include - -#include "ManagedRoute.hpp" +#include #ifdef __LINUX__ #include "LinuxNetLink.hpp" #endif @@ -62,7 +62,7 @@ namespace { // Fork a target into two more specific targets e.g. 0.0.0.0/0 -> 0.0.0.0/1, 128.0.0.0/1 // If the target is already maximally-specific, 'right' will be unchanged and 'left' will be 't' -static void _forkTarget(const InetAddress &t,InetAddress &left,InetAddress &right) +static void _forkTarget(const InetAddress& t, InetAddress& left, InetAddress& right) { const unsigned int bits = t.netmaskBits() + 1; left = t; @@ -70,26 +70,28 @@ static void _forkTarget(const InetAddress &t,InetAddress &left,InetAddress &righ if (bits <= 32) { left.setPort(bits); right = t; - reinterpret_cast(&right)->sin_addr.s_addr ^= Utils::hton((uint32_t)(1 << (32 - bits))); + reinterpret_cast(&right)->sin_addr.s_addr ^= Utils::hton((uint32_t)(1 << (32 - bits))); right.setPort(bits); - } else { + } + else { right.zero(); } - } else if (t.ss_family == AF_INET6) { + } + else if (t.ss_family == AF_INET6) { if (bits <= 128) { left.setPort(bits); right = t; - uint8_t *b = reinterpret_cast(reinterpret_cast(&right)->sin6_addr.s6_addr); + uint8_t* b = reinterpret_cast(reinterpret_cast(&right)->sin6_addr.s6_addr); b[bits / 8] ^= 1 << (8 - (bits % 8)); right.setPort(bits); - } else { + } + else { right.zero(); } } } -struct _RTE -{ +struct _RTE { InetAddress target; InetAddress via; char device[128]; @@ -98,11 +100,11 @@ struct _RTE bool isDefault; }; -#ifdef __BSD__ // ------------------------------------------------------------ +#ifdef __BSD__ // ------------------------------------------------------------ #define ZT_ROUTING_SUPPORT_FOUND 1 #ifndef ZT_SDK -static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains) +static std::vector<_RTE> _getRTEs(const InetAddress& target, bool contains) { std::vector<_RTE> rtes; int mib[6]; @@ -114,29 +116,29 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains) mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; - if (!sysctl(mib,6,NULL,&needed,NULL,0)) { + if (! sysctl(mib, 6, NULL, &needed, NULL, 0)) { if (needed <= 0) return rtes; - char *buf = (char *)::malloc(needed); + char* buf = (char*)::malloc(needed); if (buf) { - if (!sysctl(mib,6,buf,&needed,NULL,0)) { - struct rt_msghdr *rtm; - for(char *next=buf,*end=buf+needed;nextrtm_msglen; + if (! sysctl(mib, 6, buf, &needed, NULL, 0)) { + struct rt_msghdr* rtm; + for (char *next = buf, *end = buf + needed; next < end;) { + rtm = (struct rt_msghdr*)next; + char* saptr = (char*)(rtm + 1); + char* saend = next + rtm->rtm_msglen; - InetAddress sa_t,sa_v; + InetAddress sa_t, sa_v; int deviceIndex = -9999; bool isDefault = false; - if (((rtm->rtm_flags & RTF_LLINFO) == 0)&&((rtm->rtm_flags & RTF_HOST) == 0)&&((rtm->rtm_flags & RTF_UP) != 0)&&((rtm->rtm_flags & RTF_MULTICAST) == 0)) { + if (((rtm->rtm_flags & RTF_LLINFO) == 0) && ((rtm->rtm_flags & RTF_HOST) == 0) && ((rtm->rtm_flags & RTF_UP) != 0) && ((rtm->rtm_flags & RTF_MULTICAST) == 0)) { int which = 0; while (saptr < saend) { - struct sockaddr *sa = (struct sockaddr *)saptr; + struct sockaddr* sa = (struct sockaddr*)saptr; unsigned int salen = sa->sa_len; - if (!salen) + if (! salen) break; // Skip missing fields in rtm_addrs bit field @@ -150,32 +152,33 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains) break; rtm->rtm_addrs >>= 1; - switch(which++) { + switch (which++) { case 0: - //printf("RTA_DST\n"); + // printf("RTA_DST\n"); if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - if ((sin6->sin6_addr.s6_addr[0] == 0xfe)&&((sin6->sin6_addr.s6_addr[1] & 0xc0) == 0x80)) { + struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa; + if ((sin6->sin6_addr.s6_addr[0] == 0xfe) && ((sin6->sin6_addr.s6_addr[1] & 0xc0) == 0x80)) { // BSD uses this fucking strange in-band signaling method to encode device scope IDs for IPv6 addresses... probably a holdover from very early versions of the spec. unsigned int interfaceIndex = ((((unsigned int)sin6->sin6_addr.s6_addr[2]) << 8) & 0xff) | (((unsigned int)sin6->sin6_addr.s6_addr[3]) & 0xff); sin6->sin6_addr.s6_addr[2] = 0; sin6->sin6_addr.s6_addr[3] = 0; - if (!sin6->sin6_scope_id) + if (! sin6->sin6_scope_id) sin6->sin6_scope_id = interfaceIndex; } #ifdef __APPLE__ - isDefault = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && !(rtm->rtm_flags & RTF_IFSCOPE); + isDefault = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && ! (rtm->rtm_flags & RTF_IFSCOPE); #endif - } else { - struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; + } + else { + struct sockaddr_in* sin4 = (struct sockaddr_in*)sa; isDefault = sin4->sin_addr.s_addr == 0; } sa_t = *sa; break; case 1: - //printf("RTA_GATEWAY\n"); - switch(sa->sa_family) { + // printf("RTA_GATEWAY\n"); + switch (sa->sa_family) { case AF_LINK: // deviceIndex = (int)((const struct sockaddr_dl *)sa)->sdl_index; case AF_INET: @@ -185,53 +188,54 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains) } break; case 2: { - //printf("RTA_NETMASK\n"); + // printf("RTA_NETMASK\n"); if (sa_t.ss_family == AF_INET6) { salen = sizeof(struct sockaddr_in6); unsigned int bits = 0; - for(int i=0;i<16;++i) { - unsigned char c = (unsigned char)((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[i]; + for (int i = 0; i < 16; ++i) { + unsigned char c = (unsigned char)((const struct sockaddr_in6*)sa)->sin6_addr.s6_addr[i]; if (c == 0xff) bits += 8; - else break; + else + break; } sa_t.setPort(bits); - } else if (sa_t.ss_family == AF_INET) { - salen = sizeof(struct sockaddr_in); - sa_t.setPort((unsigned int)Utils::countBits((uint32_t)((const struct sockaddr_in *)sa)->sin_addr.s_addr)); } - } break; - /* - case 3: - //printf("RTA_GENMASK\n"); - break; - case 4: - //printf("RTA_IFP\n"); - break; - case 5: - //printf("RTA_IFA\n"); - break; - case 6: - //printf("RTA_AUTHOR\n"); - break; - */ + else if (sa_t.ss_family == AF_INET) { + salen = sizeof(struct sockaddr_in); + sa_t.setPort((unsigned int)Utils::countBits((uint32_t)((const struct sockaddr_in*)sa)->sin_addr.s_addr)); + } + } break; + /* + case 3: + //printf("RTA_GENMASK\n"); + break; + case 4: + //printf("RTA_IFP\n"); + break; + case 5: + //printf("RTA_IFA\n"); + break; + case 6: + //printf("RTA_AUTHOR\n"); + break; + */ } saptr += salen; } - deviceIndex = rtm->rtm_index; - - if (((contains)&&(sa_t.containsAddress(target)))||(sa_t == target)) { + if (((contains) && (sa_t.containsAddress(target))) || (sa_t == target)) { rtes.push_back(_RTE()); rtes.back().target = sa_t; rtes.back().via = sa_v; rtes.back().isDefault = isDefault; if (deviceIndex >= 0) { - if_indextoname(deviceIndex,rtes.back().device); - } else { + if_indextoname(deviceIndex, rtes.back().device); + } + else { rtes.back().device[0] = (char)0; } rtes.back().metric = ((int)rtm->rtm_rmx.rmx_hopcount < 0) ? 0 : (int)rtm->rtm_rmx.rmx_hopcount; @@ -250,60 +254,64 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains) } #endif -static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *ifscope,const char *localInterface) +static void _routeCmd(const char* op, const InetAddress& target, const InetAddress& via, const char* ifscope, const char* localInterface) { // char f1[1024],f2[1024]; printf("cmd %s %s %s %s %s\n",op,target.toString(f1),via.toString(f2),ifscope,localInterface); long p = (long)fork(); if (p > 0) { int exitcode = -1; - ::waitpid(p,&exitcode,0); - } else if (p == 0) { + ::waitpid(p, &exitcode, 0); + } + else if (p == 0) { ::close(STDOUT_FILENO); ::close(STDERR_FILENO); char ttmp[64]; char iptmp[64]; if (via) { - if ((ifscope)&&(ifscope[0])) { + if ((ifscope) && (ifscope[0])) { #ifdef ZT_TRACE - fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s" ZT_EOL_S, ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp)); + fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s" ZT_EOL_S, ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp)); #endif - ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp),(const char *)0); - } else { -#ifdef ZT_TRACE - fprintf(stderr, "DEBUG: route %s %s %s %s" ZT_EOL_S, op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp)); -#endif - ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp),(const char *)0); + ::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, "-ifscope", ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp), (const char*)0); } - } else if ((localInterface)&&(localInterface[0])) { - if ((ifscope)&&(ifscope[0])) { + else { #ifdef ZT_TRACE - fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s -interface %s" ZT_EOL_S, op, ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),localInterface); + fprintf(stderr, "DEBUG: route %s %s %s %s" ZT_EOL_S, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp)); #endif - ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),"-interface",localInterface,(const char *)0); - } else { + ::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), via.toIpString(iptmp), (const char*)0); + } + } + else if ((localInterface) && (localInterface[0])) { + if ((ifscope) && (ifscope[0])) { #ifdef ZT_TRACE - fprintf(stderr, "DEBUG: route %s %s %s -interface %s" ZT_EOL_S, op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),localInterface); + fprintf(stderr, "DEBUG: route %s -ifscope %s %s %s -interface %s" ZT_EOL_S, op, ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), localInterface); #endif - ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),"-interface",localInterface,(const char *)0); + ::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, "-ifscope", ifscope, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), "-interface", localInterface, (const char*)0); + } + else { +#ifdef ZT_TRACE + fprintf(stderr, "DEBUG: route %s %s %s -interface %s" ZT_EOL_S, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), localInterface); +#endif + ::execl(ZT_BSD_ROUTE_CMD, ZT_BSD_ROUTE_CMD, op, ((target.ss_family == AF_INET6) ? "-inet6" : "-inet"), target.toString(ttmp), "-interface", localInterface, (const char*)0); } } ::_exit(-1); } } -#endif // __BSD__ ------------------------------------------------------------ +#endif // __BSD__ ------------------------------------------------------------ -#ifdef __LINUX__ // ---------------------------------------------------------- +#ifdef __LINUX__ // ---------------------------------------------------------- #define ZT_ROUTING_SUPPORT_FOUND 1 // This has been replaced by LinuxNetLink -#endif // __LINUX__ ---------------------------------------------------------- +#endif // __LINUX__ ---------------------------------------------------------- -#ifdef __WINDOWS__ // -------------------------------------------------------- +#ifdef __WINDOWS__ // -------------------------------------------------------- #define ZT_ROUTING_SUPPORT_FOUND 1 -static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &interfaceIndex,const InetAddress &target,const InetAddress &via) +static bool _winRoute(bool del, const NET_LUID& interfaceLuid, const NET_IFINDEX& interfaceIndex, const InetAddress& target, const InetAddress& via) { MIB_IPFORWARD_ROW2 rtrow; InitializeIpForwardEntry(&rtrow); @@ -312,22 +320,24 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX & if (target.ss_family == AF_INET) { rtrow.DestinationPrefix.Prefix.si_family = AF_INET; rtrow.DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET; - rtrow.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&target)->sin_addr.S_un.S_addr; + rtrow.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&target)->sin_addr.S_un.S_addr; if (via.ss_family == AF_INET) { rtrow.NextHop.si_family = AF_INET; rtrow.NextHop.Ipv4.sin_family = AF_INET; - rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&via)->sin_addr.S_un.S_addr; + rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&via)->sin_addr.S_un.S_addr; } - } else if (target.ss_family == AF_INET6) { + } + else if (target.ss_family == AF_INET6) { rtrow.DestinationPrefix.Prefix.si_family = AF_INET6; rtrow.DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6; - memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,reinterpret_cast(&target)->sin6_addr.u.Byte,16); + memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&target)->sin6_addr.u.Byte, 16); if (via.ss_family == AF_INET6) { rtrow.NextHop.si_family = AF_INET6; rtrow.NextHop.Ipv6.sin6_family = AF_INET6; - memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte,reinterpret_cast(&via)->sin6_addr.u.Byte,16); + memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&via)->sin6_addr.u.Byte, 16); } - } else { + } + else { return false; } rtrow.DestinationPrefix.PrefixLength = target.netmaskBits(); @@ -344,19 +354,22 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX & rtrow.Origin = NlroManual; if (del) { return (DeleteIpForwardEntry2(&rtrow) == NO_ERROR); - } else { + } + else { NTSTATUS r = CreateIpForwardEntry2(&rtrow); if (r == NO_ERROR) { return true; - } else if (r == ERROR_OBJECT_ALREADY_EXISTS) { + } + else if (r == ERROR_OBJECT_ALREADY_EXISTS) { return (SetIpForwardEntry2(&rtrow) == NO_ERROR); - } else { + } + else { return false; } } } -static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &interfaceIndex, const InetAddress &target, const InetAddress &via) +static bool _winHasRoute(const NET_LUID& interfaceLuid, const NET_IFINDEX& interfaceIndex, const InetAddress& target, const InetAddress& via) { MIB_IPFORWARD_ROW2 rtrow; InitializeIpForwardEntry(&rtrow); @@ -365,22 +378,24 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter if (target.ss_family == AF_INET) { rtrow.DestinationPrefix.Prefix.si_family = AF_INET; rtrow.DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET; - rtrow.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&target)->sin_addr.S_un.S_addr; + rtrow.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&target)->sin_addr.S_un.S_addr; if (via.ss_family == AF_INET) { rtrow.NextHop.si_family = AF_INET; rtrow.NextHop.Ipv4.sin_family = AF_INET; - rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&via)->sin_addr.S_un.S_addr; + rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast(&via)->sin_addr.S_un.S_addr; } - } else if (target.ss_family == AF_INET6) { + } + else if (target.ss_family == AF_INET6) { rtrow.DestinationPrefix.Prefix.si_family = AF_INET6; rtrow.DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6; - memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&target)->sin6_addr.u.Byte, 16); + memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&target)->sin6_addr.u.Byte, 16); if (via.ss_family == AF_INET6) { rtrow.NextHop.si_family = AF_INET6; rtrow.NextHop.Ipv6.sin6_family = AF_INET6; - memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&via)->sin6_addr.u.Byte, 16); + memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte, reinterpret_cast(&via)->sin6_addr.u.Byte, 16); } - } else { + } + else { return false; } rtrow.DestinationPrefix.PrefixLength = target.netmaskBits(); @@ -388,15 +403,16 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter return (GetIpForwardEntry2(&rtrow) == NO_ERROR); } -#endif // __WINDOWS__ -------------------------------------------------------- +#endif // __WINDOWS__ -------------------------------------------------------- #ifndef ZT_ROUTING_SUPPORT_FOUND -#error "ManagedRoute.cpp has no support for managing routes on this platform! You'll need to check and see if one of the existing ones will work and make sure proper defines are set, or write one. Please do a GitHub pull request if you do this for a new OS." +#error \ + "ManagedRoute.cpp has no support for managing routes on this platform! You'll need to check and see if one of the existing ones will work and make sure proper defines are set, or write one. Please do a GitHub pull request if you do this for a new OS." #endif -} // anonymous namespace +} // anonymous namespace -ManagedRoute::ManagedRoute(const InetAddress &target,const InetAddress &via,const InetAddress &src,const char *device) +ManagedRoute::ManagedRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* device) { _target = target; _via = via; @@ -404,17 +420,19 @@ ManagedRoute::ManagedRoute(const InetAddress &target,const InetAddress &via,cons if (_via.ss_family == AF_INET) { _via.setPort(32); - } else if (_via.ss_family == AF_INET6) { + } + else if (_via.ss_family == AF_INET6) { _via.setPort(128); } if (_src.ss_family == AF_INET) { _src.setPort(32); - } else if (_src.ss_family == AF_INET6) { + } + else if (_src.ss_family == AF_INET6) { _src.setPort(128); } - Utils::scopy(_device,sizeof(_device),device); + Utils::scopy(_device, sizeof(_device), device); _systemDevice[0] = (char)0; } @@ -440,26 +458,27 @@ bool ManagedRoute::sync() { #ifdef __WINDOWS__ NET_LUID interfaceLuid; - interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute + interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute NET_IFINDEX interfaceIndex = -1; - if (ConvertInterfaceLuidToIndex(&interfaceLuid,&interfaceIndex) != NO_ERROR) + if (ConvertInterfaceLuidToIndex(&interfaceLuid, &interfaceIndex) != NO_ERROR) return false; #endif - InetAddress leftt,rightt; - if (_target.netmaskBits() == 0) // bifurcate only the default route - _forkTarget(_target,leftt,rightt); - else leftt = _target; + InetAddress leftt, rightt; + if (_target.netmaskBits() == 0) // bifurcate only the default route + _forkTarget(_target, leftt, rightt); + else + leftt = _target; -#ifdef __BSD__ // ------------------------------------------------------------ +#ifdef __BSD__ // ------------------------------------------------------------ if (_device[0]) { bool haveDevice = false; - struct ifaddrs *ifa = (struct ifaddrs *)0; - if (!getifaddrs(&ifa)) { - struct ifaddrs *p = ifa; + struct ifaddrs* ifa = (struct ifaddrs*)0; + if (! getifaddrs(&ifa)) { + struct ifaddrs* p = ifa; while (p) { - if ((p->ifa_name)&&(!strcmp(_device, p->ifa_name))) { + if ((p->ifa_name) && (! strcmp(_device, p->ifa_name))) { haveDevice = true; break; } @@ -467,112 +486,113 @@ bool ManagedRoute::sync() } freeifaddrs(ifa); } - if (!haveDevice) + if (! haveDevice) return false; } - std::vector<_RTE> rtes(_getRTEs(_target,false)); + std::vector<_RTE> rtes(_getRTEs(_target, false)); bool hasRoute = false; - for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) { - hasRoute = _target == r->target && _via.ipOnly() == r->via.ipOnly() && (strcmp(r->device,_device) == 0); - if (hasRoute) { break; } + for (std::vector<_RTE>::iterator r(rtes.begin()); r != rtes.end(); ++r) { + hasRoute = _target == r->target && _via.ipOnly() == r->via.ipOnly() && (strcmp(r->device, _device) == 0); + if (hasRoute) { + break; + } } // char buf[255]; // fprintf(stderr, "hasRoute %d %s\n", !!hasRoute, _target.toString(buf)); - - if (!hasRoute) { - if (_target && _target.netmaskBits() == 0) { // Allow Default + if (! hasRoute) { + if (_target && _target.netmaskBits() == 0) { // Allow Default InetAddress newSystemVia; char newSystemDevice[128]; newSystemDevice[0] = (char)0; // if our routes got deleted // delete the systemd via that we had added with -ifscope - if (_systemVia && !!_systemDevice[0]) { - _routeCmd("delete",_target,_systemVia,_systemDevice,(const char *)0); + if (_systemVia && ! ! _systemDevice[0]) { + _routeCmd("delete", _target, _systemVia, _systemDevice, (const char*)0); } _systemVia = newSystemVia; - Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + Utils::scopy(_systemDevice, sizeof(_systemDevice), newSystemDevice); // If macos has a network hiccup, it deletes what the route we set, and it's own physical routes. // if !hasRoute (our 0.0.0.0 has been deleted), the OS has changed stuff // So don't assume _systemX are valid anymore. Always get for _system{Via,Device} // Find system default route that this route should override // We need to put it back when default route is turned off - for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) { + for (std::vector<_RTE>::iterator r(rtes.begin()); r != rtes.end(); ++r) { if (r->via) { - if ( r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) { - + if (r->isDefault == 1 && (strcmp(r->device, _device) != 0)) { // char buf[255]; // fprintf(stderr, "system device1 %s %s\n", r->via.toString(buf), r->device); newSystemVia = r->via; - Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device); + Utils::scopy(newSystemDevice, sizeof(newSystemDevice), r->device); break; } } } - if (newSystemVia) { _systemVia = newSystemVia; } + if (newSystemVia) { + _systemVia = newSystemVia; + } if (newSystemDevice[0]) { - Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice); + Utils::scopy(_systemDevice, sizeof(_systemDevice), newSystemDevice); } // if there's no newSystemVia, the OS might not have // ipv4 or ipv6 connectivity. // we should still add our ZeroTier ipv4 or 6 routes though - if (!!_systemVia && !!_systemDevice[0]) { - _routeCmd("delete",_target,_systemVia,(const char *)0,(const char *)0); + if (! ! _systemVia && ! ! _systemDevice[0]) { + _routeCmd("delete", _target, _systemVia, (const char*)0, (const char*)0); } - _routeCmd("add",_target,_via,(const char *)0,(const char *)0); + _routeCmd("add", _target, _via, (const char*)0, (const char*)0); - if (!!_systemVia && !!_systemDevice[0]) { - _routeCmd("add",_target,_systemVia,_systemDevice,(const char *)0); + if (! ! _systemVia && ! ! _systemDevice[0]) { + _routeCmd("add", _target, _systemVia, _systemDevice, (const char*)0); } _applied[_target] = true; - - } else { + } + else { // Do Non-Default route commands _applied[_target] = true; - _routeCmd("add",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device); + _routeCmd("add", leftt, _via, (const char*)0, (_via) ? (const char*)0 : _device); } } +#endif // __BSD__ ------------------------------------------------------------ -#endif // __BSD__ ------------------------------------------------------------ +#ifdef __LINUX__ // ---------------------------------------------------------- -#ifdef __LINUX__ // ---------------------------------------------------------- - - if ((leftt)&&(!LinuxNetLink::getInstance().routeIsSet(leftt,_via,_src,_device))) { - _applied[leftt] = false; // boolean unused + if ((leftt) && (! LinuxNetLink::getInstance().routeIsSet(leftt, _via, _src, _device))) { + _applied[leftt] = false; // boolean unused LinuxNetLink::getInstance().addRoute(leftt, _via, _src, _device); } - if ((rightt)&&(!LinuxNetLink::getInstance().routeIsSet(rightt,_via,_src,_device))) { - _applied[rightt] = false; // boolean unused + if ((rightt) && (! LinuxNetLink::getInstance().routeIsSet(rightt, _via, _src, _device))) { + _applied[rightt] = false; // boolean unused LinuxNetLink::getInstance().addRoute(rightt, _via, _src, _device); } -#endif // __LINUX__ ---------------------------------------------------------- +#endif // __LINUX__ ---------------------------------------------------------- -#ifdef __WINDOWS__ // -------------------------------------------------------- +#ifdef __WINDOWS__ // -------------------------------------------------------- - if ( (!_applied.count(leftt)) || (!_winHasRoute(interfaceLuid,interfaceIndex,leftt,_via)) ) { - _applied[leftt] = false; // boolean unused - _winRoute(false,interfaceLuid,interfaceIndex,leftt,_via); + if ((! _applied.count(leftt)) || (! _winHasRoute(interfaceLuid, interfaceIndex, leftt, _via))) { + _applied[leftt] = false; // boolean unused + _winRoute(false, interfaceLuid, interfaceIndex, leftt, _via); } - if ( (rightt) && ( (!_applied.count(rightt)) || (!_winHasRoute(interfaceLuid,interfaceIndex,rightt,_via)) ) ) { - _applied[rightt] = false; // boolean unused - _winRoute(false,interfaceLuid,interfaceIndex,rightt,_via); + if ((rightt) && ((! _applied.count(rightt)) || (! _winHasRoute(interfaceLuid, interfaceIndex, rightt, _via)))) { + _applied[rightt] = false; // boolean unused + _winRoute(false, interfaceLuid, interfaceIndex, rightt, _via); } -#endif // __WINDOWS__ -------------------------------------------------------- +#endif // __WINDOWS__ -------------------------------------------------------- return true; } @@ -582,39 +602,39 @@ void ManagedRoute::remove() { #ifdef __WINDOWS__ NET_LUID interfaceLuid; - interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute + interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute NET_IFINDEX interfaceIndex = -1; - if (ConvertInterfaceLuidToIndex(&interfaceLuid,&interfaceIndex) != NO_ERROR) + if (ConvertInterfaceLuidToIndex(&interfaceLuid, &interfaceIndex) != NO_ERROR) return; #endif #ifdef __BSD__ -#endif // __BSD__ ------------------------------------------------------------ +#endif // __BSD__ ------------------------------------------------------------ - for(std::map::iterator r(_applied.begin());r!=_applied.end();++r) { -#ifdef __BSD__ // ------------------------------------------------------------ + for (std::map::iterator r(_applied.begin()); r != _applied.end(); ++r) { +#ifdef __BSD__ // ------------------------------------------------------------ if (_target && _target.netmaskBits() == 0) { - _routeCmd("delete",_target,_via,(const char *)0,(const char *)0); + _routeCmd("delete", _target, _via, (const char*)0, (const char*)0); if (_systemVia && _systemDevice[0]) { - _routeCmd("delete",_target,_systemVia,_systemDevice,(const char *)0); - - _routeCmd("add",_target,_systemVia,(const char *)0,(const char *)0); + _routeCmd("delete", _target, _systemVia, _systemDevice, (const char*)0); + _routeCmd("add", _target, _systemVia, (const char*)0, (const char*)0); } - } else { - _routeCmd("delete",_target,_via, (const char *)0, _via ? (const char *)0 : _device); - } - break; -#endif // __BSD__ ------------------------------------------------------------ + } + else { + _routeCmd("delete", _target, _via, (const char*)0, _via ? (const char*)0 : _device); + } + break; +#endif // __BSD__ ------------------------------------------------------------ -#ifdef __LINUX__ // ---------------------------------------------------------- +#ifdef __LINUX__ // ---------------------------------------------------------- //_routeCmd("del",r->first,_via,(_via) ? (const char *)0 : _device); - LinuxNetLink::getInstance().delRoute(r->first,_via,_src,(_via) ? (const char *)0 : _device); -#endif // __LINUX__ ---------------------------------------------------------- + LinuxNetLink::getInstance().delRoute(r->first, _via, _src, (_via) ? (const char*)0 : _device); +#endif // __LINUX__ ---------------------------------------------------------- -#ifdef __WINDOWS__ // -------------------------------------------------------- - _winRoute(true,interfaceLuid,interfaceIndex,r->first,_via); -#endif // __WINDOWS__ -------------------------------------------------------- +#ifdef __WINDOWS__ // -------------------------------------------------------- + _winRoute(true, interfaceLuid, interfaceIndex, r->first, _via); +#endif // __WINDOWS__ -------------------------------------------------------- } _target.zero(); @@ -625,4 +645,4 @@ void ManagedRoute::remove() _applied.clear(); } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/ManagedRoute.hpp b/osdep/ManagedRoute.hpp index 4cadedaa7..e30be8263 100644 --- a/osdep/ManagedRoute.hpp +++ b/osdep/ManagedRoute.hpp @@ -14,29 +14,27 @@ #ifndef ZT_MANAGEDROUTE_HPP #define ZT_MANAGEDROUTE_HPP +#include "../node/AtomicCounter.hpp" +#include "../node/InetAddress.hpp" +#include "../node/SharedPtr.hpp" +#include "../node/Utils.hpp" + +#include +#include #include #include - -#include "../node/InetAddress.hpp" -#include "../node/Utils.hpp" -#include "../node/SharedPtr.hpp" -#include "../node/AtomicCounter.hpp" - -#include #include -#include namespace ZeroTier { /** * A ZT-managed route that used C++ RAII semantics to automatically clean itself up on deallocate */ -class ManagedRoute -{ +class ManagedRoute { friend class SharedPtr; -public: - ManagedRoute(const InetAddress &target,const InetAddress &via,const InetAddress &src,const char *device); + public: + ManagedRoute(const InetAddress& target, const InetAddress& via, const InetAddress& src, const char* device); ~ManagedRoute(); /** @@ -58,26 +56,43 @@ public: */ void remove(); - inline const InetAddress &target() const { return _target; } - inline const InetAddress &via() const { return _via; } - inline const InetAddress &src() const { return _src; } - inline const char *device() const { return _device; } + inline const InetAddress& target() const + { + return _target; + } + inline const InetAddress& via() const + { + return _via; + } + inline const InetAddress& src() const + { + return _src; + } + inline const char* device() const + { + return _device; + } -private: - ManagedRoute(const ManagedRoute &) {} - inline ManagedRoute &operator=(const ManagedRoute &) { return *this; } + private: + ManagedRoute(const ManagedRoute&) + { + } + inline ManagedRoute& operator=(const ManagedRoute&) + { + return *this; + } InetAddress _target; InetAddress _via; InetAddress _src; - InetAddress _systemVia; // for route overrides - std::map _applied; // routes currently applied + InetAddress _systemVia; // for route overrides + std::map _applied; // routes currently applied char _device[128]; - char _systemDevice[128]; // for route overrides + char _systemDevice[128]; // for route overrides AtomicCounter __refCount; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/NeighborDiscovery.cpp b/osdep/NeighborDiscovery.cpp index 5e03282d9..dd2114a3d 100644 --- a/osdep/NeighborDiscovery.cpp +++ b/osdep/NeighborDiscovery.cpp @@ -12,248 +12,240 @@ /****/ #include "NeighborDiscovery.hpp" -#include "OSUtils.hpp" #include "../include/ZeroTierOne.h" +#include "OSUtils.hpp" #include namespace ZeroTier { -uint16_t calc_checksum (uint16_t *addr, int len) +uint16_t calc_checksum(uint16_t* addr, int len) { - int count = len; - uint32_t sum = 0; - uint16_t answer = 0; + int count = len; + uint32_t sum = 0; + uint16_t answer = 0; - // Sum up 2-byte values until none or only one byte left. - while (count > 1) { - sum += *(addr++); - count -= 2; - } + // Sum up 2-byte values until none or only one byte left. + while (count > 1) { + sum += *(addr++); + count -= 2; + } - // Add left-over byte, if any. - if (count > 0) { - sum += *(uint8_t *) addr; - } + // Add left-over byte, if any. + if (count > 0) { + sum += *(uint8_t*)addr; + } - // Fold 32-bit sum into 16 bits; we lose information by doing this, - // increasing the chances of a collision. - // sum = (lower 16 bits) + (upper 16 bits shifted right 16 bits) - while (sum >> 16) { - sum = (sum & 0xffff) + (sum >> 16); - } + // Fold 32-bit sum into 16 bits; we lose information by doing this, + // increasing the chances of a collision. + // sum = (lower 16 bits) + (upper 16 bits shifted right 16 bits) + while (sum >> 16) { + sum = (sum & 0xffff) + (sum >> 16); + } - // Checksum is one's compliment of sum. - answer = ~sum; + // Checksum is one's compliment of sum. + answer = ~sum; - return (answer); + return (answer); } struct _pseudo_header { - uint8_t sourceAddr[16]; - uint8_t targetAddr[16]; - uint32_t length; - uint8_t zeros[3]; - uint8_t next; // 58 + uint8_t sourceAddr[16]; + uint8_t targetAddr[16]; + uint32_t length; + uint8_t zeros[3]; + uint8_t next; // 58 }; struct _option { - _option(int optionType) - : type(optionType) - , length(8) - { - memset(mac, 0, sizeof(mac)); - } + _option(int optionType) : type(optionType), length(8) + { + memset(mac, 0, sizeof(mac)); + } - uint8_t type; - uint8_t length; - uint8_t mac[6]; + uint8_t type; + uint8_t length; + uint8_t mac[6]; }; struct _neighbor_solicitation { - _neighbor_solicitation() - : type(135) - , code(0) - , checksum(0) - , option(1) - { - memset(&reserved, 0, sizeof(reserved)); - memset(target, 0, sizeof(target)); - } + _neighbor_solicitation() : type(135), code(0), checksum(0), option(1) + { + memset(&reserved, 0, sizeof(reserved)); + memset(target, 0, sizeof(target)); + } - void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp) { - _pseudo_header ph; - memset(&ph, 0, sizeof(_pseudo_header)); - const sockaddr_in6 *src = (const sockaddr_in6*)&sourceIp; - const sockaddr_in6 *dest = (const sockaddr_in6*)&destIp; + void calculateChecksum(const sockaddr_storage& sourceIp, const sockaddr_storage& destIp) + { + _pseudo_header ph; + memset(&ph, 0, sizeof(_pseudo_header)); + const sockaddr_in6* src = (const sockaddr_in6*)&sourceIp; + const sockaddr_in6* dest = (const sockaddr_in6*)&destIp; - memcpy(ph.sourceAddr, &src->sin6_addr, sizeof(struct in6_addr)); - memcpy(ph.targetAddr, &dest->sin6_addr, sizeof(struct in6_addr)); - ph.next = 58; - ph.length = htonl(sizeof(_neighbor_solicitation)); + memcpy(ph.sourceAddr, &src->sin6_addr, sizeof(struct in6_addr)); + memcpy(ph.targetAddr, &dest->sin6_addr, sizeof(struct in6_addr)); + ph.next = 58; + ph.length = htonl(sizeof(_neighbor_solicitation)); - size_t len = sizeof(_pseudo_header) + sizeof(_neighbor_solicitation); - uint8_t *tmp = (uint8_t*)malloc(len); - memcpy(tmp, &ph, sizeof(_pseudo_header)); - memcpy(tmp+sizeof(_pseudo_header), this, sizeof(_neighbor_solicitation)); + size_t len = sizeof(_pseudo_header) + sizeof(_neighbor_solicitation); + uint8_t* tmp = (uint8_t*)malloc(len); + memcpy(tmp, &ph, sizeof(_pseudo_header)); + memcpy(tmp + sizeof(_pseudo_header), this, sizeof(_neighbor_solicitation)); - checksum = calc_checksum((uint16_t*)tmp, (int)len); + checksum = calc_checksum((uint16_t*)tmp, (int)len); - free(tmp); - tmp = NULL; - } + free(tmp); + tmp = NULL; + } - uint8_t type; // 135 - uint8_t code; // 0 - uint16_t checksum; - uint32_t reserved; - uint8_t target[16]; - _option option; + uint8_t type; // 135 + uint8_t code; // 0 + uint16_t checksum; + uint32_t reserved; + uint8_t target[16]; + _option option; }; struct _neighbor_advertisement { - _neighbor_advertisement() - : type(136) - , code(0) - , checksum(0) - , rso(0x40) - , option(2) - { - memset(padding, 0, sizeof(padding)); - memset(target, 0, sizeof(target)); - } + _neighbor_advertisement() : type(136), code(0), checksum(0), rso(0x40), option(2) + { + memset(padding, 0, sizeof(padding)); + memset(target, 0, sizeof(target)); + } - void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp) { - _pseudo_header ph; - memset(&ph, 0, sizeof(_pseudo_header)); - const sockaddr_in6 *src = (const sockaddr_in6*)&sourceIp; - const sockaddr_in6 *dest = (const sockaddr_in6*)&destIp; + void calculateChecksum(const sockaddr_storage& sourceIp, const sockaddr_storage& destIp) + { + _pseudo_header ph; + memset(&ph, 0, sizeof(_pseudo_header)); + const sockaddr_in6* src = (const sockaddr_in6*)&sourceIp; + const sockaddr_in6* dest = (const sockaddr_in6*)&destIp; - memcpy(ph.sourceAddr, &src->sin6_addr, sizeof(struct in6_addr)); - memcpy(ph.targetAddr, &dest->sin6_addr, sizeof(struct in6_addr)); - ph.next = 58; - ph.length = htonl(sizeof(_neighbor_advertisement)); + memcpy(ph.sourceAddr, &src->sin6_addr, sizeof(struct in6_addr)); + memcpy(ph.targetAddr, &dest->sin6_addr, sizeof(struct in6_addr)); + ph.next = 58; + ph.length = htonl(sizeof(_neighbor_advertisement)); - size_t len = sizeof(_pseudo_header) + sizeof(_neighbor_advertisement); - uint8_t *tmp = (uint8_t*)malloc(len); - memcpy(tmp, &ph, sizeof(_pseudo_header)); - memcpy(tmp+sizeof(_pseudo_header), this, sizeof(_neighbor_advertisement)); + size_t len = sizeof(_pseudo_header) + sizeof(_neighbor_advertisement); + uint8_t* tmp = (uint8_t*)malloc(len); + memcpy(tmp, &ph, sizeof(_pseudo_header)); + memcpy(tmp + sizeof(_pseudo_header), this, sizeof(_neighbor_advertisement)); - checksum = calc_checksum((uint16_t*)tmp, (int)len); + checksum = calc_checksum((uint16_t*)tmp, (int)len); - free(tmp); - tmp = NULL; - } + free(tmp); + tmp = NULL; + } - uint8_t type; // 136 - uint8_t code; // 0 - uint16_t checksum; - uint8_t rso; - uint8_t padding[3]; - uint8_t target[16]; - _option option; + uint8_t type; // 136 + uint8_t code; // 0 + uint16_t checksum; + uint8_t rso; + uint8_t padding[3]; + uint8_t target[16]; + _option option; }; -NeighborDiscovery::NeighborDiscovery() - : _cache(256) - , _lastCleaned(OSUtils::now()) -{} - -void NeighborDiscovery::addLocal(const sockaddr_storage &address, const MAC &mac) +NeighborDiscovery::NeighborDiscovery() : _cache(256), _lastCleaned(OSUtils::now()) { - _NDEntry &e = _cache[InetAddress(address)]; - e.lastQuerySent = 0; - e.lastResponseReceived = 0; - e.mac = mac; - e.local = true; } -void NeighborDiscovery::remove(const sockaddr_storage &address) +void NeighborDiscovery::addLocal(const sockaddr_storage& address, const MAC& mac) { - _cache.erase(InetAddress(address)); + _NDEntry& e = _cache[InetAddress(address)]; + e.lastQuerySent = 0; + e.lastResponseReceived = 0; + e.mac = mac; + e.local = true; } -sockaddr_storage NeighborDiscovery::processIncomingND(const uint8_t *nd, unsigned int len, const sockaddr_storage &localIp, uint8_t *response, unsigned int &responseLen, MAC &responseDest) +void NeighborDiscovery::remove(const sockaddr_storage& address) { - assert(sizeof(_neighbor_solicitation) == 28); - assert(sizeof(_neighbor_advertisement) == 32); - - const uint64_t now = OSUtils::now(); - sockaddr_storage ip = {0}; - - if (len >= sizeof(_neighbor_solicitation) && nd[0] == 0x87) { - // respond to Neighbor Solicitation request for local address - _neighbor_solicitation solicitation; - memcpy(&solicitation, nd, len); - InetAddress targetAddress(solicitation.target, 16, 0); - _NDEntry *targetEntry = _cache.get(targetAddress); - if (targetEntry && targetEntry->local) { - _neighbor_advertisement adv; - targetEntry->mac.copyTo(adv.option.mac, 6); - memcpy(adv.target, solicitation.target, 16); - adv.calculateChecksum(localIp, targetAddress); - memcpy(response, &adv, sizeof(_neighbor_advertisement)); - responseLen = sizeof(_neighbor_advertisement); - responseDest.setTo(solicitation.option.mac, 6); - } - } else if (len >= sizeof(_neighbor_advertisement) && nd[0] == 0x88) { - _neighbor_advertisement adv; - memcpy(&adv, nd, len); - InetAddress responseAddress(adv.target, 16, 0); - _NDEntry *queryEntry = _cache.get(responseAddress); - if(queryEntry && !queryEntry->local && (now - queryEntry->lastQuerySent <= ZT_ND_QUERY_MAX_TTL)) { - queryEntry->lastResponseReceived = now; - queryEntry->mac.setTo(adv.option.mac, 6); - ip = responseAddress; - } - } - - if ((now - _lastCleaned) >= ZT_ND_EXPIRE) { - _lastCleaned = now; - Hashtable::Iterator i(_cache); - InetAddress *k = NULL; - _NDEntry *v = NULL; - while (i.next(k, v)) { - if(!v->local && (now - v->lastResponseReceived) >= ZT_ND_EXPIRE) { - _cache.erase(*k); - } - } - } - - return ip; + _cache.erase(InetAddress(address)); } -MAC NeighborDiscovery::query(const MAC &localMac, const sockaddr_storage &localIp, const sockaddr_storage &targetIp, uint8_t *query, unsigned int &queryLen, MAC &queryDest) +sockaddr_storage NeighborDiscovery::processIncomingND(const uint8_t* nd, unsigned int len, const sockaddr_storage& localIp, uint8_t* response, unsigned int& responseLen, MAC& responseDest) { - const uint64_t now = OSUtils::now(); + assert(sizeof(_neighbor_solicitation) == 28); + assert(sizeof(_neighbor_advertisement) == 32); - InetAddress localAddress(localIp); - localAddress.setPort(0); - InetAddress targetAddress(targetIp); - targetAddress.setPort(0); + const uint64_t now = OSUtils::now(); + sockaddr_storage ip = { 0 }; - _NDEntry &e = _cache[targetAddress]; + if (len >= sizeof(_neighbor_solicitation) && nd[0] == 0x87) { + // respond to Neighbor Solicitation request for local address + _neighbor_solicitation solicitation; + memcpy(&solicitation, nd, len); + InetAddress targetAddress(solicitation.target, 16, 0); + _NDEntry* targetEntry = _cache.get(targetAddress); + if (targetEntry && targetEntry->local) { + _neighbor_advertisement adv; + targetEntry->mac.copyTo(adv.option.mac, 6); + memcpy(adv.target, solicitation.target, 16); + adv.calculateChecksum(localIp, targetAddress); + memcpy(response, &adv, sizeof(_neighbor_advertisement)); + responseLen = sizeof(_neighbor_advertisement); + responseDest.setTo(solicitation.option.mac, 6); + } + } + else if (len >= sizeof(_neighbor_advertisement) && nd[0] == 0x88) { + _neighbor_advertisement adv; + memcpy(&adv, nd, len); + InetAddress responseAddress(adv.target, 16, 0); + _NDEntry* queryEntry = _cache.get(responseAddress); + if (queryEntry && ! queryEntry->local && (now - queryEntry->lastQuerySent <= ZT_ND_QUERY_MAX_TTL)) { + queryEntry->lastResponseReceived = now; + queryEntry->mac.setTo(adv.option.mac, 6); + ip = responseAddress; + } + } - if ( (e.mac && ((now - e.lastResponseReceived) >= (ZT_ND_EXPIRE / 3))) || - (!e.mac && ((now - e.lastQuerySent) >= ZT_ND_QUERY_INTERVAL))) { - e.lastQuerySent = now; + if ((now - _lastCleaned) >= ZT_ND_EXPIRE) { + _lastCleaned = now; + Hashtable::Iterator i(_cache); + InetAddress* k = NULL; + _NDEntry* v = NULL; + while (i.next(k, v)) { + if (! v->local && (now - v->lastResponseReceived) >= ZT_ND_EXPIRE) { + _cache.erase(*k); + } + } + } - _neighbor_solicitation ns; - memcpy(ns.target, targetAddress.rawIpData(), 16); - localMac.copyTo(ns.option.mac, 6); - ns.calculateChecksum(localIp, targetIp); - if (e.mac) { - queryDest = e.mac; - } else { - queryDest = (uint64_t)0xffffffffffffULL; - } - } else { - queryLen = 0; - queryDest.zero(); - } - - return e.mac; + return ip; } +MAC NeighborDiscovery::query(const MAC& localMac, const sockaddr_storage& localIp, const sockaddr_storage& targetIp, uint8_t* query, unsigned int& queryLen, MAC& queryDest) +{ + const uint64_t now = OSUtils::now(); + + InetAddress localAddress(localIp); + localAddress.setPort(0); + InetAddress targetAddress(targetIp); + targetAddress.setPort(0); + + _NDEntry& e = _cache[targetAddress]; + + if ((e.mac && ((now - e.lastResponseReceived) >= (ZT_ND_EXPIRE / 3))) || (! e.mac && ((now - e.lastQuerySent) >= ZT_ND_QUERY_INTERVAL))) { + e.lastQuerySent = now; + + _neighbor_solicitation ns; + memcpy(ns.target, targetAddress.rawIpData(), 16); + localMac.copyTo(ns.option.mac, 6); + ns.calculateChecksum(localIp, targetIp); + if (e.mac) { + queryDest = e.mac; + } + else { + queryDest = (uint64_t)0xffffffffffffULL; + } + } + else { + queryLen = 0; + queryDest.zero(); + } + + return e.mac; } + +} // namespace ZeroTier diff --git a/osdep/NeighborDiscovery.hpp b/osdep/NeighborDiscovery.hpp index b25dafb91..fe5d790b0 100644 --- a/osdep/NeighborDiscovery.hpp +++ b/osdep/NeighborDiscovery.hpp @@ -15,9 +15,8 @@ #define ZT_NEIGHBORDISCOVERY_HPP #include "../node/Hashtable.hpp" -#include "../node/MAC.hpp" #include "../node/InetAddress.hpp" - +#include "../node/MAC.hpp" #define ZT_ND_QUERY_INTERVAL 2000 @@ -25,47 +24,46 @@ #define ZT_ND_EXPIRE 600000 - namespace ZeroTier { -class NeighborDiscovery -{ -public: - NeighborDiscovery(); +class NeighborDiscovery { + public: + NeighborDiscovery(); - /** - * Set a local IP entry that we should respond to Neighbor Requests withPrefix64k - * - * @param mac Our local MAC address - * @param ip Our IPv6 address - */ - void addLocal(const sockaddr_storage &address, const MAC &mac); + /** + * Set a local IP entry that we should respond to Neighbor Requests withPrefix64k + * + * @param mac Our local MAC address + * @param ip Our IPv6 address + */ + void addLocal(const sockaddr_storage& address, const MAC& mac); - /** - * Delete a local IP entry or cached Neighbor entry - * - * @param address IPv6 address to remove - */ - void remove(const sockaddr_storage &address); + /** + * Delete a local IP entry or cached Neighbor entry + * + * @param address IPv6 address to remove + */ + void remove(const sockaddr_storage& address); - sockaddr_storage processIncomingND(const uint8_t *nd, unsigned int len, const sockaddr_storage &localIp, uint8_t *response, unsigned int &responseLen, MAC &responseDest); + sockaddr_storage processIncomingND(const uint8_t* nd, unsigned int len, const sockaddr_storage& localIp, uint8_t* response, unsigned int& responseLen, MAC& responseDest); - MAC query(const MAC &localMac, const sockaddr_storage &localIp, const sockaddr_storage &targetIp, uint8_t *query, unsigned int &queryLen, MAC &queryDest); + MAC query(const MAC& localMac, const sockaddr_storage& localIp, const sockaddr_storage& targetIp, uint8_t* query, unsigned int& queryLen, MAC& queryDest); -private: - struct _NDEntry - { - _NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false) {} - uint64_t lastQuerySent; - uint64_t lastResponseReceived; - MAC mac; - bool local; - }; + private: + struct _NDEntry { + _NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false) + { + } + uint64_t lastQuerySent; + uint64_t lastResponseReceived; + MAC mac; + bool local; + }; - Hashtable _cache; - uint64_t _lastCleaned; + Hashtable _cache; + uint64_t _lastCleaned; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 5627f5f11..0508246b0 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -11,79 +11,73 @@ */ /****/ -#include -#include -#include -#include -#include +#include "NetBSDEthernetTap.hpp" -#include -#include +#include "../node/Constants.hpp" +#include "../node/Mutex.hpp" +#include "../node/Utils.hpp" +#include "OSUtils.hpp" +#include "freebsd_getifmaddrs.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include #include +#include +#include +#include #include #include #include #include - -#include - -#include "freebsd_getifmaddrs.h" - -#include -#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include - -#include "../node/Constants.hpp" -#include "../node/Utils.hpp" -#include "../node/Mutex.hpp" -#include "OSUtils.hpp" -#include "NetBSDEthernetTap.hpp" - -#include using namespace std; #define ZT_BASE32_CHARS "0123456789abcdefghijklmnopqrstuv" // ff:ff:ff:ff:ff:ff with no ADI -static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff), 0); namespace ZeroTier { NetBSDEthernetTap::NetBSDEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg) : - _handler(handler), - _arg(arg), - _nwid(nwid), - _mtu(mtu), - _metric(metric), - _fd(0), - _enabled(true) + const char* friendlyName, + void (*handler)(void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg) + : _handler(handler) + , _arg(arg) + , _nwid(nwid) + , _mtu(mtu) + , _metric(metric) + , _fd(0) + , _enabled(true) { static Mutex globalTapCreateLock; - char devpath[64],ethaddr[64],mtustr[32],metstr[32],tmpdevname[32]; + char devpath[64], ethaddr[64], mtustr[32], metstr[32], tmpdevname[32]; struct stat stattmp; Mutex::Lock _gl(globalTapCreateLock); @@ -93,43 +87,50 @@ NetBSDEthernetTap::NetBSDEthernetTap( // we can create /dev/tap* std::vector devFiles(OSUtils::listDirectory("/dev")); - for(int i=9993;i<(9993+128);++i) { - Utils::snprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); - Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); - if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { + for (int i = 9993; i < (9993 + 128); ++i) { + Utils::snprintf(tmpdevname, sizeof(tmpdevname), "tap%d", i); + Utils::snprintf(devpath, sizeof(devpath), "/dev/%s", tmpdevname); + if (std::find(devFiles.begin(), devFiles.end(), std::string(tmpdevname)) == devFiles.end()) { long cpid = (long)vfork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"create",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", tmpdevname, "create", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); - } else throw std::runtime_error("fork() failed"); + ::waitpid(cpid, &exitcode, 0); + } + else + throw std::runtime_error("fork() failed"); cpid = (long)vfork(); if (cpid == 0) { string tmp; sprintf((char*)tmp.c_str(), "%d", i); string minor = tmp.c_str(); - ::execl("/sbin/mknod","/sbin/mknod",devpath,"c","169",minor.c_str(),(const char *)0); + ::execl("/sbin/mknod", "/sbin/mknod", devpath, "c", "169", minor.c_str(), (const char*)0); // http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/conf/majors // major 169 => tap ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); - } else throw std::runtime_error("fork() failed"); + ::waitpid(cpid, &exitcode, 0); + } + else + throw std::runtime_error("fork() failed"); - cerr<<"created device "< 0) break; else throw std::runtime_error("unable to open created tap device "); - } else { + } + else { throw std::runtime_error("cannot find /dev node for newly created tap device"); } } @@ -138,22 +139,23 @@ NetBSDEthernetTap::NetBSDEthernetTap( if (_fd <= 0) throw std::runtime_error("unable to open TAP device or no more devices available"); - if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) { + if (fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL) & ~O_NONBLOCK) == -1) { ::close(_fd); throw std::runtime_error("unable to set flags on file descriptor for TAP device"); } // Configure MAC address and MTU, bring interface up - Utils::snprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); - Utils::snprintf(mtustr,sizeof(mtustr),"%u",_mtu); - Utils::snprintf(metstr,sizeof(metstr),"%u",_metric); + Utils::snprintf(ethaddr, sizeof(ethaddr), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (int)mac[0], (int)mac[1], (int)mac[2], (int)mac[3], (int)mac[4], (int)mac[5]); + Utils::snprintf(mtustr, sizeof(mtustr), "%u", _mtu); + Utils::snprintf(metstr, sizeof(metstr), "%u", _metric); long cpid = (long)vfork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"link",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "link", ethaddr, "mtu", mtustr, "metric", metstr, "up", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); if (exitcode) { ::close(_fd); throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface"); @@ -164,13 +166,14 @@ NetBSDEthernetTap::NetBSDEthernetTap( // https://wiki.netbsd.org/tutorials/faking_a_mac_address/ cpid = (long)vfork(); if (cpid == 0) { - string cmdline = "net.link.tap."+string(_dev); - cmdline += "="+string(ethaddr); - ::execl("/sbin/sysctl","/sbin/sysctl","-w",cmdline.c_str(),(const char *)0); + string cmdline = "net.link.tap." + string(_dev); + cmdline += "=" + string(ethaddr); + ::execl("/sbin/sysctl", "/sbin/sysctl", "-w", cmdline.c_str(), (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); if (exitcode) { ::close(_fd); throw std::runtime_error("sysctl failure setting link-layer address and activating tap interface"); @@ -178,17 +181,16 @@ NetBSDEthernetTap::NetBSDEthernetTap( } // Set close-on-exec so that devices cannot persist if we fork/exec for update - fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); + fcntl(_fd, F_SETFD, fcntl(_fd, F_GETFD) | FD_CLOEXEC); ::pipe(_shutdownSignalPipe); _thread = Thread::start(this); - } NetBSDEthernetTap::~NetBSDEthernetTap() { - ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit + ::write(_shutdownSignalPipe[1], "\0", 1); // causes thread to exit Thread::join(_thread); ::close(_fd); ::close(_shutdownSignalPipe[0]); @@ -196,23 +198,27 @@ NetBSDEthernetTap::~NetBSDEthernetTap() long cpid = (long)vfork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"destroy",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "destroy", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); } cpid = (long)vfork(); if (cpid == 0) { - string tmp="/dev/"; - tmp+=_dev.c_str(); - ::execl("/bin/rm","/bin/rm",tmp.c_str(),(const char *)0); + string tmp = "/dev/"; + tmp += _dev.c_str(); + ::execl("/bin/rm", "/bin/rm", tmp.c_str(), (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); - } else throw std::runtime_error("fork() failed"); + ::waitpid(cpid, &exitcode, 0); + } + else + throw std::runtime_error("fork() failed"); } void NetBSDEthernetTap::setEnabled(bool en) @@ -225,56 +231,58 @@ bool NetBSDEthernetTap::enabled() const return _enabled; } -static bool ___removeIp(const std::string &_dev,const InetAddress &ip) +static bool ___removeIp(const std::string& _dev, const InetAddress& ip) { long cpid = (long)vfork(); if (cpid == 0) { - execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0); + execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), "inet", ip.toIpString().c_str(), "-alias", (const char*)0); _exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - waitpid(cpid,&exitcode,0); + waitpid(cpid, &exitcode, 0); return (exitcode == 0); } - return false; // never reached, make compiler shut up about return value + return false; // never reached, make compiler shut up about return value } -bool NetBSDEthernetTap::addIp(const InetAddress &ip) +bool NetBSDEthernetTap::addIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; std::vector allIps(ips()); - if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) - return true; // IP/netmask already assigned + if (std::find(allIps.begin(), allIps.end(), ip) != allIps.end()) + return true; // IP/netmask already assigned // Remove and reconfigure if address is the same but netmask is different - for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { - if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) { - if (___removeIp(_dev,*i)) + for (std::vector::iterator i(allIps.begin()); i != allIps.end(); ++i) { + if ((i->ipsEqual(ip)) && (i->netmaskBits() != ip.netmaskBits())) { + if (___removeIp(_dev, *i)) break; } } long cpid = (long)vfork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0); + ::execl("/sbin/ifconfig", "/sbin/ifconfig", _dev.c_str(), ip.isV4() ? "inet" : "inet6", ip.toString().c_str(), "alias", (const char*)0); ::_exit(-1); - } else if (cpid > 0) { + } + else if (cpid > 0) { int exitcode = -1; - ::waitpid(cpid,&exitcode,0); + ::waitpid(cpid, &exitcode, 0); return (exitcode == 0); } return false; } -bool NetBSDEthernetTap::removeIp(const InetAddress &ip) +bool NetBSDEthernetTap::removeIp(const InetAddress& ip) { - if (!ip) + if (! ip) return false; std::vector allIps(ips()); - if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) { - if (___removeIp(_dev,ip)) + if (std::find(allIps.begin(), allIps.end(), ip) != allIps.end()) { + if (___removeIp(_dev, ip)) return true; } return false; @@ -282,28 +290,28 @@ bool NetBSDEthernetTap::removeIp(const InetAddress &ip) std::vector NetBSDEthernetTap::ips() const { - struct ifaddrs *ifa = (struct ifaddrs *)0; + struct ifaddrs* ifa = (struct ifaddrs*)0; if (getifaddrs(&ifa)) return std::vector(); std::vector r; - struct ifaddrs *p = ifa; + struct ifaddrs* p = ifa; while (p) { - if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { - switch(p->ifa_addr->sa_family) { + if ((! strcmp(p->ifa_name, _dev.c_str())) && (p->ifa_addr) && (p->ifa_netmask) && (p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { + switch (p->ifa_addr->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; - struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; - r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); - } break; + struct sockaddr_in* sin = (struct sockaddr_in*)p->ifa_addr; + struct sockaddr_in* nm = (struct sockaddr_in*)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr), 4, Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; case AF_INET6: { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; - struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + struct sockaddr_in6* sin = (struct sockaddr_in6*)p->ifa_addr; + struct sockaddr_in6* nm = (struct sockaddr_in6*)p->ifa_netmask; uint32_t b[4]; - memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); - r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); - } break; + memcpy(b, nm->sin6_addr.s6_addr, sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr, 16, Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; } } p = p->ifa_next; @@ -312,22 +320,22 @@ std::vector NetBSDEthernetTap::ips() const if (ifa) freeifaddrs(ifa); - std::sort(r.begin(),r.end()); - std::unique(r.begin(),r.end()); + std::sort(r.begin(), r.end()); + std::unique(r.begin(), r.end()); return r; } -void NetBSDEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void NetBSDEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { char putBuf[4096]; - if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) { - to.copyTo(putBuf,6); - from.copyTo(putBuf + 6,6); - *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType); - memcpy(putBuf + 14,data,len); + if ((_fd > 0) && (len <= _mtu) && (_enabled)) { + to.copyTo(putBuf, 6); + from.copyTo(putBuf + 6, 6); + *((uint16_t*)(putBuf + 12)) = htons((uint16_t)etherType); + memcpy(putBuf + 14, data, len); len += 14; - ::write(_fd,putBuf,len); + ::write(_fd, putBuf, len); } } @@ -336,23 +344,23 @@ std::string NetBSDEthernetTap::deviceName() const return _dev; } -void NetBSDEthernetTap::setFriendlyName(const char *friendlyName) +void NetBSDEthernetTap::setFriendlyName(const char* friendlyName) { } -void NetBSDEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void NetBSDEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { std::vector newGroups; - struct ifmaddrs *ifmap = (struct ifmaddrs *)0; - if (!getifmaddrs(&ifmap)) { - struct ifmaddrs *p = ifmap; + struct ifmaddrs* ifmap = (struct ifmaddrs*)0; + if (! getifmaddrs(&ifmap)) { + struct ifmaddrs* p = ifmap; while (p) { if (p->ifma_addr->sa_family == AF_LINK) { - struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; - struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; - if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) - newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + struct sockaddr_dl* in = (struct sockaddr_dl*)p->ifma_name; + struct sockaddr_dl* la = (struct sockaddr_dl*)p->ifma_addr; + if ((la->sdl_alen == 6) && (in->sdl_nlen <= _dev.length()) && (! memcmp(_dev.data(), in->sdl_data, in->sdl_nlen))) + newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen, 6), 0)); } p = p->ifma_next; } @@ -360,18 +368,18 @@ void NetBSDEthernetTap::scanMulticastGroups(std::vector &added,s } std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - std::unique(newGroups.begin(),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + std::unique(newGroups.begin(), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -422,12 +430,11 @@ bool NetBSDEthernetTap::updateMulticastGroups(std::set &groups) } */ -void NetBSDEthernetTap::threadMain() - throw() +void NetBSDEthernetTap::threadMain() throw() { - fd_set readfds,nullfds; - MAC to,from; - int n,nfds,r; + fd_set readfds, nullfds; + MAC to, from; + int n, nfds, r; char getBuf[8194]; // Wait for a moment after startup -- wait for Network to finish @@ -436,37 +443,38 @@ void NetBSDEthernetTap::threadMain() FD_ZERO(&readfds); FD_ZERO(&nullfds); - nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1; + nfds = (int)std::max(_shutdownSignalPipe[0], _fd) + 1; r = 0; - for(;;) { - FD_SET(_shutdownSignalPipe[0],&readfds); - FD_SET(_fd,&readfds); - select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0); + for (;;) { + FD_SET(_shutdownSignalPipe[0], &readfds); + FD_SET(_fd, &readfds); + select(nfds, &readfds, &nullfds, &nullfds, (struct timeval*)0); - if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread + if (FD_ISSET(_shutdownSignalPipe[0], &readfds)) // writes to shutdown pipe terminate thread break; - if (FD_ISSET(_fd,&readfds)) { - n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r); + if (FD_ISSET(_fd, &readfds)) { + n = (int)::read(_fd, getBuf + r, sizeof(getBuf) - r); if (n < 0) { - if ((errno != EINTR)&&(errno != ETIMEDOUT)) + if ((errno != EINTR) && (errno != ETIMEDOUT)) break; - } else { + } + else { // Some tap drivers like to send the ethernet frame and the // payload in two chunks, so handle that by accumulating // data until we have at least a frame. r += n; if (r > 14) { - if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms + if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms r = _mtu + 14; if (_enabled) { - to.setTo(getBuf,6); - from.setTo(getBuf + 6,6); - unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]); + to.setTo(getBuf, 6); + from.setTo(getBuf + 6, 6); + unsigned int etherType = ntohs(((const uint16_t*)getBuf)[6]); // TODO: VLAN support - _handler(_arg,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14); + _handler(_arg, _nwid, from, to, etherType, 0, (const void*)(getBuf + 14), r - 14); } r = 0; @@ -476,4 +484,4 @@ void NetBSDEthernetTap::threadMain() } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/NetBSDEthernetTap.hpp b/osdep/NetBSDEthernetTap.hpp index 1809d1f60..b505cb504 100644 --- a/osdep/NetBSDEthernetTap.hpp +++ b/osdep/NetBSDEthernetTap.hpp @@ -14,53 +14,52 @@ #ifndef ZT_NetBSDEthernetTap_HPP #define ZT_NetBSDEthernetTap_HPP +#include "../node/Constants.hpp" +#include "../node/MAC.hpp" +#include "../node/MulticastGroup.hpp" +#include "EthernetTap.hpp" +#include "Thread.hpp" + +#include #include #include - #include #include -#include - -#include "../node/Constants.hpp" -#include "../node/MulticastGroup.hpp" -#include "../node/MAC.hpp" -#include "Thread.hpp" -#include "EthernetTap.hpp" namespace ZeroTier { -class NetBSDEthernetTap : public EthernetTap -{ -public: +class NetBSDEthernetTap : public EthernetTap { + public: NetBSDEthernetTap( - const char *homePath, - const MAC &mac, + const char* homePath, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~NetBSDEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); - virtual bool removeIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); - virtual void setDns(const char *domain, const std::vector &servers) {} + virtual void setFriendlyName(const char* friendlyName); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); + virtual void setDns(const char* domain, const std::vector& servers) + { + } - void threadMain() - throw(); + void threadMain() throw(); -private: - void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + private: + void (*_handler)(void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; uint64_t _nwid; Thread _thread; std::string _dev; @@ -72,6 +71,6 @@ private: volatile bool _enabled; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp index e98a2c70b..41d144f1b 100644 --- a/osdep/OSUtils.cpp +++ b/osdep/OSUtils.cpp @@ -11,35 +11,34 @@ */ /****/ -#include -#include -#include -#include -#include -#include -#include - #include "../node/Constants.hpp" #include "../node/Utils.hpp" +#include +#include +#include +#include +#include +#include + #ifdef __UNIX_LIKE__ -#include +#include #include #include -#include +#include #include #include +#include #include -#include -#include +#include #endif #ifdef __WINDOWS__ -#include -#include -#include -#include #include +#include +#include +#include +#include #endif #include "OSUtils.hpp" @@ -50,15 +49,15 @@ namespace ZeroTier { -unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...) +unsigned int OSUtils::ztsnprintf(char* buf, unsigned int len, const char* fmt, ...) { va_list ap; - va_start(ap,fmt); - int n = (int)vsnprintf(buf,len,fmt,ap); + va_start(ap, fmt); + int n = (int)vsnprintf(buf, len, fmt, ap); va_end(ap); - if ((n >= (int)len)||(n < 0)) { + if ((n >= (int)len) || (n < 0)) { if (len) buf[len - 1] = (char)0; throw std::length_error("buf[] overflow"); @@ -67,70 +66,75 @@ unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...) return (unsigned int)n; } -std::string OSUtils::networkIDStr(const uint64_t nwid) { +std::string OSUtils::networkIDStr(const uint64_t nwid) +{ char tmp[32] = {}; ztsnprintf(tmp, sizeof(tmp), "%.16" PRIx64, nwid); return std::string(tmp); } -std::string OSUtils::nodeIDStr(const uint64_t nid) { +std::string OSUtils::nodeIDStr(const uint64_t nid) +{ char tmp[32] = {}; ztsnprintf(tmp, sizeof(tmp), "%.10" PRIx64, nid); return std::string(tmp); } #ifdef __UNIX_LIKE__ -bool OSUtils::redirectUnixOutputs(const char *stdoutPath,const char *stderrPath) - throw() +bool OSUtils::redirectUnixOutputs(const char* stdoutPath, const char* stderrPath) throw() { - int fdout = ::open(stdoutPath,O_WRONLY|O_CREAT,0600); + int fdout = ::open(stdoutPath, O_WRONLY | O_CREAT, 0600); if (fdout > 0) { int fderr; if (stderrPath) { - fderr = ::open(stderrPath,O_WRONLY|O_CREAT,0600); + fderr = ::open(stderrPath, O_WRONLY | O_CREAT, 0600); if (fderr <= 0) { ::close(fdout); return false; } - } else fderr = fdout; + } + else + fderr = fdout; ::close(STDOUT_FILENO); ::close(STDERR_FILENO); - ::dup2(fdout,STDOUT_FILENO); - ::dup2(fderr,STDERR_FILENO); + ::dup2(fdout, STDOUT_FILENO); + ::dup2(fderr, STDERR_FILENO); return true; } return false; } -#endif // __UNIX_LIKE__ +#endif // __UNIX_LIKE__ -std::vector OSUtils::listDirectory(const char *path,bool includeDirectories) +std::vector OSUtils::listDirectory(const char* path, bool includeDirectories) { std::vector r; #ifdef __WINDOWS__ HANDLE hFind; WIN32_FIND_DATAA ffd; - if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) { + if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(), &ffd)) != INVALID_HANDLE_VALUE) { do { - if ( (strcmp(ffd.cFileName,".")) && (strcmp(ffd.cFileName,"..")) && (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)||(((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)&&(includeDirectories))) ) + if ((strcmp(ffd.cFileName, ".")) && (strcmp(ffd.cFileName, "..")) && (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) || (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) && (includeDirectories)))) r.push_back(std::string(ffd.cFileName)); - } while (FindNextFileA(hFind,&ffd)); + } while (FindNextFileA(hFind, &ffd)); FindClose(hFind); } #else struct dirent de; - struct dirent *dptr; - DIR *d = opendir(path); - if (!d) + struct dirent* dptr; + DIR* d = opendir(path); + if (! d) return r; - dptr = (struct dirent *)0; - for(;;) { - if (readdir_r(d,&de,&dptr)) + dptr = (struct dirent*)0; + for (;;) { + if (readdir_r(d, &de, &dptr)) break; if (dptr) { - if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&((dptr->d_type != DT_DIR)||(includeDirectories))) + if ((strcmp(dptr->d_name, ".")) && (strcmp(dptr->d_name, "..")) && ((dptr->d_type != DT_DIR) || (includeDirectories))) r.push_back(std::string(dptr->d_name)); - } else break; + } + else + break; } closedir(d); #endif @@ -138,57 +142,59 @@ std::vector OSUtils::listDirectory(const char *path,bool includeDir return r; } -long OSUtils::cleanDirectory(const char *path,const int64_t olderThan) +long OSUtils::cleanDirectory(const char* path, const int64_t olderThan) { long cleaned = 0; #ifdef __WINDOWS__ HANDLE hFind; WIN32_FIND_DATAA ffd; - LARGE_INTEGER date,adjust; + LARGE_INTEGER date, adjust; adjust.QuadPart = 11644473600000 * 10000; char tmp[4096]; - if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) { + if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(), &ffd)) != INVALID_HANDLE_VALUE) { do { - if ((strcmp(ffd.cFileName,"."))&&(strcmp(ffd.cFileName,".."))&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { - date.HighPart = ffd.ftLastWriteTime.dwHighDateTime; - date.LowPart = ffd.ftLastWriteTime.dwLowDateTime; - if (date.QuadPart > 0) { - date.QuadPart -= adjust.QuadPart; - if ((int64_t)((date.QuadPart / 10000000) * 1000) < olderThan) { - ztsnprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName); - if (DeleteFileA(tmp)) - ++cleaned; - } + if ((strcmp(ffd.cFileName, ".")) && (strcmp(ffd.cFileName, "..")) && ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { + date.HighPart = ffd.ftLastWriteTime.dwHighDateTime; + date.LowPart = ffd.ftLastWriteTime.dwLowDateTime; + if (date.QuadPart > 0) { + date.QuadPart -= adjust.QuadPart; + if ((int64_t)((date.QuadPart / 10000000) * 1000) < olderThan) { + ztsnprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName); + if (DeleteFileA(tmp)) + ++cleaned; } + } } - } while (FindNextFileA(hFind,&ffd)); + } while (FindNextFileA(hFind, &ffd)); FindClose(hFind); } #else struct dirent de; - struct dirent *dptr; + struct dirent* dptr; struct stat st; char tmp[4096]; - DIR *d = opendir(path); - if (!d) + DIR* d = opendir(path); + if (! d) return -1; - dptr = (struct dirent *)0; - for(;;) { - if (readdir_r(d,&de,&dptr)) + dptr = (struct dirent*)0; + for (;;) { + if (readdir_r(d, &de, &dptr)) break; if (dptr) { - if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&(dptr->d_type == DT_REG)) { - ztsnprintf(tmp,sizeof(tmp),"%s/%s",path,dptr->d_name); - if (stat(tmp,&st) == 0) { + if ((strcmp(dptr->d_name, ".")) && (strcmp(dptr->d_name, "..")) && (dptr->d_type == DT_REG)) { + ztsnprintf(tmp, sizeof(tmp), "%s/%s", path, dptr->d_name); + if (stat(tmp, &st) == 0) { int64_t mt = (int64_t)(st.st_mtime); - if ((mt > 0)&&((mt * 1000) < olderThan)) { + if ((mt > 0) && ((mt * 1000) < olderThan)) { if (unlink(tmp) == 0) ++cleaned; } } } - } else break; + } + else + break; } closedir(d); #endif @@ -196,44 +202,45 @@ long OSUtils::cleanDirectory(const char *path,const int64_t olderThan) return cleaned; } -bool OSUtils::rmDashRf(const char *path) +bool OSUtils::rmDashRf(const char* path) { #ifdef __WINDOWS__ HANDLE hFind; WIN32_FIND_DATAA ffd; - if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) { + if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(), &ffd)) != INVALID_HANDLE_VALUE) { do { - if ((strcmp(ffd.cFileName,".") != 0)&&(strcmp(ffd.cFileName,"..") != 0)) { + if ((strcmp(ffd.cFileName, ".") != 0) && (strcmp(ffd.cFileName, "..") != 0)) { if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { if (DeleteFileA((std::string(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str()) == FALSE) return false; - } else { - if (!rmDashRf((std::string(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str())) + } + else { + if (! rmDashRf((std::string(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str())) return false; } } - } while (FindNextFileA(hFind,&ffd)); + } while (FindNextFileA(hFind, &ffd)); FindClose(hFind); } return (RemoveDirectoryA(path) != FALSE); #else struct dirent de; - struct dirent *dptr; - DIR *d = opendir(path); - if (!d) + struct dirent* dptr; + DIR* d = opendir(path); + if (! d) return true; - dptr = (struct dirent *)0; - for(;;) { - if (readdir_r(d,&de,&dptr) != 0) + dptr = (struct dirent*)0; + for (;;) { + if (readdir_r(d, &de, &dptr) != 0) break; - if (!dptr) + if (! dptr) break; - if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&(strlen(dptr->d_name) > 0)) { + if ((strcmp(dptr->d_name, ".") != 0) && (strcmp(dptr->d_name, "..") != 0) && (strlen(dptr->d_name) > 0)) { std::string p(path); p.push_back(ZT_PATH_SEPARATOR); p.append(dptr->d_name); - if (unlink(p.c_str()) != 0) { // unlink first will remove symlinks instead of recursing them - if (!rmDashRf(p.c_str())) + if (unlink(p.c_str()) != 0) { // unlink first will remove symlinks instead of recursing them + if (! rmDashRf(p.c_str())) return false; } } @@ -243,10 +250,10 @@ bool OSUtils::rmDashRf(const char *path) #endif } -void OSUtils::lockDownFile(const char *path,bool isDir) +void OSUtils::lockDownFile(const char* path, bool isDir) { #ifdef __UNIX_LIKE__ - chmod(path,isDir ? 0700 : 0600); + chmod(path, isDir ? 0700 : 0600); #else #ifdef __WINDOWS__ { @@ -254,19 +261,19 @@ void OSUtils::lockDownFile(const char *path,bool isDir) PROCESS_INFORMATION processInfo; startupInfo.cb = sizeof(startupInfo); - memset(&startupInfo,0,sizeof(STARTUPINFOA)); - memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL,(LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /inheritance:d /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) { - WaitForSingleObject(processInfo.hProcess,INFINITE); + memset(&startupInfo, 0, sizeof(STARTUPINFOA)); + memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL, (LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /inheritance:d /Q").c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } startupInfo.cb = sizeof(startupInfo); - memset(&startupInfo,0,sizeof(STARTUPINFOA)); - memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL,(LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /remove *S-1-5-32-545 /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) { - WaitForSingleObject(processInfo.hProcess,INFINITE); + memset(&startupInfo, 0, sizeof(STARTUPINFOA)); + memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL, (LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /remove *S-1-5-32-545 /Q").c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } @@ -285,28 +292,28 @@ void OSUtils::lockDownFile(const char *path,bool isDir) #endif } -uint64_t OSUtils::getLastModified(const char *path) +uint64_t OSUtils::getLastModified(const char* path) { struct stat s; - if (stat(path,&s)) + if (stat(path, &s)) return 0; return (((uint64_t)s.st_mtime) * 1000ULL); } -bool OSUtils::fileExists(const char *path,bool followLinks) +bool OSUtils::fileExists(const char* path, bool followLinks) { struct stat s; #ifdef __UNIX_LIKE__ - if (!followLinks) - return (lstat(path,&s) == 0); + if (! followLinks) + return (lstat(path, &s) == 0); #endif - return (stat(path,&s) == 0); + return (stat(path, &s) == 0); } -int64_t OSUtils::getFileSize(const char *path) +int64_t OSUtils::getFileSize(const char* path) { struct stat s; - if (stat(path,&s)) + if (stat(path, &s)) return -1; #ifdef __WINDOWS__ return s.st_size; @@ -317,16 +324,17 @@ int64_t OSUtils::getFileSize(const char *path) return -1; } -bool OSUtils::readFile(const char *path,std::string &buf) +bool OSUtils::readFile(const char* path, std::string& buf) { char tmp[16384]; - FILE *f = fopen(path,"rb"); + FILE* f = fopen(path, "rb"); if (f) { - for(;;) { - long n = (long)fread(tmp,1,sizeof(tmp),f); + for (;;) { + long n = (long)fread(tmp, 1, sizeof(tmp), f); if (n > 0) - buf.append(tmp,n); - else break; + buf.append(tmp, n); + else + break; } fclose(f); return true; @@ -334,14 +342,15 @@ bool OSUtils::readFile(const char *path,std::string &buf) return false; } -bool OSUtils::writeFile(const char *path,const void *buf,unsigned int len) +bool OSUtils::writeFile(const char* path, const void* buf, unsigned int len) { - FILE *f = fopen(path,"wb"); + FILE* f = fopen(path, "wb"); if (f) { - if ((long)fwrite(buf,1,len,f) != (long)len) { + if ((long)fwrite(buf, 1, len, f) != (long)len) { fclose(f); return false; - } else { + } + else { fclose(f); return true; } @@ -349,14 +358,14 @@ bool OSUtils::writeFile(const char *path,const void *buf,unsigned int len) return false; } -std::vector OSUtils::split(const char *s,const char *const sep,const char *esc,const char *quot) +std::vector OSUtils::split(const char* s, const char* const sep, const char* esc, const char* quot) { std::vector fields; std::string buf; - if (!esc) + if (! esc) esc = ""; - if (!quot) + if (! quot) quot = ""; bool escapeState = false; @@ -365,24 +374,30 @@ std::vector OSUtils::split(const char *s,const char *const sep,cons if (escapeState) { escapeState = false; buf.push_back(*s); - } else if (quoteState) { + } + else if (quoteState) { if (*s == quoteState) { quoteState = 0; fields.push_back(buf); buf.clear(); - } else buf.push_back(*s); - } else { - const char *quotTmp; - if (strchr(esc,*s)) + } + else + buf.push_back(*s); + } + else { + const char* quotTmp; + if (strchr(esc, *s)) escapeState = true; - else if ((buf.size() <= 0)&&((quotTmp = strchr(quot,*s)))) + else if ((buf.size() <= 0) && ((quotTmp = strchr(quot, *s)))) quoteState = *quotTmp; - else if (strchr(sep,*s)) { - if (!buf.empty()) { + else if (strchr(sep, *s)) { + if (! buf.empty()) { fields.push_back(buf); buf.clear(); - } // else skip runs of separators - } else buf.push_back(*s); + } // else skip runs of separators + } + else + buf.push_back(*s); } ++s; } @@ -396,28 +411,28 @@ std::vector OSUtils::split(const char *s,const char *const sep,cons std::string OSUtils::platformDefaultHomePath() { #ifdef __QNAP__ - char *cmd = "/sbin/getcfg zerotier Install_Path -f /etc/config/qpkg.conf"; - char buf[128]; - FILE *fp; - if ((fp = popen(cmd, "r")) == NULL) { - printf("Error opening pipe!\n"); - return NULL; - } - while (fgets(buf, 128, fp) != NULL) { } - if(pclose(fp)) { - printf("Command not found or exited with error status\n"); - return NULL; - } - std::string homeDir = std::string(buf); - homeDir.erase(std::remove(homeDir.begin(), homeDir.end(), '\n'), homeDir.end()); - return homeDir; + char* cmd = "/sbin/getcfg zerotier Install_Path -f /etc/config/qpkg.conf"; + char buf[128]; + FILE* fp; + if ((fp = popen(cmd, "r")) == NULL) { + printf("Error opening pipe!\n"); + return NULL; + } + while (fgets(buf, 128, fp) != NULL) {} + if (pclose(fp)) { + printf("Command not found or exited with error status\n"); + return NULL; + } + std::string homeDir = std::string(buf); + homeDir.erase(std::remove(homeDir.begin(), homeDir.end(), '\n'), homeDir.end()); + return homeDir; #endif #ifdef __UBIQUITI__ // Only persistent location after firmware upgrades return std::string("/config/zerotier-one"); #endif - // Check for user-defined environment variable before using defaults + // Check for user-defined environment variable before using defaults #ifdef __WINDOWS__ DWORD bufferSize = 65535; std::string userDefinedPath; @@ -426,7 +441,7 @@ std::string OSUtils::platformDefaultHomePath() return userDefinedPath; } #else - if(const char* userDefinedPath = getenv("ZEROTIER_HOME")) { + if (const char* userDefinedPath = getenv("ZEROTIER_HOME")) { return std::string(userDefinedPath); } #endif @@ -449,44 +464,55 @@ std::string OSUtils::platformDefaultHomePath() #endif -#else // not __UNIX_LIKE__ +#else // not __UNIX_LIKE__ #ifdef __WINDOWS__ // Look up app data folder on Windows, e.g. C:\ProgramData\... char buf[16384]; - if (SUCCEEDED(SHGetFolderPathA(NULL,CSIDL_COMMON_APPDATA,NULL,0,buf))) + if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA, NULL, 0, buf))) return (std::string(buf) + "\\ZeroTier\\One"); - else return std::string("C:\\ZeroTier\\One"); + else + return std::string("C:\\ZeroTier\\One"); #else - return (std::string(ZT_PATH_SEPARATOR_S) + "ZeroTier" + ZT_PATH_SEPARATOR_S + "One"); // UNKNOWN PLATFORM + return (std::string(ZT_PATH_SEPARATOR_S) + "ZeroTier" + ZT_PATH_SEPARATOR_S + "One"); // UNKNOWN PLATFORM #endif -#endif // __UNIX_LIKE__ or not... +#endif // __UNIX_LIKE__ or not... } #ifndef OMIT_JSON_SUPPORT // Inline these massive JSON operations in one place only to reduce binary footprint and compile time -nlohmann::json OSUtils::jsonParse(const std::string &buf) { return nlohmann::json::parse(buf.c_str()); } -std::string OSUtils::jsonDump(const nlohmann::json &j,int indentation) { return j.dump(indentation); } +nlohmann::json OSUtils::jsonParse(const std::string& buf) +{ + return nlohmann::json::parse(buf.c_str()); +} +std::string OSUtils::jsonDump(const nlohmann::json& j, int indentation) +{ + return j.dump(indentation); +} -uint64_t OSUtils::jsonInt(const nlohmann::json &jv,const uint64_t dfl) +uint64_t OSUtils::jsonInt(const nlohmann::json& jv, const uint64_t dfl) { try { if (jv.is_number()) { return (uint64_t)jv; - } else if (jv.is_string()) { + } + else if (jv.is_string()) { std::string s = jv; return Utils::strToU64(s.c_str()); - } else if (jv.is_boolean()) { + } + else if (jv.is_boolean()) { return ((bool)jv ? 1ULL : 0ULL); } - } catch ( ... ) {} + } + catch (...) { + } return dfl; } -double OSUtils::jsonDouble(const nlohmann::json &jv,const double dfl) +double OSUtils::jsonDouble(const nlohmann::json& jv, const double dfl) { try { if (jv.is_number()) { @@ -495,39 +521,48 @@ double OSUtils::jsonDouble(const nlohmann::json &jv,const double dfl) else if (jv.is_string()) { std::string s = jv; return Utils::strToDouble(s.c_str()); - } else if (jv.is_boolean()) { + } + else if (jv.is_boolean()) { return (double)jv; } - } catch ( ... ) {} + } + catch (...) { + } return dfl; } -uint64_t OSUtils::jsonIntHex(const nlohmann::json &jv,const uint64_t dfl) +uint64_t OSUtils::jsonIntHex(const nlohmann::json& jv, const uint64_t dfl) { try { if (jv.is_number()) { return (uint64_t)jv; - } else if (jv.is_string()) { + } + else if (jv.is_string()) { std::string s = jv; return Utils::hexStrToU64(s.c_str()); - } else if (jv.is_boolean()) { + } + else if (jv.is_boolean()) { return ((bool)jv ? 1ULL : 0ULL); } - } catch ( ... ) {} + } + catch (...) { + } return dfl; } -bool OSUtils::jsonBool(const nlohmann::json &jv,const bool dfl) +bool OSUtils::jsonBool(const nlohmann::json& jv, const bool dfl) { try { if (jv.is_boolean()) { return (bool)jv; - } else if (jv.is_number()) { + } + else if (jv.is_number()) { return ((uint64_t)jv > 0ULL); - } else if (jv.is_string()) { + } + else if (jv.is_string()) { std::string s = jv; if (s.length() > 0) { - switch(s[0]) { + switch (s[0]) { case 't': case 'T': case '1': @@ -536,47 +571,62 @@ bool OSUtils::jsonBool(const nlohmann::json &jv,const bool dfl) } return false; } - } catch ( ... ) {} + } + catch (...) { + } return dfl; } -std::string OSUtils::jsonString(const nlohmann::json &jv,const char *dfl) +std::string OSUtils::jsonString(const nlohmann::json& jv, const char* dfl) { try { if (jv.is_string()) { return jv; - } else if (jv.is_number()) { + } + else if (jv.is_number()) { char tmp[64]; - ztsnprintf(tmp,sizeof(tmp),"%llu",(uint64_t)jv); + ztsnprintf(tmp, sizeof(tmp), "%llu", (uint64_t)jv); return tmp; - } else if (jv.is_boolean()) { + } + else if (jv.is_boolean()) { return ((bool)jv ? std::string("1") : std::string("0")); } - } catch ( ... ) {} + } + catch (...) { + } return std::string((dfl) ? dfl : ""); } -std::string OSUtils::jsonBinFromHex(const nlohmann::json &jv) +std::string OSUtils::jsonBinFromHex(const nlohmann::json& jv) { - std::string s(jsonString(jv,"")); + std::string s(jsonString(jv, "")); if (s.length() > 0) { unsigned int buflen = (unsigned int)((s.length() / 2) + 1); - char *buf = new char[buflen]; + char* buf = new char[buflen]; try { - unsigned int l = Utils::unhex(s.c_str(),buf,buflen); - std::string b(buf,l); - delete [] buf; + unsigned int l = Utils::unhex(s.c_str(), buf, buflen); + std::string b(buf, l); + delete[] buf; return b; - } catch ( ... ) { - delete [] buf; + } + catch (...) { + delete[] buf; } } return std::string(); } -#endif // OMIT_JSON_SUPPORT +#endif // OMIT_JSON_SUPPORT // Used to convert HTTP header names to ASCII lower case -const unsigned char OSUtils::TOLOWER_TABLE[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +const unsigned char OSUtils::TOLOWER_TABLE[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '{', '|', '}', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, + 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, + 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp index f8214efa9..c105612f7 100644 --- a/osdep/OSUtils.hpp +++ b/osdep/OSUtils.hpp @@ -14,29 +14,28 @@ #ifndef ZT_OSUTILS_HPP #define ZT_OSUTILS_HPP -#include -#include -#include -#include -#include - -#include -#include -#include - #include "../node/Constants.hpp" #include "../node/InetAddress.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + #ifdef __WINDOWS__ -#include -#include #include +#include +#include #else -#include -#include -#include -#include #include +#include +#include +#include +#include #ifdef __LINUX__ #include #endif @@ -51,9 +50,8 @@ namespace ZeroTier { /** * Miscellaneous utility functions and global constants */ -class OSUtils -{ -public: +class OSUtils { + public: /** * Variant of snprintf that is portable and throws an exception * @@ -66,11 +64,11 @@ public: * @param ... Format arguments * @throws std::length_error buf[] too short (buf[] will still be left null-terminated) */ - static unsigned int ztsnprintf(char *buf,unsigned int len,const char *fmt,...); + static unsigned int ztsnprintf(char* buf, unsigned int len, const char* fmt, ...); /** * Converts a uint64_t network ID into a string - * + * * @param nwid network ID * @throws std::length_error buf[] too short (buf[] will still be left null-terminated) */ @@ -78,7 +76,7 @@ public: /** * Converts a uint64_t node ID into a string - * + * * @param nid node ID * @throws std::length_error buf[] too short (buf[] will still be left null-terminated) */ @@ -95,9 +93,8 @@ public: * @param stderrPath Path to file to use for stderr, or NULL for same as stdout (default) * @return True on success */ - static bool redirectUnixOutputs(const char *stdoutPath,const char *stderrPath = (const char *)0) - throw(); -#endif // __UNIX_LIKE__ + static bool redirectUnixOutputs(const char* stdoutPath, const char* stderrPath = (const char*)0) throw(); +#endif // __UNIX_LIKE__ /** * Delete a file @@ -105,7 +102,7 @@ public: * @param path Path to delete * @return True if delete was successful */ - static inline bool rm(const char *path) + static inline bool rm(const char* path) { #ifdef __WINDOWS__ return (DeleteFileA(path) != FALSE); @@ -113,29 +110,35 @@ public: return (unlink(path) == 0); #endif } - static inline bool rm(const std::string &path) { return rm(path.c_str()); } + static inline bool rm(const std::string& path) + { + return rm(path.c_str()); + } - static inline bool mkdir(const char *path) + static inline bool mkdir(const char* path) { #ifdef __WINDOWS__ if (::PathIsDirectoryA(path)) return true; - return (::CreateDirectoryA(path,NULL) == TRUE); + return (::CreateDirectoryA(path, NULL) == TRUE); #else - if (::mkdir(path,0755) != 0) + if (::mkdir(path, 0755) != 0) return (errno == EEXIST); return true; #endif } - static inline bool mkdir(const std::string &path) { return OSUtils::mkdir(path.c_str()); } + static inline bool mkdir(const std::string& path) + { + return OSUtils::mkdir(path.c_str()); + } - static inline bool rename(const char *o,const char *n) + static inline bool rename(const char* o, const char* n) { #ifdef __WINDOWS__ DeleteFileA(n); - return (::rename(o,n) == 0); + return (::rename(o, n) == 0); #else - return (::rename(o,n) == 0); + return (::rename(o, n) == 0); #endif } @@ -146,7 +149,7 @@ public: * @param includeDirectories If true, include directories as well as files * @return Names of files in directory (without path prepended) */ - static std::vector listDirectory(const char *path,bool includeDirectories = false); + static std::vector listDirectory(const char* path, bool includeDirectories = false); /** * Clean a directory of files whose last modified time is older than this @@ -156,7 +159,7 @@ public: * @param olderThan Last modified older than timestamp (ms since epoch) * @return Number of cleaned files or negative on fatal error */ - static long cleanDirectory(const char *path,const int64_t olderThan); + static long cleanDirectory(const char* path, const int64_t olderThan); /** * Delete a directory and all its files and subdirectories recursively @@ -164,7 +167,7 @@ public: * @param path Path to delete * @return True on success */ - static bool rmDashRf(const char *path); + static bool rmDashRf(const char* path); /** * Set modes on a file to something secure @@ -175,7 +178,7 @@ public: * @param path Path to lock * @param isDir True if this is a directory */ - static void lockDownFile(const char *path,bool isDir); + static void lockDownFile(const char* path, bool isDir); /** * Get file last modification time @@ -186,20 +189,20 @@ public: * @param path Path to file to get time * @return Last modification time in ms since epoch or 0 if not found */ - static uint64_t getLastModified(const char *path); + static uint64_t getLastModified(const char* path); /** * @param path Path to check * @param followLinks Follow links (on platforms with that concept) * @return True if file or directory exists at path location */ - static bool fileExists(const char *path,bool followLinks = true); + static bool fileExists(const char* path, bool followLinks = true); /** * @param path Path to file * @return File size or -1 if nonexistent or other failure */ - static int64_t getFileSize(const char *path); + static int64_t getFileSize(const char* path); /** * Get IP (v4 and/or v6) addresses for a given host @@ -209,7 +212,7 @@ public: * @param name Host name * @return IP addresses in InetAddress sort order or empty vector if not found */ - static std::vector resolve(const char *name); + static std::vector resolve(const char* name); /** * @return Current time in milliseconds since epoch @@ -221,14 +224,14 @@ public: SYSTEMTIME st; ULARGE_INTEGER tmp; GetSystemTime(&st); - SystemTimeToFileTime(&st,&ft); + SystemTimeToFileTime(&st, &ft); tmp.LowPart = ft.dwLowDateTime; tmp.HighPart = ft.dwHighDateTime; - return (int64_t)( ((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds ); + return (int64_t)(((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds); #else struct timeval tv; - gettimeofday(&tv,(struct timezone *)0); - return ( (1000LL * (int64_t)tv.tv_sec) + (int64_t)(tv.tv_usec / 1000) ); + gettimeofday(&tv, (struct timezone*)0); + return ((1000LL * (int64_t)tv.tv_sec) + (int64_t)(tv.tv_usec / 1000)); #endif }; @@ -242,7 +245,7 @@ public: * @param buf Buffer to fill * @return True if open and read successful */ - static bool readFile(const char *path,std::string &buf); + static bool readFile(const char* path, std::string& buf); /** * Write a block of data to disk, replacing any current file contents @@ -252,7 +255,7 @@ public: * @param len Length of buffer * @return True if entire file was successfully written */ - static bool writeFile(const char *path,const void *buf,unsigned int len); + static bool writeFile(const char* path, const void* buf, unsigned int len); /** * Split a string by delimiter, with optional escape and quote characters @@ -263,7 +266,7 @@ public: * @param quot Zero or more quote characters * @return Vector of tokens */ - static std::vector split(const char *s,const char *const sep,const char *esc,const char *quot); + static std::vector split(const char* s, const char* const sep, const char* esc, const char* quot); /** * Write a block of data to disk, replacing any current file contents @@ -272,13 +275,19 @@ public: * @param s Data to write * @return True if entire file was successfully written */ - static inline bool writeFile(const char *path,const std::string &s) { return writeFile(path,s.data(),(unsigned int)s.length()); } + static inline bool writeFile(const char* path, const std::string& s) + { + return writeFile(path, s.data(), (unsigned int)s.length()); + } /** * @param c ASCII character to convert * @return Lower case ASCII character or unchanged if not a letter */ - static inline char toLower(char c) throw() { return (char)OSUtils::TOLOWER_TABLE[(unsigned long)c]; } + static inline char toLower(char c) throw() + { + return (char)OSUtils::TOLOWER_TABLE[(unsigned long)c]; + } /** * @return Platform default ZeroTier One home path @@ -286,20 +295,20 @@ public: static std::string platformDefaultHomePath(); #ifndef OMIT_JSON_SUPPORT - static nlohmann::json jsonParse(const std::string &buf); - static std::string jsonDump(const nlohmann::json &j,int indentation = 1); - static uint64_t jsonInt(const nlohmann::json &jv,const uint64_t dfl); - static double jsonDouble(const nlohmann::json &jv,const double dfl); - static uint64_t jsonIntHex(const nlohmann::json &jv,const uint64_t dfl); - static bool jsonBool(const nlohmann::json &jv,const bool dfl); - static std::string jsonString(const nlohmann::json &jv,const char *dfl); - static std::string jsonBinFromHex(const nlohmann::json &jv); -#endif // OMIT_JSON_SUPPORT + static nlohmann::json jsonParse(const std::string& buf); + static std::string jsonDump(const nlohmann::json& j, int indentation = 1); + static uint64_t jsonInt(const nlohmann::json& jv, const uint64_t dfl); + static double jsonDouble(const nlohmann::json& jv, const double dfl); + static uint64_t jsonIntHex(const nlohmann::json& jv, const uint64_t dfl); + static bool jsonBool(const nlohmann::json& jv, const bool dfl); + static std::string jsonString(const nlohmann::json& jv, const char* dfl); + static std::string jsonBinFromHex(const nlohmann::json& jv); +#endif // OMIT_JSON_SUPPORT -private: + private: static const unsigned char TOLOWER_TABLE[256]; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp index 14cf92ca7..5b1a5fed9 100644 --- a/osdep/Phy.hpp +++ b/osdep/Phy.hpp @@ -14,59 +14,58 @@ #ifndef ZT_PHY_HPP #define ZT_PHY_HPP +#include +#include #include #include #include -#include -#include - #if defined(_WIN32) || defined(_WIN64) +#include #include #include -#include -#define ZT_PHY_SOCKFD_TYPE SOCKET -#define ZT_PHY_SOCKFD_NULL (INVALID_SOCKET) -#define ZT_PHY_SOCKFD_VALID(s) ((s) != INVALID_SOCKET) -#define ZT_PHY_CLOSE_SOCKET(s) ::closesocket(s) -#define ZT_PHY_MAX_SOCKETS (FD_SETSIZE) -#define ZT_PHY_MAX_INTERCEPTS ZT_PHY_MAX_SOCKETS +#define ZT_PHY_SOCKFD_TYPE SOCKET +#define ZT_PHY_SOCKFD_NULL (INVALID_SOCKET) +#define ZT_PHY_SOCKFD_VALID(s) ((s) != INVALID_SOCKET) +#define ZT_PHY_CLOSE_SOCKET(s) ::closesocket(s) +#define ZT_PHY_MAX_SOCKETS (FD_SETSIZE) +#define ZT_PHY_MAX_INTERCEPTS ZT_PHY_MAX_SOCKETS #define ZT_PHY_SOCKADDR_STORAGE_TYPE struct sockaddr_storage -#else // not Windows - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#else // not Windows #include "../node/Metrics.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) #ifndef IPV6_DONTFRAG #define IPV6_DONTFRAG 62 #endif #endif -#define ZT_PHY_SOCKFD_TYPE int -#define ZT_PHY_SOCKFD_NULL (-1) -#define ZT_PHY_SOCKFD_VALID(s) ((s) > -1) -#define ZT_PHY_CLOSE_SOCKET(s) ::close(s) -#define ZT_PHY_MAX_SOCKETS (FD_SETSIZE) -#define ZT_PHY_MAX_INTERCEPTS ZT_PHY_MAX_SOCKETS +#define ZT_PHY_SOCKFD_TYPE int +#define ZT_PHY_SOCKFD_NULL (-1) +#define ZT_PHY_SOCKFD_VALID(s) ((s) > -1) +#define ZT_PHY_CLOSE_SOCKET(s) ::close(s) +#define ZT_PHY_MAX_SOCKETS (FD_SETSIZE) +#define ZT_PHY_MAX_INTERCEPTS ZT_PHY_MAX_SOCKETS #define ZT_PHY_SOCKADDR_STORAGE_TYPE struct sockaddr_storage -#endif // Windows or not +#endif // Windows or not namespace ZeroTier { @@ -122,15 +121,12 @@ typedef void PhySocket; * This isn't thread-safe with the exception of whack(), which is safe to * call from another thread to abort poll(). */ -template -class Phy -{ -private: +template class Phy { + private: HANDLER_PTR_TYPE _handler; - enum PhySocketType - { - ZT_PHY_SOCKET_CLOSED = 0x00, // socket is closed, will be removed on next poll() + enum PhySocketType { + ZT_PHY_SOCKET_CLOSED = 0x00, // socket is closed, will be removed on next poll() ZT_PHY_SOCKET_TCP_OUT_PENDING = 0x01, ZT_PHY_SOCKET_TCP_OUT_CONNECTED = 0x02, ZT_PHY_SOCKET_TCP_IN = 0x03, @@ -142,12 +138,14 @@ private: }; struct PhySocketImpl { - PhySocketImpl() {} + PhySocketImpl() + { + } PhySocketType type; ZT_PHY_SOCKFD_TYPE sock; - void *uptr; // user-settable pointer + void* uptr; // user-settable pointer uint16_t localPort; - ZT_PHY_SOCKADDR_STORAGE_TYPE saddr; // remote for TCP_OUT and TCP_IN, local for TCP_LISTEN, RAW, and UDP + ZT_PHY_SOCKADDR_STORAGE_TYPE saddr; // remote for TCP_OUT and TCP_IN, local for TCP_LISTEN, RAW, and UDP }; std::list _socks; @@ -164,14 +162,13 @@ private: bool _noDelay; bool _noCheck; -public: + public: /** * @param handler Pointer of type HANDLER_PTR_TYPE to handler * @param noDelay If true, disable TCP NAGLE algorithm on TCP sockets * @param noCheck If true, attempt to set UDP SO_NO_CHECK option to disable sending checksums */ - Phy(HANDLER_PTR_TYPE handler,bool noDelay,bool noCheck) : - _handler(handler) + Phy(HANDLER_PTR_TYPE handler, bool noDelay, bool noCheck) : _handler(handler) { FD_ZERO(&_readfds); FD_ZERO(&_writefds); @@ -183,7 +180,7 @@ public: { // hack copied from StackOverflow, behaves a bit like pipe() on *nix systems struct sockaddr_in inaddr; struct sockaddr addr; - SOCKET lst=::socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); + SOCKET lst = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (lst == INVALID_SOCKET) throw std::runtime_error("unable to create pipes for select() abort"); memset(&inaddr, 0, sizeof(inaddr)); @@ -191,24 +188,24 @@ public: inaddr.sin_family = AF_INET; inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); inaddr.sin_port = 0; - int yes=1; - setsockopt(lst,SOL_SOCKET,SO_REUSEADDR,(char*)&yes,sizeof(yes)); - bind(lst,(struct sockaddr *)&inaddr,sizeof(inaddr)); - listen(lst,1); - int len=sizeof(inaddr); - getsockname(lst, &addr,&len); - pipes[0]=::socket(AF_INET, SOCK_STREAM,0); + int yes = 1; + setsockopt(lst, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)); + bind(lst, (struct sockaddr*)&inaddr, sizeof(inaddr)); + listen(lst, 1); + int len = sizeof(inaddr); + getsockname(lst, &addr, &len); + pipes[0] = ::socket(AF_INET, SOCK_STREAM, 0); if (pipes[0] == INVALID_SOCKET) throw std::runtime_error("unable to create pipes for select() abort"); - connect(pipes[0],&addr,len); - pipes[1]=accept(lst,0,0); + connect(pipes[0], &addr, len); + pipes[1] = accept(lst, 0, 0); closesocket(lst); } -#else // not Windows +#else // not Windows int pipes[2]; if (::pipe(pipes)) throw std::runtime_error("unable to create pipes for select() abort"); -#endif // Windows or not +#endif // Windows or not _nfds = (pipes[0] > pipes[1]) ? (long)pipes[0] : (long)pipes[1]; _whackReceiveSocket = pipes[0]; @@ -219,9 +216,9 @@ public: ~Phy() { - for(typename std::list::const_iterator s(_socks.begin());s!=_socks.end();++s) { + for (typename std::list::const_iterator s(_socks.begin()); s != _socks.end(); ++s) { if (s->type != ZT_PHY_SOCKET_CLOSED) - this->close((PhySocket *)&(*s),true); + this->close((PhySocket*)&(*s), true); } ZT_PHY_CLOSE_SOCKET(_whackReceiveSocket); ZT_PHY_CLOSE_SOCKET(_whackSendSocket); @@ -309,25 +306,26 @@ public: * @param uptr User pointer to supply to callbacks * @return PhySocket wrapping fd or NULL on failure (out of memory or too many sockets) */ - inline PhySocket *wrapSocket(ZT_PHY_SOCKFD_TYPE fd,void *uptr = (void *)0) + inline PhySocket* wrapSocket(ZT_PHY_SOCKFD_TYPE fd, void* uptr = (void*)0) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) - return (PhySocket *)0; + return (PhySocket*)0; try { _socks.push_back(PhySocketImpl()); - } catch ( ... ) { - return (PhySocket *)0; } - PhySocketImpl &sws = _socks.back(); + catch (...) { + return (PhySocket*)0; + } + PhySocketImpl& sws = _socks.back(); if ((long)fd > _nfds) _nfds = (long)fd; - FD_SET(fd,&_readfds); + FD_SET(fd, &_readfds); sws.type = ZT_PHY_SOCKET_UNIX_IN; /* TODO: Type was changed to allow for CBs with new RPC model */ sws.sock = fd; sws.uptr = uptr; - memset(&(sws.saddr),0,sizeof(struct sockaddr_storage)); + memset(&(sws.saddr), 0, sizeof(struct sockaddr_storage)); // no sockaddr for this socket type, leave saddr null - return (PhySocket *)&sws; + return (PhySocket*)&sws; } /** @@ -338,27 +336,27 @@ public: * @param bufferSize Desired socket receive/send buffer size -- will set as close to this as possible (default: 0, leave alone) * @return Socket or NULL on failure to bind */ - inline PhySocket *udpBind(const struct sockaddr *localAddress,void *uptr = (void *)0,int bufferSize = 0) + inline PhySocket* udpBind(const struct sockaddr* localAddress, void* uptr = (void*)0, int bufferSize = 0) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) - return (PhySocket *)0; + return (PhySocket*)0; - ZT_PHY_SOCKFD_TYPE s = ::socket(localAddress->sa_family,SOCK_DGRAM,0); - if (!ZT_PHY_SOCKFD_VALID(s)) - return (PhySocket *)0; + ZT_PHY_SOCKFD_TYPE s = ::socket(localAddress->sa_family, SOCK_DGRAM, 0); + if (! ZT_PHY_SOCKFD_VALID(s)) + return (PhySocket*)0; if (bufferSize > 0) { int bs = bufferSize; while (bs >= 65536) { int tmpbs = bs; - if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0) break; bs -= 4096; } bs = bufferSize; while (bs >= 65536) { int tmpbs = bs; - if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0) break; bs -= 4096; } @@ -368,77 +366,93 @@ public: { BOOL f; if (localAddress->sa_family == AF_INET6) { - f = TRUE; setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&f,sizeof(f)); - f = FALSE; setsockopt(s,IPPROTO_IPV6,IPV6_DONTFRAG,(const char *)&f,sizeof(f)); + f = TRUE; + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&f, sizeof(f)); + f = FALSE; + setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG, (const char*)&f, sizeof(f)); } - f = FALSE; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char *)&f,sizeof(f)); - f = TRUE; setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char *)&f,sizeof(f)); + f = FALSE; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&f, sizeof(f)); + f = TRUE; + setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char*)&f, sizeof(f)); } -#else // not Windows +#else // not Windows { int f; if (localAddress->sa_family == AF_INET6) { - f = 1; setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&f,sizeof(f)); + f = 1; + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&f, sizeof(f)); #ifdef IPV6_MTU_DISCOVER - f = 0; setsockopt(s,IPPROTO_IPV6,IPV6_MTU_DISCOVER,&f,sizeof(f)); + f = 0; + setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &f, sizeof(f)); #endif #ifdef IPV6_DONTFRAG - f = 0; setsockopt(s,IPPROTO_IPV6,IPV6_DONTFRAG,&f,sizeof(f)); + f = 0; + setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG, &f, sizeof(f)); #endif } - f = 0; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); - f = 1; setsockopt(s,SOL_SOCKET,SO_BROADCAST,(void *)&f,sizeof(f)); + f = 0; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&f, sizeof(f)); + f = 1; + setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void*)&f, sizeof(f)); #ifdef IP_DONTFRAG - f = 0; setsockopt(s,IPPROTO_IP,IP_DONTFRAG,&f,sizeof(f)); + f = 0; + setsockopt(s, IPPROTO_IP, IP_DONTFRAG, &f, sizeof(f)); #endif #ifdef IP_MTU_DISCOVER - f = 0; setsockopt(s,IPPROTO_IP,IP_MTU_DISCOVER,&f,sizeof(f)); + f = 0; + setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &f, sizeof(f)); #endif #ifdef SO_NO_CHECK // For now at least we only set SO_NO_CHECK on IPv4 sockets since some // IPv6 stacks incorrectly discard zero checksum packets. May remove // this restriction later once broken stuff dies more. - if ((localAddress->sa_family == AF_INET)&&(_noCheck)) { - f = 1; setsockopt(s,SOL_SOCKET,SO_NO_CHECK,(void *)&f,sizeof(f)); + if ((localAddress->sa_family == AF_INET) && (_noCheck)) { + f = 1; + setsockopt(s, SOL_SOCKET, SO_NO_CHECK, (void*)&f, sizeof(f)); } #endif } -#endif // Windows or not +#endif // Windows or not - if (::bind(s,localAddress,(localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { + if (::bind(s, localAddress, (localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; + return (PhySocket*)0; } #if defined(_WIN32) || defined(_WIN64) - { u_long iMode=1; ioctlsocket(s,FIONBIO,&iMode); } + { + u_long iMode = 1; + ioctlsocket(s, FIONBIO, &iMode); + } #else - fcntl(s,F_SETFL,O_NONBLOCK); + fcntl(s, F_SETFL, O_NONBLOCK); #endif try { _socks.push_back(PhySocketImpl()); - } catch ( ... ) { - ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; } - PhySocketImpl &sws = _socks.back(); + catch (...) { + ZT_PHY_CLOSE_SOCKET(s); + return (PhySocket*)0; + } + PhySocketImpl& sws = _socks.back(); if ((long)s > _nfds) _nfds = (long)s; - FD_SET(s,&_readfds); + FD_SET(s, &_readfds); sws.type = ZT_PHY_SOCKET_UDP; sws.sock = s; sws.uptr = uptr; #ifdef __UNIX_LIKE__ - struct sockaddr_in *sin = (struct sockaddr_in *)localAddress; + struct sockaddr_in* sin = (struct sockaddr_in*)localAddress; sws.localPort = htons(sin->sin_port); #endif - memset(&(sws.saddr),0,sizeof(struct sockaddr_storage)); - memcpy(&(sws.saddr),localAddress,(localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + memset(&(sws.saddr), 0, sizeof(struct sockaddr_storage)); + memcpy(&(sws.saddr), localAddress, (localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - return (PhySocket *)&sws; + return (PhySocket*)&sws; } /** @@ -447,15 +461,15 @@ public: * @param ttl New TTL (0 or >255 will set it to 255) * @return True on success */ - inline bool setIp4UdpTtl(PhySocket *sock,unsigned int ttl) + inline bool setIp4UdpTtl(PhySocket* sock, unsigned int ttl) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); #if defined(_WIN32) || defined(_WIN64) - DWORD tmp = ((ttl == 0)||(ttl > 255)) ? 255 : (DWORD)ttl; - return (::setsockopt(sws.sock,IPPROTO_IP,IP_TTL,(const char *)&tmp,sizeof(tmp)) == 0); + DWORD tmp = ((ttl == 0) || (ttl > 255)) ? 255 : (DWORD)ttl; + return (::setsockopt(sws.sock, IPPROTO_IP, IP_TTL, (const char*)&tmp, sizeof(tmp)) == 0); #else - int tmp = ((ttl == 0)||(ttl > 255)) ? 255 : (int)ttl; - return (::setsockopt(sws.sock,IPPROTO_IP,IP_TTL,(void *)&tmp,sizeof(tmp)) == 0); + int tmp = ((ttl == 0) || (ttl > 255)) ? 255 : (int)ttl; + return (::setsockopt(sws.sock, IPPROTO_IP, IP_TTL, (void*)&tmp, sizeof(tmp)) == 0); #endif } @@ -468,30 +482,14 @@ public: * @param len Length of packet * @return True if packet appears to have been sent successfully */ - inline bool udpSend(PhySocket *sock,const struct sockaddr *remoteAddress,const void *data,unsigned long len) + inline bool udpSend(PhySocket* sock, const struct sockaddr* remoteAddress, const void* data, unsigned long len) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); bool sent = false; #if defined(_WIN32) || defined(_WIN64) - sent = ((long)::sendto( - sws.sock, - reinterpret_cast(data), - len, - 0, - remoteAddress, - (remoteAddress->sa_family == AF_INET6) ? - sizeof(struct sockaddr_in6) : - sizeof(struct sockaddr_in)) == (long)len); + sent = ((long)::sendto(sws.sock, reinterpret_cast(data), len, 0, remoteAddress, (remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) == (long)len); #else - sent = ((long)::sendto( - sws.sock, - data, - len, - 0, - remoteAddress, - (remoteAddress->sa_family == AF_INET6) ? - sizeof(struct sockaddr_in6) : - sizeof(struct sockaddr_in)) == (long)len); + sent = ((long)::sendto(sws.sock, data, len, 0, remoteAddress, (remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) == (long)len); #endif if (sent) { Metrics::udp_send += len; @@ -508,55 +506,56 @@ public: * @param uptr Arbitrary pointer to associate * @return PhySocket or NULL if cannot bind */ - inline PhySocket *unixListen(const char *path,void *uptr = (void *)0) + inline PhySocket* unixListen(const char* path, void* uptr = (void*)0) { struct sockaddr_un sun; if (_socks.size() >= ZT_PHY_MAX_SOCKETS) - return (PhySocket *)0; + return (PhySocket*)0; - memset(&sun,0,sizeof(sun)); + memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; if (strlen(path) >= sizeof(sun.sun_path)) - return (PhySocket *)0; - strcpy(sun.sun_path,path); + return (PhySocket*)0; + strcpy(sun.sun_path, path); - ZT_PHY_SOCKFD_TYPE s = ::socket(PF_UNIX,SOCK_STREAM,0); - if (!ZT_PHY_SOCKFD_VALID(s)) - return (PhySocket *)0; + ZT_PHY_SOCKFD_TYPE s = ::socket(PF_UNIX, SOCK_STREAM, 0); + if (! ZT_PHY_SOCKFD_VALID(s)) + return (PhySocket*)0; - ::fcntl(s,F_SETFL,O_NONBLOCK); + ::fcntl(s, F_SETFL, O_NONBLOCK); ::unlink(path); - if (::bind(s,(struct sockaddr *)&sun,sizeof(struct sockaddr_un)) != 0) { + if (::bind(s, (struct sockaddr*)&sun, sizeof(struct sockaddr_un)) != 0) { ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; + return (PhySocket*)0; } - if (::listen(s,128) != 0) { + if (::listen(s, 128) != 0) { ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; + return (PhySocket*)0; } try { _socks.push_back(PhySocketImpl()); - } catch ( ... ) { - ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; } - PhySocketImpl &sws = _socks.back(); + catch (...) { + ZT_PHY_CLOSE_SOCKET(s); + return (PhySocket*)0; + } + PhySocketImpl& sws = _socks.back(); if ((long)s > _nfds) _nfds = (long)s; - FD_SET(s,&_readfds); + FD_SET(s, &_readfds); sws.type = ZT_PHY_SOCKET_UNIX_LISTEN; sws.sock = s; sws.uptr = uptr; - memset(&(sws.saddr),0,sizeof(struct sockaddr_storage)); - memcpy(&(sws.saddr),&sun,sizeof(struct sockaddr_un)); + memset(&(sws.saddr), 0, sizeof(struct sockaddr_storage)); + memcpy(&(sws.saddr), &sun, sizeof(struct sockaddr_un)); - return (PhySocket *)&sws; + return (PhySocket*)&sws; } -#endif // __UNIX_LIKE__ +#endif // __UNIX_LIKE__ /** * Bind a local listen socket to listen for new TCP connections @@ -565,62 +564,69 @@ public: * @param uptr Initial value of uptr for new socket (default: NULL) * @return Socket or NULL on failure to bind */ - inline PhySocket *tcpListen(const struct sockaddr *localAddress,void *uptr = (void *)0) + inline PhySocket* tcpListen(const struct sockaddr* localAddress, void* uptr = (void*)0) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) - return (PhySocket *)0; + return (PhySocket*)0; - ZT_PHY_SOCKFD_TYPE s = ::socket(localAddress->sa_family,SOCK_STREAM,0); - if (!ZT_PHY_SOCKFD_VALID(s)) - return (PhySocket *)0; + ZT_PHY_SOCKFD_TYPE s = ::socket(localAddress->sa_family, SOCK_STREAM, 0); + if (! ZT_PHY_SOCKFD_VALID(s)) + return (PhySocket*)0; #if defined(_WIN32) || defined(_WIN64) { BOOL f; - f = TRUE; ::setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&f,sizeof(f)); - f = TRUE; ::setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char *)&f,sizeof(f)); - f = (_noDelay ? TRUE : FALSE); setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); - u_long iMode=1; - ioctlsocket(s,FIONBIO,&iMode); + f = TRUE; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&f, sizeof(f)); + f = TRUE; + ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&f, sizeof(f)); + f = (_noDelay ? TRUE : FALSE); + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + u_long iMode = 1; + ioctlsocket(s, FIONBIO, &iMode); } #else { int f; - f = 1; ::setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&f,sizeof(f)); - f = 1; ::setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); - f = (_noDelay ? 1 : 0); setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); - fcntl(s,F_SETFL,O_NONBLOCK); + f = 1; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&f, sizeof(f)); + f = 1; + ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&f, sizeof(f)); + f = (_noDelay ? 1 : 0); + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + fcntl(s, F_SETFL, O_NONBLOCK); } #endif - if (::bind(s,localAddress,(localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { + if (::bind(s, localAddress, (localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; + return (PhySocket*)0; } - if (::listen(s,1024)) { + if (::listen(s, 1024)) { ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; + return (PhySocket*)0; } try { _socks.push_back(PhySocketImpl()); - } catch ( ... ) { - ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; } - PhySocketImpl &sws = _socks.back(); + catch (...) { + ZT_PHY_CLOSE_SOCKET(s); + return (PhySocket*)0; + } + PhySocketImpl& sws = _socks.back(); if ((long)s > _nfds) _nfds = (long)s; - FD_SET(s,&_readfds); + FD_SET(s, &_readfds); sws.type = ZT_PHY_SOCKET_TCP_LISTEN; sws.sock = s; sws.uptr = uptr; - memset(&(sws.saddr),0,sizeof(struct sockaddr_storage)); - memcpy(&(sws.saddr),localAddress,(localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + memset(&(sws.saddr), 0, sizeof(struct sockaddr_storage)); + memcpy(&(sws.saddr), localAddress, (localAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - return (PhySocket *)&sws; + return (PhySocket*)&sws; } /** @@ -645,38 +651,48 @@ public: * @param callConnectHandler If true, call TCP connect handler even if result is known before function exit (default: true) * @return New socket or NULL on failure */ - inline PhySocket *tcpConnect(const struct sockaddr *remoteAddress,bool &connected,void *uptr = (void *)0,bool callConnectHandler = true) + inline PhySocket* tcpConnect(const struct sockaddr* remoteAddress, bool& connected, void* uptr = (void*)0, bool callConnectHandler = true) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) - return (PhySocket *)0; + return (PhySocket*)0; - ZT_PHY_SOCKFD_TYPE s = ::socket(remoteAddress->sa_family,SOCK_STREAM,0); - if (!ZT_PHY_SOCKFD_VALID(s)) { + ZT_PHY_SOCKFD_TYPE s = ::socket(remoteAddress->sa_family, SOCK_STREAM, 0); + if (! ZT_PHY_SOCKFD_VALID(s)) { connected = false; - return (PhySocket *)0; + return (PhySocket*)0; } #if defined(_WIN32) || defined(_WIN64) { BOOL f; - if (remoteAddress->sa_family == AF_INET6) { f = TRUE; ::setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&f,sizeof(f)); } - f = TRUE; ::setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char *)&f,sizeof(f)); - f = (_noDelay ? TRUE : FALSE); setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); - u_long iMode=1; - ioctlsocket(s,FIONBIO,&iMode); + if (remoteAddress->sa_family == AF_INET6) { + f = TRUE; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&f, sizeof(f)); + } + f = TRUE; + ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&f, sizeof(f)); + f = (_noDelay ? TRUE : FALSE); + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + u_long iMode = 1; + ioctlsocket(s, FIONBIO, &iMode); } #else { int f; - if (remoteAddress->sa_family == AF_INET6) { f = 1; ::setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&f,sizeof(f)); } - f = 1; ::setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); - f = (_noDelay ? 1 : 0); setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); - fcntl(s,F_SETFL,O_NONBLOCK); + if (remoteAddress->sa_family == AF_INET6) { + f = 1; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&f, sizeof(f)); + } + f = 1; + ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&f, sizeof(f)); + f = (_noDelay ? 1 : 0); + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + fcntl(s, F_SETFL, O_NONBLOCK); } #endif connected = true; - if (::connect(s,remoteAddress,(remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { + if (::connect(s, remoteAddress, (remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { connected = false; #if defined(_WIN32) || defined(_WIN64) if (WSAGetLastError() != WSAEWOULDBLOCK) { @@ -684,42 +700,46 @@ public: if (errno != EINPROGRESS) { #endif ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; - } // else connection is proceeding asynchronously... + return (PhySocket*)0; + } // else connection is proceeding asynchronously... } try { _socks.push_back(PhySocketImpl()); - } catch ( ... ) { - ZT_PHY_CLOSE_SOCKET(s); - return (PhySocket *)0; } - PhySocketImpl &sws = _socks.back(); + catch (...) { + ZT_PHY_CLOSE_SOCKET(s); + return (PhySocket*)0; + } + PhySocketImpl& sws = _socks.back(); if ((long)s > _nfds) _nfds = (long)s; if (connected) { - FD_SET(s,&_readfds); + FD_SET(s, &_readfds); sws.type = ZT_PHY_SOCKET_TCP_OUT_CONNECTED; - } else { - FD_SET(s,&_writefds); + } + else { + FD_SET(s, &_writefds); #if defined(_WIN32) || defined(_WIN64) - FD_SET(s,&_exceptfds); + FD_SET(s, &_exceptfds); #endif sws.type = ZT_PHY_SOCKET_TCP_OUT_PENDING; } sws.sock = s; sws.uptr = uptr; - memset(&(sws.saddr),0,sizeof(struct sockaddr_storage)); - memcpy(&(sws.saddr),remoteAddress,(remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + memset(&(sws.saddr), 0, sizeof(struct sockaddr_storage)); + memcpy(&(sws.saddr), remoteAddress, (remoteAddress->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - if ((callConnectHandler)&&(connected)) { + if ((callConnectHandler) && (connected)) { try { - _handler->phyOnTcpConnect((PhySocket *)&sws,&(sws.uptr),true); - } catch ( ... ) {} + _handler->phyOnTcpConnect((PhySocket*)&sws, &(sws.uptr), true); + } + catch (...) { + } } - return (PhySocket *)&sws; + return (PhySocket*)&sws; } /** @@ -732,13 +752,13 @@ public: * @param receiveBufferSize Desired size of receive buffer * @param sendBufferSize Desired size of send buffer */ - inline void setBufferSizes(const PhySocket *sock,int receiveBufferSize,int sendBufferSize) + inline void setBufferSizes(const PhySocket* sock, int receiveBufferSize, int sendBufferSize) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); if (receiveBufferSize > 0) { while (receiveBufferSize > 0) { int tmpbs = receiveBufferSize; - if (::setsockopt(sws.sock,SOL_SOCKET,SO_RCVBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) + if (::setsockopt(sws.sock, SOL_SOCKET, SO_RCVBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0) break; receiveBufferSize -= 16384; } @@ -746,7 +766,7 @@ public: if (sendBufferSize > 0) { while (sendBufferSize > 0) { int tmpbs = sendBufferSize; - if (::setsockopt(sws.sock,SOL_SOCKET,SO_SNDBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) + if (::setsockopt(sws.sock, SOL_SOCKET, SO_SNDBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0) break; sendBufferSize -= 16384; } @@ -768,29 +788,29 @@ public: * @param callCloseHandler If true, call close handler on socket closing failure condition (default: true) * @return Number of bytes actually sent or -1 on fatal error (socket closure) */ - inline long streamSend(PhySocket *sock,const void *data,unsigned long len,bool callCloseHandler = true) + inline long streamSend(PhySocket* sock, const void* data, unsigned long len, bool callCloseHandler = true) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); #if defined(_WIN32) || defined(_WIN64) - long n = (long)::send(sws.sock,reinterpret_cast(data),len,0); + long n = (long)::send(sws.sock, reinterpret_cast(data), len, 0); if (n == SOCKET_ERROR) { - switch(WSAGetLastError()) { - case WSAEINTR: - case WSAEWOULDBLOCK: - return 0; - default: - this->close(sock,callCloseHandler); - return -1; - } + switch (WSAGetLastError()) { + case WSAEINTR: + case WSAEWOULDBLOCK: + return 0; + default: + this->close(sock, callCloseHandler); + return -1; + } } -#else // not Windows - long n = (long)::send(sws.sock,data,len,0); +#else // not Windows + long n = (long)::send(sws.sock, data, len, 0); if (n < 0) { - switch(errno) { + switch (errno) { #ifdef EAGAIN case EAGAIN: #endif -#if defined(EWOULDBLOCK) && ( !defined(EAGAIN) || (EWOULDBLOCK != EAGAIN) ) +#if defined(EWOULDBLOCK) && (! defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: #endif #ifdef EINTR @@ -798,11 +818,11 @@ public: #endif return 0; default: - this->close(sock,callCloseHandler); + this->close(sock, callCloseHandler); return -1; } } -#endif // Windows or not +#endif // Windows or not return n; } @@ -820,16 +840,16 @@ public: * @param callCloseHandler If true, call close handler on socket closing failure condition (default: true) * @return Number of bytes actually sent or -1 on fatal error (socket closure) */ - inline long unixSend(PhySocket *sock,const void *data,unsigned long len,bool callCloseHandler = true) + inline long unixSend(PhySocket* sock, const void* data, unsigned long len, bool callCloseHandler = true) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); - long n = (long)::write(sws.sock,data,len); + PhySocketImpl& sws = *(reinterpret_cast(sock)); + long n = (long)::write(sws.sock, data, len); if (n < 0) { - switch(errno) { + switch (errno) { #ifdef EAGAIN case EAGAIN: #endif -#if defined(EWOULDBLOCK) && ( !defined(EAGAIN) || (EWOULDBLOCK != EAGAIN) ) +#if defined(EWOULDBLOCK) && (! defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: #endif #ifdef EINTR @@ -837,13 +857,13 @@ public: #endif return 0; default: - this->close(sock,callCloseHandler); + this->close(sock, callCloseHandler); return -1; } } return n; } -#endif // __UNIX_LIKE__ +#endif // __UNIX_LIKE__ /** * For streams, sets whether we want to be notified that the socket is writable @@ -857,13 +877,14 @@ public: * @param sock Stream connection socket * @param notifyWritable Want writable notifications? */ - inline void setNotifyWritable(PhySocket *sock,bool notifyWritable) + inline void setNotifyWritable(PhySocket* sock, bool notifyWritable) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); if (notifyWritable) { - FD_SET(sws.sock,&_writefds); - } else { - FD_CLR(sws.sock,&_writefds); + FD_SET(sws.sock, &_writefds); + } + else { + FD_CLR(sws.sock, &_writefds); } } @@ -877,13 +898,14 @@ public: * @param sock Socket to modify * @param notifyReadable True if socket should be monitored for readability */ - inline void setNotifyReadable(PhySocket *sock,bool notifyReadable) + inline void setNotifyReadable(PhySocket* sock, bool notifyReadable) { - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); if (notifyReadable) { - FD_SET(sws.sock,&_readfds); - } else { - FD_CLR(sws.sock,&_readfds); + FD_SET(sws.sock, &_readfds); + } + else { + FD_CLR(sws.sock, &_readfds); } } @@ -901,105 +923,125 @@ public: char buf[131072]; struct sockaddr_storage ss; struct timeval tv; - fd_set rfds,wfds,efds; + fd_set rfds, wfds, efds; - memcpy(&rfds,&_readfds,sizeof(rfds)); - memcpy(&wfds,&_writefds,sizeof(wfds)); + memcpy(&rfds, &_readfds, sizeof(rfds)); + memcpy(&wfds, &_writefds, sizeof(wfds)); #if defined(_WIN32) || defined(_WIN64) - memcpy(&efds,&_exceptfds,sizeof(efds)); + memcpy(&efds, &_exceptfds, sizeof(efds)); #else FD_ZERO(&efds); #endif tv.tv_sec = (long)(timeout / 1000); tv.tv_usec = (long)((timeout % 1000) * 1000); - if (::select((int)_nfds + 1,&rfds,&wfds,&efds,(timeout > 0) ? &tv : (struct timeval *)0) <= 0) + if (::select((int)_nfds + 1, &rfds, &wfds, &efds, (timeout > 0) ? &tv : (struct timeval*)0) <= 0) return; - if (FD_ISSET(_whackReceiveSocket,&rfds)) { + if (FD_ISSET(_whackReceiveSocket, &rfds)) { char tmp[16]; #if defined(_WIN32) || defined(_WIN64) - ::recv(_whackReceiveSocket,tmp,16,0); + ::recv(_whackReceiveSocket, tmp, 16, 0); #else - ::read(_whackReceiveSocket,tmp,16); + ::read(_whackReceiveSocket, tmp, 16); #endif } - for(typename std::list::iterator s(_socks.begin());s!=_socks.end();) { + for (typename std::list::iterator s(_socks.begin()); s != _socks.end();) { switch (s->type) { - case ZT_PHY_SOCKET_TCP_OUT_PENDING: #if defined(_WIN32) || defined(_WIN64) - if (FD_ISSET(s->sock,&efds)) { - this->close((PhySocket *)&(*s),true); - } else // ... if + if (FD_ISSET(s->sock, &efds)) { + this->close((PhySocket*)&(*s), true); + } + else // ... if #endif - if (FD_ISSET(s->sock,&wfds)) { + if (FD_ISSET(s->sock, &wfds)) { socklen_t slen = sizeof(ss); - if (::getpeername(s->sock,(struct sockaddr *)&ss,&slen) != 0) { - this->close((PhySocket *)&(*s),true); - } else { + if (::getpeername(s->sock, (struct sockaddr*)&ss, &slen) != 0) { + this->close((PhySocket*)&(*s), true); + } + else { s->type = ZT_PHY_SOCKET_TCP_OUT_CONNECTED; - FD_SET(s->sock,&_readfds); - FD_CLR(s->sock,&_writefds); + FD_SET(s->sock, &_readfds); + FD_CLR(s->sock, &_writefds); #if defined(_WIN32) || defined(_WIN64) - FD_CLR(s->sock,&_exceptfds); + FD_CLR(s->sock, &_exceptfds); #endif try { - _handler->phyOnTcpConnect((PhySocket *)&(*s),&(s->uptr),true); - } catch ( ... ) {} + _handler->phyOnTcpConnect((PhySocket*)&(*s), &(s->uptr), true); + } + catch (...) { + } } } break; case ZT_PHY_SOCKET_TCP_OUT_CONNECTED: case ZT_PHY_SOCKET_TCP_IN: { - ZT_PHY_SOCKFD_TYPE sock = s->sock; // if closed, s->sock becomes invalid as s is no longer dereferencable - if (FD_ISSET(sock,&rfds)) { - long n = (long)::recv(sock,buf,sizeof(buf),0); + ZT_PHY_SOCKFD_TYPE sock = s->sock; // if closed, s->sock becomes invalid as s is no longer dereferencable + if (FD_ISSET(sock, &rfds)) { + long n = (long)::recv(sock, buf, sizeof(buf), 0); if (n <= 0) { - this->close((PhySocket *)&(*s),true); - } else { + this->close((PhySocket*)&(*s), true); + } + else { try { - _handler->phyOnTcpData((PhySocket *)&(*s),&(s->uptr),(void *)buf,(unsigned long)n); - } catch ( ... ) {} + _handler->phyOnTcpData((PhySocket*)&(*s), &(s->uptr), (void*)buf, (unsigned long)n); + } + catch (...) { + } } } - if ((FD_ISSET(sock,&wfds))&&(FD_ISSET(sock,&_writefds))) { + if ((FD_ISSET(sock, &wfds)) && (FD_ISSET(sock, &_writefds))) { try { - _handler->phyOnTcpWritable((PhySocket *)&(*s),&(s->uptr)); - } catch ( ... ) {} + _handler->phyOnTcpWritable((PhySocket*)&(*s), &(s->uptr)); + } + catch (...) { + } } - } break; + } break; case ZT_PHY_SOCKET_TCP_LISTEN: - if (FD_ISSET(s->sock,&rfds)) { - memset(&ss,0,sizeof(ss)); + if (FD_ISSET(s->sock, &rfds)) { + memset(&ss, 0, sizeof(ss)); socklen_t slen = sizeof(ss); - ZT_PHY_SOCKFD_TYPE newSock = ::accept(s->sock,(struct sockaddr *)&ss,&slen); + ZT_PHY_SOCKFD_TYPE newSock = ::accept(s->sock, (struct sockaddr*)&ss, &slen); if (ZT_PHY_SOCKFD_VALID(newSock)) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) { ZT_PHY_CLOSE_SOCKET(newSock); - } else { + } + else { #if defined(_WIN32) || defined(_WIN64) - { BOOL f = (_noDelay ? TRUE : FALSE); setsockopt(newSock,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); } - { u_long iMode=1; ioctlsocket(newSock,FIONBIO,&iMode); } + { + BOOL f = (_noDelay ? TRUE : FALSE); + setsockopt(newSock, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + } + { + u_long iMode = 1; + ioctlsocket(newSock, FIONBIO, &iMode); + } #else - { int f = (_noDelay ? 1 : 0); setsockopt(newSock,IPPROTO_TCP,TCP_NODELAY,(char *)&f,sizeof(f)); } - fcntl(newSock,F_SETFL,O_NONBLOCK); + { + int f = (_noDelay ? 1 : 0); + setsockopt(newSock, IPPROTO_TCP, TCP_NODELAY, (char*)&f, sizeof(f)); + } + fcntl(newSock, F_SETFL, O_NONBLOCK); #endif _socks.push_back(PhySocketImpl()); - PhySocketImpl &sws = _socks.back(); - FD_SET(newSock,&_readfds); + PhySocketImpl& sws = _socks.back(); + FD_SET(newSock, &_readfds); if ((long)newSock > _nfds) _nfds = (long)newSock; sws.type = ZT_PHY_SOCKET_TCP_IN; sws.sock = newSock; - sws.uptr = (void *)0; - memcpy(&(sws.saddr),&ss,sizeof(struct sockaddr_storage)); + sws.uptr = (void*)0; + memcpy(&(sws.saddr), &ss, sizeof(struct sockaddr_storage)); try { - _handler->phyOnTcpAccept((PhySocket *)&(*s),(PhySocket *)&(_socks.back()),&(s->uptr),&(sws.uptr),(const struct sockaddr *)&(sws.saddr)); - } catch ( ... ) {} + _handler->phyOnTcpAccept((PhySocket*)&(*s), (PhySocket*)&(_socks.back()), &(s->uptr), &(sws.uptr), (const struct sockaddr*)&(sws.saddr)); + } + catch (...) { + } } } } @@ -1066,73 +1108,83 @@ public: case ZT_PHY_SOCKET_UNIX_IN: { #ifdef __UNIX_LIKE__ - ZT_PHY_SOCKFD_TYPE sock = s->sock; // if closed, s->sock becomes invalid as s is no longer dereferencable - if ((FD_ISSET(sock,&wfds))&&(FD_ISSET(sock,&_writefds))) { + ZT_PHY_SOCKFD_TYPE sock = s->sock; // if closed, s->sock becomes invalid as s is no longer dereferencable + if ((FD_ISSET(sock, &wfds)) && (FD_ISSET(sock, &_writefds))) { try { - _handler->phyOnUnixWritable((PhySocket *)&(*s),&(s->uptr)); - } catch ( ... ) {} - } - if (FD_ISSET(sock,&rfds)) { - long n = (long)::read(sock,buf,sizeof(buf)); - if (n <= 0) { - this->close((PhySocket *)&(*s),true); - } else { - try { - _handler->phyOnUnixData((PhySocket *)&(*s),&(s->uptr),(void *)buf,(unsigned long)n); - } catch ( ... ) {} + _handler->phyOnUnixWritable((PhySocket*)&(*s), &(s->uptr)); + } + catch (...) { } } -#endif // __UNIX_LIKE__ - } break; + if (FD_ISSET(sock, &rfds)) { + long n = (long)::read(sock, buf, sizeof(buf)); + if (n <= 0) { + this->close((PhySocket*)&(*s), true); + } + else { + try { + _handler->phyOnUnixData((PhySocket*)&(*s), &(s->uptr), (void*)buf, (unsigned long)n); + } + catch (...) { + } + } + } +#endif // __UNIX_LIKE__ + } break; case ZT_PHY_SOCKET_UNIX_LISTEN: #ifdef __UNIX_LIKE__ - if (FD_ISSET(s->sock,&rfds)) { - memset(&ss,0,sizeof(ss)); + if (FD_ISSET(s->sock, &rfds)) { + memset(&ss, 0, sizeof(ss)); socklen_t slen = sizeof(ss); - ZT_PHY_SOCKFD_TYPE newSock = ::accept(s->sock,(struct sockaddr *)&ss,&slen); + ZT_PHY_SOCKFD_TYPE newSock = ::accept(s->sock, (struct sockaddr*)&ss, &slen); if (ZT_PHY_SOCKFD_VALID(newSock)) { if (_socks.size() >= ZT_PHY_MAX_SOCKETS) { ZT_PHY_CLOSE_SOCKET(newSock); - } else { - fcntl(newSock,F_SETFL,O_NONBLOCK); + } + else { + fcntl(newSock, F_SETFL, O_NONBLOCK); _socks.push_back(PhySocketImpl()); - PhySocketImpl &sws = _socks.back(); - FD_SET(newSock,&_readfds); + PhySocketImpl& sws = _socks.back(); + FD_SET(newSock, &_readfds); if ((long)newSock > _nfds) _nfds = (long)newSock; sws.type = ZT_PHY_SOCKET_UNIX_IN; sws.sock = newSock; - sws.uptr = (void *)0; - memcpy(&(sws.saddr),&ss,sizeof(struct sockaddr_storage)); + sws.uptr = (void*)0; + memcpy(&(sws.saddr), &ss, sizeof(struct sockaddr_storage)); try { //_handler->phyOnUnixAccept((PhySocket *)&(*s),(PhySocket *)&(_socks.back()),&(s->uptr),&(sws.uptr)); - } catch ( ... ) {} + } + catch (...) { + } } } } -#endif // __UNIX_LIKE__ +#endif // __UNIX_LIKE__ break; case ZT_PHY_SOCKET_FD: { ZT_PHY_SOCKFD_TYPE sock = s->sock; - const bool readable = ((FD_ISSET(sock,&rfds))&&(FD_ISSET(sock,&_readfds))); - const bool writable = ((FD_ISSET(sock,&wfds))&&(FD_ISSET(sock,&_writefds))); - if ((readable)||(writable)) { + const bool readable = ((FD_ISSET(sock, &rfds)) && (FD_ISSET(sock, &_readfds))); + const bool writable = ((FD_ISSET(sock, &wfds)) && (FD_ISSET(sock, &_writefds))); + if ((readable) || (writable)) { try { //_handler->phyOnFileDescriptorActivity((PhySocket *)&(*s),&(s->uptr),readable,writable); - } catch ( ... ) {} + } + catch (...) { + } } - } break; + } break; default: break; - } if (s->type == ZT_PHY_SOCKET_CLOSED) _socks.erase(s++); - else ++s; + else + ++s; } } @@ -1140,18 +1192,18 @@ public: * @param sock Socket to close * @param callHandlers If true, call handlers for TCP connect (success: false) or close (default: true) */ - inline void close(PhySocket *sock,bool callHandlers = true) + inline void close(PhySocket* sock, bool callHandlers = true) { - if (!sock) + if (! sock) return; - PhySocketImpl &sws = *(reinterpret_cast(sock)); + PhySocketImpl& sws = *(reinterpret_cast(sock)); if (sws.type == ZT_PHY_SOCKET_CLOSED) return; - FD_CLR(sws.sock,&_readfds); - FD_CLR(sws.sock,&_writefds); + FD_CLR(sws.sock, &_readfds); + FD_CLR(sws.sock, &_writefds); #if defined(_WIN32) || defined(_WIN64) - FD_CLR(sws.sock,&_exceptfds); + FD_CLR(sws.sock, &_exceptfds); #endif if (sws.type != ZT_PHY_SOCKET_FD) @@ -1159,28 +1211,34 @@ public: #ifdef __UNIX_LIKE__ if (sws.type == ZT_PHY_SOCKET_UNIX_LISTEN) - ::unlink(((struct sockaddr_un *)(&(sws.saddr)))->sun_path); -#endif // __UNIX_LIKE__ + ::unlink(((struct sockaddr_un*)(&(sws.saddr)))->sun_path); +#endif // __UNIX_LIKE__ if (callHandlers) { - switch(sws.type) { + switch (sws.type) { case ZT_PHY_SOCKET_TCP_OUT_PENDING: try { - _handler->phyOnTcpConnect(sock,&(sws.uptr),false); - } catch ( ... ) {} + _handler->phyOnTcpConnect(sock, &(sws.uptr), false); + } + catch (...) { + } break; case ZT_PHY_SOCKET_TCP_OUT_CONNECTED: case ZT_PHY_SOCKET_TCP_IN: try { - _handler->phyOnTcpClose(sock,&(sws.uptr)); - } catch ( ... ) {} + _handler->phyOnTcpClose(sock, &(sws.uptr)); + } + catch (...) { + } break; case ZT_PHY_SOCKET_UNIX_IN: #ifdef __UNIX_LIKE__ try { - _handler->phyOnUnixClose(sock,&(sws.uptr)); - } catch ( ... ) {} -#endif // __UNIX_LIKE__ + _handler->phyOnUnixClose(sock, &(sws.uptr)); + } + catch (...) { + } +#endif // __UNIX_LIKE__ break; default: break; @@ -1194,8 +1252,8 @@ public: long nfds = (long)_whackSendSocket; if ((long)_whackReceiveSocket > nfds) nfds = (long)_whackReceiveSocket; - for(typename std::list::iterator s(_socks.begin());s!=_socks.end();++s) { - if ((s->type != ZT_PHY_SOCKET_CLOSED)&&((long)s->sock > nfds)) + for (typename std::list::iterator s(_socks.begin()); s != _socks.end(); ++s) { + if ((s->type != ZT_PHY_SOCKET_CLOSED) && ((long)s->sock > nfds)) nfds = (long)s->sock; } _nfds = nfds; @@ -1203,6 +1261,6 @@ public: } }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/osdep/PortMapper.cpp b/osdep/PortMapper.cpp index 49e88c8a3..1b5af9fd9 100644 --- a/osdep/PortMapper.cpp +++ b/osdep/PortMapper.cpp @@ -14,7 +14,7 @@ #ifdef ZT_USE_MINIUPNPC // Uncomment to dump debug messages -//#define ZT_PORTMAPPER_TRACE 1 +// #define ZT_PORTMAPPER_TRACE 1 #ifdef __ANDROID__ #include @@ -23,16 +23,15 @@ #define PM_TRACE(...) fprintf(stderr, __VA_ARGS__) #endif -#include -#include -#include - -#include - #include "../node/Utils.hpp" #include "OSUtils.hpp" #include "PortMapper.hpp" +#include +#include +#include +#include + // These must be defined to get rid of dynamic export stuff in libminiupnpc and libnatpmp #ifdef __WINDOWS__ #ifndef MINIUPNP_STATICLIB @@ -63,34 +62,30 @@ namespace ZeroTier { -class PortMapperImpl -{ -public: - PortMapperImpl(int localUdpPortToMap,const char *un) : - run(true), - localPort(localUdpPortToMap), - uniqueName(un) +class PortMapperImpl { + public: + PortMapperImpl(int localUdpPortToMap, const char* un) : run(true), localPort(localUdpPortToMap), uniqueName(un) { } - ~PortMapperImpl() {} - - void threadMain() - throw() + ~PortMapperImpl() { - int mode = 0; // 0 == NAT-PMP, 1 == UPnP + } + + void threadMain() throw() + { + int mode = 0; // 0 == NAT-PMP, 1 == UPnP int retrytime = 500; #ifdef ZT_PORTMAPPER_TRACE - fprintf(stderr,"PortMapper: started for UDP port %d" ZT_EOL_S,localPort); + fprintf(stderr, "PortMapper: started for UDP port %d" ZT_EOL_S, localPort); #endif while (run) { - { // use initnatpmp to check if we can bind a port at all natpmp_t _natpmp; - int result = initnatpmp(&_natpmp,0,0); + int result = initnatpmp(&_natpmp, 0, 0); if (result == NATPMP_ERR_CANNOTGETGATEWAY || result == NATPMP_ERR_SOCKETERROR) { closenatpmp(&_natpmp); #ifdef ZT_PORTMAPPER_TRACE @@ -102,7 +97,8 @@ public: retrytime = ZT_PORTMAPPER_REFRESH_DELAY / 10; } continue; - } else { + } + else { closenatpmp(&_natpmp); retrytime = 500; } @@ -111,24 +107,24 @@ public: // NAT-PMP mode (preferred) // --------------------------------------------------------------------- if (mode == 0) { - natpmp_t natpmp; - natpmpresp_t response; + natpmp_t natpmp; + natpmpresp_t response; int r = 0; bool natPmpSuccess = false; - for(int tries=0;tries<60;++tries) { + for (int tries = 0; tries < 60; ++tries) { int tryPort = (int)localPort + tries; if (tryPort >= 65535) tryPort = (tryPort - 65535) + 1025; - memset(&natpmp,0,sizeof(natpmp)); - memset(&response,0,sizeof(response)); + memset(&natpmp, 0, sizeof(natpmp)); + memset(&response, 0, sizeof(response)); - if (initnatpmp(&natpmp,0,0) != 0) { + if (initnatpmp(&natpmp, 0, 0) != 0) { mode = 1; closenatpmp(&natpmp); #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: init failed, switching to UPnP mode" ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: init failed, switching to UPnP mode" ZT_EOL_S); #endif break; } @@ -148,33 +144,34 @@ public: break; } while (r == NATPMP_TRYAGAIN); if (r == 0) { - publicAddress = InetAddress((uint32_t)response.pnu.publicaddress.addr.s_addr,0); - } else { + publicAddress = InetAddress((uint32_t)response.pnu.publicaddress.addr.s_addr, 0); + } + else { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: request for external address failed, aborting..." ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: request for external address failed, aborting..." ZT_EOL_S); #endif closenatpmp(&natpmp); break; } - sendnewportmappingrequest(&natpmp,NATPMP_PROTOCOL_UDP,localPort,tryPort,(ZT_PORTMAPPER_REFRESH_DELAY * 2) / 1000); + sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_UDP, localPort, tryPort, (ZT_PORTMAPPER_REFRESH_DELAY * 2) / 1000); myTimeout = OSUtils::now() + 10000; do { - fd_set fds; - struct timeval timeout; - FD_ZERO(&fds); - FD_SET(natpmp.s, &fds); - getnatpmprequesttimeout(&natpmp, &timeout); - select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - r = readnatpmpresponseorretry(&natpmp, &response); + fd_set fds; + struct timeval timeout; + FD_ZERO(&fds); + FD_SET(natpmp.s, &fds); + getnatpmprequesttimeout(&natpmp, &timeout); + select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + r = readnatpmpresponseorretry(&natpmp, &response); if (OSUtils::now() >= myTimeout) break; - } while (r == NATPMP_TRYAGAIN); + } while (r == NATPMP_TRYAGAIN); if (r == 0) { publicAddress.setPort(response.pnu.newportmapping.mappedpublicport); #ifdef ZT_PORTMAPPER_TRACE - char paddr[128]; - PM_TRACE("PortMapper: NAT-PMP: mapped %u to %s" ZT_EOL_S,(unsigned int)localPort,publicAddress.toString(paddr)); + char paddr[128]; + PM_TRACE("PortMapper: NAT-PMP: mapped %u to %s" ZT_EOL_S, (unsigned int)localPort, publicAddress.toString(paddr)); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -182,16 +179,17 @@ public: natPmpSuccess = true; closenatpmp(&natpmp); break; - } else { + } + else { closenatpmp(&natpmp); // continue } } - if (!natPmpSuccess) { + if (! natPmpSuccess) { mode = 1; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: request failed, switching to UPnP mode" ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: request failed, switching to UPnP mode" ZT_EOL_S); #endif continue; } @@ -203,66 +201,66 @@ public: // --------------------------------------------------------------------- if (mode == 1) { char lanaddr[4096]; - char externalip[4096]; // no range checking? so make these buffers larger than any UDP packet a uPnP server could send us as a precaution :P + char externalip[4096]; // no range checking? so make these buffers larger than any UDP packet a uPnP server could send us as a precaution :P char inport[16]; char outport[16]; struct UPNPUrls urls; struct IGDdatas data; int upnpError = 0; - UPNPDev *devlist = upnpDiscoverAll(5000,(const char *)0,(const char *)0,0,0,2,&upnpError); + UPNPDev* devlist = upnpDiscoverAll(5000, (const char*)0, (const char*)0, 0, 0, 2, &upnpError); if (devlist) { - #ifdef ZT_PORTMAPPER_TRACE { - UPNPDev *dev = devlist; + UPNPDev* dev = devlist; while (dev) { - PM_TRACE("PortMapper: found UPnP device at URL '%s': %s" ZT_EOL_S,dev->descURL,dev->st); + PM_TRACE("PortMapper: found UPnP device at URL '%s': %s" ZT_EOL_S, dev->descURL, dev->st); dev = dev->pNext; } } #endif - memset(lanaddr,0,sizeof(lanaddr)); - memset(externalip,0,sizeof(externalip)); - memset(&urls,0,sizeof(urls)); - memset(&data,0,sizeof(data)); - OSUtils::ztsnprintf(inport,sizeof(inport),"%d",localPort); + memset(lanaddr, 0, sizeof(lanaddr)); + memset(externalip, 0, sizeof(externalip)); + memset(&urls, 0, sizeof(urls)); + memset(&data, 0, sizeof(data)); + OSUtils::ztsnprintf(inport, sizeof(inport), "%d", localPort); int foundValidIGD = 0; - if ((foundValidIGD = UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) { + if ((foundValidIGD = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))) && (lanaddr[0])) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: my LAN IP address: %s" ZT_EOL_S,lanaddr); + PM_TRACE("PortMapper: UPnP: my LAN IP address: %s" ZT_EOL_S, lanaddr); #endif - if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) { + if ((UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalip) == UPNPCOMMAND_SUCCESS) && (externalip[0])) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: my external IP address: %s" ZT_EOL_S,externalip); + PM_TRACE("PortMapper: UPnP: my external IP address: %s" ZT_EOL_S, externalip); #endif - for(int tries=0;tries<60;++tries) { + for (int tries = 0; tries < 60; ++tries) { int tryPort = (int)localPort + tries; if (tryPort >= 65535) tryPort = (tryPort - 65535) + 1025; - OSUtils::ztsnprintf(outport,sizeof(outport),"%u",tryPort); + OSUtils::ztsnprintf(outport, sizeof(outport), "%u", tryPort); // First check and see if this port is already mapped to the // same unique name. If so, keep this mapping and don't try // to map again since this can break buggy routers. But don't // fail if this command fails since not all routers support it. { - char haveIntClient[128]; // 128 == big enough for all these as per miniupnpc "documentation" + char haveIntClient[128]; // 128 == big enough for all these as per miniupnpc "documentation" char haveIntPort[128]; char haveDesc[128]; char haveEnabled[128]; char haveLeaseDuration[128]; - memset(haveIntClient,0,sizeof(haveIntClient)); - memset(haveIntPort,0,sizeof(haveIntPort)); - memset(haveDesc,0,sizeof(haveDesc)); - memset(haveEnabled,0,sizeof(haveEnabled)); - memset(haveLeaseDuration,0,sizeof(haveLeaseDuration)); - if ((UPNP_GetSpecificPortMappingEntry(urls.controlURL,data.first.servicetype,outport,"UDP",(const char *)0,haveIntClient,haveIntPort,haveDesc,haveEnabled,haveLeaseDuration) == UPNPCOMMAND_SUCCESS)&&(uniqueName == haveDesc)) { + memset(haveIntClient, 0, sizeof(haveIntClient)); + memset(haveIntPort, 0, sizeof(haveIntPort)); + memset(haveDesc, 0, sizeof(haveDesc)); + memset(haveEnabled, 0, sizeof(haveEnabled)); + memset(haveLeaseDuration, 0, sizeof(haveLeaseDuration)); + if ((UPNP_GetSpecificPortMappingEntry(urls.controlURL, data.first.servicetype, outport, "UDP", (const char*)0, haveIntClient, haveIntPort, haveDesc, haveEnabled, haveLeaseDuration) == UPNPCOMMAND_SUCCESS) + && (uniqueName == haveDesc)) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: reusing previously reserved external port: %s" ZT_EOL_S,outport); + PM_TRACE("PortMapper: UPnP: reusing previously reserved external port: %s" ZT_EOL_S, outport); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -275,9 +273,9 @@ public: // Try to map this port int mapResult = 0; - if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,uniqueName.c_str(),"UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) { + if ((mapResult = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, outport, inport, lanaddr, uniqueName.c_str(), "UDP", (const char*)0, "0")) == UPNPCOMMAND_SUCCESS) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: reserved external port: %s" ZT_EOL_S,outport); + PM_TRACE("PortMapper: UPnP: reserved external port: %s" ZT_EOL_S, outport); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -285,42 +283,45 @@ public: tmp.setPort(tryPort); surface.push_back(tmp); break; - } else { + } + else { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d" ZT_EOL_S,outport,mapResult); + PM_TRACE("PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d" ZT_EOL_S, outport, mapResult); #endif Thread::sleep(1000); } } - - } else { + } + else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode" ZT_EOL_S); + PM_TRACE("PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode" ZT_EOL_S); #endif } - } else { + } + else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode" ZT_EOL_S); + PM_TRACE("PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode" ZT_EOL_S); #endif } freeUPNPDevlist(devlist); - if(foundValidIGD) { + if (foundValidIGD) { FreeUPNPUrls(&urls); } - } else { + } + else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d" ZT_EOL_S,upnpError); + PM_TRACE("PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d" ZT_EOL_S, upnpError); #endif } } // --------------------------------------------------------------------- #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("UPNPClient: rescanning in %d ms" ZT_EOL_S,ZT_PORTMAPPER_REFRESH_DELAY); + PM_TRACE("UPNPClient: rescanning in %d ms" ZT_EOL_S, ZT_PORTMAPPER_REFRESH_DELAY); #endif Thread::sleep(ZT_PORTMAPPER_REFRESH_DELAY); } @@ -336,9 +337,9 @@ public: std::vector surface; }; -PortMapper::PortMapper(int localUdpPortToMap,const char *uniqueName) +PortMapper::PortMapper(int localUdpPortToMap, const char* uniqueName) { - _impl = new PortMapperImpl(localUdpPortToMap,uniqueName); + _impl = new PortMapperImpl(localUdpPortToMap, uniqueName); Thread::start(_impl); } @@ -353,6 +354,6 @@ std::vector PortMapper::get() const return _impl->surface; } -} // namespace ZeroTier +} // namespace ZeroTier -#endif // ZT_USE_MINIUPNPC +#endif // ZT_USE_MINIUPNPC diff --git a/osdep/PortMapper.hpp b/osdep/PortMapper.hpp index c74df0c10..e65064772 100644 --- a/osdep/PortMapper.hpp +++ b/osdep/PortMapper.hpp @@ -16,13 +16,13 @@ #ifndef ZT_PORTMAPPER_HPP #define ZT_PORTMAPPER_HPP -#include - #include "../node/Constants.hpp" #include "../node/InetAddress.hpp" #include "../node/Mutex.hpp" #include "Thread.hpp" +#include + /** * How frequently should we refresh our UPNP/NAT-PnP/whatever state? */ @@ -35,18 +35,17 @@ class PortMapperImpl; /** * UPnP/NAT-PnP port mapping "daemon" */ -class PortMapper -{ +class PortMapper { friend class PortMapperImpl; -public: + public: /** * Create and start port mapper service * * @param localUdpPortToMap Port we want visible to the outside world * @param name Unique name of this endpoint (based on ZeroTier address) */ - PortMapper(int localUdpPortToMap,const char *uniqueName); + PortMapper(int localUdpPortToMap, const char* uniqueName); ~PortMapper(); @@ -55,12 +54,12 @@ public: */ std::vector get() const; -private: - PortMapperImpl *_impl; + private: + PortMapperImpl* _impl; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif -#endif // ZT_USE_MINIUPNPC +#endif // ZT_USE_MINIUPNPC diff --git a/osdep/Thread.hpp b/osdep/Thread.hpp index 96d257f44..abebd4374 100644 --- a/osdep/Thread.hpp +++ b/osdep/Thread.hpp @@ -14,57 +14,57 @@ #ifndef ZT_THREAD_HPP #define ZT_THREAD_HPP -#include - #include "../node/Constants.hpp" +#include + #ifdef __WINDOWS__ -#include -#include -#include - #include "../node/Mutex.hpp" +#include +#include +#include + namespace ZeroTier { -template -static DWORD WINAPI ___zt_threadMain(LPVOID lpParam) +template static DWORD WINAPI ___zt_threadMain(LPVOID lpParam) { try { - ((C *)lpParam)->threadMain(); - } catch ( ... ) {} + ((C*)lpParam)->threadMain(); + } + catch (...) { + } return 0; } -class Thread -{ -public: +class Thread { + public: Thread() { _th = NULL; _tid = 0; } - template - static inline Thread start(C *instance) + template static inline Thread start(C* instance) { Thread t; - t._th = CreateThread(NULL,0,&___zt_threadMain,(LPVOID)instance,0,&t._tid); + t._th = CreateThread(NULL, 0, &___zt_threadMain, (LPVOID)instance, 0, &t._tid); if (t._th == NULL) throw std::runtime_error("CreateThread() failed"); return t; } - static inline void join(const Thread &t) + static inline void join(const Thread& t) { if (t._th != NULL) { - for(;;) { + for (;;) { DWORD ec = STILL_ACTIVE; - GetExitCodeThread(t._th,&ec); + GetExitCodeThread(t._th, &ec); if (ec == STILL_ACTIVE) - WaitForSingleObject(t._th,1000); - else break; + WaitForSingleObject(t._th, 1000); + else + break; } } } @@ -75,61 +75,64 @@ public: } // Not available on *nix platforms - static inline void cancelIO(const Thread &t) + static inline void cancelIO(const Thread& t) { -#if !defined(__MINGW32__) && !defined(__MINGW64__) // CancelSynchronousIo not available in MSYS2 +#if ! defined(__MINGW32__) && ! defined(__MINGW64__) // CancelSynchronousIo not available in MSYS2 if (t._th != NULL) CancelSynchronousIo(t._th); #endif } - inline operator bool() const { return (_th != NULL); } + inline operator bool() const + { + return (_th != NULL); + } -private: + private: HANDLE _th; DWORD _tid; }; -} // namespace ZeroTier +} // namespace ZeroTier #else +#include #include #include #include -#include #include namespace ZeroTier { -template -static void *___zt_threadMain(void *instance) +template static void* ___zt_threadMain(void* instance) { try { - ((C *)instance)->threadMain(); - } catch ( ... ) {} - return (void *)0; + ((C*)instance)->threadMain(); + } + catch (...) { + } + return (void*)0; } /** * A thread identifier, and static methods to start and join threads */ -class Thread -{ -public: +class Thread { + public: Thread() { - memset(this,0,sizeof(Thread)); + memset(this, 0, sizeof(Thread)); } - Thread(const Thread &t) + Thread(const Thread& t) { - memcpy(this,&t,sizeof(Thread)); + memcpy(this, &t, sizeof(Thread)); } - inline Thread &operator=(const Thread &t) + inline Thread& operator=(const Thread& t) { - memcpy(this,&t,sizeof(Thread)); + memcpy(this, &t, sizeof(Thread)); return *this; } @@ -141,19 +144,19 @@ public: * @throws std::runtime_error Unable to create thread * @tparam C Class containing threadMain() */ - template - static inline Thread start(C *instance) + template static inline Thread start(C* instance) { Thread t; pthread_attr_t tattr; pthread_attr_init(&tattr); // This corrects for systems with abnormally small defaults (musl) and also // shrinks the stack on systems with large defaults to save a bit of memory. - pthread_attr_setstacksize(&tattr,ZT_THREAD_MIN_STACK_SIZE); - if (pthread_create(&t._tid,&tattr,&___zt_threadMain,instance)) { + pthread_attr_setstacksize(&tattr, ZT_THREAD_MIN_STACK_SIZE); + if (pthread_create(&t._tid, &tattr, &___zt_threadMain, instance)) { pthread_attr_destroy(&tattr); throw std::runtime_error("pthread_create() failed, unable to create thread"); - } else { + } + else { t._started = true; pthread_attr_destroy(&tattr); } @@ -165,10 +168,10 @@ public: * * @param t Thread to join */ - static inline void join(const Thread &t) + static inline void join(const Thread& t) { if (t._started) - pthread_join(t._tid,(void **)0); + pthread_join(t._tid, (void**)0); } /** @@ -176,17 +179,23 @@ public: * * @param ms Number of milliseconds to sleep */ - static inline void sleep(unsigned long ms) { usleep(ms * 1000); } + static inline void sleep(unsigned long ms) + { + usleep(ms * 1000); + } - inline operator bool() const { return (_started); } + inline operator bool() const + { + return (_started); + } -private: + private: pthread_t _tid; volatile bool _started; }; -} // namespace ZeroTier +} // namespace ZeroTier -#endif // __WINDOWS__ / !__WINDOWS__ +#endif // __WINDOWS__ / !__WINDOWS__ #endif diff --git a/osdep/WinDNSHelper.cpp b/osdep/WinDNSHelper.cpp index 6bcd2b476..88b39e56d 100644 --- a/osdep/WinDNSHelper.cpp +++ b/osdep/WinDNSHelper.cpp @@ -1,18 +1,16 @@ #include "WinDNSHelper.hpp" -#include #include - -#include -#include +#include #include +#include #include +#include #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 -namespace ZeroTier -{ +namespace ZeroTier { BOOL RegDelnodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey) { @@ -33,8 +31,7 @@ BOOL RegDelnodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey) lResult = RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); - if (lResult != ERROR_SUCCESS) - { + if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_FILE_NOT_FOUND) { return TRUE; } @@ -47,8 +44,7 @@ BOOL RegDelnodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey) lpEnd = lpSubKey + lstrlen(lpSubKey); - if (*(lpEnd - 1) != TEXT('\\')) - { + if (*(lpEnd - 1) != TEXT('\\')) { *lpEnd = TEXT('\\'); lpEnd++; *lpEnd = TEXT('\0'); @@ -57,24 +53,20 @@ BOOL RegDelnodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey) // Enumerate the keys dwSize = MAX_PATH; - lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, - NULL, NULL, &ftWrite); + lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); - if (lResult == ERROR_SUCCESS) - { + if (lResult == ERROR_SUCCESS) { do { - *lpEnd = TEXT('\0'); StringCchCat(lpSubKey, MAX_PATH * 2, szName); - if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) { + if (! RegDelnodeRecurse(hKeyRoot, lpSubKey)) { break; } dwSize = MAX_PATH; - lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, - NULL, NULL, &ftWrite); + lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); } while (lResult == ERROR_SUCCESS); } @@ -114,61 +106,47 @@ BOOL RegDelnode(HKEY hKeyRoot, LPCTSTR lpSubKey) StringCchCopy(szDelKey, MAX_PATH * 2, lpSubKey); return RegDelnodeRecurse(hKeyRoot, szDelKey); - } std::vector getSubKeys(const char* key) { std::vector subkeys; HKEY hKey; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, - key, - 0, - KEY_READ, - &hKey) == ERROR_SUCCESS) { - - TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name - DWORD cbName; // size of name string - TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name - DWORD cchClassName = MAX_PATH; // size of class string - DWORD cSubKeys = 0; // number of subkeys - DWORD cbMaxSubKey; // longest subkey size - DWORD cchMaxClass; // longest class string - DWORD cValues; // number of values for key - DWORD cchMaxValue; // longest value name - DWORD cbMaxValueData; // longest value data - DWORD cbSecurityDescriptor; // size of security descriptor - FILETIME ftLastWriteTime; // last write time + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name + DWORD cbName; // size of name string + TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name + DWORD cchClassName = MAX_PATH; // size of class string + DWORD cSubKeys = 0; // number of subkeys + DWORD cbMaxSubKey; // longest subkey size + DWORD cchMaxClass; // longest class string + DWORD cValues; // number of values for key + DWORD cchMaxValue; // longest value name + DWORD cbMaxValueData; // longest value data + DWORD cbSecurityDescriptor; // size of security descriptor + FILETIME ftLastWriteTime; // last write time DWORD i, retCode; - TCHAR achValue[MAX_VALUE_NAME]; + TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; retCode = RegQueryInfoKey( - hKey, // key handle - achClass, // buffer for class name - &cchClassName, // size of class string - NULL, // reserved - &cSubKeys, // number of subkeys - &cbMaxSubKey, // longest subkey size - &cchMaxClass, // longest class string - &cValues, // number of values for this key - &cchMaxValue, // longest value name - &cbMaxValueData, // longest value data - &cbSecurityDescriptor, // security descriptor - &ftLastWriteTime); // last write time + hKey, // key handle + achClass, // buffer for class name + &cchClassName, // size of class string + NULL, // reserved + &cSubKeys, // number of subkeys + &cbMaxSubKey, // longest subkey size + &cchMaxClass, // longest class string + &cValues, // number of values for this key + &cchMaxValue, // longest value name + &cbMaxValueData, // longest value data + &cbSecurityDescriptor, // security descriptor + &ftLastWriteTime); // last write time for (i = 0; i < cSubKeys; ++i) { cbName = MAX_KEY_LENGTH; - retCode = RegEnumKeyEx( - hKey, - i, - achKey, - &cbName, - NULL, - NULL, - NULL, - &ftLastWriteTime); + retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) { subkeys.push_back(achKey); } @@ -178,59 +156,47 @@ std::vector getSubKeys(const char* key) return subkeys; } -std::vector getValueList(const char* key) { +std::vector getValueList(const char* key) +{ std::vector values; HKEY hKey; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, - key, - 0, - KEY_READ, - &hKey) == ERROR_SUCCESS) { - - TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name - DWORD cbName; // size of name string - TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name - DWORD cchClassName = MAX_PATH; // size of class string - DWORD cSubKeys = 0; // number of subkeys - DWORD cbMaxSubKey; // longest subkey size - DWORD cchMaxClass; // longest class string - DWORD cValues; // number of values for key - DWORD cchMaxValue; // longest value name - DWORD cbMaxValueData; // longest value data - DWORD cbSecurityDescriptor; // size of security descriptor - FILETIME ftLastWriteTime; // last write time + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name + DWORD cbName; // size of name string + TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name + DWORD cchClassName = MAX_PATH; // size of class string + DWORD cSubKeys = 0; // number of subkeys + DWORD cbMaxSubKey; // longest subkey size + DWORD cchMaxClass; // longest class string + DWORD cValues; // number of values for key + DWORD cchMaxValue; // longest value name + DWORD cbMaxValueData; // longest value data + DWORD cbSecurityDescriptor; // size of security descriptor + FILETIME ftLastWriteTime; // last write time DWORD i, retCode; - TCHAR achValue[MAX_VALUE_NAME]; + TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; retCode = RegQueryInfoKey( - hKey, // key handle - achClass, // buffer for class name - &cchClassName, // size of class string - NULL, // reserved - &cSubKeys, // number of subkeys - &cbMaxSubKey, // longest subkey size - &cchMaxClass, // longest class string - &cValues, // number of values for this key - &cchMaxValue, // longest value name - &cbMaxValueData, // longest value data - &cbSecurityDescriptor, // security descriptor - &ftLastWriteTime); // last write time - + hKey, // key handle + achClass, // buffer for class name + &cchClassName, // size of class string + NULL, // reserved + &cSubKeys, // number of subkeys + &cbMaxSubKey, // longest subkey size + &cchMaxClass, // longest class string + &cValues, // number of values for this key + &cchMaxValue, // longest value name + &cbMaxValueData, // longest value data + &cbSecurityDescriptor, // security descriptor + &ftLastWriteTime); // last write time + for (i = 0, retCode = ERROR_SUCCESS; i < cValues; ++i) { cchValue = MAX_VALUE_NAME; achValue[0] = '\0'; - retCode = RegEnumValue( - hKey, - i, - achValue, - &cchValue, - NULL, - NULL, - NULL, - NULL); + retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL); if (retCode == ERROR_SUCCESS) { values.push_back(achValue); } @@ -254,22 +220,10 @@ std::pair WinDNSHelper::hasDNSConfig(uint64_t nwid) for (auto it2 = dnsRecords.begin(); it2 != dnsRecords.end(); ++it2) { if ((*it2) == "Comment") { HKEY hKey; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, - sub, - 0, - KEY_READ, - &hKey) == ERROR_SUCCESS) { - + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, sub, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { char buf[16384] = { 0 }; DWORD size = sizeof(buf); - DWORD retCode = RegGetValueA( - HKEY_LOCAL_MACHINE, - sub, - it2->c_str(), - RRF_RT_REG_SZ, - NULL, - &buf, - &size); + DWORD retCode = RegGetValueA(HKEY_LOCAL_MACHINE, sub, it2->c_str(), RRF_RT_REG_SZ, NULL, &buf, &size); if (retCode == ERROR_SUCCESS) { if (std::string(networkStr) == std::string(buf)) { RegCloseKey(hKey); @@ -277,11 +231,10 @@ std::pair WinDNSHelper::hasDNSConfig(uint64_t nwid) } } else { - } } RegCloseKey(hKey); - } + } } } @@ -311,7 +264,8 @@ void WinDNSHelper::setDNS(uint64_t nwid, const char* domain, const std::vector -#include #include "../node/InetAddress.hpp" +#include +#include -namespace ZeroTier -{ +namespace ZeroTier { -class WinDNSHelper -{ -public: +class WinDNSHelper { + public: static void setDNS(uint64_t nwid, const char* domain, const std::vector& servers); static void removeDNS(uint64_t nwid); -private: + private: static std::pair hasDNSConfig(uint64_t nwid); }; -} +} // namespace ZeroTier #endif \ No newline at end of file diff --git a/osdep/WinFWHelper.cpp b/osdep/WinFWHelper.cpp index 40f38977e..5f657d60b 100644 --- a/osdep/WinFWHelper.cpp +++ b/osdep/WinFWHelper.cpp @@ -1,10 +1,7 @@ #include "WinFWHelper.hpp" - namespace ZeroTier { - - void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid) { char nwString[32] = { 0 }; @@ -12,7 +9,7 @@ void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid) sprintf(nwString, "%.16llx", nwid); std::string nwString2 = { nwString }; - + ip.toString(ipbuf); if (ip.isV4()) { @@ -41,7 +38,6 @@ void ZeroTier::WinFWHelper::removeICMPRule(const InetAddress& ip, uint64_t nwid) } } - void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid) { // allows icmp, scoped to a specific ip address and interface name @@ -50,123 +46,112 @@ void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid) sprintf(nwString, "%.16llx", nwid); std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + address + - R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + - " -Protocol ICMPv4 -Action Allow" + - " -LocalAddress " + address + "\"\r\n"; - - _run(cmd); + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + address + R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + + " -Protocol ICMPv4 -Action Allow" + " -LocalAddress " + address + "\"\r\n"; + + _run(cmd); } void WinFWHelper::newICMPv6Rule(std::string address, uint64_t nwid) { - // allows icmp, scoped to a specific ip address and interface name + // allows icmp, scoped to a specific ip address and interface name - char nwString[32] = { 0 }; - sprintf(nwString, "%.16llx", nwid); - std::string nwString2 = { nwString }; + char nwString[32] = { 0 }; + sprintf(nwString, "%.16llx", nwid); + std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + address + - R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + - " -Protocol ICMPv6 -Action Allow" + - " -LocalAddress " + address + "\"\r\n"; + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + address + R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + + " -Protocol ICMPv6 -Action Allow" + " -LocalAddress " + address + "\"\r\n"; - _run(cmd); + _run(cmd); } void WinFWHelper::removeICMPv4Rule(std::string addr, uint64_t nwid) { - // removes 1 icmp firewall rule + // removes 1 icmp firewall rule - char nwString[32] = { 0 }; - sprintf(nwString, "%.16llx", nwid); - std::string nwString2 = { nwString }; + char nwString[32] = { 0 }; + sprintf(nwString, "%.16llx", nwid); + std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr + - "\"\r\n"; + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr + "\"\r\n"; - _run(cmd); + _run(cmd); } void WinFWHelper::removeICMPv6Rule(std::string addr, uint64_t nwid) { - // removes 1 icmp firewall rule + // removes 1 icmp firewall rule - char nwString[32] = { 0 }; - sprintf(nwString, "%.16llx", nwid); - std::string nwString2 = { nwString }; + char nwString[32] = { 0 }; + sprintf(nwString, "%.16llx", nwid); + std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr + - "\"\r\n"; + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr + "\"\r\n"; - _run(cmd); + _run(cmd); } void WinFWHelper::removeICMPv4Rules(uint64_t nwid) { - // removes all icmp firewall rules for this network id + // removes all icmp firewall rules for this network id - char nwString[32] = { 0 }; - sprintf(nwString, "%.16llx", nwid); - std::string nwString2 = { nwString }; + char nwString[32] = { 0 }; + sprintf(nwString, "%.16llx", nwid); + std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n"; - - _run(cmd); + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n"; + + _run(cmd); } void WinFWHelper::removeICMPv6Rules(uint64_t nwid) { - // removes all icmp firewall rules for this network id + // removes all icmp firewall rules for this network id - char nwString[32] = { 0 }; - sprintf(nwString, "%.16llx", nwid); - std::string nwString2 = { nwString }; + char nwString[32] = { 0 }; + sprintf(nwString, "%.16llx", nwid); + std::string nwString2 = { nwString }; - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n"; + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n"; - _run(cmd); + _run(cmd); } void WinFWHelper::removeICMPRules() { - // removes all icmp firewall rules for all networks + // removes all icmp firewall rules for all networks - std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n"); + std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n"); - _run(cmd); + _run(cmd); } void WinFWHelper::removeICMPRules(uint64_t nwid) { - // removes all icmp firewall rules for this network - WinFWHelper::removeICMPv4Rules(nwid); - WinFWHelper::removeICMPv6Rules(nwid); + // removes all icmp firewall rules for this network + WinFWHelper::removeICMPv4Rules(nwid); + WinFWHelper::removeICMPv6Rules(nwid); } - - void WinFWHelper::_run(std::string cmd) { - - #ifdef ZT_DEBUG - fprintf(stderr, cmd.c_str()); - #endif +#ifdef ZT_DEBUG + fprintf(stderr, cmd.c_str()); +#endif - STARTUPINFOA startupInfo; - PROCESS_INFORMATION processInfo; - startupInfo.cb = sizeof(startupInfo); - memset(&startupInfo, 0, sizeof(STARTUPINFOA)); - memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); + STARTUPINFOA startupInfo; + PROCESS_INFORMATION processInfo; + startupInfo.cb = sizeof(startupInfo); + memset(&startupInfo, 0, sizeof(STARTUPINFOA)); + memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) { - WaitForSingleObject(processInfo.hProcess, INFINITE); + if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - } + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } } - - } // namespace ZeroTier \ No newline at end of file diff --git a/osdep/WinFWHelper.hpp b/osdep/WinFWHelper.hpp index a8d9e27aa..43c41e47e 100644 --- a/osdep/WinFWHelper.hpp +++ b/osdep/WinFWHelper.hpp @@ -15,7 +15,6 @@ class WinFWHelper { static void removeICMPRules(uint64_t nwid); static void removeICMPRules(); - private: static void _run(std::string cmd); static void newICMPv4Rule(std::string address, uint64_t nwid); diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index 9d644b171..3043868ae 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/osdep/WindowsEthernetTap.cpp @@ -11,158 +11,164 @@ */ /****/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include "WindowsEthernetTap.hpp" #include "../node/Constants.hpp" -#include "../node/Utils.hpp" #include "../node/Mutex.hpp" - -#include "WindowsEthernetTap.hpp" -#include "OSUtils.hpp" - +#include "../node/Utils.hpp" #include "..\windows\TapDriver6\tap-windows.h" +#include "OSUtils.hpp" #include "WinDNSHelper.hpp" +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Create a fake unused default route to force detection of network type on networks without gateways #define ZT_WINDOWS_CREATE_FAKE_DEFAULT_ROUTE // Function signatures of dynamically loaded functions, from newdev.h, setupapi.h, and cfgmgr32.h -typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesA_t)(_In_opt_ HWND hwndParent,_In_ LPCSTR HardwareId,_In_ LPCSTR FullInfPath,_In_ DWORD InstallFlags,_Out_opt_ PBOOL bRebootRequired); -typedef BOOL (WINAPI *SetupDiGetINFClassA_t)(_In_ PCSTR InfName,_Out_ LPGUID ClassGuid,_Out_writes_(ClassNameSize) PSTR ClassName,_In_ DWORD ClassNameSize,_Out_opt_ PDWORD RequiredSize); -typedef HDEVINFO (WINAPI *SetupDiCreateDeviceInfoList_t)(_In_opt_ CONST GUID *ClassGuid,_In_opt_ HWND hwndParent); -typedef BOOL (WINAPI *SetupDiCreateDeviceInfoA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PCSTR DeviceName,_In_ CONST GUID *ClassGuid,_In_opt_ PCSTR DeviceDescription,_In_opt_ HWND hwndParent,_In_ DWORD CreationFlags,_Out_opt_ PSP_DEVINFO_DATA DeviceInfoData); -typedef BOOL (WINAPI *SetupDiSetDeviceRegistryPropertyA_t)(_In_ HDEVINFO DeviceInfoSet,_Inout_ PSP_DEVINFO_DATA DeviceInfoData,_In_ DWORD Property,_In_reads_bytes_opt_(PropertyBufferSize) CONST BYTE *PropertyBuffer,_In_ DWORD PropertyBufferSize); -typedef BOOL (WINAPI *SetupDiCallClassInstaller_t)(_In_ DI_FUNCTION InstallFunction,_In_ HDEVINFO DeviceInfoSet,_In_opt_ PSP_DEVINFO_DATA DeviceInfoData); -typedef BOOL (WINAPI *SetupDiDestroyDeviceInfoList_t)(_In_ HDEVINFO DeviceInfoSet); -typedef HDEVINFO (WINAPI *SetupDiGetClassDevsExA_t)(_In_opt_ CONST GUID *ClassGuid,_In_opt_ PCSTR Enumerator,_In_opt_ HWND hwndParent,_In_ DWORD Flags,_In_opt_ HDEVINFO DeviceInfoSet,_In_opt_ PCSTR MachineName,_Reserved_ PVOID Reserved); -typedef BOOL (WINAPI *SetupDiOpenDeviceInfoA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PCSTR DeviceInstanceId,_In_opt_ HWND hwndParent,_In_ DWORD OpenFlags,_Out_opt_ PSP_DEVINFO_DATA DeviceInfoData); -typedef BOOL (WINAPI *SetupDiEnumDeviceInfo_t)(_In_ HDEVINFO DeviceInfoSet,_In_ DWORD MemberIndex,_Out_ PSP_DEVINFO_DATA DeviceInfoData); -typedef BOOL (WINAPI *SetupDiSetClassInstallParamsA_t)(_In_ HDEVINFO DeviceInfoSet,_In_opt_ PSP_DEVINFO_DATA DeviceInfoData,_In_reads_bytes_opt_(ClassInstallParamsSize) PSP_CLASSINSTALL_HEADER ClassInstallParams,_In_ DWORD ClassInstallParamsSize); -typedef CONFIGRET (WINAPI *CM_Get_Device_ID_ExA_t)(_In_ DEVINST dnDevInst,_Out_writes_(BufferLen) PSTR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine); -typedef BOOL (WINAPI *SetupDiGetDeviceInstanceIdA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PSP_DEVINFO_DATA DeviceInfoData,_Out_writes_opt_(DeviceInstanceIdSize) PSTR DeviceInstanceId,_In_ DWORD DeviceInstanceIdSize,_Out_opt_ PDWORD RequiredSize); +typedef BOOL(WINAPI* UpdateDriverForPlugAndPlayDevicesA_t)(_In_opt_ HWND hwndParent, _In_ LPCSTR HardwareId, _In_ LPCSTR FullInfPath, _In_ DWORD InstallFlags, _Out_opt_ PBOOL bRebootRequired); +typedef BOOL(WINAPI* SetupDiGetINFClassA_t)(_In_ PCSTR InfName, _Out_ LPGUID ClassGuid, _Out_writes_(ClassNameSize) PSTR ClassName, _In_ DWORD ClassNameSize, _Out_opt_ PDWORD RequiredSize); +typedef HDEVINFO(WINAPI* SetupDiCreateDeviceInfoList_t)(_In_opt_ CONST GUID* ClassGuid, _In_opt_ HWND hwndParent); +typedef BOOL(WINAPI* SetupDiCreateDeviceInfoA_t)( + _In_ HDEVINFO DeviceInfoSet, + _In_ PCSTR DeviceName, + _In_ CONST GUID* ClassGuid, + _In_opt_ PCSTR DeviceDescription, + _In_opt_ HWND hwndParent, + _In_ DWORD CreationFlags, + _Out_opt_ PSP_DEVINFO_DATA DeviceInfoData); +typedef BOOL( + WINAPI* SetupDiSetDeviceRegistryPropertyA_t)(_In_ HDEVINFO DeviceInfoSet, _Inout_ PSP_DEVINFO_DATA DeviceInfoData, _In_ DWORD Property, _In_reads_bytes_opt_(PropertyBufferSize) CONST BYTE* PropertyBuffer, _In_ DWORD PropertyBufferSize); +typedef BOOL(WINAPI* SetupDiCallClassInstaller_t)(_In_ DI_FUNCTION InstallFunction, _In_ HDEVINFO DeviceInfoSet, _In_opt_ PSP_DEVINFO_DATA DeviceInfoData); +typedef BOOL(WINAPI* SetupDiDestroyDeviceInfoList_t)(_In_ HDEVINFO DeviceInfoSet); +typedef HDEVINFO( + WINAPI* SetupDiGetClassDevsExA_t)(_In_opt_ CONST GUID* ClassGuid, _In_opt_ PCSTR Enumerator, _In_opt_ HWND hwndParent, _In_ DWORD Flags, _In_opt_ HDEVINFO DeviceInfoSet, _In_opt_ PCSTR MachineName, _Reserved_ PVOID Reserved); +typedef BOOL(WINAPI* SetupDiOpenDeviceInfoA_t)(_In_ HDEVINFO DeviceInfoSet, _In_ PCSTR DeviceInstanceId, _In_opt_ HWND hwndParent, _In_ DWORD OpenFlags, _Out_opt_ PSP_DEVINFO_DATA DeviceInfoData); +typedef BOOL(WINAPI* SetupDiEnumDeviceInfo_t)(_In_ HDEVINFO DeviceInfoSet, _In_ DWORD MemberIndex, _Out_ PSP_DEVINFO_DATA DeviceInfoData); +typedef BOOL( + WINAPI* SetupDiSetClassInstallParamsA_t)(_In_ HDEVINFO DeviceInfoSet, _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, _In_reads_bytes_opt_(ClassInstallParamsSize) PSP_CLASSINSTALL_HEADER ClassInstallParams, _In_ DWORD ClassInstallParamsSize); +typedef CONFIGRET(WINAPI* CM_Get_Device_ID_ExA_t)(_In_ DEVINST dnDevInst, _Out_writes_(BufferLen) PSTR Buffer, _In_ ULONG BufferLen, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine); +typedef BOOL( + WINAPI* SetupDiGetDeviceInstanceIdA_t)(_In_ HDEVINFO DeviceInfoSet, _In_ PSP_DEVINFO_DATA DeviceInfoData, _Out_writes_opt_(DeviceInstanceIdSize) PSTR DeviceInstanceId, _In_ DWORD DeviceInstanceIdSize, _Out_opt_ PDWORD RequiredSize); namespace ZeroTier { namespace { // Static/singleton class that when initialized loads a bunch of environment information and a few dynamically loaded DLLs -class WindowsEthernetTapEnv -{ -public: +class WindowsEthernetTapEnv { + public: WindowsEthernetTapEnv() { #ifdef _WIN64 is64Bit = TRUE; - //tapDriverPath = "\\tap-windows\\x64\\zttap300.inf"; + // tapDriverPath = "\\tap-windows\\x64\\zttap300.inf"; #else is64Bit = FALSE; - IsWow64Process(GetCurrentProcess(),&is64Bit); + IsWow64Process(GetCurrentProcess(), &is64Bit); if (is64Bit) { - fprintf(stderr,"FATAL: you must use the 64-bit ZeroTier One service on 64-bit Windows systems\r\n"); + fprintf(stderr, "FATAL: you must use the 64-bit ZeroTier One service on 64-bit Windows systems\r\n"); _exit(1); } - //tapDriverPath = "\\tap-windows\\x86\\zttap300.inf"; + // tapDriverPath = "\\tap-windows\\x86\\zttap300.inf"; #endif tapDriverName = "zttap300"; tapDriverPath = "\\zttap300.inf"; setupApiMod = LoadLibraryA("setupapi.dll"); - if (!setupApiMod) { - fprintf(stderr,"FATAL: unable to dynamically load setupapi.dll\r\n"); + if (! setupApiMod) { + fprintf(stderr, "FATAL: unable to dynamically load setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiGetINFClassA = (SetupDiGetINFClassA_t)GetProcAddress(setupApiMod,"SetupDiGetINFClassA"))) { - fprintf(stderr,"FATAL: SetupDiGetINFClassA not found in setupapi.dll\r\n"); + if (! (this->SetupDiGetINFClassA = (SetupDiGetINFClassA_t)GetProcAddress(setupApiMod, "SetupDiGetINFClassA"))) { + fprintf(stderr, "FATAL: SetupDiGetINFClassA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiCreateDeviceInfoList = (SetupDiCreateDeviceInfoList_t)GetProcAddress(setupApiMod,"SetupDiCreateDeviceInfoList"))) { - fprintf(stderr,"FATAL: SetupDiCreateDeviceInfoList not found in setupapi.dll\r\n"); + if (! (this->SetupDiCreateDeviceInfoList = (SetupDiCreateDeviceInfoList_t)GetProcAddress(setupApiMod, "SetupDiCreateDeviceInfoList"))) { + fprintf(stderr, "FATAL: SetupDiCreateDeviceInfoList not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiCreateDeviceInfoA = (SetupDiCreateDeviceInfoA_t)GetProcAddress(setupApiMod,"SetupDiCreateDeviceInfoA"))) { - fprintf(stderr,"FATAL: SetupDiCreateDeviceInfoA not found in setupapi.dll\r\n"); + if (! (this->SetupDiCreateDeviceInfoA = (SetupDiCreateDeviceInfoA_t)GetProcAddress(setupApiMod, "SetupDiCreateDeviceInfoA"))) { + fprintf(stderr, "FATAL: SetupDiCreateDeviceInfoA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiSetDeviceRegistryPropertyA = (SetupDiSetDeviceRegistryPropertyA_t)GetProcAddress(setupApiMod,"SetupDiSetDeviceRegistryPropertyA"))) { - fprintf(stderr,"FATAL: SetupDiSetDeviceRegistryPropertyA not found in setupapi.dll\r\n"); + if (! (this->SetupDiSetDeviceRegistryPropertyA = (SetupDiSetDeviceRegistryPropertyA_t)GetProcAddress(setupApiMod, "SetupDiSetDeviceRegistryPropertyA"))) { + fprintf(stderr, "FATAL: SetupDiSetDeviceRegistryPropertyA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiCallClassInstaller = (SetupDiCallClassInstaller_t)GetProcAddress(setupApiMod,"SetupDiCallClassInstaller"))) { - fprintf(stderr,"FATAL: SetupDiCallClassInstaller not found in setupapi.dll\r\n"); + if (! (this->SetupDiCallClassInstaller = (SetupDiCallClassInstaller_t)GetProcAddress(setupApiMod, "SetupDiCallClassInstaller"))) { + fprintf(stderr, "FATAL: SetupDiCallClassInstaller not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoList_t)GetProcAddress(setupApiMod,"SetupDiDestroyDeviceInfoList"))) { - fprintf(stderr,"FATAL: SetupDiDestroyDeviceInfoList not found in setupapi.dll\r\n"); + if (! (this->SetupDiDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoList_t)GetProcAddress(setupApiMod, "SetupDiDestroyDeviceInfoList"))) { + fprintf(stderr, "FATAL: SetupDiDestroyDeviceInfoList not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiGetClassDevsExA = (SetupDiGetClassDevsExA_t)GetProcAddress(setupApiMod,"SetupDiGetClassDevsExA"))) { - fprintf(stderr,"FATAL: SetupDiGetClassDevsExA not found in setupapi.dll\r\n"); + if (! (this->SetupDiGetClassDevsExA = (SetupDiGetClassDevsExA_t)GetProcAddress(setupApiMod, "SetupDiGetClassDevsExA"))) { + fprintf(stderr, "FATAL: SetupDiGetClassDevsExA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiOpenDeviceInfoA = (SetupDiOpenDeviceInfoA_t)GetProcAddress(setupApiMod,"SetupDiOpenDeviceInfoA"))) { - fprintf(stderr,"FATAL: SetupDiOpenDeviceInfoA not found in setupapi.dll\r\n"); + if (! (this->SetupDiOpenDeviceInfoA = (SetupDiOpenDeviceInfoA_t)GetProcAddress(setupApiMod, "SetupDiOpenDeviceInfoA"))) { + fprintf(stderr, "FATAL: SetupDiOpenDeviceInfoA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiEnumDeviceInfo = (SetupDiEnumDeviceInfo_t)GetProcAddress(setupApiMod,"SetupDiEnumDeviceInfo"))) { - fprintf(stderr,"FATAL: SetupDiEnumDeviceInfo not found in setupapi.dll\r\n"); + if (! (this->SetupDiEnumDeviceInfo = (SetupDiEnumDeviceInfo_t)GetProcAddress(setupApiMod, "SetupDiEnumDeviceInfo"))) { + fprintf(stderr, "FATAL: SetupDiEnumDeviceInfo not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiSetClassInstallParamsA = (SetupDiSetClassInstallParamsA_t)GetProcAddress(setupApiMod,"SetupDiSetClassInstallParamsA"))) { - fprintf(stderr,"FATAL: SetupDiSetClassInstallParamsA not found in setupapi.dll\r\n"); + if (! (this->SetupDiSetClassInstallParamsA = (SetupDiSetClassInstallParamsA_t)GetProcAddress(setupApiMod, "SetupDiSetClassInstallParamsA"))) { + fprintf(stderr, "FATAL: SetupDiSetClassInstallParamsA not found in setupapi.dll\r\n"); _exit(1); } - if (!(this->SetupDiGetDeviceInstanceIdA = (SetupDiGetDeviceInstanceIdA_t)GetProcAddress(setupApiMod,"SetupDiGetDeviceInstanceIdA"))) { - fprintf(stderr,"FATAL: SetupDiGetDeviceInstanceIdA not found in setupapi.dll\r\n"); + if (! (this->SetupDiGetDeviceInstanceIdA = (SetupDiGetDeviceInstanceIdA_t)GetProcAddress(setupApiMod, "SetupDiGetDeviceInstanceIdA"))) { + fprintf(stderr, "FATAL: SetupDiGetDeviceInstanceIdA not found in setupapi.dll\r\n"); _exit(1); } newDevMod = LoadLibraryA("newdev.dll"); - if (!newDevMod) { - fprintf(stderr,"FATAL: unable to dynamically load newdev.dll\r\n"); + if (! newDevMod) { + fprintf(stderr, "FATAL: unable to dynamically load newdev.dll\r\n"); _exit(1); } - if (!(this->UpdateDriverForPlugAndPlayDevicesA = (UpdateDriverForPlugAndPlayDevicesA_t)GetProcAddress(newDevMod,"UpdateDriverForPlugAndPlayDevicesA"))) { - fprintf(stderr,"FATAL: UpdateDriverForPlugAndPlayDevicesA not found in newdev.dll\r\n"); + if (! (this->UpdateDriverForPlugAndPlayDevicesA = (UpdateDriverForPlugAndPlayDevicesA_t)GetProcAddress(newDevMod, "UpdateDriverForPlugAndPlayDevicesA"))) { + fprintf(stderr, "FATAL: UpdateDriverForPlugAndPlayDevicesA not found in newdev.dll\r\n"); _exit(1); } cfgMgrMod = LoadLibraryA("cfgmgr32.dll"); - if (!cfgMgrMod) { - fprintf(stderr,"FATAL: unable to dynamically load cfgmgr32.dll\r\n"); + if (! cfgMgrMod) { + fprintf(stderr, "FATAL: unable to dynamically load cfgmgr32.dll\r\n"); _exit(1); } - if (!(this->CM_Get_Device_ID_ExA = (CM_Get_Device_ID_ExA_t)GetProcAddress(cfgMgrMod,"CM_Get_Device_ID_ExA"))) { - fprintf(stderr,"FATAL: CM_Get_Device_ID_ExA not found in cfgmgr32.dll\r\n"); + if (! (this->CM_Get_Device_ID_ExA = (CM_Get_Device_ID_ExA_t)GetProcAddress(cfgMgrMod, "CM_Get_Device_ID_ExA"))) { + fprintf(stderr, "FATAL: CM_Get_Device_ID_ExA not found in cfgmgr32.dll\r\n"); _exit(1); } } - BOOL is64Bit; // is the system 64-bit, regardless of whether this binary is or not + BOOL is64Bit; // is the system 64-bit, regardless of whether this binary is or not std::string tapDriverPath; std::string tapDriverName; @@ -182,7 +188,7 @@ public: CM_Get_Device_ID_ExA_t CM_Get_Device_ID_ExA; -private: + private: HMODULE setupApiMod; HMODULE newDevMod; HMODULE cfgMgrMod; @@ -195,37 +201,37 @@ static Mutex _systemTapInitLock; // Only perform installation or uninstallation options one at a time static Mutex _systemDeviceManagementLock; -} // anonymous namespace +} // anonymous namespace -std::string WindowsEthernetTap::addNewPersistentTapDevice(const char *pathToInf,std::string &deviceInstanceId) +std::string WindowsEthernetTap::addNewPersistentTapDevice(const char* pathToInf, std::string& deviceInstanceId) { Mutex::Lock _l(_systemDeviceManagementLock); GUID classGuid; char className[1024]; - if (!WINENV.SetupDiGetINFClassA(pathToInf,&classGuid,className,sizeof(className),(PDWORD)0)) { + if (! WINENV.SetupDiGetINFClassA(pathToInf, &classGuid, className, sizeof(className), (PDWORD)0)) { return std::string("SetupDiGetINFClassA() failed -- unable to read zttap driver INF file"); } - HDEVINFO deviceInfoSet = WINENV.SetupDiCreateDeviceInfoList(&classGuid,(HWND)0); + HDEVINFO deviceInfoSet = WINENV.SetupDiCreateDeviceInfoList(&classGuid, (HWND)0); if (deviceInfoSet == INVALID_HANDLE_VALUE) { return std::string("SetupDiCreateDeviceInfoList() failed"); } SP_DEVINFO_DATA deviceInfoData; - memset(&deviceInfoData,0,sizeof(deviceInfoData)); + memset(&deviceInfoData, 0, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(deviceInfoData); - if (!WINENV.SetupDiCreateDeviceInfoA(deviceInfoSet,className,&classGuid,(PCSTR)0,(HWND)0,DICD_GENERATE_ID,&deviceInfoData)) { + if (! WINENV.SetupDiCreateDeviceInfoA(deviceInfoSet, className, &classGuid, (PCSTR)0, (HWND)0, DICD_GENERATE_ID, &deviceInfoData)) { WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet); return std::string("SetupDiCreateDeviceInfoA() failed"); } - if (!WINENV.SetupDiSetDeviceRegistryPropertyA(deviceInfoSet,&deviceInfoData,SPDRP_HARDWAREID,(const BYTE *)WINENV.tapDriverName.c_str(),(DWORD)(WINENV.tapDriverName.length() + 1))) { + if (! WINENV.SetupDiSetDeviceRegistryPropertyA(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, (const BYTE*)WINENV.tapDriverName.c_str(), (DWORD)(WINENV.tapDriverName.length() + 1))) { WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet); return std::string("SetupDiSetDeviceRegistryPropertyA() failed"); } - if (!WINENV.SetupDiCallClassInstaller(DIF_REGISTERDEVICE,deviceInfoSet,&deviceInfoData)) { + if (! WINENV.SetupDiCallClassInstaller(DIF_REGISTERDEVICE, deviceInfoSet, &deviceInfoData)) { WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet); return std::string("SetupDiCallClassInstaller(DIF_REGISTERDEVICE) failed"); } @@ -233,23 +239,25 @@ std::string WindowsEthernetTap::addNewPersistentTapDevice(const char *pathToInf, // HACK: During upgrades, this can fail while the installer is still running. So make 60 attempts // with a 1s delay between each attempt. bool driverInstalled = false; - for(int retryCounter=0;retryCounter<60;++retryCounter) { + for (int retryCounter = 0; retryCounter < 60; ++retryCounter) { BOOL rebootRequired = FALSE; - if (WINENV.UpdateDriverForPlugAndPlayDevicesA((HWND)0,WINENV.tapDriverName.c_str(),pathToInf,INSTALLFLAG_FORCE|INSTALLFLAG_NONINTERACTIVE,&rebootRequired)) { + if (WINENV.UpdateDriverForPlugAndPlayDevicesA((HWND)0, WINENV.tapDriverName.c_str(), pathToInf, INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, &rebootRequired)) { driverInstalled = true; break; - } else Sleep(1000); + } + else + Sleep(1000); } - if (!driverInstalled) { + if (! driverInstalled) { WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet); return std::string("UpdateDriverForPlugAndPlayDevices() failed (made 60 attempts)"); } char iidbuf[1024]; DWORD iidReqSize = sizeof(iidbuf); - if (WINENV.SetupDiGetDeviceInstanceIdA(deviceInfoSet,&deviceInfoData,iidbuf,sizeof(iidbuf),&iidReqSize)) { + if (WINENV.SetupDiGetDeviceInstanceIdA(deviceInfoSet, &deviceInfoData, iidbuf, sizeof(iidbuf), &iidReqSize)) { deviceInstanceId = iidbuf; - } // failure here is not fatal since we only need this on Vista and 2008 -- other versions fill it into the registry automatically + } // failure here is not fatal since we only need this on Vista and 2008 -- other versions fill it into the registry automatically WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet); @@ -265,39 +273,41 @@ std::string WindowsEthernetTap::destroyAllLegacyPersistentTapDevices() std::set instanceIdPathsToRemove; { HKEY nwAdapters; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS) + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ | KEY_WRITE, &nwAdapters) != ERROR_SUCCESS) return std::string("Could not open registry key"); - for(DWORD subkeyIndex=0;;++subkeyIndex) { + for (DWORD subkeyIndex = 0;; ++subkeyIndex) { DWORD type; DWORD dataLen; DWORD subkeyNameLen = sizeof(subkeyName); DWORD subkeyClassLen = sizeof(subkeyClass); FILETIME lastWriteTime; - if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { + if (RegEnumKeyExA(nwAdapters, subkeyIndex, subkeyName, &subkeyNameLen, (DWORD*)0, subkeyClass, &subkeyClassLen, &lastWriteTime) == ERROR_SUCCESS) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + if (RegGetValueA(nwAdapters, subkeyName, "ComponentId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { data[dataLen] = '\0'; - if ((!strnicmp(data,"zttap",5))&&(WINENV.tapDriverName != data)) { + if ((! strnicmp(data, "zttap", 5)) && (WINENV.tapDriverName != data)) { std::string instanceIdPath; type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - instanceIdPath.assign(data,dataLen); + if (RegGetValueA(nwAdapters, subkeyName, "DeviceInstanceID", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) + instanceIdPath.assign(data, dataLen); if (instanceIdPath.length() != 0) instanceIdPathsToRemove.insert(instanceIdPath); } } - } else break; // end of list or failure + } + else + break; // end of list or failure } RegCloseKey(nwAdapters); } std::string errlist; - for(std::set::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) { + for (std::set::iterator iidp(instanceIdPathsToRemove.begin()); iidp != instanceIdPathsToRemove.end(); ++iidp) { std::string err = deletePersistentTapDevice(iidp->c_str()); if (err.length() > 0) { if (errlist.length() > 0) @@ -317,39 +327,41 @@ std::string WindowsEthernetTap::destroyAllPersistentTapDevices() std::set instanceIdPathsToRemove; { HKEY nwAdapters; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS) + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ | KEY_WRITE, &nwAdapters) != ERROR_SUCCESS) return std::string("Could not open registry key"); - for(DWORD subkeyIndex=0;;++subkeyIndex) { + for (DWORD subkeyIndex = 0;; ++subkeyIndex) { DWORD type; DWORD dataLen; DWORD subkeyNameLen = sizeof(subkeyName); DWORD subkeyClassLen = sizeof(subkeyClass); FILETIME lastWriteTime; - if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { + if (RegEnumKeyExA(nwAdapters, subkeyIndex, subkeyName, &subkeyNameLen, (DWORD*)0, subkeyClass, &subkeyClassLen, &lastWriteTime) == ERROR_SUCCESS) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + if (RegGetValueA(nwAdapters, subkeyName, "ComponentId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { data[dataLen] = '\0'; - if (!strnicmp(data,"zttap",5)) { + if (! strnicmp(data, "zttap", 5)) { std::string instanceIdPath; type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - instanceIdPath.assign(data,dataLen); + if (RegGetValueA(nwAdapters, subkeyName, "DeviceInstanceID", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) + instanceIdPath.assign(data, dataLen); if (instanceIdPath.length() != 0) instanceIdPathsToRemove.insert(instanceIdPath); } } - } else break; // end of list or failure + } + else + break; // end of list or failure } RegCloseKey(nwAdapters); } std::string errlist; - for(std::set::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) { + for (std::set::iterator iidp(instanceIdPathsToRemove.begin()); iidp != instanceIdPathsToRemove.end(); ++iidp) { std::string err = deletePersistentTapDevice(iidp->c_str()); if (err.length() > 0) { if (errlist.length() > 0) @@ -360,12 +372,12 @@ std::string WindowsEthernetTap::destroyAllPersistentTapDevices() return errlist; } -std::string WindowsEthernetTap::deletePersistentTapDevice(const char *instanceId) +std::string WindowsEthernetTap::deletePersistentTapDevice(const char* instanceId) { char iid[256]; SP_REMOVEDEVICE_PARAMS rmdParams; - memset(&rmdParams,0,sizeof(rmdParams)); + memset(&rmdParams, 0, sizeof(rmdParams)); rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; @@ -373,22 +385,22 @@ std::string WindowsEthernetTap::deletePersistentTapDevice(const char *instanceId Mutex::Lock _l(_systemDeviceManagementLock); - HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID *)0,(PCSTR)0,(HWND)0,DIGCF_ALLCLASSES,(HDEVINFO)0,(PCSTR)0,(PVOID)0); + HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID*)0, (PCSTR)0, (HWND)0, DIGCF_ALLCLASSES, (HDEVINFO)0, (PCSTR)0, (PVOID)0); if (devInfo == INVALID_HANDLE_VALUE) return std::string("SetupDiGetClassDevsExA() failed"); - WINENV.SetupDiOpenDeviceInfoA(devInfo,instanceId,(HWND)0,0,(PSP_DEVINFO_DATA)0); + WINENV.SetupDiOpenDeviceInfoA(devInfo, instanceId, (HWND)0, 0, (PSP_DEVINFO_DATA)0); SP_DEVINFO_DATA devInfoData; - memset(&devInfoData,0,sizeof(devInfoData)); + memset(&devInfoData, 0, sizeof(devInfoData)); devInfoData.cbSize = sizeof(devInfoData); - for(DWORD devIndex=0;WINENV.SetupDiEnumDeviceInfo(devInfo,devIndex,&devInfoData);devIndex++) { - if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst,iid,sizeof(iid),0,(HMACHINE)0) == CR_SUCCESS)&&(!strcmp(iid,instanceId))) { - if (!WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,&rmdParams.ClassInstallHeader,sizeof(rmdParams))) { + for (DWORD devIndex = 0; WINENV.SetupDiEnumDeviceInfo(devInfo, devIndex, &devInfoData); devIndex++) { + if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst, iid, sizeof(iid), 0, (HMACHINE)0) == CR_SUCCESS) && (! strcmp(iid, instanceId))) { + if (! WINENV.SetupDiSetClassInstallParamsA(devInfo, &devInfoData, &rmdParams.ClassInstallHeader, sizeof(rmdParams))) { WINENV.SetupDiDestroyDeviceInfoList(devInfo); return std::string("SetupDiSetClassInstallParams() failed"); } - if (!WINENV.SetupDiCallClassInstaller(DIF_REMOVE,devInfo,&devInfoData)) { + if (! WINENV.SetupDiCallClassInstaller(DIF_REMOVE, devInfo, &devInfoData)) { WINENV.SetupDiDestroyDeviceInfoList(devInfo); return std::string("SetupDiCallClassInstaller(DIF_REMOVE) failed"); } @@ -402,42 +414,42 @@ std::string WindowsEthernetTap::deletePersistentTapDevice(const char *instanceId return std::string("instance ID not found"); } -bool WindowsEthernetTap::setPersistentTapDeviceState(const char *instanceId,bool enabled) +bool WindowsEthernetTap::setPersistentTapDeviceState(const char* instanceId, bool enabled) { char iid[256]; SP_PROPCHANGE_PARAMS params; Mutex::Lock _l(_systemDeviceManagementLock); - HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID *)0,(PCSTR)0,(HWND)0,DIGCF_ALLCLASSES,(HDEVINFO)0,(PCSTR)0,(PVOID)0); + HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID*)0, (PCSTR)0, (HWND)0, DIGCF_ALLCLASSES, (HDEVINFO)0, (PCSTR)0, (PVOID)0); if (devInfo == INVALID_HANDLE_VALUE) return false; - WINENV.SetupDiOpenDeviceInfoA(devInfo,instanceId,(HWND)0,0,(PSP_DEVINFO_DATA)0); + WINENV.SetupDiOpenDeviceInfoA(devInfo, instanceId, (HWND)0, 0, (PSP_DEVINFO_DATA)0); SP_DEVINFO_DATA devInfoData; - memset(&devInfoData,0,sizeof(devInfoData)); + memset(&devInfoData, 0, sizeof(devInfoData)); devInfoData.cbSize = sizeof(devInfoData); - for(DWORD devIndex=0;WINENV.SetupDiEnumDeviceInfo(devInfo,devIndex,&devInfoData);devIndex++) { - if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst,iid,sizeof(iid),0,(HMACHINE)0) == CR_SUCCESS)&&(!strcmp(iid,instanceId))) { - memset(¶ms,0,sizeof(params)); + for (DWORD devIndex = 0; WINENV.SetupDiEnumDeviceInfo(devInfo, devIndex, &devInfoData); devIndex++) { + if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst, iid, sizeof(iid), 0, (HMACHINE)0) == CR_SUCCESS) && (! strcmp(iid, instanceId))) { + memset(¶ms, 0, sizeof(params)); params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; params.StateChange = enabled ? DICS_ENABLE : DICS_DISABLE; params.Scope = DICS_FLAG_GLOBAL; params.HwProfile = 0; - WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,¶ms.ClassInstallHeader,sizeof(params)); - WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,devInfo,&devInfoData); + WINENV.SetupDiSetClassInstallParamsA(devInfo, &devInfoData, ¶ms.ClassInstallHeader, sizeof(params)); + WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devInfo, &devInfoData); - memset(¶ms,0,sizeof(params)); + memset(¶ms, 0, sizeof(params)); params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; params.StateChange = enabled ? DICS_ENABLE : DICS_DISABLE; params.Scope = DICS_FLAG_CONFIGSPECIFIC; params.HwProfile = 0; - WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,¶ms.ClassInstallHeader,sizeof(params)); - WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,devInfo,&devInfoData); + WINENV.SetupDiSetClassInstallParamsA(devInfo, &devInfoData, ¶ms.ClassInstallHeader, sizeof(params)); + WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devInfo, &devInfoData); WINENV.SetupDiDestroyDeviceInfoList(devInfo); return true; @@ -449,27 +461,27 @@ bool WindowsEthernetTap::setPersistentTapDeviceState(const char *instanceId,bool } WindowsEthernetTap::WindowsEthernetTap( - const char *hp, - const MAC &mac, + const char* hp, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg) : - _handler(handler), - _arg(arg), - _mac(mac), - _nwid(nwid), - _mtu(mtu), - _tap(INVALID_HANDLE_VALUE), - _friendlyName(friendlyName), - _injectSemaphore(INVALID_HANDLE_VALUE), - _pathToHelpers(hp), - _run(true), - _initialized(false), - _enabled(true), - _lastIfAddrsUpdate(0) + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg) + : _handler(handler) + , _arg(arg) + , _mac(mac) + , _nwid(nwid) + , _mtu(mtu) + , _tap(INVALID_HANDLE_VALUE) + , _friendlyName(friendlyName) + , _injectSemaphore(INVALID_HANDLE_VALUE) + , _pathToHelpers(hp) + , _run(true) + , _initialized(false) + , _enabled(true) + , _lastIfAddrsUpdate(0) { char subkeyName[1024]; char subkeyClass[1024]; @@ -477,165 +489,171 @@ WindowsEthernetTap::WindowsEthernetTap( char tag[24]; // We "tag" registry entries with the network ID to identify persistent devices - OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid); + OSUtils::ztsnprintf(tag, sizeof(tag), "%.16llx", (unsigned long long)nwid); Mutex::Lock _l(_systemTapInitLock); HKEY nwAdapters; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS) + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ | KEY_WRITE, &nwAdapters) != ERROR_SUCCESS) throw std::runtime_error("unable to open registry key for network adapter enumeration"); // Look for the tap instance that corresponds with this network - for(DWORD subkeyIndex=0;;++subkeyIndex) { + for (DWORD subkeyIndex = 0;; ++subkeyIndex) { DWORD type; DWORD dataLen; DWORD subkeyNameLen = sizeof(subkeyName); DWORD subkeyClassLen = sizeof(subkeyClass); FILETIME lastWriteTime; - if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { + if (RegEnumKeyExA(nwAdapters, subkeyIndex, subkeyName, &subkeyNameLen, (DWORD*)0, subkeyClass, &subkeyClassLen, &lastWriteTime) == ERROR_SUCCESS) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + if (RegGetValueA(nwAdapters, subkeyName, "ComponentId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { data[dataLen] = (char)0; if (WINENV.tapDriverName == data) { std::string instanceId; type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - instanceId.assign(data,dataLen); + if (RegGetValueA(nwAdapters, subkeyName, "NetCfgInstanceId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) + instanceId.assign(data, dataLen); std::string instanceIdPath; type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - instanceIdPath.assign(data,dataLen); + if (RegGetValueA(nwAdapters, subkeyName, "DeviceInstanceID", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) + instanceIdPath.assign(data, dataLen); - if ((_netCfgInstanceId.length() == 0)&&(instanceId.length() != 0)&&(instanceIdPath.length() != 0)) { + if ((_netCfgInstanceId.length() == 0) && (instanceId.length() != 0) && (instanceIdPath.length() != 0)) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + if (RegGetValueA(nwAdapters, subkeyName, "_ZeroTierTapIdentifier", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { data[dataLen] = '\0'; - if (!strcmp(data,tag)) { + if (! strcmp(data, tag)) { _netCfgInstanceId = instanceId; _deviceInstanceId = instanceIdPath; _mySubkeyName = subkeyName; - break; // found it! + break; // found it! } } } } } - } else break; // no more subkeys or error occurred enumerating them + } + else + break; // no more subkeys or error occurred enumerating them } // If there is no device, try to create one bool creatingNewDevice = (_netCfgInstanceId.length() == 0); std::string newDeviceInstanceId; if (creatingNewDevice) { - for(int getNewAttemptCounter=0;getNewAttemptCounter<2;++getNewAttemptCounter) { - for(DWORD subkeyIndex=0;;++subkeyIndex) { + for (int getNewAttemptCounter = 0; getNewAttemptCounter < 2; ++getNewAttemptCounter) { + for (DWORD subkeyIndex = 0;; ++subkeyIndex) { DWORD type; DWORD dataLen; DWORD subkeyNameLen = sizeof(subkeyName); DWORD subkeyClassLen = sizeof(subkeyClass); FILETIME lastWriteTime; - if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { + if (RegEnumKeyExA(nwAdapters, subkeyIndex, subkeyName, &subkeyNameLen, (DWORD*)0, subkeyClass, &subkeyClassLen, &lastWriteTime) == ERROR_SUCCESS) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + if (RegGetValueA(nwAdapters, subkeyName, "ComponentId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { data[dataLen] = '\0'; if (WINENV.tapDriverName == data) { type = 0; dataLen = sizeof(data); - if ((RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) != ERROR_SUCCESS)||(dataLen <= 0)) { + if ((RegGetValueA(nwAdapters, subkeyName, "_ZeroTierTapIdentifier", RRF_RT_ANY, &type, (PVOID)data, &dataLen) != ERROR_SUCCESS) || (dataLen <= 0)) { type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { - RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1)); + if (RegGetValueA(nwAdapters, subkeyName, "NetCfgInstanceId", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) { + RegSetKeyValueA(nwAdapters, subkeyName, "_ZeroTierTapIdentifier", REG_SZ, tag, (DWORD)(strlen(tag) + 1)); - _netCfgInstanceId.assign(data,dataLen); + _netCfgInstanceId.assign(data, dataLen); type = 0; dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - _deviceInstanceId.assign(data,dataLen); + if (RegGetValueA(nwAdapters, subkeyName, "DeviceInstanceID", RRF_RT_ANY, &type, (PVOID)data, &dataLen) == ERROR_SUCCESS) + _deviceInstanceId.assign(data, dataLen); _mySubkeyName = subkeyName; // Disable DHCP by default on new devices HKEY tcpIpInterfaces; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) { + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces", 0, KEY_READ | KEY_WRITE, &tcpIpInterfaces) == ERROR_SUCCESS) { DWORD enable = 0; - RegSetKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),"EnableDHCP",REG_DWORD,&enable,sizeof(enable)); + RegSetKeyValueA(tcpIpInterfaces, _netCfgInstanceId.c_str(), "EnableDHCP", REG_DWORD, &enable, sizeof(enable)); RegCloseKey(tcpIpInterfaces); } - break; // found an unused zttap device + break; // found an unused zttap device } } } } - } else break; // no more keys or error occurred + } + else + break; // no more keys or error occurred } if (_netCfgInstanceId.length() > 0) { - break; // found an unused zttap device - } else { + break; // found an unused zttap device + } + else { // no unused zttap devices, so create one - std::string errm = addNewPersistentTapDevice((std::string(_pathToHelpers) + WINENV.tapDriverPath).c_str(),newDeviceInstanceId); + std::string errm = addNewPersistentTapDevice((std::string(_pathToHelpers) + WINENV.tapDriverPath).c_str(), newDeviceInstanceId); if (errm.length() > 0) - throw std::runtime_error(std::string("unable to create new device instance: ")+errm); + throw std::runtime_error(std::string("unable to create new device instance: ") + errm); } } } if (_netCfgInstanceId.length() > 0) { char tmps[64]; - unsigned int tmpsl = OSUtils::ztsnprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac[0],(unsigned int)mac[1],(unsigned int)mac[2],(unsigned int)mac[3],(unsigned int)mac[4],(unsigned int)mac[5]) + 1; - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl); - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl); + unsigned int tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%.2X-%.2X-%.2X-%.2X-%.2X-%.2X", (unsigned int)mac[0], (unsigned int)mac[1], (unsigned int)mac[2], (unsigned int)mac[3], (unsigned int)mac[4], (unsigned int)mac[5]) + 1; + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "NetworkAddress", REG_SZ, tmps, tmpsl); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "MAC", REG_SZ, tmps, tmpsl); tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu); - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MTU",REG_SZ,tmps,tmpsl); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "MTU", REG_SZ, tmps, tmpsl); DWORD tmp = 0; - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*NdisDeviceType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp)); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "*NdisDeviceType", REG_DWORD, (LPCVOID)&tmp, sizeof(tmp)); tmp = IF_TYPE_ETHERNET_CSMACD; - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*IfType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp)); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "*IfType", REG_DWORD, (LPCVOID)&tmp, sizeof(tmp)); if (creatingNewDevice) { // Vista/2008 does not set this if (newDeviceInstanceId.length() > 0) - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"DeviceInstanceID",REG_SZ,newDeviceInstanceId.c_str(),(DWORD)newDeviceInstanceId.length()); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "DeviceInstanceID", REG_SZ, newDeviceInstanceId.c_str(), (DWORD)newDeviceInstanceId.length()); // Set EnableDHCP to 0 by default on new devices tmp = 0; - RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp)); + RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "EnableDHCP", REG_DWORD, (LPCVOID)&tmp, sizeof(tmp)); } RegCloseKey(nwAdapters); - } else { + } + else { RegCloseKey(nwAdapters); throw std::runtime_error("unable to find or create tap adapter"); } { - char nobraces[128]; // strip braces from GUID before converting it, because Windows - const char *nbtmp1 = _netCfgInstanceId.c_str(); - char *nbtmp2 = nobraces; + char nobraces[128]; // strip braces from GUID before converting it, because Windows + const char* nbtmp1 = _netCfgInstanceId.c_str(); + char* nbtmp2 = nobraces; while (*nbtmp1) { - if ((*nbtmp1 != '{')&&(*nbtmp1 != '}')) + if ((*nbtmp1 != '{') && (*nbtmp1 != '}')) *nbtmp2++ = *nbtmp1; ++nbtmp1; } *nbtmp2 = (char)0; - if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK) + if (UuidFromStringA((RPC_CSTR)nobraces, &_deviceGuid) != RPC_S_OK) throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); } // Get the LUID, which is one of like four fucking ways to refer to a network device in Windows - if (ConvertInterfaceGuidToLuid(&_deviceGuid,&_deviceLuid) != NO_ERROR) + if (ConvertInterfaceGuidToLuid(&_deviceGuid, &_deviceLuid) != NO_ERROR) throw std::runtime_error("unable to convert device interface GUID to LUID"); //_initialized = true; @@ -643,7 +661,7 @@ WindowsEthernetTap::WindowsEthernetTap( if (friendlyName) setFriendlyName(friendlyName); - _injectSemaphore = CreateSemaphore(NULL,0,1,NULL); + _injectSemaphore = CreateSemaphore(NULL, 0, 1, NULL); _thread = Thread::start(this); } @@ -651,10 +669,10 @@ WindowsEthernetTap::~WindowsEthernetTap() { WinDNSHelper::removeDNS(_nwid); _run = false; - ReleaseSemaphore(_injectSemaphore,1,NULL); + ReleaseSemaphore(_injectSemaphore, 1, NULL); Thread::join(_thread); CloseHandle(_injectSemaphore); - setPersistentTapDeviceState(_deviceInstanceId.c_str(),false); + setPersistentTapDeviceState(_deviceInstanceId.c_str(), false); } void WindowsEthernetTap::setEnabled(bool en) @@ -667,49 +685,49 @@ bool WindowsEthernetTap::enabled() const return _enabled; } -bool WindowsEthernetTap::addIp(const InetAddress &ip) +bool WindowsEthernetTap::addIp(const InetAddress& ip) { - if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT? + if (! ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT? return false; Mutex::Lock _l(_assignedIps_m); - if (std::find(_assignedIps.begin(),_assignedIps.end(),ip) != _assignedIps.end()) + if (std::find(_assignedIps.begin(), _assignedIps.end(), ip) != _assignedIps.end()) return true; _assignedIps.push_back(ip); _syncIps(); return true; } -bool WindowsEthernetTap::removeIp(const InetAddress &ip) +bool WindowsEthernetTap::removeIp(const InetAddress& ip) { - if (ip.isV6()) - return true; + if (ip.isV6()) + return true; { Mutex::Lock _l(_assignedIps_m); - std::vector::iterator aip(std::find(_assignedIps.begin(),_assignedIps.end(),ip)); + std::vector::iterator aip(std::find(_assignedIps.begin(), _assignedIps.end(), ip)); if (aip != _assignedIps.end()) _assignedIps.erase(aip); } - if (!_initialized) + if (! _initialized) return false; try { - MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; - if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { - if ((ipt)&&(ipt->NumEntries > 0)) { - for(DWORD i=0;i<(DWORD)ipt->NumEntries;++i) { + MIB_UNICASTIPADDRESS_TABLE* ipt = (MIB_UNICASTIPADDRESS_TABLE*)0; + if (GetUnicastIpAddressTable(AF_UNSPEC, &ipt) == NO_ERROR) { + if ((ipt) && (ipt->NumEntries > 0)) { + for (DWORD i = 0; i < (DWORD)ipt->NumEntries; ++i) { if (ipt->Table[i].InterfaceLuid.Value == _deviceLuid.Value) { InetAddress addr; - switch(ipt->Table[i].Address.si_family) { + switch (ipt->Table[i].Address.si_family) { case AF_INET: - addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength); + addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr), 4, ipt->Table[i].OnLinkPrefixLength); break; case AF_INET6: - addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength); + addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte, 16, ipt->Table[i].OnLinkPrefixLength); if (addr.ipScope() == InetAddress::IP_SCOPE_LINK_LOCAL) - continue; // can't remove link-local IPv6 addresses + continue; // can't remove link-local IPv6 addresses break; } if (addr == ip) { @@ -739,16 +757,18 @@ bool WindowsEthernetTap::removeIp(const InetAddress &ip) } FreeMibTable((PVOID)ipt); } - } catch ( ... ) {} + } + catch (...) { + } return false; } std::vector WindowsEthernetTap::ips() const { - static const InetAddress linkLocalLoopback("fe80::1/64"); // what is this and why does Windows assign it? + static const InetAddress linkLocalLoopback("fe80::1/64"); // what is this and why does Windows assign it? std::vector addrs; - if (!_initialized) + if (! _initialized) return addrs; uint64_t now = OSUtils::now(); @@ -760,91 +780,94 @@ std::vector WindowsEthernetTap::ips() const _lastIfAddrsUpdate = now; try { - MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; - if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { - if ((ipt)&&(ipt->NumEntries > 0)) { - for(DWORD i=0;i<(DWORD)ipt->NumEntries;++i) { + MIB_UNICASTIPADDRESS_TABLE* ipt = (MIB_UNICASTIPADDRESS_TABLE*)0; + if (GetUnicastIpAddressTable(AF_UNSPEC, &ipt) == NO_ERROR) { + if ((ipt) && (ipt->NumEntries > 0)) { + for (DWORD i = 0; i < (DWORD)ipt->NumEntries; ++i) { if (ipt->Table[i].InterfaceLuid.Value == _deviceLuid.Value) { - switch(ipt->Table[i].Address.si_family) { + switch (ipt->Table[i].Address.si_family) { case AF_INET: { - InetAddress ip(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength); + InetAddress ip(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr), 4, ipt->Table[i].OnLinkPrefixLength); if (ip != InetAddress::LO4) addrs.push_back(ip); - } break; + } break; case AF_INET6: { - InetAddress ip(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength); - if ((ip != linkLocalLoopback)&&(ip != InetAddress::LO6)) + InetAddress ip(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte, 16, ipt->Table[i].OnLinkPrefixLength); + if ((ip != linkLocalLoopback) && (ip != InetAddress::LO6)) addrs.push_back(ip); - } break; + } break; } } } } FreeMibTable(ipt); } - } catch ( ... ) {} // sanity check, shouldn't happen unless out of memory + } + catch (...) { + } // sanity check, shouldn't happen unless out of memory - std::sort(addrs.begin(),addrs.end()); - addrs.erase(std::unique(addrs.begin(),addrs.end()),addrs.end()); + std::sort(addrs.begin(), addrs.end()); + addrs.erase(std::unique(addrs.begin(), addrs.end()), addrs.end()); _ifaddrs = addrs; return addrs; } -void WindowsEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +void WindowsEthernetTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len) { - if ((!_initialized)||(!_enabled)||(_tap == INVALID_HANDLE_VALUE)||(len > _mtu)) + if ((! _initialized) || (! _enabled) || (_tap == INVALID_HANDLE_VALUE) || (len > _mtu)) return; Mutex::Lock _l(_injectPending_m); _injectPending.emplace(); _injectPending.back().len = len + 14; - char *const d = _injectPending.back().data; - to.copyTo(d,6); - from.copyTo(d + 6,6); + char* const d = _injectPending.back().data; + to.copyTo(d, 6); + from.copyTo(d + 6, 6); d[12] = (char)((etherType >> 8) & 0xff); d[13] = (char)(etherType & 0xff); - memcpy(d + 14,data,len); + memcpy(d + 14, data, len); - ReleaseSemaphore(_injectSemaphore,1,NULL); + ReleaseSemaphore(_injectSemaphore, 1, NULL); } std::string WindowsEthernetTap::deviceName() const { char tmp[1024]; - if (ConvertInterfaceLuidToNameA(&_deviceLuid,tmp,sizeof(tmp)) != NO_ERROR) + if (ConvertInterfaceLuidToNameA(&_deviceLuid, tmp, sizeof(tmp)) != NO_ERROR) return std::string("[ConvertInterfaceLuidToName() failed]"); return std::string(tmp); } -void WindowsEthernetTap::setFriendlyName(const char *dn) +void WindowsEthernetTap::setFriendlyName(const char* dn) { - if (!_initialized) + if (! _initialized) return; HKEY ifp; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,(std::string("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") + _netCfgInstanceId).c_str(),0,KEY_READ|KEY_WRITE,&ifp) == ERROR_SUCCESS) { - RegSetKeyValueA(ifp,"Connection","Name",REG_SZ,(LPCVOID)dn,(DWORD)(strlen(dn)+1)); + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, (std::string("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") + _netCfgInstanceId).c_str(), 0, KEY_READ | KEY_WRITE, &ifp) == ERROR_SUCCESS) { + RegSetKeyValueA(ifp, "Connection", "Name", REG_SZ, (LPCVOID)dn, (DWORD)(strlen(dn) + 1)); RegCloseKey(ifp); } HRESULT hr = S_OK; - INetSharingManager *nsm; + INetSharingManager* nsm; hr = CoCreateInstance(__uuidof(NetSharingManager), NULL, CLSCTX_ALL, __uuidof(INetSharingManager), (void**)&nsm); - if (hr != S_OK) return; + if (hr != S_OK) + return; bool found = false; - INetSharingEveryConnectionCollection *nsecc = nullptr; + INetSharingEveryConnectionCollection* nsecc = nullptr; hr = nsm->get_EnumEveryConnection(&nsecc); - if (!nsecc) { + if (! nsecc) { fprintf(stderr, "Failed to get NSM connections"); return; } - IEnumVARIANT *ev = nullptr; - IUnknown *unk = nullptr; + IEnumVARIANT* ev = nullptr; + IUnknown* unk = nullptr; hr = nsecc->get__NewEnum(&unk); if (unk) { hr = unk->QueryInterface(__uuidof(IEnumVARIANT), (void**)&ev); @@ -856,17 +879,17 @@ void WindowsEthernetTap::setFriendlyName(const char *dn) while ((S_OK == ev->Next(1, &v, NULL)) && found == FALSE) { if (V_VT(&v) == VT_UNKNOWN) { - INetConnection *nc = nullptr; + INetConnection* nc = nullptr; V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void**)&nc); if (nc) { - NETCON_PROPERTIES *ncp = nullptr; + NETCON_PROPERTIES* ncp = nullptr; nc->GetProperties(&ncp); if (ncp != nullptr) { GUID curId = ncp->guidId; if (curId == _deviceGuid) { wchar_t wtext[255]; - mbstowcs(wtext, dn, strlen(dn)+1); + mbstowcs(wtext, dn, strlen(dn) + 1); nc->Rename(wtext); found = true; } @@ -891,9 +914,9 @@ std::string WindowsEthernetTap::friendlyName() const return _friendlyName; } -void WindowsEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +void WindowsEthernetTap::scanMulticastGroups(std::vector& added, std::vector& removed) { - if (!_initialized) + if (! _initialized) return; HANDLE t = _tap; if (t == INVALID_HANDLE_VALUE) @@ -906,34 +929,34 @@ void WindowsEthernetTap::scanMulticastGroups(std::vector &added, // pretty much anything work... IPv4, IPv6, IPX, oldskool Netbios, who knows... unsigned char mcastbuf[TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE]; DWORD bytesReturned = 0; - if (DeviceIoControl(t,TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS,(LPVOID)mcastbuf,sizeof(mcastbuf),(LPVOID)mcastbuf,sizeof(mcastbuf),&bytesReturned,NULL)) { - if ((bytesReturned > 0)&&(bytesReturned <= TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE)) { // sanity check + if (DeviceIoControl(t, TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS, (LPVOID)mcastbuf, sizeof(mcastbuf), (LPVOID)mcastbuf, sizeof(mcastbuf), &bytesReturned, NULL)) { + if ((bytesReturned > 0) && (bytesReturned <= TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE)) { // sanity check MAC mac; DWORD i = 0; while ((i + 6) <= bytesReturned) { - mac.setTo(mcastbuf + i,6); + mac.setTo(mcastbuf + i, 6); i += 6; - if ((mac.isMulticast())&&(!mac.isBroadcast())) { + if ((mac.isMulticast()) && (! mac.isBroadcast())) { // exclude the nulls that may be returned or any other junk Windows puts in there - newGroups.push_back(MulticastGroup(mac,0)); + newGroups.push_back(MulticastGroup(mac, 0)); } } } } std::vector allIps(ips()); - for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + for (std::vector::iterator ip(allIps.begin()); ip != allIps.end(); ++ip) newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); - std::sort(newGroups.begin(),newGroups.end()); - newGroups.erase(std::unique(newGroups.begin(),newGroups.end()),newGroups.end()); + std::sort(newGroups.begin(), newGroups.end()); + newGroups.erase(std::unique(newGroups.begin(), newGroups.end()), newGroups.end()); - for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { - if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + for (std::vector::iterator m(newGroups.begin()); m != newGroups.end(); ++m) { + if (! std::binary_search(_multicastGroups.begin(), _multicastGroups.end(), *m)) added.push_back(*m); } - for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { - if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + for (std::vector::iterator m(_multicastGroups.begin()); m != _multicastGroups.end(); ++m) { + if (! std::binary_search(newGroups.begin(), newGroups.end(), *m)) removed.push_back(*m); } @@ -957,13 +980,12 @@ void WindowsEthernetTap::setMtu(unsigned int mtu) NET_IFINDEX WindowsEthernetTap::interfaceIndex() const { NET_IFINDEX idx = -1; - if (ConvertInterfaceLuidToIndex(&_deviceLuid,&idx) == NO_ERROR) + if (ConvertInterfaceLuidToIndex(&_deviceLuid, &idx) == NO_ERROR) return idx; return -1; } -void WindowsEthernetTap::threadMain() - throw() +void WindowsEthernetTap::threadMain() throw() { HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { @@ -974,24 +996,24 @@ void WindowsEthernetTap::threadMain() char tapReadBuf[ZT_MAX_MTU + 32]; char tapPath[128]; HANDLE wait4[3]; - OVERLAPPED tapOvlRead,tapOvlWrite; + OVERLAPPED tapOvlRead, tapOvlWrite; - OSUtils::ztsnprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str()); + OSUtils::ztsnprintf(tapPath, sizeof(tapPath), "\\\\.\\Global\\%s.tap", _netCfgInstanceId.c_str()); try { while (_run) { // Because Windows Sleep(250); - setPersistentTapDeviceState(_deviceInstanceId.c_str(),false); + setPersistentTapDeviceState(_deviceInstanceId.c_str(), false); Sleep(250); - setPersistentTapDeviceState(_deviceInstanceId.c_str(),true); + setPersistentTapDeviceState(_deviceInstanceId.c_str(), true); Sleep(250); - setPersistentTapDeviceState(_deviceInstanceId.c_str(),false); + setPersistentTapDeviceState(_deviceInstanceId.c_str(), false); Sleep(250); - setPersistentTapDeviceState(_deviceInstanceId.c_str(),true); + setPersistentTapDeviceState(_deviceInstanceId.c_str(), true); Sleep(250); - _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL); + _tap = CreateFileA(tapPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL); if (_tap == INVALID_HANDLE_VALUE) { Sleep(250); continue; @@ -1000,7 +1022,7 @@ void WindowsEthernetTap::threadMain() { uint32_t tmpi = 1; DWORD bytesReturned = 0; - DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL); + DeviceIoControl(_tap, TAP_WIN_IOCTL_SET_MEDIA_STATUS, &tmpi, sizeof(tmpi), &tmpi, sizeof(tmpi), &bytesReturned, NULL); } #ifdef ZT_WINDOWS_CREATE_FAKE_DEFAULT_ROUTE @@ -1040,14 +1062,14 @@ void WindowsEthernetTap::threadMain() * the routing table before doing so. * * Like Jesse Pinkman would say: "YEEEEAAH BITCH!" */ - const uint32_t fakeIp = htonl(0x19fffffe); // 25.255.255.254 -- unrouted IPv4 block - for(int i=0;i<8;++i) { + const uint32_t fakeIp = htonl(0x19fffffe); // 25.255.255.254 -- unrouted IPv4 block + for (int i = 0; i < 8; ++i) { MIB_IPNET_ROW2 ipnr; - memset(&ipnr,0,sizeof(ipnr)); + memset(&ipnr, 0, sizeof(ipnr)); ipnr.Address.si_family = AF_INET; ipnr.Address.Ipv4.sin_addr.s_addr = fakeIp; ipnr.InterfaceLuid.Value = _deviceLuid.Value; - ipnr.PhysicalAddress[0] = _mac[0] ^ 0x10; // just make something up that's consistent and not part of this net + ipnr.PhysicalAddress[0] = _mac[0] ^ 0x10; // just make something up that's consistent and not part of this net ipnr.PhysicalAddress[1] = 0x00; ipnr.PhysicalAddress[2] = (UCHAR)((_deviceGuid.Data1 >> 24) & 0xff); ipnr.PhysicalAddress[3] = (UCHAR)((_deviceGuid.Data1 >> 16) & 0xff); @@ -1062,22 +1084,24 @@ void WindowsEthernetTap::threadMain() DWORD result = CreateIpNetEntry2(&ipnr); if (result != NO_ERROR) Sleep(250); - else break; + else + break; } - for(int i=0;i<8;++i) { + for (int i = 0; i < 8; ++i) { MIB_IPFORWARD_ROW2 nr; - memset(&nr,0,sizeof(nr)); + memset(&nr, 0, sizeof(nr)); InitializeIpForwardEntry(&nr); nr.InterfaceLuid.Value = _deviceLuid.Value; - nr.DestinationPrefix.Prefix.si_family = AF_INET; // rest is left as 0.0.0.0/0 + nr.DestinationPrefix.Prefix.si_family = AF_INET; // rest is left as 0.0.0.0/0 nr.NextHop.si_family = AF_INET; nr.NextHop.Ipv4.sin_addr.s_addr = fakeIp; - nr.Metric = 9999; // do not use as real default route + nr.Metric = 9999; // do not use as real default route nr.Protocol = MIB_IPPROTO_NETMGMT; DWORD result = CreateIpForwardEntry2(&nr); if (result != NO_ERROR) Sleep(250); - else break; + else + break; } } #endif @@ -1088,16 +1112,16 @@ void WindowsEthernetTap::threadMain() _syncIps(); } - memset(&tapOvlRead,0,sizeof(tapOvlRead)); - tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - memset(&tapOvlWrite,0,sizeof(tapOvlWrite)); - tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + memset(&tapOvlRead, 0, sizeof(tapOvlRead)); + tapOvlRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + memset(&tapOvlWrite, 0, sizeof(tapOvlWrite)); + tapOvlWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); wait4[0] = _injectSemaphore; wait4[1] = tapOvlRead.hEvent; - wait4[2] = tapOvlWrite.hEvent; // only included if writeInProgress is true + wait4[2] = tapOvlWrite.hEvent; // only included if writeInProgress is true - ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead); + ReadFile(_tap, tapReadBuf, sizeof(tapReadBuf), NULL, &tapOvlRead); bool writeInProgress = false; ULONGLONG timeOfLastBorkCheck = GetTickCount64(); _initialized = true; @@ -1106,8 +1130,9 @@ void WindowsEthernetTap::threadMain() setFriendlyName(_friendlyName.c_str()); while (_run) { - DWORD waitResult = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE); - if (!_run) break; // will also break outer while(_run) since _run is false + DWORD waitResult = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2, wait4, FALSE, 2500, TRUE); + if (! _run) + break; // will also break outer while(_run) since _run is false // Check for changes in MTU and break to restart tap device to reconfigure in this case if (_mtu != oldmtu) @@ -1123,7 +1148,13 @@ void WindowsEthernetTap::threadMain() timeOfLastBorkCheck = tc; char aabuf[16384]; ULONG aalen = sizeof(aabuf); - if (GetAdaptersAddresses(AF_UNSPEC,GAA_FLAG_SKIP_UNICAST|GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME,(void *)0,reinterpret_cast(aabuf),&aalen) == NO_ERROR) { + if (GetAdaptersAddresses( + AF_UNSPEC, + GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, + (void*)0, + reinterpret_cast(aabuf), + &aalen) + == NO_ERROR) { bool isBorked = false; PIP_ADAPTER_ADDRESSES aa = reinterpret_cast(aabuf); @@ -1143,24 +1174,26 @@ void WindowsEthernetTap::threadMain() } } - if ((waitResult == WAIT_TIMEOUT)||(waitResult == WAIT_FAILED)) { - Sleep(250); // guard against spinning under some conditions + if ((waitResult == WAIT_TIMEOUT) || (waitResult == WAIT_FAILED)) { + Sleep(250); // guard against spinning under some conditions continue; } if (HasOverlappedIoCompleted(&tapOvlRead)) { DWORD bytesRead = 0; - if (GetOverlappedResult(_tap,&tapOvlRead,&bytesRead,FALSE)) { - if ((bytesRead > 14)&&(_enabled)) { - MAC to(tapReadBuf,6); - MAC from(tapReadBuf + 6,6); + if (GetOverlappedResult(_tap, &tapOvlRead, &bytesRead, FALSE)) { + if ((bytesRead > 14) && (_enabled)) { + MAC to(tapReadBuf, 6); + MAC from(tapReadBuf + 6, 6); unsigned int etherType = ((((unsigned int)tapReadBuf[12]) & 0xff) << 8) | (((unsigned int)tapReadBuf[13]) & 0xff); try { - _handler(_arg,(void *)0,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14); - } catch ( ... ) {} // handlers should not throw + _handler(_arg, (void*)0, _nwid, from, to, etherType, 0, tapReadBuf + 14, bytesRead - 14); + } + catch (...) { + } // handlers should not throw } } - ReadFile(_tap,tapReadBuf,ZT_MAX_MTU + 32,NULL,&tapOvlRead); + ReadFile(_tap, tapReadBuf, ZT_MAX_MTU + 32, NULL, &tapOvlRead); } if (writeInProgress) { @@ -1168,11 +1201,15 @@ void WindowsEthernetTap::threadMain() writeInProgress = false; _injectPending_m.lock(); _injectPending.pop(); - } else continue; // still writing, so skip code below and wait - } else _injectPending_m.lock(); + } + else + continue; // still writing, so skip code below and wait + } + else + _injectPending_m.lock(); - if (!_injectPending.empty()) { - WriteFile(_tap,_injectPending.front().data,_injectPending.front().len,NULL,&tapOvlWrite); + if (! _injectPending.empty()) { + WriteFile(_tap, _injectPending.front().data, _injectPending.front().len, NULL, &tapOvlWrite); writeInProgress = true; } @@ -1188,19 +1225,21 @@ void WindowsEthernetTap::threadMain() // We will restart and re-open the tap unless _run == false } - } catch ( ... ) {} // catch unexpected exceptions -- this should not happen but would prevent program crash or other weird issues since threads should not throw + } + catch (...) { + } // catch unexpected exceptions -- this should not happen but would prevent program crash or other weird issues since threads should not throw CoUninitialize(); } NET_IFINDEX WindowsEthernetTap::_getDeviceIndex() { - MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0; + MIB_IF_TABLE2* ift = (MIB_IF_TABLE2*)0; - if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR) + if (GetIfTable2Ex(MibIfTableRaw, &ift) != NO_ERROR) throw std::runtime_error("GetIfTable2Ex() failed"); if (ift->NumEntries > 0) { - for(ULONG i=0;iNumEntries;++i) { + for (ULONG i = 0; i < ift->NumEntries; ++i) { if (ift->Table[i].InterfaceLuid.Value == _deviceLuid.Value) { NET_IFINDEX idx = ift->Table[i].InterfaceIndex; FreeMibTable(ift); @@ -1214,30 +1253,32 @@ NET_IFINDEX WindowsEthernetTap::_getDeviceIndex() throw std::runtime_error("interface not found"); } -std::vector WindowsEthernetTap::_getRegistryIPv4Value(const char *regKey) +std::vector WindowsEthernetTap::_getRegistryIPv4Value(const char* regKey) { std::vector value; HKEY tcpIpInterfaces; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) { + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces", 0, KEY_READ | KEY_WRITE, &tcpIpInterfaces) == ERROR_SUCCESS) { char buf[16384]; DWORD len = sizeof(buf); DWORD kt = REG_MULTI_SZ; - if (RegGetValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey,0,&kt,&buf,&len) == ERROR_SUCCESS) { - switch(kt) { + if (RegGetValueA(tcpIpInterfaces, _netCfgInstanceId.c_str(), regKey, 0, &kt, &buf, &len) == ERROR_SUCCESS) { + switch (kt) { case REG_SZ: if (len > 0) value.push_back(std::string(buf)); break; case REG_MULTI_SZ: { - for(DWORD k=0,s=0;k WindowsEthernetTap::_getRegistryIPv4Value(const char *r return value; } -void WindowsEthernetTap::_setRegistryIPv4Value(const char *regKey,const std::vector &value) +void WindowsEthernetTap::_setRegistryIPv4Value(const char* regKey, const std::vector& value) { std::string regMulti; - for(std::vector::const_iterator s(value.begin());s!=value.end();++s) { + for (std::vector::const_iterator s(value.begin()); s != value.end(); ++s) { regMulti.append(*s); regMulti.push_back((char)0); } HKEY tcpIpInterfaces; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) { + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces", 0, KEY_READ | KEY_WRITE, &tcpIpInterfaces) == ERROR_SUCCESS) { if (regMulti.length() > 0) { regMulti.push_back((char)0); - RegSetKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey,REG_MULTI_SZ,regMulti.data(),(DWORD)regMulti.length()); - } else { - RegDeleteKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey); + RegSetKeyValueA(tcpIpInterfaces, _netCfgInstanceId.c_str(), regKey, REG_MULTI_SZ, regMulti.data(), (DWORD)regMulti.length()); + } + else { + RegDeleteKeyValueA(tcpIpInterfaces, _netCfgInstanceId.c_str(), regKey); } RegCloseKey(tcpIpInterfaces); } @@ -1268,29 +1310,32 @@ void WindowsEthernetTap::_syncIps() { // assumes _assignedIps_m is locked - if (!_initialized) + if (! _initialized) return; std::vector haveIps(ips()); - for(std::vector::const_iterator aip(_assignedIps.begin());aip!=_assignedIps.end();++aip) { - if (std::find(haveIps.begin(),haveIps.end(),*aip) == haveIps.end()) { + for (std::vector::const_iterator aip(_assignedIps.begin()); aip != _assignedIps.end(); ++aip) { + if (std::find(haveIps.begin(), haveIps.end(), *aip) == haveIps.end()) { MIB_UNICASTIPADDRESS_ROW ipr; InitializeUnicastIpAddressEntry(&ipr); if (aip->isV4()) { ipr.Address.Ipv4.sin_family = AF_INET; - ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)aip->rawIpData()); + ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t*)aip->rawIpData()); ipr.OnLinkPrefixLength = aip->netmaskBits(); if (ipr.OnLinkPrefixLength >= 32) continue; - } else if (aip->isV6()) { + } + else if (aip->isV6()) { ipr.Address.Ipv6.sin6_family = AF_INET6; - memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,aip->rawIpData(),16); + memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte, aip->rawIpData(), 16); ipr.OnLinkPrefixLength = aip->netmaskBits(); if (ipr.OnLinkPrefixLength >= 128) continue; - } else continue; + } + else + continue; ipr.PrefixOrigin = IpPrefixOriginManual; ipr.SuffixOrigin = IpSuffixOriginManual; @@ -1323,4 +1368,4 @@ void WindowsEthernetTap::setDns(const char* domain, const std::vector -#include - -#include - -#include -#include -#include - #include "../node/Constants.hpp" -#include "../node/Mutex.hpp" -#include "../node/MulticastGroup.hpp" #include "../node/InetAddress.hpp" +#include "../node/MulticastGroup.hpp" +#include "../node/Mutex.hpp" #include "../osdep/Thread.hpp" #include "EthernetTap.hpp" +#include +#include +#include +#include +#include +#include + namespace ZeroTier { -class WindowsEthernetTap : public EthernetTap -{ -public: +class WindowsEthernetTap : public EthernetTap { + public: /** * Installs a new instance of the ZT tap driver * @@ -42,7 +39,7 @@ public: * @param deviceInstanceId Buffer to fill with device instance ID on success (and if SetupDiGetDeviceInstanceIdA succeeds, which it should) * @return Empty string on success, otherwise an error message */ - static std::string addNewPersistentTapDevice(const char *pathToInf,std::string &deviceInstanceId); + static std::string addNewPersistentTapDevice(const char* pathToInf, std::string& deviceInstanceId); /** * Uninstalls all persistent tap devices that have legacy drivers @@ -64,7 +61,7 @@ public: * @param instanceId Device instance ID * @return Empty string on success, otherwise an error message */ - static std::string deletePersistentTapDevice(const char *instanceId); + static std::string deletePersistentTapDevice(const char* instanceId); /** * Disable a persistent tap device by instance ID @@ -73,51 +70,62 @@ public: * @param enabled Enable device? * @return True if device was found and disabled */ - static bool setPersistentTapDeviceState(const char *instanceId,bool enabled); + static bool setPersistentTapDeviceState(const char* instanceId, bool enabled); WindowsEthernetTap( - const char *hp, - const MAC &mac, + const char* hp, + const MAC& mac, unsigned int mtu, unsigned int metric, uint64_t nwid, - const char *friendlyName, - void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), - void *arg); + const char* friendlyName, + void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int), + void* arg); virtual ~WindowsEthernetTap(); virtual void setEnabled(bool en); virtual bool enabled() const; - virtual bool addIp(const InetAddress &ip); - virtual bool removeIp(const InetAddress &ip); + virtual bool addIp(const InetAddress& ip); + virtual bool removeIp(const InetAddress& ip); virtual std::vector ips() const; - virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len); virtual std::string deviceName() const; - virtual void setFriendlyName(const char *friendlyName); + virtual void setFriendlyName(const char* friendlyName); virtual std::string friendlyName() const; - virtual void scanMulticastGroups(std::vector &added,std::vector &removed); + virtual void scanMulticastGroups(std::vector& added, std::vector& removed); virtual void setMtu(unsigned int mtu); - virtual void setDns(const char* domain, const std::vector &servers); + virtual void setDns(const char* domain, const std::vector& servers); - inline const NET_LUID &luid() const { return _deviceLuid; } - inline const GUID &guid() const { return _deviceGuid; } - inline const std::string &instanceId() const { return _deviceInstanceId; } + inline const NET_LUID& luid() const + { + return _deviceLuid; + } + inline const GUID& guid() const + { + return _deviceGuid; + } + inline const std::string& instanceId() const + { + return _deviceInstanceId; + } NET_IFINDEX interfaceIndex() const; - void threadMain() - throw(); + void threadMain() throw(); - bool isInitialized() const { return _initialized; }; + bool isInitialized() const + { + return _initialized; + }; -private: - NET_IFINDEX _getDeviceIndex(); // throws on failure - std::vector _getRegistryIPv4Value(const char *regKey); - void _setRegistryIPv4Value(const char *regKey,const std::vector &value); + private: + NET_IFINDEX _getDeviceIndex(); // throws on failure + std::vector _getRegistryIPv4Value(const char* regKey); + void _setRegistryIPv4Value(const char* regKey, const std::vector& value); void _syncIps(); - void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; + void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int); + void* _arg; MAC _mac; uint64_t _nwid; volatile unsigned int _mtu; @@ -134,13 +142,12 @@ private: std::string _friendlyName; Mutex _friendlyName_m; - std::vector _assignedIps; // IPs assigned with addIp + std::vector _assignedIps; // IPs assigned with addIp Mutex _assignedIps_m; std::vector _multicastGroups; - struct _InjectPending - { + struct _InjectPending { unsigned int len; char data[ZT_MAX_MTU + 32]; }; @@ -157,6 +164,6 @@ private: mutable uint64_t _lastIfAddrsUpdate; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/service/OneService.cpp b/service/OneService.cpp index 594ff02de..a089d11a8 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -11,51 +11,48 @@ */ /****/ +#include +#include #include +#include +#include +#include +#include #include #include #include -#include #include -#include -#include -#include -#include #include -#include -#include +#include #ifdef __FreeBSD__ -#include #include +#include #endif -#include "../version.h" #include "../include/ZeroTierOne.h" - +#include "../node/Bond.hpp" #include "../node/Constants.hpp" -#include "../node/Mutex.hpp" -#include "../node/Node.hpp" -#include "../node/Utils.hpp" +#include "../node/Identity.hpp" #include "../node/InetAddress.hpp" #include "../node/MAC.hpp" -#include "../node/Identity.hpp" -#include "../node/World.hpp" -#include "../node/Salsa20.hpp" +#include "../node/Mutex.hpp" +#include "../node/Node.hpp" +#include "../node/PacketMultiplexer.hpp" +#include "../node/Peer.hpp" #include "../node/Poly1305.hpp" #include "../node/SHA512.hpp" -#include "../node/Bond.hpp" -#include "../node/Peer.hpp" -#include "../node/PacketMultiplexer.hpp" - -#include "../osdep/Phy.hpp" -#include "../osdep/OSUtils.hpp" -#include "../osdep/Http.hpp" -#include "../osdep/PortMapper.hpp" +#include "../node/Salsa20.hpp" +#include "../node/Utils.hpp" +#include "../node/World.hpp" #include "../osdep/Binder.hpp" -#include "../osdep/ManagedRoute.hpp" #include "../osdep/BlockingQueue.hpp" - +#include "../osdep/Http.hpp" +#include "../osdep/ManagedRoute.hpp" +#include "../osdep/OSUtils.hpp" +#include "../osdep/Phy.hpp" +#include "../osdep/PortMapper.hpp" +#include "../version.h" #include "OneService.hpp" #include "SoftwareUpdater.hpp" @@ -66,20 +63,20 @@ #endif #ifdef __WINDOWS__ -#include -#include -#include -#include #include -//#include +#include +#include +#include +#include +// #include #define stat _stat #else -#include +#include #include #include +#include #include #include -#include #endif #ifdef __APPLE__ @@ -103,8 +100,8 @@ extern "C" { } #endif -#include #include +#include using json = nlohmann::json; @@ -122,7 +119,7 @@ using json = nlohmann::json; // Sanity limits for HTTP #define ZT_MAX_HTTP_MESSAGE_SIZE (1024 * 1024 * 64) -#define ZT_MAX_HTTP_CONNECTIONS 65536 +#define ZT_MAX_HTTP_CONNECTIONS 65536 // Interface metric for ZeroTier taps -- this ensures that if we are on WiFi and also // bridged via ZeroTier to the same LAN traffic will (if the OS is sane) prefer WiFi. @@ -152,14 +149,13 @@ using json = nlohmann::json; #define ZT_TCP_ACTIVITY_TIMEOUT 60000 #if ZT_VAULT_SUPPORT -size_t curlResponseWrite(void *ptr, size_t size, size_t nmemb, std::string *data) +size_t curlResponseWrite(void* ptr, size_t size, size_t nmemb, std::string* data) { data->append((char*)ptr, size * nmemb); return size * nmemb; } #endif - namespace ZeroTier { std::string ssoResponseTemplate = R"""( @@ -206,7 +202,8 @@ std::string ssoResponseTemplate = R"""( )"""; -bool bearerTokenValid(const std::string authHeader, const std::string &checkToken) { +bool bearerTokenValid(const std::string authHeader, const std::string& checkToken) +{ std::vector tokens = OSUtils::split(authHeader.c_str(), " ", NULL, NULL); if (tokens.size() != 2) { return false; @@ -214,7 +211,7 @@ bool bearerTokenValid(const std::string authHeader, const std::string &checkToke std::string bearer = tokens[0]; std::string token = tokens[1]; - std::transform(bearer.begin(), bearer.end(), bearer.begin(), [](unsigned char c){return std::tolower(c);}); + std::transform(bearer.begin(), bearer.end(), bearer.begin(), [](unsigned char c) { return std::tolower(c); }); if (bearer != "bearer") { return false; } @@ -226,65 +223,65 @@ bool bearerTokenValid(const std::string authHeader, const std::string &checkToke return true; } -#if ZT_DEBUG==1 -std::string dump_headers(const httplib::Headers &headers) { - std::string s; - char buf[BUFSIZ]; +#if ZT_DEBUG == 1 +std::string dump_headers(const httplib::Headers& headers) +{ + std::string s; + char buf[BUFSIZ]; - for (auto it = headers.begin(); it != headers.end(); ++it) { - const auto &x = *it; - snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str()); - s += buf; - } + for (auto it = headers.begin(); it != headers.end(); ++it) { + const auto& x = *it; + snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str()); + s += buf; + } - return s; + return s; } -std::string http_log(const httplib::Request &req, const httplib::Response &res) { - std::string s; - char buf[BUFSIZ]; +std::string http_log(const httplib::Request& req, const httplib::Response& res) +{ + std::string s; + char buf[BUFSIZ]; - s += "================================\n"; + s += "================================\n"; - snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(), - req.version.c_str(), req.path.c_str()); - s += buf; + snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(), req.version.c_str(), req.path.c_str()); + s += buf; - std::string query; - for (auto it = req.params.begin(); it != req.params.end(); ++it) { - const auto &x = *it; - snprintf(buf, sizeof(buf), "%c%s=%s", - (it == req.params.begin()) ? '?' : '&', x.first.c_str(), - x.second.c_str()); - query += buf; - } - snprintf(buf, sizeof(buf), "%s\n", query.c_str()); - s += buf; + std::string query; + for (auto it = req.params.begin(); it != req.params.end(); ++it) { + const auto& x = *it; + snprintf(buf, sizeof(buf), "%c%s=%s", (it == req.params.begin()) ? '?' : '&', x.first.c_str(), x.second.c_str()); + query += buf; + } + snprintf(buf, sizeof(buf), "%s\n", query.c_str()); + s += buf; - s += dump_headers(req.headers); + s += dump_headers(req.headers); - s += "--------------------------------\n"; + s += "--------------------------------\n"; - snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str()); - s += buf; - s += dump_headers(res.headers); - s += "\n"; + snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str()); + s += buf; + s += dump_headers(res.headers); + s += "\n"; - if (!res.body.empty()) { s += res.body; } + if (! res.body.empty()) { + s += res.body; + } - s += "\n"; + s += "\n"; - return s; + return s; } #endif // Configured networks -class NetworkState -{ -public: +class NetworkState { + public: NetworkState() : _webPort(9993) - , _tap((EthernetTap *)0) + , _tap((EthernetTap*)0) #if ZT_SSO_ENABLED , _idc(nullptr) #endif @@ -311,89 +308,99 @@ public: #endif } - void setWebPort(unsigned int port) { + void setWebPort(unsigned int port) + { _webPort = port; } - void setTap(std::shared_ptr tap) { + void setTap(std::shared_ptr tap) + { this->_tap = tap; } - std::shared_ptr tap() const { + std::shared_ptr tap() const + { return _tap; } - OneService::NetworkSettings settings() const { + OneService::NetworkSettings settings() const + { return _settings; } - void setSettings(const OneService::NetworkSettings &settings) { + void setSettings(const OneService::NetworkSettings& settings) + { _settings = settings; } - void setAllowManaged(bool allow) { + void setAllowManaged(bool allow) + { _settings.allowManaged = allow; } - bool allowManaged() const { + bool allowManaged() const + { return _settings.allowManaged; } - void setAllowGlobal(bool allow) { + void setAllowGlobal(bool allow) + { _settings.allowGlobal = allow; } - bool allowGlobal() const { + bool allowGlobal() const + { return _settings.allowGlobal; } - void setAllowDefault(bool allow) { + void setAllowDefault(bool allow) + { _settings.allowDefault = allow; } - bool allowDefault() const { + bool allowDefault() const + { return _settings.allowDefault; } - void setAllowDNS(bool allow) { + void setAllowDNS(bool allow) + { _settings.allowDNS = allow; } - bool allowDNS() const { + bool allowDNS() const + { return _settings.allowDNS; } - std::vector allowManagedWhitelist() const { + std::vector allowManagedWhitelist() const + { return _settings.allowManagedWhitelist; } - void addToAllowManagedWhiteList(const InetAddress& addr) { + void addToAllowManagedWhiteList(const InetAddress& addr) + { _settings.allowManagedWhitelist.push_back(addr); } - const ZT_VirtualNetworkConfig& config() { + const ZT_VirtualNetworkConfig& config() + { return _config; } - void setConfig(const ZT_VirtualNetworkConfig *nwc) { + void setConfig(const ZT_VirtualNetworkConfig* nwc) + { memcpy(&_config, nwc, sizeof(ZT_VirtualNetworkConfig)); if (_config.ssoEnabled && _config.ssoVersion == 1) { #if ZT_SSO_ENABLED - if (_idc == nullptr) - { + if (_idc == nullptr) { assert(_config.issuerURL != nullptr); assert(_config.ssoClientID != nullptr); assert(_config.centralAuthURL != nullptr); assert(_config.ssoProvider != nullptr); - _idc = zeroidc::zeroidc_new( - _config.issuerURL, - _config.ssoClientID, - _config.centralAuthURL, - _config.ssoProvider, - _webPort - ); + _idc = zeroidc::zeroidc_new(_config.issuerURL, _config.ssoClientID, _config.centralAuthURL, _config.ssoProvider, _webPort); if (_idc == nullptr) { fprintf(stderr, "idc is null\n"); @@ -401,11 +408,7 @@ public: } } - zeroidc::zeroidc_set_nonce_and_csrf( - _idc, - _config.ssoState, - _config.ssoNonce - ); + zeroidc::zeroidc_set_nonce_and_csrf(_idc, _config.ssoState, _config.ssoNonce); char* url = zeroidc::zeroidc_get_auth_url(_idc); memcpy(_config.authenticationURL, url, strlen(url)); @@ -419,21 +422,24 @@ public: } } - std::vector& managedIps() { + std::vector& managedIps() + { return _managedIps; } - void setManagedIps(const std::vector &managedIps) { + void setManagedIps(const std::vector& managedIps) + { _managedIps = managedIps; } - std::map< InetAddress, SharedPtr >& managedRoutes() { + std::map >& managedRoutes() + { return _managedRoutes; } - - char* doTokenExchange(const char *code) { - char *ret = nullptr; + char* doTokenExchange(const char* code) + { + char* ret = nullptr; #if ZT_SSO_ENABLED if (_idc == nullptr) { fprintf(stderr, "ainfo or idc null\n"); @@ -441,11 +447,7 @@ public: } ret = zeroidc::zeroidc_token_exchange(_idc, code); - zeroidc::zeroidc_set_nonce_and_csrf( - _idc, - _config.ssoState, - _config.ssoNonce - ); + zeroidc::zeroidc_set_nonce_and_csrf(_idc, _config.ssoState, _config.ssoNonce); char* url = zeroidc::zeroidc_get_auth_url(_idc); memcpy(_config.authenticationURL, url, strlen(url)); @@ -455,7 +457,8 @@ public: return ret; } - uint64_t getExpiryTime() { + uint64_t getExpiryTime() + { #if ZT_SSO_ENABLED if (_idc == nullptr) { fprintf(stderr, "idc is null\n"); @@ -467,15 +470,15 @@ public: #endif } -private: + private: unsigned int _webPort; std::shared_ptr _tap; - ZT_VirtualNetworkConfig _config; // memcpy() of raw config from core + ZT_VirtualNetworkConfig _config; // memcpy() of raw config from core std::vector _managedIps; - std::map< InetAddress, SharedPtr > _managedRoutes; + std::map > _managedRoutes; OneService::NetworkSettings _settings; #if ZT_SSO_ENABLED - zeroidc::ZeroIDC *_idc; + zeroidc::ZeroIDC* _idc; #endif }; @@ -484,50 +487,81 @@ namespace { static const InetAddress NULL_INET_ADDR; // Fake TLS hello for TCP tunnel outgoing connections (TUNNELED mode) -static const char ZT_TCP_TUNNEL_HELLO[9] = { 0x17,0x03,0x03,0x00,0x04,(char)ZEROTIER_ONE_VERSION_MAJOR,(char)ZEROTIER_ONE_VERSION_MINOR,(char)((ZEROTIER_ONE_VERSION_REVISION >> 8) & 0xff),(char)(ZEROTIER_ONE_VERSION_REVISION & 0xff) }; +static const char ZT_TCP_TUNNEL_HELLO[9] = { + 0x17, 0x03, 0x03, 0x00, 0x04, (char)ZEROTIER_ONE_VERSION_MAJOR, (char)ZEROTIER_ONE_VERSION_MINOR, (char)((ZEROTIER_ONE_VERSION_REVISION >> 8) & 0xff), (char)(ZEROTIER_ONE_VERSION_REVISION & 0xff) +}; -static std::string _trimString(const std::string &s) +static std::string _trimString(const std::string& s) { unsigned long end = (unsigned long)s.length(); while (end) { char c = s[end - 1]; - if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) + if ((c == ' ') || (c == '\r') || (c == '\n') || (! c) || (c == '\t')) --end; - else break; + else + break; } unsigned long start = 0; while (start < end) { char c = s[start]; - if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) + if ((c == ' ') || (c == '\r') || (c == '\n') || (! c) || (c == '\t')) ++start; - else break; + else + break; } - return s.substr(start,end - start); + return s.substr(start, end - start); } -static void _networkToJson(nlohmann::json &nj,NetworkState &ns) +static void _networkToJson(nlohmann::json& nj, NetworkState& ns) { char tmp[256]; - const char *nstatus = "",*ntype = ""; - switch(ns.config().status) { - case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: nstatus = "REQUESTING_CONFIGURATION"; break; - case ZT_NETWORK_STATUS_OK: nstatus = "OK"; break; - case ZT_NETWORK_STATUS_ACCESS_DENIED: nstatus = "ACCESS_DENIED"; break; - case ZT_NETWORK_STATUS_NOT_FOUND: nstatus = "NOT_FOUND"; break; - case ZT_NETWORK_STATUS_PORT_ERROR: nstatus = "PORT_ERROR"; break; - case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: nstatus = "CLIENT_TOO_OLD"; break; - case ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED: nstatus = "AUTHENTICATION_REQUIRED"; break; + const char *nstatus = "", *ntype = ""; + switch (ns.config().status) { + case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: + nstatus = "REQUESTING_CONFIGURATION"; + break; + case ZT_NETWORK_STATUS_OK: + nstatus = "OK"; + break; + case ZT_NETWORK_STATUS_ACCESS_DENIED: + nstatus = "ACCESS_DENIED"; + break; + case ZT_NETWORK_STATUS_NOT_FOUND: + nstatus = "NOT_FOUND"; + break; + case ZT_NETWORK_STATUS_PORT_ERROR: + nstatus = "PORT_ERROR"; + break; + case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: + nstatus = "CLIENT_TOO_OLD"; + break; + case ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED: + nstatus = "AUTHENTICATION_REQUIRED"; + break; } - switch(ns.config().type) { - case ZT_NETWORK_TYPE_PRIVATE: ntype = "PRIVATE"; break; - case ZT_NETWORK_TYPE_PUBLIC: ntype = "PUBLIC"; break; + switch (ns.config().type) { + case ZT_NETWORK_TYPE_PRIVATE: + ntype = "PRIVATE"; + break; + case ZT_NETWORK_TYPE_PUBLIC: + ntype = "PUBLIC"; + break; } - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",ns.config().nwid); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", ns.config().nwid); nj["id"] = tmp; nj["nwid"] = tmp; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)((ns.config().mac >> 40) & 0xff),(unsigned int)((ns.config().mac >> 32) & 0xff),(unsigned int)((ns.config().mac >> 24) & 0xff),(unsigned int)((ns.config().mac >> 16) & 0xff),(unsigned int)((ns.config().mac >> 8) & 0xff),(unsigned int)(ns.config().mac & 0xff)); + OSUtils::ztsnprintf( + tmp, + sizeof(tmp), + "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + (unsigned int)((ns.config().mac >> 40) & 0xff), + (unsigned int)((ns.config().mac >> 32) & 0xff), + (unsigned int)((ns.config().mac >> 24) & 0xff), + (unsigned int)((ns.config().mac >> 16) & 0xff), + (unsigned int)((ns.config().mac >> 8) & 0xff), + (unsigned int)(ns.config().mac & 0xff)); nj["mac"] = tmp; nj["name"] = ns.config().name; nj["status"] = nstatus; @@ -548,18 +582,19 @@ static void _networkToJson(nlohmann::json &nj,NetworkState &ns) nj["allowDNS"] = localSettings.allowDNS; nlohmann::json aa = nlohmann::json::array(); - for(unsigned int i=0;i(&(ns.config().assignedAddresses[i]))->toString(tmp)); + for (unsigned int i = 0; i < ns.config().assignedAddressCount; ++i) { + aa.push_back(reinterpret_cast(&(ns.config().assignedAddresses[i]))->toString(tmp)); } nj["assignedAddresses"] = aa; nlohmann::json ra = nlohmann::json::array(); - for(unsigned int i=0;i(&(ns.config().routes[i].target))->toString(tmp); + rj["target"] = reinterpret_cast(&(ns.config().routes[i].target))->toString(tmp); if (ns.config().routes[i].via.ss_family == ns.config().routes[i].target.ss_family) - rj["via"] = reinterpret_cast(&(ns.config().routes[i].via))->toIpString(tmp); - else rj["via"] = nlohmann::json(); + rj["via"] = reinterpret_cast(&(ns.config().routes[i].via))->toIpString(tmp); + else + rj["via"] = nlohmann::json(); rj["flags"] = (int)ns.config().routes[i].flags; rj["metric"] = (int)ns.config().routes[i].metric; ra.push_back(rj); @@ -567,7 +602,7 @@ static void _networkToJson(nlohmann::json &nj,NetworkState &ns) nj["routes"] = ra; nlohmann::json mca = nlohmann::json::array(); - for(unsigned int i=0;i &bond, bool isTunneled) +static void _peerToJson(nlohmann::json& pj, const ZT_Peer* peer, SharedPtr& bond, bool isTunneled) { char tmp[256]; - const char *prole = ""; - switch(peer->role) { - case ZT_PEER_ROLE_LEAF: prole = "LEAF"; break; - case ZT_PEER_ROLE_MOON: prole = "MOON"; break; - case ZT_PEER_ROLE_PLANET: prole = "PLANET"; break; + const char* prole = ""; + switch (peer->role) { + case ZT_PEER_ROLE_LEAF: + prole = "LEAF"; + break; + case ZT_PEER_ROLE_MOON: + prole = "MOON"; + break; + case ZT_PEER_ROLE_PLANET: + prole = "PLANET"; + break; } - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",peer->address); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.10llx", peer->address); pj["address"] = tmp; pj["versionMajor"] = peer->versionMajor; pj["versionMinor"] = peer->versionMinor; pj["versionRev"] = peer->versionRev; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",peer->versionMajor,peer->versionMinor,peer->versionRev); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%d.%d.%d", peer->versionMajor, peer->versionMinor, peer->versionRev); pj["version"] = tmp; pj["latency"] = peer->latency; pj["role"] = prole; @@ -630,11 +670,11 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer, SharedPtr } nlohmann::json pa = nlohmann::json::array(); - for(unsigned int i=0;ipathCount;++i) { + for (unsigned int i = 0; i < peer->pathCount; ++i) { int64_t lastSend = peer->paths[i].lastSend; int64_t lastReceive = peer->paths[i].lastReceive; nlohmann::json j; - j["address"] = reinterpret_cast(&(peer->paths[i].address))->toString(tmp); + j["address"] = reinterpret_cast(&(peer->paths[i].address))->toString(tmp); j["lastSend"] = (lastSend < 0) ? 0 : lastSend; j["lastReceive"] = (lastReceive < 0) ? 0 : lastReceive; j["trustedPathId"] = peer->paths[i].trustedPathId; @@ -663,20 +703,20 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer, SharedPtr pj["paths"] = pa; } -static void _moonToJson(nlohmann::json &mj,const World &world) +static void _moonToJson(nlohmann::json& mj, const World& world) { char tmp[4096]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id()); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", world.id()); mj["id"] = tmp; mj["timestamp"] = world.timestamp(); - mj["signature"] = Utils::hex(world.signature().data,ZT_C25519_SIGNATURE_LEN,tmp); - mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,ZT_C25519_PUBLIC_KEY_LEN,tmp); + mj["signature"] = Utils::hex(world.signature().data, ZT_C25519_SIGNATURE_LEN, tmp); + mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data, ZT_C25519_PUBLIC_KEY_LEN, tmp); nlohmann::json ra = nlohmann::json::array(); - for(std::vector::const_iterator r(world.roots().begin());r!=world.roots().end();++r) { + for (std::vector::const_iterator r(world.roots().begin()); r != world.roots().end(); ++r) { nlohmann::json rj; - rj["identity"] = r->identity.toString(false,tmp); + rj["identity"] = r->identity.toString(false, tmp); nlohmann::json eps = nlohmann::json::array(); - for(std::vector::const_iterator a(r->stableEndpoints.begin());a!=r->stableEndpoints.end();++a) + for (std::vector::const_iterator a(r->stableEndpoints.begin()); a != r->stableEndpoints.end(); ++a) eps.push_back(a->toString(tmp)); rj["stableEndpoints"] = eps; ra.push_back(rj); @@ -687,66 +727,48 @@ static void _moonToJson(nlohmann::json &mj,const World &world) class OneServiceImpl; -static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf); -static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData); -static void SnodeStatePutFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len); -static int SnodeStateGetFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen); -static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl); -static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); -static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int64_t localSocket,const struct sockaddr_storage *remoteAddr); -static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result); -static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); +static int SnodeVirtualNetworkConfigFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t nwid, void** nuptr, enum ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig* nwconf); +static void SnodeEventCallback(ZT_Node* node, void* uptr, void* tptr, enum ZT_Event event, const void* metaData); +static void SnodeStatePutFunction(ZT_Node* node, void* uptr, void* tptr, enum ZT_StateObjectType type, const uint64_t id[2], const void* data, int len); +static int SnodeStateGetFunction(ZT_Node* node, void* uptr, void* tptr, enum ZT_StateObjectType type, const uint64_t id[2], void* data, unsigned int maxlen); +static int SnodeWirePacketSendFunction(ZT_Node* node, void* uptr, void* tptr, int64_t localSocket, const struct sockaddr_storage* addr, const void* data, unsigned int len, unsigned int ttl); +static void SnodeVirtualNetworkFrameFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t nwid, void** nuptr, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len); +static int SnodePathCheckFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t ztaddr, int64_t localSocket, const struct sockaddr_storage* remoteAddr); +static int SnodePathLookupFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t ztaddr, int family, struct sockaddr_storage* result); +static void StapFrameHandler(void* uptr, void* tptr, uint64_t nwid, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len); -static int ShttpOnMessageBegin(http_parser *parser); -static int ShttpOnUrl(http_parser *parser,const char *ptr,size_t length); +static int ShttpOnMessageBegin(http_parser* parser); +static int ShttpOnUrl(http_parser* parser, const char* ptr, size_t length); #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2) -static int ShttpOnStatus(http_parser *parser,const char *ptr,size_t length); +static int ShttpOnStatus(http_parser* parser, const char* ptr, size_t length); #else -static int ShttpOnStatus(http_parser *parser); +static int ShttpOnStatus(http_parser* parser); #endif -static int ShttpOnHeaderField(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnValue(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnHeadersComplete(http_parser *parser); -static int ShttpOnBody(http_parser *parser,const char *ptr,size_t length); -static int ShttpOnMessageComplete(http_parser *parser); +static int ShttpOnHeaderField(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnValue(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnHeadersComplete(http_parser* parser); +static int ShttpOnBody(http_parser* parser, const char* ptr, size_t length); +static int ShttpOnMessageComplete(http_parser* parser); #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 1) -static const struct http_parser_settings HTTP_PARSER_SETTINGS = { - ShttpOnMessageBegin, - ShttpOnUrl, - ShttpOnStatus, - ShttpOnHeaderField, - ShttpOnValue, - ShttpOnHeadersComplete, - ShttpOnBody, - ShttpOnMessageComplete -}; +static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnStatus, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete }; #else -static const struct http_parser_settings HTTP_PARSER_SETTINGS = { - ShttpOnMessageBegin, - ShttpOnUrl, - ShttpOnHeaderField, - ShttpOnValue, - ShttpOnHeadersComplete, - ShttpOnBody, - ShttpOnMessageComplete -}; +static const struct http_parser_settings HTTP_PARSER_SETTINGS = { ShttpOnMessageBegin, ShttpOnUrl, ShttpOnHeaderField, ShttpOnValue, ShttpOnHeadersComplete, ShttpOnBody, ShttpOnMessageComplete }; #endif /** * A TCP connection and related state and buffers */ -struct TcpConnection -{ +struct TcpConnection { enum { - TCP_UNCATEGORIZED_INCOMING, // uncategorized incoming connection + TCP_UNCATEGORIZED_INCOMING, // uncategorized incoming connection TCP_HTTP_INCOMING, TCP_HTTP_OUTGOING, - TCP_TUNNEL_OUTGOING // TUNNELED mode proxy outbound connection + TCP_TUNNEL_OUTGOING // TUNNELED mode proxy outbound connection } type; - OneServiceImpl *parent; - PhySocket *sock; + OneServiceImpl* parent; + PhySocket* sock; InetAddress remoteAddr; uint64_t lastReceive; @@ -757,15 +779,14 @@ struct TcpConnection std::string currentHeaderValue; std::string url; std::string status; - std::map< std::string,std::string > headers; + std::map headers; std::string readq; std::string writeq; Mutex writeq_m; }; -struct PacketRecord -{ +struct PacketRecord { uint64_t now; int64_t sock; struct sockaddr_storage from; @@ -773,9 +794,8 @@ struct PacketRecord uint8_t data[ZT_MAX_MTU]; }; -class OneServiceImpl : public OneService -{ -public: +class OneServiceImpl : public OneService { + public: // begin member variables -------------------------------------------------- const std::string _homePath; @@ -785,10 +805,10 @@ public: const std::string _networksPath; const std::string _moonsPath; - EmbeddedNetworkController *_controller; - Phy _phy; - Node *_node; - SoftwareUpdater *_updater; + EmbeddedNetworkController* _controller; + Phy _phy; + Node* _node; + SoftwareUpdater* _updater; bool _updateAutoApply; httplib::Server _controlPlane; @@ -798,10 +818,10 @@ public: bool _serverThreadRunning; bool _serverThreadRunningV6; - BlockingQueue _rxPacketQueue; - std::vector _rxPacketVector; + BlockingQueue _rxPacketQueue; + std::vector _rxPacketVector; std::vector _rxPacketThreads; - Mutex _rxPacketVector_m,_rxPacketThreads_m; + Mutex _rxPacketVector_m, _rxPacketThreads_m; bool _multicoreEnabled; bool _cpuPinningEnabled; unsigned int _concurrency; @@ -818,14 +838,14 @@ public: // Local configuration and memo-ized information from it json _localConfig; - Hashtable< uint64_t,std::vector > _v4Hints; - Hashtable< uint64_t,std::vector > _v6Hints; - Hashtable< uint64_t,std::vector > _v4Blacklists; - Hashtable< uint64_t,std::vector > _v6Blacklists; - std::vector< InetAddress > _globalV4Blacklist; - std::vector< InetAddress > _globalV6Blacklist; - std::vector< InetAddress > _allowManagementFrom; - std::vector< std::string > _interfacePrefixBlacklist; + Hashtable > _v4Hints; + Hashtable > _v6Hints; + Hashtable > _v4Blacklists; + Hashtable > _v6Blacklists; + std::vector _globalV4Blacklist; + std::vector _globalV6Blacklist; + std::vector _allowManagementFrom; + std::vector _interfacePrefixBlacklist; Mutex _localConfig_m; std::vector explicitBind; @@ -857,13 +877,13 @@ public: // Deadline for the next background task service function volatile int64_t _nextBackgroundTaskDeadline; - std::map _nets; + std::map _nets; Mutex _nets_m; // Active TCP/IP connections - std::vector< TcpConnection * > _tcpConnections; + std::vector _tcpConnections; Mutex _tcpConnections_m; - TcpConnection *_tcpFallbackTunnel; + TcpConnection* _tcpFallbackTunnel; // Termination status information ReasonForTermination _termReason; @@ -871,9 +891,9 @@ public: Mutex _termReason_m; // uPnP/NAT-PMP port mapper if enabled - bool _portMappingEnabled; // local.conf settings + bool _portMappingEnabled; // local.conf settings #ifdef ZT_USE_MINIUPNPC - PortMapper *_portMapper; + PortMapper* _portMapper; #endif // HashiCorp Vault Settings @@ -881,59 +901,59 @@ public: bool _vaultEnabled; std::string _vaultURL; std::string _vaultToken; - std::string _vaultPath; // defaults to cubbyhole/zerotier/identity.secret for per-access key storage + std::string _vaultPath; // defaults to cubbyhole/zerotier/identity.secret for per-access key storage #endif // Set to false to force service to stop volatile bool _run; Mutex _run_m; - RedisConfig *_rc; + RedisConfig* _rc; std::string _ssoRedirectURL; // end member variables ---------------------------------------------------- - OneServiceImpl(const char *hp,unsigned int port) : - _homePath((hp) ? hp : ".") - ,_controllerDbPath(_homePath + ZT_PATH_SEPARATOR_S "controller.d") - ,_networksPath(_homePath + ZT_PATH_SEPARATOR_S "networks.d") - ,_moonsPath(_homePath + ZT_PATH_SEPARATOR_S "moons.d") - ,_controller((EmbeddedNetworkController *)0) - ,_phy(this,false,true) - ,_node((Node *)0) - ,_updater((SoftwareUpdater *)0) - ,_updateAutoApply(false) - ,_controlPlane() - ,_controlPlaneV6() - ,_serverThread() - ,_serverThreadV6() - ,_serverThreadRunning(false) - ,_serverThreadRunningV6(false) - ,_forceTcpRelay(false) - ,_primaryPort(port) - ,_udpPortPickerCounter(0) - ,_lastDirectReceiveFromGlobal(0) + OneServiceImpl(const char* hp, unsigned int port) + : _homePath((hp) ? hp : ".") + , _controllerDbPath(_homePath + ZT_PATH_SEPARATOR_S "controller.d") + , _networksPath(_homePath + ZT_PATH_SEPARATOR_S "networks.d") + , _moonsPath(_homePath + ZT_PATH_SEPARATOR_S "moons.d") + , _controller((EmbeddedNetworkController*)0) + , _phy(this, false, true) + , _node((Node*)0) + , _updater((SoftwareUpdater*)0) + , _updateAutoApply(false) + , _controlPlane() + , _controlPlaneV6() + , _serverThread() + , _serverThreadV6() + , _serverThreadRunning(false) + , _serverThreadRunningV6(false) + , _forceTcpRelay(false) + , _primaryPort(port) + , _udpPortPickerCounter(0) + , _lastDirectReceiveFromGlobal(0) #ifdef ZT_TCP_FALLBACK_RELAY , _fallbackRelayAddress(ZT_TCP_FALLBACK_RELAY) - ,_lastSendToGlobalV4(0) + , _lastSendToGlobalV4(0) #endif - ,_lastRestart(0) - ,_nextBackgroundTaskDeadline(0) - ,_tcpFallbackTunnel((TcpConnection *)0) - ,_termReason(ONE_STILL_RUNNING) - ,_portMappingEnabled(true) + , _lastRestart(0) + , _nextBackgroundTaskDeadline(0) + , _tcpFallbackTunnel((TcpConnection*)0) + , _termReason(ONE_STILL_RUNNING) + , _portMappingEnabled(true) #ifdef ZT_USE_MINIUPNPC - ,_portMapper((PortMapper *)0) + , _portMapper((PortMapper*)0) #endif #ifdef ZT_VAULT_SUPPORT - ,_vaultEnabled(false) - ,_vaultURL() - ,_vaultToken() - ,_vaultPath("cubbyhole/zerotier") + , _vaultEnabled(false) + , _vaultURL() + , _vaultToken() + , _vaultPath("cubbyhole/zerotier") #endif - ,_run(true) - ,_rc(NULL) - ,_ssoRedirectURL() + , _run(true) + , _rc(NULL) + , _ssoRedirectURL() { _ports[0] = 0; _ports[1] = 0; @@ -956,7 +976,7 @@ public: _rxPacketQueue.stop(); _rxPacketThreads_m.lock(); - for(auto t=_rxPacketThreads.begin();t!=_rxPacketThreads.end();++t) { + for (auto t = _rxPacketThreads.begin(); t != _rxPacketThreads.end(); ++t) { t->join(); } _rxPacketThreads_m.unlock(); @@ -975,13 +995,12 @@ public: _serverThreadV6.join(); } _rxPacketVector_m.lock(); - while (!_rxPacketVector.empty()) { + while (! _rxPacketVector.empty()) { delete _rxPacketVector.back(); _rxPacketVector.pop_back(); } _rxPacketVector_m.unlock(); - #ifdef ZT_USE_MINIUPNPC delete _portMapper; #endif @@ -1003,19 +1022,20 @@ public: try { { const std::string authTokenPath(_homePath + ZT_PATH_SEPARATOR_S "authtoken.secret"); - if (!OSUtils::readFile(authTokenPath.c_str(),_authToken)) { + if (! OSUtils::readFile(authTokenPath.c_str(), _authToken)) { unsigned char foo[24]; - Utils::getSecureRandom(foo,sizeof(foo)); + Utils::getSecureRandom(foo, sizeof(foo)); _authToken = ""; - for(unsigned int i=0;iaddress(),_ports[2]); - _portMapper = new PortMapper(_ports[2],uniqueName); + OSUtils::ztsnprintf(uniqueName, sizeof(uniqueName), "ZeroTier/%.10llx@%u", _node->address(), _ports[2]); + _portMapper = new PortMapper(_ports[2], uniqueName); } } #endif @@ -1129,31 +1153,31 @@ public: OSUtils::rmDashRf((_homePath + ZT_PATH_SEPARATOR_S "iddb.d").c_str()); // Network controller is now enabled by default for desktop and server - _controller = new EmbeddedNetworkController(_node,_homePath.c_str(),_controllerDbPath.c_str(),_ports[0], _rc); - if (!_ssoRedirectURL.empty()) { + _controller = new EmbeddedNetworkController(_node, _homePath.c_str(), _controllerDbPath.c_str(), _ports[0], _rc); + if (! _ssoRedirectURL.empty()) { _controller->setSSORedirectURL(_ssoRedirectURL); } - _node->setNetconfMaster((void *)_controller); + _node->setNetconfMaster((void*)_controller); startHTTPControlPlane(); // Join existing networks in networks.d { std::vector networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S "networks.d").c_str())); - for(std::vector::iterator f(networksDotD.begin());f!=networksDotD.end();++f) { + for (std::vector::iterator f(networksDotD.begin()); f != networksDotD.end(); ++f) { std::size_t dot = f->find_last_of('.'); - if ((dot == 16)&&(f->substr(16) == ".conf")) - _node->join(Utils::hexStrToU64(f->substr(0,dot).c_str()),(void *)0,(void *)0); + if ((dot == 16) && (f->substr(16) == ".conf")) + _node->join(Utils::hexStrToU64(f->substr(0, dot).c_str()), (void*)0, (void*)0); } } // Orbit existing moons in moons.d { std::vector moonsDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S "moons.d").c_str())); - for(std::vector::iterator f(moonsDotD.begin());f!=moonsDotD.end();++f) { + for (std::vector::iterator f(moonsDotD.begin()); f != moonsDotD.end(); ++f) { std::size_t dot = f->find_last_of('.'); - if ((dot == 16)&&(f->substr(16) == ".moon")) - _node->orbit((void *)0,Utils::hexStrToU64(f->substr(0,dot).c_str()),0); + if ((dot == 16) && (f->substr(16) == ".moon")) + _node->orbit((void*)0, Utils::hexStrToU64(f->substr(0, dot).c_str()), 0); } } @@ -1167,15 +1191,16 @@ public: int64_t lastCleanedPeersDb = 0; int64_t lastLocalConfFileCheck = OSUtils::now(); int64_t lastOnline = lastLocalConfFileCheck; - for(;;) { + for (;;) { _run_m.lock(); - if (!_run) { + if (! _run) { _run_m.unlock(); _termReason_m.lock(); _termReason = ONE_NORMAL_TERMINATION; _termReason_m.unlock(); break; - } else { + } + else { _run_m.unlock(); } @@ -1183,13 +1208,13 @@ public: // Attempt to detect sleep/wake events by detecting delay overruns bool restarted = false; - if ((now > clockShouldBe)&&((now - clockShouldBe) > 10000)) { + if ((now > clockShouldBe) && ((now - clockShouldBe) > 10000)) { _lastRestart = now; restarted = true; } // Check for updates (if enabled) - if ((_updater)&&((now - lastUpdateCheck) > 10000)) { + if ((_updater) && ((now - lastUpdateCheck) > 10000)) { lastUpdateCheck = now; if (_updater->check(now) && _updateAutoApply) _updater->apply(); @@ -1199,7 +1224,7 @@ public: if ((now - lastLocalConfFileCheck) >= ZT_LOCAL_CONF_FILE_CHECK_INTERVAL) { lastLocalConfFileCheck = now; struct stat result; - if(stat((_homePath + ZT_PATH_SEPARATOR_S "local.conf").c_str(), &result)==0) { + if (stat((_homePath + ZT_PATH_SEPARATOR_S "local.conf").c_str(), &result) == 0) { int64_t mod_time = result.st_mtime * 1000; if ((now - mod_time) <= ZT_LOCAL_CONF_FILE_CHECK_INTERVAL) { readLocalSettings(); @@ -1209,7 +1234,7 @@ public: } // Refresh bindings in case device's interfaces have changed, and also sync routes to update any shadow routes (e.g. shadow default) - if (((now - lastBindRefresh) >= (_node->bondController()->inUse() ? ZT_BINDER_REFRESH_PERIOD / 4 : ZT_BINDER_REFRESH_PERIOD))||restarted) { + if (((now - lastBindRefresh) >= (_node->bondController()->inUse() ? ZT_BINDER_REFRESH_PERIOD / 4 : ZT_BINDER_REFRESH_PERIOD)) || restarted) { // If secondary port is not configured to a constant value and we've been offline for a while, // bind a new secondary port. This is a workaround for a "coma" issue caused by buggy NATs that stop // working on one port after a while. @@ -1221,7 +1246,7 @@ public: lastOnline = now; // don't keep changing the port before we have a chance to connect _ports[1] = _getRandomPort(); -#if ZT_DEBUG==1 +#if ZT_DEBUG == 1 fprintf(stderr, "Randomized secondary port. Now it's %d\n", _ports[1]); #endif } @@ -1229,13 +1254,13 @@ public: unsigned int p[3]; unsigned int pc = 0; - for(int i=0;i<3;++i) { + for (int i = 0; i < 3; ++i) { if (_ports[i]) p[pc++] = _ports[i]; } - if (!_forceTcpRelay) { + if (! _forceTcpRelay) { // Only bother binding UDP ports if we aren't forcing TCP-relay mode - _binder.refresh(_phy,p,pc,explicitBind,*this); + _binder.refresh(_phy, p, pc, explicitBind, *this); } lastBindRefresh = now; @@ -1245,20 +1270,20 @@ public: #ifdef ZT_USE_MINIUPNPC if (_portMapper) { std::vector mappedAddresses(_portMapper->get()); - for(std::vector::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); + for (std::vector::const_iterator ext(mappedAddresses.begin()); ext != mappedAddresses.end(); ++ext) + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); } #endif std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); - for(std::vector::const_iterator i(boundAddrs.begin());i!=boundAddrs.end();++i) { - _node->addLocalInterfaceAddress(reinterpret_cast(&(*i))); + for (std::vector::const_iterator i(boundAddrs.begin()); i != boundAddrs.end(); ++i) { + _node->addLocalInterfaceAddress(reinterpret_cast(&(*i))); } { Mutex::Lock _l(_nets_m); - for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { + for (std::map::iterator n(_nets.begin()); n != _nets.end(); ++n) { if (n->second.tap()) - syncManagedStuff(n->second,false,true,false); + syncManagedStuff(n->second, false, true, false); } } } @@ -1266,55 +1291,54 @@ public: // Run background task processor in core if it's time to do so int64_t dl = _nextBackgroundTaskDeadline; if (dl <= now) { - _node->processBackgroundTasks((void *)0,now,&_nextBackgroundTaskDeadline); + _node->processBackgroundTasks((void*)0, now, &_nextBackgroundTaskDeadline); dl = _nextBackgroundTaskDeadline; } // Close TCP fallback tunnel if we have direct UDP - if (!_forceTcpRelay && (_tcpFallbackTunnel) && ((now - _lastDirectReceiveFromGlobal) < (ZT_TCP_FALLBACK_AFTER / 2))) { + if (! _forceTcpRelay && (_tcpFallbackTunnel) && ((now - _lastDirectReceiveFromGlobal) < (ZT_TCP_FALLBACK_AFTER / 2))) { _phy.close(_tcpFallbackTunnel->sock); } // Sync multicast group memberships if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { lastTapMulticastGroupCheck = now; - std::vector< std::pair< uint64_t,std::pair< std::vector,std::vector > > > mgChanges; + std::vector, std::vector > > > mgChanges; { Mutex::Lock _l(_nets_m); mgChanges.reserve(_nets.size() + 1); - for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + for (std::map::const_iterator n(_nets.begin()); n != _nets.end(); ++n) { if (n->second.tap()) { - mgChanges.push_back(std::pair< uint64_t,std::pair< std::vector,std::vector > >(n->first,std::pair< std::vector,std::vector >())); - n->second.tap()->scanMulticastGroups(mgChanges.back().second.first,mgChanges.back().second.second); + mgChanges.push_back(std::pair, std::vector > >(n->first, std::pair, std::vector >())); + n->second.tap()->scanMulticastGroups(mgChanges.back().second.first, mgChanges.back().second.second); } } } - for(std::vector< std::pair< uint64_t,std::pair< std::vector,std::vector > > >::iterator c(mgChanges.begin());c!=mgChanges.end();++c) { - for(std::vector::iterator m(c->second.first.begin());m!=c->second.first.end();++m) - _node->multicastSubscribe((void *)0,c->first,m->mac().toInt(),m->adi()); - for(std::vector::iterator m(c->second.second.begin());m!=c->second.second.end();++m) - _node->multicastUnsubscribe(c->first,m->mac().toInt(),m->adi()); + for (std::vector, std::vector > > >::iterator c(mgChanges.begin()); c != mgChanges.end(); ++c) { + for (std::vector::iterator m(c->second.first.begin()); m != c->second.first.end(); ++m) + _node->multicastSubscribe((void*)0, c->first, m->mac().toInt(), m->adi()); + for (std::vector::iterator m(c->second.second.begin()); m != c->second.second.end(); ++m) + _node->multicastUnsubscribe(c->first, m->mac().toInt(), m->adi()); } } // Clean peers.d periodically if ((now - lastCleanedPeersDb) >= 3600000) { lastCleanedPeersDb = now; - OSUtils::cleanDirectory((_homePath + ZT_PATH_SEPARATOR_S "peers.d").c_str(),now - 2592000000LL); // delete older than 30 days + OSUtils::cleanDirectory((_homePath + ZT_PATH_SEPARATOR_S "peers.d").c_str(), now - 2592000000LL); // delete older than 30 days } const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 500; clockShouldBe = now + (int64_t)delay; _phy.poll(delay); - - - } - } catch (std::exception &e) { + } + catch (std::exception& e) { Mutex::Lock _l(_termReason_m); _termReason = ONE_UNRECOVERABLE_ERROR; - _fatalErrorMessage = std::string("unexpected exception in main thread: ")+e.what(); - } catch (int e) { + _fatalErrorMessage = std::string("unexpected exception in main thread: ") + e.what(); + } + catch (int e) { Mutex::Lock _l(_termReason_m); _termReason = ONE_UNRECOVERABLE_ERROR; switch (e) { @@ -1359,7 +1383,8 @@ public: break; } } - } catch ( ... ) { + } + catch (...) { Mutex::Lock _l(_termReason_m); _termReason = ONE_UNRECOVERABLE_ERROR; _fatalErrorMessage = "unexpected exception in main thread: unknown exception"; @@ -1367,9 +1392,11 @@ public: try { Mutex::Lock _l(_tcpConnections_m); - while (!_tcpConnections.empty()) + while (! _tcpConnections.empty()) _phy.close((*_tcpConnections.begin())->sock); - } catch ( ... ) {} + } + catch (...) { + } { Mutex::Lock _l(_nets_m); @@ -1377,9 +1404,9 @@ public: } delete _updater; - _updater = (SoftwareUpdater *)0; + _updater = (SoftwareUpdater*)0; delete _node; - _node = (Node *)0; + _node = (Node*)0; return _termReason; } @@ -1387,29 +1414,32 @@ public: void readLocalSettings() { // Read local configuration - std::map ppc; + std::map ppc; // LEGACY: support old "trustedpaths" flat file - FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S "trustedpaths").c_str(),"r"); + FILE* trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S "trustedpaths").c_str(), "r"); if (trustpaths) { - fprintf(stderr,"WARNING: 'trustedpaths' flat file format is deprecated in favor of path definitions in local.conf" ZT_EOL_S); + fprintf(stderr, "WARNING: 'trustedpaths' flat file format is deprecated in favor of path definitions in local.conf" ZT_EOL_S); char buf[1024]; - while (fgets(buf,sizeof(buf),trustpaths)) { + while (fgets(buf, sizeof(buf), trustpaths)) { int fno = 0; - char *saveptr = (char *)0; + char* saveptr = (char*)0; uint64_t trustedPathId = 0; InetAddress trustedPathNetwork; - for(char *f=Utils::stok(buf,"=\r\n \t",&saveptr);(f);f=Utils::stok((char *)0,"=\r\n \t",&saveptr)) { + for (char* f = Utils::stok(buf, "=\r\n \t", &saveptr); (f); f = Utils::stok((char*)0, "=\r\n \t", &saveptr)) { if (fno == 0) { trustedPathId = Utils::hexStrToU64(f); - } else if (fno == 1) { + } + else if (fno == 1) { trustedPathNetwork = InetAddress(f); - } else break; + } + else + break; ++fno; } - if ( (trustedPathId != 0) && ((trustedPathNetwork.ss_family == AF_INET)||(trustedPathNetwork.ss_family == AF_INET6)) && (trustedPathNetwork.netmaskBits() > 0) ) { + if ((trustedPathId != 0) && ((trustedPathNetwork.ss_family == AF_INET) || (trustedPathNetwork.ss_family == AF_INET6)) && (trustedPathNetwork.netmaskBits() > 0)) { ppc[trustedPathNetwork].trustedPathId = trustedPathId; - ppc[trustedPathNetwork].mtu = 0; // use default + ppc[trustedPathNetwork].mtu = 0; // use default } } fclose(trustpaths); @@ -1418,16 +1448,17 @@ public: // Read local config file Mutex::Lock _l2(_localConfig_m); std::string lcbuf; - if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S "local.conf").c_str(),lcbuf)) { + if (OSUtils::readFile((_homePath + ZT_PATH_SEPARATOR_S "local.conf").c_str(), lcbuf)) { if (lcbuf.length() > 0) { try { _localConfig = OSUtils::jsonParse(lcbuf); - if (!_localConfig.is_object()) { - fprintf(stderr,"ERROR: unable to parse local.conf (root element is not a JSON object)" ZT_EOL_S); + if (! _localConfig.is_object()) { + fprintf(stderr, "ERROR: unable to parse local.conf (root element is not a JSON object)" ZT_EOL_S); exit(1); } - } catch ( ... ) { - fprintf(stderr,"ERROR: unable to parse local.conf (invalid JSON)" ZT_EOL_S); + } + catch (...) { + fprintf(stderr, "ERROR: unable to parse local.conf (invalid JSON)" ZT_EOL_S); exit(1); } } @@ -1437,27 +1468,27 @@ public: json lc(_localConfig); // Get any trusted paths in local.conf (we'll parse the rest of physical[] elsewhere) - json &physical = lc["physical"]; + json& physical = lc["physical"]; if (physical.is_object()) { - for(json::iterator phy(physical.begin());phy!=physical.end();++phy) { - InetAddress net(OSUtils::jsonString(phy.key(),"").c_str()); + for (json::iterator phy(physical.begin()); phy != physical.end(); ++phy) { + InetAddress net(OSUtils::jsonString(phy.key(), "").c_str()); if (net) { if (phy.value().is_object()) { uint64_t tpid; - if ((tpid = OSUtils::jsonInt(phy.value()["trustedPathId"],0ULL)) != 0ULL) { - if ((net.ss_family == AF_INET)||(net.ss_family == AF_INET6)) + if ((tpid = OSUtils::jsonInt(phy.value()["trustedPathId"], 0ULL)) != 0ULL) { + if ((net.ss_family == AF_INET) || (net.ss_family == AF_INET6)) ppc[net].trustedPathId = tpid; } - ppc[net].mtu = (int)OSUtils::jsonInt(phy.value()["mtu"],0ULL); // 0 means use default + ppc[net].mtu = (int)OSUtils::jsonInt(phy.value()["mtu"], 0ULL); // 0 means use default } } } } - json &settings = lc["settings"]; + json& settings = lc["settings"]; if (settings.is_object()) { // Allow controller DB path to be put somewhere else - const std::string cdbp(OSUtils::jsonString(settings["controllerDbPath"],"")); + const std::string cdbp(OSUtils::jsonString(settings["controllerDbPath"], "")); if (cdbp.length() > 0) _controllerDbPath = cdbp; @@ -1465,24 +1496,24 @@ public: #ifdef ZT_CONTROLLER_USE_LIBPQ // TODO: Redis config - json &redis = settings["redis"]; + json& redis = settings["redis"]; if (redis.is_object() && _rc == NULL) { _rc = new RedisConfig; - _rc->hostname = OSUtils::jsonString(redis["hostname"],""); - _rc->port = OSUtils::jsonInt(redis["port"],0); - _rc->password = OSUtils::jsonString(redis["password"],""); + _rc->hostname = OSUtils::jsonString(redis["hostname"], ""); + _rc->port = OSUtils::jsonInt(redis["port"], 0); + _rc->password = OSUtils::jsonString(redis["password"], ""); _rc->clusterMode = OSUtils::jsonBool(redis["clusterMode"], false); } #endif // Bind to wildcard instead of to specific interfaces (disables full tunnel capability) - json &bind = settings["bind"]; + json& bind = settings["bind"]; if (bind.is_array()) { - for(unsigned long i=0;i 0) { InetAddress ip(ips.c_str()); - if ((ip.ss_family == AF_INET)||(ip.ss_family == AF_INET6)) + if ((ip.ss_family == AF_INET) || (ip.ss_family == AF_INET6)) explicitBind.push_back(ip); } } @@ -1490,9 +1521,9 @@ public: } // Set trusted paths if there are any - if (!ppc.empty()) { - for(std::map::iterator i(ppc.begin());i!=ppc.end();++i) - _node->setPhysicalPathConfiguration(reinterpret_cast(&(i->first)),&(i->second)); + if (! ppc.empty()) { + for (std::map::iterator i(ppc.begin()); i != ppc.end(); ++i) + _node->setPhysicalPathConfiguration(reinterpret_cast(&(i->first)), &(i->second)); } } @@ -1511,10 +1542,11 @@ public: virtual std::string portDeviceName(uint64_t nwid) const { Mutex::Lock _l(_nets_m); - std::map::const_iterator n(_nets.find(nwid)); - if ((n != _nets.end())&&(n->second.tap())) + std::map::const_iterator n(_nets.find(nwid)); + if ((n != _nets.end()) && (n->second.tap())) return n->second.tap()->deviceName(); - else return std::string(); + else + return std::string(); } #ifdef ZT_SDK @@ -1523,22 +1555,22 @@ public: return _homePath; } - void getRoutes(uint64_t nwid, void *routeArray, unsigned int *numRoutes) + void getRoutes(uint64_t nwid, void* routeArray, unsigned int* numRoutes) { Mutex::Lock _l(_nets_m); - NetworkState &n = _nets[nwid]; + NetworkState& n = _nets[nwid]; *numRoutes = *numRoutes < n.config().routeCount ? *numRoutes : n.config().routeCount; - for(unsigned int i=0; i<*numRoutes; i++) { - ZT_VirtualNetworkRoute *vnr = (ZT_VirtualNetworkRoute*)routeArray; + for (unsigned int i = 0; i < *numRoutes; i++) { + ZT_VirtualNetworkRoute* vnr = (ZT_VirtualNetworkRoute*)routeArray; memcpy(&vnr[i], &(n.config().routes[i]), sizeof(ZT_VirtualNetworkRoute)); } } - virtual Node *getNode() + virtual Node* getNode() { return _node; } -#endif // ZT_SDK +#endif // ZT_SDK virtual void terminate() { @@ -1549,35 +1581,35 @@ public: _phy.whack(); } - virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const + virtual bool getNetworkSettings(const uint64_t nwid, NetworkSettings& settings) const { Mutex::Lock _l(_nets_m); - std::map::const_iterator n(_nets.find(nwid)); + std::map::const_iterator n(_nets.find(nwid)); if (n == _nets.end()) return false; settings = n->second.settings(); return true; } - virtual bool setNetworkSettings(const uint64_t nwid,const NetworkSettings &settings) + virtual bool setNetworkSettings(const uint64_t nwid, const NetworkSettings& settings) { char nlcpath[4096]; - OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_networksPath.c_str(),nwid); - FILE *out = fopen(nlcpath,"w"); + OSUtils::ztsnprintf(nlcpath, sizeof(nlcpath), "%s" ZT_PATH_SEPARATOR_S "%.16llx.local.conf", _networksPath.c_str(), nwid); + FILE* out = fopen(nlcpath, "w"); if (out) { - fprintf(out,"allowManaged=%d\n",(int)settings.allowManaged); - fprintf(out,"allowGlobal=%d\n",(int)settings.allowGlobal); - fprintf(out,"allowDefault=%d\n",(int)settings.allowDefault); - fprintf(out,"allowDNS=%d\n",(int)settings.allowDNS); + fprintf(out, "allowManaged=%d\n", (int)settings.allowManaged); + fprintf(out, "allowGlobal=%d\n", (int)settings.allowGlobal); + fprintf(out, "allowDefault=%d\n", (int)settings.allowDefault); + fprintf(out, "allowDNS=%d\n", (int)settings.allowDNS); fclose(out); } - return true; } - // Internal HTTP Control Plane - void startHTTPControlPlane() { + // Internal HTTP Control Plane + void startHTTPControlPlane() + { // control plane endpoints std::string bondShowPath = "/bond/show/([0-9a-fA-F]{10})"; std::string bondRotatePath = "/bond/rotate/([0-9a-fA-F]{10})"; @@ -1594,20 +1626,22 @@ public: std::string statusPath = "/status"; std::string metricsPath = "/metrics"; - std::vector noAuthEndpoints { "/sso", "/health" }; + std::vector noAuthEndpoints { "/sso", "/health" }; - - auto setContent = [=] (const httplib::Request &req, httplib::Response &res, std::string content) { + auto setContent = [=](const httplib::Request& req, httplib::Response& res, std::string content) { if (req.has_param("jsonp")) { if (content.length() > 0) { res.set_content(req.get_param_value("jsonp") + "(" + content + ");", "application/javascript"); - } else { + } + else { res.set_content(req.get_param_value("jsonp") + "(null);", "application/javascript"); } - } else { + } + else { if (content.length() > 0) { res.set_content(content, "application/json"); - } else { + } + else { res.set_content("{}", "application/json"); } } @@ -1619,18 +1653,19 @@ public: if (_enableWebServer) { static std::string appUiPath = "/app"; static char appUiDir[16384]; - sprintf(appUiDir,"%s%s",_homePath.c_str(),appUiPath.c_str()); + sprintf(appUiDir, "%s%s", _homePath.c_str(), appUiPath.c_str()); auto ret = _controlPlane.set_mount_point(appUiPath, appUiDir); _controlPlaneV6.set_mount_point(appUiPath, appUiDir); - if (!ret) { + if (! ret) { fprintf(stderr, "Mounting app directory failed. Creating it. Path: %s - Dir: %s\n", appUiPath.c_str(), appUiDir); - if (!OSUtils::mkdir(appUiDir)) { + if (! OSUtils::mkdir(appUiDir)) { fprintf(stderr, "Could not create app directory either. Path: %s - Dir: %s\n", appUiPath.c_str(), appUiDir); - } else { + } + else { ret = _controlPlane.set_mount_point(appUiPath, appUiDir); _controlPlaneV6.set_mount_point(appUiPath, appUiDir); - if (!ret) { + if (! ret) { fprintf(stderr, "Really could not create and mount directory. Path: %s - Dir: %s\nWeb apps won't work.\n", appUiPath.c_str(), appUiDir); } } @@ -1638,43 +1673,44 @@ public: if (ret) { // fallback to /index.html for paths that don't exist for SPAs - auto indexFallbackGet = [](const httplib::Request &req, httplib::Response &res) { + auto indexFallbackGet = [](const httplib::Request& req, httplib::Response& res) { // fprintf(stderr, "fallback \n"); auto match = req.matches[1]; if (match.matched) { - // fallback char indexHtmlPath[16384]; - sprintf(indexHtmlPath,"%s/%s/%s", appUiDir, match.str().c_str(), "index.html"); + sprintf(indexHtmlPath, "%s/%s/%s", appUiDir, match.str().c_str(), "index.html"); // fprintf(stderr, "fallback path %s\n", indexHtmlPath); std::string indexHtml; - if (!OSUtils::readFile(indexHtmlPath, indexHtml)) { + if (! OSUtils::readFile(indexHtmlPath, indexHtml)) { res.status = 500; return; } res.set_content(indexHtml.c_str(), "text/html"); - } else { + } + else { res.status = 500; return; } }; - auto slashRedirect = [](const httplib::Request &req, httplib::Response &res) { + auto slashRedirect = [](const httplib::Request& req, httplib::Response& res) { // fprintf(stderr, "redirect \n"); // add .html std::string htmlFile; char htmlPath[16384]; - sprintf(htmlPath,"%s%s%s", appUiDir, (req.path).substr(appUiPath.length()).c_str(), ".html"); + sprintf(htmlPath, "%s%s%s", appUiDir, (req.path).substr(appUiPath.length()).c_str(), ".html"); // fprintf(stderr, "path: %s\n", htmlPath); if (OSUtils::readFile(htmlPath, htmlFile)) { res.set_content(htmlFile.c_str(), "text/html"); return; - } else { + } + else { res.status = 301; res.set_header("location", req.path + "/"); } @@ -1700,24 +1736,24 @@ public: // fallback to index.html for unknown paths/files _controlPlane.Get(appUiPath + R"((/[\w|-]+)(/[\w|-]+)*/$)", indexFallbackGet); _controlPlaneV6.Get(appUiPath + R"((/[\w|-]+)(/[\w|-]+)*/$)", indexFallbackGet); - } } - auto authCheck = [=] (const httplib::Request &req, httplib::Response &res) { + auto authCheck = [=](const httplib::Request& req, httplib::Response& res) { if (req.path == "/metrics") { - if (req.has_header("x-zt1-auth")) { std::string token = req.get_header_value("x-zt1-auth"); if (token == _metricsToken || token == _authToken) { return httplib::Server::HandlerResponse::Unhandled; } - } else if (req.has_param("auth")) { + } + else if (req.has_param("auth")) { std::string token = req.get_param_value("auth"); if (token == _metricsToken || token == _authToken) { return httplib::Server::HandlerResponse::Unhandled; } - } else if (req.has_header("authorization")) { + } + else if (req.has_header("authorization")) { std::string auth = req.get_header_value("authorization"); if (bearerTokenValid(auth, _metricsToken) || bearerTokenValid(auth, _authToken)) { return httplib::Server::HandlerResponse::Unhandled; @@ -1727,7 +1763,8 @@ public: setContent(req, res, "{}"); res.status = 401; return httplib::Server::HandlerResponse::Handled; - } else { + } + else { std::string r = req.remote_addr; InetAddress remoteAddr(r.c_str()); @@ -1738,16 +1775,15 @@ public: ipAllowed = true; } - if (!ipAllowed) { + if (! ipAllowed) { for (auto i = _allowManagementFrom.begin(); i != _allowManagementFrom.end(); ++i) { if (i->containsAddress(remoteAddr)) { - ipAllowed = true; + ipAllowed = true; break; } } } - if (ipAllowed) { // auto-pass endpoints in `noAuthEndpoints`. No auth token required if (std::find(noAuthEndpoints.begin(), noAuthEndpoints.end(), req.path) != noAuthEndpoints.end()) { @@ -1755,23 +1791,25 @@ public: } // Web Apps base path - if (req.path.rfind("/app", 0) == 0) { //starts with /app + if (req.path.rfind("/app", 0) == 0) { // starts with /app isAuth = true; } - if (!isAuth) { + if (! isAuth) { // check auth token if (req.has_header("x-zt1-auth")) { std::string token = req.get_header_value("x-zt1-auth"); if (token == _authToken) { isAuth = true; } - } else if (req.has_param("auth")) { + } + else if (req.has_param("auth")) { std::string token = req.get_param_value("auth"); if (token == _authToken) { isAuth = true; } - } else if (req.has_header("authorization")) { + } + else if (req.has_header("authorization")) { std::string auth = req.get_header_value("authorization"); isAuth = bearerTokenValid(auth, _authToken); } @@ -1785,48 +1823,48 @@ public: res.status = 401; return httplib::Server::HandlerResponse::Handled; } - }; + }; - - auto bondShow = [&, setContent](const httplib::Request &req, httplib::Response &res) { - if (!_node->bondController()->inUse()) { + auto bondShow = [&, setContent](const httplib::Request& req, httplib::Response& res) { + if (! _node->bondController()->inUse()) { setContent(req, res, ""); res.status = 400; return; } - ZT_PeerList *pl = _node->peers(); + ZT_PeerList* pl = _node->peers(); if (pl) { bool foundBond = false; auto id = req.matches[1]; auto out = json::object(); uint64_t wantp = Utils::hexStrToU64(id.str().c_str()); - for(unsigned long i=0;ipeerCount;++i) { + for (unsigned long i = 0; i < pl->peerCount; ++i) { if (pl->peers[i].address == wantp) { SharedPtr bond = _node->bondController()->getBondByPeerId(wantp); if (bond) { - _peerToJson(out,&(pl->peers[i]),bond,(_tcpFallbackTunnel != (TcpConnection *)0)); + _peerToJson(out, &(pl->peers[i]), bond, (_tcpFallbackTunnel != (TcpConnection*)0)); setContent(req, res, out.dump()); foundBond = true; - } else { + } + else { setContent(req, res, ""); res.status = 400; } break; } } - if (!foundBond) { + if (! foundBond) { setContent(req, res, ""); res.status = 400; } } - _node->freeQueryResult((void *)pl); + _node->freeQueryResult((void*)pl); }; _controlPlane.Get(bondShowPath, bondShow); _controlPlaneV6.Get(bondShowPath, bondShow); - auto bondRotate = [&, setContent](const httplib::Request &req, httplib::Response &res) { - if (!_node->bondController()->inUse()) { + auto bondRotate = [&, setContent](const httplib::Request& req, httplib::Response& res) { + if (! _node->bondController()->inUse()) { setContent(req, res, ""); res.status = 400; return; @@ -1837,10 +1875,12 @@ public: if (bond) { if (bond->abForciblyRotateLink()) { res.status = 200; - } else { + } + else { res.status = 400; } - } else { + } + else { fprintf(stderr, "unable to find bond to peer %llx\n", (unsigned long long)id); res.status = 400; } @@ -1851,8 +1891,8 @@ public: _controlPlaneV6.Post(bondRotatePath, bondRotate); _controlPlaneV6.Put(bondRotatePath, bondRotate); - auto setMtu = [&, setContent](const httplib::Request &req, httplib::Response &res) { - if (!_node->bondController()->inUse()) { + auto setMtu = [&, setContent](const httplib::Request& req, httplib::Response& res) { + if (! _node->bondController()->inUse()) { setContent(req, res, "Bonding layer isn't active yet"); res.status = 400; return; @@ -1875,7 +1915,7 @@ public: _controlPlaneV6.Post(setBondMtuPath, setMtu); _controlPlaneV6.Put(setBondMtuPath, setMtu); - auto getConfig = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto getConfig = [&, setContent](const httplib::Request& req, httplib::Response& res) { std::string config; { Mutex::Lock lc(_localConfig_m); @@ -1889,12 +1929,12 @@ public: _controlPlane.Get(configPath, getConfig); _controlPlaneV6.Get(configPath, getConfig); - auto configPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto configPost = [&, setContent](const httplib::Request& req, httplib::Response& res) { json j(OSUtils::jsonParse(req.body)); if (j.is_object()) { Mutex::Lock lcl(_localConfig_m); json lc(_localConfig); - for(json::const_iterator s(j.begin()); s != j.end(); ++s) { + for (json::const_iterator s(j.begin()); s != j.end(); ++s) { lc["settings"][s.key()] = s.value(); } std::string lcStr = OSUtils::jsonDump(lc, 4); @@ -1909,7 +1949,7 @@ public: _controlPlaneV6.Post(configPostPath, configPost); _controlPlaneV6.Put(configPostPath, configPost); - auto healthGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto healthGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { json out = json::object(); char tmp[256]; @@ -1922,7 +1962,7 @@ public: out["versionMinor"] = ZEROTIER_ONE_VERSION_MINOR; out["versionRev"] = ZEROTIER_ONE_VERSION_REVISION; out["versionBuild"] = ZEROTIER_ONE_VERSION_BUILD; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%d.%d.%d", ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION); out["version"] = tmp; out["clock"] = OSUtils::now(); @@ -1931,7 +1971,7 @@ public: _controlPlane.Get(healthPath, healthGet); _controlPlaneV6.Get(healthPath, healthGet); - auto moonListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto moonListGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { std::vector moons(_node->moons()); auto out = json::array(); @@ -1945,7 +1985,7 @@ public: _controlPlane.Get(moonListPath, moonListGet); _controlPlaneV6.Get(moonListPath, moonListGet); - auto moonGet = [&, setContent](const httplib::Request &req, httplib::Response &res){ + auto moonGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { std::vector moons(_node->moons()); auto input = req.matches[1]; auto out = json::object(); @@ -1961,15 +2001,16 @@ public: _controlPlane.Get(moonPath, moonGet); _controlPlaneV6.Get(moonPath, moonGet); - auto moonPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto moonPost = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto input = req.matches[1]; uint64_t seed = 0; try { json j(OSUtils::jsonParse(req.body)); if (j.is_object()) { - seed = Utils::hexStrToU64(OSUtils::jsonString(j["seed"],"0").c_str()); + seed = Utils::hexStrToU64(OSUtils::jsonString(j["seed"], "0").c_str()); } - } catch ( ... ) { + } + catch (...) { // discard invalid JSON } @@ -1977,24 +2018,24 @@ public: const uint64_t id = Utils::hexStrToU64(input.str().c_str()); bool found = false; auto out = json::object(); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { + for (std::vector::const_iterator m(moons.begin()); m != moons.end(); ++m) { if (m->id() == id) { - _moonToJson(out,*m); + _moonToJson(out, *m); found = true; break; } } - if (!found && seed != 0) { + if (! found && seed != 0) { char tmp[64]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",id); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", id); out["id"] = tmp; out["roots"] = json::array(); out["timestamp"] = 0; out["signature"] = json(); out["updatesMustBeSignedBy"] = json(); out["waiting"] = true; - _node->orbit((void *)0,id,seed); + _node->orbit((void*)0, id, seed); } setContent(req, res, out.dump()); }; @@ -2003,50 +2044,50 @@ public: _controlPlaneV6.Post(moonPath, moonPost); _controlPlaneV6.Put(moonPath, moonPost); - auto moonDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto moonDelete = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto input = req.matches[1]; uint64_t id = Utils::hexStrToU64(input.str().c_str()); auto out = json::object(); - _node->deorbit((void*)0,id); + _node->deorbit((void*)0, id); out["result"] = true; setContent(req, res, out.dump()); }; _controlPlane.Delete(moonPath, moonDelete); - auto networkListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { - Mutex::Lock _l(_nets_m); - auto out = json::array(); + auto networkListGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { + Mutex::Lock _l(_nets_m); + auto out = json::array(); - for (auto it = _nets.begin(); it != _nets.end(); ++it) { - NetworkState &ns = it->second; - json nj; - _networkToJson(nj, ns); - out.push_back(nj); - } + for (auto it = _nets.begin(); it != _nets.end(); ++it) { + NetworkState& ns = it->second; + json nj; + _networkToJson(nj, ns); + out.push_back(nj); + } setContent(req, res, out.dump()); - }; + }; _controlPlane.Get(networkListPath, networkListGet); _controlPlaneV6.Get(networkListPath, networkListGet); - auto networkGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { Mutex::Lock _l(_nets_m); - auto input = req.matches[1]; + auto input = req.matches[1]; const uint64_t nwid = Utils::hexStrToU64(input.str().c_str()); if (_nets.find(nwid) != _nets.end()) { auto out = json::object(); - NetworkState &ns = _nets[nwid]; + NetworkState& ns = _nets[nwid]; _networkToJson(out, ns); setContent(req, res, out.dump()); return; } setContent(req, res, ""); res.status = 404; - }; - _controlPlane.Get(networkPath, networkGet); + }; + _controlPlane.Get(networkPath, networkGet); _controlPlaneV6.Get(networkPath, networkGet); - auto networkPost = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkPost = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto input = req.matches[1]; uint64_t wantnw = Utils::hexStrToU64(input.str().c_str()); _node->join(wantnw, (void*)0, (void*)0); @@ -2054,12 +2095,12 @@ public: Mutex::Lock l(_nets_m); bool allowDefault = false; - if (!_nets.empty()) { - NetworkState &ns = _nets[wantnw]; + if (! _nets.empty()) { + NetworkState& ns = _nets[wantnw]; try { json j(OSUtils::jsonParse(req.body)); - json &allowManaged = j["allowManaged"]; + json& allowManaged = j["allowManaged"]; if (allowManaged.is_boolean()) { ns.setAllowManaged((bool)allowManaged); } @@ -2076,23 +2117,24 @@ public: if (allowDNS.is_boolean()) { ns.setAllowDNS((bool)allowDNS); } - } catch (...) { + } + catch (...) { // discard invalid JSON } setNetworkSettings(wantnw, ns.settings()); if (ns.tap()) { - syncManagedStuff(ns,true,true,true); + syncManagedStuff(ns, true, true, true); } _networkToJson(out, ns); } #ifdef __FreeBSD__ - if(!!allowDefault){ + if (! ! allowDefault) { res.status = 400; setContent(req, res, "Allow Default does not work properly on FreeBSD. See #580"); - } else { + } + else { setContent(req, res, out.dump()); - } #else setContent(req, res, out.dump()); @@ -2103,12 +2145,12 @@ public: _controlPlaneV6.Post(networkPath, networkPost); _controlPlaneV6.Put(networkPath, networkPost); - auto networkDelete = [&, setContent](const httplib::Request &req, httplib::Response &res) { + auto networkDelete = [&, setContent](const httplib::Request& req, httplib::Response& res) { auto input = req.matches[1]; auto out = json::object(); - ZT_VirtualNetworkList *nws = _node->networks(); + ZT_VirtualNetworkList* nws = _node->networks(); uint64_t wantnw = Utils::hexStrToU64(input.str().c_str()); - for(unsigned long i=0; i < nws->networkCount; ++i) { + for (unsigned long i = 0; i < nws->networkCount; ++i) { if (nws->networks[i].nwid == wantnw) { _node->leave(wantnw, (void**)0, (void*)0); out["result"] = true; @@ -2120,18 +2162,18 @@ public: _controlPlane.Delete(networkPath, networkDelete); _controlPlaneV6.Delete(networkPath, networkDelete); - auto peerListGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { - ZT_PeerList *pl = _node->peers(); + auto peerListGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { + ZT_PeerList* pl = _node->peers(); auto out = nlohmann::json::array(); - for(unsigned long i=0;ipeerCount;++i) { + for (unsigned long i = 0; i < pl->peerCount; ++i) { nlohmann::json pj; SharedPtr bond = SharedPtr(); if (pl->peers[i].isBonded) { const uint64_t id = pl->peers[i].address; bond = _node->bondController()->getBondByPeerId(id); } - _peerToJson(pj,&(pl->peers[i]),bond,(_tcpFallbackTunnel != (TcpConnection *)0)); + _peerToJson(pj, &(pl->peers[i]), bond, (_tcpFallbackTunnel != (TcpConnection*)0)); out.push_back(pj); } _node->freeQueryResult((void*)pl); @@ -2140,19 +2182,19 @@ public: _controlPlane.Get(peerListPath, peerListGet); _controlPlaneV6.Get(peerListPath, peerListGet); - auto peerGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { - ZT_PeerList *pl = _node->peers(); + auto peerGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { + ZT_PeerList* pl = _node->peers(); auto input = req.matches[1]; uint64_t wantp = Utils::hexStrToU64(input.str().c_str()); auto out = json::object(); - for(unsigned long i=0;ipeerCount;++i) { + for (unsigned long i = 0; i < pl->peerCount; ++i) { if (pl->peers[i].address == wantp) { SharedPtr bond = SharedPtr(); if (pl->peers[i].isBonded) { bond = _node->bondController()->getBondByPeerId(wantp); } - _peerToJson(out,&(pl->peers[i]),bond,(_tcpFallbackTunnel != (TcpConnection *)0)); + _peerToJson(out, &(pl->peers[i]), bond, (_tcpFallbackTunnel != (TcpConnection*)0)); break; } } @@ -2162,167 +2204,171 @@ public: _controlPlane.Get(peerPath, peerGet); _controlPlaneV6.Get(peerPath, peerGet); - auto statusGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { - ZT_NodeStatus status; - _node->status(&status); + auto statusGet = [&, setContent](const httplib::Request& req, httplib::Response& res) { + ZT_NodeStatus status; + _node->status(&status); - auto out = json::object(); - char tmp[256] = {}; + auto out = json::object(); + char tmp[256] = {}; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",status.address); - out["address"] = tmp; - out["publicIdentity"] = status.publicIdentity; - out["online"] = (bool)(status.online != 0); - out["tcpFallbackActive"] = (_tcpFallbackTunnel != (TcpConnection *)0); - out["versionMajor"] = ZEROTIER_ONE_VERSION_MAJOR; - out["versionMinor"] = ZEROTIER_ONE_VERSION_MINOR; - out["versionRev"] = ZEROTIER_ONE_VERSION_REVISION; - out["versionBuild"] = ZEROTIER_ONE_VERSION_BUILD; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION); - out["version"] = tmp; - out["clock"] = OSUtils::now(); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.10llx", status.address); + out["address"] = tmp; + out["publicIdentity"] = status.publicIdentity; + out["online"] = (bool)(status.online != 0); + out["tcpFallbackActive"] = (_tcpFallbackTunnel != (TcpConnection*)0); + out["versionMajor"] = ZEROTIER_ONE_VERSION_MAJOR; + out["versionMinor"] = ZEROTIER_ONE_VERSION_MINOR; + out["versionRev"] = ZEROTIER_ONE_VERSION_REVISION; + out["versionBuild"] = ZEROTIER_ONE_VERSION_BUILD; + OSUtils::ztsnprintf(tmp, sizeof(tmp), "%d.%d.%d", ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION); + out["version"] = tmp; + out["clock"] = OSUtils::now(); - { - Mutex::Lock _l(_localConfig_m); - out["config"] = _localConfig; - } - json &settings = out["config"]["settings"]; - settings["allowTcpFallbackRelay"] = OSUtils::jsonBool(settings["allowTcpFallbackRelay"],_allowTcpFallbackRelay); - settings["forceTcpRelay"] = OSUtils::jsonBool(settings["forceTcpRelay"],_forceTcpRelay); - settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff; - settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"],(uint64_t)_ports[1]) & 0xffff; - settings["tertiaryPort"] = OSUtils::jsonInt(settings["tertiaryPort"],(uint64_t)_tertiaryPort) & 0xffff; - settings["homeDir"] = _homePath; - // Enumerate all local address/port pairs that this node is listening on - std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); - auto boundAddrArray = json::array(); - for (int i = 0; i < boundAddrs.size(); i++) { - char ipBuf[64] = { 0 }; - boundAddrs[i].toString(ipBuf); - boundAddrArray.push_back(ipBuf); - } - settings["listeningOn"] = boundAddrArray; - // Enumerate all external address/port pairs that are reported for this node - std::vector surfaceAddrs = _node->SurfaceAddresses(); - auto surfaceAddrArray = json::array(); - for (int i = 0; i < surfaceAddrs.size(); i++) { - char ipBuf[64] = { 0 }; - surfaceAddrs[i].toString(ipBuf); - surfaceAddrArray.push_back(ipBuf); - } - settings["surfaceAddresses"] = surfaceAddrArray; + { + Mutex::Lock _l(_localConfig_m); + out["config"] = _localConfig; + } + json& settings = out["config"]["settings"]; + settings["allowTcpFallbackRelay"] = OSUtils::jsonBool(settings["allowTcpFallbackRelay"], _allowTcpFallbackRelay); + settings["forceTcpRelay"] = OSUtils::jsonBool(settings["forceTcpRelay"], _forceTcpRelay); + settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"], (uint64_t)_primaryPort) & 0xffff; + settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"], (uint64_t)_ports[1]) & 0xffff; + settings["tertiaryPort"] = OSUtils::jsonInt(settings["tertiaryPort"], (uint64_t)_tertiaryPort) & 0xffff; + settings["homeDir"] = _homePath; + // Enumerate all local address/port pairs that this node is listening on + std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); + auto boundAddrArray = json::array(); + for (int i = 0; i < boundAddrs.size(); i++) { + char ipBuf[64] = { 0 }; + boundAddrs[i].toString(ipBuf); + boundAddrArray.push_back(ipBuf); + } + settings["listeningOn"] = boundAddrArray; + // Enumerate all external address/port pairs that are reported for this node + std::vector surfaceAddrs = _node->SurfaceAddresses(); + auto surfaceAddrArray = json::array(); + for (int i = 0; i < surfaceAddrs.size(); i++) { + char ipBuf[64] = { 0 }; + surfaceAddrs[i].toString(ipBuf); + surfaceAddrArray.push_back(ipBuf); + } + settings["surfaceAddresses"] = surfaceAddrArray; #ifdef ZT_USE_MINIUPNPC - settings["portMappingEnabled"] = OSUtils::jsonBool(settings["portMappingEnabled"],true); + settings["portMappingEnabled"] = OSUtils::jsonBool(settings["portMappingEnabled"], true); #else - settings["portMappingEnabled"] = false; // not supported in build + settings["portMappingEnabled"] = false; // not supported in build #endif #ifndef ZT_SDK - settings["softwareUpdate"] = OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT); - settings["softwareUpdateChannel"] = OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL); + settings["softwareUpdate"] = OSUtils::jsonString(settings["softwareUpdate"], ZT_SOFTWARE_UPDATE_DEFAULT); + settings["softwareUpdateChannel"] = OSUtils::jsonString(settings["softwareUpdateChannel"], ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL); #endif - const World planet(_node->planet()); - out["planetWorldId"] = planet.id(); - out["planetWorldTimestamp"] = planet.timestamp(); + const World planet(_node->planet()); + out["planetWorldId"] = planet.id(); + out["planetWorldTimestamp"] = planet.timestamp(); setContent(req, res, out.dump()); - }; + }; _controlPlane.Get(statusPath, statusGet); _controlPlaneV6.Get(statusPath, statusGet); #if ZT_SSO_ENABLED std::string ssoPath = "/sso"; - auto ssoGet = [this](const httplib::Request &req, httplib::Response &res) { - std::string htmlTemplatePath = _homePath + ZT_PATH_SEPARATOR + "sso-auth.template.html"; - std::string htmlTemplate; - if (!OSUtils::readFile(htmlTemplatePath.c_str(), htmlTemplate)) { - htmlTemplate = ssoResponseTemplate; - } + auto ssoGet = [this](const httplib::Request& req, httplib::Response& res) { + std::string htmlTemplatePath = _homePath + ZT_PATH_SEPARATOR + "sso-auth.template.html"; + std::string htmlTemplate; + if (! OSUtils::readFile(htmlTemplatePath.c_str(), htmlTemplate)) { + htmlTemplate = ssoResponseTemplate; + } - std::string responseContentType = "text/html"; - std::string responseBody = ""; - json outData; + std::string responseContentType = "text/html"; + std::string responseBody = ""; + json outData; + if (req.has_param("error")) { + std::string error = req.get_param_value("error"); + std::string desc = req.get_param_value("error_description"); - if (req.has_param("error")) { - std::string error = req.get_param_value("error"); - std::string desc = req.get_param_value("error_description"); + json data; + outData["isError"] = true; + outData["messageText"] = (std::string("ERROR ") + error + std::string(": ") + desc); + responseBody = inja::render(htmlTemplate, outData); - json data; - outData["isError"] = true; - outData["messageText"] = (std::string("ERROR ") + error + std::string(": ") + desc); - responseBody = inja::render(htmlTemplate, outData); + res.set_content(responseBody, responseContentType); + res.status = 500; + return; + } - res.set_content(responseBody, responseContentType); - res.status = 500; - return; - } + // SSO redirect handling + std::string state = req.get_param_value("state"); + char* nwid = zeroidc::zeroidc_network_id_from_state(state.c_str()); - // SSO redirect handling - std::string state = req.get_param_value("state"); - char* nwid = zeroidc::zeroidc_network_id_from_state(state.c_str()); + outData["networkId"] = std::string(nwid); - outData["networkId"] = std::string(nwid); + const uint64_t id = Utils::hexStrToU64(nwid); - const uint64_t id = Utils::hexStrToU64(nwid); + zeroidc::free_cstr(nwid); - zeroidc::free_cstr(nwid); + Mutex::Lock l(_nets_m); + if (_nets.find(id) != _nets.end()) { + NetworkState& ns = _nets[id]; + std::string code = req.get_param_value("code"); + char* ret = ns.doTokenExchange(code.c_str()); + json ssoResult = json::parse(ret); + if (ssoResult.is_object()) { + if (ssoResult.contains("errorMessage")) { + outData["isError"] = true; + outData["messageText"] = ssoResult["errorMessage"]; + responseBody = inja::render(htmlTemplate, outData); + res.set_content(responseBody, responseContentType); + res.status = 500; + } + else { + outData["isError"] = false; + outData["messageText"] = "Authentication Successful. You may now access the network."; + responseBody = inja::render(htmlTemplate, outData); + res.set_content(responseBody, responseContentType); + } + } + else { + // not an object? We got a problem + outData["isError"] = true; + outData["messageText"] = "ERROR: Unkown SSO response. Please contact your administrator."; + responseBody = inja::render(htmlTemplate, outData); + res.set_content(responseBody, responseContentType); + res.status = 500; + } - Mutex::Lock l(_nets_m); - if (_nets.find(id) != _nets.end()) { - NetworkState& ns = _nets[id]; - std::string code = req.get_param_value("code"); - char *ret = ns.doTokenExchange(code.c_str()); - json ssoResult = json::parse(ret); - if (ssoResult.is_object()) { - if (ssoResult.contains("errorMessage")) { - outData["isError"] = true; - outData["messageText"] = ssoResult["errorMessage"]; - responseBody = inja::render(htmlTemplate, outData); - res.set_content(responseBody, responseContentType); - res.status = 500; - } else { - outData["isError"] = false; - outData["messageText"] = "Authentication Successful. You may now access the network."; - responseBody = inja::render(htmlTemplate, outData); - res.set_content(responseBody, responseContentType); - } - } else { - // not an object? We got a problem - outData["isError"] = true; - outData["messageText"] = "ERROR: Unkown SSO response. Please contact your administrator."; - responseBody = inja::render(htmlTemplate, outData); - res.set_content(responseBody, responseContentType); - res.status = 500; - } - - zeroidc::free_cstr(ret); - } - }; - _controlPlane.Get(ssoPath, ssoGet); + zeroidc::free_cstr(ret); + } + }; + _controlPlane.Get(ssoPath, ssoGet); _controlPlaneV6.Get(ssoPath, ssoGet); #endif - auto metricsGet = [this](const httplib::Request &req, httplib::Response &res) { - std::string statspath = _homePath + ZT_PATH_SEPARATOR + "metrics.prom"; - std::string metrics; - if (OSUtils::readFile(statspath.c_str(), metrics)) { - res.set_content(metrics, "text/plain"); - } else { - res.set_content("{}", "application/json"); - res.status = 500; - } - }; - _controlPlane.Get(metricsPath, metricsGet); + auto metricsGet = [this](const httplib::Request& req, httplib::Response& res) { + std::string statspath = _homePath + ZT_PATH_SEPARATOR + "metrics.prom"; + std::string metrics; + if (OSUtils::readFile(statspath.c_str(), metrics)) { + res.set_content(metrics, "text/plain"); + } + else { + res.set_content("{}", "application/json"); + res.status = 500; + } + }; + _controlPlane.Get(metricsPath, metricsGet); _controlPlaneV6.Get(metricsPath, metricsGet); - auto exceptionHandler = [&, setContent](const httplib::Request &req, httplib::Response &res, std::exception_ptr ep) { + auto exceptionHandler = [&, setContent](const httplib::Request& req, httplib::Response& res, std::exception_ptr ep) { char buf[1024]; auto fmt = "{\"error\": %d, \"description\": \"%s\"}"; try { std::rethrow_exception(ep); - } catch (std::exception &e) { + } + catch (std::exception& e) { snprintf(buf, sizeof(buf), fmt, 500, e.what()); - } catch (...) { + } + catch (...) { snprintf(buf, sizeof(buf), fmt, 500, "Unknown Exception"); } setContent(req, res, buf); @@ -2338,60 +2384,58 @@ public: _controlPlane.set_pre_routing_handler(authCheck); _controlPlaneV6.set_pre_routing_handler(authCheck); -#if ZT_DEBUG==1 - _controlPlane.set_logger([](const httplib::Request &req, const httplib::Response &res) { - fprintf(stderr, "%s", http_log(req, res).c_str()); - }); - _controlPlaneV6.set_logger([](const httplib::Request &req, const httplib::Response &res) { - fprintf(stderr, "%s", http_log(req, res).c_str()); - }); +#if ZT_DEBUG == 1 + _controlPlane.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); + _controlPlaneV6.set_logger([](const httplib::Request& req, const httplib::Response& res) { fprintf(stderr, "%s", http_log(req, res).c_str()); }); #endif - if (_primaryPort==0) { + if (_primaryPort == 0) { fprintf(stderr, "unable to determine local control port"); exit(-1); } bool v4controlPlaneBound = false; _controlPlane.set_address_family(AF_INET); - if(_controlPlane.bind_to_port("0.0.0.0", _primaryPort)) { + if (_controlPlane.bind_to_port("0.0.0.0", _primaryPort)) { _serverThread = std::thread([&] { _serverThreadRunning = true; fprintf(stderr, "Starting Control Plane...\n"); - if(!_controlPlane.listen_after_bind()) { + if (! _controlPlane.listen_after_bind()) { fprintf(stderr, "Error on listen_after_bind()\n"); } fprintf(stderr, "Control Plane Stopped\n"); _serverThreadRunning = false; }); v4controlPlaneBound = true; - } else { + } + else { fprintf(stderr, "Error binding control plane to 0.0.0.0:%d\n", _primaryPort); v4controlPlaneBound = false; } bool v6controlPlaneBound = false; _controlPlaneV6.set_address_family(AF_INET6); - if(_controlPlaneV6.bind_to_port("::", _primaryPort)) { + if (_controlPlaneV6.bind_to_port("::", _primaryPort)) { _serverThreadV6 = std::thread([&] { _serverThreadRunningV6 = true; fprintf(stderr, "Starting V6 Control Plane...\n"); - if(!_controlPlaneV6.listen_after_bind()) { + if (! _controlPlaneV6.listen_after_bind()) { fprintf(stderr, "Error on V6 listen_after_bind()\n"); } fprintf(stderr, "V6 Control Plane Stopped\n"); _serverThreadRunningV6 = false; }); v6controlPlaneBound = true; - } else { + } + else { fprintf(stderr, "Error binding control plane to [::]:%d\n", _primaryPort); v6controlPlaneBound = false; } - if (!v4controlPlaneBound && !v6controlPlaneBound) { + if (! v4controlPlaneBound && ! v6controlPlaneBound) { fprintf(stderr, "ERROR: Could not bind control plane. Exiting...\n"); exit(-1); } - } + } // Must be called after _localConfig is read or modified void applyLocalConfig() @@ -2403,33 +2447,33 @@ public: _v6Hints.clear(); _v4Blacklists.clear(); _v6Blacklists.clear(); - json &virt = lc["virtual"]; + json& virt = lc["virtual"]; if (virt.is_object()) { - for(json::iterator v(virt.begin());v!=virt.end();++v) { + for (json::iterator v(virt.begin()); v != virt.end(); ++v) { const std::string nstr = v.key(); - if ((nstr.length() == ZT_ADDRESS_LENGTH_HEX)&&(v.value().is_object())) { + if ((nstr.length() == ZT_ADDRESS_LENGTH_HEX) && (v.value().is_object())) { const Address ztaddr(Utils::hexStrToU64(nstr.c_str())); if (ztaddr) { const uint64_t ztaddr2 = ztaddr.toInt(); - std::vector &v4h = _v4Hints[ztaddr2]; - std::vector &v6h = _v6Hints[ztaddr2]; - std::vector &v4b = _v4Blacklists[ztaddr2]; - std::vector &v6b = _v6Blacklists[ztaddr2]; + std::vector& v4h = _v4Hints[ztaddr2]; + std::vector& v6h = _v6Hints[ztaddr2]; + std::vector& v4b = _v4Blacklists[ztaddr2]; + std::vector& v6b = _v6Blacklists[ztaddr2]; - json &tryAddrs = v.value()["try"]; + json& tryAddrs = v.value()["try"]; if (tryAddrs.is_array()) { - for(unsigned long i=0;i 0)) { + for (json::iterator phy(physical.begin()); phy != physical.end(); ++phy) { + const InetAddress net(OSUtils::jsonString(phy.key(), "").c_str()); + if ((net) && (net.netmaskBits() > 0)) { if (phy.value().is_object()) { - if (OSUtils::jsonBool(phy.value()["blacklist"],false)) { + if (OSUtils::jsonBool(phy.value()["blacklist"], false)) { if (net.ss_family == AF_INET) _globalV4Blacklist.push_back(net); else if (net.ss_family == AF_INET6) @@ -2468,73 +2516,76 @@ public: _allowManagementFrom.clear(); _interfacePrefixBlacklist.clear(); - json &settings = lc["settings"]; + json& settings = lc["settings"]; - if (!_node->bondController()->inUse()) { + if (! _node->bondController()->inUse()) { _node->bondController()->setBinder(&_binder); // defaultBondingPolicy - std::string defaultBondingPolicyStr(OSUtils::jsonString(settings["defaultBondingPolicy"],"")); + std::string defaultBondingPolicyStr(OSUtils::jsonString(settings["defaultBondingPolicy"], "")); int defaultBondingPolicy = _node->bondController()->getPolicyCodeByStr(defaultBondingPolicyStr); _node->bondController()->setBondingLayerDefaultPolicy(defaultBondingPolicy); - _node->bondController()->setBondingLayerDefaultPolicyStr(defaultBondingPolicyStr); // Used if custom policy + _node->bondController()->setBondingLayerDefaultPolicyStr(defaultBondingPolicyStr); // Used if custom policy // Custom Policies - json &customBondingPolicies = settings["policies"]; - for (json::iterator policyItr = customBondingPolicies.begin(); policyItr != customBondingPolicies.end();++policyItr) { + json& customBondingPolicies = settings["policies"]; + for (json::iterator policyItr = customBondingPolicies.begin(); policyItr != customBondingPolicies.end(); ++policyItr) { // Custom Policy std::string customPolicyStr(policyItr.key()); - json &customPolicy = policyItr.value(); - std::string basePolicyStr(OSUtils::jsonString(customPolicy["basePolicy"],"")); + json& customPolicy = policyItr.value(); + std::string basePolicyStr(OSUtils::jsonString(customPolicy["basePolicy"], "")); if (basePolicyStr.empty()) { fprintf(stderr, "error: no base policy was specified for custom policy (%s)\n", customPolicyStr.c_str()); } int basePolicyCode = _node->bondController()->getPolicyCodeByStr(basePolicyStr); if (basePolicyCode == ZT_BOND_POLICY_NONE) { - fprintf(stderr, "error: custom policy (%s) is invalid, unknown base policy (%s).\n", - customPolicyStr.c_str(), basePolicyStr.c_str()); + fprintf(stderr, "error: custom policy (%s) is invalid, unknown base policy (%s).\n", customPolicyStr.c_str(), basePolicyStr.c_str()); continue; - } if (_node->bondController()->getPolicyCodeByStr(customPolicyStr) != ZT_BOND_POLICY_NONE) { - fprintf(stderr, "error: custom policy (%s) will be ignored, cannot use standard policy names for custom policies.\n", - customPolicyStr.c_str()); + } + if (_node->bondController()->getPolicyCodeByStr(customPolicyStr) != ZT_BOND_POLICY_NONE) { + fprintf(stderr, "error: custom policy (%s) will be ignored, cannot use standard policy names for custom policies.\n", customPolicyStr.c_str()); continue; } // New bond, used as a copy template for new instances SharedPtr newTemplateBond = new Bond(NULL, basePolicyStr, customPolicyStr, SharedPtr()); newTemplateBond->setPolicy(basePolicyCode); // Custom link quality spec - json &linkQualitySpec = customPolicy["linkQuality"]; + json& linkQualitySpec = customPolicy["linkQuality"]; if (linkQualitySpec.size() == ZT_QOS_PARAMETER_SIZE) { float weights[ZT_QOS_PARAMETER_SIZE] = {}; - weights[ZT_QOS_LAT_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_max"],0.0); - weights[ZT_QOS_PDV_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_max"],0.0); - weights[ZT_QOS_PLR_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_max"],0.0); - weights[ZT_QOS_PER_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_max"],0.0); - weights[ZT_QOS_LAT_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_weight"],0.0); - weights[ZT_QOS_PDV_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_weight"],0.0); - weights[ZT_QOS_PLR_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_weight"],0.0); - weights[ZT_QOS_PER_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_weight"],0.0); - newTemplateBond->setUserLinkQualitySpec(weights,ZT_QOS_PARAMETER_SIZE); + weights[ZT_QOS_LAT_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_max"], 0.0); + weights[ZT_QOS_PDV_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_max"], 0.0); + weights[ZT_QOS_PLR_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_max"], 0.0); + weights[ZT_QOS_PER_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_max"], 0.0); + weights[ZT_QOS_LAT_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_weight"], 0.0); + weights[ZT_QOS_PDV_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_weight"], 0.0); + weights[ZT_QOS_PLR_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_weight"], 0.0); + weights[ZT_QOS_PER_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_weight"], 0.0); + newTemplateBond->setUserLinkQualitySpec(weights, ZT_QOS_PARAMETER_SIZE); } // Bond-specific properties - newTemplateBond->setUpDelay(OSUtils::jsonInt(customPolicy["upDelay"],-1)); - newTemplateBond->setDownDelay(OSUtils::jsonInt(customPolicy["downDelay"],-1)); - newTemplateBond->setFailoverInterval(OSUtils::jsonInt(customPolicy["failoverInterval"],ZT_BOND_FAILOVER_DEFAULT_INTERVAL)); - newTemplateBond->setPacketsPerLink(OSUtils::jsonInt(customPolicy["packetsPerLink"],-1)); + newTemplateBond->setUpDelay(OSUtils::jsonInt(customPolicy["upDelay"], -1)); + newTemplateBond->setDownDelay(OSUtils::jsonInt(customPolicy["downDelay"], -1)); + newTemplateBond->setFailoverInterval(OSUtils::jsonInt(customPolicy["failoverInterval"], ZT_BOND_FAILOVER_DEFAULT_INTERVAL)); + newTemplateBond->setPacketsPerLink(OSUtils::jsonInt(customPolicy["packetsPerLink"], -1)); // Policy-Specific link set - json &links = customPolicy["links"]; - for (json::iterator linkItr = links.begin(); linkItr != links.end();++linkItr) { + json& links = customPolicy["links"]; + for (json::iterator linkItr = links.begin(); linkItr != links.end(); ++linkItr) { std::string linkNameStr(linkItr.key()); - json &link = linkItr.value(); - bool enabled = OSUtils::jsonInt(link["enabled"],true); - uint32_t capacity = OSUtils::jsonInt(link["capacity"],0); - uint8_t ipvPref = OSUtils::jsonInt(link["ipvPref"],0); - uint16_t mtu = OSUtils::jsonInt(link["mtu"],0); - std::string failoverToStr(OSUtils::jsonString(link["failoverTo"],"")); + json& link = linkItr.value(); + bool enabled = OSUtils::jsonInt(link["enabled"], true); + uint32_t capacity = OSUtils::jsonInt(link["capacity"], 0); + uint8_t ipvPref = OSUtils::jsonInt(link["ipvPref"], 0); + uint16_t mtu = OSUtils::jsonInt(link["mtu"], 0); + std::string failoverToStr(OSUtils::jsonString(link["failoverTo"], "")); // Mode - std::string linkModeStr(OSUtils::jsonString(link["mode"],"spare")); + std::string linkModeStr(OSUtils::jsonString(link["mode"], "spare")); uint8_t linkMode = ZT_BOND_SLAVE_MODE_SPARE; - if (linkModeStr == "primary") { linkMode = ZT_BOND_SLAVE_MODE_PRIMARY; } - if (linkModeStr == "spare") { linkMode = ZT_BOND_SLAVE_MODE_SPARE; } + if (linkModeStr == "primary") { + linkMode = ZT_BOND_SLAVE_MODE_PRIMARY; + } + if (linkModeStr == "spare") { + linkMode = ZT_BOND_SLAVE_MODE_SPARE; + } // ipvPref if ((ipvPref != 0) && (ipvPref != 4) && (ipvPref != 6) && (ipvPref != 46) && (ipvPref != 64)) { fprintf(stderr, "error: invalid ipvPref value (%d), link disabled.\n", ipvPref); @@ -2545,9 +2596,9 @@ public: failoverToStr = ""; enabled = false; } - _node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr,ipvPref,mtu,capacity,enabled,linkMode,failoverToStr)); + _node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr, ipvPref, mtu, capacity, enabled, linkMode, failoverToStr)); } - std::string linkSelectMethodStr(OSUtils::jsonString(customPolicy["activeReselect"],"always")); + std::string linkSelectMethodStr(OSUtils::jsonString(customPolicy["activeReselect"], "always")); if (linkSelectMethodStr == "always") { newTemplateBond->setLinkSelectMethod(ZT_BOND_RESELECTION_POLICY_ALWAYS); } @@ -2563,53 +2614,53 @@ public: if (newTemplateBond->getLinkSelectMethod() < 0 || newTemplateBond->getLinkSelectMethod() > 3) { fprintf(stderr, "warning: invalid value (%s) for linkSelectMethod, assuming mode: always\n", linkSelectMethodStr.c_str()); } - if (!_node->bondController()->addCustomPolicy(newTemplateBond)) { + if (! _node->bondController()->addCustomPolicy(newTemplateBond)) { fprintf(stderr, "error: a custom policy of this name (%s) already exists.\n", customPolicyStr.c_str()); } } // Peer-specific bonding - json &peerSpecificBonds = settings["peerSpecificBonds"]; - for (json::iterator peerItr = peerSpecificBonds.begin(); peerItr != peerSpecificBonds.end();++peerItr) { - _node->bondController()->assignBondingPolicyToPeer(std::stoull(peerItr.key(),0,16), peerItr.value()); + json& peerSpecificBonds = settings["peerSpecificBonds"]; + for (json::iterator peerItr = peerSpecificBonds.begin(); peerItr != peerSpecificBonds.end(); ++peerItr) { + _node->bondController()->assignBondingPolicyToPeer(std::stoull(peerItr.key(), 0, 16), peerItr.value()); } // Check settings - if (defaultBondingPolicyStr.length() && !defaultBondingPolicy && !_node->bondController()->inUse()) { + if (defaultBondingPolicyStr.length() && ! defaultBondingPolicy && ! _node->bondController()->inUse()) { fprintf(stderr, "error: unknown policy (%s) specified by defaultBondingPolicy, bond disabled.\n", defaultBondingPolicyStr.c_str()); } } // bondingPolicy cannot be used with allowTcpFallbackRelay - bool _forceTcpRelayTmp = (OSUtils::jsonBool(settings["forceTcpRelay"],false)); + bool _forceTcpRelayTmp = (OSUtils::jsonBool(settings["forceTcpRelay"], false)); bool _bondInUse = _node->bondController()->inUse(); if (_forceTcpRelayTmp && _bondInUse) { fprintf(stderr, "Warning: forceTcpRelay cannot be used with multipath. Disabling forceTcpRelay\n"); } - _allowTcpFallbackRelay = (OSUtils::jsonBool(settings["allowTcpFallbackRelay"],true) && !_node->bondController()->inUse()); - _forceTcpRelay = (_forceTcpRelayTmp && !_node->bondController()->inUse()); - _enableWebServer = (OSUtils::jsonBool(settings["enableWebServer"],false)); + _allowTcpFallbackRelay = (OSUtils::jsonBool(settings["allowTcpFallbackRelay"], true) && ! _node->bondController()->inUse()); + _forceTcpRelay = (_forceTcpRelayTmp && ! _node->bondController()->inUse()); + _enableWebServer = (OSUtils::jsonBool(settings["enableWebServer"], false)); #ifdef ZT_TCP_FALLBACK_RELAY _fallbackRelayAddress = InetAddress(OSUtils::jsonString(settings["tcpFallbackRelay"], ZT_TCP_FALLBACK_RELAY).c_str()); #endif - _primaryPort = (unsigned int)OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff; - _allowSecondaryPort = OSUtils::jsonBool(settings["allowSecondaryPort"],true); - _secondaryPort = (unsigned int)OSUtils::jsonInt(settings["secondaryPort"],0); - _tertiaryPort = (unsigned int)OSUtils::jsonInt(settings["tertiaryPort"],0); + _primaryPort = (unsigned int)OSUtils::jsonInt(settings["primaryPort"], (uint64_t)_primaryPort) & 0xffff; + _allowSecondaryPort = OSUtils::jsonBool(settings["allowSecondaryPort"], true); + _secondaryPort = (unsigned int)OSUtils::jsonInt(settings["secondaryPort"], 0); + _tertiaryPort = (unsigned int)OSUtils::jsonInt(settings["tertiaryPort"], 0); if (_secondaryPort != 0 || _tertiaryPort != 0) { - fprintf(stderr,"WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S); + fprintf(stderr, "WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S); } - _portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true); - _node->setLowBandwidthMode(OSUtils::jsonBool(settings["lowBandwidthMode"],false)); + _portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"], true); + _node->setLowBandwidthMode(OSUtils::jsonBool(settings["lowBandwidthMode"], false)); #if defined(__LINUX__) || defined(__FreeBSD__) - _multicoreEnabled = OSUtils::jsonBool(settings["multicoreEnabled"],false); - _concurrency = OSUtils::jsonInt(settings["concurrency"],1); - _cpuPinningEnabled = OSUtils::jsonBool(settings["cpuPinningEnabled"],false); + _multicoreEnabled = OSUtils::jsonBool(settings["multicoreEnabled"], false); + _concurrency = OSUtils::jsonInt(settings["concurrency"], 1); + _cpuPinningEnabled = OSUtils::jsonBool(settings["cpuPinningEnabled"], false); if (_multicoreEnabled) { unsigned int maxConcurrency = std::thread::hardware_concurrency(); if (_concurrency <= 1 || _concurrency >= maxConcurrency) { unsigned int conservativeDefault = (std::thread::hardware_concurrency() >= 4 ? 2 : 1); fprintf(stderr, "Concurrency level provided (%d) is invalid, assigning conservative default value of (%d)\n", _concurrency, conservativeDefault); - _concurrency = conservativeDefault; + _concurrency = conservativeDefault; } setUpMultithreading(); } @@ -2625,34 +2676,35 @@ public: #endif #ifndef ZT_SDK - const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT)); - const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"],false); - if (((up == "apply")||(up == "download"))||(udist)) { - if (!_updater) - _updater = new SoftwareUpdater(*_node,_homePath); + const std::string up(OSUtils::jsonString(settings["softwareUpdate"], ZT_SOFTWARE_UPDATE_DEFAULT)); + const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"], false); + if (((up == "apply") || (up == "download")) || (udist)) { + if (! _updater) + _updater = new SoftwareUpdater(*_node, _homePath); _updateAutoApply = (up == "apply"); _updater->setUpdateDistribution(udist); - _updater->setChannel(OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL)); - } else { + _updater->setChannel(OSUtils::jsonString(settings["softwareUpdateChannel"], ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL)); + } + else { delete _updater; - _updater = (SoftwareUpdater *)0; + _updater = (SoftwareUpdater*)0; _updateAutoApply = false; } #endif - json &ignoreIfs = settings["interfacePrefixBlacklist"]; + json& ignoreIfs = settings["interfacePrefixBlacklist"]; if (ignoreIfs.is_array()) { - for(unsigned long i=0;i 0) _interfacePrefixBlacklist.push_back(tmp); } } - json &amf = settings["allowManagementFrom"]; + json& amf = settings["allowManagementFrom"]; if (amf.is_array()) { - for(unsigned long i=0;i &ips,const InetAddress &ip) const + inline bool matchIpOnly(const std::set& ips, const InetAddress& ip) const { - for(std::set::const_iterator i(ips.begin());i!=ips.end();++i) { + for (std::set::const_iterator i(ips.begin()); i != ips.end(); ++i) { if (i->ipsEqual(ip)) return true; } @@ -2743,7 +2796,7 @@ public: } // Apply or update managed IPs for a configured network (be sure n.tap exists) - void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes, bool syncDns) + void syncManagedStuff(NetworkState& n, bool syncIps, bool syncRoutes, bool syncDns) { char ipbuf[64]; @@ -2757,51 +2810,46 @@ public: newManagedIps2.reserve(n.config().assignedAddressCount); #endif - for(unsigned int i=0;i(&(n.config().assignedAddresses[i])); - if (checkIfManagedIsAllowed(n,*ii)) + for (unsigned int i = 0; i < n.config().assignedAddressCount; ++i) { + const InetAddress* ii = reinterpret_cast(&(n.config().assignedAddresses[i])); + if (checkIfManagedIsAllowed(n, *ii)) newManagedIps.push_back(*ii); } - std::sort(newManagedIps.begin(),newManagedIps.end()); - newManagedIps.erase(std::unique(newManagedIps.begin(),newManagedIps.end()),newManagedIps.end()); + std::sort(newManagedIps.begin(), newManagedIps.end()); + newManagedIps.erase(std::unique(newManagedIps.begin(), newManagedIps.end()), newManagedIps.end()); - for(std::vector::iterator ip(n.managedIps().begin());ip!=n.managedIps().end();++ip) { - if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) { - if (!n.tap()->removeIp(*ip)) - fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf)); + for (std::vector::iterator ip(n.managedIps().begin()); ip != n.managedIps().end(); ++ip) { + if (std::find(newManagedIps.begin(), newManagedIps.end(), *ip) == newManagedIps.end()) { + if (! n.tap()->removeIp(*ip)) + fprintf(stderr, "ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf)); - #ifdef __WINDOWS__ +#ifdef __WINDOWS__ WinFWHelper::removeICMPRule(*ip, n.config().nwid); - #endif +#endif } } - - for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { - + for (std::vector::iterator ip(newManagedIps.begin()); ip != newManagedIps.end(); ++ip) { #ifdef __APPLE__ // We can't add multiple addresses to an interface on macOs unless we futz with the netmask. // see `man ifconfig`, alias section // "If the address is on the same subnet as the first network address for this interface, a non-conflicting netmask must be given. Usually 0xffffffff is most appropriate." - auto same_subnet = [ip](InetAddress i){ - return ip->network() == i.network(); - }; + auto same_subnet = [ip](InetAddress i) { return ip->network() == i.network(); }; #endif - if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) { + if (std::find(n.managedIps().begin(), n.managedIps().end(), *ip) == n.managedIps().end()) { #ifdef __APPLE__ // if same subnet as a previously added address - if ( - std::find_if(n.managedIps().begin(),n.managedIps().end(), same_subnet) != n.managedIps().end() || - std::find_if(newManagedIps2.begin(),newManagedIps2.end(), same_subnet) != newManagedIps2.end() - ) { + if (std::find_if(n.managedIps().begin(), n.managedIps().end(), same_subnet) != n.managedIps().end() || std::find_if(newManagedIps2.begin(), newManagedIps2.end(), same_subnet) != newManagedIps2.end()) { if (ip->isV4()) { ip->setPort(32); - } else { + } + else { ip->setPort(128); } - } else { + } + else { newManagedIps2.push_back(*ip); } #endif @@ -2818,11 +2866,11 @@ public: } #ifdef __APPLE__ - if (!MacDNSHelper::addIps6(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) { + if (! MacDNSHelper::addIps6(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) { fprintf(stderr, "ERROR: unable to add v6 addresses to system configuration" ZT_EOL_S); } - if (!MacDNSHelper::addIps4(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) { + if (! MacDNSHelper::addIps4(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps)) { fprintf(stderr, "ERROR: unable to add v4 addresses to system configuration" ZT_EOL_S); } #endif @@ -2831,9 +2879,9 @@ public: if (syncRoutes) { // Get tap device name (use LUID in hex on Windows) and IP addresses. -#if defined(__WINDOWS__) && !defined(ZT_SDK) +#if defined(__WINDOWS__) && ! defined(ZT_SDK) char tapdevbuf[64]; - OSUtils::ztsnprintf(tapdevbuf,sizeof(tapdevbuf),"%.16llx",(unsigned long long)((WindowsEthernetTap *)(n.tap().get()))->luid().Value); + OSUtils::ztsnprintf(tapdevbuf, sizeof(tapdevbuf), "%.16llx", (unsigned long long)((WindowsEthernetTap*)(n.tap().get()))->luid().Value); std::string tapdev(tapdevbuf); #else std::string tapdev(n.tap()->deviceName()); @@ -2841,38 +2889,38 @@ public: std::vector tapIps(n.tap()->ips()); std::set myIps(tapIps.begin(), tapIps.end()); - for(unsigned int i=0;i haveRouteTargets; - for(unsigned int i=0;i(&(n.config().routes[i].target)); - const InetAddress *const via = reinterpret_cast(&(n.config().routes[i].via)); + for (unsigned int i = 0; i < n.config().routeCount; ++i) { + const InetAddress* const target = reinterpret_cast(&(n.config().routes[i].target)); + const InetAddress* const via = reinterpret_cast(&(n.config().routes[i].via)); // Make sure we are allowed to set this managed route, and that 'via' is not our IP. The latter // avoids setting routes via the router on the router. - if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(matchIpOnly(myIps,*via))) ) + if ((! checkIfManagedIsAllowed(n, *target)) || ((via->ss_family == target->ss_family) && (matchIpOnly(myIps, *via)))) continue; // Find an IP on the interface that can be a source IP, abort if no IPs assigned. - const InetAddress *src = nullptr; + const InetAddress* src = nullptr; unsigned int mostMatchingPrefixBits = 0; - for(std::set::const_iterator i(myIps.begin());i!=myIps.end();++i) { + for (std::set::const_iterator i(myIps.begin()); i != myIps.end(); ++i) { const unsigned int matchingPrefixBits = i->matchingPrefixBits(*target); if (matchingPrefixBits >= mostMatchingPrefixBits && ((target->isV4() && i->isV4()) || (target->isV6() && i->isV6()))) { mostMatchingPrefixBits = matchingPrefixBits; src = &(*i); } } - if (!src) + if (! src) continue; // Ignore routes implied by local managed IPs since adding the IP adds the route. // Apple on the other hand seems to need this at least on some versions. #ifndef __APPLE__ bool haveRoute = false; - for(std::vector::iterator ip(n.managedIps().begin());ip!=n.managedIps().end();++ip) { - if ((target->netmaskBits() == ip->netmaskBits())&&(target->containsAddress(*ip))) { + for (std::vector::iterator ip(n.managedIps().begin()); ip != n.managedIps().end(); ++ip) { + if ((target->netmaskBits() == ip->netmaskBits()) && (target->containsAddress(*ip))) { haveRoute = true; break; } @@ -2884,27 +2932,28 @@ public: haveRouteTargets.insert(*target); #ifndef ZT_SDK - SharedPtr &mr = n.managedRoutes()[*target]; - if (!mr) + SharedPtr& mr = n.managedRoutes()[*target]; + if (! mr) mr.set(new ManagedRoute(*target, *via, *src, tapdev.c_str())); #endif } - for(std::map< InetAddress, SharedPtr >::iterator r(n.managedRoutes().begin());r!=n.managedRoutes().end();) { + for (std::map >::iterator r(n.managedRoutes().begin()); r != n.managedRoutes().end();) { if (haveRouteTargets.find(r->first) == haveRouteTargets.end()) n.managedRoutes().erase(r++); - else ++r; + else + ++r; } // Sync device-local managed routes first, then indirect results. That way // we don't get destination unreachable for routes that are via things // that do not yet have routes in the system. - for(std::map< InetAddress, SharedPtr >::iterator r(n.managedRoutes().begin());r!=n.managedRoutes().end();++r) { - if (!r->second->via()) + for (std::map >::iterator r(n.managedRoutes().begin()); r != n.managedRoutes().end(); ++r) { + if (! r->second->via()) r->second->sync(); } - for(std::map< InetAddress, SharedPtr >::iterator r(n.managedRoutes().begin());r!=n.managedRoutes().end();++r) { - if (r->second->via() && (!r->second->target().isDefaultRoute() || _node->online())) { + for (std::map >::iterator r(n.managedRoutes().begin()); r != n.managedRoutes().end(); ++r) { + if (r->second->via() && (! r->second->target().isDefaultRoute() || _node->online())) { r->second->sync(); } } @@ -2922,14 +2971,14 @@ public: } n.tap()->setDns(n.config().dns.domain, servers); } - } else { + } + else { #ifdef __APPLE__ MacDNSHelper::removeDNS(n.config().nwid); #elif defined(__WINDOWS__) WinDNSHelper::removeDNS(n.config().nwid); #endif } - } } @@ -2937,9 +2986,6 @@ public: // Handlers for Node and Phy<> callbacks // ========================================================================= - - - inline void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len) { if (_forceTcpRelay) { @@ -2950,10 +2996,10 @@ public: if ((len >= 16) && (reinterpret_cast(from)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) { _lastDirectReceiveFromGlobal = now; } - const ZT_ResultCode rc = _node->processWirePacket(nullptr,now,reinterpret_cast(sock),reinterpret_cast(from),data,len,&_nextBackgroundTaskDeadline); + const ZT_ResultCode rc = _node->processWirePacket(nullptr, now, reinterpret_cast(sock), reinterpret_cast(from), data, len, &_nextBackgroundTaskDeadline); if (ZT_ResultCode_isFatal(rc)) { char tmp[256]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "fatal error code from processWirePacket: %d", (int)rc); Mutex::Lock _l(_termReason_m); _termReason = ONE_UNRECOVERABLE_ERROR; _fatalErrorMessage = tmp; @@ -2961,17 +3007,16 @@ public: } } - - inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) + inline void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success) { - if (!success) { - phyOnTcpClose(sock,uptr); + if (! success) { + phyOnTcpClose(sock, uptr); return; } - TcpConnection *const tc = reinterpret_cast(*uptr); - if (!tc) { // sanity check - _phy.close(sock,true); + TcpConnection* const tc = reinterpret_cast(*uptr); + if (! tc) { // sanity check + _phy.close(sock, true); return; } tc->sock = sock; @@ -2980,26 +3025,28 @@ public: if (_tcpFallbackTunnel) _phy.close(_tcpFallbackTunnel->sock); _tcpFallbackTunnel = tc; - _phy.streamSend(sock,ZT_TCP_TUNNEL_HELLO,sizeof(ZT_TCP_TUNNEL_HELLO)); - } else { - _phy.close(sock,true); + _phy.streamSend(sock, ZT_TCP_TUNNEL_HELLO, sizeof(ZT_TCP_TUNNEL_HELLO)); + } + else { + _phy.close(sock, true); } } - inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) + inline void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from) { - if (!from) { - _phy.close(sockN,false); + if (! from) { + _phy.close(sockN, false); return; - } else { + } + else { #ifdef ZT_SDK // Immediately close new local connections. The intention is to prevent the backplane from being accessed when operating as libzt - if (!allowHttpBackplaneManagement && ((InetAddress*)from)->ipScope() == InetAddress::IP_SCOPE_LOOPBACK) { - _phy.close(sockN,false); + if (! allowHttpBackplaneManagement && ((InetAddress*)from)->ipScope() == InetAddress::IP_SCOPE_LOOPBACK) { + _phy.close(sockN, false); return; } #endif - TcpConnection *tc = new TcpConnection(); + TcpConnection* tc = new TcpConnection(); { Mutex::Lock _l(_tcpConnections_m); _tcpConnections.push_back(tc); @@ -3010,104 +3057,101 @@ public: tc->sock = sockN; tc->remoteAddr = from; tc->lastReceive = OSUtils::now(); - http_parser_init(&(tc->parser),HTTP_REQUEST); - tc->parser.data = (void *)tc; + http_parser_init(&(tc->parser), HTTP_REQUEST); + tc->parser.data = (void*)tc; tc->messageSize = 0; - *uptrN = (void *)tc; + *uptrN = (void*)tc; } } - void phyOnTcpClose(PhySocket *sock,void **uptr) + void phyOnTcpClose(PhySocket* sock, void** uptr) { - TcpConnection *tc = (TcpConnection *)*uptr; + TcpConnection* tc = (TcpConnection*)*uptr; if (tc) { if (tc == _tcpFallbackTunnel) { - _tcpFallbackTunnel = (TcpConnection *)0; + _tcpFallbackTunnel = (TcpConnection*)0; } { Mutex::Lock _l(_tcpConnections_m); - _tcpConnections.erase(std::remove(_tcpConnections.begin(),_tcpConnections.end(),tc),_tcpConnections.end()); + _tcpConnections.erase(std::remove(_tcpConnections.begin(), _tcpConnections.end(), tc), _tcpConnections.end()); } delete tc; } } - void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) + void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len) { try { - if (!len) return; // sanity check, should never happen - Metrics::tcp_recv += len; - TcpConnection *tc = reinterpret_cast(*uptr); + if (! len) + return; // sanity check, should never happen + Metrics::tcp_recv += len; + TcpConnection* tc = reinterpret_cast(*uptr); tc->lastReceive = OSUtils::now(); - switch(tc->type) { + switch (tc->type) { case TcpConnection::TCP_UNCATEGORIZED_INCOMING: return; case TcpConnection::TCP_HTTP_INCOMING: case TcpConnection::TCP_HTTP_OUTGOING: - http_parser_execute(&(tc->parser),&HTTP_PARSER_SETTINGS,(const char *)data,len); - if ((tc->parser.upgrade)||(tc->parser.http_errno != HPE_OK)) + http_parser_execute(&(tc->parser), &HTTP_PARSER_SETTINGS, (const char*)data, len); + if ((tc->parser.upgrade) || (tc->parser.http_errno != HPE_OK)) _phy.close(sock); return; case TcpConnection::TCP_TUNNEL_OUTGOING: - tc->readq.append((const char *)data,len); + tc->readq.append((const char*)data, len); while (tc->readq.length() >= 5) { - const char *data = tc->readq.data(); - const unsigned long mlen = ( ((((unsigned long)data[3]) & 0xff) << 8) | (((unsigned long)data[4]) & 0xff) ); + const char* data = tc->readq.data(); + const unsigned long mlen = (((((unsigned long)data[3]) & 0xff) << 8) | (((unsigned long)data[4]) & 0xff)); if (tc->readq.length() >= (mlen + 5)) { InetAddress from; - unsigned long plen = mlen; // payload length, modified if there's an IP header - data += 5; // skip forward past pseudo-TLS junk and mlen + unsigned long plen = mlen; // payload length, modified if there's an IP header + data += 5; // skip forward past pseudo-TLS junk and mlen if (plen == 4) { // Hello message, which isn't sent by proxy and would be ignored by client - } else if (plen) { + } + else if (plen) { // Messages should contain IPv4 or IPv6 source IP address data - switch(data[0]) { - case 4: // IPv4 + switch (data[0]) { + case 4: // IPv4 if (plen >= 7) { - from.set((const void *)(data + 1),4,((((unsigned int)data[5]) & 0xff) << 8) | (((unsigned int)data[6]) & 0xff)); - data += 7; // type + 4 byte IP + 2 byte port + from.set((const void*)(data + 1), 4, ((((unsigned int)data[5]) & 0xff) << 8) | (((unsigned int)data[6]) & 0xff)); + data += 7; // type + 4 byte IP + 2 byte port plen -= 7; - } else { + } + else { _phy.close(sock); return; } break; - case 6: // IPv6 + case 6: // IPv6 if (plen >= 19) { - from.set((const void *)(data + 1),16,((((unsigned int)data[17]) & 0xff) << 8) | (((unsigned int)data[18]) & 0xff)); - data += 19; // type + 16 byte IP + 2 byte port + from.set((const void*)(data + 1), 16, ((((unsigned int)data[17]) & 0xff) << 8) | (((unsigned int)data[18]) & 0xff)); + data += 19; // type + 16 byte IP + 2 byte port plen -= 19; - } else { + } + else { _phy.close(sock); return; } break; - case 0: // none/omitted + case 0: // none/omitted ++data; --plen; break; - default: // invalid address type + default: // invalid address type _phy.close(sock); return; } if (from) { - InetAddress fakeTcpLocalInterfaceAddress((uint32_t)0xffffffff,0xffff); - const ZT_ResultCode rc = _node->processWirePacket( - (void *)0, - OSUtils::now(), - -1, - reinterpret_cast(&from), - data, - plen, - &_nextBackgroundTaskDeadline); + InetAddress fakeTcpLocalInterfaceAddress((uint32_t)0xffffffff, 0xffff); + const ZT_ResultCode rc = _node->processWirePacket((void*)0, OSUtils::now(), -1, reinterpret_cast(&from), data, plen, &_nextBackgroundTaskDeadline); if (ZT_ResultCode_isFatal(rc)) { char tmp[256]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); + OSUtils::ztsnprintf(tmp, sizeof(tmp), "fatal error code from processWirePacket: %d", (int)rc); Mutex::Lock _l(_termReason_m); _termReason = ONE_UNRECOVERABLE_ERROR; _fatalErrorMessage = tmp; @@ -3119,95 +3163,101 @@ public: } if (tc->readq.length() > (mlen + 5)) - tc->readq.erase(tc->readq.begin(),tc->readq.begin() + (mlen + 5)); - else tc->readq.clear(); - } else break; + tc->readq.erase(tc->readq.begin(), tc->readq.begin() + (mlen + 5)); + else + tc->readq.clear(); + } + else + break; } return; - } - } catch ( ... ) { + } + catch (...) { _phy.close(sock); } } - inline void phyOnTcpWritable(PhySocket *sock,void **uptr) + inline void phyOnTcpWritable(PhySocket* sock, void** uptr) { - TcpConnection *tc = reinterpret_cast(*uptr); + TcpConnection* tc = reinterpret_cast(*uptr); bool closeit = false; { Mutex::Lock _l(tc->writeq_m); if (tc->writeq.length() > 0) { - long sent = (long)_phy.streamSend(sock,tc->writeq.data(),(unsigned long)tc->writeq.length(),true); - Metrics::tcp_send += sent; + long sent = (long)_phy.streamSend(sock, tc->writeq.data(), (unsigned long)tc->writeq.length(), true); + Metrics::tcp_send += sent; if (sent > 0) { if ((unsigned long)sent >= (unsigned long)tc->writeq.length()) { tc->writeq.clear(); - _phy.setNotifyWritable(sock,false); + _phy.setNotifyWritable(sock, false); if (tc->type == TcpConnection::TCP_HTTP_INCOMING) - closeit = true; // HTTP keep alive not supported - } else { - tc->writeq.erase(tc->writeq.begin(),tc->writeq.begin() + sent); + closeit = true; // HTTP keep alive not supported + } + else { + tc->writeq.erase(tc->writeq.begin(), tc->writeq.begin() + sent); } } - } else { - _phy.setNotifyWritable(sock,false); + } + else { + _phy.setNotifyWritable(sock, false); } } if (closeit) _phy.close(sock); } - inline void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) {} - inline void phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {} - inline void phyOnUnixClose(PhySocket *sock,void **uptr) {} - inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} - inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {} + inline void phyOnFileDescriptorActivity(PhySocket* sock, void** uptr, bool readable, bool writable) + { + } + inline void phyOnUnixAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN) + { + } + inline void phyOnUnixClose(PhySocket* sock, void** uptr) + { + } + inline void phyOnUnixData(PhySocket* sock, void** uptr, void* data, unsigned long len) + { + } + inline void phyOnUnixWritable(PhySocket* sock, void** uptr) + { + } - inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwc) + inline int nodeVirtualNetworkConfigFunction(uint64_t nwid, void** nuptr, enum ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig* nwc) { Mutex::Lock _l(_nets_m); - NetworkState &n = _nets[nwid]; + NetworkState& n = _nets[nwid]; n.setWebPort(_primaryPort); switch (op) { case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: - if (!n.tap()) { + if (! n.tap()) { try { char friendlyName[128]; - OSUtils::ztsnprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid); + OSUtils::ztsnprintf(friendlyName, sizeof(friendlyName), "ZeroTier One [%.16llx]", nwid); - n.setTap(EthernetTap::newInstance( - nullptr, - _concurrency, - _cpuPinningEnabled, - _homePath.c_str(), - MAC(nwc->mac), - nwc->mtu, - (unsigned int)ZT_IF_METRIC, - nwid, - friendlyName, - StapFrameHandler, - (void *)this)); - *nuptr = (void *)&n; + n.setTap(EthernetTap::newInstance(nullptr, _concurrency, _cpuPinningEnabled, _homePath.c_str(), MAC(nwc->mac), nwc->mtu, (unsigned int)ZT_IF_METRIC, nwid, friendlyName, StapFrameHandler, (void*)this)); + *nuptr = (void*)&n; char nlcpath[256]; - OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid); + OSUtils::ztsnprintf(nlcpath, sizeof(nlcpath), "%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf", _homePath.c_str(), nwid); std::string nlcbuf; - if (OSUtils::readFile(nlcpath,nlcbuf)) { + if (OSUtils::readFile(nlcpath, nlcbuf)) { Dictionary<4096> nc; nc.load(nlcbuf.c_str()); Buffer<1024> allowManaged; if (nc.get("allowManaged", allowManaged) && allowManaged.size() > 0) { - std::string addresses (allowManaged.begin(), allowManaged.size()); - if (allowManaged.size() <= 5) { // untidy parsing for backward compatibility + std::string addresses(allowManaged.begin(), allowManaged.size()); + if (allowManaged.size() <= 5) { // untidy parsing for backward compatibility if (allowManaged[0] == '1' || allowManaged[0] == 't' || allowManaged[0] == 'T') { n.setAllowManaged(true); - } else { + } + else { n.setAllowManaged(false); } - } else { + } + else { // this should be a list of IP addresses n.setAllowManaged(true); size_t pos = 0; @@ -3215,31 +3265,35 @@ public: size_t nextPos = addresses.find(',', pos); std::string address = addresses.substr(pos, (nextPos == std::string::npos ? addresses.size() : nextPos) - pos); n.addToAllowManagedWhiteList(InetAddress(address.c_str())); - if (nextPos == std::string::npos) break; + if (nextPos == std::string::npos) + break; pos = nextPos + 1; } } - } else { + } + else { n.setAllowManaged(true); } n.setAllowGlobal(nc.getB("allowGlobal", false)); n.setAllowDefault(nc.getB("allowDefault", false)); n.setAllowDNS(nc.getB("allowDNS", false)); } - } catch (std::exception &exc) { + } + catch (std::exception& exc) { #ifdef __WINDOWS__ - FILE *tapFailLog = fopen((_homePath + ZT_PATH_SEPARATOR_S"port_error_log.txt").c_str(),"a"); + FILE* tapFailLog = fopen((_homePath + ZT_PATH_SEPARATOR_S "port_error_log.txt").c_str(), "a"); if (tapFailLog) { - fprintf(tapFailLog,"%.16llx: %s" ZT_EOL_S,(unsigned long long)nwid,exc.what()); + fprintf(tapFailLog, "%.16llx: %s" ZT_EOL_S, (unsigned long long)nwid, exc.what()); fclose(tapFailLog); } #else - fprintf(stderr,"ERROR: unable to configure virtual network port: %s" ZT_EOL_S,exc.what()); + fprintf(stderr, "ERROR: unable to configure virtual network port: %s" ZT_EOL_S, exc.what()); #endif _nets.erase(nwid); return -999; - } catch ( ... ) { - return -999; // tap init failed + } + catch (...) { + return -999; // tap init failed } } // After setting up tap, fall through to CONFIG_UPDATE since we also want to do this... @@ -3247,35 +3301,36 @@ public: case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: n.setConfig(nwc); - if (n.tap()) { // sanity check -#if defined(__WINDOWS__) && !defined(ZT_SDK) + if (n.tap()) { // sanity check +#if defined(__WINDOWS__) && ! defined(ZT_SDK) // wait for up to 5 seconds for the WindowsEthernetTap to actually be initialized // // without WindowsEthernetTap::isInitialized() returning true, the won't actually // be online yet and setting managed routes on it will fail. const int MAX_SLEEP_COUNT = 500; - for (int i = 0; !((WindowsEthernetTap *)(n.tap().get()))->isInitialized() && i < MAX_SLEEP_COUNT; i++) { + for (int i = 0; ! ((WindowsEthernetTap*)(n.tap().get()))->isInitialized() && i < MAX_SLEEP_COUNT; i++) { Sleep(10); } #endif - syncManagedStuff(n,true,true,true); + syncManagedStuff(n, true, true, true); n.tap()->setMtu(nwc->mtu); - } else { + } + else { _nets.erase(nwid); - return -999; // tap init failed + return -999; // tap init failed } break; case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: - if (n.tap()) { // sanity check -#if defined(__WINDOWS__) && !defined(ZT_SDK) - std::string winInstanceId(((WindowsEthernetTap *)(n.tap().get()))->instanceId()); + if (n.tap()) { // sanity check +#if defined(__WINDOWS__) && ! defined(ZT_SDK) + std::string winInstanceId(((WindowsEthernetTap*)(n.tap().get()))->instanceId()); #endif - *nuptr = (void *)0; + *nuptr = (void*)0; n.tap().reset(); _nets.erase(nwid); -#if defined(__WINDOWS__) && !defined(ZT_SDK) +#if defined(__WINDOWS__) && ! defined(ZT_SDK) if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) && (winInstanceId.length() > 0)) { WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str()); WinFWHelper::removeICMPRules(nwid); @@ -3283,10 +3338,11 @@ public: #endif if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) { char nlcpath[256]; - OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid); + OSUtils::ztsnprintf(nlcpath, sizeof(nlcpath), "%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf", _homePath.c_str(), nwid); OSUtils::rm(nlcpath); } - } else { + } + else { _nets.erase(nwid); } break; @@ -3294,33 +3350,33 @@ public: return 0; } - inline void nodeEventCallback(enum ZT_Event event,const void *metaData) + inline void nodeEventCallback(enum ZT_Event event, const void* metaData) { - switch(event) { + switch (event) { case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { Mutex::Lock _l(_termReason_m); _termReason = ONE_IDENTITY_COLLISION; _fatalErrorMessage = "identity/address collision"; this->terminate(); - } break; + } break; case ZT_EVENT_TRACE: { if (metaData) { - ::fprintf(stderr,"%s" ZT_EOL_S,(const char *)metaData); + ::fprintf(stderr, "%s" ZT_EOL_S, (const char*)metaData); ::fflush(stderr); } - } break; + } break; case ZT_EVENT_USER_MESSAGE: { - const ZT_UserMessage *um = reinterpret_cast(metaData); - if ((um->typeId == ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE)&&(_updater)) { - _updater->handleSoftwareUpdateUserMessage(um->origin,um->data,um->length); + const ZT_UserMessage* um = reinterpret_cast(metaData); + if ((um->typeId == ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE) && (_updater)) { + _updater->handleSoftwareUpdateUserMessage(um->origin, um->data, um->length); } - } break; + } break; case ZT_EVENT_REMOTE_TRACE: { - const ZT_RemoteTrace *rt = reinterpret_cast(metaData); - if ((rt)&&(rt->len > 0)&&(rt->len <= ZT_MAX_REMOTE_TRACE_SIZE)&&(rt->data)) + const ZT_RemoteTrace* rt = reinterpret_cast(metaData); + if ((rt) && (rt->len > 0) && (rt->len <= ZT_MAX_REMOTE_TRACE_SIZE) && (rt->data)) _controller->handleRemoteTrace(*rt); } @@ -3330,22 +3386,21 @@ public: } #if ZT_VAULT_SUPPORT - inline bool nodeVaultPutIdentity(enum ZT_StateObjectType type, const void *data, int len) + inline bool nodeVaultPutIdentity(enum ZT_StateObjectType type, const void* data, int len) { bool retval = false; if (type != ZT_STATE_OBJECT_IDENTITY_PUBLIC && type != ZT_STATE_OBJECT_IDENTITY_SECRET) { return retval; } - CURL *curl = curl_easy_init(); + CURL* curl = curl_easy_init(); if (curl) { char token[512] = { 0 }; snprintf(token, sizeof(token), "X-Vault-Token: %s", _vaultToken.c_str()); - struct curl_slist *chunk = NULL; + struct curl_slist* chunk = NULL; chunk = curl_slist_append(chunk, token); - char content_type[512] = { 0 }; snprintf(content_type, sizeof(content_type), "Content-Type: application/json"); @@ -3368,10 +3423,10 @@ public: d["secret"] = key; } - if (!d.empty()) { + if (! d.empty()) { std::string post = d.dump(); - if (!post.empty()) { + if (! post.empty()) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post.length()); @@ -3400,7 +3455,7 @@ public: } #endif - inline void nodeStatePutFunction(enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len) + inline void nodeStatePutFunction(enum ZT_StateObjectType type, const uint64_t id[2], const void* data, int len) { #if ZT_VAULT_SUPPORT if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC)) { @@ -3412,49 +3467,49 @@ public: } #endif char p[1024]; - FILE *f; + FILE* f; bool secure = false; char dirname[1024]; dirname[0] = 0; - switch(type) { + switch (type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "identity.public", _homePath.c_str()); break; case ZT_STATE_OBJECT_IDENTITY_SECRET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "identity.secret", _homePath.c_str()); secure = true; break; case ZT_STATE_OBJECT_PLANET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "planet", _homePath.c_str()); break; case ZT_STATE_OBJECT_MOON: - OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "moons.d",_homePath.c_str()); - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.moon",dirname,(unsigned long long)id[0]); + OSUtils::ztsnprintf(dirname, sizeof(dirname), "%s" ZT_PATH_SEPARATOR_S "moons.d", _homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.16llx.moon", dirname, (unsigned long long)id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "networks.d",_homePath.c_str()); - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.conf",dirname,(unsigned long long)id[0]); + OSUtils::ztsnprintf(dirname, sizeof(dirname), "%s" ZT_PATH_SEPARATOR_S "networks.d", _homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.16llx.conf", dirname, (unsigned long long)id[0]); break; case ZT_STATE_OBJECT_PEER: - OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "peers.d",_homePath.c_str()); - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.10llx.peer",dirname,(unsigned long long)id[0]); + OSUtils::ztsnprintf(dirname, sizeof(dirname), "%s" ZT_PATH_SEPARATOR_S "peers.d", _homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "%.10llx.peer", dirname, (unsigned long long)id[0]); break; default: return; } - if ((len >= 0)&&(data)) { + if ((len >= 0) && (data)) { // Check to see if we've already written this first. This reduces // redundant writes and I/O overhead on most platforms and has // little effect on others. - f = fopen(p,"rb"); + f = fopen(p, "rb"); if (f) { - char *const buf = (char *)malloc(len*4); + char* const buf = (char*)malloc(len * 4); if (buf) { - long l = (long)fread(buf,1,(size_t)(len*4),f); + long l = (long)fread(buf, 1, (size_t)(len * 4), f); fclose(f); - if ((l == (long)len)&&(memcmp(data,buf,l) == 0)) { + if ((l == (long)len) && (memcmp(data, buf, l) == 0)) { free(buf); return; } @@ -3462,39 +3517,41 @@ public: } } - f = fopen(p,"wb"); - if ((!f)&&(dirname[0])) { // create subdirectory if it does not exist + f = fopen(p, "wb"); + if ((! f) && (dirname[0])) { // create subdirectory if it does not exist OSUtils::mkdir(dirname); - f = fopen(p,"wb"); + f = fopen(p, "wb"); } if (f) { - if (fwrite(data,len,1,f) != 1) - fprintf(stderr,"WARNING: unable to write to file: %s (I/O error)" ZT_EOL_S,p); + if (fwrite(data, len, 1, f) != 1) + fprintf(stderr, "WARNING: unable to write to file: %s (I/O error)" ZT_EOL_S, p); fclose(f); if (secure) - OSUtils::lockDownFile(p,false); - } else { - fprintf(stderr,"WARNING: unable to write to file: %s (unable to open)" ZT_EOL_S,p); + OSUtils::lockDownFile(p, false); } - } else { + else { + fprintf(stderr, "WARNING: unable to write to file: %s (unable to open)" ZT_EOL_S, p); + } + } + else { OSUtils::rm(p); } } #if ZT_VAULT_SUPPORT - inline int nodeVaultGetIdentity(enum ZT_StateObjectType type, void *data, unsigned int maxlen) + inline int nodeVaultGetIdentity(enum ZT_StateObjectType type, void* data, unsigned int maxlen) { if (type != ZT_STATE_OBJECT_IDENTITY_SECRET && type != ZT_STATE_OBJECT_IDENTITY_PUBLIC) { return -1; } int ret = -1; - CURL *curl = curl_easy_init(); + CURL* curl = curl_easy_init(); if (curl) { char token[512] = { 0 }; snprintf(token, sizeof(token), "X-Vault-Token: %s", _vaultToken.c_str()); - struct curl_slist *chunk = NULL; + struct curl_slist* chunk = NULL; chunk = curl_slist_append(chunk, token); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); @@ -3522,20 +3579,20 @@ public: if (response_code == 200) { try { json payload = json::parse(response); - if (!payload["data"].is_null()) { - json &d = payload["data"]; + if (! payload["data"].is_null()) { + json& d = payload["data"]; if (type == ZT_STATE_OBJECT_IDENTITY_SECRET) { - std::string secret = OSUtils::jsonString(d["secret"],""); + std::string secret = OSUtils::jsonString(d["secret"], ""); - if (!secret.empty()) { + if (! secret.empty()) { ret = (int)secret.length(); memcpy(data, secret.c_str(), ret); } } else if (type == ZT_STATE_OBJECT_IDENTITY_PUBLIC) { - std::string pub = OSUtils::jsonString(d["public"],""); + std::string pub = OSUtils::jsonString(d["public"], ""); - if (!pub.empty()) { + if (! pub.empty()) { ret = (int)pub.length(); memcpy(data, pub.c_str(), ret); } @@ -3557,10 +3614,10 @@ public: } #endif - inline int nodeStateGetFunction(enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen) + inline int nodeStateGetFunction(enum ZT_StateObjectType type, const uint64_t id[2], void* data, unsigned int maxlen) { #if ZT_VAULT_SUPPORT - if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC) ) { + if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC)) { int retval = nodeVaultGetIdentity(type, data, maxlen); if (retval >= 0) return retval; @@ -3569,31 +3626,31 @@ public: } #endif char p[4096]; - switch(type) { + switch (type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "identity.public", _homePath.c_str()); break; case ZT_STATE_OBJECT_IDENTITY_SECRET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "identity.secret", _homePath.c_str()); break; case ZT_STATE_OBJECT_PLANET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "planet", _homePath.c_str()); break; case ZT_STATE_OBJECT_MOON: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d" ZT_PATH_SEPARATOR_S "%.16llx.moon",_homePath.c_str(),(unsigned long long)id[0]); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "moons.d" ZT_PATH_SEPARATOR_S "%.16llx.moon", _homePath.c_str(), (unsigned long long)id[0]); break; case ZT_STATE_OBJECT_NETWORK_CONFIG: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.conf",_homePath.c_str(),(unsigned long long)id[0]); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.conf", _homePath.c_str(), (unsigned long long)id[0]); break; case ZT_STATE_OBJECT_PEER: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "peers.d" ZT_PATH_SEPARATOR_S "%.10llx.peer",_homePath.c_str(),(unsigned long long)id[0]); + OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "peers.d" ZT_PATH_SEPARATOR_S "%.10llx.peer", _homePath.c_str(), (unsigned long long)id[0]); break; default: return -1; } - FILE *f = fopen(p,"rb"); + FILE* f = fopen(p, "rb"); if (f) { - int n = (int)fread(data,1,maxlen,f); + int n = (int)fread(data, 1, maxlen, f); fclose(f); #if ZT_VAULT_SUPPORT if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC)) { @@ -3612,46 +3669,47 @@ public: return -1; } - inline int nodeWirePacketSendFunction(const int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl) + inline int nodeWirePacketSendFunction(const int64_t localSocket, const struct sockaddr_storage* addr, const void* data, unsigned int len, unsigned int ttl) { #ifdef ZT_TCP_FALLBACK_RELAY - if(_allowTcpFallbackRelay) { + if (_allowTcpFallbackRelay) { if (addr->ss_family == AF_INET) { // TCP fallback tunnel support, currently IPv4 only - if ((len >= 16)&&(reinterpret_cast(addr)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) { + if ((len >= 16) && (reinterpret_cast(addr)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) { // Engage TCP tunnel fallback if we haven't received anything valid from a global // IP address in ZT_TCP_FALLBACK_AFTER milliseconds. If we do start getting // valid direct traffic we'll stop using it and close the socket after a while. const int64_t now = OSUtils::now(); - if (_forceTcpRelay || (((now - _lastDirectReceiveFromGlobal) > ZT_TCP_FALLBACK_AFTER)&&((now - _lastRestart) > ZT_TCP_FALLBACK_AFTER))) { + if (_forceTcpRelay || (((now - _lastDirectReceiveFromGlobal) > ZT_TCP_FALLBACK_AFTER) && ((now - _lastRestart) > ZT_TCP_FALLBACK_AFTER))) { if (_tcpFallbackTunnel) { bool flushNow = false; { Mutex::Lock _l(_tcpFallbackTunnel->writeq_m); if (_tcpFallbackTunnel->writeq.size() < (1024 * 64)) { if (_tcpFallbackTunnel->writeq.length() == 0) { - _phy.setNotifyWritable(_tcpFallbackTunnel->sock,true); + _phy.setNotifyWritable(_tcpFallbackTunnel->sock, true); flushNow = true; } const unsigned long mlen = len + 7; _tcpFallbackTunnel->writeq.push_back((char)0x17); _tcpFallbackTunnel->writeq.push_back((char)0x03); - _tcpFallbackTunnel->writeq.push_back((char)0x03); // fake TLS 1.2 header + _tcpFallbackTunnel->writeq.push_back((char)0x03); // fake TLS 1.2 header _tcpFallbackTunnel->writeq.push_back((char)((mlen >> 8) & 0xff)); _tcpFallbackTunnel->writeq.push_back((char)(mlen & 0xff)); - _tcpFallbackTunnel->writeq.push_back((char)4); // IPv4 - _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_addr.s_addr))),4); - _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_port))),2); - _tcpFallbackTunnel->writeq.append((const char *)data,len); + _tcpFallbackTunnel->writeq.push_back((char)4); // IPv4 + _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_addr.s_addr))), 4); + _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_port))), 2); + _tcpFallbackTunnel->writeq.append((const char*)data, len); } } if (flushNow) { - void *tmpptr = (void *)_tcpFallbackTunnel; - phyOnTcpWritable(_tcpFallbackTunnel->sock,&tmpptr); + void* tmpptr = (void*)_tcpFallbackTunnel; + phyOnTcpWritable(_tcpFallbackTunnel->sock, &tmpptr); } - } else if (_forceTcpRelay || (((now - _lastSendToGlobalV4) < ZT_TCP_FALLBACK_AFTER)&&((now - _lastSendToGlobalV4) > (ZT_PING_CHECK_INTERVAL / 2)))) { + } + else if (_forceTcpRelay || (((now - _lastSendToGlobalV4) < ZT_TCP_FALLBACK_AFTER) && ((now - _lastSendToGlobalV4) > (ZT_PING_CHECK_INTERVAL / 2)))) { const InetAddress addr(_fallbackRelayAddress); - TcpConnection *tc = new TcpConnection(); + TcpConnection* tc = new TcpConnection(); { Mutex::Lock _l(_tcpConnections_m); _tcpConnections.push_back(tc); @@ -3660,10 +3718,10 @@ public: tc->remoteAddr = addr; tc->lastReceive = OSUtils::now(); tc->parent = this; - tc->sock = (PhySocket *)0; // set in connect handler + tc->sock = (PhySocket*)0; // set in connect handler tc->messageSize = 0; bool connected = false; - _phy.tcpConnect(reinterpret_cast(&addr),connected,(void *)tc,true); + _phy.tcpConnect(reinterpret_cast(&addr), connected, (void*)tc, true); } } _lastSendToGlobalV4 = now; @@ -3674,44 +3732,45 @@ public: // Shortcut here so that we don't emit any UDP packets return 0; } -#endif // ZT_TCP_FALLBACK_RELAY +#endif // ZT_TCP_FALLBACK_RELAY // Even when relaying we still send via UDP. This way if UDP starts // working we can instantly "fail forward" to it and stop using TCP // proxy fallback, which is slow. - if ((localSocket != -1)&&(localSocket != 0)&&(_binder.isUdpSocketValid((PhySocket *)((uintptr_t)localSocket)))) { - if ((ttl)&&(addr->ss_family == AF_INET)) { - _phy.setIp4UdpTtl((PhySocket *)((uintptr_t)localSocket),ttl); - } - const bool r = _phy.udpSend((PhySocket *)((uintptr_t)localSocket),(const struct sockaddr *)addr,data,len); - if ((ttl)&&(addr->ss_family == AF_INET)) { - _phy.setIp4UdpTtl((PhySocket *)((uintptr_t)localSocket),255); - } + if ((localSocket != -1) && (localSocket != 0) && (_binder.isUdpSocketValid((PhySocket*)((uintptr_t)localSocket)))) { + if ((ttl) && (addr->ss_family == AF_INET)) { + _phy.setIp4UdpTtl((PhySocket*)((uintptr_t)localSocket), ttl); + } + const bool r = _phy.udpSend((PhySocket*)((uintptr_t)localSocket), (const struct sockaddr*)addr, data, len); + if ((ttl) && (addr->ss_family == AF_INET)) { + _phy.setIp4UdpTtl((PhySocket*)((uintptr_t)localSocket), 255); + } return ((r) ? 0 : -1); - } else { - return ((_binder.udpSendAll(_phy,addr,data,len,ttl)) ? 0 : -1); + } + else { + return ((_binder.udpSendAll(_phy, addr, data, len, ttl)) ? 0 : -1); } } - inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + inline void nodeVirtualNetworkFrameFunction(uint64_t nwid, void** nuptr, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) { - NetworkState *n = reinterpret_cast(*nuptr); - if ((!n)||(!n->tap())) { + NetworkState* n = reinterpret_cast(*nuptr); + if ((! n) || (! n->tap())) { return; } - n->tap()->put(MAC(sourceMac),MAC(destMac),etherType,data,len); + n->tap()->put(MAC(sourceMac), MAC(destMac), etherType, data, len); } - inline int nodePathCheckFunction(uint64_t ztaddr,const int64_t localSocket,const struct sockaddr_storage *remoteAddr) + inline int nodePathCheckFunction(uint64_t ztaddr, const int64_t localSocket, const struct sockaddr_storage* remoteAddr) { // Make sure we're not trying to do ZeroTier-over-ZeroTier { Mutex::Lock _l(_nets_m); - for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + for (std::map::const_iterator n(_nets.begin()); n != _nets.end(); ++n) { if (n->second.tap()) { std::vector ips(n->second.tap()->ips()); - for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { - if (i->containsAddress(*(reinterpret_cast(remoteAddr)))) { + for (std::vector::const_iterator i(ips.begin()); i != ips.end(); ++i) { + if (i->containsAddress(*(reinterpret_cast(remoteAddr)))) { return 0; } } @@ -3726,28 +3785,29 @@ public: * revisit if we see recursion problems. */ // Check blacklists - const Hashtable< uint64_t,std::vector > *blh = (const Hashtable< uint64_t,std::vector > *)0; - const std::vector *gbl = (const std::vector *)0; + const Hashtable >* blh = (const Hashtable >*)0; + const std::vector* gbl = (const std::vector*)0; if (remoteAddr->ss_family == AF_INET) { blh = &_v4Blacklists; gbl = &_globalV4Blacklist; - } else if (remoteAddr->ss_family == AF_INET6) { + } + else if (remoteAddr->ss_family == AF_INET6) { blh = &_v6Blacklists; gbl = &_globalV6Blacklist; } if (blh) { Mutex::Lock _l(_localConfig_m); - const std::vector *l = blh->get(ztaddr); + const std::vector* l = blh->get(ztaddr); if (l) { - for(std::vector::const_iterator a(l->begin());a!=l->end();++a) { - if (a->containsAddress(*reinterpret_cast(remoteAddr))) + for (std::vector::const_iterator a(l->begin()); a != l->end(); ++a) { + if (a->containsAddress(*reinterpret_cast(remoteAddr))) return 0; } } } if (gbl) { - for(std::vector::const_iterator a(gbl->begin());a!=gbl->end();++a) { - if (a->containsAddress(*reinterpret_cast(remoteAddr))) + for (std::vector::const_iterator a(gbl->begin()); a != gbl->end(); ++a) { + if (a->containsAddress(*reinterpret_cast(remoteAddr))) return 0; } } @@ -3756,20 +3816,22 @@ public: inline int nodePathLookupFunction(uint64_t ztaddr, int family, struct sockaddr_storage* result) { - const Hashtable< uint64_t, std::vector >* lh = (const Hashtable< uint64_t, std::vector > *)0; + const Hashtable >* lh = (const Hashtable >*)0; if (family < 0) lh = (_node->prng() & 1) ? &_v4Hints : &_v6Hints; else if (family == AF_INET) lh = &_v4Hints; else if (family == AF_INET6) lh = &_v6Hints; - else return 0; + else + return 0; const std::vector* l = lh->get(ztaddr); - if ((l) && (!l->empty())) { + if ((l) && (! l->empty())) { memcpy(result, &((*l)[(unsigned long)_node->prng() % l->size()]), sizeof(struct sockaddr_storage)); return 1; } - else return 0; + else + return 0; } inline void tapFrameHandler(uint64_t nwid, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) @@ -3785,44 +3847,57 @@ public: bool shouldBindInterface(const char* ifname, const InetAddress& ifaddr) { #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) - if ((ifname[0] == 'l') && (ifname[1] == 'o')) return false; // loopback - if ((ifname[0] == 'z') && (ifname[1] == 't')) return false; // sanity check: zt# - if ((ifname[0] == 't') && (ifname[1] == 'u') && (ifname[2] == 'n')) return false; // tun# is probably an OpenVPN tunnel or similar - if ((ifname[0] == 't') && (ifname[1] == 'a') && (ifname[2] == 'p')) return false; // tap# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 'l') && (ifname[1] == 'o')) + return false; // loopback + if ((ifname[0] == 'z') && (ifname[1] == 't')) + return false; // sanity check: zt# + if ((ifname[0] == 't') && (ifname[1] == 'u') && (ifname[2] == 'n')) + return false; // tun# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 't') && (ifname[1] == 'a') && (ifname[2] == 'p')) + return false; // tap# is probably an OpenVPN tunnel or similar #endif #ifdef __APPLE__ - if ((ifname[0] == 'f') && (ifname[1] == 'e') && (ifname[2] == 't') && (ifname[3] == 'h')) return false; // ... as is feth# - if ((ifname[0] == 'l') && (ifname[1] == 'o')) return false; // loopback - if ((ifname[0] == 'z') && (ifname[1] == 't')) return false; // sanity check: zt# - if ((ifname[0] == 't') && (ifname[1] == 'u') && (ifname[2] == 'n')) return false; // tun# is probably an OpenVPN tunnel or similar - if ((ifname[0] == 't') && (ifname[1] == 'a') && (ifname[2] == 'p')) return false; // tap# is probably an OpenVPN tunnel or similar - if ((ifname[0] == 'u') && (ifname[1] == 't') && (ifname[2] == 'u') && (ifname[3] == 'n')) return false; // ... as is utun# + if ((ifname[0] == 'f') && (ifname[1] == 'e') && (ifname[2] == 't') && (ifname[3] == 'h')) + return false; // ... as is feth# + if ((ifname[0] == 'l') && (ifname[1] == 'o')) + return false; // loopback + if ((ifname[0] == 'z') && (ifname[1] == 't')) + return false; // sanity check: zt# + if ((ifname[0] == 't') && (ifname[1] == 'u') && (ifname[2] == 'n')) + return false; // tun# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 't') && (ifname[1] == 'a') && (ifname[2] == 'p')) + return false; // tap# is probably an OpenVPN tunnel or similar + if ((ifname[0] == 'u') && (ifname[1] == 't') && (ifname[2] == 'u') && (ifname[3] == 'n')) + return false; // ... as is utun# #endif #ifdef __FreeBSD__ - if ((ifname[0] == 'l') && (ifname[1] == 'o')) return false; // loopback - if ((ifname[0] == 'z') && (ifname[1] == 't')) return false; // sanity check: zt# + if ((ifname[0] == 'l') && (ifname[1] == 'o')) + return false; // loopback + if ((ifname[0] == 'z') && (ifname[1] == 't')) + return false; // sanity check: zt# #endif { Mutex::Lock _l(_localConfig_m); - for(std::vector::const_iterator p(_interfacePrefixBlacklist.begin());p!=_interfacePrefixBlacklist.end();++p) { - if (!strncmp(p->c_str(),ifname,p->length())) + for (std::vector::const_iterator p(_interfacePrefixBlacklist.begin()); p != _interfacePrefixBlacklist.end(); ++p) { + if (! strncmp(p->c_str(), ifname, p->length())) return false; } } { // Check global blacklists - const std::vector *gbl = (const std::vector *)0; + const std::vector* gbl = (const std::vector*)0; if (ifaddr.ss_family == AF_INET) { gbl = &_globalV4Blacklist; - } else if (ifaddr.ss_family == AF_INET6) { + } + else if (ifaddr.ss_family == AF_INET6) { gbl = &_globalV6Blacklist; } if (gbl) { Mutex::Lock _l(_localConfig_m); - for(std::vector::const_iterator a(gbl->begin());a!=gbl->end();++a) { + for (std::vector::const_iterator a(gbl->begin()); a != gbl->end(); ++a) { if (a->containsAddress(ifaddr)) return false; } @@ -3830,10 +3905,10 @@ public: } { Mutex::Lock _l(_nets_m); - for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { + for (std::map::const_iterator n(_nets.begin()); n != _nets.end(); ++n) { if (n->second.tap()) { std::vector ips(n->second.tap()->ips()); - for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { + for (std::vector::const_iterator i(ips.begin()); i != ips.end(); ++i) { if (i->ipsEqual(ifaddr)) return false; } @@ -3851,12 +3926,13 @@ public: unsigned int _getRandomPort() { unsigned int randp = 0; - Utils::getSecureRandom(&randp,sizeof(randp)); + Utils::getSecureRandom(&randp, sizeof(randp)); randp = 20000 + (randp % 45500); - for(int i=0;;++i) { + for (int i = 0;; ++i) { if (i > 1000) { return 0; - } else if (++randp >= 65536) { + } + else if (++randp >= 65536) { randp = 20000; } if (_trialBind(randp)) @@ -3869,30 +3945,30 @@ public: { struct sockaddr_in in4; struct sockaddr_in6 in6; - PhySocket *tb; + PhySocket* tb; - memset(&in4,0,sizeof(in4)); + memset(&in4, 0, sizeof(in4)); in4.sin_family = AF_INET; in4.sin_port = Utils::hton((uint16_t)port); - tb = _phy.udpBind(reinterpret_cast(&in4),(void *)0,0); + tb = _phy.udpBind(reinterpret_cast(&in4), (void*)0, 0); if (tb) { - _phy.close(tb,false); - tb = _phy.tcpListen(reinterpret_cast(&in4),(void *)0); + _phy.close(tb, false); + tb = _phy.tcpListen(reinterpret_cast(&in4), (void*)0); if (tb) { - _phy.close(tb,false); + _phy.close(tb, false); return true; } } - memset(&in6,0,sizeof(in6)); + memset(&in6, 0, sizeof(in6)); in6.sin6_family = AF_INET6; in6.sin6_port = Utils::hton((uint16_t)port); - tb = _phy.udpBind(reinterpret_cast(&in6),(void *)0,0); + tb = _phy.udpBind(reinterpret_cast(&in6), (void*)0, 0); if (tb) { - _phy.close(tb,false); - tb = _phy.tcpListen(reinterpret_cast(&in6),(void *)0); + _phy.close(tb, false); + tb = _phy.tcpListen(reinterpret_cast(&in6), (void*)0); if (tb) { - _phy.close(tb,false); + _phy.close(tb, false); return true; } } @@ -3901,28 +3977,46 @@ public: } }; -static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) -{ return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,nuptr,op,nwconf); } -static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData) -{ reinterpret_cast(uptr)->nodeEventCallback(event,metaData); } -static void SnodeStatePutFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len) -{ reinterpret_cast(uptr)->nodeStatePutFunction(type,id,data,len); } -static int SnodeStateGetFunction(ZT_Node *node,void *uptr,void *tptr,enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen) -{ return reinterpret_cast(uptr)->nodeStateGetFunction(type,id,data,maxlen); } -static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl) -{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localSocket,addr,data,len,ttl); } -static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) -{ reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,nuptr,sourceMac,destMac,etherType,vlanId,data,len); } -static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int64_t localSocket,const struct sockaddr_storage *remoteAddr) -{ return reinterpret_cast(uptr)->nodePathCheckFunction(ztaddr,localSocket,remoteAddr); } -static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result) -{ return reinterpret_cast(uptr)->nodePathLookupFunction(ztaddr,family,result); } -static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) -{ reinterpret_cast(uptr)->tapFrameHandler(nwid,from,to,etherType,vlanId,data,len); } - -static int ShttpOnMessageBegin(http_parser *parser) +static int SnodeVirtualNetworkConfigFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t nwid, void** nuptr, enum ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig* nwconf) { - TcpConnection *tc = reinterpret_cast(parser->data); + return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid, nuptr, op, nwconf); +} +static void SnodeEventCallback(ZT_Node* node, void* uptr, void* tptr, enum ZT_Event event, const void* metaData) +{ + reinterpret_cast(uptr)->nodeEventCallback(event, metaData); +} +static void SnodeStatePutFunction(ZT_Node* node, void* uptr, void* tptr, enum ZT_StateObjectType type, const uint64_t id[2], const void* data, int len) +{ + reinterpret_cast(uptr)->nodeStatePutFunction(type, id, data, len); +} +static int SnodeStateGetFunction(ZT_Node* node, void* uptr, void* tptr, enum ZT_StateObjectType type, const uint64_t id[2], void* data, unsigned int maxlen) +{ + return reinterpret_cast(uptr)->nodeStateGetFunction(type, id, data, maxlen); +} +static int SnodeWirePacketSendFunction(ZT_Node* node, void* uptr, void* tptr, int64_t localSocket, const struct sockaddr_storage* addr, const void* data, unsigned int len, unsigned int ttl) +{ + return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localSocket, addr, data, len, ttl); +} +static void SnodeVirtualNetworkFrameFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t nwid, void** nuptr, uint64_t sourceMac, uint64_t destMac, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) +{ + reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid, nuptr, sourceMac, destMac, etherType, vlanId, data, len); +} +static int SnodePathCheckFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t ztaddr, int64_t localSocket, const struct sockaddr_storage* remoteAddr) +{ + return reinterpret_cast(uptr)->nodePathCheckFunction(ztaddr, localSocket, remoteAddr); +} +static int SnodePathLookupFunction(ZT_Node* node, void* uptr, void* tptr, uint64_t ztaddr, int family, struct sockaddr_storage* result) +{ + return reinterpret_cast(uptr)->nodePathLookupFunction(ztaddr, family, result); +} +static void StapFrameHandler(void* uptr, void* tptr, uint64_t nwid, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, const void* data, unsigned int len) +{ + reinterpret_cast(uptr)->tapFrameHandler(nwid, from, to, etherType, vlanId, data, len); +} + +static int ShttpOnMessageBegin(http_parser* parser) +{ + TcpConnection* tc = reinterpret_cast(parser->data); tc->currentHeaderField = ""; tc->currentHeaderValue = ""; tc->messageSize = 0; @@ -3932,79 +4026,86 @@ static int ShttpOnMessageBegin(http_parser *parser) tc->readq.clear(); return 0; } -static int ShttpOnUrl(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnUrl(http_parser* parser, const char* ptr, size_t length) { - TcpConnection *tc = reinterpret_cast(parser->data); + TcpConnection* tc = reinterpret_cast(parser->data); tc->messageSize += (unsigned long)length; if (tc->messageSize > ZT_MAX_HTTP_MESSAGE_SIZE) return -1; - tc->url.append(ptr,length); + tc->url.append(ptr, length); return 0; } #if (HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2) -static int ShttpOnStatus(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnStatus(http_parser* parser, const char* ptr, size_t length) #else -static int ShttpOnStatus(http_parser *parser) +static int ShttpOnStatus(http_parser* parser) #endif -{ return 0; } -static int ShttpOnHeaderField(http_parser *parser,const char *ptr,size_t length) { - TcpConnection *tc = reinterpret_cast(parser->data); + return 0; +} +static int ShttpOnHeaderField(http_parser* parser, const char* ptr, size_t length) +{ + TcpConnection* tc = reinterpret_cast(parser->data); tc->messageSize += (unsigned long)length; if (tc->messageSize > ZT_MAX_HTTP_MESSAGE_SIZE) return -1; - if ((tc->currentHeaderField.length())&&(tc->currentHeaderValue.length())) { + if ((tc->currentHeaderField.length()) && (tc->currentHeaderValue.length())) { tc->headers[tc->currentHeaderField] = tc->currentHeaderValue; tc->currentHeaderField = ""; tc->currentHeaderValue = ""; } - for(size_t i=0;icurrentHeaderField.push_back(OSUtils::toLower(ptr[i])); return 0; } -static int ShttpOnValue(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnValue(http_parser* parser, const char* ptr, size_t length) { - TcpConnection *tc = reinterpret_cast(parser->data); + TcpConnection* tc = reinterpret_cast(parser->data); tc->messageSize += (unsigned long)length; if (tc->messageSize > ZT_MAX_HTTP_MESSAGE_SIZE) return -1; - tc->currentHeaderValue.append(ptr,length); + tc->currentHeaderValue.append(ptr, length); return 0; } -static int ShttpOnHeadersComplete(http_parser *parser) +static int ShttpOnHeadersComplete(http_parser* parser) { - TcpConnection *tc = reinterpret_cast(parser->data); - if ((tc->currentHeaderField.length())&&(tc->currentHeaderValue.length())) + TcpConnection* tc = reinterpret_cast(parser->data); + if ((tc->currentHeaderField.length()) && (tc->currentHeaderValue.length())) tc->headers[tc->currentHeaderField] = tc->currentHeaderValue; return 0; } -static int ShttpOnBody(http_parser *parser,const char *ptr,size_t length) +static int ShttpOnBody(http_parser* parser, const char* ptr, size_t length) { - TcpConnection *tc = reinterpret_cast(parser->data); + TcpConnection* tc = reinterpret_cast(parser->data); tc->messageSize += (unsigned long)length; if (tc->messageSize > ZT_MAX_HTTP_MESSAGE_SIZE) return -1; - tc->readq.append(ptr,length); + tc->readq.append(ptr, length); return 0; } -static int ShttpOnMessageComplete(http_parser *parser) +static int ShttpOnMessageComplete(http_parser* parser) { - TcpConnection *tc = reinterpret_cast(parser->data); - if (tc->type == TcpConnection::TCP_HTTP_INCOMING) { - } else { + TcpConnection* tc = reinterpret_cast(parser->data); + if (tc->type == TcpConnection::TCP_HTTP_INCOMING) {} + else { tc->parent->onHttpResponseFromClient(tc); } return 0; } -} // anonymous namespace +} // anonymous namespace std::string OneService::platformDefaultHomePath() { return OSUtils::platformDefaultHomePath(); } -OneService *OneService::newInstance(const char *hp,unsigned int port) { return new OneServiceImpl(hp,port); } -OneService::~OneService() {} +OneService* OneService::newInstance(const char* hp, unsigned int port) +{ + return new OneServiceImpl(hp, port); +} +OneService::~OneService() +{ +} -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/service/OneService.hpp b/service/OneService.hpp index 3f8947ae6..f63c70b26 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -22,7 +22,9 @@ namespace ZeroTier { #ifdef ZT_SDK class VirtualTap; // Use the virtual libzt endpoint instead of a tun/tap port driver -namespace ZeroTier { typedef VirtualTap EthernetTap; } +namespace ZeroTier { +typedef VirtualTap EthernetTap; +} #endif // Forward declaration so we can avoid dragging everything in @@ -32,14 +34,12 @@ class Node; /** * Local service for ZeroTier One as system VPN/NFV provider */ -class OneService -{ -public: +class OneService { + public: /** * Returned by node main if/when it terminates */ - enum ReasonForTermination - { + enum ReasonForTermination { /** * Instance is still running */ @@ -64,8 +64,7 @@ public: /** * Local settings for each network */ - struct NetworkSettings - { + struct NetworkSettings { /** * Allow this network to configure IP addresses and routes? */ @@ -111,7 +110,7 @@ public: * @param hp Home path * @param port TCP and UDP port for packets and HTTP control (if 0, pick random port) */ - static OneService *newInstance(const char *hp,unsigned int port); + static OneService* newInstance(const char* hp, unsigned int port); virtual ~OneService(); @@ -147,11 +146,11 @@ public: /** * @return Reference to the Node */ - virtual Node * getNode() = 0; + virtual Node* getNode() = 0; /** * Fills out a structure with network-specific route information */ - virtual void getRoutes(uint64_t nwid, void *routeArray, unsigned int *numRoutes) = 0; + virtual void getRoutes(uint64_t nwid, void* routeArray, unsigned int* numRoutes) = 0; #endif /** @@ -166,7 +165,7 @@ public: * @param settings Buffer to fill with local network settings * @return True if network was found and settings is filled */ - virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const = 0; + virtual bool getNetworkSettings(const uint64_t nwid, NetworkSettings& settings) const = 0; /** * Set local settings for a network @@ -175,21 +174,31 @@ public: * @param settings New network local settings * @return True if network was found and setting modified */ - virtual bool setNetworkSettings(const uint64_t nwid,const NetworkSettings &settings) = 0; + virtual bool setNetworkSettings(const uint64_t nwid, const NetworkSettings& settings) = 0; /** * @return True if service is still running */ - inline bool isRunning() const { return (this->reasonForTermination() == ONE_STILL_RUNNING); } + inline bool isRunning() const + { + return (this->reasonForTermination() == ONE_STILL_RUNNING); + } -protected: - OneService() {} + protected: + OneService() + { + } -private: - OneService(const OneService &one) {} - inline OneService &operator=(const OneService &one) { return *this; } + private: + OneService(const OneService& one) + { + } + inline OneService& operator=(const OneService& one) + { + return *this; + } }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/service/SoftwareUpdater.cpp b/service/SoftwareUpdater.cpp index 8335e3894..978370f68 100644 --- a/service/SoftwareUpdater.cpp +++ b/service/SoftwareUpdater.cpp @@ -11,61 +11,67 @@ */ /****/ -#include -#include -#include -#include - #include "../node/Constants.hpp" #include "../version.h" +#include +#include +#include +#include + #ifdef __WINDOWS__ -#include -#include -#include -#include #include +#include +#include +#include +#include #else -#include +#include #include +#include #include #include -#include #endif -#include "SoftwareUpdater.hpp" - -#include "../node/Utils.hpp" -#include "../node/SHA512.hpp" #include "../node/Buffer.hpp" #include "../node/Node.hpp" - +#include "../node/SHA512.hpp" +#include "../node/Utils.hpp" #include "../osdep/OSUtils.hpp" +#include "SoftwareUpdater.hpp" namespace ZeroTier { -static int _compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1,unsigned int b1,unsigned int maj2,unsigned int min2,unsigned int rev2,unsigned int b2) +static int _compareVersion(unsigned int maj1, unsigned int min1, unsigned int rev1, unsigned int b1, unsigned int maj2, unsigned int min2, unsigned int rev2, unsigned int b2) { if (maj1 > maj2) { return 1; - } else if (maj1 < maj2) { + } + else if (maj1 < maj2) { return -1; - } else { + } + else { if (min1 > min2) { return 1; - } else if (min1 < min2) { + } + else if (min1 < min2) { return -1; - } else { + } + else { if (rev1 > rev2) { return 1; - } else if (rev1 < rev2) { + } + else if (rev1 < rev2) { return -1; - } else { + } + else { if (b1 > b2) { return 1; - } else if (b1 < b2) { + } + else if (b1 < b2) { return -1; - } else { + } + else { return 0; } } @@ -73,14 +79,7 @@ static int _compareVersion(unsigned int maj1,unsigned int min1,unsigned int rev1 } } -SoftwareUpdater::SoftwareUpdater(Node &node,const std::string &homePath) : - _node(node), - _lastCheckTime(0), - _homePath(homePath), - _channel(ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL), - _distLog((FILE *)0), - _latestValid(false), - _downloadLength(0) +SoftwareUpdater::SoftwareUpdater(Node& node, const std::string& homePath) : _node(node), _lastCheckTime(0), _homePath(homePath), _channel(ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL), _distLog((FILE*)0), _latestValid(false), _downloadLength(0) { OSUtils::rm((_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME).c_str()); } @@ -95,100 +94,99 @@ void SoftwareUpdater::setUpdateDistribution(bool distribute) { _dist.clear(); if (distribute) { - _distLog = fopen((_homePath + ZT_PATH_SEPARATOR_S "update-dist.log").c_str(),"a"); + _distLog = fopen((_homePath + ZT_PATH_SEPARATOR_S "update-dist.log").c_str(), "a"); const std::string udd(_homePath + ZT_PATH_SEPARATOR_S "update-dist.d"); const std::vector ud(OSUtils::listDirectory(udd.c_str())); - for(std::vector::const_iterator u(ud.begin());u!=ud.end();++u) { + for (std::vector::const_iterator u(ud.begin()); u != ud.end(); ++u) { // Each update has a companion .json file describing it. Other files are ignored. - if ((u->length() > 5)&&(u->substr(u->length() - 5,5) == ".json")) { - + if ((u->length() > 5) && (u->substr(u->length() - 5, 5) == ".json")) { std::string buf; - if (OSUtils::readFile((udd + ZT_PATH_SEPARATOR_S + *u).c_str(),buf)) { + if (OSUtils::readFile((udd + ZT_PATH_SEPARATOR_S + *u).c_str(), buf)) { try { _D d; - d.meta = OSUtils::jsonParse(buf); // throws on invalid JSON + d.meta = OSUtils::jsonParse(buf); // throws on invalid JSON // If update meta is called e.g. foo.exe.json, then foo.exe is the update itself - const std::string binPath(udd + ZT_PATH_SEPARATOR_S + u->substr(0,u->length() - 5)); + const std::string binPath(udd + ZT_PATH_SEPARATOR_S + u->substr(0, u->length() - 5)); const std::string metaHash(OSUtils::jsonBinFromHex(d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH])); - if ((metaHash.length() == 64)&&(OSUtils::readFile(binPath.c_str(),d.bin))) { - std::array sha512; - SHA512(sha512.data(),d.bin.data(),(unsigned int)d.bin.length()); - if (!memcmp(sha512.data(),metaHash.data(),64)) { // double check that hash in JSON is correct - d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE] = d.bin.length(); // override with correct value -- setting this in meta json is optional - std::array shakey; - memcpy(shakey.data(),sha512.data(),16); + if ((metaHash.length() == 64) && (OSUtils::readFile(binPath.c_str(), d.bin))) { + std::array sha512; + SHA512(sha512.data(), d.bin.data(), (unsigned int)d.bin.length()); + if (! memcmp(sha512.data(), metaHash.data(), 64)) { // double check that hash in JSON is correct + d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE] = d.bin.length(); // override with correct value -- setting this in meta json is optional + std::array shakey; + memcpy(shakey.data(), sha512.data(), 16); _dist[shakey] = d; if (_distLog) { - fprintf(_distLog,".......... INIT: DISTRIBUTING %s (%u bytes)" ZT_EOL_S,binPath.c_str(),(unsigned int)d.bin.length()); + fprintf(_distLog, ".......... INIT: DISTRIBUTING %s (%u bytes)" ZT_EOL_S, binPath.c_str(), (unsigned int)d.bin.length()); fflush(_distLog); } } } - } catch ( ... ) {} // ignore bad meta JSON, etc. + } + catch (...) { + } // ignore bad meta JSON, etc. } - } } - } else { + } + else { if (_distLog) { fclose(_distLog); - _distLog = (FILE *)0; + _distLog = (FILE*)0; } } } -void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void *data,unsigned int len) +void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin, const void* data, unsigned int len) { - if (!len) return; - const MessageVerb v = (MessageVerb)reinterpret_cast(data)[0]; + if (! len) + return; + const MessageVerb v = (MessageVerb) reinterpret_cast(data)[0]; try { - switch(v) { - + switch (v) { case VERB_GET_LATEST: case VERB_LATEST: { - nlohmann::json req = OSUtils::jsonParse(std::string(reinterpret_cast(data) + 1,len - 1)); // throws on invalid JSON + nlohmann::json req = OSUtils::jsonParse(std::string(reinterpret_cast(data) + 1, len - 1)); // throws on invalid JSON if (req.is_object()) { - const unsigned int rvMaj = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR],0); - const unsigned int rvMin = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR],0); - const unsigned int rvRev = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION],0); - const unsigned int rvBld = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD],0); - const unsigned int rvPlatform = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_PLATFORM],0); - const unsigned int rvArch = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE],0); - const unsigned int rvVendor = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VENDOR],0); - const std::string rvChannel(OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_CHANNEL],"")); + const unsigned int rvMaj = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR], 0); + const unsigned int rvMin = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR], 0); + const unsigned int rvRev = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION], 0); + const unsigned int rvBld = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD], 0); + const unsigned int rvPlatform = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_PLATFORM], 0); + const unsigned int rvArch = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE], 0); + const unsigned int rvVendor = (unsigned int)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_VENDOR], 0); + const std::string rvChannel(OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_CHANNEL], "")); if (v == VERB_GET_LATEST) { - - if (!_dist.empty()) { - const nlohmann::json *latest = (const nlohmann::json *)0; - const std::string expectedSigner = OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_EXPECT_SIGNED_BY],""); + if (! _dist.empty()) { + const nlohmann::json* latest = (const nlohmann::json*)0; + const std::string expectedSigner = OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_EXPECT_SIGNED_BY], ""); unsigned int bestVMaj = rvMaj; unsigned int bestVMin = rvMin; unsigned int bestVRev = rvRev; unsigned int bestVBld = rvBld; - for(std::map< std::array,_D >::const_iterator d(_dist.begin());d!=_dist.end();++d) { + for (std::map, _D>::const_iterator d(_dist.begin()); d != _dist.end(); ++d) { // The arch field in update description .json files can be an array for e.g. multi-arch update files - const nlohmann::json &dvArch2 = d->second.meta[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE]; + const nlohmann::json& dvArch2 = d->second.meta[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE]; std::vector dvArch; if (dvArch2.is_array()) { - for(unsigned long i=0;isecond.meta[ZT_SOFTWARE_UPDATE_JSON_PLATFORM],0) == rvPlatform)&& - (std::find(dvArch.begin(),dvArch.end(),rvArch) != dvArch.end())&& - (OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VENDOR],0) == rvVendor)&& - (OSUtils::jsonString(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_CHANNEL],"") == rvChannel)&& - (OSUtils::jsonString(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNED_BY],"") == expectedSigner)) { - const unsigned int dvMaj = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR],0); - const unsigned int dvMin = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR],0); - const unsigned int dvRev = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION],0); - const unsigned int dvBld = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD],0); - if (_compareVersion(dvMaj,dvMin,dvRev,dvBld,bestVMaj,bestVMin,bestVRev,bestVBld) > 0) { + if ((OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_PLATFORM], 0) == rvPlatform) && (std::find(dvArch.begin(), dvArch.end(), rvArch) != dvArch.end()) + && (OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VENDOR], 0) == rvVendor) && (OSUtils::jsonString(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_CHANNEL], "") == rvChannel) + && (OSUtils::jsonString(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNED_BY], "") == expectedSigner)) { + const unsigned int dvMaj = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR], 0); + const unsigned int dvMin = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR], 0); + const unsigned int dvRev = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION], 0); + const unsigned int dvBld = (unsigned int)OSUtils::jsonInt(d->second.meta[ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD], 0); + if (_compareVersion(dvMaj, dvMin, dvRev, dvBld, bestVMaj, bestVMin, bestVRev, bestVBld) > 0) { latest = &(d->second.meta); bestVMaj = dvMaj; bestVMin = dvMin; @@ -201,79 +199,92 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void std::string lj; lj.push_back((char)VERB_LATEST); lj.append(OSUtils::jsonDump(*latest)); - _node.sendUserMessage((void *)0,origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,lj.data(),(unsigned int)lj.length()); + _node.sendUserMessage((void*)0, origin, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, lj.data(), (unsigned int)lj.length()); if (_distLog) { - fprintf(_distLog,"%.10llx GET_LATEST %u.%u.%u_%u platform %u arch %u vendor %u channel %s -> LATEST %u.%u.%u_%u" ZT_EOL_S,(unsigned long long)origin,rvMaj,rvMin,rvRev,rvBld,rvPlatform,rvArch,rvVendor,rvChannel.c_str(),bestVMaj,bestVMin,bestVRev,bestVBld); + fprintf( + _distLog, + "%.10llx GET_LATEST %u.%u.%u_%u platform %u arch %u vendor %u channel %s -> LATEST %u.%u.%u_%u" ZT_EOL_S, + (unsigned long long)origin, + rvMaj, + rvMin, + rvRev, + rvBld, + rvPlatform, + rvArch, + rvVendor, + rvChannel.c_str(), + bestVMaj, + bestVMin, + bestVRev, + bestVBld); fflush(_distLog); } } - } // else no reply, since we have nothing to distribute + } // else no reply, since we have nothing to distribute + } + else { // VERB_LATEST - } else { // VERB_LATEST - - if ((origin == ZT_SOFTWARE_UPDATE_SERVICE)&& - (_compareVersion(rvMaj,rvMin,rvRev,rvBld,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION,ZEROTIER_ONE_VERSION_BUILD) > 0)&& - (OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNED_BY],"") == ZT_SOFTWARE_UPDATE_SIGNING_AUTHORITY)) { - const unsigned long len = (unsigned long)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE],0); + if ((origin == ZT_SOFTWARE_UPDATE_SERVICE) && (_compareVersion(rvMaj, rvMin, rvRev, rvBld, ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION, ZEROTIER_ONE_VERSION_BUILD) > 0) + && (OSUtils::jsonString(req[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNED_BY], "") == ZT_SOFTWARE_UPDATE_SIGNING_AUTHORITY)) { + const unsigned long len = (unsigned long)OSUtils::jsonInt(req[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE], 0); const std::string hash = OSUtils::jsonBinFromHex(req[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH]); - if ((len <= ZT_SOFTWARE_UPDATE_MAX_SIZE)&&(hash.length() >= 16)) { + if ((len <= ZT_SOFTWARE_UPDATE_MAX_SIZE) && (hash.length() >= 16)) { if (_latestMeta != req) { _latestMeta = req; _latestValid = false; OSUtils::rm((_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME).c_str()); _download = std::string(); - memcpy(_downloadHashPrefix.data(),hash.data(),16); + memcpy(_downloadHashPrefix.data(), hash.data(), 16); _downloadLength = len; } - if ((_downloadLength > 0)&&(_download.length() < _downloadLength)) { + if ((_downloadLength > 0) && (_download.length() < _downloadLength)) { Buffer<128> gd; gd.append((uint8_t)VERB_GET_DATA); - gd.append(_downloadHashPrefix.data(),16); + gd.append(_downloadHashPrefix.data(), 16); gd.append((uint32_t)_download.length()); - _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); + _node.sendUserMessage((void*)0, ZT_SOFTWARE_UPDATE_SERVICE, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, gd.data(), gd.size()); } } } } - } - } break; + } break; case VERB_GET_DATA: - if ((len >= 21)&&(!_dist.empty())) { - unsigned long idx = (unsigned long)*(reinterpret_cast(data) + 17) << 24; - idx |= (unsigned long)*(reinterpret_cast(data) + 18) << 16; - idx |= (unsigned long)*(reinterpret_cast(data) + 19) << 8; - idx |= (unsigned long)*(reinterpret_cast(data) + 20); - std::array shakey; - memcpy(shakey.data(),reinterpret_cast(data) + 1,16); - std::map< std::array,_D >::iterator d(_dist.find(shakey)); - if ((d != _dist.end())&&(idx < (unsigned long)d->second.bin.length())) { + if ((len >= 21) && (! _dist.empty())) { + unsigned long idx = (unsigned long)*(reinterpret_cast(data) + 17) << 24; + idx |= (unsigned long)*(reinterpret_cast(data) + 18) << 16; + idx |= (unsigned long)*(reinterpret_cast(data) + 19) << 8; + idx |= (unsigned long)*(reinterpret_cast(data) + 20); + std::array shakey; + memcpy(shakey.data(), reinterpret_cast(data) + 1, 16); + std::map, _D>::iterator d(_dist.find(shakey)); + if ((d != _dist.end()) && (idx < (unsigned long)d->second.bin.length())) { Buffer buf; buf.append((uint8_t)VERB_DATA); - buf.append(reinterpret_cast(data) + 1,16); + buf.append(reinterpret_cast(data) + 1, 16); buf.append((uint32_t)idx); - buf.append(d->second.bin.data() + idx,std::min((unsigned long)ZT_SOFTWARE_UPDATE_CHUNK_SIZE,(unsigned long)(d->second.bin.length() - idx))); - _node.sendUserMessage((void *)0,origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,buf.data(),buf.size()); + buf.append(d->second.bin.data() + idx, std::min((unsigned long)ZT_SOFTWARE_UPDATE_CHUNK_SIZE, (unsigned long)(d->second.bin.length() - idx))); + _node.sendUserMessage((void*)0, origin, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, buf.data(), buf.size()); } } break; case VERB_DATA: - if ((len >= 21)&&(_downloadLength > 0)&&(!memcmp(_downloadHashPrefix.data(),reinterpret_cast(data) + 1,16))) { - unsigned long idx = (unsigned long)*(reinterpret_cast(data) + 17) << 24; - idx |= (unsigned long)*(reinterpret_cast(data) + 18) << 16; - idx |= (unsigned long)*(reinterpret_cast(data) + 19) << 8; - idx |= (unsigned long)*(reinterpret_cast(data) + 20); + if ((len >= 21) && (_downloadLength > 0) && (! memcmp(_downloadHashPrefix.data(), reinterpret_cast(data) + 1, 16))) { + unsigned long idx = (unsigned long)*(reinterpret_cast(data) + 17) << 24; + idx |= (unsigned long)*(reinterpret_cast(data) + 18) << 16; + idx |= (unsigned long)*(reinterpret_cast(data) + 19) << 8; + idx |= (unsigned long)*(reinterpret_cast(data) + 20); if (idx == (unsigned long)_download.length()) { - _download.append(reinterpret_cast(data) + 21,len - 21); + _download.append(reinterpret_cast(data) + 21, len - 21); if (_download.length() < _downloadLength) { Buffer<128> gd; gd.append((uint8_t)VERB_GET_DATA); - gd.append(_downloadHashPrefix.data(),16); + gd.append(_downloadHashPrefix.data(), 16); gd.append((uint32_t)_download.length()); - _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); + _node.sendUserMessage((void*)0, ZT_SOFTWARE_UPDATE_SERVICE, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, gd.data(), gd.size()); } } } @@ -281,14 +292,15 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void default: if (_distLog) { - fprintf(_distLog,"%.10llx WARNING: bad update message verb==%u length==%u (unrecognized verb)" ZT_EOL_S,(unsigned long long)origin,(unsigned int)v,len); + fprintf(_distLog, "%.10llx WARNING: bad update message verb==%u length==%u (unrecognized verb)" ZT_EOL_S, (unsigned long long)origin, (unsigned int)v, len); fflush(_distLog); } break; } - } catch ( ... ) { + } + catch (...) { if (_distLog) { - fprintf(_distLog,"%.10llx WARNING: bad update message verb==%u length==%u (unexpected exception, likely invalid JSON)" ZT_EOL_S,(unsigned long long)origin,(unsigned int)v,len); + fprintf(_distLog, "%.10llx WARNING: bad update message verb==%u length==%u (unexpected exception, likely invalid JSON)" ZT_EOL_S, (unsigned long long)origin, (unsigned int)v, len); fflush(_distLog); } } @@ -299,7 +311,9 @@ bool SoftwareUpdater::check(const int64_t now) if ((now - _lastCheckTime) >= ZT_SOFTWARE_UPDATE_CHECK_PERIOD) { _lastCheckTime = now; char tmp[512]; - const unsigned int len = OSUtils::ztsnprintf(tmp,sizeof(tmp), + const unsigned int len = OSUtils::ztsnprintf( + tmp, + sizeof(tmp), "%c{\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR "\":%d," "\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR "\":%d," "\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION "\":%d," @@ -319,7 +333,7 @@ bool SoftwareUpdater::check(const int64_t now) ZT_BUILD_ARCHITECTURE, (int)ZT_VENDOR_ZEROTIER, _channel.c_str()); - _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,tmp,len); + _node.sendUserMessage((void*)0, ZT_SOFTWARE_UPDATE_SERVICE, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, tmp, len); } if (_latestValid) @@ -334,16 +348,16 @@ bool SoftwareUpdater::check(const int64_t now) try { // (1) Check the hash itself to make sure the image is basically okay uint8_t sha512[64]; - SHA512(sha512,_download.data(),(unsigned int)_download.length()); + SHA512(sha512, _download.data(), (unsigned int)_download.length()); char hexbuf[(64 * 2) + 2]; - if (OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH],"") == Utils::hex(sha512,64,hexbuf)) { + if (OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH], "") == Utils::hex(sha512, 64, hexbuf)) { // (2) Check signature by signing authority const std::string sig(OSUtils::jsonBinFromHex(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNATURE])); - if (Identity(ZT_SOFTWARE_UPDATE_SIGNING_AUTHORITY).verify(_download.data(),(unsigned int)_download.length(),sig.data(),(unsigned int)sig.length())) { + if (Identity(ZT_SOFTWARE_UPDATE_SIGNING_AUTHORITY).verify(_download.data(), (unsigned int)_download.length(), sig.data(), (unsigned int)sig.length())) { // (3) Try to save file, and if so we are good. OSUtils::rm(binPath.c_str()); - if (OSUtils::writeFile(binPath.c_str(),_download)) { - OSUtils::lockDownFile(binPath.c_str(),false); + if (OSUtils::writeFile(binPath.c_str(), _download)) { + OSUtils::lockDownFile(binPath.c_str(), false); _latestValid = true; _download = std::string(); _downloadLength = 0; @@ -351,7 +365,9 @@ bool SoftwareUpdater::check(const int64_t now) } } } - } catch ( ... ) {} // any exception equals verification failure + } + catch (...) { + } // any exception equals verification failure // If we get here, checks failed. OSUtils::rm(binPath.c_str()); @@ -359,12 +375,13 @@ bool SoftwareUpdater::check(const int64_t now) _latestValid = false; _download = std::string(); _downloadLength = 0; - } else { + } + else { Buffer<128> gd; gd.append((uint8_t)VERB_GET_DATA); - gd.append(_downloadHashPrefix.data(),16); + gd.append(_downloadHashPrefix.data(), 16); gd.append((uint32_t)_download.length()); - _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); + _node.sendUserMessage((void*)0, ZT_SOFTWARE_UPDATE_SERVICE, ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE, gd.data(), gd.size()); } } @@ -374,37 +391,40 @@ bool SoftwareUpdater::check(const int64_t now) void SoftwareUpdater::apply() { std::string updatePath(_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME); - if ((_latestMeta.is_object())&&(_latestValid)&&(OSUtils::fileExists(updatePath.c_str(),false))) { + if ((_latestMeta.is_object()) && (_latestValid) && (OSUtils::fileExists(updatePath.c_str(), false))) { #ifdef __WINDOWS__ - std::string cmdArgs(OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_EXEC_ARGS],"")); + std::string cmdArgs(OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_EXEC_ARGS], "")); if (cmdArgs.length() > 0) { updatePath.push_back(' '); updatePath.append(cmdArgs); } STARTUPINFOA si; PROCESS_INFORMATION pi; - memset(&si,0,sizeof(si)); - memset(&pi,0,sizeof(pi)); - CreateProcessA(NULL,const_cast(updatePath.c_str()),NULL,NULL,FALSE,CREATE_NO_WINDOW|CREATE_NEW_PROCESS_GROUP,NULL,NULL,&si,&pi); + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + CreateProcessA(NULL, const_cast(updatePath.c_str()), NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi); // Windows doesn't exit here -- updater will stop the service during update, etc. -- but we do want to stop multiple runs from happening _latestMeta = nlohmann::json(); _latestValid = false; #else - char *argv[256]; + char* argv[256]; unsigned long ac = 0; - argv[ac++] = const_cast(updatePath.c_str()); - const std::vector argsSplit(OSUtils::split(OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_EXEC_ARGS],"").c_str()," ","\\","\"")); - for(std::vector::const_iterator a(argsSplit.begin());a!=argsSplit.end();++a) { - argv[ac] = const_cast(a->c_str()); - if (++ac == 255) break; + argv[ac++] = const_cast(updatePath.c_str()); + const std::vector argsSplit(OSUtils::split(OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_EXEC_ARGS], "").c_str(), " ", "\\", "\"")); + for (std::vector::const_iterator a(argsSplit.begin()); a != argsSplit.end(); ++a) { + argv[ac] = const_cast(a->c_str()); + if (++ac == 255) + break; } - argv[ac] = (char *)0; - chmod(updatePath.c_str(),0700); + argv[ac] = (char*)0; + chmod(updatePath.c_str(), 0700); // Close all open file descriptors except stdout/stderr/etc. int minMyFd = STDIN_FILENO; - if (STDOUT_FILENO > minMyFd) minMyFd = STDOUT_FILENO; - if (STDERR_FILENO > minMyFd) minMyFd = STDERR_FILENO; + if (STDOUT_FILENO > minMyFd) + minMyFd = STDOUT_FILENO; + if (STDERR_FILENO > minMyFd) + minMyFd = STDERR_FILENO; ++minMyFd; #ifdef _SC_OPEN_MAX int maxMyFd = (int)sysconf(_SC_OPEN_MAX); @@ -416,11 +436,11 @@ void SoftwareUpdater::apply() while (minMyFd < maxMyFd) close(minMyFd++); - execv(updatePath.c_str(),argv); - fprintf(stderr,"FATAL: unable to execute software update binary at %s\n",updatePath.c_str()); + execv(updatePath.c_str(), argv); + fprintf(stderr, "FATAL: unable to execute software update binary at %s\n", updatePath.c_str()); exit(1); #endif } } -} // namespace ZeroTier +} // namespace ZeroTier diff --git a/service/SoftwareUpdater.hpp b/service/SoftwareUpdater.hpp index 59e62d5b6..18539af44 100644 --- a/service/SoftwareUpdater.hpp +++ b/service/SoftwareUpdater.hpp @@ -14,20 +14,17 @@ #ifndef ZT_SOFTWAREUPDATER_HPP #define ZT_SOFTWAREUPDATER_HPP -#include -#include - -#include -#include -#include -#include - #include "../include/ZeroTierOne.h" - #include "../node/Identity.hpp" #include "../node/Packet.hpp" +#include +#include #include +#include +#include +#include +#include /** * VERB_USER_MESSAGE type ID for software update messages @@ -71,21 +68,21 @@ */ #define ZT_SOFTWARE_UPDATE_BIN_FILENAME "latest-update.exe" -#define ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR "vMajor" -#define ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR "vMinor" +#define ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR "vMajor" +#define ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR "vMinor" #define ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION "vRev" -#define ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD "vBuild" -#define ZT_SOFTWARE_UPDATE_JSON_PLATFORM "platform" -#define ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE "arch" -#define ZT_SOFTWARE_UPDATE_JSON_VENDOR "vendor" -#define ZT_SOFTWARE_UPDATE_JSON_CHANNEL "channel" +#define ZT_SOFTWARE_UPDATE_JSON_VERSION_BUILD "vBuild" +#define ZT_SOFTWARE_UPDATE_JSON_PLATFORM "platform" +#define ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE "arch" +#define ZT_SOFTWARE_UPDATE_JSON_VENDOR "vendor" +#define ZT_SOFTWARE_UPDATE_JSON_CHANNEL "channel" #define ZT_SOFTWARE_UPDATE_JSON_EXPECT_SIGNED_BY "expectedSigner" #define ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNED_BY "signer" #define ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNATURE "signature" -#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH "hash" -#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE "size" +#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH "hash" +#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE "size" #define ZT_SOFTWARE_UPDATE_JSON_UPDATE_EXEC_ARGS "execArgs" -#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_URL "url" +#define ZT_SOFTWARE_UPDATE_JSON_UPDATE_URL "url" namespace ZeroTier { @@ -94,14 +91,12 @@ class Node; /** * This class handles retrieving and executing updates, or serving them */ -class SoftwareUpdater -{ -public: +class SoftwareUpdater { + public: /** * Each message begins with an 8-bit message verb */ - enum MessageVerb - { + enum MessageVerb { /** * Payload: JSON containing current system platform, version, etc. */ @@ -128,7 +123,7 @@ public: VERB_DATA = 4 }; - SoftwareUpdater(Node &node,const std::string &homePath); + SoftwareUpdater(Node& node, const std::string& homePath); ~SoftwareUpdater(); /** @@ -145,7 +140,7 @@ public: * @param data Message payload * @param len Length of message */ - void handleSoftwareUpdateUserMessage(uint64_t origin,const void *data,unsigned int len); + void handleSoftwareUpdateUserMessage(uint64_t origin, const void* data, unsigned int len); /** * Check for updates and do other update-related housekeeping @@ -159,7 +154,10 @@ public: /** * @return Meta-data for downloaded update or NULL if none */ - inline const nlohmann::json &pending() const { return _latestMeta; } + inline const nlohmann::json& pending() const + { + return _latestMeta; + } /** * Apply any ready update now @@ -174,31 +172,33 @@ public: * * @param channel 'release', 'beta', etc. */ - inline void setChannel(const std::string &channel) { _channel = channel; } + inline void setChannel(const std::string& channel) + { + _channel = channel; + } -private: - Node &_node; + private: + Node& _node; uint64_t _lastCheckTime; std::string _homePath; std::string _channel; - FILE *_distLog; + FILE* _distLog; // Offered software updates if we are an update host (we have update-dist.d and update hosting is enabled) - struct _D - { + struct _D { nlohmann::json meta; std::string bin; }; - std::map< std::array,_D > _dist; // key is first 16 bytes of hash + std::map, _D> _dist; // key is first 16 bytes of hash nlohmann::json _latestMeta; bool _latestValid; std::string _download; - std::array _downloadHashPrefix; + std::array _downloadHashPrefix; unsigned long _downloadLength; }; -} // namespace ZeroTier +} // namespace ZeroTier #endif diff --git a/tcp-proxy/tcp-proxy.cpp b/tcp-proxy/tcp-proxy.cpp index 44bc5eab0..f763306d6 100644 --- a/tcp-proxy/tcp-proxy.cpp +++ b/tcp-proxy/tcp-proxy.cpp @@ -19,34 +19,32 @@ // HACK! Will eventually use epoll() or something in Phy<> instead of select(). // Also be sure to change ulimit -n and fs.file-max in /etc/sysctl.conf on relays. #if defined(__linux__) || defined(__LINUX__) || defined(__LINUX) || defined(LINUX) -#include #include +#include #undef __FD_SETSIZE #define __FD_SETSIZE 1048576 #undef FD_SETSIZE #define FD_SETSIZE 1048576 #endif +#include "../node/Metrics.hpp" +#include "../osdep/Phy.hpp" + +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include - -#include -#include #include -#include +#include +#include #include -#include "../osdep/Phy.hpp" - -#include "../node/Metrics.hpp" - #define ZT_TCP_PROXY_CONNECTION_TIMEOUT_SECONDS 300 -#define ZT_TCP_PROXY_TCP_PORT 443 +#define ZT_TCP_PROXY_TCP_PORT 443 using namespace ZeroTier; @@ -88,89 +86,87 @@ using namespace ZeroTier; */ struct TcpProxyService; -struct TcpProxyService -{ - Phy *phy; +struct TcpProxyService { + Phy* phy; int udpPortCounter; - struct Client - { + struct Client { char tcpReadBuf[131072]; char tcpWriteBuf[131072]; unsigned long tcpWritePtr; unsigned long tcpReadPtr; - PhySocket *tcp; - PhySocket *udp; + PhySocket* tcp; + PhySocket* udp; time_t lastActivity; bool newVersion; }; - std::map< PhySocket *,Client > clients; + std::map clients; - PhySocket *getUnusedUdp(void *uptr) + PhySocket* getUnusedUdp(void* uptr) { - for(int i=0;i<65535;++i) { + for (int i = 0; i < 65535; ++i) { ++udpPortCounter; if (udpPortCounter > 0xfffe) udpPortCounter = 1024; struct sockaddr_in laddr; - memset(&laddr,0,sizeof(struct sockaddr_in)); + memset(&laddr, 0, sizeof(struct sockaddr_in)); laddr.sin_family = AF_INET; laddr.sin_port = htons((uint16_t)udpPortCounter); - PhySocket *udp = phy->udpBind(reinterpret_cast(&laddr),uptr); + PhySocket* udp = phy->udpBind(reinterpret_cast(&laddr), uptr); if (udp) return udp; } - return (PhySocket *)0; + return (PhySocket*)0; } - void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) + void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len) { - if (!*uptr) + if (! *uptr) return; - if ((from->sa_family == AF_INET)&&(len >= 16)&&(len < 2048)) { - Client &c = *((Client *)*uptr); - c.lastActivity = time((time_t *)0); + if ((from->sa_family == AF_INET) && (len >= 16) && (len < 2048)) { + Client& c = *((Client*)*uptr); + c.lastActivity = time((time_t*)0); unsigned long mlen = len; if (c.newVersion) - mlen += 7; // new clients get IP info + mlen += 7; // new clients get IP info if ((c.tcpWritePtr + 5 + mlen) <= sizeof(c.tcpWriteBuf)) { - if (!c.tcpWritePtr) - phy->setNotifyWritable(c.tcp,true); + if (! c.tcpWritePtr) + phy->setNotifyWritable(c.tcp, true); - c.tcpWriteBuf[c.tcpWritePtr++] = 0x17; // look like TLS data - c.tcpWriteBuf[c.tcpWritePtr++] = 0x03; // look like TLS 1.2 - c.tcpWriteBuf[c.tcpWritePtr++] = 0x03; // look like TLS 1.2 + c.tcpWriteBuf[c.tcpWritePtr++] = 0x17; // look like TLS data + c.tcpWriteBuf[c.tcpWritePtr++] = 0x03; // look like TLS 1.2 + c.tcpWriteBuf[c.tcpWritePtr++] = 0x03; // look like TLS 1.2 c.tcpWriteBuf[c.tcpWritePtr++] = (char)((mlen >> 8) & 0xff); c.tcpWriteBuf[c.tcpWritePtr++] = (char)(mlen & 0xff); if (c.newVersion) { - c.tcpWriteBuf[c.tcpWritePtr++] = (char)4; // IPv4 - *((uint32_t *)(c.tcpWriteBuf + c.tcpWritePtr)) = ((const struct sockaddr_in *)from)->sin_addr.s_addr; + c.tcpWriteBuf[c.tcpWritePtr++] = (char)4; // IPv4 + *((uint32_t*)(c.tcpWriteBuf + c.tcpWritePtr)) = ((const struct sockaddr_in*)from)->sin_addr.s_addr; c.tcpWritePtr += 4; - *((uint16_t *)(c.tcpWriteBuf + c.tcpWritePtr)) = ((const struct sockaddr_in *)from)->sin_port; + *((uint16_t*)(c.tcpWriteBuf + c.tcpWritePtr)) = ((const struct sockaddr_in*)from)->sin_port; c.tcpWritePtr += 2; } - for(unsigned long i=0;i %.16llx\n",inet_ntoa(reinterpret_cast(from)->sin_addr),(int)ntohs(reinterpret_cast(from)->sin_port),(unsigned long long)&c); + printf("<< UDP %s:%d -> %.16llx\n", inet_ntoa(reinterpret_cast(from)->sin_addr), (int)ntohs(reinterpret_cast(from)->sin_port), (unsigned long long)&c); } } - void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) + void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success) { // unused, we don't initiate outbound connections } - void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) + void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from) { - Client &c = clients[sockN]; - PhySocket *udp = getUnusedUdp((void *)&c); - if (!udp) { + Client& c = clients[sockN]; + PhySocket* udp = getUnusedUdp((void*)&c); + if (! udp) { phy->close(sockN); clients.erase(sockN); printf("** TCP rejected, no more UDP ports to assign\n"); @@ -180,135 +176,139 @@ struct TcpProxyService c.tcpReadPtr = 0; c.tcp = sockN; c.udp = udp; - c.lastActivity = time((time_t *)0); + c.lastActivity = time((time_t*)0); c.newVersion = false; - *uptrN = (void *)&c; - printf("<< TCP from %s -> %.16llx\n",inet_ntoa(reinterpret_cast(from)->sin_addr),(unsigned long long)&c); + *uptrN = (void*)&c; + printf("<< TCP from %s -> %.16llx\n", inet_ntoa(reinterpret_cast(from)->sin_addr), (unsigned long long)&c); } - void phyOnTcpClose(PhySocket *sock,void **uptr) + void phyOnTcpClose(PhySocket* sock, void** uptr) { - if (!*uptr) + if (! *uptr) return; - Client &c = *((Client *)*uptr); + Client& c = *((Client*)*uptr); phy->close(c.udp); clients.erase(sock); - printf("** TCP %.16llx closed\n",(unsigned long long)*uptr); + printf("** TCP %.16llx closed\n", (unsigned long long)*uptr); } - void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) + void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len) { - Client &c = *((Client *)*uptr); - c.lastActivity = time((time_t *)0); + Client& c = *((Client*)*uptr); + c.lastActivity = time((time_t*)0); - for(unsigned long i=0;i= sizeof(c.tcpReadBuf)) { phy->close(sock); return; } - c.tcpReadBuf[c.tcpReadPtr++] = ((const char *)data)[i]; + c.tcpReadBuf[c.tcpReadPtr++] = ((const char*)data)[i]; if (c.tcpReadPtr >= 5) { - unsigned long mlen = ( ((((unsigned long)c.tcpReadBuf[3]) & 0xff) << 8) | (((unsigned long)c.tcpReadBuf[4]) & 0xff) ); + unsigned long mlen = (((((unsigned long)c.tcpReadBuf[3]) & 0xff) << 8) | (((unsigned long)c.tcpReadBuf[4]) & 0xff)); if (c.tcpReadPtr >= (mlen + 5)) { if (mlen == 4) { // Right now just sending this means the client is 'new enough' for the IP header c.newVersion = true; - printf("<< TCP %.16llx HELLO\n",(unsigned long long)*uptr); - } else if (mlen >= 7) { - char *payload = c.tcpReadBuf + 5; + printf("<< TCP %.16llx HELLO\n", (unsigned long long)*uptr); + } + else if (mlen >= 7) { + char* payload = c.tcpReadBuf + 5; unsigned long payloadLen = mlen; struct sockaddr_in dest; - memset(&dest,0,sizeof(dest)); + memset(&dest, 0, sizeof(dest)); if (c.newVersion) { if (*payload == (char)4) { // New clients tell us where their packets go. ++payload; dest.sin_family = AF_INET; - dest.sin_addr.s_addr = *((uint32_t *)payload); + dest.sin_addr.s_addr = *((uint32_t*)payload); payload += 4; - dest.sin_port = *((uint16_t *)payload); // will be in network byte order already + dest.sin_port = *((uint16_t*)payload); // will be in network byte order already payload += 2; payloadLen -= 7; } - } else { + } + else { // For old clients we will just proxy everything to a local ZT instance. The // fact that this will come from 127.0.0.1 will in turn prevent that instance // from doing unite() with us. It'll just forward. There will not be many of // these. dest.sin_family = AF_INET; - dest.sin_addr.s_addr = htonl(0x7f000001); // 127.0.0.1 + dest.sin_addr.s_addr = htonl(0x7f000001); // 127.0.0.1 dest.sin_port = htons(9993); } // Note: we do not relay to privileged ports... just an abuse prevention rule. - if ((ntohs(dest.sin_port) > 1024)&&(payloadLen >= 16)) { - phy->udpSend(c.udp,(const struct sockaddr *)&dest,payload,payloadLen); - printf(">> TCP %.16llx to %s:%d\n",(unsigned long long)*uptr,inet_ntoa(dest.sin_addr),(int)ntohs(dest.sin_port)); + if ((ntohs(dest.sin_port) > 1024) && (payloadLen >= 16)) { + phy->udpSend(c.udp, (const struct sockaddr*)&dest, payload, payloadLen); + printf(">> TCP %.16llx to %s:%d\n", (unsigned long long)*uptr, inet_ntoa(dest.sin_addr), (int)ntohs(dest.sin_port)); } } - memmove(c.tcpReadBuf,c.tcpReadBuf + (mlen + 5),c.tcpReadPtr -= (mlen + 5)); + memmove(c.tcpReadBuf, c.tcpReadBuf + (mlen + 5), c.tcpReadPtr -= (mlen + 5)); } } } } - void phyOnTcpWritable(PhySocket *sock,void **uptr) + void phyOnTcpWritable(PhySocket* sock, void** uptr) { - Client &c = *((Client *)*uptr); + Client& c = *((Client*)*uptr); if (c.tcpWritePtr) { - long n = phy->streamSend(sock,c.tcpWriteBuf,c.tcpWritePtr); + long n = phy->streamSend(sock, c.tcpWriteBuf, c.tcpWritePtr); if (n > 0) { - memmove(c.tcpWriteBuf,c.tcpWriteBuf + n,c.tcpWritePtr -= (unsigned long)n); - if (!c.tcpWritePtr) - phy->setNotifyWritable(sock,false); + memmove(c.tcpWriteBuf, c.tcpWriteBuf + n, c.tcpWritePtr -= (unsigned long)n); + if (! c.tcpWritePtr) + phy->setNotifyWritable(sock, false); } - } else phy->setNotifyWritable(sock,false); + } + else + phy->setNotifyWritable(sock, false); } void doHousekeeping() { - std::vector toClose; - time_t now = time((time_t *)0); - for(std::map< PhySocket *,Client >::iterator c(clients.begin());c!=clients.end();++c) { + std::vector toClose; + time_t now = time((time_t*)0); + for (std::map::iterator c(clients.begin()); c != clients.end(); ++c) { if ((now - c->second.lastActivity) >= ZT_TCP_PROXY_CONNECTION_TIMEOUT_SECONDS) { toClose.push_back(c->first); toClose.push_back(c->second.udp); } } - for(std::vector::iterator s(toClose.begin());s!=toClose.end();++s) + for (std::vector::iterator s(toClose.begin()); s != toClose.end(); ++s) phy->close(*s); } }; -int main(int argc,char **argv) +int main(int argc, char** argv) { - signal(SIGPIPE,SIG_IGN); - signal(SIGHUP,SIG_IGN); - srand(time((time_t *)0)); + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + srand(time((time_t*)0)); TcpProxyService svc; - Phy phy(&svc,false,true); + Phy phy(&svc, false, true); svc.phy = &phy; svc.udpPortCounter = 1023; { struct sockaddr_in laddr; - memset(&laddr,0,sizeof(laddr)); + memset(&laddr, 0, sizeof(laddr)); laddr.sin_family = AF_INET; laddr.sin_port = htons(ZT_TCP_PROXY_TCP_PORT); - if (!phy.tcpListen((const struct sockaddr *)&laddr)) { - fprintf(stderr,"%s: fatal error: unable to bind TCP port %d\n",argv[0],ZT_TCP_PROXY_TCP_PORT); + if (! phy.tcpListen((const struct sockaddr*)&laddr)) { + fprintf(stderr, "%s: fatal error: unable to bind TCP port %d\n", argv[0], ZT_TCP_PROXY_TCP_PORT); return 1; } } - time_t lastDidHousekeeping = time((time_t *)0); - for(;;) { + time_t lastDidHousekeeping = time((time_t*)0); + for (;;) { phy.poll(120000); - time_t now = time((time_t *)0); + time_t now = time((time_t*)0); if ((now - lastDidHousekeeping) > 120) { lastDidHousekeeping = now; svc.doHousekeeping();