All Products
Search
Document Center

HTTPDNS:C SDK API

Last Updated:Jun 17, 2026

All C SDK APIs are defined in hdns_api.h.

SDK environment creation/destruction

The SDK uses shared global resources, such as connection pools, thread pools, and network detectors. Initialize these resources before creating any client instance, and release them when you finish using the SDK.

/*
 * @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

You can create multiple client instances with different account IDs. Each instance handles HTTPDNS server interaction and cache management. A client's lifecycle includes creation, configuration, startup, and destruction.

/*
 * @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 client starts, you can resolve domain names through eight standard interfaces that cover synchronous/asynchronous, cached/uncached, and single/batch resolution. The with_cache variants (hdns_get_result_for_host_sync_with_cache and hdns_get_result_for_host_async_with_cache) behave like LocalDNS: they query the local cache first and fall back to the DNS server on a cache miss.

/*
 *
 * @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

Custom resolution interfaces let you configure request parameters for custom resolution scenarios that require business-specific 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 for troubleshooting. By default, logs print to the console at the warn level. Each client instance generates a SessionID that persists for the instance's lifetime and is sent with every request. Use the SessionID to diagnose unexpected resolution results.

/*
 *
 * @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

Clear 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 that simplify common SDK operations.

/*
 *
 * @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);