Author: Run <carlo@alinoe.com>
authorBleep <twhelvey1@home.com>
Tue, 7 Mar 2000 00:56:36 +0000 (00:56 +0000)
committerBleep <twhelvey1@home.com>
Tue, 7 Mar 2000 00:56:36 +0000 (00:56 +0000)
Log message:
Overview of changes
-------------------

- The ircd will now always use bind() to bind sockets to interfaces,
  the compile option VIRTUAL_HOST has been removed therefore as it
  is turned on by default now.

- It has become possible to specify in the ircd.conf the interfaces
  to which each listen port should bind to, per port. A default is
  available too though.

- The ircd will now correctly use the same interface as the client
  used to connect to the server when doing an identd lookup.

- It is not needed anymore for the hostname in the M: line to resolve.
  Moreover, if you want to hide your server, make sure it doesn't :).
  If it DOES resolve, then it should be the correct IP-number of
  the actually host (one of your interfaces), in that case it will
  be just like the current ircu with VIRTUAL_HOST defined.

Each interface has an IP-number, you can list those by typing the
following command on the UNIX prompt:

ifconfig -a

You can specify the interfaces to which a listen port needed to bind
to by giving this IP-number in the corresponding "passwd" field of the
P: line (the third field).  For example, to bind a listen port `6667'
to 127.0.0.1, use:

P::127.0.0.1::6667

At this moment, each P: line represents a client port. With hide8.patch
however, you can also bind the server listen port to an interface
by simply adding a P: line, forinstance:

P::192.168.1.2::4400

would bind the server port to 192.168.1.2.  Here `4400' is the server
port that is specified in the M: line! (You can only have one server
port).  You can of course bind it to more than one interface now
(that was not possible before, it was all (#undef VIRTUAL_HOST) or
only one (#define VIRTUAL_HOST)) by adding more P: lines for port 4400.
For instance:

P::192.168.1.2::4400
P::127.0.0.1::4400

Using a '*' in the password field will bind that port to ALL interfaces,
while using nothing at all will use the DEFAULT inteface.
For example:

P::::6667

will bind a client port 6667 to the DEFAULT interface.

The default interface is determined as follows:

1) If an interface is specified on the commandline (using the -w commandline
   option), then that is the default interface;  otherwise
2) If the hostname in the M: line resolves to a local IP number, then that
   is the default interface;  otherwise
3) All interfaces will be bound by default (as if a '*' was specified).

For outgoing connect (/connect and /uping), the ircd will use a slightly
different "default" interface:

1) If the IP of the peer server to connect is 127.0.0.1 it will use
   127.0.0.1 as interface; otherwise
2) see 1) above
3) see 2) above
4) The last interface specified in a P: line in the ircd.conf for the
   server port that is not 127.0.0.1 is the default interface;  otherwise
5) see 3) above

However, I wouldn't worry about this too much: it should do what is
intuitively right.

Finally, the syntax of /CONNECT and /UPING have been extended.
It now is possible to specify an IP-number explicitely to distinguish
between different C/N: lines.

You can still do:

/CONNECT target.server 4400 remote.server

but you can also use:

/CONNECT target.server <IP number>:4400 remote.server

For instance, if "remote.server" had the following C/N lines for
target.server:

C:111.111.111.111:passwd:target.server
N:111.111.111.111:passwd:target.server
C:127.0.0.1:passwd:target.server
N:127.0.0.1:passwd:target.server

Then you can specify to which interface you want to connect
by using:

/CONNECT target.server 111.111.111.111:4400 remote.server

or

/CONNECT target.server 127.0.0.1:4400 remote.server

by default it will use the C: line at the top.

If you want to hide your HUB, then you can apply this patch --
add C/N lines for all your peers using 127.0.0.1 as IP number
and set up portwarders (ask Nemesi for help with the latter).

Of course your peers need to fix their and ircd.conf and rehash,
as well as use a portforwarder too (like ssh) but they won't need
to patch their servers.

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

18 files changed:
ChangeLog
config/config-sh.in
doc/Configure.help
doc/example.conf
doc/ircd.8
include/ircd.h
include/patchlevel.h
include/s_bsd.h
ircd/chkconf.c
ircd/ircd.c
ircd/opercmds.c
ircd/s_auth.c
ircd/s_bsd.c
ircd/s_conf.c
ircd/s_debug.c
ircd/s_ping.c
ircd/s_serv.c
ircd/userload.c

index 54f523f858b7255c2161a411cc00c5d8ffe057d0..88cee38582630c0d3d125ffeb770c0c6e64697b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,15 @@
 #
 # ChangeLog for Undernet ircu Servers
 #
-# $Id: ChangeLog,v 1.9 2000-01-22 17:47:07 bleep Exp $
+# $Id: ChangeLog,v 1.10 2000-03-07 00:56:36 bleep Exp $
 #
 # Please insert new entries on the top of the list, a one or two line comment
 # is sufficient. Please include your name on the entries we know who to blame.
 # Please keep lines < 80 chars.
 #-------------------------------------------------------------------------------
