EV-cares

 view release on metacpan or  search on metacpan

cares.xs  view on Meta::CPAN

        CONST_IV(stash, T_TXT);
        CONST_IV(stash, T_AAAA);
        CONST_IV(stash, T_SRV);
        CONST_IV(stash, T_NAPTR);
        CONST_IV(stash, T_DS);
        CONST_IV(stash, T_RRSIG);
        CONST_IV(stash, T_DNSKEY);
        CONST_IV(stash, T_TLSA);
        CONST_IV(stash, T_SVCB);
        CONST_IV(stash, T_HTTPS);
        CONST_IV(stash, T_CAA);
        CONST_IV(stash, T_ANY);

        /* DNS classes */
        CONST_IV(stash, C_IN);
        CONST_IV(stash, C_CHAOS);
        CONST_IV(stash, C_HS);
        CONST_IV(stash, C_ANY);

        /* channel flags */
        CONST_IV(stash, ARES_FLAG_USEVC);
        CONST_IV(stash, ARES_FLAG_PRIMARY);
        CONST_IV(stash, ARES_FLAG_IGNTC);
        CONST_IV(stash, ARES_FLAG_NORECURSE);
        CONST_IV(stash, ARES_FLAG_STAYOPEN);
        CONST_IV(stash, ARES_FLAG_NOSEARCH);
        CONST_IV(stash, ARES_FLAG_NOALIASES);
        CONST_IV(stash, ARES_FLAG_NOCHECKRESP);
        CONST_IV(stash, ARES_FLAG_EDNS);
        CONST_IV(stash, ARES_FLAG_NO_DFLT_SVR);
        CONST_IV(stash, ARES_FLAG_DNS0x20);

        /* addrinfo hint flags */
        CONST_IV(stash, ARES_AI_CANONNAME);
        CONST_IV(stash, ARES_AI_NUMERICHOST);
        CONST_IV(stash, ARES_AI_PASSIVE);
        CONST_IV(stash, ARES_AI_NUMERICSERV);
        CONST_IV(stash, ARES_AI_V4MAPPED);
        CONST_IV(stash, ARES_AI_ALL);
        CONST_IV(stash, ARES_AI_ADDRCONFIG);
        CONST_IV(stash, ARES_AI_NOSORT);

        /* nameinfo flags */
        CONST_IV(stash, ARES_NI_NOFQDN);
        CONST_IV(stash, ARES_NI_NUMERICHOST);
        CONST_IV(stash, ARES_NI_NAMEREQD);
        CONST_IV(stash, ARES_NI_NUMERICSERV);
        CONST_IV(stash, ARES_NI_DGRAM);
        CONST_IV(stash, ARES_NI_TCP);
        CONST_IV(stash, ARES_NI_UDP);

        /* address families */
        CONST_IV(stash, AF_INET);
        CONST_IV(stash, AF_INET6);
        CONST_IV(stash, AF_UNSPEC);
    }
}

