Author: Gte <gte@atomicrevs.demon.co.uk>
authorGreg Sikorski <gte@atomicrevs.demon.co.uk>
Thu, 13 Apr 2000 05:53:48 +0000 (05:53 +0000)
committerGreg Sikorski <gte@atomicrevs.demon.co.uk>
Thu, 13 Apr 2000 05:53:48 +0000 (05:53 +0000)
Log message:

 * tools/Bouncer/*: Add port bouncer for http (x/w)
 * tools/Bouncer/*: Add comments/documentation/tags.
 * tools/Bouncer/*: Add debug defines, make task fork().

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@159 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
tools/Bounce/Bounce.cpp
tools/Bounce/Bounce.h

index ac70a6be32dc068b928a92c281639af2a5d9f278..5dbfba807b4a2eb627cfb3de0ca9feed9705eb7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-04-13  Greg Sikorski <gte@atomicrevs.demon.co.uk>
+
+       * tools/Bouncer/*: Add comments/documentation/tags.
+       * tools/Bouncer/*: Add debug defines, make task fork().
+
 2000-04-12  Thomas Helvey <tomh@inxpress.net>
        * ircd/s_err.c: Cleanup s_err.c make one table so we
        don't have to do anything tricky to get an error string.
 #
 # ChangeLog for ircu2.10.11
 #
-# $Id: ChangeLog,v 1.76 2000-04-13 03:49:06 bleep Exp $
+# $Id: ChangeLog,v 1.77 2000-04-13 05:53:48 gte Exp $
 #
 # Insert new changes at beginning of the change list.
 #
index 87509674e2df3a2f1fef1374cf14a8bf9d1b0775..4ea729fd93d35b9e528851d227968d387376fcbe 100755 (executable)
@@ -1,21 +1,69 @@
-#include "Bounce.h"
-
 /*
- *  Lacking Comments. :)
- *  12/04/2000 --Gte
+ * IRC - Internet Relay Chat, tools/Bouncer/Bouncer.cpp
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ *                    University of Oulu, Computing Center
+ *
+ * See file AUTHORS in IRC package for additional names of
+ * the programmers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Port Bouncer.
+ *
+ * This tool is designed to set up a number of local listening ports, and
+ * then forward any data recived on those ports, to another host/port combo.
+ * Each listening port can bounce to a different host/port defined in the
+ * config file. --Gte 
+ *
+ * $Id: Bounce.cpp,v 1.2 2000-04-13 05:53:48 gte Exp $ 
+ *
  */
 
