int infd, outfd, rc;
uschar *argv[5];
- DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens `%s'\n",
- name, dns_text_type(type), utilname);
+ DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n", name, dns_text_type(type));
argv[0] = utilname;
argv[1] = config_main_directory;
asize -= rc; /* may need to be passed on to res_search(). */
}
+ /* If we ran out of output buffer before exhasting the return,
+ carry on reading and counting it. */
+
+ if (asize == 0)
+ while ((rc = read(outfd, name, sizeof(name))) > 0)
+ len += rc;
+
if (rc < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "read from fakens failed: %s",
strerror(errno));
dnsa the DNS answer block
rr the RR
-Returns: pointer to a chain of dns_address items
+Returns: pointer to a chain of dns_address items; NULL when the dnsa was overrun
*/
dns_address *
dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
{
-dns_address *yield = NULL;
-
-dnsa = dnsa; /* Stop picky compilers warning */
+dns_address * yield = NULL;
+uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
if (rr->type == T_A)
{
uschar *p = US rr->data;
- yield = store_get(sizeof(dns_address) + 20);
- (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- yield->next = NULL;
+ if (p + 4 <= dnsa_lim)
+ {
+ yield = store_get(sizeof(dns_address) + 20);
+ (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ yield->next = NULL;
+ }
}
#if HAVE_IPV6
else
{
- yield = store_get(sizeof(dns_address) + 50);
- inet_ntop(AF_INET6, US rr->data, CS yield->address, 50);
- yield->next = NULL;
+ if (rr->data + 16 <= dnsa_lim)
+ {
+ yield = store_get(sizeof(dns_address) + 50);
+ inet_ntop(AF_INET6, US rr->data, CS yield->address, 50);
+ yield->next = NULL;
+ }
}
#endif /* HAVE_IPV6 */