/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ tb_dns_looker_ref_t tb_dns_looker_init(tb_char_t const* name) { // check tb_assert_and_check_return_val(name, tb_null); // must be not address tb_assert(!tb_ipaddr_ip_cstr_set(tb_null, name, TB_IPADDR_FAMILY_NONE)); // done tb_bool_t ok = tb_false; tb_dns_looker_t* looker = tb_null; do { // make looker looker = tb_malloc0_type(tb_dns_looker_t); tb_assert_and_check_return_val(looker, tb_null); // dump server // tb_dns_server_dump(); // get the dns server list looker->maxn = tb_dns_server_get(looker->list); tb_check_break(looker->maxn && looker->maxn <= tb_arrayn(looker->list)); // init name if (!tb_static_string_init(&looker->name, (tb_char_t*)looker->data, TB_DNS_NAME_MAXN)) break; tb_static_string_cstrcpy(&looker->name, name); // init rpkt if (!tb_static_buffer_init(&looker->rpkt, looker->data + TB_DNS_NAME_MAXN, TB_DNS_RPKT_MAXN)) break; // init family looker->family = TB_IPADDR_FAMILY_IPV4; // init sock looker->sock = tb_socket_init(TB_SOCKET_TYPE_UDP, looker->family); tb_assert_and_check_break(looker->sock); // init itor looker->itor = 1; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (looker) tb_dns_looker_exit((tb_dns_looker_ref_t)looker); looker = tb_null; } // ok? return (tb_dns_looker_ref_t)looker; }
tb_bool_t tb_aicp_dns_done(tb_aicp_dns_ref_t dns, tb_char_t const* host, tb_long_t timeout, tb_aicp_dns_done_func_t func, tb_cpointer_t priv) { // check tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)dns; tb_assert_and_check_return_val(impl && func && host && host[0], tb_false); // trace tb_trace_d("done: aico: %p, host: %s: ..", impl->aico, host); // init func impl->done.func = func; impl->done.priv = priv; // save host tb_strlcpy(impl->host, host, sizeof(impl->host)); // only address? ok tb_ipaddr_t addr = {0}; if (tb_ipaddr_ip_cstr_set(&addr, impl->host, TB_IPADDR_FAMILY_NONE)) { impl->done.func(dns, impl->host, &addr, impl->done.priv); return tb_true; } // try to lookup it from cache first if (tb_dns_cache_get(impl->host, &addr)) { impl->done.func(dns, impl->host, &addr, impl->done.priv); return tb_true; } // init server list if (!impl->size) impl->size = tb_dns_server_get(impl->list); tb_check_return_val(impl->size, tb_false); // get the server tb_ipaddr_ref_t server = &impl->list[impl->indx = 0]; tb_assert_and_check_return_val(!tb_ipaddr_is_empty(server), tb_false); // init reqt tb_size_t size = tb_aicp_dns_reqt_init(impl); tb_assert_and_check_return_val(size, tb_false); // init it first if no aico if (!impl->aico) { // init aico impl->aico = tb_aico_init(impl->aicp); tb_assert_and_check_return_val(impl->aico, tb_false); // open aico if (!tb_aico_open_sock_from_type(impl->aico, TB_SOCKET_TYPE_UDP, tb_ipaddr_family(server))) return tb_false; // init timeout tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_SEND, timeout); tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_RECV, timeout); } // post reqt return tb_aico_usend(impl->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl); }