Exemple #1
0
tb_bool_t tb_dns_looker_done(tb_char_t const* name, tb_ipaddr_ref_t addr)
{
    // check
    tb_assert_and_check_return_val(name && addr, tb_false);

    // try to lookup it from cache first
    if (tb_dns_cache_get(name, addr)) return tb_true;

    // init looker
    tb_dns_looker_ref_t looker = tb_dns_looker_init(name);
    tb_check_return_val(looker, tb_false);

    // spak
    tb_long_t r = -1;
    while (!(r = tb_dns_looker_spak(looker, addr)))
    {
        // wait
        r = tb_dns_looker_wait(looker, TB_DNS_LOOKER_TIMEOUT);
        tb_assert_and_check_break(r >= 0);
    }

    // exit
    tb_dns_looker_exit(looker);

    // ok
    return r > 0? tb_true : tb_false;
}
Exemple #2
0
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);
}
Exemple #3
0
static tb_bool_t tb_aicp_dns_resp_func(tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_URECV, tb_false);

    // the aicp
    tb_aicp_ref_t aicp = (tb_aicp_ref_t)tb_aico_aicp(aice->aico);
    tb_assert_and_check_return_val(aicp, tb_false);
    
    // the impl
    tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)aice->priv; 
    tb_assert_and_check_return_val(impl, tb_false);

    // done
    tb_ipaddr_t addr = {0};
    if (aice->state == TB_STATE_OK)
    {
        // trace
        tb_trace_d("resp[%s]: aico: %p, server: %{ipaddr}, real: %lu", impl->host, impl->aico, &aice->u.urecv.addr, aice->u.urecv.real);

        // check
        tb_assert_and_check_return_val(aice->u.urecv.real, tb_false);

        // done resp
        tb_aicp_dns_resp_done(impl, aice->u.urecv.real, &addr);
    }
    // timeout or failed?
    else
    {
        // trace
        tb_trace_d("resp[%s]: aico: %p, state: %s", impl->host, impl->aico, tb_state_cstr(aice->state));
    }

    // ok or try to get ok from cache again if failed or timeout? 
    tb_bool_t from_cache = tb_false;
    if (!tb_ipaddr_ip_is_empty(&addr) || (from_cache = tb_dns_cache_get(impl->host, &addr))) 
    {
        // save to cache 
        if (!from_cache) tb_dns_cache_set(impl->host, &addr);
        
        // done func
        impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, &addr, impl->done.priv);
        return tb_true;
    }

    // try next server?
    tb_bool_t           ok = tb_false;
    tb_ipaddr_ref_t     server = &impl->list[impl->indx + 1];
    if (!tb_ipaddr_is_empty(server))
    {   
        // indx++
        impl->indx++;

        // init reqt
        tb_size_t size = tb_aicp_dns_reqt_init(impl);
        if (size)
        {
            // post reqt
            ok = tb_aico_usend(aice->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl);
        }
    }

    // failed? done func
    if (!ok) impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, tb_null, impl->done.priv);

    // continue
    return tb_true;
}