diff -ruN qmail-1.03-factory/Makefile qmail-1.03-newbind/Makefile --- qmail-1.03-factory/Makefile 1998-06-15 06:53:16.000000000 -0400 +++ qmail-1.03-newbind/Makefile 2007-11-08 02:24:26.000000000 -0500 @@ -1333,10 +1333,10 @@ qmail-qmqpc: \ load qmail-qmqpc.o slurpclose.o timeoutread.o timeoutwrite.o \ -timeoutconn.o ip.o control.o auto_qmail.o sig.a ndelay.a open.a \ +timeoutconn.o constmap.o case.a ip.o control.o auto_qmail.o sig.a ndelay.a open.a \ getln.a substdio.a stralloc.a alloc.a error.a str.a fs.a socket.lib ./load qmail-qmqpc slurpclose.o timeoutread.o \ - timeoutwrite.o timeoutconn.o ip.o control.o auto_qmail.o \ + timeoutwrite.o timeoutconn.o constmap.o case.a ip.o control.o auto_qmail.o \ sig.a ndelay.a open.a getln.a substdio.a stralloc.a alloc.a \ error.a str.a fs.a `cat socket.lib` @@ -2067,8 +2067,10 @@ tcp-env: \ load tcp-env.o dns.o remoteinfo.o timeoutread.o timeoutwrite.o \ timeoutconn.o ip.o ipalloc.o case.a ndelay.a sig.a env.a getopt.a \ -stralloc.a alloc.a substdio.a error.a str.a fs.a dns.lib socket.lib +stralloc.a alloc.a substdio.a error.a str.a fs.a dns.lib socket.lib \ +constmap.o control.o open.a getln.a ./load tcp-env dns.o remoteinfo.o timeoutread.o \ + constmap.o control.o open.a getln.a \ timeoutwrite.o timeoutconn.o ip.o ipalloc.o case.a ndelay.a \ sig.a env.a getopt.a stralloc.a alloc.a substdio.a error.a \ str.a fs.a `cat dns.lib` `cat socket.lib` @@ -2097,7 +2099,7 @@ timeoutconn.o: \ compile timeoutconn.c ndelay.h select.h error.h readwrite.h ip.h \ -byte.h timeoutconn.h +byte.h timeoutconn.h control.h constmap.h stralloc.h ./compile timeoutconn.c timeoutread.o: \ diff -ruN qmail-1.03-factory/qmail-remote.c qmail-1.03-newbind/qmail-remote.c --- qmail-1.03-factory/qmail-remote.c 1998-06-15 06:53:16.000000000 -0400 +++ qmail-1.03-newbind/qmail-remote.c 2007-11-08 02:15:15.000000000 -0500 @@ -365,6 +365,8 @@ addrmangle(&sender,argv[2],&flagalias,0); + stralloc_0(&sender); + sender.len -- ; if (!saa_readyplus(&reciplist,0)) temp_nomem(); if (ipme_init() != 1) temp_oserr(); @@ -414,6 +416,9 @@ smtpfd = socket(AF_INET,SOCK_STREAM,0); if (smtpfd == -1) temp_oserr(); + bind_by_sender ( smtpfd , sender.s , 1 ) ; + bind_by_remoteip ( smtpfd , &ip.ix[i].ip , 0 ) ; + if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { tcpto_err(&ip.ix[i].ip,0); partner = ip.ix[i].ip; diff -ruN qmail-1.03-factory/timeoutconn.c qmail-1.03-newbind/timeoutconn.c --- qmail-1.03-factory/timeoutconn.c 1998-06-15 06:53:16.000000000 -0400 +++ qmail-1.03-newbind/timeoutconn.c 2007-11-08 12:07:10.000000000 -0500 @@ -9,6 +9,87 @@ #include "ip.h" #include "byte.h" #include "timeoutconn.h" +#include "control.h" +#include "constmap.h" +#include "stralloc.h" + +/* if 1, bind() failing will be ignored */ +#define IGNORE_BIND_ERROR 0 + +struct ip_address iplocal; +int bindlocal = 0 ; + +int bind_by_sender(s,addr,force) +int s; +char *addr; +int force; +{ + int j; + stralloc stext = {0} ; + struct constmap senderip ; + stralloc domain = {0} ; + char *chosenip = (char *) 0 ; + + if (!force) if(bindlocal) return 0; /* already bound, no bind */ + + switch ( control_readfile ( &stext , "control/senderip" , 0 ) ) + { + case 0: return 0 ; /* no file, no bind */ + case -1: return -2 ; /* error */ + case 1: + if ( ! constmap_init ( &senderip , stext.s , stext.len , 1 ) ) + return -3 ; + } + + j = str_chr(addr,'@') ; + stralloc_copys ( &domain , addr[j] ? &(addr[j+1]) : addr ) ; + stralloc_0 ( &domain ) ; + domain.len -- ; + + chosenip = constmap ( &senderip , domain.s , domain.len ) ; + if ( !chosenip || !*chosenip ) return 0 ; /* no match, no bind */ + if ( ! ip_scan ( chosenip , &iplocal ) ) return -4 ; /* invalid IP */ + bindlocal = 1 ; + return 0 ; +} + +int bind_by_remoteip(s,ip,force) +int s; +struct ip_address *ip; +int force; +{ + struct sockaddr_in salocal; + char *ipstr, ipstring[IPFMT+1]; + int iplen; + stralloc routes = {0}; + struct constmap bindroutes; + char *bindroute = (char *)0; + + if (!force) if(bindlocal) return 0; /* already bound, no bind */ + + /* make sure we have a control/bindroutes file */ + switch(control_readfile(&routes,"control/bindroutes",0)) + { + case 0: return 0; /* no file, no bind to worry about */ + case -1: return -2; /* buggered up somewhere, urgh! */ + case 1: if (!constmap_init(&bindroutes,routes.s,routes.len,1)) return -3; + } + + /* search for d.d.d.d, d.d.d., d.d., d., none */ + ipstring[0] = '.'; /* "cheating", but makes the loop check easier below! */ + ipstr = ipstring+1; + iplen = ip_fmt(ipstr,ip); /* Well, Dan seems to trust its output! */ + + bindroute = constmap(&bindroutes,ipstr,iplen); + if (!bindroute) while (iplen--) /* no worries - the lost char must be 0-9 */ + if (ipstring[iplen] == '.') + if (bindroute = constmap(&bindroutes,ipstr,iplen)) break; + if (!bindroute || !*bindroute) return 0; /* no bind required */ + if (!ip_scan(bindroute,&iplocal)) return -4; /* wasn't an ip returned */ + bindlocal = 1 ; + return 0; +} + int timeoutconn(s,ip,port,timeout) int s; @@ -18,6 +99,7 @@ { char ch; struct sockaddr_in sin; + struct sockaddr_in salocal; char *x; fd_set wfds; struct timeval tv; @@ -30,8 +112,15 @@ if (ndelay_on(s) == -1) return -1; - /* XXX: could bind s */ - + /* bind s, if we've been given a local IP */ + if ( bindlocal ) { + byte_zero ( &salocal , sizeof(salocal) ) ; + salocal.sin_family = AF_INET ; + byte_copy ( &salocal.sin_addr , 4 , &iplocal ) ; + if ( bind ( s , (struct sockaddr *) &salocal , sizeof(salocal) ) ) + if ( ! IGNORE_BIND_ERROR ) return errno ; + } + if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) { ndelay_off(s); return 0; diff -ruN qmail-1.03-factory/timeoutconn.h qmail-1.03-newbind/timeoutconn.h --- qmail-1.03-factory/timeoutconn.h 1998-06-15 06:53:16.000000000 -0400 +++ qmail-1.03-newbind/timeoutconn.h 2007-11-07 17:57:53.000000000 -0500 @@ -2,5 +2,7 @@ #define TIMEOUTCONN_H extern int timeoutconn(); +extern int bind_by_sender(); +extern int bind_by_remoteip(); #endif