This commit was generated by cvs2svn to compensate for changes in r2,
[ircu2.10.12-pk.git] / ircd / s_bsd.c
1 /*
2  * IRC - Internet Relay Chat, ircd/s_bsd.c
3  * Copyright (C) 1990 Jarkko Oikarinen and
4  *                    University of Oulu, Computing Center
5  *
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)
9  * any later version.
10  *
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.
15  *
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.
19  */
20
21 #include "sys.h"
22 #include <stdlib.h>
23 #include <sys/socket.h>
24 #if HAVE_SYS_FILE_H
25 #include <sys/file.h>
26 #endif
27 #if HAVE_SYS_IOCTL_H
28 #include <sys/ioctl.h>
29 #endif
30 #ifdef SOL2
31 #include <sys/filio.h>
32 #endif
33 #ifdef UNIXPORT
34 #include <sys/un.h>
35 #endif
36 #include <stdio.h>
37 #ifdef USE_POLL
38 #ifndef HAVE_POLL_H
39 #undef USE_POLL
40 #else /* HAVE_POLL_H */
41 #ifdef HAVE_STROPTS_H
42 #include <stropts.h>
43 #endif
44 #include <poll.h>
45 #endif /* HAVE_POLL_H */
46 #endif /* USE_POLL */
47 #include <signal.h>
48 #if HAVE_FCNTL_H
49 #include <fcntl.h>
50 #endif
51 #if HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 #include <sys/stat.h>
55 #include <utmp.h>
56 #include <sys/resource.h>
57 #ifdef USE_SYSLOG
58 #include <syslog.h>
59 #endif
60 #include <sys/utsname.h>
61 #include <netinet/in.h>
62 #include <arpa/inet.h>
63 #include <arpa/nameser.h>
64 #include <resolv.h>
65 #include "h.h"
66 #include "res.h"
67 #include "struct.h"
68 #include "s_bsd.h"
69 #include "s_serv.h"
70 #include "numeric.h"
71 #include "send.h"
72 #include "s_conf.h"
73 #include "s_misc.h"
74 #include "s_bsd.h"
75 #include "hash.h"
76 #include "s_err.h"
77 #include "ircd.h"
78 #include "support.h"
79 #include "s_auth.h"
80 #include "class.h"
81 #include "packet.h"
82 #include "s_ping.h"
83 #include "channel.h"
84 #include "version.h"
85 #include "parse.h"
86 #include "common.h"
87 #include "bsd.h"
88 #include "numnicks.h"
89 #include "s_user.h"
90 #include "sprintf_irc.h"
91 #include "querycmds.h"
92 #include "IPcheck.h"
93
94 RCSTAG_CC("$Id$");
95
96 #ifndef IN_LOOPBACKNET
97 #define IN_LOOPBACKNET  0x7f
98 #endif
99
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();
105
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 *);
110 #ifdef  UNIXPORT
111 static struct sockaddr *connect_unix(aConfItem *, aClient *, int *);
112 static void add_unixconnection(aClient *, int);
113 static char unixpath[256];
114 #endif
115 static char readbuf[8192];
116 #ifdef USE_POLL
117 static struct pollfd poll_fds[MAXCONNECTIONS + 1];
118 static aClient *poll_cptr[MAXCONNECTIONS + 1];
119 #endif /* USE_POLL */
120 #ifdef VIRTUAL_HOST
121 struct sockaddr_in vserv;
122 #endif
123 static int running_in_background;
124
125 #ifdef GODMODE
126 #ifndef NODNS
127 #define NODNS
128 #endif
129 #ifndef NOFLOODCONTROL
130 #define NOFLOODCONTROL
131 #endif
132 #endif
133
134 /*
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.
137  */
138 #ifdef RLIMIT_FDMAX
139 #define RLIMIT_FD_MAX   RLIMIT_FDMAX
140 #else
141 #ifdef RLIMIT_NOFILE
142 #define RLIMIT_FD_MAX RLIMIT_NOFILE
143 #else
144 #ifdef RLIMIT_OPEN_MAX
145 #define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
146 #else
147 #undef RLIMIT_FD_MAX
148 #endif
149 #endif
150 #endif
151
152 #if !defined(USE_POLL)
153 #if FD_SETSIZE < (MAXCONNECTIONS + 4)
154 /*
155  * Sanity check
156  *
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)
165  */
166 #error "FD_SETSIZE is too small or MAXCONNECTIONS too large."
167 #endif
168 #endif
169
170 /*
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...
174  */
175
176 /*
177  * report_error
178  *
179  * This a replacement for perror(). Record error to log and
180  * also send a copy to all *LOCAL* opers online.
181  *
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].
186  *
187  * cptr    if not NULL, is the *LOCAL* client associated with
188  *         the error.
189  */
190 void report_error(char *text, aClient *cptr)
191 {
192   Reg1 int errtmp = errno;      /* debug may change 'errno' */
193   Reg2 char *host;
194   int err;
195   size_t len = sizeof(err);
196
197   host = (cptr) ? get_client_name(cptr, FALSE) : "";
198
199   Debug((DEBUG_ERROR, text, host, strerror(errtmp)));
200
201   /*
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
204    * gamble anyway.
205    */
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))
209       if (err)
210         errtmp = err;
211 #endif
212   sendto_ops(text, host, strerror(errtmp));
213 #ifdef USE_SYSLOG
214   syslog(LOG_WARNING, text, host, strerror(errtmp));
215 #endif
216   if (!running_in_background)
217   {
218     fprintf(stderr, text, host, strerror(errtmp));
219     fprintf(stderr, "\n");
220     fflush(stderr);
221   }
222   return;
223 }
224
225 /*
226  * inetport
227  *
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.
232  */
233 int inetport(aClient *cptr, char *name, unsigned short int port)
234 {
235   static struct sockaddr_in server;
236   int ad[4], opt;
237   size_t len = sizeof(server);
238   char ipname[20];
239
240   ad[0] = ad[1] = ad[2] = ad[3] = 0;
241
242   /*
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 :-)
246    */
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]);
249
250   if (cptr != &me)
251   {
252     sprintf(cptr->sockhost, "%-.42s.%u", name, port);
253     strcpy(cptr->name, me.name);
254   }
255   /*
256    * At first, open a new socket
257    */
258   if (cptr->fd == -1)
259   {
260     alarm(2);
261     cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
262     alarm(0);
263     if (cptr->fd < 0 && errno == EAGAIN)
264     {
265       sendto_ops("opening stream socket %s: No more sockets",
266           get_client_name(cptr, TRUE));
267       return -1;
268     }
269   }
270   if (cptr->fd < 0)
271   {
272     report_error("opening stream socket %s: %s", cptr);
273     return -1;
274   }
275   else if (cptr->fd >= MAXCLIENTS)
276   {
277     sendto_ops("No more connections allowed (%s)", cptr->name);
278     close(cptr->fd);
279     return -1;
280   }
281
282   opt = 1;
283   setsockopt(cptr->fd, SOL_SOCKET, SO_REUSEADDR, (OPT_TYPE *)&opt, sizeof(opt));
284
285   /*
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.
288    */
289   if (port)
290   {
291     server.sin_family = AF_INET;
292 #ifndef VIRTUAL_HOST
293     server.sin_addr.s_addr = INADDR_ANY;
294 #else
295     if (vserv.sin_addr.s_addr == 0)     /* Not already initialised ? */
296     {
297       struct hostent *hep;
298       memset(&vserv, 0, sizeof(vserv));
299       vserv.sin_family = AF_INET;
300       hep = gethostbyname(me.name);     /* Use name from M: line */
301       if (hep && hep->h_addrtype == AF_INET && hep->h_addr_list[0] &&
302           !hep->h_addr_list[1])
303         memcpy(&vserv.sin_addr, hep->h_addr_list[0], sizeof(struct in_addr));
304       else
305       {
306         report_error("Error creating virtual host %s: %s", cptr);
307         return -1;
308       }
309     }
310     server.sin_addr = vserv.sin_addr;
311 #endif
312 #ifdef TESTNET
313     server.sin_port = htons(port + 10000);
314 #else
315     server.sin_port = htons(port);
316 #endif
317     if (bind(cptr->fd, (struct sockaddr *)&server, sizeof(server)) == -1)
318     {
319       report_error("binding stream socket %s: %s", cptr);
320       close(cptr->fd);
321       return -1;
322     }
323   }
324   if (getsockname(cptr->fd, (struct sockaddr *)&server, &len))
325   {
326     report_error("getsockname failed for %s: %s", cptr);
327     close(cptr->fd);
328     return -1;
329   }
330
331   if (cptr == &me)              /* KLUDGE to get it work... */
332   {
333     char buf[1024];
334
335 #ifdef TESTNET
336     sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
337         ntohs(server.sin_port) - 10000);
338 #else
339     sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
340         ntohs(server.sin_port));
341 #endif
342     write(1, buf, strlen(buf));
343   }
344   if (cptr->fd > highest_fd)
345     highest_fd = cptr->fd;
346   cptr->ip.s_addr = inet_addr(ipname);
347 #ifdef TESTNET
348   cptr->port = ntohs(server.sin_port) - 10000;
349 #else
350   cptr->port = ntohs(server.sin_port);
351 #endif
352   listen(cptr->fd, 128);        /* Use listen port backlog of 128 */
353   loc_clients[cptr->fd] = cptr;
354
355   return 0;
356 }
357
358 #ifdef  UNIXPORT
359 /*
360  * unixport
361  *
362  * Create a socket and bind it to a filename which is comprised of the path
363  * (directory where file is placed) and port (actual filename created).
364  * Set directory permissions as rwxr-xr-x so other users can connect to the
365  * file which is 'forced' to rwxrwxrwx (different OS's have different need of
366  * modes so users can connect to the socket).
367  */
368 int unixport(aClient *cptr, char *path, unsigned short int port)
369 {
370   struct sockaddr_un un;
371
372   alarm(2);
373   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
374   alarm(0);
375   if (cptr->fd == -1 && errno == EAGAIN)
376   {
377     sendto_ops("error opening unix domain socket %s: No more sockets",
378         get_client_name(cptr, TRUE));
379     return -1;
380   }
381   if (cptr->fd == -1)
382   {
383     report_error("error opening unix domain socket %s: %s", cptr);
384     return -1;
385   }
386   else if (cptr->fd >= MAXCLIENTS)
387   {
388     sendto_ops("No more connections allowed (%s)", cptr->name);
389     close(cptr->fd);
390     cptr->fd = -1;
391     return -1;
392   }
393
394   un.sun_family = AF_UNIX;
395 #if HAVE_MKDIR
396   mkdir(path, 0755);
397 #else
398   if (chmod(path, 0755) == -1)
399   {
400     sendto_ops("error 'chmod 0755 %s': %s", path, strerror(errno));
401 #ifdef USE_SYSLOG
402     syslog(LOG_WARNING, "error 'chmod 0755 %s': %s", path, strerror(errno));
403 #endif
404     close(cptr->fd);
405     cptr->fd = -1;
406     return -1;
407   }
408 #endif
409   sprintf_irc(unixpath, "%s/%u", path, port);
410   unlink(unixpath);
411   strncpy(un.sun_path, unixpath, sizeof(un.sun_path) - 1);
412   un.sun_path[sizeof(un.sun_path) - 1] = 0;
413   strcpy(cptr->name, me.name);
414   errno = 0;
415   get_sockhost(cptr, unixpath);
416
417   if (bind(cptr->fd, (struct sockaddr *)&un, strlen(unixpath) + 2) == -1)
418   {
419     report_error("error binding unix socket %s: %s", cptr);
420     close(cptr->fd);
421     return -1;
422   }
423   if (cptr->fd > highest_fd)
424     highest_fd = cptr->fd;
425   listen(cptr->fd, 5);
426   chmod(unixpath, 0777);
427   cptr->flags |= FLAGS_UNIX;
428   cptr->port = 0;
429   loc_clients[cptr->fd] = cptr;
430
431   return 0;
432 }
433 #endif
434
435 /*
436  * add_listener
437  *
438  * Create a new client which is essentially the stub like 'me' to be used
439  * for a socket that is passive (listen'ing for connections to be accepted).
440  */
441 int add_listener(aConfItem *aconf)
442 {
443   aClient *cptr;
444
445   cptr = make_client(NULL, STAT_ME);
446   cptr->flags = FLAGS_LISTEN;
447   cptr->acpt = cptr;
448   cptr->from = cptr;
449   strncpy(cptr->name, aconf->host, sizeof(cptr->name) - 1);
450   cptr->name[sizeof(cptr->name) - 1] = 0;
451 #ifdef  UNIXPORT
452   if (*aconf->host == '/')
453   {
454     if (unixport(cptr, aconf->host, aconf->port))
455       cptr->fd = -2;
456   }
457   else
458 #endif
459   if (inetport(cptr, aconf->host, aconf->port))
460     cptr->fd = -2;
461
462   if (cptr->fd >= 0)
463   {
464     cptr->confs = make_link();
465     cptr->confs->next = NULL;
466     cptr->confs->value.aconf = aconf;
467     set_non_blocking(cptr->fd, cptr);
468   }
469   else
470     free_client(cptr);
471   return 0;
472 }
473
474 /*
475  * close_listeners
476  *
477  * Close and free all clients which are marked as having their socket open
478  * and in a state where they can accept connections.  Unix sockets have
479  * the path to the socket unlinked for cleanliness.
480  */
481 void close_listeners(void)
482 {
483   Reg1 aClient *cptr;
484   Reg2 int i;
485   Reg3 aConfItem *aconf;
486
487   /*
488    * close all 'extra' listening ports we have and unlink the file
489    * name if it was a unix socket.
490    */
491   for (i = highest_fd; i >= 0; i--)
492   {
493     if (!(cptr = loc_clients[i]))
494       continue;
495     if (!IsMe(cptr) || cptr == &me || !IsListening(cptr))
496       continue;
497     aconf = cptr->confs->value.aconf;
498
499     if (IsIllegal(aconf) && aconf->clients == 0)
500     {
501 #ifdef  UNIXPORT
502       if (IsUnixSocket(cptr))
503       {
504         sprintf_irc(unixpath, "%s/%u", aconf->host, aconf->port);
505         unlink(unixpath);
506       }
507 #endif
508       close_connection(cptr);
509     }
510   }
511 }
512
513 /*
514  * init_sys
515  */
516 void init_sys(void)
517 {
518   Reg1 int fd;
519 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
520   struct rlimit limit;
521
522   if (!getrlimit(RLIMIT_FD_MAX, &limit))
523   {
524 #ifdef  pyr
525     if (limit.rlim_cur < MAXCONNECTIONS)
526 #else
527     if (limit.rlim_max < MAXCONNECTIONS)
528 #endif
529     {
530       fprintf(stderr, "ircd fd table too big\n");
531       fprintf(stderr, "Hard Limit: " LIMIT_FMT " IRC max: %d\n",
532 #ifdef pyr
533           limit.rlim_cur,
534 #else
535           limit.rlim_max,
536 #endif
537           (int)MAXCONNECTIONS);
538       fprintf(stderr, "Fix MAXCONNECTIONS\n");
539       exit(-1);
540     }
541 #ifndef pyr
542     limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
543     if (setrlimit(RLIMIT_FD_MAX, &limit) == -1)
544     {
545       fprintf(stderr, "error setting max fd's to " LIMIT_FMT "\n",
546           limit.rlim_cur);
547       exit(-1);
548     }
549 #endif
550   }
551 #endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
552 #ifdef DEBUGMODE
553   if (1)
554   {
555     static char logbuf[BUFSIZ];
556 #if SETVBUF_REVERSED
557     setvbuf(stderr, _IOLBF, logbuf, sizeof(logbuf));
558 #else
559     setvbuf(stderr, logbuf, _IOLBF, sizeof(logbuf));
560 #endif
561   }
562 #endif
563
564   for (fd = 3; fd < MAXCONNECTIONS; fd++)
565   {
566     close(fd);
567     loc_clients[fd] = NULL;
568   }
569   loc_clients[1] = NULL;
570   close(1);
571
572   if (bootopt & BOOT_TTY)       /* debugging is going to a tty */
573     goto init_dgram;
574   if (!(bootopt & BOOT_DEBUG))
575     close(2);
576
577   if (((bootopt & BOOT_CONSOLE) || isatty(0)) &&
578       !(bootopt & (BOOT_INETD | BOOT_OPER)))
579   {
580     if (fork())
581       exit(0);
582     running_in_background = 1;
583 #ifdef TIOCNOTTY
584     if ((fd = open("/dev/tty", O_RDWR)) >= 0)
585     {
586       ioctl(fd, TIOCNOTTY, (char *)NULL);
587       close(fd);
588     }
589 #endif
590 #if defined(HPUX) || defined(SOL2) || defined(_SEQUENT_) || \
591     defined(_POSIX_SOURCE) || defined(SVR4)
592     setsid();
593 #else
594     setpgid(0, 0);
595 #endif
596     close(0);                   /* fd 0 opened by inetd */
597     loc_clients[0] = NULL;
598   }
599 init_dgram:
600   resfd = init_resolver();
601
602   return;
603 }
604
605 void write_pidfile(void)
606 {
607 #ifdef PPATH
608   int fd;
609   char buff[20];
610   if ((fd = open(PPATH, O_CREAT | O_WRONLY, 0600)) >= 0)
611   {
612     memset(buff, 0, sizeof(buff));
613     sprintf(buff, "%5d\n", (int)getpid());
614     if (write(fd, buff, strlen(buff)) == -1)
615       Debug((DEBUG_NOTICE, "Error writing to pid file %s", PPATH));
616     close(fd);
617     return;
618   }
619 #ifdef  DEBUGMODE
620   else
621     Debug((DEBUG_NOTICE, "Error opening pid file \"%s\": %s",
622         PPATH, strerror(errno)));
623 #endif
624 #endif
625 }
626
627 /*
628  * Initialize the various name strings used to store hostnames. This is set
629  * from either the server's sockhost (if client fd is a tty or localhost)
630  * or from the ip# converted into a string. 0 = success, -1 = fail.
631  */
632 static int check_init(aClient *cptr, char *sockn)
633 {
634   struct sockaddr_in sk;
635   size_t len = sizeof(struct sockaddr_in);
636   sockn[HOSTLEN] = 0;
637
638 #ifdef  UNIXPORT
639   if (IsUnixSocket(cptr))
640   {
641     strncpy(sockn, cptr->acpt->sockhost, HOSTLEN);
642     get_sockhost(cptr, sockn);
643     return 0;
644   }
645 #endif
646
647   /* If descriptor is a tty, special checking... */
648   if (isatty(cptr->fd))
649   {
650     strncpy(sockn, me.sockhost, HOSTLEN);
651     memset(&sk, 0, sizeof(struct sockaddr_in));
652   }
653   else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
654   {
655     report_error("connect failure: %s %s", cptr);
656     return -1;
657   }
658   strcpy(sockn, inetntoa(sk.sin_addr));
659   if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
660   {
661     cptr->hostp = NULL;
662     strncpy(sockn, me.sockhost, HOSTLEN);
663   }
664   memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
665 #ifdef TESTNET
666   cptr->port = ntohs(sk.sin_port) - 10000;
667 #else
668   cptr->port = ntohs(sk.sin_port);
669 #endif
670
671   return 0;
672 }
673
674 /*
675  * Ordinary client access check. Look for conf lines which have the same
676  * status as the flags passed.
677  */
678 enum AuthorizationCheckResult check_client(aClient *cptr)
679 {
680   static char sockname[HOSTLEN + 1];
681   Reg2 struct hostent *hp = NULL;
682   Reg3 int i;
683   enum AuthorizationCheckResult acr;
684
685   ClearAccess(cptr);
686   Debug((DEBUG_DNS, "ch_cl: check access for %s[%s]",
687       cptr->name, inetntoa(cptr->ip)));
688
689   if (check_init(cptr, sockname))
690     return ACR_BAD_SOCKET;
691
692   if (!IsUnixSocket(cptr))
693     hp = cptr->hostp;
694   /*
695    * Verify that the host to ip mapping is correct both ways and that
696    * the ip#(s) for the socket is listed for the host.
697    */
698   if (hp)
699   {
700     for (i = 0; hp->h_addr_list[i]; i++)
701       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
702         break;
703     if (!hp->h_addr_list[i])
704     {
705       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
706           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
707       hp = NULL;
708     }
709   }
710
711   if ((acr = attach_Iline(cptr, hp, sockname)))
712   {
713     Debug((DEBUG_DNS, "ch_cl: access denied: %s[%s]", cptr->name, sockname));
714     return acr;
715   }
716
717   Debug((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
718
719   if (inet_netof(cptr->ip) == IN_LOOPBACKNET || IsUnixSocket(cptr) ||
720       inet_netof(cptr->ip) == inet_netof(mysk.sin_addr))
721   {
722     ircstp->is_loc++;
723     cptr->flags |= FLAGS_LOCAL;
724   }
725   return ACR_OK;
726 }
727
728 #define CFLAG   CONF_CONNECT_SERVER
729 #define NFLAG   CONF_NOCONNECT_SERVER
730
731 /*
732  * check_server()
733  *
734  * Check access for a server given its name (passed in cptr struct).
735  * Must check for all C/N lines which have a name which matches the
736  * name given and a host which matches. A host alias which is the
737  * same as the server name is also acceptable in the host field of a
738  * C/N line.
739  *
740  * Returns
741  *  0 = Success
742  * -1 = Access denied
743  * -2 = Bad socket.
744  */
745 int check_server(aClient *cptr)
746 {
747   Reg1 const char *name;
748   Reg2 aConfItem *c_conf = NULL, *n_conf = NULL;
749   struct hostent *hp = NULL;
750   Link *lp;
751   char abuff[HOSTLEN + USERLEN + 2];
752   char sockname[HOSTLEN + 1], fullname[HOSTLEN + 1];
753   int i;
754
755   name = cptr->name;
756   Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", name, cptr->sockhost));
757
758   if (IsUnknown(cptr) && !attach_confs(cptr, name, CFLAG | NFLAG))
759   {
760     Debug((DEBUG_DNS, "No C/N lines for %s", name));
761     return -1;
762   }
763   lp = cptr->confs;
764   /*
765    * We initiated this connection so the client should have a C and N
766    * line already attached after passing through the connec_server()
767    * function earlier.
768    */
769   if (IsConnecting(cptr) || IsHandshake(cptr))
770   {
771     c_conf = find_conf(lp, name, CFLAG);
772     n_conf = find_conf(lp, name, NFLAG);
773     if (!c_conf || !n_conf)
774     {
775       sendto_ops("Connecting Error: %s[%s]", name, cptr->sockhost);
776       det_confs_butmask(cptr, 0);
777       return -1;
778     }
779   }
780 #ifdef  UNIXPORT
781   if (IsUnixSocket(cptr))
782   {
783     if (!c_conf)
784       c_conf = find_conf(lp, name, CFLAG);
785     if (!n_conf)
786       n_conf = find_conf(lp, name, NFLAG);
787   }
788 #endif
789
790   /*
791    * If the servername is a hostname, either an alias (CNAME) or
792    * real name, then check with it as the host. Use gethostbyname()
793    * to check for servername as hostname.
794    */
795   if (!IsUnixSocket(cptr) && !cptr->hostp)
796   {
797     Reg1 aConfItem *aconf;
798
799     aconf = count_cnlines(lp);
800     if (aconf)
801     {
802       Reg1 char *s;
803       Link lin;
804
805       /*
806        * Do a lookup for the CONF line *only* and not
807        * the server connection else we get stuck in a
808        * nasty state since it takes a SERVER message to
809        * get us here and we cant interrupt that very well.
810        */
811       ClearAccess(cptr);
812       lin.value.aconf = aconf;
813       lin.flags = ASYNC_CONF;
814       nextdnscheck = 1;
815       if ((s = strchr(aconf->host, '@')))
816         s++;
817       else
818         s = aconf->host;
819       Debug((DEBUG_DNS, "sv_ci:cache lookup (%s)", s));
820       hp = gethost_byname(s, &lin);
821     }
822   }
823
824   lp = cptr->confs;
825
826   ClearAccess(cptr);
827   if (check_init(cptr, sockname))
828     return -2;
829
830 check_serverback:
831   if (hp)
832   {
833     for (i = 0; hp->h_addr_list[i]; i++)
834       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
835         break;
836     if (!hp->h_addr_list[i])
837     {
838       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
839           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
840       hp = NULL;
841     }
842   }
843   else if (cptr->hostp)
844   {
845     hp = cptr->hostp;
846     goto check_serverback;
847   }
848
849   if (hp)
850     /*
851      * If we are missing a C or N line from above, search for
852      * it under all known hostnames we have for this ip#.
853      */
854     for (i = 0, name = hp->h_name; name; name = hp->h_aliases[i++])
855     {
856       strncpy(fullname, name, sizeof(fullname) - 1);
857       fullname[sizeof(fullname) - 1] = 0;
858       add_local_domain(fullname, HOSTLEN - strlen(fullname));
859       Debug((DEBUG_DNS, "sv_cl: gethostbyaddr: %s->%s", sockname, fullname));
860       sprintf_irc(abuff, "%s@%s", cptr->username, fullname);
861       if (!c_conf)
862         c_conf = find_conf_host(lp, abuff, CFLAG);
863       if (!n_conf)
864         n_conf = find_conf_host(lp, abuff, NFLAG);
865       if (c_conf && n_conf)
866       {
867         get_sockhost(cptr, fullname);
868         break;
869       }
870     }
871   name = cptr->name;
872
873   /*
874    * Check for C and N lines with the hostname portion the ip number
875    * of the host the server runs on. This also checks the case where
876    * there is a server connecting from 'localhost'.
877    */
878   if (IsUnknown(cptr) && (!c_conf || !n_conf))
879   {
880     sprintf_irc(abuff, "%s@%s", cptr->username, sockname);
881     if (!c_conf)
882       c_conf = find_conf_host(lp, abuff, CFLAG);
883     if (!n_conf)
884       n_conf = find_conf_host(lp, abuff, NFLAG);
885   }
886   /*
887    * Attach by IP# only if all other checks have failed.
888    * It is quite possible to get here with the strange things that can
889    * happen when using DNS in the way the irc server does. -avalon
890    */
891   if (!hp)
892   {
893     if (!c_conf)
894       c_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, CFLAG);
895     if (!n_conf)
896       n_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, NFLAG);
897   }
898   else
899     for (i = 0; hp->h_addr_list[i]; i++)
900     {
901       if (!c_conf)
902         c_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, CFLAG);
903       if (!n_conf)
904         n_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, NFLAG);
905     }
906   /*
907    * detach all conf lines that got attached by attach_confs()
908    */
909   det_confs_butmask(cptr, 0);
910   /*
911    * if no C or no N lines, then deny access
912    */
913   if (!c_conf || !n_conf)
914   {
915     get_sockhost(cptr, sockname);
916     Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s] c %p n %p",
917         name, cptr->username, cptr->sockhost, c_conf, n_conf));
918     return -1;
919   }
920   /*
921    * attach the C and N lines to the client structure for later use.
922    */
923   attach_conf(cptr, n_conf);
924   attach_conf(cptr, c_conf);
925   attach_confs(cptr, name, CONF_HUB | CONF_LEAF | CONF_UWORLD);
926
927   if ((c_conf->ipnum.s_addr == INADDR_NONE) && !IsUnixSocket(cptr))
928     memcpy(&c_conf->ipnum, &cptr->ip, sizeof(struct in_addr));
929   if (!IsUnixSocket(cptr))
930     get_sockhost(cptr, c_conf->host);
931
932   Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", name, cptr->sockhost));
933   return 0;
934 }
935 #undef  CFLAG
936 #undef  NFLAG
937
938 /*
939  * completed_connection
940  *
941  * Complete non-blocking connect()-sequence. Check access and
942  * terminate connection, if trouble detected.
943  *
944  * Return  TRUE, if successfully completed
945  *        FALSE, if failed and ClientExit
946  */
947 static int completed_connection(aClient *cptr)
948 {
949   aConfItem *aconf;
950   time_t newts;
951   aClient *acptr;
952   int i;
953
954   aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
955   if (!aconf)
956   {
957     sendto_ops("Lost C-Line for %s", get_client_name(cptr, FALSE));
958     return -1;
959   }
960   if (!BadPtr(aconf->passwd))
961     sendto_one(cptr, "PASS :%s", aconf->passwd);
962
963   aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
964   if (!aconf)
965   {
966     sendto_ops("Lost N-Line for %s", get_client_name(cptr, FALSE));
967     return -1;
968   }
969   make_server(cptr);
970   /* Create a unique timestamp */
971   newts = TStime();
972   for (i = highest_fd; i >= 0; i--)
973   {
974     if (!(acptr = loc_clients[i]) || (!IsServer(acptr) && !IsHandshake(acptr)))
975       continue;
976     if (acptr->serv->timestamp >= newts)
977       newts = acptr->serv->timestamp + 1;
978   }
979   cptr->serv->timestamp = newts;
980   SetHandshake(cptr);
981   /* Make us timeout after twice the timeout for DNS look ups */
982   cptr->lasttime = now;
983   cptr->flags |= FLAGS_PINGSENT;
984   sendto_one(cptr, "SERVER %s 1 " TIME_T_FMT " " TIME_T_FMT " J%s %s%s :%s",
985       my_name_for_link(me.name, aconf), me.serv->timestamp,
986       newts, MAJOR_PROTOCOL, NumServCap(&me), me.info);
987   if (!IsDead(cptr))
988     start_auth(cptr);
989
990   return (IsDead(cptr)) ? -1 : 0;
991 }
992
993 /*
994  * close_connection
995  *
996  * Close the physical connection. This function must make
997  * MyConnect(cptr) == FALSE, and set cptr->from == NULL.
998  */
999 void close_connection(aClient *cptr)
1000 {
1001   Reg1 aConfItem *aconf;
1002   Reg2 int i, j;
1003   int empty = cptr->fd;
1004
1005   if (IsServer(cptr))
1006   {
1007     ircstp->is_sv++;
1008     ircstp->is_sbs += cptr->sendB;
1009     ircstp->is_sbr += cptr->receiveB;
1010     ircstp->is_sks += cptr->sendK;
1011     ircstp->is_skr += cptr->receiveK;
1012     ircstp->is_sti += now - cptr->firsttime;
1013     if (ircstp->is_sbs > 1023)
1014     {
1015       ircstp->is_sks += (ircstp->is_sbs >> 10);
1016       ircstp->is_sbs &= 0x3ff;
1017     }
1018     if (ircstp->is_sbr > 1023)
1019     {
1020       ircstp->is_skr += (ircstp->is_sbr >> 10);
1021       ircstp->is_sbr &= 0x3ff;
1022     }
1023   }
1024   else if (IsUser(cptr))
1025   {
1026     ircstp->is_cl++;
1027     ircstp->is_cbs += cptr->sendB;
1028     ircstp->is_cbr += cptr->receiveB;
1029     ircstp->is_cks += cptr->sendK;
1030     ircstp->is_ckr += cptr->receiveK;
1031     ircstp->is_cti += now - cptr->firsttime;
1032     if (ircstp->is_cbs > 1023)
1033     {
1034       ircstp->is_cks += (ircstp->is_cbs >> 10);
1035       ircstp->is_cbs &= 0x3ff;
1036     }
1037     if (ircstp->is_cbr > 1023)
1038     {
1039       ircstp->is_ckr += (ircstp->is_cbr >> 10);
1040       ircstp->is_cbr &= 0x3ff;
1041     }
1042   }
1043   else
1044     ircstp->is_ni++;
1045
1046   /*
1047    * Remove outstanding DNS queries.
1048    */
1049   del_queries((char *)cptr);
1050   /*
1051    * If the connection has been up for a long amount of time, schedule
1052    * a 'quick' reconnect, else reset the next-connect cycle.
1053    */
1054
1055   if ((aconf = find_conf_exact(cptr->name, cptr->username,
1056       cptr->sockhost, CONF_CONNECT_SERVER)))
1057   {
1058     /*
1059      * Reschedule a faster reconnect, if this was a automaticly
1060      * connected configuration entry. (Note that if we have had
1061      * a rehash in between, the status has been changed to
1062      * CONF_ILLEGAL). But only do this if it was a "good" link.
1063      */
1064     aconf->hold = now;
1065     aconf->hold += (aconf->hold - cptr->since > HANGONGOODLINK) ?
1066         HANGONRETRYDELAY : ConfConFreq(aconf);
1067     if (nextconnect > aconf->hold)
1068       nextconnect = aconf->hold;
1069   }
1070
1071   if (cptr->authfd >= 0)
1072     close(cptr->authfd);
1073
1074   if (cptr->fd >= 0)
1075   {
1076     flush_connections(cptr->fd);
1077     loc_clients[cptr->fd] = NULL;
1078     close(cptr->fd);
1079     cptr->fd = -2;
1080   }
1081
1082   DBufClear(&cptr->sendQ);
1083   DBufClear(&cptr->recvQ);
1084   memset(cptr->passwd, 0, sizeof(cptr->passwd));
1085   set_snomask(cptr, 0, SNO_SET);
1086   /*
1087    * Clean up extra sockets from P-lines which have been discarded.
1088    */
1089   if (cptr->acpt != &me && cptr->acpt != cptr)
1090   {
1091     aconf = cptr->acpt->confs->value.aconf;
1092     if (aconf->clients > 0)
1093       aconf->clients--;
1094     if (!aconf->clients && IsIllegal(aconf))
1095       close_connection(cptr->acpt);
1096   }
1097
1098   for (; highest_fd > 0; highest_fd--)
1099     if (loc_clients[highest_fd])
1100       break;
1101
1102   det_confs_butmask(cptr, 0);
1103
1104   /*
1105    * fd remap to keep loc_clients[i] filled at the bottom.
1106    */
1107   if (empty > 0)
1108     if ((j = highest_fd) > (i = empty) && !IsLog(loc_clients[j]))
1109     {
1110       if (IsListening(loc_clients[j]))
1111         return;
1112       if (dup2(j, i) == -1)
1113         return;
1114       loc_clients[i] = loc_clients[j];
1115       loc_clients[i]->fd = i;
1116       loc_clients[j] = NULL;
1117       close(j);
1118       while (!loc_clients[highest_fd])
1119         highest_fd--;
1120     }
1121
1122   return;
1123 }
1124
1125 /*
1126  *  set_sock_opts
1127  */
1128 static void set_sock_opts(int fd, aClient *cptr)
1129 {
1130   size_t opt;
1131 #ifdef SO_REUSEADDR
1132   opt = 1;
1133   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1134       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1135     report_error("setsockopt(SO_REUSEADDR) %s: %s", cptr);
1136 #endif
1137 #ifdef  SO_USELOOPBACK
1138   opt = 1;
1139   if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK,
1140       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1141     report_error("setsockopt(SO_USELOOPBACK) %s: %s", cptr);
1142 #endif
1143 #ifdef  SO_RCVBUF
1144   opt = 8192;
1145   if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1146     report_error("setsockopt(SO_RCVBUF) %s: %s", cptr);
1147 #endif
1148 #ifdef SO_SNDBUF
1149 #ifdef _SEQUENT_
1150 /*
1151  * Seems that Sequent freezes up if the receving buffer is a different size
1152  * to the sending buffer (maybe a tcp window problem too).
1153  */
1154   opt = 8192;
1155 #else
1156   opt = 8192;
1157 #endif
1158   if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1159     report_error("setsockopt(SO_SNDBUF) %s: %s", cptr);
1160 #endif
1161 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
1162   {
1163     char *s = readbuf, *t = readbuf + sizeof(readbuf) / 2;
1164
1165     opt = sizeof(readbuf) / 8;
1166     if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)t, &opt) < 0)
1167       report_error("getsockopt(IP_OPTIONS) %s: %s", cptr);
1168     else if (opt > 0 && opt != sizeof(readbuf) / 8)
1169     {
1170       for (*readbuf = '\0'; opt > 0; opt--, s += 3)
1171         sprintf(s, "%02x:", *t++);
1172       *s = '\0';
1173       sendto_ops("Connection %s using IP opts: (%s)",
1174           get_client_name(cptr, TRUE), readbuf);
1175     }
1176     if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
1177       report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
1178   }
1179 #endif
1180 }
1181
1182 int get_sockerr(aClient *cptr)
1183 {
1184   int errtmp = errno, err = 0;
1185   size_t len = sizeof(err);
1186 #if defined(SO_ERROR) && !defined(SOL2)
1187   if (cptr->fd >= 0)
1188     if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
1189       if (err)
1190         errtmp = err;
1191 #endif
1192   return errtmp;
1193 }
1194
1195 /*
1196  * set_non_blocking
1197  *
1198  * Set the client connection into non-blocking mode. If your
1199  * system doesn't support this, you can make this a dummy
1200  * function (and get all the old problems that plagued the
1201  * blocking version of IRC--not a problem if you are a
1202  * lightly loaded node...)
1203  */
1204 void set_non_blocking(int fd, aClient *cptr)
1205 {
1206   int res;
1207 #ifndef NBLOCK_SYSV
1208   int nonb = 0;
1209 #endif
1210
1211   /*
1212    * NOTE: consult ALL your relevant manual pages *BEFORE* changing
1213    * these ioctl's. There are quite a few variations on them,
1214    * as can be seen by the PCS one. They are *NOT* all the same.
1215    * Heed this well. - Avalon.
1216    */
1217 #ifdef  NBLOCK_POSIX
1218   nonb |= O_NONBLOCK;
1219 #endif
1220 #ifdef  NBLOCK_BSD
1221   nonb |= O_NDELAY;
1222 #endif
1223 #ifdef  NBLOCK_SYSV
1224   /* This portion of code might also apply to NeXT. -LynX */
1225   res = 1;
1226
1227   if (ioctl(fd, FIONBIO, &res) < 0)
1228     report_error("ioctl(fd,FIONBIO) failed for %s: %s", cptr);
1229 #else
1230   if ((res = fcntl(fd, F_GETFL, 0)) == -1)
1231     report_error("fcntl(fd, F_GETFL) failed for %s: %s", cptr);
1232   else if (fcntl(fd, F_SETFL, res | nonb) == -1)
1233     report_error("fcntl(fd, F_SETL, nonb) failed for %s: %s", cptr);
1234 #endif
1235   return;
1236 }
1237
1238 extern unsigned short server_port;
1239
1240 /*
1241  * Creates a client which has just connected to us on the given fd.
1242  * The sockhost field is initialized with the ip# of the host.
1243  * The client is added to the linked list of clients but isnt added to any
1244  * hash tables yet since it doesn't have a name.
1245  */
1246 aClient *add_connection(aClient *cptr, int fd, int type)
1247 {
1248   Link lin;
1249   aClient *acptr;
1250   aConfItem *aconf = NULL;
1251   acptr =
1252       make_client(NULL,
1253       (cptr->port == server_port) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
1254
1255   if (cptr != &me)
1256     aconf = cptr->confs->value.aconf;
1257   /*
1258    * Removed preliminary access check. Full check is performed in
1259    * m_server and m_user instead. Also connection time out help to
1260    * get rid of unwanted connections.
1261    */
1262   if (type == ADCON_TTY)        /* If descriptor is a tty,
1263                                    special checking... */
1264     get_sockhost(acptr, cptr->sockhost);
1265   else
1266   {
1267     Reg1 char *s, *t;
1268     struct sockaddr_in addr;
1269     size_t len = sizeof(struct sockaddr_in);
1270
1271     if (getpeername(fd, (struct sockaddr *)&addr, &len) == -1)
1272     {
1273       report_error("Failed in connecting to %s: %s", cptr);
1274     add_con_refuse:
1275       ircstp->is_ref++;
1276       acptr->fd = -2;
1277       free_client(acptr);
1278       close(fd);
1279       return NULL;
1280     }
1281     /* Don't want to add "Failed in connecting to" here.. */
1282     if (aconf && IsIllegal(aconf))
1283       goto add_con_refuse;
1284     /*
1285      * Copy ascii address to 'sockhost' just in case. Then we
1286      * have something valid to put into error messages...
1287      */
1288     get_sockhost(acptr, inetntoa(addr.sin_addr));
1289     memcpy(&acptr->ip, &addr.sin_addr, sizeof(struct in_addr));
1290 #ifdef TESTNET
1291     acptr->port = ntohs(addr.sin_port) - 10000;
1292 #else
1293     acptr->port = ntohs(addr.sin_port);
1294 #endif
1295
1296     /*
1297      * Check that this socket (client) is allowed to accept
1298      * connections from this IP#.
1299      */
1300     for (s = (char *)&cptr->ip, t = (char *)&acptr->ip, len = 4;
1301         len > 0; len--, s++, t++)
1302     {
1303       if (!*s)
1304         continue;
1305       if (*s != *t)
1306         break;
1307     }
1308
1309     if (len)
1310       goto add_con_refuse;
1311
1312     lin.flags = ASYNC_CLIENT;
1313     lin.value.cptr = acptr;
1314 #ifdef NODNS
1315     if (!strcmp("127.0.0.1", inetntoa(addr.sin_addr)))
1316     {
1317       static struct hostent lhe = { "localhost", NULL, 0, 0, NULL };
1318       acptr->hostp = &lhe;
1319       if (!DoingAuth(acptr))
1320         SetAccess(acptr);
1321     }
1322     else
1323     {
1324 #endif
1325       Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
1326       acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
1327       if (!acptr->hostp)
1328         SetDNS(acptr);
1329       nextdnscheck = 1;
1330 #ifdef NODNS
1331     }
1332 #endif
1333   }
1334
1335   if (aconf)
1336     aconf->clients++;
1337   acptr->fd = fd;
1338   if (fd > highest_fd)
1339     highest_fd = fd;
1340   loc_clients[fd] = acptr;
1341   acptr->acpt = cptr;
1342   Count_newunknown(nrof);
1343   add_client_to_list(acptr);
1344   set_non_blocking(acptr->fd, acptr);
1345   set_sock_opts(acptr->fd, acptr);
1346
1347   /*
1348    * Add this local client to the IPcheck registry.
1349    * If it is a connection to a user port and if the site has been throttled,
1350    * reject the user.
1351    */
1352   if (IPcheck_local_connect(acptr) == -1 && IsUserPort(acptr))
1353   {
1354     ircstp->is_ref++;
1355     exit_client(cptr, acptr, &me,
1356         "Your host is trying to (re)connect too fast -- throttled");
1357     return NULL;
1358   }
1359
1360   start_auth(acptr);
1361   return acptr;
1362 }
1363
1364 #ifdef  UNIXPORT
1365 static void add_unixconnection(aClient *cptr, int fd)
1366 {
1367   aClient *acptr;
1368   aConfItem *aconf = NULL;
1369
1370   acptr = make_client(NULL, STAT_UNKNOWN);
1371
1372   /*
1373    * Copy ascii address to 'sockhost' just in case. Then we
1374    * have something valid to put into error messages...
1375    */
1376   get_sockhost(acptr, me.sockhost);
1377   if (cptr != &me)
1378     aconf = cptr->confs->value.aconf;
1379   if (aconf)
1380   {
1381     if (IsIllegal(aconf))
1382     {
1383       ircstp->is_ref++;
1384       acptr->fd = -2;
1385       free_client(acptr);
1386       close(fd);
1387       return;
1388     }
1389     else
1390       aconf->clients++;
1391   }
1392   acptr->fd = fd;
1393   if (fd > highest_fd)
1394     highest_fd = fd;
1395   loc_clients[fd] = acptr;
1396   acptr->acpt = cptr;
1397   SetUnixSock(acptr);
1398   memcpy(&acptr->ip, &me.ip, sizeof(struct in_addr));
1399
1400   Count_newunknown(nrof);
1401   add_client_to_list(acptr);
1402   set_non_blocking(acptr->fd, acptr);
1403   set_sock_opts(acptr->fd, acptr);
1404   SetAccess(acptr);
1405   return;
1406 }
1407 #endif
1408
1409 /*
1410  * select/poll convert macro's by Run.
1411  *
1412  * The names are chosen to reflect what they means when NOT using poll().
1413  */
1414 #ifndef USE_POLL
1415 typedef fd_set *fd_setp_t;
1416 #define RFD_ISSET(fd, rfd, index) FD_ISSET((fd), (rfd))
1417 #define WFD_ISSET(fd, wfd, index) FD_ISSET((fd), (wfd))
1418 #define RFD_SET(fd, rfd, index, cptr) FD_SET((fd), (rfd))
1419 #define WFD_SET(fd, wfd, index, cptr) FD_SET((fd), (wfd))
1420 #define RWFD_SET(fd, wfd, index) FD_SET((fd), (wfd))
1421 #define RFD_CLR_OUT(fd, rfd, index) FD_CLR((fd), (rfd))
1422 #define WFD_CLR_OUT(fd, wfd, index) FD_CLR((fd), (wfd))
1423 #define LOC_FD(index) (index)
1424 #define LOC_CLIENTS(index) loc_clients[index]
1425 #define HIGHEST_INDEX highest_fd
1426 #else /* USE_POLL */
1427 typedef unsigned int fd_setp_t; /* Actually, an index to poll_fds[] */
1428 #ifdef _AIX
1429 #define POLLREADFLAGS (POLLIN|POLLMSG)
1430 #else
1431 #  if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
1432 #    define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
1433 #  else
1434 #    if defined(POLLIN) && defined(POLLRDNORM)
1435 #      define POLLREADFLAGS (POLLIN|POLLRDNORM)
1436 #    else
1437 #      if defined(POLLIN)
1438 #        define POLLREADFLAGS POLLIN
1439 #      else
1440 #        if defined(POLLRDNORM)
1441 #          define POLLREADFLAGS POLLRDNORM
1442 #        endif
1443 #      endif
1444 #    endif
1445 #  endif
1446 #endif
1447 #if defined(POLLOUT) && defined(POLLWRNORM)
1448 #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
1449 #else
1450 #  if defined(POLLOUT)
1451 #    define POLLWRITEFLAGS POLLOUT
1452 #  else
1453 #    if defined(POLLWRNORM)
1454 #      define POLLWRITEFLAGS POLLWRNORM
1455 #    endif
1456 #  endif
1457 #endif
1458 #ifdef POLLHUP
1459 #define POLLERRORS (POLLHUP|POLLERR)
1460 #else
1461 #define POLLERRORS POLLERR
1462 #endif
1463 #define RFD_ISSET(fd, rfd, index) \
1464   ((poll_fds[index].revents & POLLREADFLAGS) || \
1465   ((poll_fds[index].events & POLLREADFLAGS) && \
1466     (poll_fds[index].revents & POLLERRORS)))
1467 #define WFD_ISSET(fd, wfd, index) \
1468   ((poll_fds[index].revents & POLLWRITEFLAGS) || \
1469   ((poll_fds[index].events & POLLWRITEFLAGS) && \
1470     (poll_fds[index].revents & POLLERRORS)))
1471 #define RFD_SET(fdes, rfd, index, cptr) \
1472   do { \
1473     poll_fds[index].fd = fdes; \
1474     poll_cptr[index] = cptr; \
1475     poll_fds[index].events = POLLREADFLAGS; \
1476     added = TRUE; \
1477   } while(0)
1478 #define WFD_SET(fdes, wfd, index, cptr) \
1479   do { \
1480     poll_fds[index].fd = fdes; \
1481     poll_cptr[index] = cptr; \
1482     if (added) \
1483       poll_fds[index].events |= POLLWRITEFLAGS; \
1484     else \
1485     { \
1486       poll_fds[index].events = POLLWRITEFLAGS; \
1487       added = TRUE; \
1488     } \
1489   } while(0)
1490 /* This identical to WFD_SET() when used after a call to RFD_SET(): */
1491 #define RWFD_SET(fd, wfd, index) poll_fds[index].events |= POLLWRITEFLAGS
1492 /* [RW]FD_CLR_OUT() clears revents, not events */
1493 #define RFD_CLR_OUT(fd, rfd, index) poll_fds[index].revents &= ~POLLREADFLAGS
1494 #define WFD_CLR_OUT(fd, wfd, index) poll_fds[index].revents &= ~POLLWRITEFLAGS
1495 #define LOC_FD(index) (poll_fds[index].fd)
1496 #define LOC_CLIENTS(index) (poll_cptr[index])
1497 #define HIGHEST_INDEX (currfd_index - 1)
1498 #endif /* USE_POLL */
1499
1500 /*
1501  * read_packet
1502  *
1503  * Read a 'packet' of data from a connection and process it.  Read in 8k
1504  * chunks to give a better performance rating (for server connections).
1505  * Do some tricky stuff for client connections to make sure they don't do
1506  * any flooding >:-) -avalon
1507  */
1508 static int read_packet(aClient *cptr, fd_setp_t rfd)
1509 {
1510   size_t dolen = 0;
1511   int length = 0;
1512   int done;
1513
1514   if (RFD_ISSET(cptr->fd, rfd, rfd) &&
1515       !(IsUser(cptr) && DBufLength(&cptr->recvQ) > 6090))
1516   {
1517     errno = 0;
1518     length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
1519
1520     cptr->lasttime = now;
1521     if (cptr->lasttime > cptr->since)
1522       cptr->since = cptr->lasttime;
1523     cptr->flags &= ~(FLAGS_PINGSENT | FLAGS_NONL);
1524     /*
1525      * If not ready, fake it so it isnt closed
1526      */
1527     if (length == -1 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1528       return 1;
1529     if (length <= 0)
1530       return length;
1531   }
1532
1533   /*
1534    * For server connections, we process as many as we can without
1535    * worrying about the time of day or anything :)
1536    */
1537   if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
1538   {
1539     if (length > 0)
1540       if ((done = dopacket(cptr, readbuf, length)))
1541         return done;
1542   }
1543   else
1544   {
1545     /*
1546      * Before we even think of parsing what we just read, stick
1547      * it on the end of the receive queue and do it when its
1548      * turn comes around.
1549      */
1550     if (!dbuf_put(&cptr->recvQ, readbuf, length))
1551       return exit_client(cptr, cptr, &me, "dbuf_put fail");
1552
1553 #ifndef NOFLOODCONTROL
1554     if (IsUser(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD)
1555       return exit_client(cptr, cptr, &me, "Excess Flood");
1556 #endif
1557
1558     while (DBufLength(&cptr->recvQ) && !NoNewLine(cptr)
1559 #ifndef NOFLOODCONTROL
1560         && (IsTrusted(cptr) || cptr->since - now < 10)
1561 #endif
1562         )
1563     {
1564       /*
1565        * If it has become registered as a Server
1566        * then skip the per-message parsing below.
1567        */
1568       if (IsServer(cptr))
1569       {
1570         /*
1571          * XXX - this blindly deletes data if no cr/lf is received at
1572          * the end of a lot of messages and the data stored in the 
1573          * dbuf is greater than sizeof(readbuf)
1574          */
1575         dolen = dbuf_get(&cptr->recvQ, readbuf, sizeof(readbuf));
1576         if (0 == dolen)
1577           break;
1578         if ((done = dopacket(cptr, readbuf, dolen)))
1579           return done;
1580         break;
1581       }
1582       dolen = dbuf_getmsg(&cptr->recvQ, cptr->buffer, BUFSIZE);
1583       /*
1584        * Devious looking...whats it do ? well..if a client
1585        * sends a *long* message without any CR or LF, then
1586        * dbuf_getmsg fails and we pull it out using this
1587        * loop which just gets the next 512 bytes and then
1588        * deletes the rest of the buffer contents.
1589        * -avalon
1590        */
1591       if (0 == dolen)
1592       {
1593         if (DBufLength(&cptr->recvQ) < 510)
1594         {
1595           cptr->flags |= FLAGS_NONL;
1596           break;
1597         }
1598         DBufClear(&cptr->recvQ);
1599         break;
1600       }
1601       else if (CPTR_KILLED == client_dopacket(cptr, dolen))
1602         return CPTR_KILLED;
1603     }
1604   }
1605   return 1;
1606 }
1607
1608 /*
1609  * Check all connections for new connections and input data that is to be
1610  * processed. Also check for connections with data queued and whether we can
1611  * write it out.
1612  *
1613  * Don't ever use ZERO for `delay', unless you mean to poll and then
1614  * you have to have sleep/wait somewhere else in the code.--msa
1615  */
1616 int read_message(time_t delay)
1617 {
1618   Reg1 aClient *cptr;
1619   Reg2 int nfds;
1620   struct timeval wait;
1621 #ifdef  pyr
1622   struct timeval nowt;
1623   unsigned long us;
1624 #endif
1625   time_t delay2 = delay;
1626   unsigned long usec = 0;
1627   int res, length, fd, i;
1628   int auth = 0, ping = 0;
1629 #ifndef USE_POLL
1630   fd_set read_set, write_set;
1631 #else /* USE_POLL */
1632   unsigned int currfd_index = 0;
1633   unsigned int udpfdindex = 0;
1634   unsigned int resfdindex = 0;
1635   unsigned long timeout;
1636   int added;
1637 #endif /* USE_POLL */
1638
1639 #ifdef  pyr
1640   gettimeofday(&nowt, NULL);
1641   now = nowt.tv_sec;
1642 #endif
1643
1644   for (res = 0;;)
1645   {
1646 #ifndef USE_POLL
1647     FD_ZERO(&read_set);
1648     FD_ZERO(&write_set);
1649 #endif /* not USE_POLL */
1650     for (i = highest_fd; i >= 0; i--)
1651     {
1652 #ifdef USE_POLL
1653       added = FALSE;
1654 #endif /* USE_POLL */
1655       if (!(cptr = loc_clients[i]))
1656         continue;
1657       if (IsLog(cptr))
1658         continue;
1659       if (DoingAuth(cptr))
1660       {
1661         auth++;
1662         Debug((DEBUG_NOTICE, "auth on %p %d", cptr, i));
1663         RFD_SET(cptr->authfd, &read_set, currfd_index, cptr);
1664         if (cptr->flags & FLAGS_WRAUTH)
1665           RWFD_SET(cptr->authfd, &write_set, currfd_index);
1666       }
1667       if (IsPing(cptr))
1668       {
1669         ping++;
1670         Debug((DEBUG_NOTICE, "open ping on %p %d", cptr, i));
1671         if (!cptr->firsttime || now <= cptr->firsttime)
1672         {
1673           RFD_SET(i, &read_set, currfd_index, cptr);
1674           delay2 = 1;
1675           if (DoPing(cptr) && now > cptr->lasttime)
1676             RWFD_SET(i, &write_set, currfd_index);
1677         }
1678         else
1679         {
1680           del_queries((char *)cptr);
1681           end_ping(cptr);
1682         }
1683 #ifdef USE_POLL
1684         if (added)
1685           currfd_index++;
1686 #endif /* USE_POLL */
1687         continue;
1688       }
1689       if (DoingDNS(cptr) || DoingAuth(cptr))
1690       {
1691 #ifdef USE_POLL
1692         if (added)
1693           currfd_index++;
1694 #endif /* USE_POLL */
1695         continue;
1696       }
1697       if (IsMe(cptr) && IsListening(cptr))
1698         RFD_SET(i, &read_set, currfd_index, cptr);
1699       else if (!IsMe(cptr))
1700       {
1701         if (DBufLength(&cptr->recvQ) && delay2 > 2)
1702           delay2 = 1;
1703         if (DBufLength(&cptr->recvQ) < 4088)
1704           RFD_SET(i, &read_set, currfd_index, cptr);
1705         if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
1706             (cptr->listing && DBufLength(&cptr->sendQ) < 2048))
1707 #ifndef pyr
1708           WFD_SET(i, &write_set, currfd_index, cptr);
1709 #else /* pyr */
1710         {
1711           if (!(cptr->flags & FLAGS_BLOCKED))
1712             WFD_SET(i, &write_set, currfd_index, cptr);
1713           else
1714             delay2 = 0, usec = 500000;
1715         }
1716         if (now - cptr->lw.tv_sec && nowt.tv_usec - cptr->lw.tv_usec < 0)
1717           us = 1000000;
1718         else
1719           us = 0;
1720         us += nowt.tv_usec;
1721         if (us - cptr->lw.tv_usec > 500000)
1722           cptr->flags &= ~FLAGS_BLOCKED;
1723 #endif /* pyr */
1724       }
1725 #ifdef USE_POLL
1726       if (added)
1727         currfd_index++;
1728 #endif /* USE_POLL */
1729     }
1730
1731     if (udpfd >= 0)
1732     {
1733       RFD_SET(udpfd, &read_set, currfd_index, NULL);
1734 #ifdef USE_POLL
1735       udpfdindex = currfd_index;
1736       currfd_index++;
1737 #endif /* USE_POLL */
1738     }
1739     if (resfd >= 0)
1740     {
1741       RFD_SET(resfd, &read_set, currfd_index, NULL);
1742 #ifdef USE_POLL
1743       resfdindex = currfd_index;
1744       currfd_index++;
1745 #endif /* USE_POLL */
1746     }
1747
1748     wait.tv_sec = MIN(delay2, delay);
1749     wait.tv_usec = usec;
1750 #ifndef USE_POLL
1751 #ifdef  HPUX
1752     nfds = select(FD_SETSIZE, (int *)&read_set, (int *)&write_set, 0, &wait);
1753 #else
1754     nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
1755 #endif
1756 #else /* USE_POLL */
1757     timeout = (wait.tv_sec * 1000) + (wait.tv_usec / 1000);
1758     nfds = poll(poll_fds, currfd_index, timeout);
1759 #endif /* USE_POLL */
1760     now = time(NULL);
1761     if (nfds == -1 && errno == EINTR)
1762       return -1;
1763     else if (nfds >= 0)
1764       break;
1765     report_error("select %s: %s", &me);
1766     res++;
1767     if (res > 5)
1768       restart("too many select errors");
1769     sleep(10);
1770     now += 10;
1771   }
1772
1773   if (udpfd >= 0 && RFD_ISSET(udpfd, &read_set, udpfdindex))
1774   {
1775     polludp();
1776     nfds--;
1777     RFD_CLR_OUT(udpfd, &read_set, udpfdindex);
1778   }
1779   /*
1780    * Check fd sets for the ping fd's (if set and valid!) first
1781    * because these can not be processed using the normal loops below.
1782    * And we want them to be as fast as possible.
1783    * -Run
1784    */
1785   for (i = HIGHEST_INDEX; (ping > 0) && (i >= 0); i--)
1786   {
1787     if (!(cptr = LOC_CLIENTS(i)))
1788       continue;
1789     if (!IsPing(cptr))
1790       continue;
1791     ping--;
1792     if ((nfds > 0) && RFD_ISSET(cptr->fd, &read_set, i))
1793     {
1794       nfds--;
1795       RFD_CLR_OUT(cptr->fd, &read_set, i);
1796       read_ping(cptr);          /* This can RunFree(cptr) ! */
1797     }
1798     else if ((nfds > 0) && WFD_ISSET(cptr->fd, &write_set, i))
1799     {
1800       nfds--;
1801       cptr->lasttime = now;
1802       WFD_CLR_OUT(cptr->fd, &write_set, i);
1803       send_ping(cptr);          /* This can RunFree(cptr) ! */
1804     }
1805   }
1806   if (resfd >= 0 && RFD_ISSET(resfd, &read_set, resfdindex))
1807   {
1808     do_dns_async();
1809     nfds--;
1810     RFD_CLR_OUT(resfd, &read_set, resfdindex);
1811   }
1812   /*
1813    * Check fd sets for the auth fd's (if set and valid!) first
1814    * because these can not be processed using the normal loops below.
1815    * -avalon
1816    */
1817   for (i = HIGHEST_INDEX; (auth > 0) && (i >= 0); i--)
1818   {
1819     if (!(cptr = LOC_CLIENTS(i)))
1820       continue;
1821     if (cptr->authfd < 0)
1822       continue;
1823     auth--;
1824     if ((nfds > 0) && WFD_ISSET(cptr->authfd, &write_set, i))
1825     {
1826       nfds--;
1827       send_authports(cptr);
1828     }
1829     else if ((nfds > 0) && RFD_ISSET(cptr->authfd, &read_set, i))
1830     {
1831       nfds--;
1832       read_authports(cptr);
1833     }
1834   }
1835   for (i = HIGHEST_INDEX; i >= 0; i--)
1836     if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) &&
1837         IsListening(cptr))
1838     {
1839       RFD_CLR_OUT(i, &read_set, i);
1840       nfds--;
1841       cptr->lasttime = now;
1842       /*
1843        * There may be many reasons for error return, but
1844        * in otherwise correctly working environment the
1845        * probable cause is running out of file descriptors
1846        * (EMFILE, ENFILE or others?). The man pages for
1847        * accept don't seem to list these as possible,
1848        * although it's obvious that it may happen here.
1849        * Thus no specific errors are tested at this
1850        * point, just assume that connections cannot
1851        * be accepted until some old is closed first.
1852        */
1853       if ((fd = accept(LOC_FD(i), NULL, NULL)) < 0)
1854       {
1855         if (errno != EWOULDBLOCK)
1856           report_error("accept() failed%s: %s", NULL);
1857         break;
1858       }
1859 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECTS)
1860       {                         /* get an early log of all connections   --dl */
1861         static struct sockaddr_in peer;
1862         static int len;
1863         len = sizeof(peer);
1864         getpeername(fd, (struct sockaddr *)&peer, &len);
1865         syslog(LOG_DEBUG, "Conn: %s", inetntoa(peer.sin_addr));
1866       }
1867 #endif
1868       ircstp->is_ac++;
1869       if (fd >= MAXCLIENTS)
1870       {
1871         /* Don't send more messages then one every 10 minutes */
1872         static int count;
1873         static time_t last_time;
1874         ircstp->is_ref++;
1875         ++count;
1876         if (last_time < now - (time_t) 600)
1877         {
1878           if (count > 0)
1879           {
1880             if (!last_time)
1881               last_time = me.since;
1882             sendto_ops
1883                 ("All connections in use!  Had to refuse %d clients in the last "
1884                 STIME_T_FMT " minutes", count, (now - last_time) / 60);
1885           }
1886           else
1887             sendto_ops("All connections in use. (%s)", get_client_name(cptr,
1888                 TRUE));
1889           count = 0;
1890           last_time = now;
1891         }
1892         send(fd, "ERROR :All connections in use\r\n", 32, 0);
1893         close(fd);
1894         break;
1895       }
1896       /*
1897        * Use of add_connection (which never fails :) meLazy
1898        */
1899 #ifdef  UNIXPORT
1900       if (IsUnixSocket(cptr))
1901         add_unixconnection(cptr, fd);
1902       else
1903 #endif
1904       if (!add_connection(cptr, fd, ADCON_SOCKET))
1905         continue;
1906       nextping = now;
1907       if (!cptr->acpt)
1908         cptr->acpt = &me;
1909     }
1910
1911   for (i = HIGHEST_INDEX; i >= 0; i--)
1912   {
1913     if (!(cptr = LOC_CLIENTS(i)) || IsMe(cptr))
1914       continue;
1915 #ifdef USE_POLL
1916     if (DoingDNS(cptr) || DoingAuth(cptr) || !(cptr = loc_clients[LOC_FD(i)]))
1917       continue;
1918 #endif /* USE_POLL */
1919 #ifdef DEBUGMODE
1920     if (IsLog(cptr))
1921       continue;
1922 #endif
1923     if (WFD_ISSET(i, &write_set, i))
1924     {
1925       int write_err = 0;
1926       nfds--;
1927       /*
1928        *  ...room for writing, empty some queue then...
1929        */
1930       cptr->flags &= ~FLAGS_BLOCKED;
1931       if (IsConnecting(cptr))
1932         write_err = completed_connection(cptr);
1933       if (!write_err)
1934       {
1935         if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
1936           list_next_channels(cptr, 64);
1937         send_queued(cptr);
1938       }
1939       if (IsDead(cptr) || write_err)
1940       {
1941       deadsocket:
1942         if (RFD_ISSET(i, &read_set, i))
1943         {
1944           nfds--;
1945           RFD_CLR_OUT(i, &read_set, i);
1946         }
1947         exit_client(cptr, cptr, &me,
1948             IsDead(cptr) ? LastDeadComment(cptr) : strerror(get_sockerr(cptr)));
1949         continue;
1950       }
1951     }
1952     length = 1;                 /* for fall through case */
1953     if ((!NoNewLine(cptr) || RFD_ISSET(i, &read_set, i)) && !IsDead(cptr))
1954 #ifndef USE_POLL
1955       length = read_packet(cptr, &read_set);
1956 #else /* USE_POLL */
1957       length = read_packet(cptr, i);
1958 #endif /* USE_POLL */
1959 #if 0
1960     /* Bullshit, why would we want to flush sockets while using non-blocking?
1961      * This uses > 4% cpu! --Run */
1962     if (length > 0)
1963       flush_connections(LOC_FD(i));
1964 #endif
1965     if ((length != CPTR_KILLED) && IsDead(cptr))
1966       goto deadsocket;
1967     if (!RFD_ISSET(i, &read_set, i) && length > 0)
1968       continue;
1969     nfds--;
1970     readcalls++;
1971     if (length > 0)
1972       continue;
1973
1974     /*
1975      * ...hmm, with non-blocking sockets we might get
1976      * here from quite valid reasons, although.. why
1977      * would select report "data available" when there
1978      * wasn't... So, this must be an error anyway...  --msa
1979      * actually, EOF occurs when read() returns 0 and
1980      * in due course, select() returns that fd as ready
1981      * for reading even though it ends up being an EOF. -avalon
1982      */
1983     Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
1984
1985     if (length == CPTR_KILLED)
1986       continue;
1987
1988     if ((IsServer(cptr) || IsHandshake(cptr)) && errno == 0 && length == 0)
1989       exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
1990           get_client_name(cptr, FALSE), cptr->serv->last_error_msg);
1991     else
1992       exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
1993           get_client_name(cptr, FALSE), (length < 0) ?
1994           strerror(get_sockerr(cptr)) : "EOF from client");
1995   }
1996   return 0;
1997 }
1998
1999 /*
2000  * connect_server
2001  */
2002 int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp)
2003 {
2004   Reg1 struct sockaddr *svp;
2005   Reg2 aClient *cptr, *c2ptr;
2006   Reg3 char *s;
2007   int errtmp, len;
2008
2009   Debug((DEBUG_NOTICE, "Connect to %s[%s] @%s",
2010       aconf->name, aconf->host, inetntoa(aconf->ipnum)));
2011
2012   if ((c2ptr = FindClient(aconf->name)))
2013   {
2014     if (IsServer(c2ptr) || IsMe(c2ptr))
2015     {
2016       sendto_ops("Server %s already present from %s",
2017           aconf->name, c2ptr->from->name);
2018       if (by && IsUser(by) && !MyUser(by))
2019       {
2020 #ifndef NO_PROTOCOL9
2021         if (Protocol(by->from) < 10)
2022           sendto_one(by, ":%s NOTICE %s :Server %s already present from %s",
2023               me.name, by->name, aconf->name, c2ptr->from->name);
2024         else
2025 #endif
2026           sendto_one(by, "%s NOTICE %s%s :Server %s already present from %s",
2027               NumServ(&me), NumNick(by), aconf->name, c2ptr->from->name);
2028       }
2029       return -1;
2030     }
2031     else if (IsHandshake(c2ptr) || IsConnecting(c2ptr))
2032     {
2033       if (by && IsUser(by))
2034       {
2035         if (MyUser(by) || Protocol(by->from) < 10)
2036           sendto_one(by, ":%s NOTICE %s :Connection to %s already in progress",
2037               me.name, by->name, get_client_name(c2ptr, TRUE));
2038         else
2039           sendto_one(by,
2040               "%s NOTICE %s%s :Connection to %s already in progress",
2041               NumServ(&me), NumNick(by), get_client_name(c2ptr, TRUE));
2042       }
2043       return -1;
2044     }
2045   }
2046
2047   /*
2048    * If we dont know the IP# for this host and itis a hostname and
2049    * not a ip# string, then try and find the appropriate host record.
2050    */
2051   if ((!aconf->ipnum.s_addr)
2052 #ifdef UNIXPORT
2053       && ((aconf->host[2]) != '/')      /* needed for Unix domain -- dl */
2054 #endif
2055       )
2056   {
2057     Link lin;
2058
2059     lin.flags = ASYNC_CONNECT;
2060     lin.value.aconf = aconf;
2061     nextdnscheck = 1;
2062     s = strchr(aconf->host, '@');
2063     s++;                        /* should NEVER be NULL */
2064     if ((aconf->ipnum.s_addr = inet_addr(s)) == INADDR_NONE)
2065     {
2066       aconf->ipnum.s_addr = INADDR_ANY;
2067       hp = gethost_byname(s, &lin);
2068       Debug((DEBUG_NOTICE, "co_sv: hp %p ac %p na %s ho %s",
2069           hp, aconf, aconf->name, s));
2070       if (!hp)
2071         return 0;
2072       memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2073     }
2074   }
2075   cptr = make_client(NULL, STAT_UNKNOWN);
2076   cptr->hostp = hp;
2077   /*
2078    * Copy these in so we have something for error detection.
2079    */
2080   strncpy(cptr->name, aconf->name, sizeof(cptr->name) - 1);
2081   cptr->name[sizeof(cptr->name) - 1] = 0;
2082   strncpy(cptr->sockhost, aconf->host, HOSTLEN);
2083   cptr->sockhost[HOSTLEN] = 0;
2084
2085 #ifdef  UNIXPORT
2086   if (aconf->host[2] == '/')    /* (/ starts a 2), Unix domain -- dl */
2087     svp = connect_unix(aconf, cptr, &len);
2088   else
2089     svp = connect_inet(aconf, cptr, &len);
2090 #else
2091   svp = connect_inet(aconf, cptr, &len);
2092 #endif
2093
2094   if (!svp)
2095   {
2096     if (cptr->fd >= 0)
2097       close(cptr->fd);
2098     cptr->fd = -2;
2099     if (by && IsUser(by) && !MyUser(by))
2100     {
2101 #ifndef NO_PROTOCOL9
2102       if (Protocol(by->from) < 10)
2103         sendto_one(by, ":%s NOTICE %s :Couldn't connect to %s",
2104             me.name, by->name, get_client_name(cptr, TRUE));
2105       else
2106 #endif
2107         sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
2108             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2109     }
2110     free_client(cptr);
2111     return -1;
2112   }
2113
2114   set_non_blocking(cptr->fd, cptr);
2115   set_sock_opts(cptr->fd, cptr);
2116   signal(SIGALRM, dummy);
2117   alarm(4);
2118   if (connect(cptr->fd, svp, len) < 0 && errno != EINPROGRESS)
2119   {
2120     int err = get_sockerr(cptr);
2121     errtmp = errno;             /* other system calls may eat errno */
2122     alarm(0);
2123     report_error("Connect to host %s failed: %s", cptr);
2124     if (by && IsUser(by) && !MyUser(by))
2125     {
2126 #ifndef NO_PROTOCOL9
2127       if (Protocol(by->from) < 10)
2128         sendto_one(by, ":%s NOTICE %s :Connect to host %s failed: %s",
2129             me.name, by->name, get_client_name(cptr, TRUE), strerror(err));
2130       else
2131 #endif
2132         sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
2133             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE),
2134             strerror(err));
2135     }
2136     close(cptr->fd);
2137     cptr->fd = -2;
2138     free_client(cptr);
2139     errno = errtmp;
2140     if (errno == EINTR)
2141       errno = ETIMEDOUT;
2142     return -1;
2143   }
2144   alarm(0);
2145
2146   /*
2147    * Attach config entries to client here rather than in
2148    * completed_connection. This to avoid null pointer references
2149    * when name returned by gethostbyaddr matches no C lines
2150    * (could happen in 2.6.1a when host and servername differ).
2151    * No need to check access and do gethostbyaddr calls.
2152    * There must at least be one as we got here C line...  meLazy
2153    */
2154   attach_confs_host(cptr, aconf->host,
2155       CONF_NOCONNECT_SERVER | CONF_CONNECT_SERVER);
2156
2157   if (!find_conf_host(cptr->confs, aconf->host, CONF_NOCONNECT_SERVER) ||
2158       !find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
2159   {
2160     sendto_ops("Host %s is not enabled for connecting:no C/N-line",
2161         aconf->host);
2162     if (by && IsUser(by) && !MyUser(by))
2163     {
2164 #ifndef NO_PROTOCOL9
2165       if (Protocol(by->from) < 10)
2166         sendto_one(by,
2167             ":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
2168             me.name, by->name, get_client_name(cptr, TRUE));
2169       else
2170 #endif
2171         sendto_one(by,
2172             "%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
2173             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2174     }
2175     det_confs_butmask(cptr, 0);
2176     close(cptr->fd);
2177     cptr->fd = -2;
2178     free_client(cptr);
2179     return (-1);
2180   }
2181   /*
2182    * The socket has been connected or connect is in progress.
2183    */
2184   make_server(cptr);
2185   if (by && IsUser(by))
2186   {
2187     sprintf_irc(cptr->serv->by, "%s%s", NumNick(by));
2188     if (cptr->serv->user)
2189       free_user(cptr->serv->user, NULL);
2190     cptr->serv->user = by->user;
2191     by->user->refcnt++;
2192   }
2193   else
2194   {
2195     *cptr->serv->by = '\0';
2196     if (cptr->serv->user)
2197       free_user(cptr->serv->user, NULL);
2198     cptr->serv->user = NULL;
2199   }
2200   cptr->serv->up = &me;
2201   if (cptr->fd > highest_fd)
2202     highest_fd = cptr->fd;
2203   loc_clients[cptr->fd] = cptr;
2204   cptr->acpt = &me;
2205   SetConnecting(cptr);
2206
2207   get_sockhost(cptr, aconf->host);
2208   Count_newunknown(nrof);
2209   add_client_to_list(cptr);
2210   hAddClient(cptr);
2211   nextping = now;
2212
2213   return 0;
2214 }
2215
2216 static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
2217 {
2218   static struct sockaddr_in server;
2219   Reg3 struct hostent *hp;
2220
2221   /*
2222    * Might as well get sockhost from here, the connection is attempted
2223    * with it so if it fails its useless.
2224    */
2225   alarm(2);
2226   cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
2227   alarm(0);
2228   if (cptr->fd == -1 && errno == EAGAIN)
2229   {
2230     sendto_ops("opening stream socket to server %s: No more sockets",
2231         get_client_name(cptr, TRUE));
2232     return NULL;
2233   }
2234   if (cptr->fd == -1)
2235   {
2236     report_error("opening stream socket to server %s: %s", cptr);
2237     return NULL;
2238   }
2239   if (cptr->fd >= MAXCLIENTS)
2240   {
2241     sendto_ops("No more connections allowed (%s)", cptr->name);
2242     return NULL;
2243   }
2244   mysk.sin_port = 0;
2245   memset(&server, 0, sizeof(server));
2246   server.sin_family = AF_INET;
2247   get_sockhost(cptr, aconf->host);
2248
2249 #ifdef VIRTUAL_HOST
2250   mysk.sin_addr = vserv.sin_addr;
2251 #endif
2252
2253   /*
2254    * Bind to a local IP# (with unknown port - let unix decide) so
2255    * we have some chance of knowing the IP# that gets used for a host
2256    * with more than one IP#.
2257    */
2258   /* No we don't bind it, not all OS's can handle connecting with
2259    * an already bound socket, different ip# might occur anyway
2260    * leading to a freezing select() on this side for some time.
2261    * I had this on my Linux 1.1.88 --Run
2262    */
2263 #ifdef VIRTUAL_HOST
2264   /*
2265    * No, we do bind it if we have virtual host support. If we don't
2266    * explicitly bind it, it will default to IN_ADDR_ANY and we lose
2267    * due to the other server not allowing our base IP --smg
2268    */
2269   if (bind(cptr->fd, (struct sockaddr *)&mysk, sizeof(mysk)) == -1)
2270   {
2271     report_error("error binding to local port for %s: %s", cptr);
2272     return NULL;
2273   }
2274 #endif
2275
2276   /*
2277    * By this point we should know the IP# of the host listed in the
2278    * conf line, whether as a result of the hostname lookup or the ip#
2279    * being present instead. If we dont know it, then the connect fails.
2280    */
2281   if (isDigit(*aconf->host) && (aconf->ipnum.s_addr == INADDR_NONE))
2282     aconf->ipnum.s_addr = inet_addr(aconf->host);
2283   if (aconf->ipnum.s_addr == INADDR_NONE)
2284   {
2285     hp = cptr->hostp;
2286     if (!hp)
2287     {
2288       Debug((DEBUG_FATAL, "%s: unknown host", aconf->host));
2289       return NULL;
2290     }
2291     memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2292   }
2293   memcpy(&server.sin_addr, &aconf->ipnum, sizeof(struct in_addr));
2294   memcpy(&cptr->ip, &aconf->ipnum, sizeof(struct in_addr));
2295 #ifdef TESTNET
2296   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum) + 10000);
2297 #else
2298   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum));
2299 #endif
2300   *lenp = sizeof(server);
2301   return (struct sockaddr *)&server;
2302 }
2303
2304 #ifdef  UNIXPORT
2305 /*
2306  * connect_unix
2307  *
2308  * Build a socket structure for cptr so that it can connet to the unix
2309  * socket defined by the conf structure aconf.
2310  */
2311 static struct sockaddr *connect_unix(aConfItem *aconf, aClient *cptr, int *lenp)
2312 {
2313   static struct sockaddr_un sock;
2314
2315   alarm(2);
2316   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
2317   alarm(0);
2318   if (cptr->fd == -1 && errno == EAGAIN)
2319   {
2320     sendto_ops("Unix domain connect to host %s failed: No more sockets",
2321         get_client_name(cptr, TRUE));
2322     return NULL;
2323   }
2324   if (cptr->fd == -1)
2325   {
2326     report_error("Unix domain connect to host %s failed: %s", cptr);
2327     return NULL;
2328   }
2329   else if (cptr->fd >= MAXCLIENTS)
2330   {
2331     sendto_ops("No more connections allowed (%s)", cptr->name);
2332     return NULL;
2333   }
2334
2335   get_sockhost(cptr, aconf->host);
2336   /* +2 needed for working Unix domain -- dl */
2337   strncpy(sock.sun_path, aconf->host + 2, sizeof(sock.sun_path) - 1);
2338   sock.sun_path[sizeof(sock.sun_path) - 1] = 0;
2339   sock.sun_family = AF_UNIX;
2340   *lenp = strlen(sock.sun_path) + 2;
2341
2342   SetUnixSock(cptr);
2343   return (struct sockaddr *)&sock;
2344 }
2345
2346 #endif
2347
2348 /*
2349  * Find the real hostname for the host running the server (or one which
2350  * matches the server's name) and its primary IP#.  Hostname is stored
2351  * in the client structure passed as a pointer.
2352  */
2353 void get_my_name(aClient *cptr, char *name, size_t len)
2354 {
2355   static char tmp[HOSTLEN + 1];
2356 #if HAVE_UNAME
2357   struct utsname utsn;
2358 #endif
2359   struct hostent *hp;
2360   char *cname = cptr->name;
2361   size_t len2;
2362
2363   /*
2364    * Setup local socket structure to use for binding to.
2365    */
2366   memset(&mysk, 0, sizeof(mysk));
2367   mysk.sin_family = AF_INET;
2368
2369 #if HAVE_UNAME
2370   if (uname(&utsn) == -1)
2371     return;
2372   len2 = strlen(utsn.nodename);
2373   if (len2 > len)
2374     len2 = len;
2375   strncpy(name, utsn.nodename, len2);
2376 #else /* HAVE_GETHOSTNAME */
2377   if (gethostname(name, len) == -1)
2378     return;
2379 #endif
2380   name[len] = '\0';
2381
2382   /* Assume that a name containing '.' is a FQDN */
2383   if (!strchr(name, '.'))
2384     add_local_domain(name, len - strlen(name));
2385
2386   /*
2387    * If hostname gives another name than cname, then check if there is
2388    * a CNAME record for cname pointing to hostname. If so accept
2389    * cname as our name.   meLazy
2390    */
2391   if (BadPtr(cname))
2392     return;
2393   if (
2394 #ifndef NODNS
2395       /* I don't have DNS while testing, this delays too much */
2396       (hp = gethostbyname(cname)) ||
2397 #endif
2398       (hp = gethostbyname(name)))
2399   {
2400     const char *hname;
2401     int i = 0;
2402
2403     for (hname = hp->h_name; hname; hname = hp->h_aliases[i++])
2404     {
2405       strncpy(tmp, hname, sizeof(tmp) - 1);
2406       add_local_domain(tmp, sizeof(tmp) - 1 - strlen(tmp));
2407
2408       /*
2409        * Copy the matching name over and store the
2410        * 'primary' IP# as 'myip' which is used
2411        * later for making the right one is used
2412        * for connecting to other hosts.
2413        */
2414       if (!strCasediff(me.name, tmp))
2415         break;
2416     }
2417     if (strCasediff(me.name, tmp))
2418       strncpy(name, hp->h_name, len);
2419     else
2420       strncpy(name, tmp, len);
2421     memcpy(&mysk.sin_addr, hp->h_addr, sizeof(struct in_addr));
2422     Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
2423   }
2424   return;
2425 }
2426
2427 /*
2428  * Setup a UDP socket and listen for incoming packets
2429  */
2430 int setup_ping(void)
2431 {
2432   struct sockaddr_in from;
2433   int on = 1;
2434
2435   memset(&from, 0, sizeof(from));
2436 #ifdef VIRTUAL_HOST
2437   from.sin_addr = vserv.sin_addr;
2438 #else
2439   from.sin_addr.s_addr = htonl(INADDR_ANY);
2440 #endif
2441 #ifdef TESTNET
2442   from.sin_port = htons(atoi(UDP_PORT) + 10000);
2443 #else
2444   from.sin_port = htons(atoi(UDP_PORT));
2445 #endif
2446   from.sin_family = AF_INET;
2447
2448   if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2449   {
2450     Debug((DEBUG_ERROR, "socket udp : %s", strerror(errno)));
2451     return -1;
2452   }
2453   if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR,
2454       (OPT_TYPE *)&on, sizeof(on)) == -1)
2455   {
2456 #ifdef  USE_SYSLOG
2457     syslog(LOG_ERR, "setsockopt udp fd %d : %m", udpfd);
2458 #endif
2459     Debug((DEBUG_ERROR, "setsockopt so_reuseaddr : %s", strerror(errno)));
2460     close(udpfd);
2461     udpfd = -1;
2462     return -1;
2463   }
2464   on = 0;
2465   setsockopt(udpfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on));
2466   if (bind(udpfd, (struct sockaddr *)&from, sizeof(from)) == -1)
2467   {
2468 #ifdef  USE_SYSLOG
2469     syslog(LOG_ERR, "bind udp.%d fd %d : %m", from.sin_port, udpfd);
2470 #endif
2471     Debug((DEBUG_ERROR, "bind : %s", strerror(errno)));
2472     close(udpfd);
2473     udpfd = -1;
2474     return -1;
2475   }
2476   if (fcntl(udpfd, F_SETFL, FNDELAY) == -1)
2477   {
2478     Debug((DEBUG_ERROR, "fcntl fndelay : %s", strerror(errno)));
2479     close(udpfd);
2480     udpfd = -1;
2481     return -1;
2482   }
2483   return udpfd;
2484 }
2485
2486 /*
2487  * max # of pings set to 15/sec.
2488  */
2489 static void polludp(void)
2490 {
2491   Reg1 char *s;
2492   struct sockaddr_in from;
2493   int n;
2494   size_t fromlen = sizeof(from);
2495   static time_t last = 0;
2496   static int cnt = 0, mlen = 0;
2497
2498   /*
2499    * find max length of data area of packet.
2500    */
2501   if (!mlen)
2502   {
2503     mlen = sizeof(readbuf) - strlen(me.name) - strlen(version);
2504     mlen -= 6;
2505     if (mlen < 0)
2506       mlen = 0;
2507   }
2508   Debug((DEBUG_DEBUG, "udp poll"));
2509
2510   n = recvfrom(udpfd, readbuf, mlen, 0, (struct sockaddr *)&from, &fromlen);
2511   if (now == last)
2512     if (++cnt > 14)
2513       return;
2514   cnt = 0;
2515   last = now;
2516
2517   if (n == -1)
2518   {
2519     if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
2520       return;
2521     else
2522     {
2523       report_error("udp port recvfrom (%s): %s", &me);
2524       return;
2525     }
2526   }
2527   ircstp->is_udp++;
2528   if (n < 19)
2529     return;
2530
2531   s = readbuf + n;
2532   /*
2533    * attach my name and version for the reply
2534    */
2535   *readbuf |= 1;
2536   strcpy(s, me.name);
2537   s += strlen(s) + 1;
2538   strcpy(s, version);
2539   s += strlen(s);
2540   sendto(udpfd, readbuf, s - readbuf, 0,
2541       (struct sockaddr *)&from, sizeof(from));
2542   return;
2543 }
2544
2545 /*
2546  * do_dns_async
2547  *
2548  * Called when the fd returned from init_resolver() has been selected for
2549  * reading.
2550  */
2551 static void do_dns_async(void)
2552 {
2553   static Link ln;
2554   aClient *cptr;
2555   aConfItem *aconf;
2556   struct hostent *hp;
2557
2558   ln.flags = ASYNC_NONE;
2559   hp = get_res((char *)&ln);
2560
2561   Debug((DEBUG_DNS, "%p = get_res(%d,%p)", hp, ln.flags, ln.value.cptr));
2562
2563   switch (ln.flags)
2564   {
2565     case ASYNC_NONE:
2566       /*
2567        * No reply was processed that was outstanding or had a client
2568        * still waiting.
2569        */
2570       break;
2571     case ASYNC_CLIENT:
2572       if ((cptr = ln.value.cptr))
2573       {
2574         del_queries((char *)cptr);
2575         ClearDNS(cptr);
2576         if (!DoingAuth(cptr))
2577           SetAccess(cptr);
2578         cptr->hostp = hp;
2579       }
2580       break;
2581     case ASYNC_CONNECT:
2582       aconf = ln.value.aconf;
2583       if (hp && aconf)
2584       {
2585         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2586         connect_server(aconf, NULL, hp);
2587       }
2588       else
2589         sendto_ops("Connect to %s failed: host lookup",
2590             (aconf) ? aconf->host : "unknown");
2591       break;
2592     case ASYNC_PING:
2593       cptr = ln.value.cptr;
2594       del_queries((char *)cptr);
2595       if (hp)
2596       {
2597         memcpy(&cptr->ip, hp->h_addr, sizeof(struct in_addr));
2598         if (ping_server(cptr) == -1)
2599           end_ping(cptr);
2600       }
2601       else
2602       {
2603         sendto_ops("Udp ping to %s failed: host lookup", cptr->sockhost);
2604         end_ping(cptr);
2605       }
2606       break;
2607     case ASYNC_CONF:
2608       aconf = ln.value.aconf;
2609       if (hp && aconf)
2610         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2611       break;
2612     default:
2613       break;
2614   }
2615 }