diff -urN netqmail-1.05.orig/control.c netqmail-1.05.new/control.c
--- netqmail-1.05.orig/control.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/control.c	2007-03-13 13:02:26.000000000 -0600
@@ -8,7 +8,7 @@
 #include "alloc.h"
 #include "scan.h"
 
-static char inbuf[64];
+static char inbuf[8192];
 static stralloc line = {0};
 static stralloc me = {0};
 static int meok = 0;
diff -urN netqmail-1.05.orig/qmail-control.9 netqmail-1.05.new/qmail-control.9
--- netqmail-1.05.orig/qmail-control.9	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/qmail-control.9	2007-03-13 13:02:18.000000000 -0600
@@ -21,6 +21,7 @@
 Comments are allowed
 in
 .IR badmailfrom ,
+.IR domainbindings ,
 .IR locals ,
 .IR percenthack ,
 .IR qmqpservers ,
@@ -48,6 +49,7 @@
 .I defaultdomain	\fIme	\fRqmail-inject
 .I defaulthost	\fIme	\fRqmail-inject
 .I databytes	\fR0	\fRqmail-smtpd
+.I domainbindings	\fR(none)	\fRqmail-remote
 .I doublebouncehost	\fIme	\fRqmail-send
 .I doublebounceto	\fRpostmaster	\fRqmail-send
 .I envnoathost	\fIme	\fRqmail-send
diff -urN netqmail-1.05.orig/qmail-qmqpc.c netqmail-1.05.new/qmail-qmqpc.c
--- netqmail-1.05.orig/qmail-qmqpc.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/qmail-qmqpc.c	2007-03-13 13:02:20.000000000 -0600
@@ -102,14 +102,16 @@
 char *server;
 {
   struct ip_address ip;
+  struct ip_address outgoingip;
   char ch;
 
+  outgoingip.d[0] = outgoingip.d[1] = outgoingip.d[2] = outgoingip.d[3] = (unsigned long) 0;
   if (!ip_scan(server,&ip)) return;
 
   qmqpfd = socket(AF_INET,SOCK_STREAM,0);
   if (qmqpfd == -1) die_socket();
 
-  if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) {
+  if (timeoutconn(qmqpfd,&ip,&outgoingip,PORT_QMQP,10) != 0) {
     lasterror = 73;
     if (errno == error_timeout) lasterror = 72;
     close(qmqpfd);
diff -urN netqmail-1.05.orig/qmail-remote.8 netqmail-1.05.new/qmail-remote.8
--- netqmail-1.05.orig/qmail-remote.8	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/qmail-remote.8	2007-03-13 13:02:19.000000000 -0600
@@ -114,6 +114,53 @@
 always exits zero.
 .SH "CONTROL FILES"
 .TP 5
+.I domainbindings
+Local IP bindings based on envelope sender domain.
+Each binding has the form
+.IR domain\fB:\fIlocal-ip ,
+without any extra spaces.
+If
+.I domain
+matches
+.IR host ,
+.B qmail-remote
+will bind the local side of the socket for the outgoing connection to
+.IR local-ip .
+.I local-ip
+may be empty;
+this tells
+.B qmail-remote
+to let the OS choose the local address for outgoing connections as usual.
+.I domainbindings
+may include wildcards:
+
+.EX
+   example.com:5.6.7.8
+   .example.com:5.6.7.9
+   heaven.af.mil:1.2.3.4
+.EE
+
+Here the connection for any message with an envelope sender address ending with
+.B .example.com
+(but not
+.B example.com
+itself)
+is bound to local address
+.BR 5.6.7.9 ,
+while envelope senders in
+.B example.com
+are bound to 
+.BR 5.6.7.8 ,
+and senders in
+.B heaven.af.mil
+are bound to 
+.BR 1.2.3.4 .
+All other outgoing connections (including messages with the null return-path)
+use the OS-chosen default local address. The
+.B qmail
+system does not protect you if you specify an invalid local address to
+bind to.
+.TP 5
 .I helohost
 Current host name,
 for use solely in saying hello to the remote SMTP server.
@@ -122,7 +169,9 @@
 if that is supplied;
 otherwise
 .B qmail-remote
-refuses to run.
+refuses to run.  If the envelope sender address matches a domain in the
+.IR domainbindings
+control file, the envelope sender domain will be used instead of this value.
 .TP 5
 .I smtproutes
 Artificial SMTP routes.
diff -urN netqmail-1.05.orig/qmail-remote.c netqmail-1.05.new/qmail-remote.c
--- netqmail-1.05.orig/qmail-remote.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/qmail-remote.c	2007-03-13 13:02:21.000000000 -0600
@@ -41,12 +41,16 @@
 stralloc helohost = {0};
 stralloc routes = {0};
 struct constmap maproutes;
+stralloc localips = {0};
+struct constmap maplocalips;
 stralloc host = {0};
 stralloc sender = {0};
+stralloc senderbind = {0};
 
 saa reciplist = {0};
 
 struct ip_address partner;
+struct ip_address outgoingip;
 
 void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); }
 void zero() { if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); }
