static struct pollfd poll_fds[MAXCONNECTIONS + 1];
static aClient *poll_cptr[MAXCONNECTIONS + 1];
#endif /* USE_POLL */
-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. */
+#ifdef VIRTUAL_HOST
+struct sockaddr_in vserv;
+#endif
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) : "";
+ host = (cptr) ? cptr->name : "";
Debug((DEBUG_ERROR, text, host, strerror(errtmp)));
* 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, char *bind_addr, unsigned short int port)
+int inetport(aClient *cptr, char *name, unsigned short int port)
{
- unsigned short int sin_port;
+ static struct sockaddr_in server;
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 "*" to 0.0.0.0 or 134.* to 134.0.0.0 :-)
+ * easy conversion of "*" 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 (cptr->fd < 0 && errno == EAGAIN)
{
sendto_ops("opening stream socket %s: No more sockets",
- get_client_name(cptr, TRUE));
+ cptr->name);
return -1;
}
}
*/
if (port)
{
- 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)
- {
- 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 */
- }
- 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)
+ server.sin_family = AF_INET;
+#ifndef VIRTUAL_HOST
+ server.sin_addr.s_addr = INADDR_ANY;
+#else
+ 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)
{
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];
- sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*", port);
+
+#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
write(1, buf, strlen(buf));
}
if (cptr->fd > highest_fd)
highest_fd = cptr->fd;
cptr->ip.s_addr = inet_addr(ipname);
- cptr->port = port;
+#ifdef TESTNET
+ cptr->port = ntohs(server.sin_port) - 10000;
+#else
+ cptr->port = ntohs(server.sin_port);
+#endif
listen(cptr->fd, 128); /* Use listen port backlog of 128 */
loc_clients[cptr->fd] = cptr;
if (cptr->fd == -1 && errno == EAGAIN)
{
sendto_ops("error opening unix domain socket %s: No more sockets",
- get_client_name(cptr, TRUE));
+ cptr->name);
return -1;
}
if (cptr->fd == -1)
}
else
#endif
- if (inetport(cptr, aconf->host, aconf->passwd, aconf->port))
+ if (inetport(cptr, aconf->host, 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);
/* If descriptor is a tty, special checking... */
if (isatty(cptr->fd))
{
- strncpy(sockn, me.sockhost, HOSTLEN);
+ strncpy(sockn, me.name, HOSTLEN);
memset(&sk, 0, sizeof(struct sockaddr_in));
}
else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
{
cptr->hostp = NULL;
- strncpy(sockn, me.sockhost, HOSTLEN);
+ strncpy(sockn, me.name, HOSTLEN);
}
memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
#ifdef TESTNET
n_conf = find_conf(lp, name, NFLAG);
if (!c_conf || !n_conf)
{
- sendto_ops("Connecting Error: %s[%s]", name, cptr->sockhost);
+ sendto_ops("Connecting Error: %s", name);
det_confs_butmask(cptr, 0);
return -1;
}
aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
if (!aconf)
{
- sendto_ops("Lost C-Line for %s", get_client_name(cptr, FALSE));
+ sendto_ops("Lost C-Line for %s", cptr->name);
return -1;
}
if (!BadPtr(aconf->passwd))
aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
if (!aconf)
{
- sendto_ops("Lost N-Line for %s", get_client_name(cptr, FALSE));
+ sendto_ops("Lost N-Line for %s", cptr->name);
return -1;
}
make_server(cptr);
sprintf(s, "%02x:", *t++);
*s = '\0';
sendto_ops("Connection %s using IP opts: (%s)",
- get_client_name(cptr, TRUE), readbuf);
+ get_client_name(cptr, FALSE), readbuf);
}
if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
int get_sockerr(aClient *cptr)
{
- int errtmp = errno;
-#if defined(SO_ERROR) && !defined(SOL2)
- int err = 0;
+ int errtmp = errno, err = 0;
size_t len = sizeof(err);
+#if defined(SO_ERROR) && !defined(SOL2)
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 == portnum) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
+ (cptr->port == server_port) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
if (cptr != &me)
aconf = cptr->confs->value.aconf;
lin.flags = ASYNC_CLIENT;
lin.value.cptr = acptr;
- 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
+ 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
}
if (aconf)
* Copy ascii address to 'sockhost' just in case. Then we
* have something valid to put into error messages...
*/
- get_sockhost(acptr, me.sockhost);
+ strncpy(acptr->sockhost, me.name, HOSTLEN);
if (cptr != &me)
aconf = cptr->confs->value.aconf;
if (aconf)
STIME_T_FMT " minutes", count, (now - last_time) / 60);
}
else
- sendto_ops("All connections in use. (%s)", get_client_name(cptr,
- TRUE));
+ sendto_ops("All connections in use. (%s)", cptr->name);
count = 0;
last_time = now;
}
continue;
nfds--;
readcalls++;
- if (length > 0 || length == CPTR_KILLED)
+ if (length > 0)
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);
+ cptr->name, cptr->serv->last_error_msg);
else
exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
get_client_name(cptr, FALSE), (length < 0) ?
{
if (MyUser(by) || Protocol(by->from) < 10)
sendto_one(by, ":%s NOTICE %s :Connection to %s already in progress",
- me.name, by->name, get_client_name(c2ptr, TRUE));
+ me.name, by->name, c2ptr->name);
else
sendto_one(by,
"%s NOTICE %s%s :Connection to %s already in progress",
- NumServ(&me), NumNick(by), get_client_name(c2ptr, TRUE));
+ NumServ(&me), NumNick(by), c2ptr->name);
}
return -1;
}
#ifndef NO_PROTOCOL9
if (Protocol(by->from) < 10)
sendto_one(by, ":%s NOTICE %s :Couldn't connect to %s",
- me.name, by->name, get_client_name(cptr, TRUE));
+ me.name, by->name, cptr->name);
else
#endif
sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
- NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
+ NumServ(&me), NumNick(by), cptr->name);
}
free_client(cptr);
return -1;
#ifndef NO_PROTOCOL9
if (Protocol(by->from) < 10)
sendto_one(by, ":%s NOTICE %s :Connect to host %s failed: %s",
- me.name, by->name, get_client_name(cptr, TRUE), strerror(err));
+ me.name, by->name, cptr->name, strerror(err));
else
#endif
sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
- NumServ(&me), NumNick(by), get_client_name(cptr, TRUE),
- strerror(err));
+ NumServ(&me), NumNick(by), cptr->name, strerror(err));
}
close(cptr->fd);
cptr->fd = -2;
!find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
{
sendto_ops("Host %s is not enabled for connecting:no C/N-line",
- aconf->host);
+ aconf->name);
if (by && IsUser(by) && !MyUser(by))
{
#ifndef NO_PROTOCOL9
if (Protocol(by->from) < 10)
sendto_one(by,
":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
- me.name, by->name, get_client_name(cptr, TRUE));
+ me.name, by->name, cptr->name);
else
#endif
sendto_one(by,
"%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
- NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
+ NumServ(&me), NumNick(by), cptr->name);
}
det_confs_butmask(cptr, 0);
close(cptr->fd);
{
static struct sockaddr_in server;
Reg3 struct hostent *hp;
- struct sockaddr_in bindaddr;
/*
* Might as well get sockhost from here, the connection is attempted
if (cptr->fd == -1 && errno == EAGAIN)
{
sendto_ops("opening stream socket to server %s: No more sockets",
- get_client_name(cptr, TRUE));
+ cptr->name);
return NULL;
}
if (cptr->fd == -1)
return NULL;
}
mysk.sin_port = 0;
+
memset(&server, 0, sizeof(server));
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#.
*/
- 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)
+ /* 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)
{
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 (cptr->fd == -1 && errno == EAGAIN)
{
sendto_ops("Unix domain connect to host %s failed: No more sockets",
- get_client_name(cptr, TRUE));
+ cptr->name);
return NULL;
}
if (cptr->fd == -1)
* matches the server's name) and its primary IP#. Hostname is stored
* in the client structure passed as a pointer.
*/
-void get_my_name(aClient *cptr, char *name, size_t len)
+void get_my_name(aClient *cptr)
{
- static char tmp[HOSTLEN + 1];
-#if HAVE_UNAME
- struct utsname utsn;
-#endif
- struct hostent *hp;
- char *cname = cptr->name;
- size_t len2;
-
+ struct ConfItem* aconf = find_me();
/*
* Setup local socket structure to use for binding to.
*/
memset(&mysk, 0, sizeof(mysk));
mysk.sin_family = AF_INET;
+ mysk.sin_addr.s_addr = INADDR_ANY;
-#if HAVE_UNAME
- if (uname(&utsn) == -1)
- return;
- len2 = strlen(utsn.nodename);
- if (len2 > len)
- len2 = len;
- strncpy(name, utsn.nodename, len2);
-#else /* HAVE_GETHOSTNAME */
- if (gethostname(name, len) == -1)
- return;
-#endif
- name[len] = '\0';
-
- /* Assume that a name containing '.' is a FQDN */
- if (!strchr(name, '.'))
- add_local_domain(name, len - strlen(name));
-
- /*
- * If hostname gives another name than cname, then check if there is
- * a CNAME record for cname pointing to hostname. If so accept
- * cname as our name. meLazy
- */
- if (BadPtr(cname))
+ if (!aconf || BadPtr(aconf->host))
return;
- if ((hp = gethostbyname(cname)) || (hp = gethostbyname(name)))
- {
- const char *hname;
- int i = 0;
-
- for (hname = hp->h_name; hname; hname = hp->h_aliases[i++])
- {
- strncpy(tmp, hname, sizeof(tmp) - 1);
- add_local_domain(tmp, sizeof(tmp) - 1 - strlen(tmp));
+ strncpy(me.name, aconf->host, sizeof(me.name) - 1);
- /*
- * Copy the matching name over and store the
- * 'primary' IP# as 'myip' which is used
- * later for making the right one is used
- * for connecting to other hosts.
- */
- if (!strCasediff(me.name, tmp))
- break;
- }
- if (strCasediff(me.name, tmp))
- strncpy(name, hp->h_name, len);
- else
- strncpy(name, tmp, len);
- memcpy(&mysk.sin_addr, hp->h_addr, sizeof(struct in_addr));
- Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
+ if (!BadPtr(aconf->passwd) && 0 != strcmp(aconf->passwd, "*")) {
+ mysk.sin_addr.s_addr = inet_addr(aconf->passwd);
+ if (INADDR_NONE == mysk.sin_addr.s_addr)
+ mysk.sin_addr.s_addr = INADDR_ANY;
+#ifdef VIRTUAL_HOST
+ memcpy(&vserv, &mysk, sizeof(struct sockaddr_in));
+#endif
}
- return;
+ Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
}
/*
int on = 1;
memset(&from, 0, sizeof(from));
- from.sin_addr = cserv.sin_addr;
+#ifdef VIRTUAL_HOST
+ from.sin_addr = vserv.sin_addr;
+#else
+ from.sin_addr.s_addr = htonl(INADDR_ANY);
+#endif
#ifdef TESTNET
from.sin_port = htons(atoi(UDP_PORT) + 10000);
#else