EV-ADNS
view release on metacpan or search on metacpan
#include "XSUB.h"
#include <poll.h>
#define ADNS_FEATURE_MANYAF
#include <adns.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "EVAPI.h"
#define DEFAULT_INIT_FLAGS \
adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn \
| adns_if_noautosys | adns_if_permit_ipv4 | adns_if_permit_ipv6
static struct pollfd *fds;
static int nfd, mfd;
static ev_io *iow;
static ev_timer tw;
static ev_idle iw;
static ev_prepare pw;
static struct timeval tv_now;
static int outstanding;
static void
outstanding_inc (adns_state ads)
{
if (!outstanding++)
ev_prepare_start (EV_DEFAULT, &pw);
}
static void
outstanding_dec (adns_state ads)
{
--outstanding;
}
struct ctx
{
SV *self;
adns_state ads;
adns_query query;
SV *cb;
};
static SV *
ip_to_sv (int family, void *addr)
{
char buf[128];
return newSVpv (inet_ntop (family, addr, buf, sizeof buf), 0);
}
static SV *
addr_to_sv (adns_rr_addr *addr)
{
return ip_to_sv (addr->addr.sa.sa_family,
addr->addr.sa.sa_family == AF_INET6
? (void *)&addr->addr.inet6.sin6_addr
: (void *)&addr->addr.inet.sin_addr);
}
static SV *
ha2sv (adns_rr_hostaddr *rr)
{
int i;
AV *av = newAV ();
av_push (av, newSVpv (rr->host, 0));
av_push (av, newSViv (rr->astatus));
for (i = 0; i < rr->naddrs; ++i)
av_push (av, addr_to_sv (rr->addrs + i));
return newRV_noinc ((SV *)av);
}
static void
process (adns_state ads)
{
dSP;
ENTER;
SAVETMPS;
for (;;)
{
int i;
adns_query q = 0;
adns_answer *a;
void *ctx;
SV *cb;
struct ctx *c;
int r = adns_check (ads, &q, &a, &ctx);
if (r)
break;
c = (struct ctx *)ctx;
cb = c->cb;
c->cb = 0; outstanding_dec (ads);
SvREFCNT_dec (c->self);
assert (cb);
PUSHMARK (SP);
EXTEND (SP, a->nrrs + 2);
PUSHs (sv_2mortal (newSViv (a->status)));
PUSHs (sv_2mortal (newSViv (a->expires)));
for (i = 0; i < a->nrrs; ++i)
{
SV *sv;
switch (a->type & adns_r_unknown ? adns_r_unknown : a->type)
{
case adns_r_ns_raw:
case adns_r_cname:
case adns_r_ptr:
( run in 0.686 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )