diff --git a/include/libzt.h b/include/libzt.h index b8ccd74..2f24a09 100644 --- a/include/libzt.h +++ b/include/libzt.h @@ -99,10 +99,16 @@ typedef int zts_err_t; // Control API error codes // ////////////////////////////////////////////////////////////////////////////// -#define ZTS_ERR_OK 0 // Everything is ok -#define ZTS_ERR_INVALID_ARG -1 // A parameter provided by the user application is invalid (e.g. our of range, NULL, etc) -#define ZTS_ERR_SERVICE -2 // The service isn't initialized or is for some other reason currently unavailable -#define ZTS_ERR_INVALID_OP -3 // For some reason this API operation is not permitted (perhaps the service is still starting?) +// Everything is ok +#define ZTS_ERR_OK 0 +// A argument provided by the user application is invalid (e.g. out of range, NULL, etc) +#define ZTS_ERR_INVALID_ARG -1 +// The service isn't initialized or is for some reason currently unavailable. Try again. +#define ZTS_ERR_SERVICE -2 +// For some reason this API operation is not permitted or doesn't make sense at this time. +#define ZTS_ERR_INVALID_OP -3 +// The call succeeded, but no object or relevant result was available +#define ZTS_ERR_NO_RESULT -4 ////////////////////////////////////////////////////////////////////////////// // Control API event codes // @@ -125,7 +131,8 @@ typedef int zts_err_t; #define ZTS_EVENT_NETWORK_ACCESS_DENIED 36 #define ZTS_EVENT_NETWORK_READY_IP4 37 #define ZTS_EVENT_NETWORK_READY_IP6 38 -#define ZTS_EVENT_NETWORK_DOWN 39 +#define ZTS_EVENT_NETWORK_READY_IP4_IP6 39 +#define ZTS_EVENT_NETWORK_DOWN 40 // Network Stack events #define ZTS_EVENT_STACK_UP 48 #define ZTS_EVENT_STACK_DOWN 49 @@ -935,17 +942,26 @@ ZT_SOCKET_API void ZTCALL zts_get_rfc4193_addr( */ ZT_SOCKET_API zts_err_t zts_get_peer_count(); +/** + * @brief Return details of all peers + * + * @param pds Pointer to array of zts_peer_details structs to be filled out + * @param num Length of destination array, will be filled out with actual number + * of peers that details were available for. + * @usage Call this after zts_start() has succeeded + * @return + */ ZT_SOCKET_API zts_err_t zts_get_peers(struct zts_peer_details *pds, int *num); /** - * @brief Determines whether a peer is reachable via a P2P connection - * or is being relayed via roots. + * @brief Return details of a given peer. * - * @usage - * @param nodeId The ID of the peer to check - * @return The status of a peer + * @param pds Pointer to zts_peer_details struct to be filled out + * @param peerId ID of peer that the caller wants details of + * @usage Call this after zts_start() has succeeded + * @return */ -ZT_SOCKET_API zts_err_t zts_get_peer_status(uint64_t nodeId); +ZT_SOCKET_API zts_err_t zts_get_peer(struct zts_peer_details *pds, uint64_t peerId); /** * @brief Starts a ZeroTier service in the background @@ -969,15 +985,35 @@ void *_zts_start_service(void *thread_id); */ int _zts_can_perform_service_operation(); -/** - * @brief [Should not be called from user application] Returns whether or not the node is - * online. - * @usage Can be called at any time - * @return 1 or 0 - */ -int _zts_node_online(); +////////////////////////////////////////////////////////////////////////////// +// Status getters // +////////////////////////////////////////////////////////////////////////////// -int zts_ready(); +/** + * @brief Queries a the status of the core node/service + * + * @usage Can be called at any time + * @return ZTS_EVENT_NODE_ONLINE, ZTS_EVENT_NODE_OFFLINE, or standard ZTS_ errors + */ +ZT_SOCKET_API zts_err_t zts_get_node_status(); + +/** + * @brief Queries a the status of a network + * + * @usage Can be called at any time + * @return ZTS_NETWORK_ values, or standard ZTS_ errors + */ +ZT_SOCKET_API zts_err_t zts_get_network_status(uint64_t nwid); + +/** + * @brief Determines whether a peer is reachable via a P2P connection + * or is being relayed via roots. + * + * @usage + * @param peerId The ID of the peer to check + * @return ZTS_PEER_ values, or standard ZTS_ errors + */ +ZT_SOCKET_API zts_err_t zts_get_peer_status(uint64_t peerId); ////////////////////////////////////////////////////////////////////////////// // Socket API // diff --git a/src/Controls.cpp b/src/Controls.cpp index 6718080..742339c 100644 --- a/src/Controls.cpp +++ b/src/Controls.cpp @@ -176,15 +176,12 @@ only for legacy reasons. */ uint64_t arg = 0; uint64_t id = 0; if (NODE_EVENT_TYPE(msg->eventCode)) { - DEBUG_INFO("NODE_EVENT_TYPE(%d)", msg->eventCode); id = msg->node ? msg->node->address : 0; } if (NETWORK_EVENT_TYPE(msg->eventCode)) { - DEBUG_INFO("NETWORK_EVENT_TYPE(%d)", msg->eventCode); id = msg->network ? msg->network->nwid : 0; } if (PEER_EVENT_TYPE(msg->eventCode)) { - DEBUG_INFO("PEER_EVENT_TYPE(%d)", msg->eventCode); id = msg->peer ? msg->peer->address : 0; } env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->eventCode); @@ -667,7 +664,6 @@ JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1count( int zts_get_peers(struct zts_peer_details *pds, int *num) { - // TODO: Modernize Mutex::Lock _l(_service_lock); if (!pds || !num) { return ZTS_ERR_INVALID_ARG; @@ -677,9 +673,17 @@ int zts_get_peers(struct zts_peer_details *pds, int *num) } ZT_PeerList *pl = service->getNode()->peers(); if (pl) { + if (*num < pl->peerCount) { + service->getNode()->freeQueryResult((void *)pl); + return ZTS_ERR_INVALID_ARG; + } *num = pl->peerCount; for(unsigned long i=0;ipeerCount;++i) { memcpy(&(pds[i]), &(pl->peers[i]), sizeof(struct zts_peer_details)); + for (int j=0; jpeers[i].pathCount; j++) { + memcpy(&(pds[i].paths[j].address), + &(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage)); + } } } service->getNode()->freeQueryResult((void *)pl); @@ -688,21 +692,35 @@ int zts_get_peers(struct zts_peer_details *pds, int *num) #ifdef SDK_JNI #endif -int zts_get_peer_status(uint64_t id) +int zts_get_peer(struct zts_peer_details *pd, uint64_t peerId) { Mutex::Lock _l(_service_lock); - zts_err_t retval = ZTS_ERR_OK; + if (!pd || !peerId) { + return ZTS_ERR_INVALID_ARG; + } if (!__zts_can_perform_service_operation()) { return ZTS_ERR_SERVICE; } - return service->getPeerStatus(id); + ZT_PeerList *pl = service->getNode()->peers(); + int retval = ZTS_ERR_NO_RESULT; + if (pl) { + for(unsigned long i=0;ipeerCount;++i) { + if (pl->peers[i].address == peerId) { + DEBUG_INFO("found"); + memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details)); + for (int j=0; jpeers[i].pathCount; j++) { + memcpy(&(pd->paths[j].address), + &(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage)); + } + retval = ZTS_ERR_OK; + break; + } + } + } + service->getNode()->freeQueryResult((void *)pl); + return retval; } #ifdef SDK_JNI -JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1status( - JNIEnv *env, jobject thisObj, jlong id) -{ - return zts_get_peer_status(id); -} #endif ////////////////////////////////////////////////////////////////////////////// @@ -822,14 +840,66 @@ zts_err_t zts_get_all_network_details(struct zts_network_details *nds, int *num) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -// Misc // +// Status getters // ////////////////////////////////////////////////////////////////////////////// -int zts_ready() +int zts_get_node_status() { Mutex::Lock _l(_service_lock); - return _run_service && _run_lwip_tcpip; + // Don't check __zts_can_perform_service_operation() here. + return service + && service->getNode() + && service->getNode()->online() ? ZTS_EVENT_NODE_ONLINE : ZTS_EVENT_NODE_OFFLINE; } +#ifdef SDK_JNI +JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1status( + JNIEnv *env, jobject thisObj) +{ + return zts_get_node_status(); +} +#endif + +int zts_get_network_status(uint64_t networkId) +{ + Mutex::Lock _l(_service_lock); + if (!networkId) { + return ZTS_ERR_INVALID_ARG; + } + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + /* + TODO: + ZTS_EVENT_NETWORK_READY_IP4 + ZTS_EVENT_NETWORK_READY_IP6 + ZTS_EVENT_NETWORK_READY_IP4_IP6 + */ + return ZTS_ERR_NO_RESULT; +} +#ifdef SDK_JNI +JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1network_1status( + JNIEnv *env, jobject thisObj, jlong networkId) +{ + return zts_get_network_status(networkId); +} +#endif + +int zts_get_peer_status(uint64_t peerId) +{ + Mutex::Lock _l(_service_lock); + zts_err_t retval = ZTS_ERR_OK; + if (!__zts_can_perform_service_operation()) { + return ZTS_ERR_SERVICE; + } + return service->getPeerStatus(peerId); +} +#ifdef SDK_JNI +JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1status( + JNIEnv *env, jobject thisObj, jlong peerId) +{ + return zts_get_peer_status(peerId); +} +#endif #ifdef __cplusplus }