~ubuntu-branches/ubuntu/raring/postfix/raring

« back to all changes in this revision

Viewing changes to src/lmtp/lmtp_addr.c

Tags: upstream-2.2.6
ImportĀ upstreamĀ versionĀ 2.2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
#include <string.h>
68
68
#include <unistd.h>
69
69
 
70
 
#ifndef INADDR_NONE
71
 
#define INADDR_NONE 0xffffffff
72
 
#endif
73
 
 
74
70
/* Utility library. */
75
71
 
76
72
#include <msg.h>
78
74
#include <mymalloc.h>
79
75
#include <inet_addr_list.h>
80
76
#include <stringops.h>
 
77
#include <myaddrinfo.h>
 
78
#include <sock_addr.h>
 
79
#include <inet_proto.h>
81
80
 
82
81
/* Global library. */
83
82
 
98
97
static void lmtp_print_addr(char *what, DNS_RR *addr_list)
99
98
{
100
99
    DNS_RR *addr;
101
 
    struct in_addr in_addr;
 
100
    MAI_HOSTADDR_STR hostaddr;
102
101
 
103
102
    msg_info("begin %s address list", what);
104
103
    for (addr = addr_list; addr; addr = addr->next) {
105
 
        if (addr->data_len > sizeof(addr)) {
106
 
            msg_warn("skipping address length %d", addr->data_len);
 
104
        if (dns_rr_to_pa(addr, &hostaddr) == 0) {
 
105
            msg_warn("skipping record type %s: %m", dns_strtype(addr->type));
107
106
        } else {
108
 
            memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
109
107
            msg_info("pref %4d host %s/%s",
110
108
                     addr->pref, addr->name,
111
 
                     inet_ntoa(in_addr));
 
109
                     hostaddr.buf);
112
110
        }
113
111
    }
114
112
    msg_info("end %s address list", what);
119
117
static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
120
118
{
121
119
    char   *myname = "lmtp_addr_one";
122
 
    struct in_addr inaddr;
123
 
    DNS_FIXED fixed;
124
120
    DNS_RR *addr = 0;
125
121
    DNS_RR *rr;
126
 
    struct hostent *hp;
 
122
    int     aierr;
 
123
    struct addrinfo *res0;
 
124
    struct addrinfo *res;
 
125
    INET_PROTO_INFO *proto_info = inet_proto_info();
 
126
    int     found;
127
127
 
128
128
    if (msg_verbose)
129
129
        msg_info("%s: host %s", myname, host);
131
131
    /*
132
132
     * Interpret a numerical name as an address.
133
133
     */
134
 
    if (ISDIGIT(host[0]) && (inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
135
 
        memset((char *) &fixed, 0, sizeof(fixed));
136
 
        return (dns_rr_append(addr_list,
137
 
                              dns_rr_create(host, &fixed, pref,
138
 
                                        (char *) &inaddr, sizeof(inaddr))));
 
134
    if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
 
135
        && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
 
136
        if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
 
137
            msg_fatal("host %s: conversion error for address family %d: %m",
 
138
                    host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
 
139
        addr_list = dns_rr_append(addr_list, addr);
 
140
        freeaddrinfo(res0);
 
141
        return (addr_list);
139
142
    }
140
143
 
141
144
    /*
142
 
     * Use gethostbyname() when DNS is disabled.
 
145
     * Use native name service when DNS is disabled.
143
146
     */
 
147
#define RETRY_AI_ERROR(e) \
 
148
        ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
 
149
 
144
150
    if (var_disable_dns) {
145
 
        memset((char *) &fixed, 0, sizeof(fixed));
146
 
        if ((hp = gethostbyname(host)) == 0) {
147
 
            vstring_sprintf(why, "%s: host not found", host);
148
 
            lmtp_errno = LMTP_FAIL;
149
 
        } else if (hp->h_addrtype != AF_INET) {
150
 
            vstring_sprintf(why, "%s: host not found", host);
151
 
            msg_warn("%s: unknown address family %d for %s",
152
 
                     myname, hp->h_addrtype, host);
153
 
            lmtp_errno = LMTP_FAIL;
 
151
        if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
 
152
            vstring_sprintf(why, "%s: %s", host, MAI_STRERROR(aierr));
 
153
            lmtp_errno = (RETRY_AI_ERROR(aierr) ? LMTP_RETRY : LMTP_FAIL);
154
154
        } else {
155
 
            while (hp->h_addr_list[0]) {
156
 
                addr_list = dns_rr_append(addr_list,
157
 
                                          dns_rr_create(host, &fixed, pref,
158
 
                                                        hp->h_addr_list[0],
159
 
                                                        sizeof(inaddr)));
160
 
                hp->h_addr_list++;
161
 
            }
 
155
            for (found = 0, res = res0; res != 0; res = res->ai_next) {
 
156
                if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
 
157
                    msg_info("skipping address family %d for host %s",
 
158
                             res->ai_family, host);
 
159
                    continue;
 
160
                }
 
161
                found++;
 
162
                if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
 
163
                    msg_fatal("host %s: conversion error for address family %d: %m",
 
164
                    host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
 
165
                addr_list = dns_rr_append(addr_list, addr);
 
166
            }
 
167
            freeaddrinfo(res0);
 
168
            if (found == 0) {
 
169
                vstring_sprintf(why, "%s: host not found", host);
 
170
                lmtp_errno = LMTP_FAIL;
 
171
            }
 
172
            return (addr_list);
162
173
        }
163
 
        return (addr_list);
164
174
    }
165
175
 
166
176
    /*
167
177
     * Append the addresses for this host to the address list.
168
178
     */
169
 
    switch (dns_lookup(host, T_A, RES_DEFNAMES, &addr, (VSTRING *) 0, why)) {
 
179
    switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0, why,
 
180
                         DNS_REQ_FLAG_ALL, proto_info->dns_atype_list)) {
170
181
    case DNS_OK:
171
182
        for (rr = addr; rr; rr = rr->next)
172
183
            rr->pref = pref;