Dear all,

We have a htdig installation for our college that uses different IP
addresses to perform normal and external (to the college network)
searches. To achieve this we have always used a separate squid proxy to
make connections to college webservers from a special non-college IP
address.

It would be better, IMHO, for htdig to bind to different source ethernet
addresses (present on the machine as aliases to the primary address) as
a configuration option. To that end I've produced (an untested and
scrappy) patch (attached) against the current beta.

The patch should allow you to use the following directive in your
htdig.conf file:

# interface address to use (for hosts with more than one IP address).
#
interface: 123.45.6.7

I've not tested the patch much yet and there may be several scrappy bits
of programming (I am not a good c++ programmer) verify that it works...
you can choose any interface on chi and put its IP addr in the interface
directive. Running rundig should cause that IP address to be listed in
log files of the webservers that you search against.

Take care,
Martin.

-- 
-- Dr MDT Evans, Computing Services, Queen Mary, University of London
diff -Naur htdig-3.2.0b5.orig/htdig/Document.cc htdig-3.2.0b5.mdte3/htdig/Document.cc
--- htdig-3.2.0b5.orig/htdig/Document.cc	2003-10-23 03:10:55.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htdig/Document.cc	2004-02-17 12:14:49.000000000 +0000
@@ -260,7 +260,8 @@
    HtDateTime 		*ptrdatetime = 0;
    int			useproxy = UseProxy();
    int                  NumRetries;
-  
+   HtConfiguration* config= HtConfiguration::config();
+
    transportConnect = 0;
 
    if (ExternalTransport::canHandle(url->service()))
@@ -527,7 +528,10 @@
       
       // OK. Let's set the maximum size of a document to be retrieved
       transportConnect->SetRequestMaxDocumentSize(max_doc_size);
-      
+
+      // Set the local interface to use
+      transportConnect->SetLocalInterface(config->Find("interface"));
+                  
       // Let's set the credentials
       if (authorization.length())
       	transportConnect->SetCredentials(authorization);
diff -Naur htdig-3.2.0b5.orig/htnet/Connection.cc htdig-3.2.0b5.mdte3/htnet/Connection.cc
--- htdig-3.2.0b5.orig/htnet/Connection.cc	2003-07-21 09:16:11.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htnet/Connection.cc	2004-02-16 16:43:59.000000000 +0000
@@ -323,6 +323,40 @@
     return OK;
 }
 
+//*****************************************************************************
+// Assign_Interface
+// - mdte local bind patch.
+int Connection::Assign_Interface(const String& name)
+{
+    struct hostent *hp;
+    unsigned int addr;
+
+    if (name.empty()) { 
+       return OK;
+    }
+    
+    addr = inet_addr((char*)name.get());
+    if (addr == (unsigned int)~0)
+    {
+        // Gets the host given a string
+        hp = gethostbyname(name);
+
+        if (hp == 0)
+           return NOTOK;
+
+        memcpy((char *)&interface.sin_addr, (char *)hp->h_addr, hp->h_length);
+    }
+    else
+    {
+        memcpy((char *)&interface.sin_addr, (char *)&addr, sizeof(addr));
+    }
+
+    interface_name = name.get();
+    interface_ip_address = inet_ntoa(interface.sin_addr);
+
+    return OK;
+}
+
 //
 // Do nothing, we are only interested in the EINTR return of the
 // running system call.
