/* * take an address and return all the mx entries for it, * most preferred first */ static int callmx(DS *ds, char *dest, char *domain) { int fd, i, nmx; char addr[Maxstring]; /* get a list of mx entries */ nmx = mxlookup(ds, domain); if(nmx < 0){ /* dns isn't working, don't just dial */ return -1; } if(nmx == 0){ if(debug) fprint(2, "mxlookup returns nothing\n"); return dial(dest, 0, 0, 0); } /* refuse to honor loopback addresses given by dns */ for(i = 0; i < nmx; i++){ if(strcmp(mx[i].ip, "127.0.0.1") == 0){ if(debug) fprint(2, "mxlookup returns loopback\n"); werrstr("illegal: domain lists 127.0.0.1 as mail server"); return -1; } } /* sort by preference */ if(nmx > 1) qsort(mx, nmx, sizeof(Mx), compar); if(debug){ for(i=0; i<nmx; i++) print("%s %d\n", mx[i].host, mx[i].pref); } /* dial each one in turn */ for(i = 0; i < nmx; i++){ #ifdef PLAN9PORT snprint(addr, sizeof(addr), "%s", mx[i].host); #else snprint(addr, sizeof(addr), "%s!%s!%s", ds->proto, mx[i].host, ds->service); #endif if(debug) fprint(2, "mxdial trying %s (%d)\n", addr, i); atnotify(timeout, 1); alarm(10*1000); #ifdef PLAN9PORT fd = smtpdial(addr); #else fd = dial(addr, 0, 0, 0); #endif alarm(0); atnotify(timeout, 0); if(fd >= 0) return fd; } return -1; }
/* * take an address and return all the mx entries for it, * most preferred first */ static int callmx(DS *ds, char *dest, char *domain) { int fd, i, nmx; char *ip; char addr[Maxstring]; /* get a list of mx entries */ nmx = mxlookup(ds, domain); if(nmx < 0){ /* dns isn't working, don't just dial */ return -1; } if(nmx == 0){ if(debug) fprint(2, "mxlookup returns nothing\n"); return dial(dest, 0, 0, 0); } /* refuse to honor loopback addresses given by dns. catch \n too. */ for(i = 0; i < nmx; i++) { ip = mx[i].ip; if(strchr(ip, '\n') != nil){ if(debug) fprint(2, "mxlookup ip contains newline\n"); werrstr("illegal: newline in mail server ip"); return -1; }else if(isloopback(ip)){ if(debug) fprint(2, "mxlookup returns loopback\n"); werrstr("illegal: domain lists %s as mail server", ip); return -1; } } /* sort by preference */ if(nmx > 1) qsort(mx, nmx, sizeof(Mx), compar); /* dial each one in turn by name, not ip */ for(i = 0; i < nmx; i++){ if (busted(mx[i].host)) { if (debug) fprint(2, "mxdial skipping busted mx %s\n", mx[i].host); continue; } snprint(addr, sizeof(addr), "%s/%s!%s!%s", ds->netdir, ds->proto, mx[i].host, ds->service); if(debug) fprint(2, "mxdial trying %s\n", addr); atnotify(timeout, 1); /* this was 10 seconds, but oclsc.org at least needs more. */ alarm(60*1000); fd = dial(addr, 0, 0, 0); if (debug && fd < 0) fprint(2, "dial: %r\n"); alarm(0); atnotify(timeout, 0); if(fd >= 0) return fd; } return -1; }