388 lines
9.1 KiB
C
388 lines
9.1 KiB
C
#include "tvs_http_client.h"
|
||
#include "tvs_http_manager.h"
|
||
|
||
#include "mongoose.h"
|
||
|
||
#define TVS_LOG_DEBUG_MODULE "DNS"
|
||
#include "tvs_log.h"
|
||
#include "tvs_config.h"
|
||
#include "tvs_echo.h"
|
||
#include "tvs_ip_provider.h"
|
||
#include "tvs_dns.h"
|
||
#include "tvs_threads.h"
|
||
#include "os/os_api.h"
|
||
|
||
#define HTTP_DNS_PATH "http://119.29.29.29:80/d?dn="
|
||
|
||
static long g_last_dns_time = 0;
|
||
|
||
static int g_http_dns_ip = 0;
|
||
static int g_system_dns_ip = 0;
|
||
|
||
static int g_http_dns_ip_tmp = 0;
|
||
static int g_system_dns_ip_tmp = 0;
|
||
|
||
// 兜底IP
|
||
#define BACKUP_IP "183.3.225.67"
|
||
|
||
|
||
static int g_tvs_dns_pid = NULL;
|
||
static void *g_tvs_dns_mutex = NULL;
|
||
static int g_tvs_dns_start;
|
||
|
||
#define DNS_REFRESH_TIMER 40 // 更新DNS的时间间隔
|
||
|
||
|
||
typedef struct {
|
||
int ip_addr;
|
||
} tvs_http_dns_param;
|
||
|
||
TVS_LOCKER_DEFINE
|
||
|
||
extern void tvs_dns_fetch_all();
|
||
|
||
void tvs_dns_retry_dns(tvs_http_client_callback_exit_loop should_exit_func,
|
||
tvs_http_client_callback_should_cancel should_cancel_func, void *exit_param)
|
||
{
|
||
long cur_time = os_wrapper_get_time_ms();
|
||
if (g_last_dns_time == 0 || cur_time - g_last_dns_time > 600 * 1000) {
|
||
TVS_LOG_PRINTF("dns timeout, begin\n");
|
||
|
||
g_last_dns_time = cur_time;
|
||
// 超时,重新获取一次dns
|
||
tvs_dns_fetch_all(should_exit_func, should_cancel_func, exit_param);
|
||
}
|
||
}
|
||
|
||
void tvs_http_dns_callback_on_connect(void *connection, int error_code, tvs_http_client_param *param)
|
||
{
|
||
//TVS_LOG_PRINTF("send iplist connect\n");
|
||
}
|
||
|
||
void tvs_http_dns_callback_on_response(void *connection, int ret_code, const char *response, int response_len, tvs_http_client_param *param)
|
||
{
|
||
if (ret_code == 200) {
|
||
|
||
unsigned int a, b, c, d = 0;
|
||
if (response_len > 0 && response != NULL) {
|
||
char *ip_str = malloc(response_len + 1);
|
||
if (ip_str == NULL) {
|
||
TVS_LOG_PRINTF("get resonse ip OOM\n");
|
||
return;
|
||
}
|
||
|
||
memset(ip_str, 0, response_len + 1);
|
||
strncpy(ip_str, response, response_len);
|
||
|
||
if (sscanf(ip_str, "%u.%u.%u.%u", &a, &b, &c, &d) == 4) {
|
||
tvs_http_dns_param *dns_param = (tvs_http_dns_param *)param->user_data;
|
||
dns_param->ip_addr =
|
||
mg_htonl(((uint32_t) a << 24) | ((uint32_t) b << 16) | c << 8 | d);
|
||
//TVS_LOG_PRINTF("get resonse ip %s, %d\n", response, dns_param->ip_addr);
|
||
}
|
||
|
||
free(ip_str);
|
||
}
|
||
|
||
} else {
|
||
TVS_LOG_PRINTF("get resonse err %d - %.*s\n", ret_code, response_len, response);
|
||
}
|
||
}
|
||
|
||
void tvs_http_dns_callback_on_close(void *connection, int by_server, tvs_http_client_param *param) { }
|
||
|
||
int tvs_http_dns_callback_on_send_request(void *connection, const char *path, const char *host, const char *extra_header, const char *payload, tvs_http_client_param *param)
|
||
{
|
||
tvs_http_send_normal_get_request((struct mg_connection *)connection, path, strlen(path), host, strlen(host));
|
||
return 0;
|
||
}
|
||
|
||
bool tvs_http_dns_callback_on_loop(void *connection, tvs_http_client_param *param)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
int tvs_http_dns_start(const char *host,
|
||
tvs_http_client_callback_exit_loop should_exit_func,
|
||
tvs_http_client_callback_should_cancel should_cancel_func,
|
||
void *exit_param,
|
||
int *ip_addr)
|
||
{
|
||
if (host == NULL || strlen(host) <= 0) {
|
||
TVS_LOG_PRINTF("%s -- invalid host\n", __func__);
|
||
return -1;
|
||
}
|
||
int max_buf_len = 200;
|
||
char *http_dns_url = malloc(max_buf_len);
|
||
if (NULL == http_dns_url) {
|
||
TVS_LOG_PRINTF("%s -- OOM\n", __func__);
|
||
return -1;
|
||
}
|
||
|
||
memset(http_dns_url, 0, max_buf_len);
|
||
|
||
sprintf(http_dns_url, "%s%s", HTTP_DNS_PATH, host);
|
||
|
||
//TVS_LOG_PRINTF("send http dns url %s\n", http_dns_url);
|
||
|
||
tvs_http_client_callback cb = { 0 };
|
||
cb.cb_on_close = tvs_http_dns_callback_on_close;
|
||
cb.cb_on_connect = tvs_http_dns_callback_on_connect;
|
||
cb.cb_on_loop = tvs_http_dns_callback_on_loop;
|
||
cb.cb_on_request = tvs_http_dns_callback_on_send_request;
|
||
cb.cb_on_response = tvs_http_dns_callback_on_response;
|
||
cb.exit_loop = should_exit_func;
|
||
cb.should_cancel = should_cancel_func;
|
||
cb.exit_loop_param = exit_param;
|
||
|
||
tvs_http_client_config config = { 0 };
|
||
tvs_http_client_param http_param = { 0 };
|
||
tvs_http_dns_param http_dns_param = { 0 };
|
||
|
||
int ret = tvs_http_client_request_with_forceip(http_dns_url, NULL, NULL, &http_dns_param, &config, &cb, &http_param, false, 0);
|
||
|
||
if (http_dns_url != NULL) {
|
||
free(http_dns_url);
|
||
}
|
||
|
||
*ip_addr = http_dns_param.ip_addr;
|
||
TVS_LOG_PRINTF("send http dns result %d\n", *ip_addr);
|
||
|
||
return ret;
|
||
}
|
||
|
||
extern int mg_resolve2(const char *host, struct in_addr *ina);
|
||
|
||
int tvs_resolve(const char *host, int *ina)
|
||
{
|
||
return mg_resolve2(host, (struct in_addr *)ina);
|
||
}
|
||
|
||
int tvs_dns_system_start(const char *host)
|
||
{
|
||
int ipaddr = 0;
|
||
tvs_resolve(host, &ipaddr);
|
||
|
||
return ipaddr;
|
||
}
|
||
|
||
void tvs_dns_fetch_all(tvs_http_client_callback_exit_loop should_exit_func,
|
||
tvs_http_client_callback_should_cancel should_cancel_func, void *exit_param)
|
||
{
|
||
const char *host = tvs_config_get_current_host();
|
||
int ipaddr = 0;
|
||
tvs_http_dns_start(host, should_exit_func, should_cancel_func, exit_param, &ipaddr);
|
||
TVS_LOG_PRINTF("tvs_dns_fetch_all http dns %d \n", ipaddr);
|
||
if (ipaddr != 0) {
|
||
do_lock();
|
||
g_http_dns_ip = ipaddr;
|
||
|
||
g_http_dns_ip_tmp = g_http_dns_ip;
|
||
TVS_LOG_PRINTF("get http dns %d - %s\n", ipaddr, inet_ntoa(*(struct in_addr *)&ipaddr));
|
||
do_unlock();
|
||
}
|
||
|
||
ipaddr = tvs_dns_system_start(host);
|
||
|
||
if (ipaddr != 0) {
|
||
do_lock();
|
||
if (g_http_dns_ip != ipaddr) {
|
||
g_system_dns_ip = ipaddr;
|
||
TVS_LOG_PRINTF("get system dns %d - %s\n", ipaddr, inet_ntoa(*(struct in_addr *)&ipaddr));
|
||
} else {
|
||
g_system_dns_ip = 0;
|
||
}
|
||
|
||
g_system_dns_ip_tmp = g_system_dns_ip;
|
||
|
||
do_unlock();
|
||
}
|
||
}
|
||
|
||
bool tvs_http_dns_check_start()
|
||
{
|
||
return true;
|
||
}
|
||
|
||
bool tvs_http_dns_remove_ip(int ip_addr)
|
||
{
|
||
if (ip_addr == 0) {
|
||
return false;
|
||
}
|
||
do_lock();
|
||
|
||
if (g_http_dns_ip_tmp == ip_addr) {
|
||
g_http_dns_ip_tmp = 0;
|
||
}
|
||
|
||
do_unlock();
|
||
|
||
return true;
|
||
}
|
||
|
||
int tvs_http_dns_get_count()
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
int tvs_system_dns_get_count()
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
int tvs_http_dns_get_next_ip(int index)
|
||
{
|
||
if (index != 0) {
|
||
return 0;
|
||
}
|
||
|
||
do_lock();
|
||
|
||
int ip = g_http_dns_ip_tmp;
|
||
|
||
do_unlock();
|
||
|
||
return ip;
|
||
}
|
||
|
||
bool tvs_system_dns_check_start()
|
||
{
|
||
return true;
|
||
}
|
||
|
||
|
||
int tvs_system_dns_get_next_ip(int index)
|
||
{
|
||
if (index != 0) {
|
||
return 0;
|
||
}
|
||
|
||
do_lock();
|
||
|
||
int ip = g_system_dns_ip_tmp;
|
||
|
||
do_unlock();
|
||
|
||
return ip;
|
||
}
|
||
|
||
bool tvs_system_dns_remove_ip(int ip_addr)
|
||
{
|
||
if (ip_addr == 0) {
|
||
return false;
|
||
}
|
||
do_lock();
|
||
|
||
if (g_system_dns_ip_tmp == ip_addr) {
|
||
g_system_dns_ip_tmp = 0;
|
||
}
|
||
|
||
do_unlock();
|
||
|
||
return true;
|
||
}
|
||
|
||
static void dns_thread_func(tvs_thread_handle_t *thread_handle_t);
|
||
|
||
int tvs_dns_init()
|
||
{
|
||
TVS_LOCKER_INIT
|
||
|
||
return 0;
|
||
}
|
||
|
||
int tvs_dns_uninit()
|
||
{
|
||
|
||
TVS_LOCKER_UNINIT
|
||
|
||
return 0;
|
||
}
|
||
|
||
void tvs_dns_get_first_ip()
|
||
{
|
||
// 首次连接,获取DNS IP,不进行echo校验,直接设置为valid ip
|
||
tvs_dns_fetch_all(NULL, NULL, NULL);
|
||
|
||
do_lock();
|
||
int ip = g_http_dns_ip == 0 ? g_system_dns_ip : g_http_dns_ip;
|
||
do_unlock();
|
||
|
||
if (ip != 0) {
|
||
tvs_ip_provider_set_valid_ip(ip, true);
|
||
} else {
|
||
// 如果系统dns和http dns都没有,那么使用兜底IP
|
||
tvs_ip_provider_set_valid_ip_ex(BACKUP_IP, true);
|
||
}
|
||
}
|
||
|
||
static void dns_thread_func(tvs_thread_handle_t *thread_handle_t)
|
||
{
|
||
tvs_dns_fetch_all(NULL, NULL, NULL);
|
||
|
||
int validip = 0;
|
||
|
||
do_lock();
|
||
int http_ip = g_http_dns_ip;
|
||
int system_ip = g_system_dns_ip;
|
||
do_unlock();
|
||
|
||
bool ret = tvs_echo_start(http_ip);
|
||
|
||
if (!ret) {
|
||
ret = tvs_echo_start(system_ip);
|
||
if (ret) {
|
||
validip = system_ip;
|
||
}
|
||
} else {
|
||
validip = http_ip;
|
||
}
|
||
|
||
if (validip != 0) {
|
||
tvs_ip_provider_set_valid_ip(validip, true);
|
||
}
|
||
}
|
||
|
||
|
||
static void tvs_dns_timer_func(void *param)
|
||
{
|
||
while (g_tvs_dns_start) {
|
||
dns_thread_func(NULL);
|
||
os_wrapper_wait_signal(g_tvs_dns_mutex, DNS_REFRESH_TIMER * 60 * 1000);
|
||
}
|
||
}
|
||
|
||
static void tvs_dns_refresh_start()
|
||
{
|
||
if (!g_tvs_dns_pid) {
|
||
if (!g_tvs_dns_mutex) {
|
||
g_tvs_dns_mutex = os_wrapper_create_signal_mutex(0);
|
||
}
|
||
g_tvs_dns_start = 1;
|
||
thread_fork("tvs_dns_thread", 20, 1024, 0, &g_tvs_dns_pid, tvs_dns_timer_func, NULL);
|
||
}
|
||
}
|
||
|
||
void tvs_dns_refresh_stop()
|
||
{
|
||
if (g_tvs_dns_pid) {
|
||
g_tvs_dns_start = 0;
|
||
os_wrapper_post_signal(g_tvs_dns_mutex);
|
||
thread_kill(&g_tvs_dns_pid, KILL_WAIT);
|
||
g_tvs_dns_pid = 0;
|
||
os_wrapper_delete_signal_mutex(&g_tvs_dns_mutex);
|
||
}
|
||
|
||
}
|
||
|
||
void tvs_dns_on_network_changed(bool connected)
|
||
{
|
||
TVS_LOG_PRINTF("network changed,dns:%d\n", connected);
|
||
if (connected) {
|
||
// 网络重连的时候,需要刷新DNS IP
|
||
tvs_dns_refresh_start();
|
||
} else {
|
||
tvs_dns_refresh_stop();
|
||
}
|
||
}
|