@@ -337,7 +371,19 @@
 {
     int	status;
     int retries = retry_value;
-
+    int bind_status;
+    
+    // bind to local interface
+    if ( &interface!=0 ) {
+      //cout <<"Connection.cc : really binding now." <<endl;
+      bind_status = bind(sock,(struct sockaddr *)&interface,sizeof(interface));
+      if (bind_status==-1) {
+         cout <<"problem ("<<errno<< ") binding to local interface"<<endl;
+         return NOTOK;
+      }
+    }
+        
+    // try to connect
     while (retries--)
       {
 #ifndef _MSC_VER //_WIN32
@@ -419,6 +465,18 @@
     return OK;
 }
 
+//*****************************************************************************
+// int Connection::BindLocalInterface()
+// - mdte patch function to bind to an interface on the htdig host
+//
+int Connection::BindLocalInterface()
+{
+    if (::bind(sock, (struct sockaddr *)&interface, sizeof(interface)) == NOTOK)
+    {
+	return NOTOK;
+    }
+    return OK;
+}
 
 //*****************************************************************************
 // int Connection::Get_Port()
diff -Naur htdig-3.2.0b5.orig/htnet/Connection.h htdig-3.2.0b5.mdte3/htnet/Connection.h
--- htdig-3.2.0b5.orig/htnet/Connection.h	2003-06-24 20:58:06.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htnet/Connection.h	2004-02-10 13:00:07.000000000 +0000
@@ -59,6 +59,7 @@
    // Host stuff
    int Assign_Server(const String& name);
    int Assign_Server(unsigned int addr = INADDR_ANY);
+   int Assign_Interface(const String& name);
    const String &Get_Server() const { return server_name; }
    const String &Get_Server_IPAddress() const { return server_ip_address; }
 
@@ -69,6 +70,7 @@
 
    // Registration things
    int Bind();
+   int BindLocalInterface();
    int Listen(int n = 5);
 
    // IO
@@ -111,10 +113,13 @@
 protected:
    int            sock;
    struct         sockaddr_in server;
+   struct         sockaddr_in interface;
    int            connected;
    String         peer;
    String         server_name;
    String         server_ip_address;
+   String         interface_name;
+   String         interface_ip_address;
    int            need_io_stop;
    int            timeout_value;
    int            retry_value;
diff -Naur htdig-3.2.0b5.orig/htnet/HtHTTP.cc htdig-3.2.0b5.mdte3/htnet/HtHTTP.cc
--- htdig-3.2.0b5.orig/htnet/HtHTTP.cc	2003-10-21 02:16:58.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htnet/HtHTTP.cc	2004-02-16 15:18:04.000000000 +0000
@@ -547,6 +547,12 @@
       	 return Connection_no_port;   	
 	 else if (debug > 4)
 	       cout << "\tAssigned the port " << _url.port() << endl;
+
+      // Assign the local interface to the connection
+      if ( !AssignConnectionInterface() )
+      	 return Connection_failed;
+	 else if (debug > 4)
+	       cout << "\tAssigned the local interface." << endl;
    }
 
    // Connect
diff -Naur htdig-3.2.0b5.orig/htnet/Transport.cc htdig-3.2.0b5.mdte3/htnet/Transport.cc
--- htdig-3.2.0b5.orig/htnet/Transport.cc	2003-07-21 09:16:11.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htnet/Transport.cc	2004-02-17 12:12:20.000000000 +0000
@@ -163,7 +163,7 @@
 
 Transport::Transport(Connection* connection)
 : _connection(connection),
-   _host(0), _ip_address(0), _port(-1), _timeout(DEFAULT_CONNECTION_TIMEOUT),
+   _host(0), _ip_address(0), _port(-1), _interface(0), _timeout(DEFAULT_CONNECTION_TIMEOUT),
    _retries(1), _wait_time(5),
    _modification_time(0), _max_document_size(0),
    _credentials(0), _useproxy(0), _proxy_credentials(0)
@@ -271,6 +271,23 @@
 }
 
 
+   // Assign the local interface to the connection
+
+int Transport::AssignConnectionInterface()
+{
+   if (debug > 5)
+      cout << "\tAssigning the interface (" << _interface << ") to the TCP connection" << endl;
+
+   if( _connection == 0 )
+     {
+       cout << "Transport::AssignConnectionInterface: _connection is NULL\n";
+       exit(0);
+     }
+      
+   if (_connection->Assign_Interface(_interface) == NOTOK) return 0;
+   
+   return 1;
+}
 
 
    // Connect
diff -Naur htdig-3.2.0b5.orig/htnet/Transport.h htdig-3.2.0b5.mdte3/htnet/Transport.h
--- htdig-3.2.0b5.orig/htnet/Transport.h	2003-07-21 09:16:11.000000000 +0100
+++ htdig-3.2.0b5.mdte3/htnet/Transport.h	2004-02-17 12:29:46.000000000 +0000
@@ -218,6 +218,9 @@
    void SetRequestMaxDocumentSize (int s) { _max_document_size=s; }
    int GetRequestMaxDocumentSize() const { return _max_document_size; }
 
+   // Set the interface to use to download documents
+   void SetLocalInterface (const String& s) { _interface=s; }
+
    virtual Transport_Response *GetResponse() = 0;
    
    virtual DocStatus GetDocumentStatus() = 0; 
@@ -260,6 +263,7 @@
    
    int AssignConnectionServer();
    int AssignConnectionPort();   
+   int AssignConnectionInterface();   
 
    // Connect to the specified host and port
    int Connect();
@@ -321,6 +325,7 @@
    String       _host;                 // TCP Connection host
    String       _ip_address;           // TCP Connection host (IP Address)
    int          _port;                 // TCP Connection port
+   String	_interface;            // TCP local IP interface
    
    int		_timeout;              // Connection timeout
    int		_retries;              // Connection retry limit

Reply via email to