diff --git a/include/ZeroTierSockets.h b/include/ZeroTierSockets.h index 98058e9..d21d9fe 100644 --- a/include/ZeroTierSockets.h +++ b/include/ZeroTierSockets.h @@ -2966,6 +2966,18 @@ ZTS_API int ZTCALL zts_core_query_route( uint16_t* flags, uint16_t* metric); +/** + * @brief Lock the core service so that queries about addresses, routes, paths, etc. can be + * performed. + * + * Notice: Core locking functions are intended to be used by high-level language wrappers. + * Only lock the core if you know *exactly* what you are doing. zts_core_lock_obtain() and + * zts_core_lock_release() must be called before and after this function. + * + * @return `ZTS_ERR_OK` if successful. `ZTS_ERR_SERVICE` if the core service is unavailable. + */ +ZTS_API int ZTCALL zts_core_query_peer_info(uint64_t net_id, uint64_t mac, zts_peer_info_t* peerInfo); + /** * @brief Lock the core service so that queries about addresses, routes, paths, etc. can be * performed. diff --git a/src/Controls.cpp b/src/Controls.cpp index 536868f..5f916a7 100644 --- a/src/Controls.cpp +++ b/src/Controls.cpp @@ -396,6 +396,12 @@ int zts_core_query_route( return zts_service->getRouteAtIdx(net_id, idx, target, via, len, flags, metric); } +int zts_core_query_peer_info(uint64_t net_id, uint64_t mac, zts_peer_info_t* peerInfo) +{ + ACQUIRE_SERVICE(ZTS_ERR_SERVICE); + return zts_service->getPeer(net_id, mac, peerInfo); +} + int zts_core_query_path_count(uint64_t peer_id) { ACQUIRE_SERVICE(ZTS_ERR_SERVICE); diff --git a/src/NodeService.cpp b/src/NodeService.cpp index 2c2bb8a..5bea9ab 100644 --- a/src/NodeService.cpp +++ b/src/NodeService.cpp @@ -843,9 +843,24 @@ void NodeService::sendEventToUser(unsigned int zt_event_code, const void* obj, u case ZTS_EVENT_PEER_PATH_DEAD: { zts_peer_info_t* pd = new zts_peer_info_t(); ZT_Peer* peer = (ZT_Peer*)obj; - memcpy(pd, peer, sizeof(zts_peer_info_t)); + pd->peer_id = peer->address; + pd->ver_major = peer->versionMajor; + pd->ver_minor = peer->versionMinor; + pd->ver_rev = peer->versionRev; + pd->latency = peer->latency; + pd->role = static_cast(peer->role); + pd->path_count = peer->pathCount; for (unsigned int j = 0; j < peer->pathCount; j++) { native_ss_to_zts_ss(&(pd->paths[j].address), &(peer->paths[j].address)); + pd->paths[j].last_tx = peer->paths[j].lastSend; + pd->paths[j].last_rx = peer->paths[j].lastReceive; + pd->paths[j].trusted_path_id = peer->paths[j].trustedPathId; + pd->paths[j].latency = peer->paths[j].latencyMean; + // I doubt there is any guarantee that the ZT_Peer + // instance will outlive the zts_peer_info_t instance + //pd->paths[j].ifname = peer->paths[j].ifname; + pd->paths[j].expired = peer->paths[j].expired; + pd->paths[j].preferred = peer->paths[j].preferred; } objptr = (void*)pd; break; @@ -1008,6 +1023,31 @@ int NodeService::multicastSubCount(uint64_t net_id) const return n->second.config.multicastSubscriptionCount; } +int NodeService::getPeer(uint64_t net_id, uint64_t mac, zts_peer_info_t* peerInfo) const +{ + ZT_Peer* peer = _node->peer((void*)0, net_id, mac); + if (!peer) + return ZTS_ERR_NO_RESULT; + peerInfo->peer_id = peer->address; + peerInfo->ver_major = peer->versionMajor; + peerInfo->ver_minor = peer->versionMinor; + peerInfo->ver_rev = peer->versionRev; + peerInfo->latency = peer->latency; + peerInfo->role = static_cast(peer->role); + peerInfo->path_count = peer->pathCount; + for (unsigned int j = 0; j < peer->pathCount; j++) { + native_ss_to_zts_ss(&(peerInfo->paths[j].address), &(peer->paths[j].address)); + peerInfo->paths[j].last_tx = peer->paths[j].lastSend; + peerInfo->paths[j].last_rx = peer->paths[j].lastReceive; + peerInfo->paths[j].trusted_path_id = peer->paths[j].trustedPathId; + peerInfo->paths[j].latency = peer->paths[j].latencyMean; + peerInfo->paths[j].expired = peer->paths[j].expired; + peerInfo->paths[j].preferred = peer->paths[j].preferred; + } + _node->freeQueryResult(peer); + return ZTS_ERR_OK; +} + int NodeService::pathCount(uint64_t peer_id) const { return ZTS_ERR_NO_RESULT; // TODO diff --git a/src/NodeService.hpp b/src/NodeService.hpp index 86be58a..d08c6f2 100644 --- a/src/NodeService.hpp +++ b/src/NodeService.hpp @@ -293,6 +293,9 @@ class NodeService { /** Return number of multicast subscriptions on the network. Service must be locked. */ int multicastSubCount(uint64_t net_id) const; + /** Return peer info for a given MAC address. */ + int getPeer(uint64_t net_id, uint64_t mac, zts_peer_info_t* peerInfo) const; + /** Return number of known physical paths to the peer. Service must be locked. */ int pathCount(uint64_t peer_id) const;