Lists the APIs provided by the SDK, which are defined in the SDK's hdns_api.h.
SDK environment creation/destruction
The SDK requires initialization of essential global resources, such as connection pools, thread pools, and network detectors. These global resources are shared by all client instances and must be initialized before creating client instances, and released when exiting SDK usage.
/*
* @brief SDK environment initialization, mainly including global random numbers, session pool, network detector, thread pool
* @return 0: initialization successful; 1: initialization failed
* @note:
* - After calling this interface, please make sure to call hdns_sdk_cleanup once to release resources
* - This interface is not thread-safe
*/
int hdns_sdk_init();
/*
*
* @brief Clean up and release HTTPDNS SDK environment
* @node :
* - This interface is not thread-safe
*/
void hdns_sdk_cleanup();Client creation/configuration/startup/destruction
HTTPDNS supports initializing multiple client instances using different account IDs. These client instances handle interaction with the HTTPDNS server and manage the cache. The lifecycle of a client instance includes: creation, configuration, startup, and destruction. The SDK provides interfaces corresponding to this lifecycle.
/*
* @brief Create client instance
* @param[in] account_id HTTPDNS account ID
* @param[in] secret_key Secret key for signing HTTP requests, can be NULL if signing is not required
* @return Returns client instance if creation is successful, otherwise returns NULL
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_client_t *hdns_client_create(const char *account_id, const char *secret_key);
/*
* @brief Set the maximum timeout for a single server request when local cache is invalid
* @param[in] client Client instance
* @param[in] timeout Timeout in milliseconds
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_timeout(hdns_client_t *client, int32_t timeout);
/*
* @brief Set whether the service uses local cache
* @param[in] client Client instance
* @param[in] using_cache false: do not use local cache, true: use local cache
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_using_cache(hdns_client_t *client, bool using_cache);
/*
* @brief Set whether to use https protocol when accessing HTTPDNS server
* @param[in] client Client instance
* @param[in] using_https false: do not use https protocol, true: use https protocol
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_using_https(hdns_client_t *client, bool using_https);
/*
* @brief Set whether to sign requests when accessing HTTPDNS server
* @param[in] client Client instance
* @param[in] using_sign false: do not sign, true: sign
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_using_sign(hdns_client_t *client, bool using_sign);
/*
* @brief Set the number of retry attempts when accessing HTTPDNS server, default is 1
* @param[in] client Client instance
* @param[in] retry_times Number of retry attempts
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_retry_times(hdns_client_t *client, int32_t retry_times);
/*
* @brief Set the cluster for accessing HTTPDNS server
* @param[in] client Client instance
* @param[in] region global: nearest access (default), cn: mainland China, hk: Hong Kong (China), sg: Singapore, us: United States, de: Germany
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_region(hdns_client_t *client, const char *region);
/*
* @brief Set the region for HTTPDNS scheduling center
* @param[in] client Client instance
* @param[in] region cn: mainland China (default), hk: Hong Kong (China), sg: Singapore, us: United States, de: Germany
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_set_schedule_center_region(hdns_client_t *client, const char *region);
/*
* @brief Whether to enable cache update when network changes
* @param[in] client Client instance
* @param[in] enable true: refresh, false: do not refresh
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_enable_update_cache_after_net_change(hdns_client_t *client, bool enable);
/*
* @brief Whether to allow using expired IP
* @param[in] client Client instance
* @param[in] enable true: allow using expired IP, false: do not allow
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_enable_expired_ip(hdns_client_t *client, bool enable);
/*
* @brief Whether to allow fallback to local DNS
* @param[in] client Client instance
* @param[in] enable true: allow using expired IP, false: do not allow
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_enable_failover_localdns(hdns_client_t *client, bool enable);
/*
* @brief Add domain name for pre-resolution when client starts
* @param[in] client Client instance
* @param[in] host Domain name for pre-resolution
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_add_pre_resolve_host(hdns_client_t *client, const char *host);
/*
* @brief Add domain name and port for IP sniffing, only one port is allowed for detection per domain
* @param[in] client Client instance
* @param[in] host Domain name for detection
* @param[in] port Port for detection
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_add_ip_probe_item(hdns_client_t *client, const char *host, const int port);
/*
* @brief Add a custom resolution TTL for a specific domain name, only valid for HTTPDNS resolution results, not valid when falling back to local DNS
* @param[in] client Client instance
* @param[in] host Domain name for detection
* @param[in] ttl Custom TTL
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
void hdns_client_add_custom_ttl_item(hdns_client_t *client, const char *host, const int ttl);
/*
* @brief Start the client, perform asynchronous pre-resolution of domain names and fetch domain name resolution server list
* @param[in] client Client instance
* @return Client startup status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_client_start(hdns_client_t *client);
/*
*
* @brief Clean up and release HTTPDNS client resources
*
* @param[in] client Client instance
*/
void hdns_client_cleanup(hdns_client_t *client);Standard domain name resolution interfaces
After the HTTPDNS client is started, you can perform domain name resolution through standard interfaces. Based on synchronous/asynchronous interfaces, using cache/not using cache for resolution, and single domain/batch domain resolution, the SDK provides a total of 8 standard interfaces. The domain name resolution logic of the synchronous interface hdns_get_result_for_host_sync_with_cache and the asynchronous interface hdns_get_result_for_host_async_with_cache is equivalent to LocalDNS: first query the local cache, and if the cache is not hit, request the DNS server.
/*
*
* @brief Single domain name synchronous resolution, blocks the thread, first checks the cache, if cache is empty then queries the HTTPDNS server, until the result is returned or timeout
* @param[in] client Client instance
* @param[in] host Domain name to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[out] results Resolution results, memory needs to be released through hdns_list_cleanup
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_result_for_host_sync_with_cache(hdns_client_t *client,
const char *host,
hdns_query_type_t query_type,
const char *client_ip,
hdns_list_head_t **results);
/*
*
* @brief Single domain name synchronous resolution, blocks the thread, queries the HTTPDNS server, until the result is returned or timeout
* @param[in] client Client instance
* @param[in] host Domain name to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[out] results Resolution results, memory needs to be released through hdns_list_cleanup
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_result_for_host_sync_without_cache(hdns_client_t *client,
const char *host,
hdns_query_type_t query_type,
const char *client_ip,
hdns_list_head_t **results);
/*
*
* @brief Batch domain name synchronous resolution, blocks the thread, first checks the cache, if cache is empty then queries the HTTPDNS server, until the result is returned or timeout
*
* @param[in] client Client instance
* @param[in] hosts List of domain names to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[out] results Resolution results, memory needs to be released through hdns_list_cleanup
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_results_for_hosts_sync_with_cache(hdns_client_t *client,
const hdns_list_head_t *hosts,
hdns_query_type_t query_type,
const char *client_ip,
hdns_list_head_t **results);
/*
*
* @brief Batch domain name synchronous resolution, blocks the thread, queries the HTTPDNS server, until the result is returned or timeout
*
* @param[in] client Client instance
* @param[in] hosts List of domain names to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[out] results Resolution results, memory needs to be released through hdns_list_cleanup
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_results_for_hosts_sync_without_cache(hdns_client_t *client,
const hdns_list_head_t *hosts,
hdns_query_type_t query_type,
const char *client_ip,
hdns_list_head_t **results);
/*
* @brief Asynchronous resolution callback function
* @param[in] status Final resolution status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @param[in] results Resolution result list
* @param[in] param User-defined custom parameter
*/
typedef void (*hdns_resv_done_callback_pt)(hdns_status_t *status, hdns_list_head_t *results, void *param);
/*
*
* @brief Single domain name asynchronous resolution, does not block the thread, first checks the cache, if cache is empty then queries the HTTPDNS server, until the result is returned or timeout, finally triggers the function callback
*
* @param[in] client Client instance
* @param[in] host Domain name to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[in] cb Callback function after resolution is completed
* @param[in] cb_param User-defined parameter for the callback function
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_result_for_host_async_with_cache(hdns_client_t *client,
const char *host,
hdns_query_type_t query_type,
const char *client_ip,
hdns_resv_done_callback_pt cb,
void *cb_param);
/*
*
* @brief Single domain name asynchronous resolution, does not block the thread, queries the HTTPDNS server, until the result is returned or timeout, finally triggers the function callback
*
* @param[in] client Client instance
* @param[in] host Domain name to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[in] cb Callback function after resolution is completed
* @param[in] cb_param User-defined parameter for the callback function
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_result_for_host_async_without_cache(hdns_client_t *client,
const char *host,
hdns_query_type_t query_type,
const char *client_ip,
hdns_resv_done_callback_pt cb,
void *cb_param);
/*
*
* @brief Batch domain name asynchronous resolution, does not block the thread, first checks the cache, if cache is empty then queries the HTTPDNS server, until the result is returned or timeout, finally triggers the function callback
*
* @param[in] client Client instance
* @param[in] hosts List of domain names to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[in] cb Callback function after resolution is completed
* @param[in] cb_param User-defined parameter for the callback function
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_results_for_hosts_async_with_cache(hdns_client_t *client,
const hdns_list_head_t *hosts,
hdns_query_type_t query_type,
const char *client_ip,
hdns_resv_done_callback_pt cb,
void *cb_param);
/*
*
* @brief Batch domain name asynchronous resolution, does not block the thread, queries the HTTPDNS server, until the result is returned or timeout, finally triggers the function callback
*
* @param[in] client Client instance
* @param[in] hosts List of domain names to be resolved
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[in] client_ip Optional, client IP, default is the exit IP of the interface caller
* @param[in] cb Callback function after resolution is completed
* @param[in] cb_param User-defined parameter for the callback function
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_results_for_hosts_async_without_cache(hdns_client_t *client,
const hdns_list_head_t *hosts,
hdns_query_type_t query_type,
const char *client_ip,
hdns_resv_done_callback_pt cb,
void *cb_param);
Custom domain name resolution interfaces
The SDK provides custom domain name resolution interfaces. Users can configure resolution request parameters through the interface, mainly used for custom resolution scenarios that need to pass business parameters.
/*
* @brief Custom synchronous resolution
* @param[in] client Client instance
* @param[in] req Custom resolution request instance
* @param[out] results Resolution results, memory needs to be released through hdns_list_cleanup
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_list_head_t is not thread-safe, when shared across multiple threads, synchronization should be achieved through means such as mutexes
*/
hdns_status_t hdns_get_result_for_host_sync_with_custom_request(hdns_client_t *client,
const hdns_resv_req_t *req,
hdns_list_head_t **results);
/*
* @brief First perform custom asynchronous resolution, finally trigger function callback
* @param[in] client Client instance
* @param[in] req Custom resolution request instance
* @param[in] cb Callback function after resolution is completed
* @param[in] cb_param User-defined parameter for the callback function
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_client_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_get_result_for_host_async_with_custom_request(hdns_client_t *client,
const hdns_resv_req_t *resv_req,
hdns_resv_done_callback_pt cb,
void *cb_param);
/*
* @brief When custom domain name resolution, create resolution request instance
* @param[in] client Client instance
* @return Request instance corresponding to the client
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_resv_req_t *hdns_resv_req_create(hdns_client_t *client);
/*
* @brief When custom domain name resolution, set the client IP for the request instance
* @param[in] client Client instance
* @param[in] client_ip Client IP
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_resv_req_set_client_ip(hdns_resv_req_t *req, const char *client_ip);
/*
* @brief When custom domain name resolution, set the domain name for the request instance
* @param[in] req Request instance
* @param[in] host Domain name to be resolved
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_resv_req_set_host(hdns_resv_req_t *req, const char *host);
/*
* @brief When custom domain name resolution, add business parameter pair
* @param[in] req Request instance
* @param[in] key Parameter name
* @param[in] value Parameter value
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_resv_req_append_sdns_param(hdns_resv_req_t *req, const char *key, const char *value);
/*
* @brief When custom domain name resolution, set the DNS resolution type for the request instance
* @param[in] req Request instance
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_resv_req_set_query_type(hdns_resv_req_t *req, hdns_query_type_t query_type);
/*
* @brief When custom domain name resolution, set the cache key for resolution results
* @param[in] req Request instance
* @param[in] key Parameter name
* @param[in] value Parameter value
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_resv_req_t is thread-safe and can be shared across multiple threads
*/
hdns_status_t hdns_resv_req_set_cache_key(hdns_resv_req_t *req, const char *cache_key);
/*
* @brief When custom domain name resolution, release request instance resources
* @param[in] req Request instance
*/
void hdns_resv_req_cleanup(hdns_resv_req_t *req);
/*
*
* @brief Return the extra field in software custom resolution
*
* @param[in] results Resolution results already obtained
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[out] extra Buffer to write extra
* @return Operation status, 0 indicates success, otherwise failure
*/
int hdns_get_sdns_extra(hdns_list_head_t *results, hdns_query_type_t query_type, char *extra);
Troubleshooting and tracking
The SDK provides logging and session tracking functions for troubleshooting when resolution does not meet expectations. Logs are printed to the console by default, with a log level of warn. Each client instance generates a SessionID that interacts with the server and remains valid during the client instance lifecycle. The SessionID is passed to the server during each request. When the resolution result does not meet expectations, this SessionID can help determine the cause of the problem.
/*
*
* @brief Set SDK log file path
*
* @param[in] file_path Log file path
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
*/
hdns_status_t hdns_log_set_log_file_path(const char *file_path);
/*
*
* @brief Set SDK log level
*
* @param[in] level Log level
* - HDNS_LOG_OFF Do not open log
* - HDNS_LOG_FATAL fatal level and below
* - HDNS_LOG_ERROR error level and below
* - HDNS_LOG_WARN warn level and below
* - HDNS_LOG_INFO info level and below
* - HDNS_LOG_DEBUG debug level and below
* - HDNS_LOG_TRACE trace level and below
*/
void hdns_log_set_log_level(hdns_log_level_e level);
/*
* @brief Get the session id of the client, used for troubleshooting
* @param[in] client Client instance
* @param[out] session_id session id
* @return 0 successful, otherwise failed
* @note:
* - session id is a string of length 12, please ensure the receiving buffer is larger than 12
*/
int hdns_client_get_session_id(hdns_client_t *client, char *session_id);Cache management
Supports manually clearing the local resolution cache for a specific domain name.
/*
*
* @brief Clear the local cache for a specific domain name
*
* @param[in] client Client instance
* @param[in] host Domain name
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
*/
void hdns_remove_host_cache(hdns_client_t *client, const char *host);Auxiliary interfaces
Utility interfaces, used to reduce the complexity of using the SDK for users.
/*
*
* @brief Randomly select an IP from the resolution list, IPv4 is preferred in dual-stack, only applicable to single domain name resolution
*
* @param[in] results Resolution results already obtained
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[out] ip Buffer to write IP
* @return Operation status, 0 indicates success, otherwise failure
*/
int hdns_select_ip_randomly(hdns_list_head_t *results, hdns_query_type_t query_type, char *ip);
/*
*
* @brief Return the first IP in the resolution IP list, if IP optimization is enabled, it often means the optimal IP, only applicable to single domain name resolution
*
* @param[in] results Resolution results already obtained
* @param[in] query_type Request type
* - HDNS_QUERY_AUTO: Automatically resolve based on network stack;
* - HDNS_QUERY_IPV4: Resolve IPV4 type;
* - HDNS_QUERY_IPV6: Resolve IPV6 type;
* - HDNS_QUERY_BOTH: Resolve both IPV4 and IPV6 types
* @param[out] ip Buffer to write IP
* @return Operation status, 0 indicates success, otherwise failure
*/
int hdns_select_first_ip(hdns_list_head_t *results, hdns_query_type_t query_type, char *ip);
/*
* @brief Create linked list instance
* @return Linked list instance, returns NULL if failed
* @note :
* - hdns_list_head_t is not thread-safe, when shared across multiple threads, synchronization should be achieved through means such as mutexes
*/
hdns_list_head_t *hdns_list_create();
/*
* @brief Add string to linked list
* @return Operation status, if status code is 0 it indicates success, otherwise failure, error_msg contains the error information
* @note :
* - hdns_list_head_t is not thread-safe, when shared across multiple threads, synchronization should be achieved through means such as mutexes
*/
hdns_status_t hdns_list_add_str(hdns_list_head_t *list, const char *str);
/*
* @brief Release linked list resources
* @param[in] list List instance to be released
* @note :
* - hdns_list_head_t is not thread-safe, when shared across multiple threads, synchronization should be achieved through means such as mutexes
*/
void hdns_list_cleanup(hdns_list_head_t *list);