This patch to innfeed 0.10.1 adds the config file items "bind-name" and "bind-port". To be used like "ip-name" and "port-number", they specify the adress _from_ which the connection will be made. This is often necessary with multi-homed hosts. E.g. peer blurf.com { ip-name: news0.blurf.com # I'm news5.roller.org, but news0 has in its hosts.nntp # only my alias IP address, news.sanfran.blurf.com bind-name: news.sanfran.blurf.com } You normally don't want to set "bind-port", it's just there for completeness. Also in here is a one-liner in sysconfig.h to get it to compile and not crash under Linux (2.0.30/Debian 1.3). Bugs are due to See also my patches for INN to create virtual news servers. Index: configfile.h =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/configfile.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- configfile.h 1997/08/01 12:52:06 1.1.1.1 +++ configfile.h 1997/08/01 14:12:34 1.2 @@ -81,7 +81,8 @@ #define PORT_NUMBER "port-number" #define RESP_TIMEOUT "response-timeout" #define STREAMING "streaming" - +#define MY_IP_NAME "bind-name" +#define MY_PORT_NUMBER "bind-port" #define ISPEER(V) (ISSCOPE(V) && strcmp ((V)->v.scope_val->scope_type,"peer") == 0) #define ISSCOPE(V) (V->type == scopeval) Index: connection.c =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/connection.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 connection.c --- connection.c 1997/08/01 12:52:04 1.1.1.1 +++ connection.c 1997/08/10 19:31:04 @@ -184,6 +184,9 @@ u_int maxCheck ; /* the max number of CHECKs to send */ u_short port ; /* the port number to use */ + char *myIpName; /* bind parameter */ + u_short myPort; + /* * Timeout values and their callback IDs */ @@ -398,7 +401,9 @@ u_int respTimeout, u_int flushTimeout, double lowPassHigh, - double lowPassLow) + double lowPassLow, + const char *myIpName, + u_int myPortNum) { Connection cxn ; bool croak = false ; @@ -439,6 +444,9 @@ cxn->ipName = strdup (ipname) ; cxn->port = portNum ; + cxn->myIpName = myIpName ? strdup (myIpName) : NULL; + cxn->myPort = myPortNum ; + cxn->articleReceiptTimeout = fudgeFactor (articleReceiptTimeout) ; cxn->artReceiptTimerId = 0 ; @@ -466,6 +474,24 @@ } +static int dobind(int fd, char *myIpName, u_short myPortNum) +{ + struct sockaddr_in sa; + struct hostent *hostEnt ; + + if ( !inet_aton (myIpName,&sa.sin_addr) ) + { + if ((hostEnt = gethostbyname (myIpName)) == NULL) { + syslog (LOG_ERR, HOST_RESOLV_ERROR, myIpName, myIpName, + host_err_str ()) ; + return -1; + } + memcpy(&sa.sin_addr, hostEnt->h_addr_list[0], sizeof(sa.sin_addr)); + } + sa.sin_family = AF_INET; + sa.sin_port = htons(myPortNum); + return bind(fd, (struct sockaddr *)&sa, sizeof(sa)); +} @@ -558,6 +584,15 @@ return false ; } + + if (cxn->myIpName) { + if (dobind (fd, cxn->myIpName, cxn->myPort) < 0) { + syslog(LOG_ERR, BIND_ERROR, peerName, cxn->ident); + close(fd); + cxnSleep(cxn); + return false; + } + } rval = connect (fd, (struct sockaddr *) &cxnAddr, sizeof (cxnAddr)) ; if (rval < 0 && errno != EINPROGRESS) Index: connection.h =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/connection.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- connection.h 1997/08/01 12:52:07 1.1.1.1 +++ connection.h 1997/08/01 14:12:39 1.2 @@ -81,7 +81,9 @@ u_int respTimeout, u_int closePeriod, double lowPassLow, - double lowPassHigh) ; + double lowPassHigh, + const char *myIpName, + u_int myPortNum) ; /* Causes the Connection to build the network connection. */ bool cxnConnect (Connection cxn) ; Index: host.c =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/host.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- host.c 1997/08/01 12:52:05 1.1.1.1 +++ host.c 1997/08/01 14:12:40 1.2 @@ -94,6 +94,7 @@ char *ipName ; /* IP name/address from config file. */ char **ipAddrs ; /* the ip addresses of the remote */ char **nextIpAddr ; /* the next ip address to hand out */ + char *myIpName ; /* our ip address to bind to */ Connection *connections ; /* NULL-terminated list of all connections */ bool *cxnActive ; /* true if the corresponding cxn is active */ @@ -113,6 +114,7 @@ u_int articleTimeout ; /* max time to wait for new article */ u_int responseTimeout ; /* max time to wait for response from remote */ u_short port ; /* port the remote listens on */ + u_short myPort ; /* port we connect from */ ProcQElem queued ; /* articles done nothing with yet. */ ProcQElem queuedTail ; @@ -246,7 +248,9 @@ bool *streaming, double *lowFilter, double *highFilter, - u_short *portNumber) ; + u_short *portNumber, + char **myIpName, + u_short *myPortNumber) ; static Host findHostByName (char *name) ; static void hostCleanup (void) ; @@ -539,11 +543,11 @@ void configHosts (bool talkSelf) { Host nHost, h, q ; - char *name = NULL, *ipName = NULL ; + char *name = NULL, *ipName = NULL, *myIpName = NULL ; u_int artTout, respTout, initCxns, maxCxns, maxChecks ; double lowFilter, highFilter ; bool streaming ; - u_short portNum ; + u_short portNum, myPortNum ; HostHolder hh, hi ; name = ipName = NULL ; @@ -562,7 +566,7 @@ while (getHostInfo (&name, &ipName, &artTout, &respTout, &initCxns, &maxCxns, &maxChecks, &streaming, &lowFilter, - &highFilter,&portNum)) + &highFilter,&portNum, &myIpName, &myPortNum)) { h = findHostByName (name) ; if ( h != NULL ) @@ -634,7 +638,8 @@ h->articleTimeout, h->port, h->responseTimeout, - defClosePeriod, lowFilter, highFilter) ; + defClosePeriod, lowFilter, highFilter, + h->myIpName, h->myPort) ; h->cxnActive [i] = false ; h->cxnSleeping [i] = false ; cxnWait (h->connections [i]) ; @@ -653,7 +658,8 @@ { nHost = newHost (mainListener,name,ipName,artTout,respTout,initCxns, maxCxns,maxChecks,portNum,CLOSE_PERIOD, - streaming,lowFilter,highFilter) ; + streaming,lowFilter,highFilter, + myIpName,myPortNum) ; if (nHost == NULL) { @@ -683,10 +689,10 @@ if (initCxns == 0 && talkSelf) syslog (LOG_NOTICE,BATCH_AND_NO_CXNS,name) ; - dprintf (1,"Adding %s %s article (%d) response (%d) initial (%d) max con (%d) max checks (%d) portnumber (%d) streaming (%s) lowFilter (%.2f) highFilter (%.2f)\n", + dprintf (1,"Adding %s %s article (%d) response (%d) initial (%d) max con (%d) max checks (%d) portnumber (%d) streaming (%s) lowFilter (%.2f) highFilter (%.2f) bind (%s:%d)\n", name, ipName, artTout, respTout, initCxns, maxCxns, maxChecks, portNum, streaming ? "true" : "false", - lowFilter, highFilter) ; + lowFilter, highFilter, myIpName, myPortNum) ; FREE (name) ; FREE (ipName) ; @@ -730,7 +736,9 @@ u_int closePeriod, bool streaming, double lowPassLow, - double lowPassHigh) + double lowPassHigh, + const char *myIpName, + u_short myPortNum) { u_int i ; Host nh ; @@ -825,6 +833,12 @@ nh->spoolTime = 0 ; + if (myIpName == NULL) + nh->myIpName = NULL ; + else + nh->myIpName = strdup (myIpName) ; + nh->myPort = myPortNum ; + /* Create all the connections, but only the initial ones connect immediately */ for (i = 0 ; i < maxCxns ; i++) @@ -839,7 +853,9 @@ nh->responseTimeout, closePeriod, nh->lowPassLow, - nh->lowPassHigh) ; + nh->lowPassHigh, + nh->myIpName, + nh->myPort) ; if (i < initialCxns) cxnConnect (nh->connections [i]) ; else @@ -1814,7 +1830,7 @@ if (filename == NULL) die ("Can't set status file name with a NULL filename\n") ; - else if (*filename == NULL) + else if (*filename == '\0') die ("Can't set status file name with a empty string\n") ; if (*filename == '/') @@ -1862,7 +1878,9 @@ bool *streaming, double *lowFilter, double *highFilter, - u_short *portNumber) + u_short *portNumber, + char **myIpName, + u_short *myPortNumber) { long iv ; int bv ; @@ -2012,6 +2030,26 @@ iv = PORTNUM ; } *portNumber = (u_short) iv ; + + if (getString (s,MY_IP_NAME,&p,INHERIT)) + *myIpName = p ; + else + *myIpName = NULL ; + + if (!getInteger (s,MY_PORT_NUMBER,&iv,INHERIT)) + { + /* syslog (LOG_ERR,NO_PEER_FIELD_INT,MY_PORT_NUMBER,name,0) ; */ + iv = 0 ; + } + else if (iv < 1) + { + syslog (LOG_ERR,"ME %s value (%ld) in peer %s cannot be less than 1", + MY_PORT_NUMBER,iv,name) ; + iv = 0 ; + } + *myPortNumber = (u_short) iv ; + + } @@ -2027,7 +2065,9 @@ bool *streaming, double *lowFilter, double *highFilter, - u_short *portNumber) + u_short *portNumber, + char **myIpName, + u_short *myPortNumber) { static int idx = 0 ; value *v ; @@ -2048,7 +2088,7 @@ hostDetails(s,*name,ipName,articleTimeout,responseTimeout, initialConnections,maxConnections,maxChecks,streaming, - lowFilter,highFilter,portNumber) ; + lowFilter,highFilter,portNumber,myIpName,myPortNumber) ; isGood = true ; Index: host.h =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/host.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- host.h 1997/08/01 12:52:07 1.1.1.1 +++ host.h 1997/08/01 14:12:44 1.2 @@ -90,7 +90,9 @@ u_int closePeriod, bool streaming, double lowPassLow, - double lowPassHigh) ; + double lowPassHigh, + const char *myIpName, + u_short myPortNum) ; void configHosts (bool talkSelf) ; Index: innlistener.c =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/innlistener.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- innlistener.c 1997/08/01 12:52:06 1.1.1.1 +++ innlistener.c 1997/08/01 14:12:46 1.2 @@ -669,7 +669,7 @@ newHostObj = newHost (lis, peerName, peerName, articleTout, respTout, initialCxns, maxCxns, maxChecks, portNum, CLOSE_PERIOD, - streaming, lowFilter, highFilter); + streaming, lowFilter, highFilter, NULL, 0); if (newHostObj == NULL) { Index: msgs.h =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/msgs.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- msgs.h 1997/08/01 12:52:07 1.1.1.1 +++ msgs.h 1997/08/01 14:12:47 1.2 @@ -36,6 +36,7 @@ #define ARTICLE_TIMEOUT_MSG "%s:%d idle tearing down connection" #define ARTICLE_TIMEOUT_W_Q_MSG "%s:%d idle connection still has articles" +#define BIND_ERROR "%s:%d bind : %m" #define CONNECT_ERROR "%s:%d connect : %m" #define CONNECTED "%s:%d connected" #define CXN_CLOSED "%s:%d closed" Index: sysconfig.h =================================================================== RCS file: /home/olaf/CVSrepos/news/innfeed/sysconfig.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 sysconfig.h --- sysconfig.h 1997/08/01 12:52:07 1.1.1.1 +++ sysconfig.h 1997/08/05 20:24:55 @@ -82,8 +82,8 @@ /* Note: If you are running version 5.4.3 or better of libc, then 16 is the number to use. Lower than that, and you should use 1. */ -#define MAX_WRITEV_VEC 1 -#define DO_NEED_SYS_SELECT 1 +#define MAX_WRITEV_VEC 16 +#define USE_SIGACTION #endif =================================================================== End of patch.