+* Add Run's pline patch. --Run
+* channel.c (send_channel_modes): send modes for second line for channels with
+  a lot of ops. --Gte
 * config-sh.in: add runs fix for symlink restart bug. --Bleep
 * Fixed default behavior for BADCHAN. supposed to DEFAULT yes, however
   should not change each time a make config is done. -- WT
index a84f115e009dac86a2ab2bfbb3b9a8b5f1a7e410..2df6b728165c7457abe9dfd92678302b1e097510 100644 (file)
@@ -171,7 +171,6 @@ comment 'General defines'
     fi
   fi
   bool 'Set up a Unix domain socket to connect clients/servers' UNIXPORT
-  bool 'Do you need virtual hosting' VIRTUAL_HOST
   PREV_HUB=$HUB
   bool 'Will you connect to more then one server at a time' HUB
   if [ "$PREV_HUB" != "$HUB" ]; then
@@ -201,7 +200,6 @@ comment 'Debugging (do not define this on production servers)'
     define_bool MEMSIZESTATS $MEMSIZESTATS
     define_bool MEMTIMESTATS $MEMTIMESTATS
   fi
-  bool 'Are you testing on a host without DNS' NODNS
 endmenu
 
 mainmenu_option next_comment
index 508e20832743bce28a47f49f55ee2d6069a844ea..6b1046dba1ff55498d8f639f35d71ce3d68e2e2f 100644 (file)
@@ -302,24 +302,6 @@ UNIXPORT
   or when your local IRC client doesn't support UNIX domain sockets,
   specify 'n' here.  Otherwise specify 'y'.
 
-Do you need virtual hosting
-VIRTUAL_HOST
-  This is only needed when you want to run two or more servers on the
-  same machine and on the same port (but different devices).
-  In general you will only need this if you have at least two ethernet
-  cards in your machine with a different IP-number.
-  If you specify 'y' here, then you can "bind" a server to one of your
-  interfaces.  You should use the command line option '-w' to tell the
-  server to which interface to bind to.  No error is reported if this
-  fails, the server will simply not run.
-  If no '-w' option is given then the server name specified in the
-  'M: line' of the "ircd.conf" file of the server is used, provided it
-  resolves to an IP-number of one of your interfaces.  Note that
-  normally the name does not have to resolve, but when you define this,
-  it MUST resolve or you must use the -w command line option, or the
-  "bind" will fail.
-  If you are unsure, specify 'n'.
-
 Will you connect to more then one server at a time
 HUB
   All servers of one IRC "network" are connected in a "tree" (no loops).
@@ -448,19 +430,6 @@ MEMTIMESTATS
   counted blocks must be returned.  This allows to ignore recently allocated
   blocks and permanently allocated blocks (since the start of the server).
 
