2 * IRC - Internet Relay Chat, ircd/s_bsd.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 1, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <sys/socket.h>
28 #include <sys/ioctl.h>
31 #include <sys/filio.h>
40 #else /* HAVE_POLL_H */
45 #endif /* HAVE_POLL_H */
56 #include <sys/resource.h>
60 #include <sys/utsname.h>
61 #include <netinet/in.h>
62 #include <arpa/inet.h>
63 #include <arpa/nameser.h>
90 #include "sprintf_irc.h"
91 #include "querycmds.h"
96 #ifndef IN_LOOPBACKNET
97 #define IN_LOOPBACKNET 0x7f
100 aClient *loc_clients[MAXCONNECTIONS];
101 int highest_fd = 0, udpfd = -1, resfd = -1;
102 unsigned int readcalls = 0;
103 static struct sockaddr_in mysk;
104 static void polludp();
106 static struct sockaddr *connect_inet(aConfItem *, aClient *, int *);
107 static int completed_connection(aClient *);
108 static int check_init(aClient *, char *);
109 static void do_dns_async(), set_sock_opts(int, aClient *);
111 static struct sockaddr *connect_unix(aConfItem *, aClient *, int *);
112 static void add_unixconnection(aClient *, int);
113 static char unixpath[256];
115 static char readbuf[8192];
117 static struct pollfd poll_fds[MAXCONNECTIONS + 1];
118 static aClient *poll_cptr[MAXCONNECTIONS + 1];
119 #endif /* USE_POLL */
120 struct sockaddr_in vserv; /* Default address/interface to bind listen sockets to.
121 This is set with the -w commandline option OR whatever
122 the name in the M: line resolves to OR INADDR_ANY. */
123 struct sockaddr_in cserv; /* Default address/interface to bind connecting sockets to.
124 This is set with the -w commandline option OR whatever
125 the name in the M: line resolves to OR the first
126 interface specified in the ircd.conf file for the
128 static int running_in_background;
131 #ifndef NOFLOODCONTROL
132 #define NOFLOODCONTROL
137 * Try and find the correct name to use with getrlimit() for setting the max.
138 * number of files allowed to be open by this process.
141 #define RLIMIT_FD_MAX RLIMIT_FDMAX
144 #define RLIMIT_FD_MAX RLIMIT_NOFILE
146 #ifdef RLIMIT_OPEN_MAX
147 #define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
154 #if !defined(USE_POLL)
155 #if FD_SETSIZE < (MAXCONNECTIONS + 4)
159 * All operating systems work when MAXCONNECTIONS <= 252.
160 * Most operating systems work when MAXCONNECTIONS <= 1020 and FD_SETSIZE is
161 * updated correctly in the system headers (on BSD systems our sys.h has
162 * defined FD_SETSIZE to MAXCONNECTIONS+4 before including the system's headers
163 * but sys/types.h might have abruptly redefined it so the check is still
164 * done), you might already need to recompile your kernel.
165 * For larger FD_SETSIZE your milage may vary (kernel patches may be needed).
166 * The check is _NOT_ done if we will not use FD_SETS at all (USE_POLL)
168 #error "FD_SETSIZE is too small or MAXCONNECTIONS too large."
173 * Cannot use perror() within daemon. stderr is closed in
174 * ircd and cannot be used. And, worse yet, it might have
175 * been reassigned to a normal connection...
181 * This a replacement for perror(). Record error to log and
182 * also send a copy to all *LOCAL* opers online.
184 * text is a *format* string for outputting error. It must
185 * contain only two '%s', the first will be replaced
186 * by the sockhost from the cptr, and the latter will
187 * be taken from sys_errlist[errno].
189 * cptr if not NULL, is the *LOCAL* client associated with
192 void report_error(char *text, aClient *cptr)
194 Reg1 int errtmp = errno; /* debug may change 'errno' */
196 #if defined(SO_ERROR) && !defined(SOL2)
198 size_t len = sizeof(err);
201 host = (cptr) ? get_client_name(cptr, FALSE) : "";
203 Debug((DEBUG_ERROR, text, host, strerror(errtmp)));
206 * Get the *real* error from the socket (well try to anyway..).
207 * This may only work when SO_DEBUG is enabled but its worth the
210 #if defined(SO_ERROR) && !defined(SOL2)
211 if (cptr && !IsMe(cptr) && cptr->fd >= 0)
212 if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
216 sendto_ops(text, host, strerror(errtmp));
218 syslog(LOG_WARNING, text, host, strerror(errtmp));
220 if (!running_in_background)
222 fprintf(stderr, text, host, strerror(errtmp));
223 fprintf(stderr, "\n");
232 * Create a socket in the AF_INET domain, bind it to the port given in
233 * 'port' and listen to it. Connections are accepted to this socket
234 * depending on the IP# mask given by 'name'. Returns the fd of the
235 * socket created or -1 on error.
237 int inetport(aClient *cptr, char *name, char *bind_addr, unsigned short int port)
239 unsigned short int sin_port;
244 sin_port = htons(port + 10000);
246 sin_port = htons(port);
249 ad[0] = ad[1] = ad[2] = ad[3] = 0;
252 * do it this way because building ip# from separate values for each
253 * byte requires endian knowledge or some nasty messing. Also means
254 * easy conversion of "*" to 0.0.0.0 or 134.* to 134.0.0.0 :-)
256 sscanf(name, "%d.%d.%d.%d", &ad[0], &ad[1], &ad[2], &ad[3]);
257 sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
261 sprintf(cptr->sockhost, "%-.42s.%u", name, port);
262 strcpy(cptr->name, me.name);
265 * At first, open a new socket
270 cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
272 if (cptr->fd < 0 && errno == EAGAIN)
274 sendto_ops("opening stream socket %s: No more sockets",
275 get_client_name(cptr, TRUE));
281 report_error("opening stream socket %s: %s", cptr);
284 else if (cptr->fd >= MAXCLIENTS)
286 sendto_ops("No more connections allowed (%s)", cptr->name);
292 setsockopt(cptr->fd, SOL_SOCKET, SO_REUSEADDR, (OPT_TYPE *)&opt, sizeof(opt));
295 * Bind a port to listen for new connections if port is non-null,
296 * else assume it is already open and try get something from it.
300 struct sockaddr_in bindaddr;
301 memset(&bindaddr, 0, sizeof(struct sockaddr_in));
302 if (*bind_addr == '*' && bind_addr[1] == 0)
303 bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Bind to all interfaces */
306 bindaddr.sin_addr.s_addr = inet_addr(bind_addr); /* Use name from P: line */
307 /* If server port and bind_addr isn't localhost: */
308 if (port == portnum && strcmp("127.0.0.1", bind_addr))
309 cserv.sin_addr.s_addr = bindaddr.sin_addr.s_addr; /* Initialize /connect port */
312 bindaddr.sin_addr = vserv.sin_addr; /* Default */
313 bindaddr.sin_family = AF_INET;
314 bindaddr.sin_port = sin_port;
315 if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
317 report_error("binding stream socket %s: %s", cptr);
323 if (cptr == &me) /* KLUDGE to get it work... */
326 sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*", port);
327 write(1, buf, strlen(buf));
329 if (cptr->fd > highest_fd)
330 highest_fd = cptr->fd;
331 cptr->ip.s_addr = inet_addr(ipname);
333 listen(cptr->fd, 128); /* Use listen port backlog of 128 */
334 loc_clients[cptr->fd] = cptr;
343 * Create a socket and bind it to a filename which is comprised of the path
344 * (directory where file is placed) and port (actual filename created).
345 * Set directory permissions as rwxr-xr-x so other users can connect to the
346 * file which is 'forced' to rwxrwxrwx (different OS's have different need of
347 * modes so users can connect to the socket).
349 int unixport(aClient *cptr, char *path, unsigned short int port)
351 struct sockaddr_un un;
354 cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
356 if (cptr->fd == -1 && errno == EAGAIN)
358 sendto_ops("error opening unix domain socket %s: No more sockets",
359 get_client_name(cptr, TRUE));
364 report_error("error opening unix domain socket %s: %s", cptr);
367 else if (cptr->fd >= MAXCLIENTS)
369 sendto_ops("No more connections allowed (%s)", cptr->name);
375 un.sun_family = AF_UNIX;
379 if (chmod(path, 0755) == -1)
381 sendto_ops("error 'chmod 0755 %s': %s", path, strerror(errno));
383 syslog(LOG_WARNING, "error 'chmod 0755 %s': %s", path, strerror(errno));
390 sprintf_irc(unixpath, "%s/%u", path, port);
392 strncpy(un.sun_path, unixpath, sizeof(un.sun_path) - 1);
393 un.sun_path[sizeof(un.sun_path) - 1] = 0;
394 strcpy(cptr->name, me.name);
396 get_sockhost(cptr, unixpath);
398 if (bind(cptr->fd, (struct sockaddr *)&un, strlen(unixpath) + 2) == -1)
400 report_error("error binding unix socket %s: %s", cptr);
404 if (cptr->fd > highest_fd)
405 highest_fd = cptr->fd;
407 chmod(unixpath, 0777);
408 cptr->flags |= FLAGS_UNIX;
410 loc_clients[cptr->fd] = cptr;
419 * Create a new client which is essentially the stub like 'me' to be used
420 * for a socket that is passive (listen'ing for connections to be accepted).
422 int add_listener(aConfItem *aconf)
426 cptr = make_client(NULL, STAT_ME);
427 cptr->flags = FLAGS_LISTEN;
430 strncpy(cptr->name, aconf->host, sizeof(cptr->name) - 1);
431 cptr->name[sizeof(cptr->name) - 1] = 0;
433 if (*aconf->host == '/')
435 if (unixport(cptr, aconf->host, aconf->port))
440 if (inetport(cptr, aconf->host, aconf->passwd, aconf->port))
445 cptr->confs = make_link();
446 cptr->confs->next = NULL;
447 cptr->confs->value.aconf = aconf;
448 set_non_blocking(cptr->fd, cptr);
449 if (aconf->port == portnum)
450 have_server_port = 1;
460 * Close and free all clients which are marked as having their socket open
461 * and in a state where they can accept connections. Unix sockets have
462 * the path to the socket unlinked for cleanliness.
464 void close_listeners(void)
468 Reg3 aConfItem *aconf;
471 * close all 'extra' listening ports we have and unlink the file
472 * name if it was a unix socket.
474 for (i = highest_fd; i >= 0; i--)
476 if (!(cptr = loc_clients[i]))
478 if (!IsMe(cptr) || cptr == &me || !IsListening(cptr))
480 aconf = cptr->confs->value.aconf;
482 if (IsIllegal(aconf) && aconf->clients == 0)
485 if (IsUnixSocket(cptr))
487 sprintf_irc(unixpath, "%s/%u", aconf->host, aconf->port);
491 close_connection(cptr);
502 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
505 if (!getrlimit(RLIMIT_FD_MAX, &limit))
508 if (limit.rlim_cur < MAXCONNECTIONS)
510 if (limit.rlim_max < MAXCONNECTIONS)
513 fprintf(stderr, "ircd fd table too big\n");
514 fprintf(stderr, "Hard Limit: " LIMIT_FMT " IRC max: %d\n",
520 (int)MAXCONNECTIONS);
521 fprintf(stderr, "Fix MAXCONNECTIONS\n");
525 limit.rlim_cur = limit.rlim_max; /* make soft limit the max */
526 if (setrlimit(RLIMIT_FD_MAX, &limit) == -1)
528 fprintf(stderr, "error setting max fd's to " LIMIT_FMT "\n",
534 #endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
538 static char logbuf[BUFSIZ];
540 setvbuf(stderr, _IOLBF, logbuf, sizeof(logbuf));
542 setvbuf(stderr, logbuf, _IOLBF, sizeof(logbuf));
547 for (fd = 3; fd < MAXCONNECTIONS; fd++)
550 loc_clients[fd] = NULL;
552 loc_clients[1] = NULL;
555 if (bootopt & BOOT_TTY) /* debugging is going to a tty */
557 if (!(bootopt & BOOT_DEBUG))
560 if (((bootopt & BOOT_CONSOLE) || isatty(0)) &&
561 !(bootopt & BOOT_INETD))
565 running_in_background = 1;
567 if ((fd = open("/dev/tty", O_RDWR)) >= 0)
569 ioctl(fd, TIOCNOTTY, (char *)NULL);
573 #if defined(HPUX) || defined(SOL2) || defined(_SEQUENT_) || \
574 defined(_POSIX_SOURCE) || defined(SVR4)
579 close(0); /* fd 0 opened by inetd */
580 loc_clients[0] = NULL;
583 resfd = init_resolver();
588 void write_pidfile(void)
593 if ((fd = open(PPATH, O_CREAT | O_WRONLY, 0600)) >= 0)
595 memset(buff, 0, sizeof(buff));
596 sprintf(buff, "%5d\n", (int)getpid());
597 if (write(fd, buff, strlen(buff)) == -1)
598 Debug((DEBUG_NOTICE, "Error writing to pid file %s", PPATH));
604 Debug((DEBUG_NOTICE, "Error opening pid file \"%s\": %s",
605 PPATH, strerror(errno)));
611 * Initialize the various name strings used to store hostnames. This is set
612 * from either the server's sockhost (if client fd is a tty or localhost)
613 * or from the ip# converted into a string. 0 = success, -1 = fail.
615 static int check_init(aClient *cptr, char *sockn)
617 struct sockaddr_in sk;
618 size_t len = sizeof(struct sockaddr_in);
622 if (IsUnixSocket(cptr))
624 strncpy(sockn, cptr->acpt->sockhost, HOSTLEN);
625 get_sockhost(cptr, sockn);
630 /* If descriptor is a tty, special checking... */
631 if (isatty(cptr->fd))
633 strncpy(sockn, me.sockhost, HOSTLEN);
634 memset(&sk, 0, sizeof(struct sockaddr_in));
636 else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
638 report_error("connect failure: %s %s", cptr);
641 strcpy(sockn, inetntoa(sk.sin_addr));
642 if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
645 strncpy(sockn, me.sockhost, HOSTLEN);
647 memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
649 cptr->port = ntohs(sk.sin_port) - 10000;
651 cptr->port = ntohs(sk.sin_port);
658 * Ordinary client access check. Look for conf lines which have the same
659 * status as the flags passed.
661 enum AuthorizationCheckResult check_client(aClient *cptr)
663 static char sockname[HOSTLEN + 1];
664 Reg2 struct hostent *hp = NULL;
666 enum AuthorizationCheckResult acr;
669 Debug((DEBUG_DNS, "ch_cl: check access for %s[%s]",
670 cptr->name, inetntoa(cptr->ip)));
672 if (check_init(cptr, sockname))
673 return ACR_BAD_SOCKET;
675 if (!IsUnixSocket(cptr))
678 * Verify that the host to ip mapping is correct both ways and that
679 * the ip#(s) for the socket is listed for the host.
683 for (i = 0; hp->h_addr_list[i]; i++)
684 if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
686 if (!hp->h_addr_list[i])
688 sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
689 inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
694 if ((acr = attach_Iline(cptr, hp, sockname)))
696 Debug((DEBUG_DNS, "ch_cl: access denied: %s[%s]", cptr->name, sockname));
700 Debug((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
702 if (inet_netof(cptr->ip) == IN_LOOPBACKNET || IsUnixSocket(cptr) ||
703 inet_netof(cptr->ip) == inet_netof(mysk.sin_addr))
706 cptr->flags |= FLAGS_LOCAL;
711 #define CFLAG CONF_CONNECT_SERVER
712 #define NFLAG CONF_NOCONNECT_SERVER
717 * Check access for a server given its name (passed in cptr struct).
718 * Must check for all C/N lines which have a name which matches the
719 * name given and a host which matches. A host alias which is the
720 * same as the server name is also acceptable in the host field of a
728 int check_server(aClient *cptr)
730 Reg1 const char *name;
731 Reg2 aConfItem *c_conf = NULL, *n_conf = NULL;
732 struct hostent *hp = NULL;
734 char abuff[HOSTLEN + USERLEN + 2];
735 char sockname[HOSTLEN + 1], fullname[HOSTLEN + 1];
739 Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", name, cptr->sockhost));
741 if (IsUnknown(cptr) && !attach_confs(cptr, name, CFLAG | NFLAG))
743 Debug((DEBUG_DNS, "No C/N lines for %s", name));
748 * We initiated this connection so the client should have a C and N
749 * line already attached after passing through the connec_server()
752 if (IsConnecting(cptr) || IsHandshake(cptr))
754 c_conf = find_conf(lp, name, CFLAG);
755 n_conf = find_conf(lp, name, NFLAG);
756 if (!c_conf || !n_conf)
758 sendto_ops("Connecting Error: %s[%s]", name, cptr->sockhost);
759 det_confs_butmask(cptr, 0);
764 if (IsUnixSocket(cptr))
767 c_conf = find_conf(lp, name, CFLAG);
769 n_conf = find_conf(lp, name, NFLAG);
774 * If the servername is a hostname, either an alias (CNAME) or
775 * real name, then check with it as the host. Use gethostbyname()
776 * to check for servername as hostname.
778 if (!IsUnixSocket(cptr) && !cptr->hostp)
780 Reg1 aConfItem *aconf;
782 aconf = count_cnlines(lp);
789 * Do a lookup for the CONF line *only* and not
790 * the server connection else we get stuck in a
791 * nasty state since it takes a SERVER message to
792 * get us here and we cant interrupt that very well.
795 lin.value.aconf = aconf;
796 lin.flags = ASYNC_CONF;
798 if ((s = strchr(aconf->host, '@')))
802 Debug((DEBUG_DNS, "sv_ci:cache lookup (%s)", s));
803 hp = gethost_byname(s, &lin);
810 if (check_init(cptr, sockname))
816 for (i = 0; hp->h_addr_list[i]; i++)
817 if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
819 if (!hp->h_addr_list[i])
821 sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
822 inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
826 else if (cptr->hostp)
829 goto check_serverback;
834 * If we are missing a C or N line from above, search for
835 * it under all known hostnames we have for this ip#.
837 for (i = 0, name = hp->h_name; name; name = hp->h_aliases[i++])
839 strncpy(fullname, name, sizeof(fullname) - 1);
840 fullname[sizeof(fullname) - 1] = 0;
841 add_local_domain(fullname, HOSTLEN - strlen(fullname));
842 Debug((DEBUG_DNS, "sv_cl: gethostbyaddr: %s->%s", sockname, fullname));
843 sprintf_irc(abuff, "%s@%s", cptr->username, fullname);
845 c_conf = find_conf_host(lp, abuff, CFLAG);
847 n_conf = find_conf_host(lp, abuff, NFLAG);
848 if (c_conf && n_conf)
850 get_sockhost(cptr, fullname);
857 * Check for C and N lines with the hostname portion the ip number
858 * of the host the server runs on. This also checks the case where
859 * there is a server connecting from 'localhost'.
861 if (IsUnknown(cptr) && (!c_conf || !n_conf))
863 sprintf_irc(abuff, "%s@%s", cptr->username, sockname);
865 c_conf = find_conf_host(lp, abuff, CFLAG);
867 n_conf = find_conf_host(lp, abuff, NFLAG);
870 * Attach by IP# only if all other checks have failed.
871 * It is quite possible to get here with the strange things that can
872 * happen when using DNS in the way the irc server does. -avalon
877 c_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, CFLAG);
879 n_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, NFLAG);
882 for (i = 0; hp->h_addr_list[i]; i++)
885 c_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, CFLAG);
887 n_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, NFLAG);
890 * detach all conf lines that got attached by attach_confs()
892 det_confs_butmask(cptr, 0);
894 * if no C or no N lines, then deny access
896 if (!c_conf || !n_conf)
898 get_sockhost(cptr, sockname);
899 Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s] c %p n %p",
900 name, cptr->username, cptr->sockhost, c_conf, n_conf));
904 * attach the C and N lines to the client structure for later use.
906 attach_conf(cptr, n_conf);
907 attach_conf(cptr, c_conf);
908 attach_confs(cptr, name, CONF_HUB | CONF_LEAF | CONF_UWORLD);
910 if ((c_conf->ipnum.s_addr == INADDR_NONE) && !IsUnixSocket(cptr))
911 memcpy(&c_conf->ipnum, &cptr->ip, sizeof(struct in_addr));
912 if (!IsUnixSocket(cptr))
913 get_sockhost(cptr, c_conf->host);
915 Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", name, cptr->sockhost));
922 * completed_connection
924 * Complete non-blocking connect()-sequence. Check access and
925 * terminate connection, if trouble detected.
927 * Return TRUE, if successfully completed
928 * FALSE, if failed and ClientExit
930 static int completed_connection(aClient *cptr)
937 aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
940 sendto_ops("Lost C-Line for %s", get_client_name(cptr, FALSE));
943 if (!BadPtr(aconf->passwd))
944 sendto_one(cptr, "PASS :%s", aconf->passwd);
946 aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
949 sendto_ops("Lost N-Line for %s", get_client_name(cptr, FALSE));
953 /* Create a unique timestamp */
955 for (i = highest_fd; i >= 0; i--)
957 if (!(acptr = loc_clients[i]) || (!IsServer(acptr) && !IsHandshake(acptr)))
959 if (acptr->serv->timestamp >= newts)
960 newts = acptr->serv->timestamp + 1;
962 cptr->serv->timestamp = newts;
964 /* Make us timeout after twice the timeout for DNS look ups */
965 cptr->lasttime = now;
966 cptr->flags |= FLAGS_PINGSENT;
967 sendto_one(cptr, "SERVER %s 1 " TIME_T_FMT " " TIME_T_FMT " J%s %s%s :%s",
968 my_name_for_link(me.name, aconf), me.serv->timestamp,
969 newts, MAJOR_PROTOCOL, NumServCap(&me), me.info);
973 return (IsDead(cptr)) ? -1 : 0;
979 * Close the physical connection. This function must make
980 * MyConnect(cptr) == FALSE, and set cptr->from == NULL.
982 void close_connection(aClient *cptr)
984 Reg1 aConfItem *aconf;
986 int empty = cptr->fd;
991 ircstp->is_sbs += cptr->sendB;
992 ircstp->is_sbr += cptr->receiveB;
993 ircstp->is_sks += cptr->sendK;
994 ircstp->is_skr += cptr->receiveK;
995 ircstp->is_sti += now - cptr->firsttime;
996 if (ircstp->is_sbs > 1023)
998 ircstp->is_sks += (ircstp->is_sbs >> 10);
999 ircstp->is_sbs &= 0x3ff;
1001 if (ircstp->is_sbr > 1023)
1003 ircstp->is_skr += (ircstp->is_sbr >> 10);
1004 ircstp->is_sbr &= 0x3ff;
1007 else if (IsUser(cptr))
1010 ircstp->is_cbs += cptr->sendB;
1011 ircstp->is_cbr += cptr->receiveB;
1012 ircstp->is_cks += cptr->sendK;
1013 ircstp->is_ckr += cptr->receiveK;
1014 ircstp->is_cti += now - cptr->firsttime;
1015 if (ircstp->is_cbs > 1023)
1017 ircstp->is_cks += (ircstp->is_cbs >> 10);
1018 ircstp->is_cbs &= 0x3ff;
1020 if (ircstp->is_cbr > 1023)
1022 ircstp->is_ckr += (ircstp->is_cbr >> 10);
1023 ircstp->is_cbr &= 0x3ff;
1030 * Remove outstanding DNS queries.
1032 del_queries((char *)cptr);
1034 * If the connection has been up for a long amount of time, schedule
1035 * a 'quick' reconnect, else reset the next-connect cycle.
1038 if ((aconf = find_conf_exact(cptr->name, cptr->username,
1039 cptr->sockhost, CONF_CONNECT_SERVER)))
1042 * Reschedule a faster reconnect, if this was a automaticly
1043 * connected configuration entry. (Note that if we have had
1044 * a rehash in between, the status has been changed to
1045 * CONF_ILLEGAL). But only do this if it was a "good" link.
1048 aconf->hold += (aconf->hold - cptr->since > HANGONGOODLINK) ?
1049 HANGONRETRYDELAY : ConfConFreq(aconf);
1050 if (nextconnect > aconf->hold)
1051 nextconnect = aconf->hold;
1054 if (cptr->authfd >= 0)
1055 close(cptr->authfd);
1059 flush_connections(cptr->fd);
1060 loc_clients[cptr->fd] = NULL;
1065 DBufClear(&cptr->sendQ);
1066 DBufClear(&cptr->recvQ);
1067 memset(cptr->passwd, 0, sizeof(cptr->passwd));
1068 set_snomask(cptr, 0, SNO_SET);
1070 * Clean up extra sockets from P-lines which have been discarded.
1072 if (cptr->acpt != &me && cptr->acpt != cptr)
1074 aconf = cptr->acpt->confs->value.aconf;
1075 if (aconf->clients > 0)
1077 if (!aconf->clients && IsIllegal(aconf))
1078 close_connection(cptr->acpt);
1081 for (; highest_fd > 0; highest_fd--)
1082 if (loc_clients[highest_fd])
1085 det_confs_butmask(cptr, 0);
1088 * fd remap to keep loc_clients[i] filled at the bottom.
1091 if ((j = highest_fd) > (i = empty) && !IsLog(loc_clients[j]))
1093 if (IsListening(loc_clients[j]))
1095 if (dup2(j, i) == -1)
1097 loc_clients[i] = loc_clients[j];
1098 loc_clients[i]->fd = i;
1099 loc_clients[j] = NULL;
1101 while (!loc_clients[highest_fd])
1111 static void set_sock_opts(int fd, aClient *cptr)
1116 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1117 (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1118 report_error("setsockopt(SO_REUSEADDR) %s: %s", cptr);
1120 #ifdef SO_USELOOPBACK
1122 if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK,
1123 (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1124 report_error("setsockopt(SO_USELOOPBACK) %s: %s", cptr);
1128 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1129 report_error("setsockopt(SO_RCVBUF) %s: %s", cptr);
1134 * Seems that Sequent freezes up if the receving buffer is a different size
1135 * to the sending buffer (maybe a tcp window problem too).
1141 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1142 report_error("setsockopt(SO_SNDBUF) %s: %s", cptr);
1144 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
1146 char *s = readbuf, *t = readbuf + sizeof(readbuf) / 2;
1148 opt = sizeof(readbuf) / 8;
1149 if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)t, &opt) < 0)
1150 report_error("getsockopt(IP_OPTIONS) %s: %s", cptr);
1151 else if (opt > 0 && opt != sizeof(readbuf) / 8)
1153 for (*readbuf = '\0'; opt > 0; opt--, s += 3)
1154 sprintf(s, "%02x:", *t++);
1156 sendto_ops("Connection %s using IP opts: (%s)",
1157 get_client_name(cptr, TRUE), readbuf);
1159 if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
1160 report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
1165 int get_sockerr(aClient *cptr)
1168 #if defined(SO_ERROR) && !defined(SOL2)
1170 size_t len = sizeof(err);
1172 if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
1182 * Set the client connection into non-blocking mode. If your
1183 * system doesn't support this, you can make this a dummy
1184 * function (and get all the old problems that plagued the
1185 * blocking version of IRC--not a problem if you are a
1186 * lightly loaded node...)
1188 void set_non_blocking(int fd, aClient *cptr)
1196 * NOTE: consult ALL your relevant manual pages *BEFORE* changing
1197 * these ioctl's. There are quite a few variations on them,
1198 * as can be seen by the PCS one. They are *NOT* all the same.
1199 * Heed this well. - Avalon.
1208 /* This portion of code might also apply to NeXT. -LynX */
1211 if (ioctl(fd, FIONBIO, &res) < 0)
1212 report_error("ioctl(fd,FIONBIO) failed for %s: %s", cptr);
1214 if ((res = fcntl(fd, F_GETFL, 0)) == -1)
1215 report_error("fcntl(fd, F_GETFL) failed for %s: %s", cptr);
1216 else if (fcntl(fd, F_SETFL, res | nonb) == -1)
1217 report_error("fcntl(fd, F_SETL, nonb) failed for %s: %s", cptr);
1223 * Creates a client which has just connected to us on the given fd.
1224 * The sockhost field is initialized with the ip# of the host.
1225 * The client is added to the linked list of clients but isnt added to any
1226 * hash tables yet since it doesn't have a name.
1228 aClient *add_connection(aClient *cptr, int fd, int type)
1232 aConfItem *aconf = NULL;
1235 (cptr->port == portnum) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
1238 aconf = cptr->confs->value.aconf;
1240 * Removed preliminary access check. Full check is performed in
1241 * m_server and m_user instead. Also connection time out help to
1242 * get rid of unwanted connections.
1244 if (type == ADCON_TTY) /* If descriptor is a tty,
1245 special checking... */
1246 get_sockhost(acptr, cptr->sockhost);
1250 struct sockaddr_in addr;
1251 size_t len = sizeof(struct sockaddr_in);
1253 if (getpeername(fd, (struct sockaddr *)&addr, &len) == -1)
1255 report_error("Failed in connecting to %s: %s", cptr);
1263 /* Don't want to add "Failed in connecting to" here.. */
1264 if (aconf && IsIllegal(aconf))
1265 goto add_con_refuse;
1267 * Copy ascii address to 'sockhost' just in case. Then we
1268 * have something valid to put into error messages...
1270 get_sockhost(acptr, inetntoa(addr.sin_addr));
1271 memcpy(&acptr->ip, &addr.sin_addr, sizeof(struct in_addr));
1273 acptr->port = ntohs(addr.sin_port) - 10000;
1275 acptr->port = ntohs(addr.sin_port);
1279 * Check that this socket (client) is allowed to accept
1280 * connections from this IP#.
1282 for (s = (char *)&cptr->ip, t = (char *)&acptr->ip, len = 4;
1283 len > 0; len--, s++, t++)
1292 goto add_con_refuse;
1294 lin.flags = ASYNC_CLIENT;
1295 lin.value.cptr = acptr;
1296 Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
1297 acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
1306 if (fd > highest_fd)
1308 loc_clients[fd] = acptr;
1310 Count_newunknown(nrof);
1311 add_client_to_list(acptr);
1312 set_non_blocking(acptr->fd, acptr);
1313 set_sock_opts(acptr->fd, acptr);
1316 * Add this local client to the IPcheck registry.
1317 * If it is a connection to a user port and if the site has been throttled,
1320 if (IPcheck_local_connect(acptr) == -1 && IsUserPort(acptr))
1323 exit_client(cptr, acptr, &me,
1324 "Your host is trying to (re)connect too fast -- throttled");
1333 static void add_unixconnection(aClient *cptr, int fd)
1336 aConfItem *aconf = NULL;
1338 acptr = make_client(NULL, STAT_UNKNOWN);
1341 * Copy ascii address to 'sockhost' just in case. Then we
1342 * have something valid to put into error messages...
1344 get_sockhost(acptr, me.sockhost);
1346 aconf = cptr->confs->value.aconf;
1349 if (IsIllegal(aconf))
1361 if (fd > highest_fd)
1363 loc_clients[fd] = acptr;
1366 memcpy(&acptr->ip, &me.ip, sizeof(struct in_addr));
1368 Count_newunknown(nrof);
1369 add_client_to_list(acptr);
1370 set_non_blocking(acptr->fd, acptr);
1371 set_sock_opts(acptr->fd, acptr);
1378 * select/poll convert macro's by Run.
1380 * The names are chosen to reflect what they means when NOT using poll().
1383 typedef fd_set *fd_setp_t;
1384 #define RFD_ISSET(fd, rfd, index) FD_ISSET((fd), (rfd))
1385 #define WFD_ISSET(fd, wfd, index) FD_ISSET((fd), (wfd))
1386 #define RFD_SET(fd, rfd, index, cptr) FD_SET((fd), (rfd))
1387 #define WFD_SET(fd, wfd, index, cptr) FD_SET((fd), (wfd))
1388 #define RWFD_SET(fd, wfd, index) FD_SET((fd), (wfd))
1389 #define RFD_CLR_OUT(fd, rfd, index) FD_CLR((fd), (rfd))
1390 #define WFD_CLR_OUT(fd, wfd, index) FD_CLR((fd), (wfd))
1391 #define LOC_FD(index) (index)
1392 #define LOC_CLIENTS(index) loc_clients[index]
1393 #define HIGHEST_INDEX highest_fd
1394 #else /* USE_POLL */
1395 typedef unsigned int fd_setp_t; /* Actually, an index to poll_fds[] */
1397 #define POLLREADFLAGS (POLLIN|POLLMSG)
1399 # if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
1400 # define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
1402 # if defined(POLLIN) && defined(POLLRDNORM)
1403 # define POLLREADFLAGS (POLLIN|POLLRDNORM)
1405 # if defined(POLLIN)
1406 # define POLLREADFLAGS POLLIN
1408 # if defined(POLLRDNORM)
1409 # define POLLREADFLAGS POLLRDNORM
1415 #if defined(POLLOUT) && defined(POLLWRNORM)
1416 #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
1418 # if defined(POLLOUT)
1419 # define POLLWRITEFLAGS POLLOUT
1421 # if defined(POLLWRNORM)
1422 # define POLLWRITEFLAGS POLLWRNORM
1427 #define POLLERRORS (POLLHUP|POLLERR)
1429 #define POLLERRORS POLLERR
1431 #define RFD_ISSET(fd, rfd, index) \
1432 ((poll_fds[index].revents & POLLREADFLAGS) || \
1433 ((poll_fds[index].events & POLLREADFLAGS) && \
1434 (poll_fds[index].revents & POLLERRORS)))
1435 #define WFD_ISSET(fd, wfd, index) \
1436 ((poll_fds[index].revents & POLLWRITEFLAGS) || \
1437 ((poll_fds[index].events & POLLWRITEFLAGS) && \
1438 (poll_fds[index].revents & POLLERRORS)))
1439 #define RFD_SET(fdes, rfd, index, cptr) \
1441 poll_fds[index].fd = fdes; \
1442 poll_cptr[index] = cptr; \
1443 poll_fds[index].events = POLLREADFLAGS; \
1446 #define WFD_SET(fdes, wfd, index, cptr) \
1448 poll_fds[index].fd = fdes; \
1449 poll_cptr[index] = cptr; \
1451 poll_fds[index].events |= POLLWRITEFLAGS; \
1454 poll_fds[index].events = POLLWRITEFLAGS; \
1458 /* This identical to WFD_SET() when used after a call to RFD_SET(): */
1459 #define RWFD_SET(fd, wfd, index) poll_fds[index].events |= POLLWRITEFLAGS
1460 /* [RW]FD_CLR_OUT() clears revents, not events */
1461 #define RFD_CLR_OUT(fd, rfd, index) poll_fds[index].revents &= ~POLLREADFLAGS
1462 #define WFD_CLR_OUT(fd, wfd, index) poll_fds[index].revents &= ~POLLWRITEFLAGS
1463 #define LOC_FD(index) (poll_fds[index].fd)
1464 #define LOC_CLIENTS(index) (poll_cptr[index])
1465 #define HIGHEST_INDEX (currfd_index - 1)
1466 #endif /* USE_POLL */
1471 * Read a 'packet' of data from a connection and process it. Read in 8k
1472 * chunks to give a better performance rating (for server connections).
1473 * Do some tricky stuff for client connections to make sure they don't do
1474 * any flooding >:-) -avalon
1476 static int read_packet(aClient *cptr, fd_setp_t rfd)
1482 if (RFD_ISSET(cptr->fd, rfd, rfd) &&
1483 !(IsUser(cptr) && DBufLength(&cptr->recvQ) > 6090))
1486 length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
1488 cptr->lasttime = now;
1489 if (cptr->lasttime > cptr->since)
1490 cptr->since = cptr->lasttime;
1491 cptr->flags &= ~(FLAGS_PINGSENT | FLAGS_NONL);
1493 * If not ready, fake it so it isnt closed
1495 if (length == -1 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1502 * For server connections, we process as many as we can without
1503 * worrying about the time of day or anything :)
1505 if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
1508 if ((done = dopacket(cptr, readbuf, length)))
1514 * Before we even think of parsing what we just read, stick
1515 * it on the end of the receive queue and do it when its
1516 * turn comes around.
1518 if (!dbuf_put(&cptr->recvQ, readbuf, length))
1519 return exit_client(cptr, cptr, &me, "dbuf_put fail");
1521 #ifndef NOFLOODCONTROL
1522 if (IsUser(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD)
1523 return exit_client(cptr, cptr, &me, "Excess Flood");
1526 while (DBufLength(&cptr->recvQ) && !NoNewLine(cptr)
1527 #ifndef NOFLOODCONTROL
1528 && (IsTrusted(cptr) || cptr->since - now < 10)
1533 * If it has become registered as a Server
1534 * then skip the per-message parsing below.
1539 * XXX - this blindly deletes data if no cr/lf is received at
1540 * the end of a lot of messages and the data stored in the
1541 * dbuf is greater than sizeof(readbuf)
1543 dolen = dbuf_get(&cptr->recvQ, readbuf, sizeof(readbuf));
1546 if ((done = dopacket(cptr, readbuf, dolen)))
1550 dolen = dbuf_getmsg(&cptr->recvQ, cptr->buffer, BUFSIZE);
1552 * Devious looking...whats it do ? well..if a client
1553 * sends a *long* message without any CR or LF, then
1554 * dbuf_getmsg fails and we pull it out using this
1555 * loop which just gets the next 512 bytes and then
1556 * deletes the rest of the buffer contents.
1561 if (DBufLength(&cptr->recvQ) < 510)
1563 cptr->flags |= FLAGS_NONL;
1566 DBufClear(&cptr->recvQ);
1569 else if (CPTR_KILLED == client_dopacket(cptr, dolen))
1577 * Check all connections for new connections and input data that is to be
1578 * processed. Also check for connections with data queued and whether we can
1581 * Don't ever use ZERO for `delay', unless you mean to poll and then
1582 * you have to have sleep/wait somewhere else in the code.--msa
1584 int read_message(time_t delay)
1588 struct timeval wait;
1590 struct timeval nowt;
1593 time_t delay2 = delay;
1594 unsigned long usec = 0;
1595 int res, length, fd, i;
1596 int auth = 0, ping = 0;
1598 fd_set read_set, write_set;
1599 #else /* USE_POLL */
1600 unsigned int currfd_index = 0;
1601 unsigned int udpfdindex = 0;
1602 unsigned int resfdindex = 0;
1603 unsigned long timeout;
1605 #endif /* USE_POLL */
1608 gettimeofday(&nowt, NULL);
1616 FD_ZERO(&write_set);
1617 #endif /* not USE_POLL */
1618 for (i = highest_fd; i >= 0; i--)
1622 #endif /* USE_POLL */
1623 if (!(cptr = loc_clients[i]))
1627 if (DoingAuth(cptr))
1630 Debug((DEBUG_NOTICE, "auth on %p %d", cptr, i));
1631 RFD_SET(cptr->authfd, &read_set, currfd_index, cptr);
1632 if (cptr->flags & FLAGS_WRAUTH)
1633 RWFD_SET(cptr->authfd, &write_set, currfd_index);
1638 Debug((DEBUG_NOTICE, "open ping on %p %d", cptr, i));
1639 if (!cptr->firsttime || now <= cptr->firsttime)
1641 RFD_SET(i, &read_set, currfd_index, cptr);
1643 if (DoPing(cptr) && now > cptr->lasttime)
1644 RWFD_SET(i, &write_set, currfd_index);
1648 del_queries((char *)cptr);
1654 #endif /* USE_POLL */
1657 if (DoingDNS(cptr) || DoingAuth(cptr))
1662 #endif /* USE_POLL */
1665 if (IsMe(cptr) && IsListening(cptr))
1666 RFD_SET(i, &read_set, currfd_index, cptr);
1667 else if (!IsMe(cptr))
1669 if (DBufLength(&cptr->recvQ) && delay2 > 2)
1671 if (DBufLength(&cptr->recvQ) < 4088)
1672 RFD_SET(i, &read_set, currfd_index, cptr);
1673 if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
1674 (cptr->listing && DBufLength(&cptr->sendQ) < 2048))
1676 WFD_SET(i, &write_set, currfd_index, cptr);
1679 if (!(cptr->flags & FLAGS_BLOCKED))
1680 WFD_SET(i, &write_set, currfd_index, cptr);
1682 delay2 = 0, usec = 500000;
1684 if (now - cptr->lw.tv_sec && nowt.tv_usec - cptr->lw.tv_usec < 0)
1689 if (us - cptr->lw.tv_usec > 500000)
1690 cptr->flags &= ~FLAGS_BLOCKED;
1696 #endif /* USE_POLL */
1701 RFD_SET(udpfd, &read_set, currfd_index, NULL);
1703 udpfdindex = currfd_index;
1705 #endif /* USE_POLL */
1709 RFD_SET(resfd, &read_set, currfd_index, NULL);
1711 resfdindex = currfd_index;
1713 #endif /* USE_POLL */
1716 wait.tv_sec = MIN(delay2, delay);
1717 wait.tv_usec = usec;
1720 nfds = select(FD_SETSIZE, (int *)&read_set, (int *)&write_set, 0, &wait);
1722 nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
1724 #else /* USE_POLL */
1725 timeout = (wait.tv_sec * 1000) + (wait.tv_usec / 1000);
1726 nfds = poll(poll_fds, currfd_index, timeout);
1727 #endif /* USE_POLL */
1729 if (nfds == -1 && errno == EINTR)
1733 report_error("select %s: %s", &me);
1736 restart("too many select errors");
1741 if (udpfd >= 0 && RFD_ISSET(udpfd, &read_set, udpfdindex))
1745 RFD_CLR_OUT(udpfd, &read_set, udpfdindex);
1748 * Check fd sets for the ping fd's (if set and valid!) first
1749 * because these can not be processed using the normal loops below.
1750 * And we want them to be as fast as possible.
1753 for (i = HIGHEST_INDEX; (ping > 0) && (i >= 0); i--)
1755 if (!(cptr = LOC_CLIENTS(i)))
1760 if ((nfds > 0) && RFD_ISSET(cptr->fd, &read_set, i))
1763 RFD_CLR_OUT(cptr->fd, &read_set, i);
1764 read_ping(cptr); /* This can RunFree(cptr) ! */
1766 else if ((nfds > 0) && WFD_ISSET(cptr->fd, &write_set, i))
1769 cptr->lasttime = now;
1770 WFD_CLR_OUT(cptr->fd, &write_set, i);
1771 send_ping(cptr); /* This can RunFree(cptr) ! */
1774 if (resfd >= 0 && RFD_ISSET(resfd, &read_set, resfdindex))
1778 RFD_CLR_OUT(resfd, &read_set, resfdindex);
1781 * Check fd sets for the auth fd's (if set and valid!) first
1782 * because these can not be processed using the normal loops below.
1785 for (i = HIGHEST_INDEX; (auth > 0) && (i >= 0); i--)
1787 if (!(cptr = LOC_CLIENTS(i)))
1789 if (cptr->authfd < 0)
1792 if ((nfds > 0) && WFD_ISSET(cptr->authfd, &write_set, i))
1795 send_authports(cptr);
1797 else if ((nfds > 0) && RFD_ISSET(cptr->authfd, &read_set, i))
1800 read_authports(cptr);
1803 for (i = HIGHEST_INDEX; i >= 0; i--)
1804 if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) &&
1807 RFD_CLR_OUT(i, &read_set, i);
1809 cptr->lasttime = now;
1811 * There may be many reasons for error return, but
1812 * in otherwise correctly working environment the
1813 * probable cause is running out of file descriptors
1814 * (EMFILE, ENFILE or others?). The man pages for
1815 * accept don't seem to list these as possible,
1816 * although it's obvious that it may happen here.
1817 * Thus no specific errors are tested at this
1818 * point, just assume that connections cannot
1819 * be accepted until some old is closed first.
1821 if ((fd = accept(LOC_FD(i), NULL, NULL)) < 0)
1823 if (errno != EWOULDBLOCK)
1824 report_error("accept() failed%s: %s", NULL);
1827 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECTS)
1828 { /* get an early log of all connections --dl */
1829 static struct sockaddr_in peer;
1832 getpeername(fd, (struct sockaddr *)&peer, &len);
1833 syslog(LOG_DEBUG, "Conn: %s", inetntoa(peer.sin_addr));
1837 if (fd >= MAXCLIENTS)
1839 /* Don't send more messages then one every 10 minutes */
1841 static time_t last_time;
1844 if (last_time < now - (time_t) 600)
1849 last_time = me.since;
1851 ("All connections in use! Had to refuse %d clients in the last "
1852 STIME_T_FMT " minutes", count, (now - last_time) / 60);
1855 sendto_ops("All connections in use. (%s)", get_client_name(cptr,
1860 send(fd, "ERROR :All connections in use\r\n", 32, 0);
1865 * Use of add_connection (which never fails :) meLazy
1868 if (IsUnixSocket(cptr))
1869 add_unixconnection(cptr, fd);
1872 if (!add_connection(cptr, fd, ADCON_SOCKET))
1879 for (i = HIGHEST_INDEX; i >= 0; i--)
1881 if (!(cptr = LOC_CLIENTS(i)) || IsMe(cptr))
1884 if (DoingDNS(cptr) || DoingAuth(cptr) || !(cptr = loc_clients[LOC_FD(i)]))
1886 #endif /* USE_POLL */
1891 if (WFD_ISSET(i, &write_set, i))
1896 * ...room for writing, empty some queue then...
1898 cptr->flags &= ~FLAGS_BLOCKED;
1899 if (IsConnecting(cptr))
1900 write_err = completed_connection(cptr);
1903 if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
1904 list_next_channels(cptr, 64);
1907 if (IsDead(cptr) || write_err)
1910 if (RFD_ISSET(i, &read_set, i))
1913 RFD_CLR_OUT(i, &read_set, i);
1915 exit_client(cptr, cptr, &me,
1916 IsDead(cptr) ? LastDeadComment(cptr) : strerror(get_sockerr(cptr)));
1920 length = 1; /* for fall through case */
1921 if ((!NoNewLine(cptr) || RFD_ISSET(i, &read_set, i)) && !IsDead(cptr))
1923 length = read_packet(cptr, &read_set);
1924 #else /* USE_POLL */
1925 length = read_packet(cptr, i);
1926 #endif /* USE_POLL */
1928 /* Bullshit, why would we want to flush sockets while using non-blocking?
1929 * This uses > 4% cpu! --Run */
1931 flush_connections(LOC_FD(i));
1933 if ((length != CPTR_KILLED) && IsDead(cptr))
1935 if (!RFD_ISSET(i, &read_set, i) && length > 0)
1939 if (length > 0 || length == CPTR_KILLED)
1943 * ...hmm, with non-blocking sockets we might get
1944 * here from quite valid reasons, although.. why
1945 * would select report "data available" when there
1946 * wasn't... So, this must be an error anyway... --msa
1947 * actually, EOF occurs when read() returns 0 and
1948 * in due course, select() returns that fd as ready
1949 * for reading even though it ends up being an EOF. -avalon
1951 Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
1953 if ((IsServer(cptr) || IsHandshake(cptr)) && errno == 0 && length == 0)
1954 exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
1955 get_client_name(cptr, FALSE), cptr->serv->last_error_msg);
1957 exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
1958 get_client_name(cptr, FALSE), (length < 0) ?
1959 strerror(get_sockerr(cptr)) : "EOF from client");
1967 int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp)
1969 Reg1 struct sockaddr *svp;
1970 Reg2 aClient *cptr, *c2ptr;
1974 Debug((DEBUG_NOTICE, "Connect to %s[%s] @%s",
1975 aconf->name, aconf->host, inetntoa(aconf->ipnum)));
1977 if ((c2ptr = FindClient(aconf->name)))
1979 if (IsServer(c2ptr) || IsMe(c2ptr))
1981 sendto_ops("Server %s already present from %s",
1982 aconf->name, c2ptr->from->name);
1983 if (by && IsUser(by) && !MyUser(by))
1985 #ifndef NO_PROTOCOL9
1986 if (Protocol(by->from) < 10)
1987 sendto_one(by, ":%s NOTICE %s :Server %s already present from %s",
1988 me.name, by->name, aconf->name, c2ptr->from->name);
1991 sendto_one(by, "%s NOTICE %s%s :Server %s already present from %s",
1992 NumServ(&me), NumNick(by), aconf->name, c2ptr->from->name);
1996 else if (IsHandshake(c2ptr) || IsConnecting(c2ptr))
1998 if (by && IsUser(by))
2000 if (MyUser(by) || Protocol(by->from) < 10)
2001 sendto_one(by, ":%s NOTICE %s :Connection to %s already in progress",
2002 me.name, by->name, get_client_name(c2ptr, TRUE));
2005 "%s NOTICE %s%s :Connection to %s already in progress",
2006 NumServ(&me), NumNick(by), get_client_name(c2ptr, TRUE));
2013 * If we dont know the IP# for this host and itis a hostname and
2014 * not a ip# string, then try and find the appropriate host record.
2016 if ((!aconf->ipnum.s_addr)
2018 && ((aconf->host[2]) != '/') /* needed for Unix domain -- dl */
2024 lin.flags = ASYNC_CONNECT;
2025 lin.value.aconf = aconf;
2027 s = strchr(aconf->host, '@');
2028 s++; /* should NEVER be NULL */
2029 if ((aconf->ipnum.s_addr = inet_addr(s)) == INADDR_NONE)
2031 aconf->ipnum.s_addr = INADDR_ANY;
2032 hp = gethost_byname(s, &lin);
2033 Debug((DEBUG_NOTICE, "co_sv: hp %p ac %p na %s ho %s",
2034 hp, aconf, aconf->name, s));
2037 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2040 cptr = make_client(NULL, STAT_UNKNOWN);
2043 * Copy these in so we have something for error detection.
2045 strncpy(cptr->name, aconf->name, sizeof(cptr->name) - 1);
2046 cptr->name[sizeof(cptr->name) - 1] = 0;
2047 strncpy(cptr->sockhost, aconf->host, HOSTLEN);
2048 cptr->sockhost[HOSTLEN] = 0;
2051 if (aconf->host[2] == '/') /* (/ starts a 2), Unix domain -- dl */
2052 svp = connect_unix(aconf, cptr, &len);
2054 svp = connect_inet(aconf, cptr, &len);
2056 svp = connect_inet(aconf, cptr, &len);
2064 if (by && IsUser(by) && !MyUser(by))
2066 #ifndef NO_PROTOCOL9
2067 if (Protocol(by->from) < 10)
2068 sendto_one(by, ":%s NOTICE %s :Couldn't connect to %s",
2069 me.name, by->name, get_client_name(cptr, TRUE));
2072 sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
2073 NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2079 set_non_blocking(cptr->fd, cptr);
2080 set_sock_opts(cptr->fd, cptr);
2081 signal(SIGALRM, dummy);
2083 if (connect(cptr->fd, svp, len) < 0 && errno != EINPROGRESS)
2085 int err = get_sockerr(cptr);
2086 errtmp = errno; /* other system calls may eat errno */
2088 report_error("Connect to host %s failed: %s", cptr);
2089 if (by && IsUser(by) && !MyUser(by))
2091 #ifndef NO_PROTOCOL9
2092 if (Protocol(by->from) < 10)
2093 sendto_one(by, ":%s NOTICE %s :Connect to host %s failed: %s",
2094 me.name, by->name, get_client_name(cptr, TRUE), strerror(err));
2097 sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
2098 NumServ(&me), NumNick(by), get_client_name(cptr, TRUE),
2112 * Attach config entries to client here rather than in
2113 * completed_connection. This to avoid null pointer references
2114 * when name returned by gethostbyaddr matches no C lines
2115 * (could happen in 2.6.1a when host and servername differ).
2116 * No need to check access and do gethostbyaddr calls.
2117 * There must at least be one as we got here C line... meLazy
2119 attach_confs_host(cptr, aconf->host,
2120 CONF_NOCONNECT_SERVER | CONF_CONNECT_SERVER);
2122 if (!find_conf_host(cptr->confs, aconf->host, CONF_NOCONNECT_SERVER) ||
2123 !find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
2125 sendto_ops("Host %s is not enabled for connecting:no C/N-line",
2127 if (by && IsUser(by) && !MyUser(by))
2129 #ifndef NO_PROTOCOL9
2130 if (Protocol(by->from) < 10)
2132 ":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
2133 me.name, by->name, get_client_name(cptr, TRUE));
2137 "%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
2138 NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2140 det_confs_butmask(cptr, 0);
2147 * The socket has been connected or connect is in progress.
2150 if (by && IsUser(by))
2152 sprintf_irc(cptr->serv->by, "%s%s", NumNick(by));
2153 if (cptr->serv->user)
2154 free_user(cptr->serv->user, NULL);
2155 cptr->serv->user = by->user;
2160 *cptr->serv->by = '\0';
2161 if (cptr->serv->user)
2162 free_user(cptr->serv->user, NULL);
2163 cptr->serv->user = NULL;
2165 cptr->serv->up = &me;
2166 if (cptr->fd > highest_fd)
2167 highest_fd = cptr->fd;
2168 loc_clients[cptr->fd] = cptr;
2170 SetConnecting(cptr);
2172 get_sockhost(cptr, aconf->host);
2173 Count_newunknown(nrof);
2174 add_client_to_list(cptr);
2181 static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
2183 static struct sockaddr_in server;
2184 Reg3 struct hostent *hp;
2185 struct sockaddr_in bindaddr;
2188 * Might as well get sockhost from here, the connection is attempted
2189 * with it so if it fails its useless.
2192 cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
2194 if (cptr->fd == -1 && errno == EAGAIN)
2196 sendto_ops("opening stream socket to server %s: No more sockets",
2197 get_client_name(cptr, TRUE));
2202 report_error("opening stream socket to server %s: %s", cptr);
2205 if (cptr->fd >= MAXCLIENTS)
2207 sendto_ops("No more connections allowed (%s)", cptr->name);
2211 memset(&server, 0, sizeof(server));
2212 server.sin_family = AF_INET;
2213 get_sockhost(cptr, aconf->host);
2216 * Bind to a local IP# (with unknown port - let unix decide) so
2217 * we have some chance of knowing the IP# that gets used for a host
2218 * with more than one IP#.
2220 memcpy(&bindaddr, &cserv, sizeof(bindaddr));
2221 if (aconf->ipnum.s_addr == 0x100007f)
2222 bindaddr.sin_addr.s_addr = 0x100007f; /* bind with localhost when we are connecting to localhost */
2223 if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
2225 report_error("error binding to local port for %s: %s", cptr);
2230 * By this point we should know the IP# of the host listed in the
2231 * conf line, whether as a result of the hostname lookup or the ip#
2232 * being present instead. If we dont know it, then the connect fails.
2234 if (isDigit(*aconf->host) && (aconf->ipnum.s_addr == INADDR_NONE))
2235 aconf->ipnum.s_addr = inet_addr(aconf->host);
2236 if (aconf->ipnum.s_addr == INADDR_NONE)
2241 Debug((DEBUG_FATAL, "%s: unknown host", aconf->host));
2244 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2246 memcpy(&server.sin_addr, &aconf->ipnum, sizeof(struct in_addr));
2247 memcpy(&cptr->ip, &aconf->ipnum, sizeof(struct in_addr));
2249 server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum) + 10000);
2251 server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum));
2253 *lenp = sizeof(server);
2254 return (struct sockaddr *)&server;
2261 * Build a socket structure for cptr so that it can connet to the unix
2262 * socket defined by the conf structure aconf.
2264 static struct sockaddr *connect_unix(aConfItem *aconf, aClient *cptr, int *lenp)
2266 static struct sockaddr_un sock;
2269 cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
2271 if (cptr->fd == -1 && errno == EAGAIN)
2273 sendto_ops("Unix domain connect to host %s failed: No more sockets",
2274 get_client_name(cptr, TRUE));
2279 report_error("Unix domain connect to host %s failed: %s", cptr);
2282 else if (cptr->fd >= MAXCLIENTS)
2284 sendto_ops("No more connections allowed (%s)", cptr->name);
2288 get_sockhost(cptr, aconf->host);
2289 /* +2 needed for working Unix domain -- dl */
2290 strncpy(sock.sun_path, aconf->host + 2, sizeof(sock.sun_path) - 1);
2291 sock.sun_path[sizeof(sock.sun_path) - 1] = 0;
2292 sock.sun_family = AF_UNIX;
2293 *lenp = strlen(sock.sun_path) + 2;
2296 return (struct sockaddr *)&sock;
2302 * Find the real hostname for the host running the server (or one which
2303 * matches the server's name) and its primary IP#. Hostname is stored
2304 * in the client structure passed as a pointer.
2306 void get_my_name(aClient *cptr, char *name, size_t len)
2308 static char tmp[HOSTLEN + 1];
2310 struct utsname utsn;
2313 char *cname = cptr->name;
2317 * Setup local socket structure to use for binding to.
2319 memset(&mysk, 0, sizeof(mysk));
2320 mysk.sin_family = AF_INET;
2323 if (uname(&utsn) == -1)
2325 len2 = strlen(utsn.nodename);
2328 strncpy(name, utsn.nodename, len2);
2329 #else /* HAVE_GETHOSTNAME */
2330 if (gethostname(name, len) == -1)
2335 /* Assume that a name containing '.' is a FQDN */
2336 if (!strchr(name, '.'))
2337 add_local_domain(name, len - strlen(name));
2340 * If hostname gives another name than cname, then check if there is
2341 * a CNAME record for cname pointing to hostname. If so accept
2342 * cname as our name. meLazy
2346 if ((hp = gethostbyname(cname)) || (hp = gethostbyname(name)))
2351 for (hname = hp->h_name; hname; hname = hp->h_aliases[i++])
2353 strncpy(tmp, hname, sizeof(tmp) - 1);
2354 add_local_domain(tmp, sizeof(tmp) - 1 - strlen(tmp));
2357 * Copy the matching name over and store the
2358 * 'primary' IP# as 'myip' which is used
2359 * later for making the right one is used
2360 * for connecting to other hosts.
2362 if (!strCasediff(me.name, tmp))
2365 if (strCasediff(me.name, tmp))
2366 strncpy(name, hp->h_name, len);
2368 strncpy(name, tmp, len);
2369 memcpy(&mysk.sin_addr, hp->h_addr, sizeof(struct in_addr));
2370 Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
2376 * Setup a UDP socket and listen for incoming packets
2378 int setup_ping(void)
2380 struct sockaddr_in from;
2383 memset(&from, 0, sizeof(from));
2384 from.sin_addr = cserv.sin_addr;
2386 from.sin_port = htons(atoi(UDP_PORT) + 10000);
2388 from.sin_port = htons(atoi(UDP_PORT));
2390 from.sin_family = AF_INET;
2392 if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2394 Debug((DEBUG_ERROR, "socket udp : %s", strerror(errno)));
2397 if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR,
2398 (OPT_TYPE *)&on, sizeof(on)) == -1)
2401 syslog(LOG_ERR, "setsockopt udp fd %d : %m", udpfd);
2403 Debug((DEBUG_ERROR, "setsockopt so_reuseaddr : %s", strerror(errno)));
2409 setsockopt(udpfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on));
2410 if (bind(udpfd, (struct sockaddr *)&from, sizeof(from)) == -1)
2413 syslog(LOG_ERR, "bind udp.%d fd %d : %m", from.sin_port, udpfd);
2415 Debug((DEBUG_ERROR, "bind : %s", strerror(errno)));
2420 if (fcntl(udpfd, F_SETFL, FNDELAY) == -1)
2422 Debug((DEBUG_ERROR, "fcntl fndelay : %s", strerror(errno)));
2431 * max # of pings set to 15/sec.
2433 static void polludp(void)
2436 struct sockaddr_in from;
2438 size_t fromlen = sizeof(from);
2439 static time_t last = 0;
2440 static int cnt = 0, mlen = 0;
2443 * find max length of data area of packet.
2447 mlen = sizeof(readbuf) - strlen(me.name) - strlen(version);
2452 Debug((DEBUG_DEBUG, "udp poll"));
2454 n = recvfrom(udpfd, readbuf, mlen, 0, (struct sockaddr *)&from, &fromlen);
2463 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
2467 report_error("udp port recvfrom (%s): %s", &me);
2477 * attach my name and version for the reply
2484 sendto(udpfd, readbuf, s - readbuf, 0,
2485 (struct sockaddr *)&from, sizeof(from));
2492 * Called when the fd returned from init_resolver() has been selected for
2495 static void do_dns_async(void)
2502 ln.flags = ASYNC_NONE;
2503 hp = get_res((char *)&ln);
2505 Debug((DEBUG_DNS, "%p = get_res(%d,%p)", hp, ln.flags, ln.value.cptr));
2511 * No reply was processed that was outstanding or had a client
2516 if ((cptr = ln.value.cptr))
2518 del_queries((char *)cptr);
2520 if (!DoingAuth(cptr))
2526 aconf = ln.value.aconf;
2529 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2530 connect_server(aconf, NULL, hp);
2533 sendto_ops("Connect to %s failed: host lookup",
2534 (aconf) ? aconf->host : "unknown");
2537 cptr = ln.value.cptr;
2538 del_queries((char *)cptr);
2541 memcpy(&cptr->ip, hp->h_addr, sizeof(struct in_addr));
2542 if (ping_server(cptr) == -1)
2547 sendto_ops("Udp ping to %s failed: host lookup", cptr->sockhost);
2552 aconf = ln.value.aconf;
2554 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));