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; }
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; }
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; }