@ -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_a ccess_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_a ccess_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_a ccess_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