Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}