Exemple #1
0
int     main(int argc, char **argv)
{
    MAI_HOSTADDR_STR hostaddr;
    struct addrinfo *res0;
    struct addrinfo *res;
    struct addrinfo **resv;
    size_t  len, n;
    DNS_RR *rr;
    int     aierr;

    myname = argv[0];
    if (argc < 2)
	usage();

    inet_proto_init(argv[0], INET_PROTO_NAME_ALL);

    while (*++argv) {
	if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
	    msg_fatal("%s: %s", argv[0], MAI_STRERROR(aierr));
	for (len = 0, res = res0; res != 0; res = res->ai_next)
	    len += 1;
	resv = (struct addrinfo **) mymalloc(len * sizeof(*resv));
	for (len = 0, res = res0; res != 0; res = res->ai_next)
	    resv[len++] = res;
	qsort((void *) resv, len, sizeof(*resv), compare_family);
	for (n = 0; n < len; n++) {
	    if ((rr = dns_sa_to_rr(argv[0], 0, resv[n]->ai_addr)) == 0)
		msg_fatal("dns_sa_to_rr: %m");
	    if (dns_rr_to_pa(rr, &hostaddr) == 0)
		msg_fatal("dns_rr_to_pa: %m");
	    vstream_printf("%s -> %s\n", argv[0], hostaddr.buf);
	    vstream_fflush(VSTREAM_OUT);
	    dns_rr_free(rr);
	}
	freeaddrinfo(res0);
	myfree((void *) resv);
    }
    return (0);
}
Exemple #2
0
static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host,
                             unsigned pref, DSN_BUF *why)
{
    const char *myname = "smtp_addr_one";
    DNS_RR *addr = 0;
    DNS_RR *rr;
    int     aierr;
    struct addrinfo *res0;
    struct addrinfo *res;
    INET_PROTO_INFO *proto_info = inet_proto_info();
    int     found;

    if (msg_verbose)
        msg_info("%s: host %s", myname, host);

    /*
     * Interpret a numerical name as an address.
     */
    if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
            && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
        if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
            msg_fatal("host %s: conversion error for address family %d: %m",
                      host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
        addr_list = dns_rr_append(addr_list, addr);
        freeaddrinfo(res0);
        return (addr_list);
    }

    /*
     * Use DNS lookup, but keep the option open to use native name service.
     *
     * XXX A soft error dominates past and future hard errors. Therefore we
     * should not clobber a soft error text and status code.
     */
    if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) {
        switch (dns_lookup_v(host, smtp_dns_res_opt, &addr, (VSTRING *) 0,
                             why->reason, DNS_REQ_FLAG_NONE,
                             proto_info->dns_atype_list)) {
        case DNS_OK:
            for (rr = addr; rr; rr = rr->next)
                rr->pref = pref;
            addr_list = dns_rr_append(addr_list, addr);
            return (addr_list);
        default:
            dsb_status(why, "4.4.3");
            return (addr_list);
        case DNS_FAIL:
            dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.3" : "5.4.3");
            return (addr_list);
        case DNS_INVAL:
            dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4");
            return (addr_list);
        case DNS_NOTFOUND:
            dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4");
            /* maybe native naming service will succeed */
            break;
        }
    }

    /*
     * Use the native name service which also looks in /etc/hosts.
     *
     * XXX A soft error dominates past and future hard errors. Therefore we
     * should not clobber a soft error text and status code.
     */
#define RETRY_AI_ERROR(e) \
        ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
#ifdef EAI_NODATA
#define DSN_NOHOST(e) \
	((e) == EAI_AGAIN || (e) == EAI_NODATA || (e) == EAI_NONAME)
#else
#define DSN_NOHOST(e) \
	((e) == EAI_AGAIN || (e) == EAI_NONAME)
#endif

    if (smtp_host_lookup_mask & SMTP_HOST_FLAG_NATIVE) {
        if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
            dsb_simple(why, (SMTP_HAS_SOFT_DSN(why) || RETRY_AI_ERROR(aierr)) ?
                       (DSN_NOHOST(aierr) ? "4.4.4" : "4.3.0") :
                       (DSN_NOHOST(aierr) ? "5.4.4" : "5.3.0"),
                       "unable to look up host %s: %s",
                       host, MAI_STRERROR(aierr));
        } else {
            for (found = 0, res = res0; res != 0; res = res->ai_next) {
                if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
                    msg_info("skipping address family %d for host %s",
                             res->ai_family, host);
                    continue;
                }
                found++;
                if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
                    msg_fatal("host %s: conversion error for address family %d: %m",
                              host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
                addr_list = dns_rr_append(addr_list, addr);
            }
            freeaddrinfo(res0);
            if (found == 0) {
                dsb_simple(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4",
                           "%s: host not found", host);
            }
            return (addr_list);
        }
    }

    /*
     * No further alternatives for host lookup.
     */
    return (addr_list);
}