Пример #1
0
static tb_long_t tb_dns_looker_resp(tb_dns_looker_impl_t* impl, tb_ipaddr_ref_t addr)
{
    // check
    tb_check_return_val(!(impl->step & TB_DNS_LOOKER_STEP_RESP), 1);

    // need wait if no data
    impl->step &= ~TB_DNS_LOOKER_STEP_NEVT;

    // recv response data
    tb_byte_t rpkt[4096];
    while (1)
    {
        // read data
        tb_long_t read = tb_socket_urecv(impl->sock, tb_null, rpkt, 4096);
        //tb_trace_d("read %d", read);
        tb_assert_and_check_return_val(read >= 0, -1);

        // no data? 
        if (!read)
        {
            // end? read x, read 0
            tb_check_break(!tb_static_buffer_size(&impl->rpkt));
    
            // abort? read 0, read 0
            tb_check_return_val(!impl->tryn, -1);
            
            // tryn++
            impl->tryn++;

            // continue 
            return 0;
        }
        else impl->tryn = 0;

        // copy data
        tb_static_buffer_memncat(&impl->rpkt, rpkt, read);
    }

    // done
    if (!tb_dns_looker_resp_done(impl, addr)) return -1;

    // check
    tb_assert_and_check_return_val(tb_static_string_size(&impl->name) && !tb_ipaddr_ip_is_empty(addr), -1);

    // save address to cache
    tb_dns_cache_set(tb_static_string_cstr(&impl->name), addr);

    // finish it
    impl->step |= TB_DNS_LOOKER_STEP_RESP;
    impl->tryn = 0;

    // reset rpkt
    impl->size = 0;
    tb_static_buffer_clear(&impl->rpkt);

    // ok
    tb_trace_d("response: ok");
    return 1;
}
Пример #2
0
static tb_long_t tb_dns_looker_resp(tb_dns_looker_t* looker, tb_ipaddr_ref_t addr)
{
    // check
    tb_check_return_val(!(looker->step & TB_DNS_LOOKER_STEP_RESP), 1);

    // need wait if no data
    looker->step &= ~TB_DNS_LOOKER_STEP_NEVT;

    // recv response data
    tb_size_t  size = tb_static_buffer_size(&looker->rpkt);
    tb_size_t  maxn = tb_static_buffer_maxn(&looker->rpkt);
    tb_byte_t* data = tb_static_buffer_data(&looker->rpkt);
    while (size < maxn)
    {
        // read data
        tb_long_t read = tb_socket_urecv(looker->sock, tb_null, data + size, maxn - size);
        tb_assert_and_check_return_val(read >= 0, -1);

        // no data? 
        if (!read)
        {
            // end? read x, read 0
            tb_check_break(!tb_static_buffer_size(&looker->rpkt));
    
            // abort? read 0, read 0
            tb_check_return_val(!looker->tryn, -1);
            
            // tryn++
            looker->tryn++;

            // continue 
            return 0;
        }
        else looker->tryn = 0;

        // update buffer size
        tb_static_buffer_resize(&looker->rpkt, size + read);
        size = tb_static_buffer_size(&looker->rpkt);
    }

    // done
    if (!tb_dns_looker_resp_done(looker, addr)) return -1;

    // check
    tb_assert_and_check_return_val(tb_static_string_size(&looker->name) && !tb_ipaddr_ip_is_empty(addr), -1);

    // save address to cache
    tb_dns_cache_set(tb_static_string_cstr(&looker->name), addr);

    // finish it
    looker->step |= TB_DNS_LOOKER_STEP_RESP;
    looker->tryn = 0;

    // reset rpkt
    looker->size = 0;
    tb_static_buffer_clear(&looker->rpkt);

    // ok
    tb_trace_d("response: ok");
    return 1;
}
Пример #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;
}