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
#
# 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
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
define_bool MEMSIZESTATS $MEMSIZESTATS
define_bool MEMTIMESTATS $MEMTIMESTATS
fi
- bool 'Are you testing on a host without DNS' NODNS
endmenu
mainmenu_option next_comment
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).
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
#
# 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.
# 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>
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
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;
\
\
\
- ""
+ ".hide8"
/*
* Deliberate empty lines
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);
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 */
break;
case 'x':
debugflag = 1;
- if (isdigit(argv[1][2]))
+ if (isdigit((int)argv[1][2]))
debugflag = atoi(&argv[1][2]);
break;
default:
#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"
return;
}
+int have_server_port;
+
int main(int argc, char *argv[])
{
unsigned short int portarg = 0;
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();
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)
initmsgtree();
initstats();
open_debugfile();
- if (portnum == 0)
- portnum = PORTNUM;
- me.port = portnum;
init_sys();
me.flags = FLAGS_LISTEN;
if ((bootopt & BOOT_INETD))
}
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();
*
* 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[])
unsigned short int port, tmpport;
aConfItem *aconf, *cconf;
aClient *acptr;
+ char *p;
if (!IsPrivileged(sptr))
{
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)
(match(parv[1], aconf->host) == 0 ||
match(parv[1], strchr(aconf->host, '@') + 1) == 0))
break;
+ if (p)
+ *p = ':';
if (!aconf)
{
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,
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));
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);
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
{
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) : "";
* 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]);
*/
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;
}
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)
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);
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)
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.
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;
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)
continue;
nfds--;
readcalls++;
- if (length > 0)
+ if (length > 0 || length == CPTR_KILLED)
continue;
/*
*/
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);
{
static struct sockaddr_in server;
Reg3 struct hostent *hp;
+ struct sockaddr_in bindaddr;
/*
* Might as well get sockhost from here, the connection is attempted
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
*/
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;
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
#define MAXCONFLINKS 150
-unsigned short server_port;
-
int initconf(int opt)
{
static char quotes[9][2] = {
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, "
{
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;
}
/*
#if defined(USE_POLL) && defined(HAVE_POLL_H)
'U',
#endif
-#ifdef VIRTUAL_HOST
- 'v',
-#endif
#ifdef BADCHAN
'W',
#ifdef LOCAL_BADCHAN
aConfItem *aconf;
unsigned short int port;
int fd, opt;
+ char *p;
if (!IsPrivileged(sptr))
{
}
/* 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)
(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)
/*
* 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);
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;
return (a == b ? 1 : 0);
}
-extern unsigned short server_port;
-
/*
* m_server
*
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';
"Minute Hour Day Yest. YYest. Userload for:";
/* *INDENT-ON* */
static const char *what[3] = {
- DOMAINNAME " clients",
+ "local domain clients",
"total clients",
"total connections"
};