Improve Central API
This commit is contained in:
158
src/Central.cpp
158
src/Central.cpp
@@ -26,14 +26,14 @@
|
||||
#include "Debug.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
char central_api_url[CENRTAL_API_MAX_URL_LEN];
|
||||
char central_api_token[CENTRAL_API_TOKEN_LEN+1];
|
||||
char api_url[ZTS_CENRTAL_MAX_URL_LEN];
|
||||
char api_token[ZTS_CENTRAL_TOKEN_LEN+1];
|
||||
|
||||
char *_response_buffer;
|
||||
int _response_buffer_len;
|
||||
int _response_buffer_offset;
|
||||
char *_resp_buf;
|
||||
int _resp_buf_len;
|
||||
int _resp_buf_offset;
|
||||
|
||||
static int8_t _api_access_modes;
|
||||
static int8_t _access_modes;
|
||||
static int8_t _bIsVerbose;
|
||||
static int8_t _bInit;
|
||||
|
||||
@@ -47,100 +47,101 @@ extern "C" {
|
||||
|
||||
size_t on_data(void *buffer, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
DEBUG_INFO("buffer=%p, size=%zu, nmemb=%zu, userp=%p", buffer, size, nmemb, userp);
|
||||
DEBUG_INFO("buf=%p,size=%zu,nmemb=%zu,userp=%p", buffer, size, nmemb, userp);
|
||||
int byte_count = (size * nmemb);
|
||||
if (_response_buffer_offset + byte_count >= _response_buffer_len) {
|
||||
if (_resp_buf_offset + byte_count >= _resp_buf_len) {
|
||||
DEBUG_ERROR("Out of buffer space. Cannot store response from server");
|
||||
return 0; // Signal to libcurl that our buffer is full (triggers a write error.)
|
||||
}
|
||||
memcpy(_response_buffer+_response_buffer_offset, buffer, byte_count);
|
||||
_response_buffer_offset += byte_count;
|
||||
memcpy(_resp_buf+_resp_buf_offset, buffer, byte_count);
|
||||
_resp_buf_offset += byte_count;
|
||||
return byte_count;
|
||||
}
|
||||
|
||||
void zts_central_api_set_access(int8_t modes)
|
||||
void zts_central_set_access_mode(int8_t modes)
|
||||
{
|
||||
_api_access_modes = modes;
|
||||
_access_modes = modes;
|
||||
}
|
||||
|
||||
void zts_central_api_set_verbose(int8_t is_verbose)
|
||||
void zts_central_set_verbose(int8_t is_verbose)
|
||||
{
|
||||
_bIsVerbose = is_verbose;
|
||||
}
|
||||
|
||||
void zts_central_api_clear_response_buffer()
|
||||
void zts_central_clear_resp_buf()
|
||||
{
|
||||
Mutex::Lock _l(_responseBuffer_m);
|
||||
memset(_response_buffer, 0, _response_buffer_len);
|
||||
_response_buffer_offset = 0;
|
||||
memset(_resp_buf, 0, _resp_buf_len);
|
||||
_resp_buf_offset = 0;
|
||||
}
|
||||
|
||||
int zts_central_api_init(const char *url_str, const char *token_str, char *response_buffer, uint32_t response_buffer_len)
|
||||
int zts_central_init(
|
||||
const char *url_str, const char *token_str, char *resp_buf, uint32_t resp_buf_len)
|
||||
{
|
||||
_api_access_modes = ZTS_CENTRAL_READ; // Defauly read-only
|
||||
_access_modes = ZTS_CENTRAL_READ; // Defauly read-only
|
||||
_bIsVerbose = 0; // Default disable libcurl verbose output
|
||||
Mutex::Lock _l(_responseBuffer_m);
|
||||
if (response_buffer_len == 0) {
|
||||
if (resp_buf_len == 0) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
_response_buffer = response_buffer;
|
||||
_response_buffer_len = response_buffer_len;
|
||||
_response_buffer_offset = 0;
|
||||
_resp_buf = resp_buf;
|
||||
_resp_buf_len = resp_buf_len;
|
||||
_resp_buf_offset = 0;
|
||||
// Initialize all curl internal submodules
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
int url_len = strlen(url_str);
|
||||
if (url_len < 3 || url_len > CENRTAL_API_MAX_URL_LEN) {
|
||||
if (url_len < 3 || url_len > ZTS_CENRTAL_MAX_URL_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
} else {
|
||||
memset(central_api_url, 0, CENRTAL_API_MAX_URL_LEN);
|
||||
memcpy(central_api_url, url_str, url_len);
|
||||
memset(api_url, 0, ZTS_CENRTAL_MAX_URL_LEN);
|
||||
memcpy(api_url, url_str, url_len);
|
||||
}
|
||||
int token_len = strlen(token_str);
|
||||
if (token_len != CENTRAL_API_TOKEN_LEN) {
|
||||
if (token_len != ZTS_CENTRAL_TOKEN_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
} else {
|
||||
memset(central_api_token, 0, CENTRAL_API_TOKEN_LEN);
|
||||
memcpy(central_api_token, token_str, token_len);
|
||||
memset(api_token, 0, ZTS_CENTRAL_TOKEN_LEN);
|
||||
memcpy(api_token, token_str, token_len);
|
||||
}
|
||||
_bInit = true;
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
void zts_central_api_cleanup()
|
||||
void zts_central_cleanup()
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
int _central_req(int request_type, char *central_api_str,
|
||||
int _central_req(int request_type, char *central_str,
|
||||
char *api_route_str, char *token_str, int *response_code, char *post_data)
|
||||
{
|
||||
int err = ZTS_ERR_OK;
|
||||
if (!_bInit) {
|
||||
DEBUG_ERROR("Error: Central API must be initialized first. Call zts_central_api_init()");
|
||||
DEBUG_ERROR("Error: Central API must be initialized first. Call zts_central_init()");
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (request_type == HTTP_GET && !(_api_access_modes & ZTS_CENTRAL_READ)) {
|
||||
if (request_type == ZTS_HTTP_GET && !(_access_modes & ZTS_CENTRAL_READ)) {
|
||||
DEBUG_ERROR("Error: Incorrect access mode. Need (ZTS_CENTRAL_READ) permission");
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (request_type == HTTP_POST && !(_api_access_modes & ZTS_CENTRAL_WRITE)) {
|
||||
if (request_type == ZTS_HTTP_POST && !(_access_modes & ZTS_CENTRAL_WRITE)) {
|
||||
DEBUG_ERROR("Error: Incorrect access mode. Need (ZTS_CENTRAL_WRITE) permission");
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
zts_central_api_clear_response_buffer();
|
||||
int central_api_strlen = strlen(central_api_str);
|
||||
zts_central_clear_resp_buf();
|
||||
int central_strlen = strlen(central_str);
|
||||
int api_route_strlen = strlen(api_route_str);
|
||||
int token_strlen = strlen(token_str);
|
||||
int url_len = central_api_strlen + api_route_strlen;
|
||||
if (token_strlen > CENTRAL_API_TOKEN_LEN) {
|
||||
int url_len = central_strlen + api_route_strlen;
|
||||
if (token_strlen > ZTS_CENTRAL_TOKEN_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
if (url_len > CENRTAL_API_MAX_URL_LEN) {
|
||||
if (url_len > ZTS_CENRTAL_MAX_URL_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
char req_url[CENRTAL_API_MAX_URL_LEN];
|
||||
strcpy(req_url, central_api_str);
|
||||
char req_url[ZTS_CENRTAL_MAX_URL_LEN];
|
||||
strcpy(req_url, central_str);
|
||||
strcat(req_url, api_route_str);
|
||||
|
||||
CURL *curl;
|
||||
@@ -151,9 +152,9 @@ int _central_req(int request_type, char *central_api_str,
|
||||
}
|
||||
|
||||
struct curl_slist *hs=NULL;
|
||||
char auth_str[CENTRAL_API_TOKEN_LEN + 32];
|
||||
if (token_strlen == CENTRAL_API_TOKEN_LEN) {
|
||||
memset(auth_str, 0, CENTRAL_API_TOKEN_LEN + 32);
|
||||
char auth_str[ZTS_CENTRAL_TOKEN_LEN + 32];
|
||||
if (token_strlen == ZTS_CENTRAL_TOKEN_LEN) {
|
||||
memset(auth_str, 0, ZTS_CENTRAL_TOKEN_LEN + 32);
|
||||
sprintf(auth_str, "Authorization: Bearer %s", token_str);
|
||||
}
|
||||
|
||||
@@ -161,7 +162,7 @@ int _central_req(int request_type, char *central_api_str,
|
||||
hs = curl_slist_append(hs, "Content-Type: application/json");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, req_url);
|
||||
// example.com is redirected, so we tell libcurl to follow redirection
|
||||
// example.com is redirected, so we tell libcurl to follow redirection
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
if (_bIsVerbose) {
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
@@ -169,18 +170,18 @@ int _central_req(int request_type, char *central_api_str,
|
||||
// Tell curl to use our write function
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_data);
|
||||
|
||||
if (request_type == HTTP_GET) {
|
||||
if (request_type == ZTS_HTTP_GET) {
|
||||
// Nothing
|
||||
DEBUG_INFO("Request (GET) = %s", api_route_str);
|
||||
}
|
||||
if (request_type == HTTP_POST) {
|
||||
if (request_type == ZTS_HTTP_POST) {
|
||||
DEBUG_INFO("Request (POST) = %s", api_route_str);
|
||||
if (post_data) {
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
}
|
||||
if (request_type == HTTP_DELETE) {
|
||||
if (request_type == ZTS_HTTP_DELETE) {
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
}
|
||||
//curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); // Consider 400-500 series code as failures
|
||||
@@ -192,7 +193,7 @@ int _central_req(int request_type, char *central_api_str,
|
||||
long hrc = 0;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &hrc);
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &elapsed_time);
|
||||
DEBUG_INFO("Request took %f second(s). HTTP code (%ld)", elapsed_time, hrc);
|
||||
DEBUG_INFO("Req. took %f second(s). HTTP code (%ld)", elapsed_time, hrc);
|
||||
*response_code = hrc;
|
||||
//curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
|
||||
} else {
|
||||
@@ -203,73 +204,83 @@ int _central_req(int request_type, char *central_api_str,
|
||||
return err;
|
||||
}
|
||||
|
||||
int zts_get_last_response_buffer(char *dest_buffer, int dest_buffer_len)
|
||||
int zts_get_last_resp_buf(char *dest_buffer, int dest_buf_len)
|
||||
{
|
||||
if (dest_buffer_len <= _response_buffer_offset) {
|
||||
if (dest_buf_len <= _resp_buf_offset) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
int amount_to_copy = dest_buffer_len < _response_buffer_len ? dest_buffer_len : _response_buffer_len;
|
||||
memcpy(dest_buffer, _response_buffer, amount_to_copy);
|
||||
int sz = dest_buf_len < _resp_buf_len ? dest_buf_len : _resp_buf_len;
|
||||
memcpy(dest_buffer, _resp_buf, sz);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
int zts_central_api_get_status(int *http_response_code)
|
||||
int zts_central_get_status(int *resp_code)
|
||||
{
|
||||
return _central_req(HTTP_GET, central_api_url, (char*)"/api/status", central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, (char*)"/api/status", api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_get_self(int *http_response_code)
|
||||
int zts_central_get_self(int *resp_code)
|
||||
{
|
||||
return _central_req(HTTP_GET, central_api_url, (char*)"/api/self", central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, (char*)"/api/self", api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_get_network(int *http_response_code, uint64_t nwid)
|
||||
int zts_central_get_network(int *resp_code, uint64_t nwid)
|
||||
{
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx", nwid);
|
||||
return _central_req(HTTP_GET, central_api_url, req, central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_update_network(int *http_response_code, uint64_t nwid)
|
||||
int zts_central_update_network(int *resp_code, uint64_t nwid)
|
||||
{
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx", nwid);
|
||||
return _central_req(HTTP_POST, central_api_url, req, central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_POST, api_url, req, api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_delete_network(int *http_response_code, uint64_t nwid)
|
||||
int zts_central_delete_network(int *resp_code, uint64_t nwid)
|
||||
{
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx", nwid);
|
||||
return _central_req(HTTP_DELETE, central_api_url, req, central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_DELETE, api_url, req, api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_get_networks(int *http_response_code)
|
||||
int zts_central_get_networks(int *resp_code)
|
||||
{
|
||||
return _central_req(HTTP_GET, central_api_url, (char*)"/api/network", central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, (char*)"/api/network", api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_get_member(int *http_response_code, uint64_t nwid, uint64_t nodeid)
|
||||
int zts_central_get_member(int *resp_code, uint64_t nwid, uint64_t nodeid)
|
||||
{
|
||||
if (nwid == 0 || nodeid == 0) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx/member/%llx", nwid, nodeid);
|
||||
return _central_req(HTTP_GET, central_api_url, req, central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
int zts_central_api_update_member(int *http_response_code, uuint64_t nwid, uuint64_t nodeid, char *post_data)
|
||||
int zts_central_update_member(
|
||||
int *resp_code, uint64_t nwid, uint64_t nodeid, char *post_data)
|
||||
{
|
||||
if (nwid == 0 || nodeid == 0 || post_data == NULL) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx/member/%llx", nwid, nodeid);
|
||||
return _central_req(HTTP_POST, central_api_url, req, central_api_token, http_response_code, post_data);
|
||||
return _central_req(
|
||||
ZTS_HTTP_POST, api_url, req, api_token, resp_code, post_data);
|
||||
}
|
||||
|
||||
int zts_set_node_auth(int *http_response_code, uint64_t nwid, uint64_t nodeid, int8_t is_authed)
|
||||
int zts_central_set_node_auth(
|
||||
int *resp_code, uint64_t nwid, uint64_t nodeid, uint8_t is_authed)
|
||||
{
|
||||
if (is_authed != 0 && is_authed != 1) {
|
||||
return ZTS_ERR_ARG;
|
||||
@@ -281,19 +292,20 @@ int zts_set_node_auth(int *http_response_code, uint64_t nwid, uint64_t nodeid, i
|
||||
if (is_authed == ZTS_CENTRAL_NODE_AUTH_FALSE) {
|
||||
sprintf(config_data, "{\"config\": {\"authorized\": false} }");
|
||||
}
|
||||
return zts_central_api_update_member(http_response_code, nwid, nodeid, config_data);
|
||||
return zts_central_update_member(resp_code, nwid, nodeid, config_data);
|
||||
}
|
||||
|
||||
int zts_central_api_get_members_of_network(int *http_response_code, uint64_t nwid)
|
||||
int zts_central_get_members_of_network(int *resp_code, uint64_t nwid)
|
||||
{
|
||||
char req[64];
|
||||
sprintf(req, "/api/network/%llx/member", nwid);
|
||||
return _central_req(HTTP_GET, central_api_url, req, central_api_token, http_response_code, NULL);
|
||||
return _central_req(
|
||||
ZTS_HTTP_GET, api_url, req, api_token, resp_code, NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // NO_CENTRAL_API
|
||||
#endif // ZTS_ENABLE_CENTRAL_API
|
||||
#endif // _H
|
||||
|
||||
Reference in New Issue
Block a user