-Are you testing on a host without DNS
-NODNS
-  If you are playing with the server off-line, and no DNS is available, then
-  long delays occur before the server starts up because it tries to resolv
-  the name given on the M:line (which usually isn't given in /etc/hosts) and
-  for each connecting client.
-  If you specify 'y' here, then a call to gethostbyname() will be done only
-  for the real hostname, and the server will not try to resolv clients that
-  connect to `localhost'.
-  Note that other calls to gethostbyname() are still done anyway if you
-  use VIRTUAL_HOST and that the server still tries to resolv clients
-  that connect to the real IP-number of the server.
-
 Directory where all ircd stuff sits
 DPATH
   DPATH is provided so that the other path names may be provided in just
index c1893eec6fe3f392ef868a8a908995ca3f5b76d0..4d7f1f46ab039deb7fd7c3dec19e44a93d6393b9 100644 (file)
@@ -38,6 +38,9 @@
 #
 # The <server port> is the port that other servers can connect to.
 # Client ports need to be specified with a P: line, see below.
+# Note that P: lines can still be used to override the address
+# that a server port is bound to, use the <server port> of the M:
+# line in that case on the P: line.
 #
 # Note that <server numeric> has to be unique on the network your server
 # is running on, must be between 1 and 64, and is not updated on a rehash.
@@ -332,13 +335,40 @@ O:*@*.cs.vu.nl:VRKLKuGKn0jLs:Niels::10
 # is located behind a firewall, you may want to make another hole in it
 # for this port.
 #
-# P:<hostmask, or path>:::<client port number>
+# P:<ipmask, or path>:[<interface>|*]::<client port number>
+#
+# or
+#
+# P:<ipmask, or path>:[<interface>|*]::<server port>
+#
+# where <server port> is the port specified on the M: line.
+#
 
+# Listen on port 6667 and 6668, use the default interface
+# (that is: the interface specified on the commandline with
+#  -w <interface IP#>, or the interface of the IP# that the
+#  M: line resolves too (or ALL interfaces if it doesn't
+#  resolve)).
 P::::6667
 P::::6668
-P:*.nl:::6666
+# Only accept clients from 168.* on port 6666
+P:168.*:::6666
+
+# Listen on port 7700 for clients that connect to "127.0.0.1"
+# where "127.0.0.1" can be the IP number of any of your interfaces.
+P::127.0.0.1::7700
+# Bind to all interfaces:
+P::*::6669
+
+# Open a client UNIX port on /tmp/.ircd
 P:/tmp/.ircd:::6667
 
+# Listen on loopback and eth0 (192.168.1.1) for other servers:
+P::192.168.1.1::4400   # <<--- The last P: line not specifying 127.0.0.1
+                       #       is uses as IP# for _outgoing_ connections.
+P::127.0.0.1::4400
+# where 4400 is the server port (as specified on the M: line)
+
 #
 # Well, you have now reached the end of this sample configuration file
 # If you have any questions, feel free to mail <doco-com@undernet.org>
index be36b88fc323e56497f01e0fb1d9fd0ce5968dc0..a274c48996a1e9ff8f96559abc00b4bd5906b0c9 100644 (file)
@@ -62,11 +62,19 @@ ircd stream tcp wait irc /etc/ircd ircd \-i
 allows inetd to start up ircd on request.
 .TP
 .B \-w interface
-If the server was compiled with VIRTUAL_HOST (run 'make config' to toggle
-this compile option), then \fIinterface\fP is passed to gethostbyname(3) in
-order to retrieve the IP-number of the interface to bind to. An example
-would be to use '-w localhost', after which the server only listens on the
-loopback interface.  Run `ifconfig -a' to see which interfaces you have.
+\fIinterface\fP is passed to gethostbyname(3) in order to retrieve the
+IP-number of the default interface to bind to.  An example would be to
+use `-w localhost' after which the server listens by default on the
+loopback interface.  Use `ifconfig -a' to see which interfaces you have.
+Without this option the hostname in the M: line is used as default
+interface and if that doesn't resolve, all interfaces are used. The
+server uses the default interface to listen for UDP packets (UPING)
+and for each listen port without a specified interface to bind to.
+Interfaces can be specified per listen port in the configuration file
+(ircd.conf) using P: lines. Note that the last P: line in the
+ircd.conf specifying an interface (not localhost) overrules the
+default CONNECT interface (outgoing connections) but does not change
+the default listen interface as described above.
 .TP
 .B \-f filename
 Specifies the ircd.conf file to be used for this ircdaemon. The option
index f9340434fa52672e4564936bf6fdedc8a0e59396..af7393d4d2c17eda56416e2c81c13853c123db38 100644 (file)
@@ -42,6 +42,7 @@ extern time_t now;
 extern aClient *client;
 extern time_t TSoffset;
 extern unsigned int bootopt;
+extern int have_server_port;
 extern time_t nextdnscheck;
 extern time_t nextconnect;
 extern int dorehash;
index 531b25fda251d1202ffacf2eb79e891d6f9cca26..27811f3acfd98b793a5dd5222aa3f1edf7f1347a 100644 (file)
@@ -59,7 +59,7 @@
                \
                \
                \
-               ""
+               ".hide8"
 
 /*
  * Deliberate empty lines
index 9fa24d19063a0d8f9a8d49a3ab0cfd44d5b53ae7..7975d8f5f08a1613f672f8ec226bfb126dc2a363 100644 (file)
@@ -159,7 +159,7 @@ extern int setsnomask(aClient *cptr, snomask_t newmask, int what);
 extern snomask_t umode_make_snomask(snomask_t oldmask, char *arg, int what);
 extern int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp);
 extern void report_error(char *text, aClient *cptr);
-extern int inetport(aClient *cptr, char *name, unsigned short int port);
+extern int inetport(aClient *cptr, char *name, char *bind_addr, unsigned short int port);
 extern int add_listener(aConfItem *aconf);
 extern void close_listeners(void);
 extern void init_sys(void);
@@ -177,8 +177,7 @@ extern int setup_ping(void);
 extern int highest_fd, resfd;
 extern unsigned int readcalls;
 extern aClient *loc_clients[MAXCONNECTIONS];
-#ifdef VIRTUAL_HOST
 extern struct sockaddr_in vserv;
-#endif
+extern struct sockaddr_in cserv;
 
 #endif /* S_BSD_H */
index 97eb4416201dab797a996ed1a23c2a32e96d8992..24185091584b26c0592504f94485569556fbc9cd 100644 (file)
@@ -113,7 +113,7 @@ int main(int argc, char *argv[])
          break;
        case 'x':
          debugflag = 1;
-         if (isdigit(argv[1][2]))
+         if (isdigit((int)argv[1][2]))
            debugflag = atoi(&argv[1][2]);
          break;
        default:
index 6d361f28c93d6b2a854fbb6ca4fbac23b7d2cfcb..030b1277c7437d6fad2c444e086bfbfc749161d3 100644 (file)
@@ -48,9 +48,7 @@
 #include <arpa/nameser.h>
 #include <resolv.h>
 #endif
-#ifdef VIRTUAL_HOST
 #include <sys/socket.h>                /* Needed for AF_INET on some OS */
-#endif
 #include "h.h"
 #include "res.h"
 #include "struct.h"
@@ -553,6 +551,8 @@ static void open_debugfile(void)
   return;
 }
 
