Branch Coverage

cares.xs
Criterion Covered Total %
branch 421 730 57.6


line true false branch
200 29 6 for (i = 0; i < len; i++) {
202 0 29 if (!elem) continue;
205 2 27 if (SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
2 0 if (SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
209 0 2 if (!host)
212 1 1 if (written++) sv_catpvs(csv, ",");
214 1 1 if (port) sv_catpvf(csv, ":%d", (int)SvIV(*port));
216 22 5 if (written++) sv_catpvs(csv, ",");
238 1 93 if (self->destroyed) return;
240 47 46 if (readable) events |= EV_READ;
241 0 93 if (writable) events |= EV_WRITE;
244 834 47 for (i = 0; i < MAX_IO; i++)
245 46 788 if (self->ios[i].fd == fd) break;
247 47 46 if (events) {
248 47 0 if (i == MAX_IO) {
250 83 0 for (i = 0; i < MAX_IO; i++)
251 47 36 if (self->ios[i].fd == ARES_SOCKET_BAD) break;
252 0 47 if (i == MAX_IO) {
268 46 0 if (i < MAX_IO) {
283 0 42 if (self->destroyed) return;
285 72 0 for (i = 0; i < MAX_IO; i++) {
286 42 30 if (&self->ios[i].watcher == w) {
287 42 0 if (revents & EV_READ) rfd = self->ios[i].fd;
288 0 42 if (revents & EV_WRITE) wfd = self->ios[i].fd;
293 0 42 if ((revents & EV_ERROR) &&
0 0 if ((revents & EV_ERROR) &&
294 0 0 rfd == ARES_SOCKET_BAD && wfd == ARES_SOCKET_BAD)
302 42 0 ARES_CALL_END(self);
0 42 ARES_CALL_END(self);
309 0 0 if (self->destroyed) return;
313 0 0 ARES_CALL_END(self);
0 0 ARES_CALL_END(self);
320 4 297 if (self->destroyed) return;
324 62 235 if (tvp) {
326 0 62 if (after < 0.001) after = 0.001;
336 14 97 if (self->destroyed) return;
340 1552 97 for (i = 0; i < MAX_IO; i++) {
341 1 1551 if (self->ios[i].fd != ARES_SOCKET_BAD) {
352 3 94 if (self->loop_sv) {
397 0 67 CB_PROLOGUE(arg, status);
0 67 CB_PROLOGUE(arg, status);
399 48 19 if (result) {
400 48 0 if (status == ARES_SUCCESS) {
403 0 48 const char *cname = result->cnames ? result->cnames->name : NULL;
404 98 48 for (node = result->nodes; node; node = node->ai_next) {
406 59 39 if (node->ai_family == AF_INET) {
409 39 0 } else if (node->ai_family == AF_INET6) {
415 7 91 if (req->with_ttl) {
421 0 7 if (cname)
423 0 7 mXPUSHs(newRV_noinc((SV *)hv));
425 0 91 mXPUSHp(ip, strlen(ip));
432 67 0 CB_EPILOGUE;
1 66 CB_EPILOGUE;
1 0 CB_EPILOGUE;
1 0 CB_EPILOGUE;
67 0 CB_EPILOGUE;
2 65 CB_EPILOGUE;
0 2 CB_EPILOGUE;
437 0 4 CB_PROLOGUE(arg, status);
0 4 CB_PROLOGUE(arg, status);
439 4 0 if (status == ARES_SUCCESS && hostent) {
4 0 if (status == ARES_SUCCESS && hostent) {
440 3 1 if (req->by_addr) {
442 3 0 if (hostent->h_name)
443 0 3 mXPUSHp(hostent->h_name, strlen(hostent->h_name));
444 3 0 if (hostent->h_aliases) {
446 1 3 for (p = hostent->h_aliases; *p; p++)
447 0 1 mXPUSHp(*p, strlen(*p));
452 1 1 for (p = hostent->h_addr_list; *p; p++) {
454 1 0 if (hostent->h_addrtype == AF_INET)
458 0 1 mXPUSHp(ip, strlen(ip));
463 4 0 CB_EPILOGUE;
0 4 CB_EPILOGUE;
0 0 CB_EPILOGUE;
0 0 CB_EPILOGUE;
4 0 CB_EPILOGUE;
0 4 CB_EPILOGUE;
0 0 CB_EPILOGUE;
468 0 35 CB_PROLOGUE(arg, status);
0 35 CB_PROLOGUE(arg, status);
470 3 32 if (status == ARES_SUCCESS && abuf && alen > 0)
3 0 if (status == ARES_SUCCESS && abuf && alen > 0)
3 0 if (status == ARES_SUCCESS && abuf && alen > 0)
471 0 3 mXPUSHp((char *)abuf, alen);
473 35 0 CB_EPILOGUE;
0 35 CB_EPILOGUE;
0 0 CB_EPILOGUE;
0 0 CB_EPILOGUE;
35 0 CB_EPILOGUE;
0 35 CB_EPILOGUE;
0 0 CB_EPILOGUE;
478 0 20 CB_PROLOGUE(arg, status);
0 20 CB_PROLOGUE(arg, status);
480 19 1 if (status == ARES_SUCCESS && abuf && alen > 0) {
19 0 if (status == ARES_SUCCESS && abuf && alen > 0) {
19 0 if (status == ARES_SUCCESS && abuf && alen > 0) {
485 7 0 if (ares_parse_a_reply(abuf, alen, &host, NULL, NULL) == ARES_SUCCESS && host) {
7 0 if (ares_parse_a_reply(abuf, alen, &host, NULL, NULL) == ARES_SUCCESS && host) {
487 18 7 for (p = host->h_addr_list; *p; p++) {
490 0 18 mXPUSHp(ip, strlen(ip));
499 1 0 if (ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL) == ARES_SUCCESS && host) {
1 0 if (ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL) == ARES_SUCCESS && host) {
501 4 1 for (p = host->h_addr_list; *p; p++) {
504 0 4 mXPUSHp(ip, strlen(ip));
513 1 0 if (ares_parse_mx_reply(abuf, alen, &mx_out) == ARES_SUCCESS && mx_out) {
1 0 if (ares_parse_mx_reply(abuf, alen, &mx_out) == ARES_SUCCESS && mx_out) {
515 1 1 for (mx = mx_out; mx; mx = mx->next) {
519 0 1 mXPUSHs(newRV_noinc((SV *)hv));
528 1 0 if (ares_parse_srv_reply(abuf, alen, &srv_out) == ARES_SUCCESS && srv_out) {
1 0 if (ares_parse_srv_reply(abuf, alen, &srv_out) == ARES_SUCCESS && srv_out) {
530 1 1 for (srv = srv_out; srv; srv = srv->next) {
536 0 1 mXPUSHs(newRV_noinc((SV *)hv));
545 1 0 if (ares_parse_txt_reply_ext(abuf, alen, &txt_out) == ARES_SUCCESS && txt_out) {
1 0 if (ares_parse_txt_reply_ext(abuf, alen, &txt_out) == ARES_SUCCESS && txt_out) {
548 13 1 for (txt = txt_out; txt; txt = txt->next) {
549 0 13 if (txt->record_start || !current) {
0 0 if (txt->record_start || !current) {
550 12 1 if (current) mXPUSHs(current);
0 12 if (current) mXPUSHs(current);
556 1 0 if (current) mXPUSHs(current);
0 1 if (current) mXPUSHs(current);
564 1 0 if (ares_parse_ns_reply(abuf, alen, &host) == ARES_SUCCESS && host) {
1 0 if (ares_parse_ns_reply(abuf, alen, &host) == ARES_SUCCESS && host) {
565 1 0 if (host->h_aliases) {
567 4 1 for (p = host->h_aliases; *p; p++)
568 0 4 mXPUSHp(*p, strlen(*p));
577 1 0 if (ares_parse_soa_reply(abuf, alen, &soa) == ARES_SUCCESS && soa) {
1 0 if (ares_parse_soa_reply(abuf, alen, &soa) == ARES_SUCCESS && soa) {
586 0 1 mXPUSHs(newRV_noinc((SV *)hv));
596 0 0 if (ares_parse_ptr_reply(abuf, alen, NULL, 0, AF_UNSPEC, &host) == ARES_SUCCESS && host) {
0 0 if (ares_parse_ptr_reply(abuf, alen, NULL, 0, AF_UNSPEC, &host) == ARES_SUCCESS && host) {
597 0 0 if (host->h_name)
598 0 0 mXPUSHp(host->h_name, strlen(host->h_name));
599 0 0 if (host->h_aliases) {
601 0 0 for (p = host->h_aliases; *p; p++)
602 0 0 mXPUSHp(*p, strlen(*p));
611 1 0 if (ares_parse_naptr_reply(abuf, alen, &naptr_out) == ARES_SUCCESS && naptr_out) {
1 0 if (ares_parse_naptr_reply(abuf, alen, &naptr_out) == ARES_SUCCESS && naptr_out) {
613 3 1 for (n = naptr_out; n; n = n->next) {
621 0 3 mXPUSHs(newRV_noinc((SV *)hv));
630 1 0 if (ares_parse_caa_reply(abuf, alen, &caa_out) == ARES_SUCCESS && caa_out) {
1 0 if (ares_parse_caa_reply(abuf, alen, &caa_out) == ARES_SUCCESS && caa_out) {
632 11 1 for (c = caa_out; c; c = c->next) {
637 0 11 mXPUSHs(newRV_noinc((SV *)hv));
652 2 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
2 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
655 3 2 for (i = 0; i < cnt; i++) {
663 0 3 if (ares_dns_rr_get_type(rr) != ARES_REC_TYPE_RAW_RR)
666 0 3 if (raw_type != req->qtype) continue;
669 0 3 if (!rd) continue;
672 1 2 if (raw_type == T_DS && rdlen >= 4) {
1 0 if (raw_type == T_DS && rdlen >= 4) {
678 2 0 } else if (raw_type == T_DNSKEY && rdlen >= 4) {
2 0 } else if (raw_type == T_DNSKEY && rdlen >= 4) {
684 0 0 } else if (raw_type == T_RRSIG && rdlen >= 18) {
0 0 } else if (raw_type == T_RRSIG && rdlen >= 18) {
691 0 0 while (pos < rdlen) {
694 0 0 if (l == 0) { saw_null_label = 1; break; }
695 0 0 if ((l & 0xc0) || pos + l > rdlen) {
0 0 if ((l & 0xc0) || pos + l > rdlen) {
700 0 0 if (snlen + need >= sizeof signer) {
704 0 0 if (snlen) signer[snlen++] = '.';
713 0 0 if (pos > rdlen || signer_overflow || !saw_null_label) {
0 0 if (pos > rdlen || signer_overflow || !saw_null_label) {
0 0 if (pos > rdlen || signer_overflow || !saw_null_label) {
740 0 3 mXPUSHs(newRV_noinc((SV *)hv));
749 1 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
1 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
752 2 1 for (i = 0; i < cnt; i++) {
759 0 2 if (ares_dns_rr_get_type(rr) != ARES_REC_TYPE_TLSA) continue;
769 2 0 hv_stores(hv, "data",
2 0 hv_stores(hv, "data",
771 0 2 mXPUSHs(newRV_noinc((SV *)hv));
781 1 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
1 0 if (ares_dns_parse(abuf, alen, 0, &dnsrec) == ARES_SUCCESS && dnsrec) {
784 1 1 for (i = 0; i < cnt; i++) {
794 1 0 if (rtype == ARES_REC_TYPE_HTTPS) {
798 0 0 } else if (rtype == ARES_REC_TYPE_SVCB) {
811 1 0 hv_stores(hv, "target", newSVpv(target ? target : "", 0));
815 3 1 for (j = 0; j < opt_cnt; j++) {
825 2 1 while (pos < vlen) {
828 2 0 if (plen == 0 || pos + plen > vlen) break;
2 0 if (plen == 0 || pos + plen > vlen) break;
839 0 0 if (vlen >= 2)
846 2 1 for (pos = 0; pos + 4 <= vlen; pos += 4) {
864 2 1 for (pos = 0; pos + 16 <= vlen; pos += 16) {
888 0 1 mXPUSHs(newRV_noinc((SV *)hv));
897 0 0 mXPUSHp((char *)abuf, alen);
902 20 0 CB_EPILOGUE;
0 20 CB_EPILOGUE;
0 0 CB_EPILOGUE;
0 0 CB_EPILOGUE;
20 0 CB_EPILOGUE;
0 20 CB_EPILOGUE;
0 0 CB_EPILOGUE;
907 0 1 CB_PROLOGUE(arg, status);
0 1 CB_PROLOGUE(arg, status);
909 1 0 if (status == ARES_SUCCESS) {
910 1 0 if (node)
911 0 1 mXPUSHp(node, strlen(node));
913 0 0 XPUSHs(&PL_sv_undef);
915 0 1 if (service)
916 0 0 mXPUSHp(service, strlen(service));
918 0 1 XPUSHs(&PL_sv_undef);
921 1 0 CB_EPILOGUE;
0 1 CB_EPILOGUE;
0 0 CB_EPILOGUE;
0 0 CB_EPILOGUE;
1 0 CB_EPILOGUE;
0 1 CB_EPILOGUE;
0 0 CB_EPILOGUE;
929 0 19 I_EV_API("EV::cares");
19 0 I_EV_API("EV::cares");
0 19 I_EV_API("EV::cares");
932 0 19 if (rc != ARES_SUCCESS)
1043 0 100 if ((items - 1) % 2 != 0)
1048 118 97 for (i = 1; i < items; i += 2) {
1052 6 112 if (strEQ(key, "loop")) {
1053 5 1 if (SvOK(val)) {
1054 4 1 if (!SvROK(val) || !sv_derived_from(val, "EV::Loop"))
1 3 if (!SvROK(val) || !sv_derived_from(val, "EV::Loop"))
1062 18 94 else if (strEQ(key, "timeout")) {
1066 17 77 else if (strEQ(key, "tries")) {
1070 1 76 else if (strEQ(key, "ndots")) {
1074 7 69 else if (strEQ(key, "flags")) {
1078 48 21 else if (strEQ(key, "lookups")) {
1082 0 21 else if (strEQ(key, "tcp_port")) {
1086 0 21 else if (strEQ(key, "udp_port")) {
1090 5 16 else if (strEQ(key, "servers")) {
1091 5 0 if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
5 0 if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV) {
1093 1 4 if (av_len(av) < 0)
1100 2 14 else if (strEQ(key, "rotate")) {
1101 2 0 if (SvTRUE(val)) {
1105 1 13 }
1109 1 12 opts.ednspsz = SvIV(val);
1113 9 3 #ifdef ARES_OPT_RESOLVCONF
1117 1 2 }
1121 1 1 opts.hosts_path = SvPV_nolen(val); /* c-ares copies internally */
1125 1 0 #ifdef ARES_OPT_UDP_MAX_QUERIES
1140 3 94 optmask |= ARES_OPT_QUERY_CACHE;
1141 1552 97 }
1149 0 97 self->magic = EV_CARES_MAGIC;
1150 0 0 self->loop = loop_ptr;
1155 4 93 for (i = 0; i < MAX_IO; i++)
1157 0 4
1159 0 0 opts.sock_state_cb_data = self;
1171 0 97 if (status != ARES_SUCCESS) {
1199 0 60 REQUIRE_LIVE(self);
2 58 REQUIRE_LIVE(self);
1200 57 1 REQUIRE_CB(cb);
0 57 REQUIRE_CB(cb);
1209 56 1 ARES_CALL_END(self);
0 56 ARES_CALL_END(self);
1222 0 4 REQUIRE_LIVE(self);
0 4 REQUIRE_LIVE(self);
1223 4 0 REQUIRE_CB(cb);
0 4 REQUIRE_CB(cb);
1233 4 0 ARES_CALL_END(self);
0 4 ARES_CALL_END(self);
1245 6 0 const char *c_node = SvOK(node) ? SvPV_nolen(node) : NULL;
1246 1 5 const char *c_service = SvOK(service) ? SvPV_nolen(service) : NULL;
1250 0 6 REQUIRE_LIVE(self);
0 6 REQUIRE_LIVE(self);
1251 6 0 REQUIRE_CB(cb);
0 6 REQUIRE_CB(cb);
1259 6 0 if (SvROK(hints_hv) && SvTYPE(SvRV(hints_hv)) == SVt_PVHV) {
6 0 if (SvROK(hints_hv) && SvTYPE(SvRV(hints_hv)) == SVt_PVHV) {
1262 6 0 if ((sv = hv_fetchs(hv, "family", 0))) hints.ai_family = SvIV(*sv);
1263 0 6 if ((sv = hv_fetchs(hv, "socktype", 0))) hints.ai_socktype = SvIV(*sv);
1264 0 6 if ((sv = hv_fetchs(hv, "protocol", 0))) hints.ai_protocol = SvIV(*sv);
1265 0 6 if ((sv = hv_fetchs(hv, "flags", 0))) hints.ai_flags = SvIV(*sv);
1266 1 5 if ((sv = hv_fetchs(hv, "ttl", 0)) && SvTRUE(*sv))
1 0 if ((sv = hv_fetchs(hv, "ttl", 0)) && SvTRUE(*sv))
1272 6 0 ARES_CALL_END(self);
0 6 ARES_CALL_END(self);
1284 0 1 REQUIRE_LIVE(self);
0 1 REQUIRE_LIVE(self);
1285 1 0 REQUIRE_CB(cb);
0 1 REQUIRE_CB(cb);
1289 1 0 ARES_CALL_END(self);
0 1 ARES_CALL_END(self);
1299 21 0 int dnsclass = C_IN;
1303 0 21 REQUIRE_LIVE(self);
0 21 REQUIRE_LIVE(self);
1306 18 3 if (items == 4) {
1308 2 1 } else if (items == 5) {
1314 20 0 REQUIRE_CB(cb);
0 20 REQUIRE_CB(cb);
1320 20 0 ARES_CALL_END(self);
0 20 ARES_CALL_END(self);
1333 0 35 REQUIRE_LIVE(self);
0 35 REQUIRE_LIVE(self);
1334 35 0 REQUIRE_CB(cb);
0 35 REQUIRE_CB(cb);
1338 35 0 ARES_CALL_END(self);
0 35 ARES_CALL_END(self);
1355 0 4 REQUIRE_LIVE(self);
0 4 REQUIRE_LIVE(self);
1356 4 0 REQUIRE_CB(cb);
0 4 REQUIRE_CB(cb);
1360 3 1 if (inet_pton(AF_INET, ip, &addr4) == 1) {
1362 0 1 } else if (inet_pton(AF_INET6, ip, &addr6) == 1) {
1372 3 0 ARES_CALL_END(self);
0 3 ARES_CALL_END(self);
1390 0 4 REQUIRE_LIVE(self);
0 4 REQUIRE_LIVE(self);
1391 4 0 REQUIRE_CB(cb);
0 4 REQUIRE_CB(cb);
1397 1 3 if (len < sizeof(struct sockaddr))
1403 0 3 if (len > sizeof ss) len = sizeof ss;
1406 1 2 if (family == AF_INET) min_len = sizeof(struct sockaddr_in);
1407 1 1 else if (family == AF_INET6) min_len = sizeof(struct sockaddr_in6);
1410 1 1 if (len < min_len)
1411 1 0 croak("EV::cares::getnameinfo: sockaddr too short for %s (%d bytes)",
1418 1 0 ARES_CALL_END(self);
0 1 ARES_CALL_END(self);
1425 0 6 REQUIRE_LIVE(self);
1 5 REQUIRE_LIVE(self);
1428 5 0 ARES_CALL_END(self);
0 5 ARES_CALL_END(self);
1438 0 10 REQUIRE_LIVE(self);
0 10 REQUIRE_LIVE(self);
1439 1 9 if (items <= 1)
1443 8 1 if (items == 2 && SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVAV) {
4 4 if (items == 2 && SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVAV) {
3 1 if (items == 2 && SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVAV) {
1445 1 2 if (av_len(av) < 0)
1450 7 5 for (i = 1; i < items; i++) {
1451 1 6 if (SvROK(ST(i)))
1454 1 5 if (i > 1) sv_catpvs(csv, ",");
1460 0 7 if (rc != ARES_SUCCESS)
1470 0 8 REQUIRE_LIVE(self);
0 8 REQUIRE_LIVE(self);
1472 0 8 if (!csv) croak("EV::cares::servers: ares_get_servers_csv failed");
1473 0 8 mXPUSHp(csv, strlen(csv));
1482 0 1 REQUIRE_LIVE(self);
0 1 REQUIRE_LIVE(self);
1492 0 2 REQUIRE_LIVE(self);
0 2 REQUIRE_LIVE(self);
1493 1 1 if (inet_pton(AF_INET, ip, &addr) != 1)
1505 0 2 REQUIRE_LIVE(self);
0 2 REQUIRE_LIVE(self);
1506 1 1 if (inet_pton(AF_INET6, ip, &addr) != 1)
1515 16 14 RETVAL = self->active_queries;
1523 0 3 RETVAL = self->last_timeouts;
1531 17 15 RETVAL = self->destroyed;
1542 1 2 RETVAL = self->loop_sv ? newRV_inc(self->loop_sv) : &PL_sv_undef;
1552 0 2 REQUIRE_LIVE(self);
1 1 REQUIRE_LIVE(self);
1554 0 1 RETVAL = tvp ? (double)tvp->tv_sec + (double)tvp->tv_usec / 1e6 : -1.0;
0 1 RETVAL = tvp ? (double)tvp->tv_sec + (double)tvp->tv_usec / 1e6 : -1.0;
1566 0 2 REQUIRE_LIVE(self);
0 2 REQUIRE_LIVE(self);
1568 1 1 if (rc != ARES_SUCCESS)
1579 0 14 if (self->magic != EV_CARES_MAGIC) croak("EV::cares: invalid object");
1588 0 4 REQUIRE_LIVE(self);
1 3 REQUIRE_LIVE(self);
1590 0 3 if (rc != ARES_SUCCESS)
1598 0 97 if (self->magic != EV_CARES_MAGIC) return;
1600 0 97 if (PL_dirty) {
1612 0 97 if (self->in_callback) {
1628 32 3 if (items == 1) arg = ST(0);
1629 2 1 else if (items >= 2) arg = ST(1); /* skip class/instance arg */
1633 3 31 if (!looks_like_number(arg))