static DNS_RR *smtp_addr_list(DNS_RR *mx_names, DSN_BUF *why) { DNS_RR *addr_list = 0; DNS_RR *rr; /* * As long as we are able to look up any host address, we ignore problems * with DNS lookups (except if we're backup MX, and all the better MX * hosts can't be found). * * XXX 2821: update the error status (0->FAIL upon unrecoverable lookup * error, any->RETRY upon temporary lookup error) so that we can * correctly handle the case of no resolvable MX host. Currently this is * always treated as a soft error. RFC 2821 wants a more precise * response. * * XXX dns_lookup() enables RES_DEFNAMES. This is wrong for names found in * MX records - we should not append the local domain to dot-less names. * * XXX However, this is not the only problem. If we use the native name * service for host lookup, then it will usually enable RES_DNSRCH which * appends local domain information to all lookups. In particular, * getaddrinfo() may invoke a resolver that runs in a different process * (NIS server, nscd), so we can't even reliably turn this off by * tweaking the in-process resolver flags. */ for (rr = mx_names; rr; rr = rr->next) { if (rr->type != T_MX) msg_panic("smtp_addr_list: bad resource type: %d", rr->type); addr_list = smtp_addr_one(addr_list, (char *) rr->data, rr->pref, why); } return (addr_list); }
DNS_RR *smtp_host_addr(const char *host, int misc_flags, DSN_BUF *why) { DNS_RR *addr_list; dsb_reset(why); /* Paranoia */ /* * If the host is specified by numerical address, just convert the * address to internal form. Otherwise, the host is specified by name. */ #define PREF0 0 addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why); if (addr_list && (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) && smtp_find_self(addr_list) != 0) { dns_rr_free(addr_list); dsb_simple(why, "5.4.6", "mail for %s loops back to myself", host); return (0); } if (addr_list && addr_list->next) { if (var_smtp_rand_addr) addr_list = dns_rr_shuffle(addr_list); /* The following changes the order of equal-preference hosts. */ if (inet_proto_info()->ai_family_list[1] != 0) addr_list = dns_rr_sort(addr_list, SMTP_COMPARE_ADDR(misc_flags)); } if (msg_verbose) smtp_print_addr(host, addr_list); return (addr_list); }
DNS_RR *smtp_host_addr(const char *host, int misc_flags, DSN_BUF *why) { DNS_RR *addr_list; int res_opt = 0; const char *ahost; dsb_reset(why); /* Paranoia */ if (smtp_dns_support == SMTP_DNS_DNSSEC) res_opt |= RES_USE_DNSSEC; /* * IDNA support. */ #ifndef NO_EAI if (!allascii(host) && (ahost = midna_domain_to_ascii(host)) != 0) { if (msg_verbose) msg_info("%s asciified to %s", host, ahost); } else #endif ahost = host; /* * If the host is specified by numerical address, just convert the * address to internal form. Otherwise, the host is specified by name. */ #define PREF0 0 addr_list = smtp_addr_one((DNS_RR *) 0, ahost, res_opt, PREF0, why); if (addr_list && (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) && smtp_find_self(addr_list) != 0) { dns_rr_free(addr_list); dsb_simple(why, "5.4.6", "mail for %s loops back to myself", host); return (0); } if (addr_list && addr_list->next) { if (var_smtp_rand_addr) addr_list = dns_rr_shuffle(addr_list); /* The following changes the order of equal-preference hosts. */ if (inet_proto_info()->ai_family_list[1] != 0) addr_list = dns_rr_sort(addr_list, SMTP_COMPARE_ADDR(misc_flags)); } if (msg_verbose) smtp_print_addr(host, addr_list); return (addr_list); }