static int resolve_name(struct http_client_ctx *ctx, const char *server, enum dns_query_type type) { struct waiter dns_waiter; int ret; dns_waiter.ctx = ctx; k_sem_init(&dns_waiter.wait, 0, 1); ret = dns_get_addr_info(server, type, &ctx->dns_id, dns_cb, &dns_waiter, DNS_WAIT); if (ret < 0) { NET_ERR("Cannot resolve %s (%d)", server, ret); ctx->dns_id = 0; return ret; } /* Wait a little longer for the DNS to finish so that * the DNS will timeout before the semaphore. */ if (k_sem_take(&dns_waiter.wait, DNS_WAIT_SEM)) { NET_ERR("Timeout while resolving %s", server); ctx->dns_id = 0; return -ETIMEDOUT; } ctx->dns_id = 0; if (ctx->tcp.remote.family == AF_UNSPEC) { return -EINVAL; } return 0; }
STATIC mp_obj_t mod_getaddrinfo(size_t n_args, const mp_obj_t *args) { mp_obj_t host_in = args[0], port_in = args[1]; const char *host = mp_obj_str_get_str(host_in); mp_int_t family = 0; if (n_args > 2) { family = mp_obj_get_int(args[2]); } getaddrinfo_state_t state; // Just validate that it's int (void)mp_obj_get_int(port_in); state.port = port_in; state.result = mp_obj_new_list(0, NULL); k_sem_init(&state.sem, 0, UINT_MAX); for (int i = 2; i--;) { int type = (family != AF_INET6 ? DNS_QUERY_TYPE_A : DNS_QUERY_TYPE_AAAA); RAISE_ERRNO(dns_get_addr_info(host, type, NULL, dns_resolve_cb, &state, 3000)); k_sem_take(&state.sem, K_FOREVER); if (family != 0) { break; } family = AF_INET6; } // Raise error only if there's nothing to return, otherwise // it may be IPv4 vs IPv6 differences. mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(state.result)); if (state.status != 0 && len == 0) { mp_raise_OSError(state.status); } return state.result; }