+#include "Bounce.h"
 int main() {
   Bounce* application = new Bounce();
 
   /*
    *  Ignore SIGPIPE.
    */
+
   struct sigaction act; 
   act.sa_handler = SIG_IGN;
   act.sa_flags = 0;
   sigemptyset(&act.sa_mask);
   sigaction(SIGPIPE, &act, 0);
+#ifndef DEBUG
+  /*
+   *  If we aren't debugging, we might as well
+   *  detach from the console.
+   */
+
+  pid_t forkResult = fork() ;
+  if(forkResult < 0)
+  { 
+    printf("Unable to fork new process.\n");
+    return -1 ;
+  } 
+  else if(forkResult != 0)
+  {
+    printf("Successfully Forked, New process ID is %i.\n", forkResult);
+    return 0;
+  } 
+#endif
 
   /*
    *  Create new application object, bind listeners and begin
@@ -28,7 +76,24 @@ int main() {
   } 
 }
 
+/*
+ ****************************************
+ *                                      *
+ *     Bounce class implementation.     *
+ *                                      *
+ ****************************************
+ */
 void Bounce::bindListeners() { 
+/*
+ *  bindListeners.
+ *  Inputs: Nothing.
+ *  Outputs: Nothing.
+ *  Process: 1. Reads the config file, and..
+ *           2. Creates a new listener for each 'P' line found.
+ *
+ */
+
   FILE* configFd;
   char tempBuf[256];
   int localPort = 0;
@@ -42,7 +107,7 @@ void Bounce::bindListeners() {
   
   if(!(configFd = fopen("bounce.conf", "r")))
   {
-    printf("Error, unable to open config.\n");
+    printf("Error, unable to open config file!\n");
     exit(0);
   } 
 
@@ -51,22 +116,24 @@ void Bounce::bindListeners() {
     switch(tempBuf[0])
     {
       case 'P': { /* Add new port listener */ 
-      strtok(tempBuf, ":");
-      vHost = strtok(NULL, ":");
-      localPort = atoi(strtok(NULL, ":"));
-      remoteServer = strtok(NULL, ":");
-      remotePort = atoi(strtok(NULL, ":")); 
-
-      Listener* newListener = new Listener();
-      strcpy(newListener->myVhost, vHost); 
-      strcpy(newListener->remoteServer, remoteServer);
-      newListener->remotePort = remotePort;
-      newListener->localPort = localPort;
-      printf("Adding new Listener: Local: %s:%i, Remote: %s:%i\n", vHost, localPort, remoteServer, remotePort);
-
-      newListener->beginListening();
-      listenerList.insert(listenerList.begin(), newListener); 
-      break;
+        strtok(tempBuf, ":");
+        vHost = strtok(NULL, ":");
+        localPort = atoi(strtok(NULL, ":"));
+        remoteServer = strtok(NULL, ":");
+        remotePort = atoi(strtok(NULL, ":")); 
+
+        Listener* newListener = new Listener();
+        strcpy(newListener->myVhost, vHost); 
+        strcpy(newListener->remoteServer, remoteServer);
+        newListener->remotePort = remotePort;
+        newListener->localPort = localPort;
+#ifdef DEBUG
+        printf("Adding new Listener: Local: %s:%i, Remote: %s:%i\n", vHost, localPort, remoteServer, remotePort);
+#endif
+
+        newListener->beginListening();
+        listenerList.insert(listenerList.begin(), newListener); 
+        break;
       }
     }
     } 
@@ -75,8 +142,14 @@ void Bounce::bindListeners() {
 
 void Bounce::checkSockets() { 
 /*
- *  Build up a Select FD set, and Select() 'em.
- */
+ *  checkSockets.
+ *  Inputs: Nothing.
+ *  Outputs: Nothing.
+ *  Process: 1. Builds up a FD_SET of all sockets we wish to check.
+ *              (Including all listeners & all open connections).
+ *           2. SELECT(2) the set, and forward/accept as needed.
+ *
+ */ 
   typedef std::list<Listener*> listenerContainer;
   typedef listenerContainer::iterator listIter;
 
@@ -94,6 +167,10 @@ void Bounce::checkSockets() {
   char* tempBuf;
 
   FD_ZERO(&readfds);
+  /*
+   *  Add all Listeners to the set.
+   */
 
   listIter a = listenerList.begin();
   while(a != listenerList.end())
@@ -104,6 +181,11 @@ void Bounce::checkSockets() {
     a++;
   }
 
+  /*
+   *  Add Local & Remote connections from each
+   *  connection object to the set.
+   */
+
   connIter b = connectionsList.begin();
   while(b != connectionsList.end())
   { 
@@ -119,9 +201,14 @@ void Bounce::checkSockets() {
   select(highestFd+1, &readfds, NULL, NULL, &tv); 
 
   /*
-   *  Check all connections for reading/writing
+   *  Check all connections for readability.
    *  First check Local FD's.
+   *  If the connection is closed on either side,
+   *  shutdown both sockets, and clean up.
+   *  Otherwise, send the data from local->remote, or
+   *  remote->local.
    */
+
   b = connectionsList.begin();
   while(b != connectionsList.end())
   { 
@@ -130,12 +217,14 @@ void Bounce::checkSockets() {
     if (FD_ISSET(tempFd, &readfds))
     { 
       tempBuf = (*b)->localSocket->read();
-      if ((tempBuf[0] == 0)) // Connection closed on one of our sockets.
+      if ((tempBuf[0] == 0)) // Connection closed.
       {
         close((*b)->localSocket->fd);
         close((*b)->remoteSocket->fd); 
+#ifdef DEBUG
         printf("Closing FD: %i\n", (*b)->localSocket->fd);
         printf("Closing FD: %i\n", (*b)->remoteSocket->fd); 
+#endif
         delete(*b);
         delCheck = 1;
         b = connectionsList.erase(b); 
@@ -158,12 +247,14 @@ void Bounce::checkSockets() {
     if (FD_ISSET(tempFd, &readfds))
     {
       tempBuf = (*b)->remoteSocket->read();
-      if ((tempBuf[0] == 0)) // Connection closed on one of our sockets.
+      if ((tempBuf[0] == 0)) // Connection closed.
       {
         close((*b)->localSocket->fd);
         close((*b)->remoteSocket->fd); 
+#ifdef DEBUG
         printf("Closing FD: %i\n", (*b)->localSocket->fd);
         printf("Closing FD: %i\n", (*b)->remoteSocket->fd);
+#endif
         delete(*b);
         delCheck = 1;
         b = connectionsList.erase(b); 
@@ -178,6 +269,7 @@ void Bounce::checkSockets() {
   /*
    *  Check all listeners for new connections.
    */
+
   a = listenerList.begin();
   while(a != listenerList.end())
   { 
@@ -191,8 +283,22 @@ void Bounce::checkSockets() {
 
 }
 
-void Bounce::recieveNewConnection(Listener* listener)
-{
+void Bounce::recieveNewConnection(Listener* listener) {
+/*
+ *  recieveNewConnection.
+ *  Inputs: A Listener Object.
+ *  Outputs: Nothing.
+ *  Process: 1. Recieves a new connection on a local port,
+ *              and creates a connection object for it.
+ *           2. Accepts the incomming connection.
+ *           3. Creates a new Socket object for the remote
+ *              end of the connection.
+ *           4. Connects up the remote Socket.
+ *           5. Adds the new Connection object to the
+ *              connections list.
+ *
+ */
+
   Connection* newConnection = new Connection(); 
   newConnection->localSocket = listener->handleAccept();
 
@@ -201,15 +307,34 @@ void Bounce::recieveNewConnection(Listener* listener)
   if(remoteSocket->connectTo(listener->remoteServer, listener->remotePort)) { 
     connectionsList.insert(connectionsList.begin(), newConnection);
   } else {
-    newConnection->localSocket->write("Unable to connect to remote host..\n");
+#ifdef DEBUG
+    newConnection->localSocket->write("Unable to connect to remote host.\n");
+#endif
     close(newConnection->localSocket->fd);
     delete(newConnection);
     delete(remoteSocket);
   } 
 }
  
+
+/*
+ ****************************************
+ *                                      *
+ *    Listener class implementation.    *
+ *                                      *
+ ****************************************
+ */
+
  
 Socket* Listener::handleAccept() {
+/*
+ *  handleAccept.
+ *  Inputs: Nothing.
+ *  Outputs: A Socket Object.
+ *  Process: 1. Accept's an incomming connection,
+ *              and returns a new socket object. 
+ */
+
   int new_fd = 0;
   int sin_size = sizeof(struct sockaddr_in);
 
@@ -220,6 +345,15 @@ Socket* Listener::handleAccept() {
 }
  
 void Listener::beginListening() {
+/*
+ *  beginListening.
+ *  Inputs: Nothing.
+ *  Outputs: Nothing.
+ *  Process: 1. Binds the local ports for all the
+ *              Listener objects.
+ *
+ */
+
   struct sockaddr_in my_addr;
   int bindRes;
   int optval;
@@ -247,31 +381,76 @@ void Listener::beginListening() {
    } 
 }
 
+/*
+ ****************************************
+ *                                      *
+ *     Socket class implementation.     *
+ *                                      *
+ ****************************************
+ */
+
+
 Socket::Socket() {
+/*
+ *  Socket Constructor.
+ *  Inputs: Nothing.
+ *  Outputs: Nothing.
+ *  Process: Initialises member variables.
+ *
+ */
+
   fd = -1;
   lastReadSize = 0;
 }
 
-int Socket::write(char *message, int len)
-{ 
+int Socket::write(char *message, int len) { 
+/*
+ *  write.
+ *  Inputs: Message string, and lenght.
+ *  Outputs: Amount written, or 0 on error.
+ *  Process: 1. Writes out 'len' amount of 'message'.
+ *              to this socket.
+ *
+ */
+
    if (fd == -1) return 0; 
  
    int amount = ::write(fd, message, len); 
+#ifdef DEBUG
    printf("Wrote %i Bytes.\n", amount);
+#endif
    return amount; 
 }
 
-int Socket::write(char *message)
-{ 
+int Socket::write(char *message) { 
+/*
+ *  write(2).
+ *  Inputs: Message string.
+ *  Outputs: Amount writte, or 0 on error.
+ *  Process: Writes out the whole of 'message'.
+ *
+ */
+
    if (fd == -1) return 0; 
  
    int amount = ::write(fd, message, strlen(message)); 
+#ifdef DEBUG
    printf("Wrote %i Bytes.\n", amount);
+#endif
    return amount; 
 }
 
 
 int Socket::connectTo(char *hostname, unsigned short portnum) { 
+/*
+ *  connectTo.
+ *  Inputs: Hostname and port.
+ *  Outputs: +ve on success, 0 on failure.
+ *  Process: 1. Connects this socket to remote 'hostname' on
+ *              port 'port'.
+ *
+ */
+
   struct hostent     *hp;
  
   if ((hp = gethostbyname(hostname)) == NULL) { 
@@ -294,8 +473,16 @@ int Socket::connectTo(char *hostname, unsigned short portnum) {
   return(1);
 }
 
-char* Socket::read()
-{ 
+char* Socket::read() { 
+/*
+ *  read.
+ *  Inputs: Nothing.
+ *  Outputs: char* to static buffer containing data.
+ *  Process: 1. Reads as much as possible from this socket, up to
+ *              4k.
+ *
+ */
+
   int amountRead = 0;
   static char buffer[4096];
 
@@ -304,8 +491,14 @@ char* Socket::read()
   if ((amountRead == -1)) buffer[0] = '\0';
   buffer[amountRead] = '\0';
 
+#ifdef DEBUG
   printf("Read %i Bytes.\n", amountRead);
-  /* Record this incase we're dealing with binary data with 0's in it. */
+#endif
+  /* 
+   * Record this just incase we're dealing with binary data with 0's in it.
+   */
   lastReadSize = amountRead;
   return (char *)&buffer;
 }
+
index 5529786ba7b9ce01ca03d707c48c9cccc253192d..c0e466b8e4004492ae68f7a85a5a863d290591ba 100755 (executable)
@@ -1,3 +1,29 @@
+/*
+ * IRC - Internet Relay Chat, tools/Bouncer/Bouncer.h
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ *                    University of Oulu, Computing Center
+ *
+ * See file AUTHORS in IRC package for additional names of
+ * the programmers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ */
+
 #include <sys/types.h> 
 #include <sys/time.h>
 #include <sys/wait.h> 
@@ -23,7 +49,8 @@
 #include <list>
 using std::list; 
 
-
+#define DEBUG
 /*
  *  "Bounce" Class.
  */
@@ -33,12 +60,12 @@ class Connection;
 class Bounce
 {
 public:
-  list<Listener*> listenerList; // List of Listeners.
+  list<Listener*> listenerList;      // List of 'Listeners'.
   list<Connection*> connectionsList; // List of 'Connections'. 
 
-  void bindListeners(); //Binds Listening Ports.
-  void checkSockets(); // Polls all sockets.
-  void recieveNewConnection(Listener*);
+  void bindListeners(); // Binds Listening Ports.
+  void checkSockets();  // Polls all sockets.
+  void recieveNewConnection(Listener*); // Accepts connections.
 };
 
 /*
@@ -48,14 +75,14 @@ public:
 class Socket 
 {
 public:
-  int fd; 
-  int lastReadSize;
-  struct sockaddr_in address;
-  int connectTo(char*, unsigned short);
-  int write(char*, int); 
-  int write(char*); 
-  char* read();
-  Socket();
+  int fd;                               // File descriptor.
+  int lastReadSize;                     // Size of last read buffer.
+  struct sockaddr_in address;           // Socket addr_in struct.
+  int connectTo(char*, unsigned short); // Connects the socket.
+  int write(char*, int);                // Writes 'int' bytes from message.
+  int write(char*);                     // Writes strlen(message).
+  char* read();                         // Reads as much as possible into a 4k buffer.
+  Socket();                             // Constructor.
 };
 
 /*
@@ -66,18 +93,19 @@ class Bounce;
 class Listener
 {
 public:
-  int fd; 
-  int remotePort;
-  int localPort;
-  char myVhost[15];
-  char remoteServer[15];
+  int fd;                 // File descriptor.
+  int remotePort;         // Remote port from config.
+  int localPort;          // Local port for binding.
+  char myVhost[15];       // Vhost to bind locally.
+  char remoteServer[15];  // Remote server to connect to.
 
-  void beginListening();
-  Socket* handleAccept();
+  void beginListening();  // Bind listening ports.
+  Socket* handleAccept(); // Accept a new connection.
 };
 
 /*
  *  "Connection" Class.
+ *  Simply a container for a local/remote Socket pair.
  */
 
 class Connection