+int have_server_port;
+
 int main(int argc, char *argv[])
 {
   unsigned short int portarg = 0;
@@ -590,9 +590,12 @@ int main(int argc, char *argv[])
   myargv = argv;
   umask(077);                  /* better safe than sorry --SRB */
   memset(&me, 0, sizeof(me));
-#ifdef VIRTUAL_HOST
   memset(&vserv, 0, sizeof(vserv));
-#endif
+  vserv.sin_family = AF_INET;
+  vserv.sin_addr.s_addr = htonl(INADDR_ANY);
+  memset(&cserv, 0, sizeof(cserv));
+  cserv.sin_addr.s_addr = htonl(INADDR_ANY);
+  cserv.sin_family = AF_INET;
 
   setup_signals();
   initload();
@@ -672,31 +675,33 @@ int main(int argc, char *argv[])
       case 'v':
        printf("ircd %s\n", version);
        exit(0);
-#ifdef VIRTUAL_HOST
       case 'w':
       {
        struct hostent *hep;
        if (!(hep = gethostbyname(p)))
        {
-         fprintf(stderr, "%s: Error creating virtual host \"%s\": %d",
-             argv[0], p, h_errno);
+         fprintf(stderr, "%s: Error resolving \"%s\" (h_errno == %d).\n",
+             argv[-1], p, h_errno);
          return -1;
        }
        if (hep->h_addrtype == AF_INET && hep->h_addr_list[0] &&
            !hep->h_addr_list[1])
        {
+         int fd;
          memcpy(&vserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
-         vserv.sin_family = AF_INET;
-       }
-       else
-       {
-         fprintf(stderr, "%s: Error creating virtual host \"%s\": "
-             "Use -w <IP-number of interface>\n", argv[0], p);
-         return -1;
+         memcpy(&cserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
+         /* Test if we can bind to this address */
+         fd = socket(AF_INET, SOCK_STREAM, 0);
+          if (bind(fd, (struct sockaddr *)&vserv, sizeof(vserv)) == 0)
+         {
+           close(fd);
+           break;
+         }
        }
-       break;
+       fprintf(stderr, "%s:\tError binding to interface \"%s\".\n"
+           "   \tUse `ifconfig -a' to check your interfaces.\n", argv[-1], p);
+       return -1;
       }
-#endif
       case 'x':
 #ifdef DEBUGMODE
        if (euid != uid)
@@ -818,9 +823,6 @@ int main(int argc, char *argv[])
   initmsgtree();
   initstats();
   open_debugfile();
-  if (portnum == 0)
-    portnum = PORTNUM;
-  me.port = portnum;
   init_sys();
   me.flags = FLAGS_LISTEN;
   if ((bootopt & BOOT_INETD))
@@ -843,16 +845,11 @@ int main(int argc, char *argv[])
   }
   if (!(bootopt & BOOT_INETD))
   {
-    static char star[] = "*";
-    aConfItem *aconf;
-
-    if ((aconf = find_me()) && portarg == 0 && aconf->port != 0)
-      portnum = aconf->port;
     Debug((DEBUG_ERROR, "Port = %u", portnum));
-    if (inetport(&me, star, portnum))
+    if (!have_server_port && inetport(&me, "*", "", portnum))
       exit(1);
   }
-  else if (inetport(&me, "*", 0))
+  else if (inetport(&me, "*", "*", 0))
     exit(1);
 
   read_tlines();
index a04ba0fe96eff08dc6a5fb1c5147df57edd08906..8b318bfb0d6d8959a3bdf805b24696cd20219218 100644 (file)
@@ -659,7 +659,7 @@ int m_stats(aClient *cptr, aClient *sptr, int parc, char *parv[])
  *
  *    parv[0] = sender prefix
  *    parv[1] = servername
- *    parv[2] = port number
+ *    parv[2] = [IP-number:]port number
  *    parv[3] = remote server
  */
 int m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
@@ -668,6 +668,7 @@ int m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
   unsigned short int port, tmpport;
   aConfItem *aconf, *cconf;
   aClient *acptr;
+  char *p;
 
   if (!IsPrivileged(sptr))
   {
@@ -717,9 +718,17 @@ int m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
     return 0;
   }
 
+  if (parc > 2 && !BadPtr(parv[2]))
+    p = strchr(parv[2], ':');
+  else
+    p = 0;
+  if (p)
+    *p = 0;
   for (aconf = conf; aconf; aconf = aconf->next)
     if (aconf->status == CONF_CONNECT_SERVER &&
-       match(parv[1], aconf->name) == 0)
+       match(parv[1], aconf->name) == 0 &&
+       (!p || match(parv[2], aconf->host) == 0 ||
+       match(parv[2], strchr(aconf->host, '@') + 1) == 0))
       break;
   /* Checked first servernames, then try hostnames. */
   if (!aconf)
@@ -728,6 +737,8 @@ int m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
          (match(parv[1], aconf->host) == 0 ||
          match(parv[1], strchr(aconf->host, '@') + 1) == 0))
        break;
