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 */
121 struct sockaddr_in vserv;
123 static int running_in_background;
129 #ifndef NOFLOODCONTROL
130 #define NOFLOODCONTROL
135 * Try and find the correct name to use with getrlimit() for setting the max.
136 * number of files allowed to be open by this process.
139 #define RLIMIT_FD_MAX RLIMIT_FDMAX
142 #define RLIMIT_FD_MAX RLIMIT_NOFILE
144 #ifdef RLIMIT_OPEN_MAX
145 #define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
152 #if !defined(USE_POLL)
153 #if FD_SETSIZE < (MAXCONNECTIONS + 4)
157 * All operating systems work when MAXCONNECTIONS <= 252.
158 * Most operating systems work when MAXCONNECTIONS <= 1020 and FD_SETSIZE is
159 * updated correctly in the system headers (on BSD systems our sys.h has
160 * defined FD_SETSIZE to MAXCONNECTIONS+4 before including the system's headers
161 * but sys/types.h might have abruptly redefined it so the check is still
162 * done), you might already need to recompile your kernel.
163 * For larger FD_SETSIZE your milage may vary (kernel patches may be needed).
164 * The check is _NOT_ done if we will not use FD_SETS at all (USE_POLL)
166 #error "FD_SETSIZE is too small or MAXCONNECTIONS too large."
171 * Cannot use perror() within daemon. stderr is closed in
172 * ircd and cannot be used. And, worse yet, it might have
173 * been reassigned to a normal connection...
179 * This a replacement for perror(). Record error to log and
180 * also send a copy to all *LOCAL* opers online.
182 * text is a *format* string for outputting error. It must
183 * contain only two '%s', the first will be replaced
184 * by the sockhost from the cptr, and the latter will
185 * be taken from sys_errlist[errno].
187 * cptr if not NULL, is the *LOCAL* client associated with
190 void report_error(char *text, aClient *cptr)
192 Reg1 int errtmp = errno; /* debug may change 'errno' */
195 size_t len = sizeof(err);
197 host = (cptr) ? cptr->name : "";
199 Debug((DEBUG_ERROR, text, host, strerror(errtmp)));
202 * Get the *real* error from the socket (well try to anyway..).
203 * This may only work when SO_DEBUG is enabled but its worth the
206 #if defined(SO_ERROR) && !defined(SOL2)
207 if (cptr && !IsMe(cptr) && cptr->fd >= 0)
208 if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
212 sendto_ops(text, host, strerror(errtmp));
214 syslog(LOG_WARNING, text, host, strerror(errtmp));
216 if (!running_in_background)
218 fprintf(stderr, text, host, strerror(errtmp));
219 fprintf(stderr, "\n");
228 * Create a socket in the AF_INET domain, bind it to the port given in
229 * 'port' and listen to it. Connections are accepted to this socket
230 * depending on the IP# mask given by 'name'. Returns the fd of the
231 * socket created or -1 on error.
233 int inetport(aClient *cptr, char *name, unsigned short int port)
235 static struct sockaddr_in server;
237 size_t len = sizeof(server);
240 ad[0] = ad[1] = ad[2] = ad[3] = 0;
243 * do it this way because building ip# from separate values for each
244 * byte requires endian knowledge or some nasty messing. Also means
245 * easy conversion of "*" 0.0.0.0 or 134.* to 134.0.0.0 :-)
247 sscanf(name, "%d.%d.%d.%d", &ad[0], &ad[1], &ad[2], &ad[3]);
248 sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
252 sprintf(cptr->sockhost, "%-.42s.%u", name, port);
253 strcpy(cptr->name, me.name);
256 * At first, open a new socket
261 cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
263 if (cptr->fd < 0 && errno == EAGAIN)
265 sendto_ops("opening stream socket %s: No more sockets",
272 report_error("opening stream socket %s: %s", cptr);
275 else if (cptr->fd >= MAXCLIENTS)
277 sendto_ops("No more connections allowed (%s)", cptr->name);
283 setsockopt(cptr->fd, SOL_SOCKET, SO_REUSEADDR, (OPT_TYPE *)&opt, sizeof(opt));
286 * Bind a port to listen for new connections if port is non-null,
287 * else assume it is already open and try get something from it.
291 server.sin_family = AF_INET;
293 server.sin_addr.s_addr = INADDR_ANY;
295 server.sin_addr = vserv.sin_addr;
298 server.sin_port = htons(port + 10000);
300 server.sin_port = htons(port);
302 if (bind(cptr->fd, (struct sockaddr *)&server, sizeof(server)) == -1)
304 report_error("binding stream socket %s: %s", cptr);
309 if (getsockname(cptr->fd, (struct sockaddr *)&server, &len))
311 report_error("getsockname failed for %s: %s", cptr);
316 if (cptr == &me) /* KLUDGE to get it work... */
321 sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
322 ntohs(server.sin_port) - 10000);
324 sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
325 ntohs(server.sin_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 cptr->port = ntohs(server.sin_port) - 10000;
335 cptr->port = ntohs(server.sin_port);
337 listen(cptr->fd, 128); /* Use listen port backlog of 128 */
338 loc_clients[cptr->fd] = cptr;
347 * Create a socket and bind it to a filename which is comprised of the path
348 * (directory where file is placed) and port (actual filename created).
349 * Set directory permissions as rwxr-xr-x so other users can connect to the
350 * file which is 'forced' to rwxrwxrwx (different OS's have different need of
351 * modes so users can connect to the socket).
353 int unixport(aClient *cptr, char *path, unsigned short int port)
355 struct sockaddr_un un;
358 cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
360 if (cptr->fd == -1 && errno == EAGAIN)
362 sendto_ops("error opening unix domain socket %s: No more sockets",
368 report_error("error opening unix domain socket %s: %s", cptr);
371 else if (cptr->fd >= MAXCLIENTS)
373 sendto_ops("No more connections allowed (%s)", cptr->name);
379 un.sun_family = AF_UNIX;
383 if (chmod(path, 0755) == -1)
385 sendto_ops("error 'chmod 0755 %s': %s", path, strerror(errno));
387 syslog(LOG_WARNING, "error 'chmod 0755 %s': %s", path, strerror(errno));
394 sprintf_irc(unixpath, "%s/%u", path, port);
396 strncpy(un.sun_path, unixpath, sizeof(un.sun_path) - 1);
397 un.sun_path[sizeof(un.sun_path) - 1] = 0;
398 strcpy(cptr->name, me.name);
400 get_sockhost(cptr, unixpath);
402 if (bind(cptr->fd, (struct sockaddr *)&un, strlen(unixpath) + 2) == -1)
404 report_error("error binding unix socket %s: %s", cptr);
408 if (cptr->fd > highest_fd)
409 highest_fd = cptr->fd;
411 chmod(unixpath, 0777);
412 cptr->flags |= FLAGS_UNIX;
414 loc_clients[cptr->fd] = cptr;
423 * Create a new client which is essentially the stub like 'me' to be used
424 * for a socket that is passive (listen'ing for connections to be accepted).
426 int add_listener(aConfItem *aconf)
430 cptr = make_client(NULL, STAT_ME);
431 cptr->flags = FLAGS_LISTEN;
434 strncpy(cptr->name, aconf->host, sizeof(cptr->name) - 1);
435 cptr->name[sizeof(cptr->name) - 1] = 0;
437 if (*aconf->host == '/')
439 if (unixport(cptr, aconf->host, aconf->port))
444 if (inetport(cptr, aconf->host, aconf->port))
449 cptr->confs = make_link();
450 cptr->confs->next = NULL;
451 cptr->confs->value.aconf = aconf;
452 set_non_blocking(cptr->fd, cptr);
462 * Close and free all clients which are marked as having their socket open
463 * and in a state where they can accept connections. Unix sockets have
464 * the path to the socket unlinked for cleanliness.
466 void close_listeners(void)
470 Reg3 aConfItem *aconf;
473 * close all 'extra' listening ports we have and unlink the file
474 * name if it was a unix socket.
476 for (i = highest_fd; i >= 0; i--)
478 if (!(cptr = loc_clients[i]))
480 if (!IsMe(cptr) || cptr == &me || !IsListening(cptr))
482 aconf = cptr->confs->value.aconf;
484 if (IsIllegal(aconf) && aconf->clients == 0)
487 if (IsUnixSocket(cptr))
489 sprintf_irc(unixpath, "%s/%u", aconf->host, aconf->port);
493 close_connection(cptr);
504 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
507 if (!getrlimit(RLIMIT_FD_MAX, &limit))
510 if (limit.rlim_cur < MAXCONNECTIONS)
512 if (limit.rlim_max < MAXCONNECTIONS)
515 fprintf(stderr, "ircd fd table too big\n");
516 fprintf(stderr, "Hard Limit: " LIMIT_FMT " IRC max: %d\n",
522 (int)MAXCONNECTIONS);
523 fprintf(stderr, "Fix MAXCONNECTIONS\n");
527 limit.rlim_cur = limit.rlim_max; /* make soft limit the max */
528 if (setrlimit(RLIMIT_FD_MAX, &limit) == -1)
530 fprintf(stderr, "error setting max fd's to " LIMIT_FMT "\n",
536 #endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
540 static char logbuf[BUFSIZ];
542 setvbuf(stderr, _IOLBF, logbuf, sizeof(logbuf));
544 setvbuf(stderr, logbuf, _IOLBF, sizeof(logbuf));
549 for (fd = 3; fd < MAXCONNECTIONS; fd++)
552 loc_clients[fd] = NULL;
554 loc_clients[1] = NULL;
557 if (bootopt & BOOT_TTY) /* debugging is going to a tty */
559 if (!(bootopt & BOOT_DEBUG))
562 if (((bootopt & BOOT_CONSOLE) || isatty(0)) &&
563 !(bootopt & BOOT_INETD))
567 running_in_background = 1;
569 if ((fd = open("/dev/tty", O_RDWR)) >= 0)
571 ioctl(fd, TIOCNOTTY, (char *)NULL);
575 #if defined(HPUX) || defined(SOL2) || defined(_SEQUENT_) || \
576 defined(_POSIX_SOURCE) || defined(SVR4)
581 close(0); /* fd 0 opened by inetd */
582 loc_clients[0] = NULL;
585 resfd = init_resolver();
590 void write_pidfile(void)
595 if ((fd = open(PPATH, O_CREAT | O_WRONLY, 0600)) >= 0)
597 memset(buff, 0, sizeof(buff));
598 sprintf(buff, "%5d\n", (int)getpid());
599 if (write(fd, buff, strlen(buff)) == -1)
600 Debug((DEBUG_NOTICE, "Error writing to pid file %s", PPATH));
606 Debug((DEBUG_NOTICE, "Error opening pid file \"%s\": %s",
607 PPATH, strerror(errno)));
613 * Initialize the various name strings used to store hostnames. This is set
614 * from either the server's sockhost (if client fd is a tty or localhost)
615 * or from the ip# converted into a string. 0 = success, -1 = fail.
617 static int check_init(aClient *cptr, char *sockn)
619 struct sockaddr_in sk;
620 size_t len = sizeof(struct sockaddr_in);
624 if (IsUnixSocket(cptr))
626 strncpy(sockn, cptr->acpt->sockhost, HOSTLEN);
627 get_sockhost(cptr, sockn);
632 /* If descriptor is a tty, special checking... */
633 if (isatty(cptr->fd))
635 strncpy(sockn, me.name, HOSTLEN);
636 memset(&sk, 0, sizeof(struct sockaddr_in));
638 else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
640 report_error("connect failure: %s %s", cptr);
643 strcpy(sockn, inetntoa(sk.sin_addr));
644 if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
647 strncpy(sockn, me.name, HOSTLEN);
649 memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
651 cptr->port = ntohs(sk.sin_port) - 10000;
653 cptr->port = ntohs(sk.sin_port);
660 * Ordinary client access check. Look for conf lines which have the same
661 * status as the flags passed.
663 enum AuthorizationCheckResult check_client(aClient *cptr)
665 static char sockname[HOSTLEN + 1];
666 Reg2 struct hostent *hp = NULL;
668 enum AuthorizationCheckResult acr;
671 Debug((DEBUG_DNS, "ch_cl: check access for %s[%s]",
672 cptr->name, inetntoa(cptr->ip)));
674 if (check_init(cptr, sockname))
675 return ACR_BAD_SOCKET;
677 if (!IsUnixSocket(cptr))
680 * Verify that the host to ip mapping is correct both ways and that
681 * the ip#(s) for the socket is listed for the host.
685 for (i = 0; hp->h_addr_list[i]; i++)
686 if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
688 if (!hp->h_addr_list[i])
690 sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
691 inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
696 if ((acr = attach_Iline(cptr, hp, sockname)))
698 Debug((DEBUG_DNS, "ch_cl: access denied: %s[%s]", cptr->name, sockname));
702 Debug((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
704 if (inet_netof(cptr->ip) == IN_LOOPBACKNET || IsUnixSocket(cptr) ||
705 inet_netof(cptr->ip) == inet_netof(mysk.sin_addr))
708 cptr->flags |= FLAGS_LOCAL;
713 #define CFLAG CONF_CONNECT_SERVER
714 #define NFLAG CONF_NOCONNECT_SERVER
719 * Check access for a server given its name (passed in cptr struct).
720 * Must check for all C/N lines which have a name which matches the
721 * name given and a host which matches. A host alias which is the
722 * same as the server name is also acceptable in the host field of a
730 int check_server(aClient *cptr)
732 Reg1 const char *name;
733 Reg2 aConfItem *c_conf = NULL, *n_conf = NULL;
734 struct hostent *hp = NULL;
736 char abuff[HOSTLEN + USERLEN + 2];
737 char sockname[HOSTLEN + 1], fullname[HOSTLEN + 1];
741 Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", name, cptr->sockhost));
743 if (IsUnknown(cptr) && !attach_confs(cptr, name, CFLAG | NFLAG))
745 Debug((DEBUG_DNS, "No C/N lines for %s", name));
750 * We initiated this connection so the client should have a C and N
751 * line already attached after passing through the connec_server()
754 if (IsConnecting(cptr) || IsHandshake(cptr))
756 c_conf = find_conf(lp, name, CFLAG);
757 n_conf = find_conf(lp, name, NFLAG);
758 if (!c_conf || !n_conf)
760 sendto_ops("Connecting Error: %s", name);
761 det_confs_butmask(cptr, 0);
766 if (IsUnixSocket(cptr))
769 c_conf = find_conf(lp, name, CFLAG);
771 n_conf = find_conf(lp, name, NFLAG);
776 * If the servername is a hostname, either an alias (CNAME) or
777 * real name, then check with it as the host. Use gethostbyname()
778 * to check for servername as hostname.
780 if (!IsUnixSocket(cptr) && !cptr->hostp)
782 Reg1 aConfItem *aconf;
784 aconf = count_cnlines(lp);
791 * Do a lookup for the CONF line *only* and not
792 * the server connection else we get stuck in a
793 * nasty state since it takes a SERVER message to
794 * get us here and we cant interrupt that very well.
797 lin.value.aconf = aconf;
798 lin.flags = ASYNC_CONF;
800 if ((s = strchr(aconf->host, '@')))
804 Debug((DEBUG_DNS, "sv_ci:cache lookup (%s)", s));
805 hp = gethost_byname(s, &lin);
812 if (check_init(cptr, sockname))
818 for (i = 0; hp->h_addr_list[i]; i++)
819 if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
821 if (!hp->h_addr_list[i])
823 sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
824 inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
828 else if (cptr->hostp)
831 goto check_serverback;
836 * If we are missing a C or N line from above, search for
837 * it under all known hostnames we have for this ip#.
839 for (i = 0, name = hp->h_name; name; name = hp->h_aliases[i++])
841 strncpy(fullname, name, sizeof(fullname) - 1);
842 fullname[sizeof(fullname) - 1] = 0;
843 add_local_domain(fullname, HOSTLEN - strlen(fullname));
844 Debug((DEBUG_DNS, "sv_cl: gethostbyaddr: %s->%s", sockname, fullname));
845 sprintf_irc(abuff, "%s@%s", cptr->username, fullname);
847 c_conf = find_conf_host(lp, abuff, CFLAG);
849 n_conf = find_conf_host(lp, abuff, NFLAG);
850 if (c_conf && n_conf)
852 get_sockhost(cptr, fullname);
859 * Check for C and N lines with the hostname portion the ip number
860 * of the host the server runs on. This also checks the case where
861 * there is a server connecting from 'localhost'.
863 if (IsUnknown(cptr) && (!c_conf || !n_conf))
865 sprintf_irc(abuff, "%s@%s", cptr->username, sockname);
867 c_conf = find_conf_host(lp, abuff, CFLAG);
869 n_conf = find_conf_host(lp, abuff, NFLAG);
872 * Attach by IP# only if all other checks have failed.
873 * It is quite possible to get here with the strange things that can
874 * happen when using DNS in the way the irc server does. -avalon
879 c_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, CFLAG);
881 n_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, NFLAG);
884 for (i = 0; hp->h_addr_list[i]; i++)
887 c_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, CFLAG);
889 n_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, NFLAG);
892 * detach all conf lines that got attached by attach_confs()
894 det_confs_butmask(cptr, 0);
896 * if no C or no N lines, then deny access
898 if (!c_conf || !n_conf)
900 get_sockhost(cptr, sockname);
901 Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s] c %p n %p",
902 name, cptr->username, cptr->sockhost, c_conf, n_conf));
906 * attach the C and N lines to the client structure for later use.
908 attach_conf(cptr, n_conf);
909 attach_conf(cptr, c_conf);
910 attach_confs(cptr, name, CONF_HUB | CONF_LEAF | CONF_UWORLD);
912 if ((c_conf->ipnum.s_addr == INADDR_NONE) && !IsUnixSocket(cptr))
913 memcpy(&c_conf->ipnum, &cptr->ip, sizeof(struct in_addr));
914 if (!IsUnixSocket(cptr))
915 get_sockhost(cptr, c_conf->host);
917 Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", name, cptr->sockhost));
924 * completed_connection
926 * Complete non-blocking connect()-sequence. Check access and
927 * terminate connection, if trouble detected.
929 * Return TRUE, if successfully completed
930 * FALSE, if failed and ClientExit
932 static int completed_connection(aClient *cptr)
939 aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
942 sendto_ops("Lost C-Line for %s", cptr->name);
945 if (!BadPtr(aconf->passwd))
946 sendto_one(cptr, "PASS :%s", aconf->passwd);
948 aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
951 sendto_ops("Lost N-Line for %s", cptr->name);
955 /* Create a unique timestamp */
957 for (i = highest_fd; i >= 0; i--)
959 if (!(acptr = loc_clients[i]) || (!IsServer(acptr) && !IsHandshake(acptr)))
961 if (acptr->serv->timestamp >= newts)
962 newts = acptr->serv->timestamp + 1;
964 cptr->serv->timestamp = newts;
966 /* Make us timeout after twice the timeout for DNS look ups */
967 cptr->lasttime = now;
968 cptr->flags |= FLAGS_PINGSENT;
969 sendto_one(cptr, "SERVER %s 1 " TIME_T_FMT " " TIME_T_FMT " J%s %s%s :%s",
970 my_name_for_link(me.name, aconf), me.serv->timestamp,
971 newts, MAJOR_PROTOCOL, NumServCap(&me), me.info);
975 return (IsDead(cptr)) ? -1 : 0;
981 * Close the physical connection. This function must make
982 * MyConnect(cptr) == FALSE, and set cptr->from == NULL.
984 void close_connection(aClient *cptr)
986 Reg1 aConfItem *aconf;
988 int empty = cptr->fd;
993 ircstp->is_sbs += cptr->sendB;
994 ircstp->is_sbr += cptr->receiveB;
995 ircstp->is_sks += cptr->sendK;
996 ircstp->is_skr += cptr->receiveK;
997 ircstp->is_sti += now - cptr->firsttime;
998 if (ircstp->is_sbs > 1023)
1000 ircstp->is_sks += (ircstp->is_sbs >> 10);
1001 ircstp->is_sbs &= 0x3ff;
1003 if (ircstp->is_sbr > 1023)
1005 ircstp->is_skr += (ircstp->is_sbr >> 10);
1006 ircstp->is_sbr &= 0x3ff;
1009 else if (IsUser(cptr))
1012 ircstp->is_cbs += cptr->sendB;
1013 ircstp->is_cbr += cptr->receiveB;
1014 ircstp->is_cks += cptr->sendK;
1015 ircstp->is_ckr += cptr->receiveK;
1016 ircstp->is_cti += now - cptr->firsttime;
1017 if (ircstp->is_cbs > 1023)
1019 ircstp->is_cks += (ircstp->is_cbs >> 10);
1020 ircstp->is_cbs &= 0x3ff;
1022 if (ircstp->is_cbr > 1023)
1024 ircstp->is_ckr += (ircstp->is_cbr >> 10);
1025 ircstp->is_cbr &= 0x3ff;
1032 * Remove outstanding DNS queries.
1034 del_queries((char *)cptr);
1036 * If the connection has been up for a long amount of time, schedule
1037 * a 'quick' reconnect, else reset the next-connect cycle.
1040 if ((aconf = find_conf_exact(cptr->name, cptr->username,
1041 cptr->sockhost, CONF_CONNECT_SERVER)))
1044 * Reschedule a faster reconnect, if this was a automaticly
1045 * connected configuration entry. (Note that if we have had
1046 * a rehash in between, the status has been changed to
1047 * CONF_ILLEGAL). But only do this if it was a "good" link.
1050 aconf->hold += (aconf->hold - cptr->since > HANGONGOODLINK) ?
1051 HANGONRETRYDELAY : ConfConFreq(aconf);
1052 if (nextconnect > aconf->hold)
1053 nextconnect = aconf->hold;
1056 if (cptr->authfd >= 0)
1057 close(cptr->authfd);
1061 flush_connections(cptr->fd);
1062 loc_clients[cptr->fd] = NULL;
1067 DBufClear(&cptr->sendQ);
1068 DBufClear(&cptr->recvQ);
1069 memset(cptr->passwd, 0, sizeof(cptr->passwd));
1070 set_snomask(cptr, 0, SNO_SET);
1072 * Clean up extra sockets from P-lines which have been discarded.
1074 if (cptr->acpt != &me && cptr->acpt != cptr)
1076 aconf = cptr->acpt->confs->value.aconf;
1077 if (aconf->clients > 0)
1079 if (!aconf->clients && IsIllegal(aconf))
1080 close_connection(cptr->acpt);
1083 for (; highest_fd > 0; highest_fd--)
1084 if (loc_clients[highest_fd])
1087 det_confs_butmask(cptr, 0);
1090 * fd remap to keep loc_clients[i] filled at the bottom.
1093 if ((j = highest_fd) > (i = empty) && !IsLog(loc_clients[j]))
1095 if (IsListening(loc_clients[j]))
1097 if (dup2(j, i) == -1)
1099 loc_clients[i] = loc_clients[j];
1100 loc_clients[i]->fd = i;
1101 loc_clients[j] = NULL;
1103 while (!loc_clients[highest_fd])
1113 static void set_sock_opts(int fd, aClient *cptr)
1118 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1119 (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1120 report_error("setsockopt(SO_REUSEADDR) %s: %s", cptr);
1122 #ifdef SO_USELOOPBACK
1124 if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK,
1125 (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1126 report_error("setsockopt(SO_USELOOPBACK) %s: %s", cptr);
1130 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1131 report_error("setsockopt(SO_RCVBUF) %s: %s", cptr);
1136 * Seems that Sequent freezes up if the receving buffer is a different size
1137 * to the sending buffer (maybe a tcp window problem too).
1143 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1144 report_error("setsockopt(SO_SNDBUF) %s: %s", cptr);
1146 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
1148 char *s = readbuf, *t = readbuf + sizeof(readbuf) / 2;
1150 opt = sizeof(readbuf) / 8;
1151 if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)t, &opt) < 0)
1152 report_error("getsockopt(IP_OPTIONS) %s: %s", cptr);
1153 else if (opt > 0 && opt != sizeof(readbuf) / 8)
1155 for (*readbuf = '\0'; opt > 0; opt--, s += 3)
1156 sprintf(s, "%02x:", *t++);
1158 sendto_ops("Connection %s using IP opts: (%s)",
1159 get_client_name(cptr, FALSE), readbuf);
1161 if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
1162 report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
1167 int get_sockerr(aClient *cptr)
1169 int errtmp = errno, err = 0;
1170 size_t len = sizeof(err);
1171 #if defined(SO_ERROR) && !defined(SOL2)
1173 if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
1183 * Set the client connection into non-blocking mode. If your
1184 * system doesn't support this, you can make this a dummy
1185 * function (and get all the old problems that plagued the
1186 * blocking version of IRC--not a problem if you are a
1187 * lightly loaded node...)
1189 void set_non_blocking(int fd, aClient *cptr)
1197 * NOTE: consult ALL your relevant manual pages *BEFORE* changing
1198 * these ioctl's. There are quite a few variations on them,
1199 * as can be seen by the PCS one. They are *NOT* all the same.
1200 * Heed this well. - Avalon.
1209 /* This portion of code might also apply to NeXT. -LynX */
1212 if (ioctl(fd, FIONBIO, &res) < 0)
1213 report_error("ioctl(fd,FIONBIO) failed for %s: %s", cptr);
1215 if ((res = fcntl(fd, F_GETFL, 0)) == -1)
1216 report_error("fcntl(fd, F_GETFL) failed for %s: %s", cptr);
1217 else if (fcntl(fd, F_SETFL, res | nonb) == -1)
1218 report_error("fcntl(fd, F_SETL, nonb) failed for %s: %s", cptr);
1223 extern unsigned short server_port;
1226 * Creates a client which has just connected to us on the given fd.
1227 * The sockhost field is initialized with the ip# of the host.
1228 * The client is added to the linked list of clients but isnt added to any
1229 * hash tables yet since it doesn't have a name.
1231 aClient *add_connection(aClient *cptr, int fd, int type)
1235 aConfItem *aconf = NULL;
1238 (cptr->port == server_port) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
1241 aconf = cptr->confs->value.aconf;
1243 * Removed preliminary access check. Full check is performed in
1244 * m_server and m_user instead. Also connection time out help to
1245 * get rid of unwanted connections.
1247 if (type == ADCON_TTY) /* If descriptor is a tty,
1248 special checking... */
1249 get_sockhost(acptr, cptr->sockhost);
1253 struct sockaddr_in addr;
1254 size_t len = sizeof(struct sockaddr_in);
1256 if (getpeername(fd, (struct sockaddr *)&addr, &len) == -1)
1258 report_error("Failed in connecting to %s: %s", cptr);
1266 /* Don't want to add "Failed in connecting to" here.. */
1267 if (aconf && IsIllegal(aconf))
1268 goto add_con_refuse;
1270 * Copy ascii address to 'sockhost' just in case. Then we
1271 * have something valid to put into error messages...
1273 get_sockhost(acptr, inetntoa(addr.sin_addr));
1274 memcpy(&acptr->ip, &addr.sin_addr, sizeof(struct in_addr));
1276 acptr->port = ntohs(addr.sin_port) - 10000;
1278 acptr->port = ntohs(addr.sin_port);
1282 * Check that this socket (client) is allowed to accept
1283 * connections from this IP#.
1285 for (s = (char *)&cptr->ip, t = (char *)&acptr->ip, len = 4;
1286 len > 0; len--, s++, t++)
1295 goto add_con_refuse;
1297 lin.flags = ASYNC_CLIENT;
1298 lin.value.cptr = acptr;
1300 if (!strcmp("127.0.0.1", inetntoa(addr.sin_addr)))
1302 static struct hostent lhe = { "localhost", NULL, 0, 0, NULL };
1303 acptr->hostp = &lhe;
1304 if (!DoingAuth(acptr))
1310 Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
1311 acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
1323 if (fd > highest_fd)
1325 loc_clients[fd] = acptr;
1327 Count_newunknown(nrof);
1328 add_client_to_list(acptr);
1329 set_non_blocking(acptr->fd, acptr);
1330 set_sock_opts(acptr->fd, acptr);
1333 * Add this local client to the IPcheck registry.
1334 * If it is a connection to a user port and if the site has been throttled,
1337 if (IPcheck_local_connect(acptr) == -1 && IsUserPort(acptr))
1340 exit_client(cptr, acptr, &me,
1341 "Your host is trying to (re)connect too fast -- throttled");
1350 static void add_unixconnection(aClient *cptr, int fd)
1353 aConfItem *aconf = NULL;
1355 acptr = make_client(NULL, STAT_UNKNOWN);
1358 * Copy ascii address to 'sockhost' just in case. Then we
1359 * have something valid to put into error messages...
1361 strncpy(acptr->sockhost, me.name, HOSTLEN);
1363 aconf = cptr->confs->value.aconf;
1366 if (IsIllegal(aconf))
1378 if (fd > highest_fd)
1380 loc_clients[fd] = acptr;
1383 memcpy(&acptr->ip, &me.ip, sizeof(struct in_addr));
1385 Count_newunknown(nrof);
1386 add_client_to_list(acptr);
1387 set_non_blocking(acptr->fd, acptr);
1388 set_sock_opts(acptr->fd, acptr);
1395 * select/poll convert macro's by Run.
1397 * The names are chosen to reflect what they means when NOT using poll().
1400 typedef fd_set *fd_setp_t;
1401 #define RFD_ISSET(fd, rfd, index) FD_ISSET((fd), (rfd))
1402 #define WFD_ISSET(fd, wfd, index) FD_ISSET((fd), (wfd))
1403 #define RFD_SET(fd, rfd, index, cptr) FD_SET((fd), (rfd))
1404 #define WFD_SET(fd, wfd, index, cptr) FD_SET((fd), (wfd))
1405 #define RWFD_SET(fd, wfd, index) FD_SET((fd), (wfd))
1406 #define RFD_CLR_OUT(fd, rfd, index) FD_CLR((fd), (rfd))
1407 #define WFD_CLR_OUT(fd, wfd, index) FD_CLR((fd), (wfd))
1408 #define LOC_FD(index) (index)
1409 #define LOC_CLIENTS(index) loc_clients[index]
1410 #define HIGHEST_INDEX highest_fd
1411 #else /* USE_POLL */
1412 typedef unsigned int fd_setp_t; /* Actually, an index to poll_fds[] */
1414 #define POLLREADFLAGS (POLLIN|POLLMSG)
1416 # if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
1417 # define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
1419 # if defined(POLLIN) && defined(POLLRDNORM)
1420 # define POLLREADFLAGS (POLLIN|POLLRDNORM)
1422 # if defined(POLLIN)
1423 # define POLLREADFLAGS POLLIN
1425 # if defined(POLLRDNORM)
1426 # define POLLREADFLAGS POLLRDNORM
1432 #if defined(POLLOUT) && defined(POLLWRNORM)
1433 #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
1435 # if defined(POLLOUT)
1436 # define POLLWRITEFLAGS POLLOUT
1438 # if defined(POLLWRNORM)
1439 # define POLLWRITEFLAGS POLLWRNORM
1444 #define POLLERRORS (POLLHUP|POLLERR)
1446 #define POLLERRORS POLLERR
1448 #define RFD_ISSET(fd, rfd, index) \
1449 ((poll_fds[index].revents & POLLREADFLAGS) || \
1450 ((poll_fds[index].events & POLLREADFLAGS) && \
1451 (poll_fds[index].revents & POLLERRORS)))
1452 #define WFD_ISSET(fd, wfd, index) \
1453 ((poll_fds[index].revents & POLLWRITEFLAGS) || \
1454 ((poll_fds[index].events & POLLWRITEFLAGS) && \
1455 (poll_fds[index].revents & POLLERRORS)))
1456 #define RFD_SET(fdes, rfd, index, cptr) \
1458 poll_fds[index].fd = fdes; \
1459 poll_cptr[index] = cptr; \
1460 poll_fds[index].events = POLLREADFLAGS; \
1463 #define WFD_SET(fdes, wfd, index, cptr) \
1465 poll_fds[index].fd = fdes; \
1466 poll_cptr[index] = cptr; \
1468 poll_fds[index].events |= POLLWRITEFLAGS; \
1471 poll_fds[index].events = POLLWRITEFLAGS; \
1475 /* This identical to WFD_SET() when used after a call to RFD_SET(): */
1476 #define RWFD_SET(fd, wfd, index) poll_fds[index].events |= POLLWRITEFLAGS
1477 /* [RW]FD_CLR_OUT() clears revents, not events */
1478 #define RFD_CLR_OUT(fd, rfd, index) poll_fds[index].revents &= ~POLLREADFLAGS
1479 #define WFD_CLR_OUT(fd, wfd, index) poll_fds[index].revents &= ~POLLWRITEFLAGS
1480 #define LOC_FD(index) (poll_fds[index].fd)
1481 #define LOC_CLIENTS(index) (poll_cptr[index])
1482 #define HIGHEST_INDEX (currfd_index - 1)
1483 #endif /* USE_POLL */
1488 * Read a 'packet' of data from a connection and process it. Read in 8k
1489 * chunks to give a better performance rating (for server connections).
1490 * Do some tricky stuff for client connections to make sure they don't do
1491 * any flooding >:-) -avalon
1493 static int read_packet(aClient *cptr, fd_setp_t rfd)
1499 if (RFD_ISSET(cptr->fd, rfd, rfd) &&
1500 !(IsUser(cptr) && DBufLength(&cptr->recvQ) > 6090))
1503 length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
1505 cptr->lasttime = now;
1506 if (cptr->lasttime > cptr->since)
1507 cptr->since = cptr->lasttime;
1508 cptr->flags &= ~(FLAGS_PINGSENT | FLAGS_NONL);
1510 * If not ready, fake it so it isnt closed
1512 if (length == -1 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1519 * For server connections, we process as many as we can without
1520 * worrying about the time of day or anything :)
1522 if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
1525 if ((done = dopacket(cptr, readbuf, length)))
1531 * Before we even think of parsing what we just read, stick
1532 * it on the end of the receive queue and do it when its
1533 * turn comes around.
1535 if (!dbuf_put(&cptr->recvQ, readbuf, length))
1536 return exit_client(cptr, cptr, &me, "dbuf_put fail");
1538 #ifndef NOFLOODCONTROL
1539 if (IsUser(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD)
1540 return exit_client(cptr, cptr, &me, "Excess Flood");
1543 while (DBufLength(&cptr->recvQ) && !NoNewLine(cptr)
1544 #ifndef NOFLOODCONTROL
1545 && (IsTrusted(cptr) || cptr->since - now < 10)
1550 * If it has become registered as a Server
1551 * then skip the per-message parsing below.
1556 * XXX - this blindly deletes data if no cr/lf is received at
1557 * the end of a lot of messages and the data stored in the
1558 * dbuf is greater than sizeof(readbuf)
1560 dolen = dbuf_get(&cptr->recvQ, readbuf, sizeof(readbuf));
1563 if ((done = dopacket(cptr, readbuf, dolen)))
1567 dolen = dbuf_getmsg(&cptr->recvQ, cptr->buffer, BUFSIZE);
1569 * Devious looking...whats it do ? well..if a client
1570 * sends a *long* message without any CR or LF, then
1571 * dbuf_getmsg fails and we pull it out using this
1572 * loop which just gets the next 512 bytes and then
1573 * deletes the rest of the buffer contents.
1578 if (DBufLength(&cptr->recvQ) < 510)
1580 cptr->flags |= FLAGS_NONL;
1583 DBufClear(&cptr->recvQ);
1586 else if (CPTR_KILLED == client_dopacket(cptr, dolen))
1594 * Check all connections for new connections and input data that is to be
1595 * processed. Also check for connections with data queued and whether we can
1598 * Don't ever use ZERO for `delay', unless you mean to poll and then
1599 * you have to have sleep/wait somewhere else in the code.--msa
1601 int read_message(time_t delay)
1605 struct timeval wait;
1607 struct timeval nowt;
1610 time_t delay2 = delay;
1611 unsigned long usec = 0;
1612 int res, length, fd, i;
1613 int auth = 0, ping = 0;
1615 fd_set read_set, write_set;
1616 #else /* USE_POLL */
1617 unsigned int currfd_index = 0;
1618 unsigned int udpfdindex = 0;
1619 unsigned int resfdindex = 0;
1620 unsigned long timeout;
1622 #endif /* USE_POLL */
1625 gettimeofday(&nowt, NULL);
1633 FD_ZERO(&write_set);
1634 #endif /* not USE_POLL */
1635 for (i = highest_fd; i >= 0; i--)
1639 #endif /* USE_POLL */
1640 if (!(cptr = loc_clients[i]))
1644 if (DoingAuth(cptr))
1647 Debug((DEBUG_NOTICE, "auth on %p %d", cptr, i));
1648 RFD_SET(cptr->authfd, &read_set, currfd_index, cptr);
1649 if (cptr->flags & FLAGS_WRAUTH)
1650 RWFD_SET(cptr->authfd, &write_set, currfd_index);
1655 Debug((DEBUG_NOTICE, "open ping on %p %d", cptr, i));
1656 if (!cptr->firsttime || now <= cptr->firsttime)
1658 RFD_SET(i, &read_set, currfd_index, cptr);
1660 if (DoPing(cptr) && now > cptr->lasttime)
1661 RWFD_SET(i, &write_set, currfd_index);
1665 del_queries((char *)cptr);
1671 #endif /* USE_POLL */
1674 if (DoingDNS(cptr) || DoingAuth(cptr))
1679 #endif /* USE_POLL */
1682 if (IsMe(cptr) && IsListening(cptr))
1683 RFD_SET(i, &read_set, currfd_index, cptr);
1684 else if (!IsMe(cptr))
1686 if (DBufLength(&cptr->recvQ) && delay2 > 2)
1688 if (DBufLength(&cptr->recvQ) < 4088)
1689 RFD_SET(i, &read_set, currfd_index, cptr);
1690 if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
1691 (cptr->listing && DBufLength(&cptr->sendQ) < 2048))
1693 WFD_SET(i, &write_set, currfd_index, cptr);
1696 if (!(cptr->flags & FLAGS_BLOCKED))
1697 WFD_SET(i, &write_set, currfd_index, cptr);
1699 delay2 = 0, usec = 500000;
1701 if (now - cptr->lw.tv_sec && nowt.tv_usec - cptr->lw.tv_usec < 0)
1706 if (us - cptr->lw.tv_usec > 500000)
1707 cptr->flags &= ~FLAGS_BLOCKED;
1713 #endif /* USE_POLL */
1718 RFD_SET(udpfd, &read_set, currfd_index, NULL);
1720 udpfdindex = currfd_index;
1722 #endif /* USE_POLL */
1726 RFD_SET(resfd, &read_set, currfd_index, NULL);
1728 resfdindex = currfd_index;
1730 #endif /* USE_POLL */
1733 wait.tv_sec = MIN(delay2, delay);
1734 wait.tv_usec = usec;
1737 nfds = select(FD_SETSIZE, (int *)&read_set, (int *)&write_set, 0, &wait);
1739 nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
1741 #else /* USE_POLL */
1742 timeout = (wait.tv_sec * 1000) + (wait.tv_usec / 1000);
1743 nfds = poll(poll_fds, currfd_index, timeout);
1744 #endif /* USE_POLL */
1746 if (nfds == -1 && errno == EINTR)
1750 report_error("select %s: %s", &me);
1753 restart("too many select errors");
1758 if (udpfd >= 0 && RFD_ISSET(udpfd, &read_set, udpfdindex))
1762 RFD_CLR_OUT(udpfd, &read_set, udpfdindex);
1765 * Check fd sets for the ping fd's (if set and valid!) first
1766 * because these can not be processed using the normal loops below.
1767 * And we want them to be as fast as possible.
1770 for (i = HIGHEST_INDEX; (ping > 0) && (i >= 0); i--)
1772 if (!(cptr = LOC_CLIENTS(i)))
1777 if ((nfds > 0) && RFD_ISSET(cptr->fd, &read_set, i))
1780 RFD_CLR_OUT(cptr->fd, &read_set, i);
1781 read_ping(cptr); /* This can RunFree(cptr) ! */
1783 else if ((nfds > 0) && WFD_ISSET(cptr->fd, &write_set, i))
1786 cptr->lasttime = now;
1787 WFD_CLR_OUT(cptr->fd, &write_set, i);
1788 send_ping(cptr); /* This can RunFree(cptr) ! */
1791 if (resfd >= 0 && RFD_ISSET(resfd, &read_set, resfdindex))
1795 RFD_CLR_OUT(resfd, &read_set, resfdindex);
1798 * Check fd sets for the auth fd's (if set and valid!) first
1799 * because these can not be processed using the normal loops below.
1802 for (i = HIGHEST_INDEX; (auth > 0) && (i >= 0); i--)
1804 if (!(cptr = LOC_CLIENTS(i)))
1806 if (cptr->authfd < 0)
1809 if ((nfds > 0) && WFD_ISSET(cptr->authfd, &write_set, i))
1812 send_authports(cptr);
1814 else if ((nfds > 0) && RFD_ISSET(cptr->authfd, &read_set, i))
1817 read_authports(cptr);
1820 for (i = HIGHEST_INDEX; i >= 0; i--)
1821 if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) &&
1824 RFD_CLR_OUT(i, &read_set, i);
1826 cptr->lasttime = now;
1828 * There may be many reasons for error return, but
1829 * in otherwise correctly working environment the
1830 * probable cause is running out of file descriptors
1831 * (EMFILE, ENFILE or others?). The man pages for
1832 * accept don't seem to list these as possible,
1833 * although it's obvious that it may happen here.
1834 * Thus no specific errors are tested at this
1835 * point, just assume that connections cannot
1836 * be accepted until some old is closed first.
1838 if ((fd = accept(LOC_FD(i), NULL, NULL)) < 0)
1840 if (errno != EWOULDBLOCK)
1841 report_error("accept() failed%s: %s", NULL);
1844 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECTS)
1845 { /* get an early log of all connections --dl */
1846 static struct sockaddr_in peer;
1849 getpeername(fd, (struct sockaddr *)&peer, &len);
1850 syslog(LOG_DEBUG, "Conn: %s", inetntoa(peer.sin_addr));
1854 if (fd >= MAXCLIENTS)
1856 /* Don't send more messages then one every 10 minutes */
1858 static time_t last_time;
1861 if (last_time < now - (time_t) 600)
1866 last_time = me.since;
1868 ("All connections in use! Had to refuse %d clients in the last "
1869 STIME_T_FMT " minutes", count, (now - last_time) / 60);
1872 sendto_ops("All connections in use. (%s)", cptr->name);
1876 send(fd, "ERROR :All connections in use\r\n", 32, 0);
1881 * Use of add_connection (which never fails :) meLazy
1884 if (IsUnixSocket(cptr))
1885 add_unixconnection(cptr, fd);
1888 if (!add_connection(cptr, fd, ADCON_SOCKET))
1895 for (i = HIGHEST_INDEX; i >= 0; i--)
1897 if (!(cptr = LOC_CLIENTS(i)) || IsMe(cptr))
1900 if (DoingDNS(cptr) || DoingAuth(cptr) || !(cptr = loc_clients[LOC_FD(i)]))
1902 #endif /* USE_POLL */
1907 if (WFD_ISSET(i, &write_set, i))
1912 * ...room for writing, empty some queue then...
1914 cptr->flags &= ~FLAGS_BLOCKED;
1915 if (IsConnecting(cptr))
1916 write_err = completed_connection(cptr);
1919 if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
1920 list_next_channels(cptr, 64);
1923 if (IsDead(cptr) || write_err)
1926 if (RFD_ISSET(i, &read_set, i))
1929 RFD_CLR_OUT(i, &read_set, i);
1931 exit_client(cptr, cptr, &me,
1932 IsDead(cptr) ? LastDeadComment(cptr) : strerror(get_sockerr(cptr)));
1936 length = 1; /* for fall through case */
1937 if ((!NoNewLine(cptr) || RFD_ISSET(i, &read_set, i)) && !IsDead(cptr))
1939 length = read_packet(cptr, &read_set);
1940 #else /* USE_POLL */
1941 length = read_packet(cptr, i);
1942 #endif /* USE_POLL */
1944 /* Bullshit, why would we want to flush sockets while using non-blocking?
1945 * This uses > 4% cpu! --Run */
1947 flush_connections(LOC_FD(i));
1949 if ((length != CPTR_KILLED) && IsDead(cptr))
1951 if (!RFD_ISSET(i, &read_set, i) && length > 0)
1959 * ...hmm, with non-blocking sockets we might get
1960 * here from quite valid reasons, although.. why
1961 * would select report "data available" when there
1962 * wasn't... So, this must be an error anyway... --msa
1963 * actually, EOF occurs when read() returns 0 and
1964 * in due course, select() returns that fd as ready
1965 * for reading even though it ends up being an EOF. -avalon
1967 Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
1969 if (length == CPTR_KILLED)
1972 if ((IsServer(cptr) || IsHandshake(cptr)) && errno == 0 && length == 0)
1973 exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
1974 cptr->name, cptr->serv->last_error_msg);
1976 exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
1977 get_client_name(cptr, FALSE), (length < 0) ?
1978 strerror(get_sockerr(cptr)) : "EOF from client");
1986 int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp)
1988 Reg1 struct sockaddr *svp;
1989 Reg2 aClient *cptr, *c2ptr;
1993 Debug((DEBUG_NOTICE, "Connect to %s[%s] @%s",
1994 aconf->name, aconf->host, inetntoa(aconf->ipnum)));
1996 if ((c2ptr = FindClient(aconf->name)))
1998 if (IsServer(c2ptr) || IsMe(c2ptr))
2000 sendto_ops("Server %s already present from %s",
2001 aconf->name, c2ptr->from->name);
2002 if (by && IsUser(by) && !MyUser(by))
2004 #ifndef NO_PROTOCOL9
2005 if (Protocol(by->from) < 10)
2006 sendto_one(by, ":%s NOTICE %s :Server %s already present from %s",
2007 me.name, by->name, aconf->name, c2ptr->from->name);
2010 sendto_one(by, "%s NOTICE %s%s :Server %s already present from %s",
2011 NumServ(&me), NumNick(by), aconf->name, c2ptr->from->name);
2015 else if (IsHandshake(c2ptr) || IsConnecting(c2ptr))
2017 if (by && IsUser(by))
2019 if (MyUser(by) || Protocol(by->from) < 10)
2020 sendto_one(by, ":%s NOTICE %s :Connection to %s already in progress",
2021 me.name, by->name, c2ptr->name);
2024 "%s NOTICE %s%s :Connection to %s already in progress",
2025 NumServ(&me), NumNick(by), c2ptr->name);
2032 * If we dont know the IP# for this host and itis a hostname and
2033 * not a ip# string, then try and find the appropriate host record.
2035 if ((!aconf->ipnum.s_addr)
2037 && ((aconf->host[2]) != '/') /* needed for Unix domain -- dl */
2043 lin.flags = ASYNC_CONNECT;
2044 lin.value.aconf = aconf;
2046 s = strchr(aconf->host, '@');
2047 s++; /* should NEVER be NULL */
2048 if ((aconf->ipnum.s_addr = inet_addr(s)) == INADDR_NONE)
2050 aconf->ipnum.s_addr = INADDR_ANY;
2051 hp = gethost_byname(s, &lin);
2052 Debug((DEBUG_NOTICE, "co_sv: hp %p ac %p na %s ho %s",
2053 hp, aconf, aconf->name, s));
2056 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2059 cptr = make_client(NULL, STAT_UNKNOWN);
2062 * Copy these in so we have something for error detection.
2064 strncpy(cptr->name, aconf->name, sizeof(cptr->name) - 1);
2065 cptr->name[sizeof(cptr->name) - 1] = 0;
2066 strncpy(cptr->sockhost, aconf->host, HOSTLEN);
2067 cptr->sockhost[HOSTLEN] = 0;
2070 if (aconf->host[2] == '/') /* (/ starts a 2), Unix domain -- dl */
2071 svp = connect_unix(aconf, cptr, &len);
2073 svp = connect_inet(aconf, cptr, &len);
2075 svp = connect_inet(aconf, cptr, &len);
2083 if (by && IsUser(by) && !MyUser(by))
2085 #ifndef NO_PROTOCOL9
2086 if (Protocol(by->from) < 10)
2087 sendto_one(by, ":%s NOTICE %s :Couldn't connect to %s",
2088 me.name, by->name, cptr->name);
2091 sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
2092 NumServ(&me), NumNick(by), cptr->name);
2098 set_non_blocking(cptr->fd, cptr);
2099 set_sock_opts(cptr->fd, cptr);
2100 signal(SIGALRM, dummy);
2102 if (connect(cptr->fd, svp, len) < 0 && errno != EINPROGRESS)
2104 int err = get_sockerr(cptr);
2105 errtmp = errno; /* other system calls may eat errno */
2107 report_error("Connect to host %s failed: %s", cptr);
2108 if (by && IsUser(by) && !MyUser(by))
2110 #ifndef NO_PROTOCOL9
2111 if (Protocol(by->from) < 10)
2112 sendto_one(by, ":%s NOTICE %s :Connect to host %s failed: %s",
2113 me.name, by->name, cptr->name, strerror(err));
2116 sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
2117 NumServ(&me), NumNick(by), cptr->name, strerror(err));
2130 * Attach config entries to client here rather than in
2131 * completed_connection. This to avoid null pointer references
2132 * when name returned by gethostbyaddr matches no C lines
2133 * (could happen in 2.6.1a when host and servername differ).
2134 * No need to check access and do gethostbyaddr calls.
2135 * There must at least be one as we got here C line... meLazy
2137 attach_confs_host(cptr, aconf->host,
2138 CONF_NOCONNECT_SERVER | CONF_CONNECT_SERVER);
2140 if (!find_conf_host(cptr->confs, aconf->host, CONF_NOCONNECT_SERVER) ||
2141 !find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
2143 sendto_ops("Host %s is not enabled for connecting:no C/N-line",
2145 if (by && IsUser(by) && !MyUser(by))
2147 #ifndef NO_PROTOCOL9
2148 if (Protocol(by->from) < 10)
2150 ":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
2151 me.name, by->name, cptr->name);
2155 "%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
2156 NumServ(&me), NumNick(by), cptr->name);
2158 det_confs_butmask(cptr, 0);
2165 * The socket has been connected or connect is in progress.
2168 if (by && IsUser(by))
2170 sprintf_irc(cptr->serv->by, "%s%s", NumNick(by));
2171 if (cptr->serv->user)
2172 free_user(cptr->serv->user, NULL);
2173 cptr->serv->user = by->user;
2178 *cptr->serv->by = '\0';
2179 if (cptr->serv->user)
2180 free_user(cptr->serv->user, NULL);
2181 cptr->serv->user = NULL;
2183 cptr->serv->up = &me;
2184 if (cptr->fd > highest_fd)
2185 highest_fd = cptr->fd;
2186 loc_clients[cptr->fd] = cptr;
2188 SetConnecting(cptr);
2190 get_sockhost(cptr, aconf->host);
2191 Count_newunknown(nrof);
2192 add_client_to_list(cptr);
2199 static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
2201 static struct sockaddr_in server;
2202 Reg3 struct hostent *hp;
2205 * Might as well get sockhost from here, the connection is attempted
2206 * with it so if it fails its useless.
2209 cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
2211 if (cptr->fd == -1 && errno == EAGAIN)
2213 sendto_ops("opening stream socket to server %s: No more sockets",
2219 report_error("opening stream socket to server %s: %s", cptr);
2222 if (cptr->fd >= MAXCLIENTS)
2224 sendto_ops("No more connections allowed (%s)", cptr->name);
2229 memset(&server, 0, sizeof(server));
2230 server.sin_family = AF_INET;
2231 get_sockhost(cptr, aconf->host);
2234 mysk.sin_addr = vserv.sin_addr;
2238 * Bind to a local IP# (with unknown port - let unix decide) so
2239 * we have some chance of knowing the IP# that gets used for a host
2240 * with more than one IP#.
2242 /* No we don't bind it, not all OS's can handle connecting with
2243 * an already bound socket, different ip# might occur anyway
2244 * leading to a freezing select() on this side for some time.
2245 * I had this on my Linux 1.1.88 --Run
2249 * No, we do bind it if we have virtual host support. If we don't
2250 * explicitly bind it, it will default to IN_ADDR_ANY and we lose
2251 * due to the other server not allowing our base IP --smg
2253 if (bind(cptr->fd, (struct sockaddr *)&mysk, sizeof(mysk)) == -1)
2255 report_error("error binding to local port for %s: %s", cptr);
2261 * By this point we should know the IP# of the host listed in the
2262 * conf line, whether as a result of the hostname lookup or the ip#
2263 * being present instead. If we dont know it, then the connect fails.
2265 if (isDigit(*aconf->host) && (aconf->ipnum.s_addr == INADDR_NONE))
2266 aconf->ipnum.s_addr = inet_addr(aconf->host);
2267 if (aconf->ipnum.s_addr == INADDR_NONE)
2272 Debug((DEBUG_FATAL, "%s: unknown host", aconf->host));
2275 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2277 memcpy(&server.sin_addr, &aconf->ipnum, sizeof(struct in_addr));
2278 memcpy(&cptr->ip, &aconf->ipnum, sizeof(struct in_addr));
2280 server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum) + 10000);
2282 server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum));
2284 *lenp = sizeof(server);
2285 return (struct sockaddr *)&server;
2292 * Build a socket structure for cptr so that it can connet to the unix
2293 * socket defined by the conf structure aconf.
2295 static struct sockaddr *connect_unix(aConfItem *aconf, aClient *cptr, int *lenp)
2297 static struct sockaddr_un sock;
2300 cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
2302 if (cptr->fd == -1 && errno == EAGAIN)
2304 sendto_ops("Unix domain connect to host %s failed: No more sockets",
2310 report_error("Unix domain connect to host %s failed: %s", cptr);
2313 else if (cptr->fd >= MAXCLIENTS)
2315 sendto_ops("No more connections allowed (%s)", cptr->name);
2319 get_sockhost(cptr, aconf->host);
2320 /* +2 needed for working Unix domain -- dl */
2321 strncpy(sock.sun_path, aconf->host + 2, sizeof(sock.sun_path) - 1);
2322 sock.sun_path[sizeof(sock.sun_path) - 1] = 0;
2323 sock.sun_family = AF_UNIX;
2324 *lenp = strlen(sock.sun_path) + 2;
2327 return (struct sockaddr *)&sock;
2333 * Find the real hostname for the host running the server (or one which
2334 * matches the server's name) and its primary IP#. Hostname is stored
2335 * in the client structure passed as a pointer.
2337 void get_my_name(aClient *cptr)
2339 struct ConfItem* aconf = find_me();
2341 * Setup local socket structure to use for binding to.
2343 memset(&mysk, 0, sizeof(mysk));
2344 mysk.sin_family = AF_INET;
2345 mysk.sin_addr.s_addr = INADDR_ANY;
2347 if (!aconf || BadPtr(aconf->host))
2349 strncpy(me.name, aconf->host, sizeof(me.name) - 1);
2351 if (!BadPtr(aconf->passwd) && 0 != strcmp(aconf->passwd, "*")) {
2352 mysk.sin_addr.s_addr = inet_addr(aconf->passwd);
2353 if (INADDR_NONE == mysk.sin_addr.s_addr)
2354 mysk.sin_addr.s_addr = INADDR_ANY;
2356 memcpy(&vserv, &mysk, sizeof(struct sockaddr_in));
2359 Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
2363 * Setup a UDP socket and listen for incoming packets
2365 int setup_ping(void)
2367 struct sockaddr_in from;
2370 memset(&from, 0, sizeof(from));
2372 from.sin_addr = vserv.sin_addr;
2374 from.sin_addr.s_addr = htonl(INADDR_ANY);
2377 from.sin_port = htons(atoi(UDP_PORT) + 10000);
2379 from.sin_port = htons(atoi(UDP_PORT));
2381 from.sin_family = AF_INET;
2383 if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2385 Debug((DEBUG_ERROR, "socket udp : %s", strerror(errno)));
2388 if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR,
2389 (OPT_TYPE *)&on, sizeof(on)) == -1)
2392 syslog(LOG_ERR, "setsockopt udp fd %d : %m", udpfd);
2394 Debug((DEBUG_ERROR, "setsockopt so_reuseaddr : %s", strerror(errno)));
2400 setsockopt(udpfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on));
2401 if (bind(udpfd, (struct sockaddr *)&from, sizeof(from)) == -1)
2404 syslog(LOG_ERR, "bind udp.%d fd %d : %m", from.sin_port, udpfd);
2406 Debug((DEBUG_ERROR, "bind : %s", strerror(errno)));
2411 if (fcntl(udpfd, F_SETFL, FNDELAY) == -1)
2413 Debug((DEBUG_ERROR, "fcntl fndelay : %s", strerror(errno)));
2422 * max # of pings set to 15/sec.
2424 static void polludp(void)
2427 struct sockaddr_in from;
2429 size_t fromlen = sizeof(from);
2430 static time_t last = 0;
2431 static int cnt = 0, mlen = 0;
2434 * find max length of data area of packet.
2438 mlen = sizeof(readbuf) - strlen(me.name) - strlen(version);
2443 Debug((DEBUG_DEBUG, "udp poll"));
2445 n = recvfrom(udpfd, readbuf, mlen, 0, (struct sockaddr *)&from, &fromlen);
2454 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
2458 report_error("udp port recvfrom (%s): %s", &me);
2468 * attach my name and version for the reply
2475 sendto(udpfd, readbuf, s - readbuf, 0,
2476 (struct sockaddr *)&from, sizeof(from));
2483 * Called when the fd returned from init_resolver() has been selected for
2486 static void do_dns_async(void)
2493 ln.flags = ASYNC_NONE;
2494 hp = get_res((char *)&ln);
2496 Debug((DEBUG_DNS, "%p = get_res(%d,%p)", hp, ln.flags, ln.value.cptr));
2502 * No reply was processed that was outstanding or had a client
2507 if ((cptr = ln.value.cptr))
2509 del_queries((char *)cptr);
2511 if (!DoingAuth(cptr))
2517 aconf = ln.value.aconf;
2520 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2521 connect_server(aconf, NULL, hp);
2524 sendto_ops("Connect to %s failed: host lookup",
2525 (aconf) ? aconf->host : "unknown");
2528 cptr = ln.value.cptr;
2529 del_queries((char *)cptr);
2532 memcpy(&cptr->ip, hp->h_addr, sizeof(struct in_addr));
2533 if (ping_server(cptr) == -1)
2538 sendto_ops("Udp ping to %s failed: host lookup", cptr->sockhost);
2543 aconf = ln.value.aconf;
2545 memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));