@@ -70,6 +74,8 @@
 Unable to switch to home directory. (#4.3.0)\n"); zerodie(); }
 void temp_control() { out("Z\
 Unable to read control files. (#4.3.0)\n"); zerodie(); }
+void temp_badip() { out("Z\
+Unable to parse IP address. (#4.3.0)\n"); zerodie(); }
 void perm_partialline() { out("D\
 SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); }
 void perm_usage() { out("D\
@@ -324,6 +330,14 @@
     case 1:
       if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
   }
+  switch(control_readfile(&localips,"control/domainbindings",0)) {
+    case -1:
+      temp_control();
+    case 0:
+      if (!constmap_init(&maplocalips,"",0,1)) temp_nomem(); break;
+    case 1:
+      if (!constmap_init(&maplocalips,localips.s,localips.len,1)) temp_nomem(); break;
+  }
 }
 
 void main(argc,argv)
@@ -332,12 +346,14 @@
 {
   static ipalloc ip = {0};
   int i;
+  int j;
   unsigned long random;
   char **recips;
   unsigned long prefme;
   int flagallaliases;
   int flagalias;
   char *relayhost;
+  char *senderdomain;
  
   sig_pipeignore();
   if (argc < 4) perm_usage();
@@ -363,9 +379,30 @@
     if (!stralloc_copys(&host,relayhost)) temp_nomem();
   }
 
-
   addrmangle(&sender,argv[2],&flagalias,0);
+
+  outgoingip.d[0] = outgoingip.d[1] = outgoingip.d[2] = outgoingip.d[3] = (unsigned long) 0;
+  senderdomain = 0;
+  if (sender.len) {
+    j = str_rchr(sender.s,'@');
+    if (j) {
+      senderdomain = sender.s + j + 1;
+    }
+    stralloc_copyb(&senderbind,senderdomain,sender.len - j - 1);
+
+    for (i = 0;i <= senderbind.len;++i) {
+      if ((i == 0) || (i == senderbind.len) || (senderbind.s[i] == '.')) {
+        if (senderdomain = constmap(&maplocalips,senderbind.s + i,senderbind.len - i)) break;
+      }
+    }
+    if (senderdomain && !*senderdomain) senderdomain = 0;
  
+    if (senderdomain) { 
+      if (!ip_scan(senderdomain, &outgoingip)) temp_badip();
+      helohost = senderbind;
+    }
+  }
+  
   if (!saa_readyplus(&reciplist,0)) temp_nomem();
   if (ipme_init() != 1) temp_oserr();
  
@@ -414,7 +451,7 @@
     smtpfd = socket(AF_INET,SOCK_STREAM,0);
     if (smtpfd == -1) temp_oserr();
  
-    if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) {
+    if (timeoutconn(smtpfd,&ip.ix[i].ip,&outgoingip,(unsigned int) port,timeoutconnect) == 0) {
       tcpto_err(&ip.ix[i].ip,0);
       partner = ip.ix[i].ip;
       smtp(); /* does not return */
diff -urN netqmail-1.05.orig/qmail-showctl.c netqmail-1.05.new/qmail-showctl.c
--- netqmail-1.05.orig/qmail-showctl.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/qmail-showctl.c	2007-03-13 13:02:22.000000000 -0600
@@ -222,6 +222,7 @@
   do_int("databytes","0","SMTP DATA limit is "," bytes");
   do_str("defaultdomain",1,"defaultdomain","Default domain name is ");
   do_str("defaulthost",1,"defaulthost","Default host name is ");
+  do_lst("domainbindings","No sender domain based local ip bindings.","Sender domain local IP binding: ","");
   do_str("doublebouncehost",1,"doublebouncehost","2B recipient host: ");
   do_str("doublebounceto",0,"postmaster","2B recipient user: ");
   do_str("envnoathost",1,"envnoathost","Presumed domain name is ");
@@ -275,6 +276,7 @@
     if (str_equal(d->d_name,"databytes")) continue;
     if (str_equal(d->d_name,"defaultdomain")) continue;
     if (str_equal(d->d_name,"defaulthost")) continue;
+    if (str_equal(d->d_name,"domainbindings")) continue;
     if (str_equal(d->d_name,"doublebouncehost")) continue;
     if (str_equal(d->d_name,"doublebounceto")) continue;
     if (str_equal(d->d_name,"envnoathost")) continue;
diff -urN netqmail-1.05.orig/remoteinfo.c netqmail-1.05.new/remoteinfo.c
--- netqmail-1.05.orig/remoteinfo.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/remoteinfo.c	2007-03-13 13:02:25.000000000 -0600
@@ -44,12 +44,7 @@
   s = socket(AF_INET,SOCK_STREAM,0);
   if (s == -1) return 0;
  
-  byte_zero(&sin,sizeof(sin));
-  sin.sin_family = AF_INET;
-  byte_copy(&sin.sin_addr,4,ipl);
-  sin.sin_port = 0;
-  if (bind(s,(struct sockaddr *) &sin,sizeof(sin)) == -1) { close(s); return 0; }
-  if (timeoutconn(s,ipr,113,timeout) == -1) { close(s); return 0; }
+  if (timeoutconn(s,ipr,ipl,113,timeout) == -1) { close(s); return 0; }
   fcntl(s,F_SETFL,fcntl(s,F_GETFL,0) & ~O_NDELAY);
  
   len = 0;
diff -urN netqmail-1.05.orig/timeoutconn.c netqmail-1.05.new/timeoutconn.c
--- netqmail-1.05.orig/timeoutconn.c	1998-06-15 04:53:16.000000000 -0600
+++ netqmail-1.05.new/timeoutconn.c	2007-03-13 13:02:25.000000000 -0600
@@ -10,9 +10,10 @@
 #include "byte.h"
 #include "timeoutconn.h"
 
-int timeoutconn(s,ip,port,timeout)
+int timeoutconn(s,ip,outgoingip,port,timeout)
 int s;
 struct ip_address *ip;
+struct ip_address *outgoingip;
 unsigned int port;
 int timeout;
 {
@@ -21,7 +22,14 @@
   char *x;
   fd_set wfds;
   struct timeval tv;
+
+  /* Bind the local address on the outgoing connection */
+  byte_zero(&sin,sizeof(sin));
+  byte_copy(&sin.sin_addr.s_addr,4,outgoingip);
+  sin.sin_family = AF_INET;
  
+  if (-1 == bind(s,(struct sockaddr *) &sin,sizeof(sin))) return -1;
+   
   byte_zero(&sin,sizeof(sin));
   byte_copy(&sin.sin_addr,4,ip);
   x = (char *) &sin.sin_port;
@@ -30,8 +38,6 @@
  
   if (ndelay_on(s) == -1) return -1;
  
-  /* XXX: could bind s */
- 
   if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) {
     ndelay_off(s);
     return 0;