+  if (p)
+    *p = ':';
 
   if (!aconf)
   {
@@ -749,7 +760,12 @@ int m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
   tmpport = port = aconf->port;
   if (parc > 2 && !BadPtr(parv[2]))
   {
-    if ((port = atoi(parv[2])) == 0)
+    p = strchr(parv[2], ':');
+    if (!p)
+      p = parv[2];
+    else
+      p = p + 1;
+    if ((port = atoi(p)) == 0)
     {
       if (MyUser(sptr) || Protocol(cptr) < 10)
        sendto_one(sptr,
index 7299327014321bc2e8f6259febcac0caf2a9bafe..a2a7d111b84cbb399390e14a79d93c325290b5d5 100644 (file)
@@ -66,7 +66,7 @@ RCSTAG_CC("$Id$");
 void start_auth(aClient *cptr)
 {
   struct sockaddr_in sock;
-  int err;
+  int err, len;
 
   Debug((DEBUG_NOTICE, "start_auth(%p) fd %d status %d",
       cptr, cptr->fd, cptr->status));
@@ -101,14 +101,15 @@ void start_auth(aClient *cptr)
 
   set_non_blocking(cptr->authfd, cptr);
 
-#ifdef VIRTUAL_HOST
-  if (bind(cptr->authfd, (struct sockaddr *)&vserv, sizeof(vserv)) == -1)
+  if (getsockname(cptr->fd, (struct sockaddr *)&sock, &len) == -1
+      || (sock.sin_port = 0)   /* Reset sin_port and let OS choose the port */
+      || bind(cptr->authfd, (struct sockaddr *)&sock, len) == -1)
   {
     report_error("binding auth stream socket %s: %s", cptr);
     close(cptr->fd);
     return;
   }
-#endif
+
   memcpy(&sock.sin_addr, &cptr->ip, sizeof(struct in_addr));
 
   sock.sin_port = htons(113);
index 0fe5702ef05902a649bcceefe20506aa92bd7ab4..b38f61b493831fcf56a8c9da87dc2b112bb88b69 100644 (file)
@@ -117,15 +117,17 @@ static char readbuf[8192];
 static struct pollfd poll_fds[MAXCONNECTIONS + 1];
 static aClient *poll_cptr[MAXCONNECTIONS + 1];
 #endif /* USE_POLL */
-#ifdef VIRTUAL_HOST
-struct sockaddr_in vserv;
-#endif
+struct sockaddr_in vserv;      /* Default address/interface to bind listen sockets to.
+                                   This is set with the -w commandline option OR whatever
+                                  the name in the M: line resolves to OR INADDR_ANY. */
+struct sockaddr_in cserv;      /* Default address/interface to bind connecting sockets to.
+                                  This is set with the -w commandline option OR whatever
+                                  the name in the M: line resolves to OR the first
+                                  interface specified in the ircd.conf file for the
+                                  server port. */
 static int running_in_background;
 
 #ifdef GODMODE
-#ifndef NODNS
-#define NODNS
-#endif
 #ifndef NOFLOODCONTROL
 #define NOFLOODCONTROL
 #endif
@@ -191,8 +193,10 @@ void report_error(char *text, aClient *cptr)
 {
   Reg1 int errtmp = errno;     /* debug may change 'errno' */
   Reg2 char *host;
+#if defined(SO_ERROR) && !defined(SOL2)
   int err;
   size_t len = sizeof(err);
+#endif
 
   host = (cptr) ? get_client_name(cptr, FALSE) : "";
 
@@ -230,19 +234,24 @@ void report_error(char *text, aClient *cptr)
  * depending on the IP# mask given by 'name'.  Returns the fd of the
  * socket created or -1 on error.
  */
-int inetport(aClient *cptr, char *name, unsigned short int port)
+int inetport(aClient *cptr, char *name, char *bind_addr, unsigned short int port)
 {
-  static struct sockaddr_in server;
+  unsigned short int sin_port;
   int ad[4], opt;
-  size_t len = sizeof(server);
   char ipname[20];
 
+#ifdef TESTNET
+    sin_port = htons(port + 10000);
+#else
+    sin_port = htons(port);
+#endif
+
   ad[0] = ad[1] = ad[2] = ad[3] = 0;
 
   /*
    * do it this way because building ip# from separate values for each
    * byte requires endian knowledge or some nasty messing. Also means
-   * easy conversion of "*" 0.0.0.0 or 134.* to 134.0.0.0 :-)
+   * easy conversion of "*" to 0.0.0.0 or 134.* to 134.0.0.0 :-)
    */
   sscanf(name, "%d.%d.%d.%d", &ad[0], &ad[1], &ad[2], &ad[3]);
   sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
@@ -288,67 +297,39 @@ int inetport(aClient *cptr, char *name, unsigned short int port)
    */
   if (port)
   {
-    server.sin_family = AF_INET;
-#ifndef VIRTUAL_HOST
-    server.sin_addr.s_addr = INADDR_ANY;
-#else
-    if (vserv.sin_addr.s_addr == 0)    /* Not already initialised ? */
+    struct sockaddr_in bindaddr;
+    memset(&bindaddr, 0, sizeof(struct sockaddr_in));
+    if (*bind_addr == '*' && bind_addr[1] == 0)
+      bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);    /* Bind to all interfaces */
+    else if (*bind_addr)
     {
-      struct hostent *hep;
-      memset(&vserv, 0, sizeof(vserv));
-      vserv.sin_family = AF_INET;
-      hep = gethostbyname(me.name);    /* Use name from M: line */
-      if (hep && hep->h_addrtype == AF_INET && hep->h_addr_list[0] &&
-         !hep->h_addr_list[1])
-       memcpy(&vserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
-      else
-      {
-       report_error("Error creating virtual host %s: %s", cptr);
-       return -1;
-      }
+      bindaddr.sin_addr.s_addr = inet_addr(bind_addr); /* Use name from P: line */
+      /* If server port and bind_addr isn't localhost: */
+      if (port == portnum && strcmp("127.0.0.1", bind_addr))
+        cserv.sin_addr.s_addr = bindaddr.sin_addr.s_addr;      /* Initialize /connect port */
     }
-    server.sin_addr = vserv.sin_addr;
-#endif
-#ifdef TESTNET
-    server.sin_port = htons(port + 10000);
-#else
-    server.sin_port = htons(port);
-#endif
-    if (bind(cptr->fd, (struct sockaddr *)&server, sizeof(server)) == -1)
+    else
+      bindaddr.sin_addr = vserv.sin_addr;              /* Default */
+    bindaddr.sin_family = AF_INET;
+    bindaddr.sin_port = sin_port;
+    if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
     {
       report_error("binding stream socket %s: %s", cptr);
       close(cptr->fd);
       return -1;
     }
   }
-  if (getsockname(cptr->fd, (struct sockaddr *)&server, &len))
-  {
-    report_error("getsockname failed for %s: %s", cptr);
-    close(cptr->fd);
-    return -1;
-  }
 
   if (cptr == &me)             /* KLUDGE to get it work... */
   {
     char buf[1024];
-
-#ifdef TESTNET
-    sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
-       ntohs(server.sin_port) - 10000);
-#else
-    sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
-       ntohs(server.sin_port));
-#endif
+    sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*", port);
     write(1, buf, strlen(buf));
   }
   if (cptr->fd > highest_fd)
     highest_fd = cptr->fd;
   cptr->ip.s_addr = inet_addr(ipname);
-#ifdef TESTNET
-  cptr->port = ntohs(server.sin_port) - 10000;
-#else
-  cptr->port = ntohs(server.sin_port);
-#endif
+  cptr->port = port;
   listen(cptr->fd, 128);       /* Use listen port backlog of 128 */
   loc_clients[cptr->fd] = cptr;
 
@@ -456,7 +437,7 @@ int add_listener(aConfItem *aconf)
   }
   else
 #endif
-  if (inetport(cptr, aconf->host, aconf->port))
+  if (inetport(cptr, aconf->host, aconf->passwd, aconf->port))
     cptr->fd = -2;
 
   if (cptr->fd >= 0)
@@ -465,6 +446,8 @@ int add_listener(aConfItem *aconf)
     cptr->confs->next = NULL;
     cptr->confs->value.aconf = aconf;
     set_non_blocking(cptr->fd, cptr);
+    if (aconf->port == portnum)
+      have_server_port = 1;
   }
   else
     free_client(cptr);
@@ -1181,9 +1164,10 @@ static void set_sock_opts(int fd, aClient *cptr)
 
 int get_sockerr(aClient *cptr)
 {
-  int errtmp = errno, err = 0;
-  size_t len = sizeof(err);
+  int errtmp = errno;
 #if defined(SO_ERROR) && !defined(SOL2)
+  int err = 0;
+  size_t len = sizeof(err);
   if (cptr->fd >= 0)
     if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
       if (err)
@@ -1235,8 +1219,6 @@ void set_non_blocking(int fd, aClient *cptr)
   return;
 }
 
-extern unsigned short server_port;
-
 /*
  * Creates a client which has just connected to us on the given fd.
  * The sockhost field is initialized with the ip# of the host.
@@ -1250,7 +1232,7 @@ aClient *add_connection(aClient *cptr, int fd, int type)
   aConfItem *aconf = NULL;
   acptr =
       make_client(NULL,
-      (cptr->port == server_port) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
+      (cptr->port == portnum) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
 
   if (cptr != &me)
     aconf = cptr->confs->value.aconf;
@@ -1311,25 +1293,11 @@ aClient *add_connection(aClient *cptr, int fd, int type)
 
     lin.flags = ASYNC_CLIENT;
     lin.value.cptr = acptr;
-#ifdef NODNS
-    if (!strcmp("127.0.0.1", inetntoa(addr.sin_addr)))
-    {
-      static struct hostent lhe = { "localhost", NULL, 0, 0, NULL };
-      acptr->hostp = &lhe;
-      if (!DoingAuth(acptr))
-       SetAccess(acptr);
-    }
-    else
-    {
-#endif
-      Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
-      acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
-      if (!acptr->hostp)
-       SetDNS(acptr);
-      nextdnscheck = 1;
-#ifdef NODNS
-    }
-#endif
+    Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
+    acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
+    if (!acptr->hostp)
+      SetDNS(acptr);
+    nextdnscheck = 1;
   }
 
   if (aconf)
@@ -1968,7 +1936,7 @@ int read_message(time_t delay)
       continue;
     nfds--;
     readcalls++;
-    if (length > 0)
+    if (length > 0 || length == CPTR_KILLED)
       continue;
 
     /*
@@ -1982,9 +1950,6 @@ int read_message(time_t delay)
      */
     Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
 
-    if (length == CPTR_KILLED)
-      continue;
-
     if ((IsServer(cptr) || IsHandshake(cptr)) && errno == 0 && length == 0)
       exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
          get_client_name(cptr, FALSE), cptr->serv->last_error_msg);
@@ -2217,6 +2182,7 @@ static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
 {
   static struct sockaddr_in server;
   Reg3 struct hostent *hp;
+  struct sockaddr_in bindaddr;
 
   /*
    * Might as well get sockhost from here, the connection is attempted
@@ -2246,32 +2212,19 @@ static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
   server.sin_family = AF_INET;
   get_sockhost(cptr, aconf->host);
 
-#ifdef VIRTUAL_HOST
-  mysk.sin_addr = vserv.sin_addr;
-#endif
-
   /*
    * Bind to a local IP# (with unknown port - let unix decide) so
    * we have some chance of knowing the IP# that gets used for a host
    * with more than one IP#.
    */
-  /* No we don't bind it, not all OS's can handle connecting with
-   * an already bound socket, different ip# might occur anyway
-   * leading to a freezing select() on this side for some time.
-   * I had this on my Linux 1.1.88 --Run
-   */
-#ifdef VIRTUAL_HOST
-  /*
-   * No, we do bind it if we have virtual host support. If we don't
-   * explicitly bind it, it will default to IN_ADDR_ANY and we lose
-   * due to the other server not allowing our base IP --smg
-   */
-  if (bind(cptr->fd, (struct sockaddr *)&mysk, sizeof(mysk)) == -1)
+  memcpy(&bindaddr, &cserv, sizeof(bindaddr));
+  if (aconf->ipnum.s_addr == 0x100007f)
+    bindaddr.sin_addr.s_addr = 0x100007f;      /* bind with localhost when we are connecting to localhost */
+  if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
   {
     report_error("error binding to local port for %s: %s", cptr);
     return NULL;
   }
-#endif
 
   /*
    * By this point we should know the IP# of the host listed in the
@@ -2390,12 +2343,7 @@ void get_my_name(aClient *cptr, char *name, size_t len)
    */
   if (BadPtr(cname))
     return;
-  if (
-#ifndef NODNS
-      /* I don't have DNS while testing, this delays too much */
-      (hp = gethostbyname(cname)) ||
-#endif
-      (hp = gethostbyname(name)))
+  if ((hp = gethostbyname(cname)) || (hp = gethostbyname(name)))
   {
     const char *hname;
     int i = 0;
@@ -2433,11 +2381,7 @@ int setup_ping(void)
   int on = 1;
 
   memset(&from, 0, sizeof(from));
-#ifdef VIRTUAL_HOST
-  from.sin_addr = vserv.sin_addr;
-#else
-  from.sin_addr.s_addr = htonl(INADDR_ANY);
-#endif
+  from.sin_addr = cserv.sin_addr;
 #ifdef TESTNET
   from.sin_port = htons(atoi(UDP_PORT) + 10000);
 #else
index 3409ef99384020e147fdd12e17731efd71b62c49..b9498824c78eb8a5adb3412b3ecbc67abfd09901 100644 (file)
@@ -773,8 +773,6 @@ int rehash(aClient *cptr, int sig)
 
 #define MAXCONFLINKS 150
 
-unsigned short server_port;
-
 int initconf(int opt)
 {
   static char quotes[9][2] = {
@@ -948,7 +946,11 @@ int initconf(int opt)
       tmp = getfield(NULL, ':');
       if (aconf->status & CONF_ME)
       {
-       server_port = aconf->port;
+       portnum = aconf->port;
+       if (portnum == 0)
+         portnum = PORTNUM;
+       me.port = portnum;
+       vserv.sin_port = htons(portnum);
        if (!tmp)
        {
          Debug((DEBUG_FATAL, "Your M: line must have the Numeric, "
@@ -1058,9 +1060,22 @@ int initconf(int opt)
     {
       strncpy(me.info, aconf->name, sizeof(me.info) - 1);
       if (me.name[0] == '\0' && aconf->host[0])
+      {
        strncpy(me.name, aconf->host, sizeof(me.name) - 1);
+       if (vserv.sin_addr.s_addr == htonl(INADDR_ANY))         /* Not already initialised on commandline with -w ? */
+       {
+         struct hostent *hep;
+         hep = gethostbyname(me.name);
+         if (hep && hep->h_addrtype == AF_INET && hep->h_addr_list[0] && !hep->h_addr_list[1])
+          {
+           memcpy(&vserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
+           memcpy(&cserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
+          }
+       }
+      }
       if (portnum == 0)
        portnum = aconf->port;
+      have_server_port = 0;
     }
 
     /*
index 5ba170503a9182e5c8ab2fb90f962c342d637627..1b18d646accdb67aa6dba289235aed0fdf013dfd 100644 (file)
@@ -167,9 +167,6 @@ char serveropts[] = {
 #if defined(USE_POLL) && defined(HAVE_POLL_H)
     'U',
 #endif
-#ifdef VIRTUAL_HOST
-    'v',
-#endif
 #ifdef BADCHAN
    'W',
 #ifdef LOCAL_BADCHAN
index aa10dd94bfa4a7b58695a01b9ddb618d46da69b6..c694869946747b0024df28dee6270aa84cdf8d75 100644 (file)
@@ -325,6 +325,7 @@ int m_uping(aClient *cptr, aClient *sptr, int parc, char *parv[])
   aConfItem *aconf;
   unsigned short int port;
   int fd, opt;
+  char *p;
 
   if (!IsPrivileged(sptr))
   {
@@ -393,9 +394,17 @@ int m_uping(aClient *cptr, aClient *sptr, int parc, char *parv[])
   }
 
   /* Check if a CONNECT would be possible at all (adapted from m_connect) */
+  if (parc > 2 && !BadPtr(parv[2]))
+    p = strchr(parv[2], ':');
+  else
+    p = 0;
+  if (p)
+    *p = 0;
   for (aconf = conf; aconf; aconf = aconf->next)
     if (aconf->status == CONF_CONNECT_SERVER &&
-       match(parv[1], aconf->name) == 0)
+       match(parv[1], aconf->name) == 0 &&
+        (!p || match(parv[2], aconf->host) == 0 ||
+       match(parv[2], strchr(aconf->host, '@') + 1) == 0))
       break;
   if (!aconf)
     for (aconf = conf; aconf; aconf = aconf->next)
@@ -403,6 +412,8 @@ int m_uping(aClient *cptr, aClient *sptr, int parc, char *parv[])
          (match(parv[1], aconf->host) == 0 ||
          match(parv[1], strchr(aconf->host, '@') + 1) == 0))
        break;
+  if (p)
+    *p = ':';
   if (!aconf)
   {
     if (MyUser(sptr) || Protocol(cptr) < 10)
@@ -421,7 +432,7 @@ int m_uping(aClient *cptr, aClient *sptr, int parc, char *parv[])
   /*
    * Determine port: First user supplied, then default : 7007
    */
-  if (BadPtr(parv[2]) || (port = atoi(parv[2])) <= 0)
+  if (!p || (port = atoi(p + 1)) <= 0)
     port = atoi(UDP_PORT);
 
   alarm(2);
@@ -491,6 +502,18 @@ int m_uping(aClient *cptr, aClient *sptr, int parc, char *parv[])
     close(fd);
     return 0;
   }
+  if (bind(fd, (struct sockaddr *)&cserv, sizeof(cserv)) == -1)
+  {
+    sendto_ops("Failure binding fd for uping");
+    if (MyUser(sptr) || Protocol(cptr) < 10)
+      sendto_one(sptr, ":%s NOTICE %s :UPING: failure binding udp socket",
+         me.name, parv[0]);
+    else
+      sendto_one(sptr, "%s NOTICE %s%s :UPING: failure binding udp socket",
+         NumServ(&me), NumNick(sptr));
+    close(fd);
+    return 0;
+  }
 
   if (fd > highest_fd)
     highest_fd = fd;
index ab5ff17f1c2e654986ca81569f58ff7cc080a9f0..868d2eb68e4c9a6e210001847afaccafb11b582b 100644 (file)
@@ -88,8 +88,6 @@ static int a_kills_b_too(aClient *a, aClient *b)
   return (a == b ? 1 : 0);
 }
 
-extern unsigned short server_port;
-
 /*
  *  m_server
  *
@@ -125,7 +123,7 @@ int m_server(aClient *cptr, aClient *sptr, int parc, char *parv[])
   if (IsUserPort(cptr))
     return exit_client_msg(cptr, cptr, &me,
        "You cannot connect a server to a user port; connect to %s port %u",
-       me.name, server_port);
+       me.name, portnum);
 
   recv_time = TStime();
   info[0] = '\0';
index 4b0c8b9d1d16122f3cd25bb79dc7a261a89c5bd1..ae867827b337e086b15a83356049f40e20068930 100644 (file)
@@ -206,7 +206,7 @@ void calc_load(aClient *sptr)
       "Minute  Hour    Day   Yest. YYest. Userload for:";
   /* *INDENT-ON* */
   static const char *what[3] = {
-    DOMAINNAME " clients",
+    "local domain clients",
     "total clients",
     "total connections"
   };