25
24
#include "fetchmail.h"
25
#include "getaddrinfo.h"
27
27
#define MX_RETRIES 3
29
typedef unsigned char address_t[sizeof (struct in_addr)];
31
static int getaddresses(struct addrinfo **result, const char *name)
33
struct addrinfo hints;
35
memset(&hints, 0, sizeof(hints));
36
hints.ai_socktype=SOCK_STREAM;
37
hints.ai_protocol=PF_UNSPEC;
38
hints.ai_family=AF_UNSPEC;
39
return getaddrinfo(name, NULL, &hints, result);
42
/* XXX FIXME: doesn't detect if an IPv6-mapped IPv4 address
43
* matches a real IPv4 address */
44
static int compareaddr(const struct addrinfo *a1, const struct addrinfo *a2)
46
if (a1->ai_family != a2->ai_family) return FALSE;
47
if (a1->ai_addrlen != a2->ai_addrlen) return FALSE;
48
return (!memcmp(a1->ai_addr, a2->ai_addr, a1->ai_addrlen));
29
51
static int is_ip_alias(const char *name1,const char *name2)
31
53
* Given two hostnames as arguments, returns TRUE if they
34
56
* the calling function does them.
37
typedef unsigned char address_t[sizeof (struct in_addr)];
38
typedef struct _address_e
40
struct _address_e *next;
44
address_e *host_a_addr=0, *host_b_addr=0; /* assignments pacify -Wall */
45
address_e *dummy_addr;
51
hp = gethostbyname((char*)name1);
53
dummy_addr = (address_e *)NULL;
55
for (i=0,p = hp->h_addr_list; *p != 0; i++,p++)
58
(void) memcpy(&in.s_addr, *p, sizeof (in.s_addr));
59
xalloca(host_a_addr, address_e *, sizeof (address_e));
60
memset (host_a_addr,0, sizeof (address_e));
61
host_a_addr->next = dummy_addr;
62
(void) memcpy(&host_a_addr->address, *p, sizeof (in.s_addr));
63
dummy_addr = host_a_addr;
66
hp = gethostbyname((char*)name2);
68
dummy_addr = (address_e *)NULL;
69
for (i=0,p = hp->h_addr_list; *p != 0; i++,p++)
72
(void) memcpy(&in.s_addr, *p, sizeof (in.s_addr));
73
xalloca(host_b_addr, address_e *, sizeof (address_e));
74
memset (host_b_addr,0, sizeof (address_e));
75
host_b_addr->next = dummy_addr;
76
(void) memcpy(&host_b_addr->address, *p, sizeof (in.s_addr));
77
dummy_addr = host_b_addr;
84
if (!memcmp(host_b_addr->address,host_a_addr->address, sizeof (address_t)))
87
host_b_addr = host_b_addr->next;
61
struct addrinfo *res1 = NULL, *res2 = NULL, *ii, *ij;
63
if (getaddresses(&res1, name1))
66
if (getaddresses(&res2, name2))
69
for (ii = res1 ; ii ; ii = ii -> ai_next) {
70
for (ij = res2 ; ij ; ij = ij -> ai_next) {
71
if (compareaddr(ii, ij)) {
89
host_a_addr = host_a_addr->next;
94
86
int is_host_alias(const char *name, struct query *ctl)
95
87
/* determine whether name is a DNS alias of the mailserver for this query */
97
struct hostent *he,*he_st;
98
89
struct mxentry *mxp, *mxrecords;
99
90
struct idlist *idl;
92
struct addrinfo hints, *res, *res_st;
102
struct hostdata *lead_server =
94
struct hostdata *lead_server =
103
95
ctl->server.lead_server ? ctl->server.lead_server : &ctl->server;
161
153
* delivering the current message or anything else from the
162
154
* current server until it's back up.
164
if ((he = gethostbyname((char*)name)) != (struct hostent *)NULL)
156
memset(&hints, 0, sizeof hints);
157
hints.ai_family=AF_UNSPEC;
158
hints.ai_protocol=PF_UNSPEC;
159
hints.ai_socktype=SOCK_STREAM;
160
hints.ai_flags=AI_CANONNAME;
162
e = getaddrinfo(name, NULL, &hints, &res);
166
if (strcasecmp(ctl->server.truename, he->h_name) == 0)
165
int rr = (strcasecmp(ctl->server.truename, res->ai_canonname) == 0);
168
else if (((he_st = gethostbyname(ctl->server.truename)) != (struct hostent *)NULL) && ctl->server.checkalias)
169
else if (ctl->server.checkalias && 0 == getaddrinfo(ctl->server.truename, NULL, &hints, &res_st))
171
freeaddrinfo(res_st);
170
172
if (outlevel >= O_DEBUG)
171
173
report(stdout, GT_("Checking if %s is really the same node as %s\n"),ctl->server.truename,name);
172
174
if (is_ip_alias(ctl->server.truename,name) == TRUE)
178
180
if (outlevel >= O_DEBUG)
179
181
report(stdout, GT_("No, their IP addresses don't match\n"));
188
case HOST_NOT_FOUND: /* specified host is unknown */
190
case NO_ADDRESS: /* valid, but does not have an IP address */
193
case NO_RECOVERY: /* non-recoverable name server error */
194
case TRY_AGAIN: /* temporary error on authoritative server */
196
if (outlevel != O_SILENT)
197
report_complete(stdout, "\n"); /* terminate the progress message */
199
GT_("nameserver failure while looking for `%s' during poll of %s.\n"),
200
name, ctl->server.pollname);
190
case EAI_NONAME: /* specified host is unknown */
194
if (outlevel != O_SILENT)
195
report_complete(stdout, "\n"); /* terminate the progress message */
197
GT_("nameserver failure while looking for '%s' during poll of %s: %s\n"),
198
name, ctl->server.pollname, gai_strerror(e));