X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=checkalias.c;h=6437db4c7c7f979b535e564bc9e5859fb7a583b2;hb=33cddbff323efcbae1503e91e6e65b2733da80c7;hp=1eca63daadc7c19409d3fc83ffd555fbc9d30911;hpb=b75b43db636a92444be6224e56c765edece19fc3;p=~andy%2Ffetchmail diff --git a/checkalias.c b/checkalias.c index 1eca63da..6437db4c 100644 --- a/checkalias.c +++ b/checkalias.c @@ -1,82 +1,75 @@ /* - * checkalias.c -- check to see if the IP addresses of two hosts are the same + * checkalias.c -- check to see if two hostnames or IP addresses are equivalent * * Copyright 1997 by Eric S. Raymond * For license terms, see the file COPYING in this directory. */ - +#include "config.h" +#include #include #include #include -#include -#include -#include -#include -#include "fetchmail.h" - -int is_ip_alias(const char *name1,const char *name2) -/* Given two hostnames as arguments, returns TRUE if they - * have at least one IP address in common. - * It is meant to be called by the is_host_alias() function in driver.c - * No check is done on errors returned by gethostbyname, - * the calling function does them. - */ -{ - typedef unsigned char address_t[sizeof (struct in_addr)]; - typedef struct _address_e - { - struct _address_e *next; - address_t address; - } - address_e; - address_e *host_a_addr, *host_b_addr,*dummy_addr; - - int i; - struct hostent *hp; - char **p; - - hp = gethostbyname(name1); - - dummy_addr = (address_e *)NULL; - - for (i=0,p = hp->h_addr_list; *p != 0; i++,p++) - { - struct in_addr in; - (void) memcpy(&in.s_addr, *p, sizeof (in.s_addr)); - host_a_addr = (address_e *)xmalloc(sizeof( address_e)); - memset (host_a_addr,0, sizeof (address_e)); - host_a_addr->next = dummy_addr; - (void) memcpy(&host_a_addr->address, *p, sizeof (in.s_addr)); - dummy_addr = host_a_addr; - } +#include "fetchmail.h" - hp = gethostbyname(name2); +int is_host_alias(const char *name, struct query *ctl, struct addrinfo **res) +/* determine whether name is a DNS alias of the mailserver for this query */ +{ + struct idlist *idl; + size_t namelen; - dummy_addr = (address_e *)NULL; + struct hostdata *lead_server = + ctl->server.lead_server ? ctl->server.lead_server : &ctl->server; - for (i=0,p = hp->h_addr_list; *p != 0; i++,p++) - { - struct in_addr in; - (void) memcpy(&in.s_addr, *p, sizeof (in.s_addr)); - host_b_addr = (address_e *)xmalloc(sizeof( address_e)); - memset (host_b_addr,0, sizeof (address_e)); - host_b_addr->next = dummy_addr; - (void) memcpy(&host_b_addr->address, *p, sizeof (in.s_addr)); - dummy_addr = host_b_addr; - } + /* + * The first two checks are optimizations that will catch a good + * many cases. + * + * (1) check against the `true name' deduced from the poll label + * and the via option (if present) at the beginning of the poll cycle. + * Odds are good this will either be the mailserver's FQDN or a suffix of + * it with the mailserver's domain's default host name omitted. + * + * (2) Then check the rest of the `also known as' + * cache accumulated by previous DNS checks. This cache is primed + * by the aka list option. + * + * Any of these on a mail address is definitive. Only if the + * name doesn't match any is it time to call the bind library. + * If this happens odds are good we're looking at an MX name. + */ + if (strcasecmp(lead_server->truename, name) == 0) + return(TRUE); + else if (str_in_list(&lead_server->akalist, name, TRUE)) + return(TRUE); - while (host_a_addr) + /* + * Now check for a suffix match on the akalist. The theory here is + * that if the user says `aka netaxs.com', we actually want to match + * foo.netaxs.com and bar.netaxs.com. + */ + namelen = strlen(name); + for (idl = lead_server->akalist; idl; idl = idl->next) { - while (host_b_addr) - { - if (!memcmp(host_b_addr->address,host_a_addr->address, sizeof (address_t))) - return (TRUE); + const char *ep; - host_b_addr = host_b_addr->next; - } - host_a_addr = host_a_addr->next; + /* + * Test is >= here because str_in_list() should have caught the + * equal-length case above. Doing it this way guarantees that + * ep[-1] is a valid reference. + */ + if (strlen(idl->id) >= namelen) + continue; + ep = name + (namelen - strlen(idl->id)); + /* a suffix led by . must match */ + if (ep[-1] == '.' && !strcasecmp(ep, idl->id)) + return(TRUE); } - return (FALSE); + + if (!ctl->server.dns) + return(FALSE); + (void)res; + return(FALSE); } +/* checkalias.c ends here */