--- qmail-remote.c.org 2007-11-23 16:09:56.000000000 -0800 +++ qmail-remote.c 2007-11-23 21:54:46.000000000 -0800 @@ -41,6 +41,8 @@ stralloc helohost = {0}; stralloc routes = {0}; struct constmap maproutes; +stralloc sources = {0}; +struct constmap mapsources; stralloc host = {0}; stralloc sender = {0}; @@ -324,6 +326,14 @@ case 1: if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break; } + switch(control_readfile(&sources,"control/sourceip",0)) { + case -1: + temp_control(); + case 0: + if (!constmap_init(&mapsources,"",0,1)) temp_nomem(); break; + case 1: + if (!constmap_init(&mapsources,sources.s,sources.len,1)) temp_nomem(); break; + } } void main(argc,argv) @@ -331,6 +341,7 @@ char **argv; { static ipalloc ip = {0}; + static ipalloc sip = {0}; int i; unsigned long random; char **recips; @@ -338,6 +349,7 @@ int flagallaliases; int flagalias; char *relayhost; + char *srchost; sig_pipeignore(); if (argc < 4) perm_usage(); @@ -408,12 +420,65 @@ if (i >= ip.len) perm_ambigmx(); + i = str_rchr(sender.s, '@'); + if (sender.s[i]) ++i; + + srchost = constmap(&mapsources, sender.s + i, sender.len - i); + + if (!srchost) { + while (i <= sender.len) { + if ((i == sender.len) || (sender.s[i] == '.')) { + if (srchost = constmap(&mapsources, sender.s + i, sender.len - i)) + break; + } + + ++i; + } + } + + if (srchost) { + if (!*srchost) { + srchost = 0; + } + else { + i = str_chr(srchost,':'); + + if (srchost[i]) { + if (!stralloc_copys(&helohost, srchost + i + 1)) temp_nomem(); + srchost[i] = 0; + } + else { + if (!stralloc_copys(&helohost, srchost)) temp_nomem(); + } + + if (!stralloc_copys(&host, srchost)) temp_nomem(); + random = now() + (getpid() << 16); + switch (dns_mxip(&sip, &host, random)) { + case DNS_MEM: temp_nomem(); + case DNS_SOFT: temp_dns(); + case DNS_HARD: perm_dns(); + case 1: + if (sip.len <= 0) temp_dns(); + } + + if (sip.len <= 0) srchost = 0; + } + } + for (i = 0;i < ip.len;++i) if (ip.ix[i].pref < prefme) { if (tcpto(&ip.ix[i].ip)) continue; smtpfd = socket(AF_INET,SOCK_STREAM,0); if (smtpfd == -1) temp_oserr(); - + + if (srchost) { + struct sockaddr_in si; + si.sin_family=AF_INET; + si.sin_port=0; + byte_copy(&si.sin_addr,4,&(sip.ix->ip)); + if (bind(smtpfd,(struct sockaddr*)&si,sizeof(si))) temp_oserr(); + } + if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { tcpto_err(&ip.ix[i].ip,0); partner = ip.ix[i].ip;