void
new(class, ...)
PPCODE:
{
    const char *class_name = SvPV_nolen(ST(0));
    ev_cares_t *self;
    struct ares_options opts;
    int optmask = 0;
    int status, i;
    const char *servers = NULL;
    struct ev_loop *loop_ptr = EV_DEFAULT;
    SV *loop_sv = NULL;

    if ((items - 1) % 2 != 0)
        croak("EV::cares::new: odd number of arguments");

    memset(&opts, 0, sizeof(opts));

    for (i = 1; i < items; i += 2) {
        const char *key = SvPV_nolen(ST(i));
        SV *val = ST(i + 1);

        if (strEQ(key, "loop")) {
            if (SvOK(val)) {
                if (!SvROK(val) || !sv_derived_from(val, "EV::Loop"))
                    croak("EV::cares::new: 'loop' must be an EV::Loop instance");
                /* SvIV (not SvIVX) so any get-magic on the inner SV is
                   honoured before extracting the loop pointer. */
                loop_ptr = INT2PTR(struct ev_loop *, SvIV(SvRV(val)));
                loop_sv = val;  /* refcount bumped after struct alloc */
            }
        }
        else if (strEQ(key, "timeout")) {
            opts.timeout = (int)(SvNV(val) * 1000);
            optmask |= ARES_OPT_TIMEOUTMS;
        }
        else if (strEQ(key, "tries")) {
            opts.tries = SvIV(val);
            optmask |= ARES_OPT_TRIES;
        }
        else if (strEQ(key, "ndots")) {
            opts.ndots = SvIV(val);
            optmask |= ARES_OPT_NDOTS;
        }
        else if (strEQ(key, "flags")) {
            opts.flags = SvIV(val);
            optmask |= ARES_OPT_FLAGS;
        }
        else if (strEQ(key, "lookups")) {
            opts.lookups = SvPV_nolen(val);  /* c-ares copies internally */
            optmask |= ARES_OPT_LOOKUPS;
        }
        else if (strEQ(key, "tcp_port")) {
            opts.tcp_port = (unsigned short)SvUV(val);
            optmask |= ARES_OPT_TCP_PORT;
        }
        else if (strEQ(key, "udp_port")) {
            opts.udp_port = (unsigned short)SvUV(val);
            optmask |= ARES_OPT_UDP_PORT;
        }
        else if (strEQ(key, "servers")) {
            if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
                AV *av = (AV *)SvRV(val);

cares.xs  view on Meta::CPAN

    else if (family == AF_INET6) min_len = sizeof(struct sockaddr_in6);
    else croak("EV::cares::getnameinfo: unsupported sockaddr family %d "
               "(need AF_INET or AF_INET6)", (int)family);
    if (len < min_len)
        croak("EV::cares::getnameinfo: sockaddr too short for %s (%d bytes)",
              family == AF_INET6 ? "AF_INET6" : "AF_INET", (int)len);

    req = new_req(aTHX_ self, cb);
    ARES_CALL_BEGIN(self);
    ares_getnameinfo(self->channel, (const struct sockaddr *)&ss,
                     (ares_socklen_t)len, flags, nameinfo_cb, req);
    ARES_CALL_END(self);
}

void
cancel(self)
    EV::cares self
CODE:
    REQUIRE_LIVE(self);
    ARES_CALL_BEGIN(self);
    ares_cancel(self->channel);
    ARES_CALL_END(self);

void
set_servers(self, ...)
    EV::cares self
CODE:
{
    SV *csv;
    int rc, i;

    REQUIRE_LIVE(self);
    if (items <= 1)
        croak("EV::cares::set_servers: requires at least one server address");

    /* accept either a single arrayref or a flat list, mirroring `new(servers => ...)` */
    if (items == 2 && SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVAV) {
        AV *av = (AV *)SvRV(ST(1));
        if (av_len(av) < 0)
            croak("EV::cares::set_servers: empty arrayref");
        csv = av_to_csv(aTHX_ av);
    } else {
        csv = sv_2mortal(newSVpvs(""));
        for (i = 1; i < items; i++) {
            if (SvROK(ST(i)))
                croak("EV::cares::set_servers: arg %d is a reference; "
                      "use the arrayref form for {host,port} hashrefs", i);
            if (i > 1) sv_catpvs(csv, ",");
            sv_catsv(csv, ST(i));
        }
    }

    rc = ares_set_servers_csv(self->channel, SvPV_nolen(csv));
    if (rc != ARES_SUCCESS)
        croak("EV::cares::set_servers: %s", ares_strerror(rc));
}

void
servers(self)
    EV::cares self
PPCODE:
{
    char *csv;
    REQUIRE_LIVE(self);
    csv = ares_get_servers_csv(self->channel);
    if (!csv) croak("EV::cares::servers: ares_get_servers_csv failed");
    mXPUSHp(csv, strlen(csv));
    ares_free_string(csv);
}

void
set_local_dev(self, dev)
    EV::cares self
    const char *dev
CODE:
    REQUIRE_LIVE(self);
    ares_set_local_dev(self->channel, dev);

void
set_local_ip4(self, ip)
    EV::cares self
    const char *ip
CODE:
{
    struct in_addr addr;
    REQUIRE_LIVE(self);
    if (inet_pton(AF_INET, ip, &addr) != 1)
        croak("EV::cares::set_local_ip4: invalid IPv4 address: %s", ip);
    ares_set_local_ip4(self->channel, ntohl(addr.s_addr));
}

void
set_local_ip6(self, ip)
    EV::cares self
    const char *ip
CODE:
{
    struct in6_addr addr;
    REQUIRE_LIVE(self);
    if (inet_pton(AF_INET6, ip, &addr) != 1)
        croak("EV::cares::set_local_ip6: invalid IPv6 address: %s", ip);
    ares_set_local_ip6(self->channel, (const unsigned char *)&addr);
}

int
active_queries(self)
    EV::cares self
CODE:
    RETVAL = self->active_queries;
OUTPUT:
    RETVAL

int
last_query_timeouts(self)
    EV::cares self
CODE:
    RETVAL = self->last_timeouts;
OUTPUT:
    RETVAL

int



( run in 0.942 second using v1.01-cache-2.11-cpan-5511b514fd6 )