Author: Bleep <tomh@inxpress.net>
[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) ? cptr->name : "";
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           cptr->name);
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     server.sin_addr = vserv.sin_addr;
296 #endif
297 #ifdef TESTNET
298     server.sin_port = htons(port + 10000);
299 #else
300     server.sin_port = htons(port);
301 #endif
302     if (bind(cptr->fd, (struct sockaddr *)&server, sizeof(server)) == -1)
303     {
304       report_error("binding stream socket %s: %s", cptr);
305       close(cptr->fd);
306       return -1;
307     }
308   }
309   if (getsockname(cptr->fd, (struct sockaddr *)&server, &len))
310   {
311     report_error("getsockname failed for %s: %s", cptr);
312     close(cptr->fd);
313     return -1;
314   }
315
316   if (cptr == &me)              /* KLUDGE to get it work... */
317   {
318     char buf[1024];
319
320 #ifdef TESTNET
321     sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
322         ntohs(server.sin_port) - 10000);
323 #else
324     sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*",
325         ntohs(server.sin_port));
326 #endif
327     write(1, buf, strlen(buf));
328   }
329   if (cptr->fd > highest_fd)
330     highest_fd = cptr->fd;
331   cptr->ip.s_addr = inet_addr(ipname);
332 #ifdef TESTNET
333   cptr->port = ntohs(server.sin_port) - 10000;
334 #else
335   cptr->port = ntohs(server.sin_port);
336 #endif
337   listen(cptr->fd, 128);        /* Use listen port backlog of 128 */
338   loc_clients[cptr->fd] = cptr;
339
340   return 0;
341 }
342
343 #ifdef  UNIXPORT
344 /*
345  * unixport
346  *
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).
352  */
353 int unixport(aClient *cptr, char *path, unsigned short int port)
354 {
355   struct sockaddr_un un;
356
357   alarm(2);
358   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
359   alarm(0);
360   if (cptr->fd == -1 && errno == EAGAIN)
361   {
362     sendto_ops("error opening unix domain socket %s: No more sockets",
363         cptr->name);
364     return -1;
365   }
366   if (cptr->fd == -1)
367   {
368     report_error("error opening unix domain socket %s: %s", cptr);
369     return -1;
370   }
371   else if (cptr->fd >= MAXCLIENTS)
372   {
373     sendto_ops("No more connections allowed (%s)", cptr->name);
374     close(cptr->fd);
375     cptr->fd = -1;
376     return -1;
377   }
378
379   un.sun_family = AF_UNIX;
380 #if HAVE_MKDIR
381   mkdir(path, 0755);
382 #else
383   if (chmod(path, 0755) == -1)
384   {
385     sendto_ops("error 'chmod 0755 %s': %s", path, strerror(errno));
386 #ifdef USE_SYSLOG
387     syslog(LOG_WARNING, "error 'chmod 0755 %s': %s", path, strerror(errno));
388 #endif
389     close(cptr->fd);
390     cptr->fd = -1;
391     return -1;
392   }
393 #endif
394   sprintf_irc(unixpath, "%s/%u", path, port);
395   unlink(unixpath);
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);
399   errno = 0;
400   get_sockhost(cptr, unixpath);
401
402   if (bind(cptr->fd, (struct sockaddr *)&un, strlen(unixpath) + 2) == -1)
403   {
404     report_error("error binding unix socket %s: %s", cptr);
405     close(cptr->fd);
406     return -1;
407   }
408   if (cptr->fd > highest_fd)
409     highest_fd = cptr->fd;
410   listen(cptr->fd, 5);
411   chmod(unixpath, 0777);
412   cptr->flags |= FLAGS_UNIX;
413   cptr->port = 0;
414   loc_clients[cptr->fd] = cptr;
415
416   return 0;
417 }
418 #endif
419
420 /*
421  * add_listener
422  *
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).
425  */
426 int add_listener(aConfItem *aconf)
427 {
428   aClient *cptr;
429
430   cptr = make_client(NULL, STAT_ME);
431   cptr->flags = FLAGS_LISTEN;
432   cptr->acpt = cptr;
433   cptr->from = cptr;
434   strncpy(cptr->name, aconf->host, sizeof(cptr->name) - 1);
435   cptr->name[sizeof(cptr->name) - 1] = 0;
436 #ifdef  UNIXPORT
437   if (*aconf->host == '/')
438   {
439     if (unixport(cptr, aconf->host, aconf->port))
440       cptr->fd = -2;
441   }
442   else
443 #endif
444   if (inetport(cptr, aconf->host, aconf->port))
445     cptr->fd = -2;
446
447   if (cptr->fd >= 0)
448   {
449     cptr->confs = make_link();
450     cptr->confs->next = NULL;
451     cptr->confs->value.aconf = aconf;
452     set_non_blocking(cptr->fd, cptr);
453   }
454   else
455     free_client(cptr);
456   return 0;
457 }
458
459 /*
460  * close_listeners
461  *
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.
465  */
466 void close_listeners(void)
467 {
468   Reg1 aClient *cptr;
469   Reg2 int i;
470   Reg3 aConfItem *aconf;
471
472   /*
473    * close all 'extra' listening ports we have and unlink the file
474    * name if it was a unix socket.
475    */
476   for (i = highest_fd; i >= 0; i--)
477   {
478     if (!(cptr = loc_clients[i]))
479       continue;
480     if (!IsMe(cptr) || cptr == &me || !IsListening(cptr))
481       continue;
482     aconf = cptr->confs->value.aconf;
483
484     if (IsIllegal(aconf) && aconf->clients == 0)
485     {
486 #ifdef  UNIXPORT
487       if (IsUnixSocket(cptr))
488       {
489         sprintf_irc(unixpath, "%s/%u", aconf->host, aconf->port);
490         unlink(unixpath);
491       }
492 #endif
493       close_connection(cptr);
494     }
495   }
496 }
497
498 /*
499  * init_sys
500  */
501 void init_sys(void)
502 {
503   Reg1 int fd;
504 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
505   struct rlimit limit;
506
507   if (!getrlimit(RLIMIT_FD_MAX, &limit))
508   {
509 #ifdef  pyr
510     if (limit.rlim_cur < MAXCONNECTIONS)
511 #else
512     if (limit.rlim_max < MAXCONNECTIONS)
513 #endif
514     {
515       fprintf(stderr, "ircd fd table too big\n");
516       fprintf(stderr, "Hard Limit: " LIMIT_FMT " IRC max: %d\n",
517 #ifdef pyr
518           limit.rlim_cur,
519 #else
520           limit.rlim_max,
521 #endif
522           (int)MAXCONNECTIONS);
523       fprintf(stderr, "Fix MAXCONNECTIONS\n");
524       exit(-1);
525     }
526 #ifndef pyr
527     limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
528     if (setrlimit(RLIMIT_FD_MAX, &limit) == -1)
529     {
530       fprintf(stderr, "error setting max fd's to " LIMIT_FMT "\n",
531           limit.rlim_cur);
532       exit(-1);
533     }
534 #endif
535   }
536 #endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
537 #ifdef DEBUGMODE
538   if (1)
539   {
540     static char logbuf[BUFSIZ];
541 #if SETVBUF_REVERSED
542     setvbuf(stderr, _IOLBF, logbuf, sizeof(logbuf));
543 #else
544     setvbuf(stderr, logbuf, _IOLBF, sizeof(logbuf));
545 #endif
546   }
547 #endif
548
549   for (fd = 3; fd < MAXCONNECTIONS; fd++)
550   {
551     close(fd);
552     loc_clients[fd] = NULL;
553   }
554   loc_clients[1] = NULL;
555   close(1);
556
557   if (bootopt & BOOT_TTY)       /* debugging is going to a tty */
558     goto init_dgram;
559   if (!(bootopt & BOOT_DEBUG))
560     close(2);
561
562   if (((bootopt & BOOT_CONSOLE) || isatty(0)) &&
563       !(bootopt & BOOT_INETD))
564   {
565     if (fork())
566       exit(0);
567     running_in_background = 1;
568 #ifdef TIOCNOTTY
569     if ((fd = open("/dev/tty", O_RDWR)) >= 0)
570     {
571       ioctl(fd, TIOCNOTTY, (char *)NULL);
572       close(fd);
573     }
574 #endif
575 #if defined(HPUX) || defined(SOL2) || defined(_SEQUENT_) || \
576     defined(_POSIX_SOURCE) || defined(SVR4)
577     setsid();
578 #else
579     setpgid(0, 0);
580 #endif
581     close(0);                   /* fd 0 opened by inetd */
582     loc_clients[0] = NULL;
583   }
584 init_dgram:
585   resfd = init_resolver();
586
587   return;
588 }
589
590 void write_pidfile(void)
591 {
592 #ifdef PPATH
593   int fd;
594   char buff[20];
595   if ((fd = open(PPATH, O_CREAT | O_WRONLY, 0600)) >= 0)
596   {
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));
601     close(fd);
602     return;
603   }
604 #ifdef  DEBUGMODE
605   else
606     Debug((DEBUG_NOTICE, "Error opening pid file \"%s\": %s",
607         PPATH, strerror(errno)));
608 #endif
609 #endif
610 }
611
612 /*
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.
616  */
617 static int check_init(aClient *cptr, char *sockn)
618 {
619   struct sockaddr_in sk;
620   size_t len = sizeof(struct sockaddr_in);
621   sockn[HOSTLEN] = 0;
622
623 #ifdef  UNIXPORT
624   if (IsUnixSocket(cptr))
625   {
626     strncpy(sockn, cptr->acpt->sockhost, HOSTLEN);
627     get_sockhost(cptr, sockn);
628     return 0;
629   }
630 #endif
631
632   /* If descriptor is a tty, special checking... */
633   if (isatty(cptr->fd))
634   {
635     strncpy(sockn, me.name, HOSTLEN);
636     memset(&sk, 0, sizeof(struct sockaddr_in));
637   }
638   else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
639   {
640     report_error("connect failure: %s %s", cptr);
641     return -1;
642   }
643   strcpy(sockn, inetntoa(sk.sin_addr));
644   if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
645   {
646     cptr->hostp = NULL;
647     strncpy(sockn, me.name, HOSTLEN);
648   }
649   memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
650 #ifdef TESTNET
651   cptr->port = ntohs(sk.sin_port) - 10000;
652 #else
653   cptr->port = ntohs(sk.sin_port);
654 #endif
655
656   return 0;
657 }
658
659 /*
660  * Ordinary client access check. Look for conf lines which have the same
661  * status as the flags passed.
662  */
663 enum AuthorizationCheckResult check_client(aClient *cptr)
664 {
665   static char sockname[HOSTLEN + 1];
666   Reg2 struct hostent *hp = NULL;
667   Reg3 int i;
668   enum AuthorizationCheckResult acr;
669
670   ClearAccess(cptr);
671   Debug((DEBUG_DNS, "ch_cl: check access for %s[%s]",
672       cptr->name, inetntoa(cptr->ip)));
673
674   if (check_init(cptr, sockname))
675     return ACR_BAD_SOCKET;
676
677   if (!IsUnixSocket(cptr))
678     hp = cptr->hostp;
679   /*
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.
682    */
683   if (hp)
684   {
685     for (i = 0; hp->h_addr_list[i]; i++)
686       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
687         break;
688     if (!hp->h_addr_list[i])
689     {
690       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
691           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
692       hp = NULL;
693     }
694   }
695
696   if ((acr = attach_Iline(cptr, hp, sockname)))
697   {
698     Debug((DEBUG_DNS, "ch_cl: access denied: %s[%s]", cptr->name, sockname));
699     return acr;
700   }
701
702   Debug((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
703
704   if (inet_netof(cptr->ip) == IN_LOOPBACKNET || IsUnixSocket(cptr) ||
705       inet_netof(cptr->ip) == inet_netof(mysk.sin_addr))
706   {
707     ircstp->is_loc++;
708     cptr->flags |= FLAGS_LOCAL;
709   }
710   return ACR_OK;
711 }
712
713 #define CFLAG   CONF_CONNECT_SERVER
714 #define NFLAG   CONF_NOCONNECT_SERVER
715
716 /*
717  * check_server()
718  *
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
723  * C/N line.
724  *
725  * Returns
726  *  0 = Success
727  * -1 = Access denied
728  * -2 = Bad socket.
729  */
730 int check_server(aClient *cptr)
731 {
732   Reg1 const char *name;
733   Reg2 aConfItem *c_conf = NULL, *n_conf = NULL;
734   struct hostent *hp = NULL;
735   Link *lp;
736   char abuff[HOSTLEN + USERLEN + 2];
737   char sockname[HOSTLEN + 1], fullname[HOSTLEN + 1];
738   int i;
739
740   name = cptr->name;
741   Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", name, cptr->sockhost));
742
743   if (IsUnknown(cptr) && !attach_confs(cptr, name, CFLAG | NFLAG))
744   {
745     Debug((DEBUG_DNS, "No C/N lines for %s", name));
746     return -1;
747   }
748   lp = cptr->confs;
749   /*
750    * We initiated this connection so the client should have a C and N
751    * line already attached after passing through the connec_server()
752    * function earlier.
753    */
754   if (IsConnecting(cptr) || IsHandshake(cptr))
755   {
756     c_conf = find_conf(lp, name, CFLAG);
757     n_conf = find_conf(lp, name, NFLAG);
758     if (!c_conf || !n_conf)
759     {
760       sendto_ops("Connecting Error: %s", name);
761       det_confs_butmask(cptr, 0);
762       return -1;
763     }
764   }
765 #ifdef  UNIXPORT
766   if (IsUnixSocket(cptr))
767   {
768     if (!c_conf)
769       c_conf = find_conf(lp, name, CFLAG);
770     if (!n_conf)
771       n_conf = find_conf(lp, name, NFLAG);
772   }
773 #endif
774
775   /*
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.
779    */
780   if (!IsUnixSocket(cptr) && !cptr->hostp)
781   {
782     Reg1 aConfItem *aconf;
783
784     aconf = count_cnlines(lp);
785     if (aconf)
786     {
787       Reg1 char *s;
788       Link lin;
789
790       /*
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.
795        */
796       ClearAccess(cptr);
797       lin.value.aconf = aconf;
798       lin.flags = ASYNC_CONF;
799       nextdnscheck = 1;
800       if ((s = strchr(aconf->host, '@')))
801         s++;
802       else
803         s = aconf->host;
804       Debug((DEBUG_DNS, "sv_ci:cache lookup (%s)", s));
805       hp = gethost_byname(s, &lin);
806     }
807   }
808
809   lp = cptr->confs;
810
811   ClearAccess(cptr);
812   if (check_init(cptr, sockname))
813     return -2;
814
815 check_serverback:
816   if (hp)
817   {
818     for (i = 0; hp->h_addr_list[i]; i++)
819       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
820         break;
821     if (!hp->h_addr_list[i])
822     {
823       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
824           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
825       hp = NULL;
826     }
827   }
828   else if (cptr->hostp)
829   {
830     hp = cptr->hostp;
831     goto check_serverback;
832   }
833
834   if (hp)
835     /*
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#.
838      */
839     for (i = 0, name = hp->h_name; name; name = hp->h_aliases[i++])
840     {
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);
846       if (!c_conf)
847         c_conf = find_conf_host(lp, abuff, CFLAG);
848       if (!n_conf)
849         n_conf = find_conf_host(lp, abuff, NFLAG);
850       if (c_conf && n_conf)
851       {
852         get_sockhost(cptr, fullname);
853         break;
854       }
855     }
856   name = cptr->name;
857
858   /*
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'.
862    */
863   if (IsUnknown(cptr) && (!c_conf || !n_conf))
864   {
865     sprintf_irc(abuff, "%s@%s", cptr->username, sockname);
866     if (!c_conf)
867       c_conf = find_conf_host(lp, abuff, CFLAG);
868     if (!n_conf)
869       n_conf = find_conf_host(lp, abuff, NFLAG);
870   }
871   /*
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
875    */
876   if (!hp)
877   {
878     if (!c_conf)
879       c_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, CFLAG);
880     if (!n_conf)
881       n_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, NFLAG);
882   }
883   else
884     for (i = 0; hp->h_addr_list[i]; i++)
885     {
886       if (!c_conf)
887         c_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, CFLAG);
888       if (!n_conf)
889         n_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, NFLAG);
890     }
891   /*
892    * detach all conf lines that got attached by attach_confs()
893    */
894   det_confs_butmask(cptr, 0);
895   /*
896    * if no C or no N lines, then deny access
897    */
898   if (!c_conf || !n_conf)
899   {
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));
903     return -1;
904   }
905   /*
906    * attach the C and N lines to the client structure for later use.
907    */
908   attach_conf(cptr, n_conf);
909   attach_conf(cptr, c_conf);
910   attach_confs(cptr, name, CONF_HUB | CONF_LEAF | CONF_UWORLD);
911
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);
916
917   Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", name, cptr->sockhost));
918   return 0;
919 }
920 #undef  CFLAG
921 #undef  NFLAG
922
923 /*
924  * completed_connection
925  *
926  * Complete non-blocking connect()-sequence. Check access and
927  * terminate connection, if trouble detected.
928  *
929  * Return  TRUE, if successfully completed
930  *        FALSE, if failed and ClientExit
931  */
932 static int completed_connection(aClient *cptr)
933 {
934   aConfItem *aconf;
935   time_t newts;
936   aClient *acptr;
937   int i;
938
939   aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
940   if (!aconf)
941   {
942     sendto_ops("Lost C-Line for %s", cptr->name);
943     return -1;
944   }
945   if (!BadPtr(aconf->passwd))
946     sendto_one(cptr, "PASS :%s", aconf->passwd);
947
948   aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
949   if (!aconf)
950   {
951     sendto_ops("Lost N-Line for %s", cptr->name);
952     return -1;
953   }
954   make_server(cptr);
955   /* Create a unique timestamp */
956   newts = TStime();
957   for (i = highest_fd; i >= 0; i--)
958   {
959     if (!(acptr = loc_clients[i]) || (!IsServer(acptr) && !IsHandshake(acptr)))
960       continue;
961     if (acptr->serv->timestamp >= newts)
962       newts = acptr->serv->timestamp + 1;
963   }
964   cptr->serv->timestamp = newts;
965   SetHandshake(cptr);
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);
972   if (!IsDead(cptr))
973     start_auth(cptr);
974
975   return (IsDead(cptr)) ? -1 : 0;
976 }
977
978 /*
979  * close_connection
980  *
981  * Close the physical connection. This function must make
982  * MyConnect(cptr) == FALSE, and set cptr->from == NULL.
983  */
984 void close_connection(aClient *cptr)
985 {
986   Reg1 aConfItem *aconf;
987   Reg2 int i, j;
988   int empty = cptr->fd;
989
990   if (IsServer(cptr))
991   {
992     ircstp->is_sv++;
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)
999     {
1000       ircstp->is_sks += (ircstp->is_sbs >> 10);
1001       ircstp->is_sbs &= 0x3ff;
1002     }
1003     if (ircstp->is_sbr > 1023)
1004     {
1005       ircstp->is_skr += (ircstp->is_sbr >> 10);
1006       ircstp->is_sbr &= 0x3ff;
1007     }
1008   }
1009   else if (IsUser(cptr))
1010   {
1011     ircstp->is_cl++;
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)
1018     {
1019       ircstp->is_cks += (ircstp->is_cbs >> 10);
1020       ircstp->is_cbs &= 0x3ff;
1021     }
1022     if (ircstp->is_cbr > 1023)
1023     {
1024       ircstp->is_ckr += (ircstp->is_cbr >> 10);
1025       ircstp->is_cbr &= 0x3ff;
1026     }
1027   }
1028   else
1029     ircstp->is_ni++;
1030
1031   /*
1032    * Remove outstanding DNS queries.
1033    */
1034   del_queries((char *)cptr);
1035   /*
1036    * If the connection has been up for a long amount of time, schedule
1037    * a 'quick' reconnect, else reset the next-connect cycle.
1038    */
1039
1040   if ((aconf = find_conf_exact(cptr->name, cptr->username,
1041       cptr->sockhost, CONF_CONNECT_SERVER)))
1042   {
1043     /*
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.
1048      */
1049     aconf->hold = now;
1050     aconf->hold += (aconf->hold - cptr->since > HANGONGOODLINK) ?
1051         HANGONRETRYDELAY : ConfConFreq(aconf);
1052     if (nextconnect > aconf->hold)
1053       nextconnect = aconf->hold;
1054   }
1055
1056   if (cptr->authfd >= 0)
1057     close(cptr->authfd);
1058
1059   if (cptr->fd >= 0)
1060   {
1061     flush_connections(cptr->fd);
1062     loc_clients[cptr->fd] = NULL;
1063     close(cptr->fd);
1064     cptr->fd = -2;
1065   }
1066
1067   DBufClear(&cptr->sendQ);
1068   DBufClear(&cptr->recvQ);
1069   memset(cptr->passwd, 0, sizeof(cptr->passwd));
1070   set_snomask(cptr, 0, SNO_SET);
1071   /*
1072    * Clean up extra sockets from P-lines which have been discarded.
1073    */
1074   if (cptr->acpt != &me && cptr->acpt != cptr)
1075   {
1076     aconf = cptr->acpt->confs->value.aconf;
1077     if (aconf->clients > 0)
1078       aconf->clients--;
1079     if (!aconf->clients && IsIllegal(aconf))
1080       close_connection(cptr->acpt);
1081   }
1082
1083   for (; highest_fd > 0; highest_fd--)
1084     if (loc_clients[highest_fd])
1085       break;
1086
1087   det_confs_butmask(cptr, 0);
1088
1089   /*
1090    * fd remap to keep loc_clients[i] filled at the bottom.
1091    */
1092   if (empty > 0)
1093     if ((j = highest_fd) > (i = empty) && !IsLog(loc_clients[j]))
1094     {
1095       if (IsListening(loc_clients[j]))
1096         return;
1097       if (dup2(j, i) == -1)
1098         return;
1099       loc_clients[i] = loc_clients[j];
1100       loc_clients[i]->fd = i;
1101       loc_clients[j] = NULL;
1102       close(j);
1103       while (!loc_clients[highest_fd])
1104         highest_fd--;
1105     }
1106
1107   return;
1108 }
1109
1110 /*
1111  *  set_sock_opts
1112  */
1113 static void set_sock_opts(int fd, aClient *cptr)
1114 {
1115   size_t opt;
1116 #ifdef SO_REUSEADDR
1117   opt = 1;
1118   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1119       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1120     report_error("setsockopt(SO_REUSEADDR) %s: %s", cptr);
1121 #endif
1122 #ifdef  SO_USELOOPBACK
1123   opt = 1;
1124   if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK,
1125       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1126     report_error("setsockopt(SO_USELOOPBACK) %s: %s", cptr);
1127 #endif
1128 #ifdef  SO_RCVBUF
1129   opt = 8192;
1130   if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1131     report_error("setsockopt(SO_RCVBUF) %s: %s", cptr);
1132 #endif
1133 #ifdef SO_SNDBUF
1134 #ifdef _SEQUENT_
1135 /*
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).
1138  */
1139   opt = 8192;
1140 #else
1141   opt = 8192;
1142 #endif
1143   if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1144     report_error("setsockopt(SO_SNDBUF) %s: %s", cptr);
1145 #endif
1146 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
1147   {
1148     char *s = readbuf, *t = readbuf + sizeof(readbuf) / 2;
1149
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)
1154     {
1155       for (*readbuf = '\0'; opt > 0; opt--, s += 3)
1156         sprintf(s, "%02x:", *t++);
1157       *s = '\0';
1158       sendto_ops("Connection %s using IP opts: (%s)",
1159           get_client_name(cptr, FALSE), readbuf);
1160     }
1161     if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
1162       report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
1163   }
1164 #endif
1165 }
1166
1167 int get_sockerr(aClient *cptr)
1168 {
1169   int errtmp = errno, err = 0;
1170   size_t len = sizeof(err);
1171 #if defined(SO_ERROR) && !defined(SOL2)
1172   if (cptr->fd >= 0)
1173     if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
1174       if (err)
1175         errtmp = err;
1176 #endif
1177   return errtmp;
1178 }
1179
1180 /*
1181  * set_non_blocking
1182  *
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...)
1188  */
1189 void set_non_blocking(int fd, aClient *cptr)
1190 {
1191   int res;
1192 #ifndef NBLOCK_SYSV
1193   int nonb = 0;
1194 #endif
1195
1196   /*
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.
1201    */
1202 #ifdef  NBLOCK_POSIX
1203   nonb |= O_NONBLOCK;
1204 #endif
1205 #ifdef  NBLOCK_BSD
1206   nonb |= O_NDELAY;
1207 #endif
1208 #ifdef  NBLOCK_SYSV
1209   /* This portion of code might also apply to NeXT. -LynX */
1210   res = 1;
1211
1212   if (ioctl(fd, FIONBIO, &res) < 0)
1213     report_error("ioctl(fd,FIONBIO) failed for %s: %s", cptr);
1214 #else
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);
1219 #endif
1220   return;
1221 }
1222
1223 extern unsigned short server_port;
1224
1225 /*
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.
1230  */
1231 aClient *add_connection(aClient *cptr, int fd, int type)
1232 {
1233   Link lin;
1234   aClient *acptr;
1235   aConfItem *aconf = NULL;
1236   acptr =
1237       make_client(NULL,
1238       (cptr->port == server_port) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
1239
1240   if (cptr != &me)
1241     aconf = cptr->confs->value.aconf;
1242   /*
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.
1246    */
1247   if (type == ADCON_TTY)        /* If descriptor is a tty,
1248                                    special checking... */
1249     get_sockhost(acptr, cptr->sockhost);
1250   else
1251   {
1252     Reg1 char *s, *t;
1253     struct sockaddr_in addr;
1254     size_t len = sizeof(struct sockaddr_in);
1255
1256     if (getpeername(fd, (struct sockaddr *)&addr, &len) == -1)
1257     {
1258       report_error("Failed in connecting to %s: %s", cptr);
1259     add_con_refuse:
1260       ircstp->is_ref++;
1261       acptr->fd = -2;
1262       free_client(acptr);
1263       close(fd);
1264       return NULL;
1265     }
1266     /* Don't want to add "Failed in connecting to" here.. */
1267     if (aconf && IsIllegal(aconf))
1268       goto add_con_refuse;
1269     /*
1270      * Copy ascii address to 'sockhost' just in case. Then we
1271      * have something valid to put into error messages...
1272      */
1273     get_sockhost(acptr, inetntoa(addr.sin_addr));
1274     memcpy(&acptr->ip, &addr.sin_addr, sizeof(struct in_addr));
1275 #ifdef TESTNET
1276     acptr->port = ntohs(addr.sin_port) - 10000;
1277 #else
1278     acptr->port = ntohs(addr.sin_port);
1279 #endif
1280
1281     /*
1282      * Check that this socket (client) is allowed to accept
1283      * connections from this IP#.
1284      */
1285     for (s = (char *)&cptr->ip, t = (char *)&acptr->ip, len = 4;
1286         len > 0; len--, s++, t++)
1287     {
1288       if (!*s)
1289         continue;
1290       if (*s != *t)
1291         break;
1292     }
1293
1294     if (len)
1295       goto add_con_refuse;
1296
1297     lin.flags = ASYNC_CLIENT;
1298     lin.value.cptr = acptr;
1299 #ifdef NODNS
1300     if (!strcmp("127.0.0.1", inetntoa(addr.sin_addr)))
1301     {
1302       static struct hostent lhe = { "localhost", NULL, 0, 0, NULL };
1303       acptr->hostp = &lhe;
1304       if (!DoingAuth(acptr))
1305         SetAccess(acptr);
1306     }
1307     else
1308     {
1309 #endif
1310       Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
1311       acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
1312       if (!acptr->hostp)
1313         SetDNS(acptr);
1314       nextdnscheck = 1;
1315 #ifdef NODNS
1316     }
1317 #endif
1318   }
1319
1320   if (aconf)
1321     aconf->clients++;
1322   acptr->fd = fd;
1323   if (fd > highest_fd)
1324     highest_fd = fd;
1325   loc_clients[fd] = acptr;
1326   acptr->acpt = cptr;
1327   Count_newunknown(nrof);
1328   add_client_to_list(acptr);
1329   set_non_blocking(acptr->fd, acptr);
1330   set_sock_opts(acptr->fd, acptr);
1331
1332   /*
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,
1335    * reject the user.
1336    */
1337   if (IPcheck_local_connect(acptr) == -1 && IsUserPort(acptr))
1338   {
1339     ircstp->is_ref++;
1340     exit_client(cptr, acptr, &me,
1341         "Your host is trying to (re)connect too fast -- throttled");
1342     return NULL;
1343   }
1344
1345   start_auth(acptr);
1346   return acptr;
1347 }
1348
1349 #ifdef  UNIXPORT
1350 static void add_unixconnection(aClient *cptr, int fd)
1351 {
1352   aClient *acptr;
1353   aConfItem *aconf = NULL;
1354
1355   acptr = make_client(NULL, STAT_UNKNOWN);
1356
1357   /*
1358    * Copy ascii address to 'sockhost' just in case. Then we
1359    * have something valid to put into error messages...
1360    */
1361   strncpy(acptr->sockhost, me.name, HOSTLEN);
1362   if (cptr != &me)
1363     aconf = cptr->confs->value.aconf;
1364   if (aconf)
1365   {
1366     if (IsIllegal(aconf))
1367     {
1368       ircstp->is_ref++;
1369       acptr->fd = -2;
1370       free_client(acptr);
1371       close(fd);
1372       return;
1373     }
1374     else
1375       aconf->clients++;
1376   }
1377   acptr->fd = fd;
1378   if (fd > highest_fd)
1379     highest_fd = fd;
1380   loc_clients[fd] = acptr;
1381   acptr->acpt = cptr;
1382   SetUnixSock(acptr);
1383   memcpy(&acptr->ip, &me.ip, sizeof(struct in_addr));
1384
1385   Count_newunknown(nrof);
1386   add_client_to_list(acptr);
1387   set_non_blocking(acptr->fd, acptr);
1388   set_sock_opts(acptr->fd, acptr);
1389   SetAccess(acptr);
1390   return;
1391 }
1392 #endif
1393
1394 /*
1395  * select/poll convert macro's by Run.
1396  *
1397  * The names are chosen to reflect what they means when NOT using poll().
1398  */
1399 #ifndef USE_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[] */
1413 #ifdef _AIX
1414 #define POLLREADFLAGS (POLLIN|POLLMSG)
1415 #else
1416 #  if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
1417 #    define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
1418 #  else
1419 #    if defined(POLLIN) && defined(POLLRDNORM)
1420 #      define POLLREADFLAGS (POLLIN|POLLRDNORM)
1421 #    else
1422 #      if defined(POLLIN)
1423 #        define POLLREADFLAGS POLLIN
1424 #      else
1425 #        if defined(POLLRDNORM)
1426 #          define POLLREADFLAGS POLLRDNORM
1427 #        endif
1428 #      endif
1429 #    endif
1430 #  endif
1431 #endif
1432 #if defined(POLLOUT) && defined(POLLWRNORM)
1433 #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
1434 #else
1435 #  if defined(POLLOUT)
1436 #    define POLLWRITEFLAGS POLLOUT
1437 #  else
1438 #    if defined(POLLWRNORM)
1439 #      define POLLWRITEFLAGS POLLWRNORM
1440 #    endif
1441 #  endif
1442 #endif
1443 #ifdef POLLHUP
1444 #define POLLERRORS (POLLHUP|POLLERR)
1445 #else
1446 #define POLLERRORS POLLERR
1447 #endif
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) \
1457   do { \
1458     poll_fds[index].fd = fdes; \
1459     poll_cptr[index] = cptr; \
1460     poll_fds[index].events = POLLREADFLAGS; \
1461     added = TRUE; \
1462   } while(0)
1463 #define WFD_SET(fdes, wfd, index, cptr) \
1464   do { \
1465     poll_fds[index].fd = fdes; \
1466     poll_cptr[index] = cptr; \
1467     if (added) \
1468       poll_fds[index].events |= POLLWRITEFLAGS; \
1469     else \
1470     { \
1471       poll_fds[index].events = POLLWRITEFLAGS; \
1472       added = TRUE; \
1473     } \
1474   } while(0)
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 */
1484
1485 /*
1486  * read_packet
1487  *
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
1492  */
1493 static int read_packet(aClient *cptr, fd_setp_t rfd)
1494 {
1495   size_t dolen = 0;
1496   int length = 0;
1497   int done;
1498
1499   if (RFD_ISSET(cptr->fd, rfd, rfd) &&
1500       !(IsUser(cptr) && DBufLength(&cptr->recvQ) > 6090))
1501   {
1502     errno = 0;
1503     length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
1504
1505     cptr->lasttime = now;
1506     if (cptr->lasttime > cptr->since)
1507       cptr->since = cptr->lasttime;
1508     cptr->flags &= ~(FLAGS_PINGSENT | FLAGS_NONL);
1509     /*
1510      * If not ready, fake it so it isnt closed
1511      */
1512     if (length == -1 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1513       return 1;
1514     if (length <= 0)
1515       return length;
1516   }
1517
1518   /*
1519    * For server connections, we process as many as we can without
1520    * worrying about the time of day or anything :)
1521    */
1522   if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
1523   {
1524     if (length > 0)
1525       if ((done = dopacket(cptr, readbuf, length)))
1526         return done;
1527   }
1528   else
1529   {
1530     /*
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.
1534      */
1535     if (!dbuf_put(&cptr->recvQ, readbuf, length))
1536       return exit_client(cptr, cptr, &me, "dbuf_put fail");
1537
1538 #ifndef NOFLOODCONTROL
1539     if (IsUser(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD)
1540       return exit_client(cptr, cptr, &me, "Excess Flood");
1541 #endif
1542
1543     while (DBufLength(&cptr->recvQ) && !NoNewLine(cptr)
1544 #ifndef NOFLOODCONTROL
1545         && (IsTrusted(cptr) || cptr->since - now < 10)
1546 #endif
1547         )
1548     {
1549       /*
1550        * If it has become registered as a Server
1551        * then skip the per-message parsing below.
1552        */
1553       if (IsServer(cptr))
1554       {
1555         /*
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)
1559          */
1560         dolen = dbuf_get(&cptr->recvQ, readbuf, sizeof(readbuf));
1561         if (0 == dolen)
1562           break;
1563         if ((done = dopacket(cptr, readbuf, dolen)))
1564           return done;
1565         break;
1566       }
1567       dolen = dbuf_getmsg(&cptr->recvQ, cptr->buffer, BUFSIZE);
1568       /*
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.
1574        * -avalon
1575        */
1576       if (0 == dolen)
1577       {
1578         if (DBufLength(&cptr->recvQ) < 510)
1579         {
1580           cptr->flags |= FLAGS_NONL;
1581           break;
1582         }
1583         DBufClear(&cptr->recvQ);
1584         break;
1585       }
1586       else if (CPTR_KILLED == client_dopacket(cptr, dolen))
1587         return CPTR_KILLED;
1588     }
1589   }
1590   return 1;
1591 }
1592
1593 /*
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
1596  * write it out.
1597  *
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
1600  */
1601 int read_message(time_t delay)
1602 {
1603   Reg1 aClient *cptr;
1604   Reg2 int nfds;
1605   struct timeval wait;
1606 #ifdef  pyr
1607   struct timeval nowt;
1608   unsigned long us;
1609 #endif
1610   time_t delay2 = delay;
1611   unsigned long usec = 0;
1612   int res, length, fd, i;
1613   int auth = 0, ping = 0;
1614 #ifndef USE_POLL
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;
1621   int added;
1622 #endif /* USE_POLL */
1623
1624 #ifdef  pyr
1625   gettimeofday(&nowt, NULL);
1626   now = nowt.tv_sec;
1627 #endif
1628
1629   for (res = 0;;)
1630   {
1631 #ifndef USE_POLL
1632     FD_ZERO(&read_set);
1633     FD_ZERO(&write_set);
1634 #endif /* not USE_POLL */
1635     for (i = highest_fd; i >= 0; i--)
1636     {
1637 #ifdef USE_POLL
1638       added = FALSE;
1639 #endif /* USE_POLL */
1640       if (!(cptr = loc_clients[i]))
1641         continue;
1642       if (IsLog(cptr))
1643         continue;
1644       if (DoingAuth(cptr))
1645       {
1646         auth++;
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);
1651       }
1652       if (IsPing(cptr))
1653       {
1654         ping++;
1655         Debug((DEBUG_NOTICE, "open ping on %p %d", cptr, i));
1656         if (!cptr->firsttime || now <= cptr->firsttime)
1657         {
1658           RFD_SET(i, &read_set, currfd_index, cptr);
1659           delay2 = 1;
1660           if (DoPing(cptr) && now > cptr->lasttime)
1661             RWFD_SET(i, &write_set, currfd_index);
1662         }
1663         else
1664         {
1665           del_queries((char *)cptr);
1666           end_ping(cptr);
1667         }
1668 #ifdef USE_POLL
1669         if (added)
1670           currfd_index++;
1671 #endif /* USE_POLL */
1672         continue;
1673       }
1674       if (DoingDNS(cptr) || DoingAuth(cptr))
1675       {
1676 #ifdef USE_POLL
1677         if (added)
1678           currfd_index++;
1679 #endif /* USE_POLL */
1680         continue;
1681       }
1682       if (IsMe(cptr) && IsListening(cptr))
1683         RFD_SET(i, &read_set, currfd_index, cptr);
1684       else if (!IsMe(cptr))
1685       {
1686         if (DBufLength(&cptr->recvQ) && delay2 > 2)
1687           delay2 = 1;
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))
1692 #ifndef pyr
1693           WFD_SET(i, &write_set, currfd_index, cptr);
1694 #else /* pyr */
1695         {
1696           if (!(cptr->flags & FLAGS_BLOCKED))
1697             WFD_SET(i, &write_set, currfd_index, cptr);
1698           else
1699             delay2 = 0, usec = 500000;
1700         }
1701         if (now - cptr->lw.tv_sec && nowt.tv_usec - cptr->lw.tv_usec < 0)
1702           us = 1000000;
1703         else
1704           us = 0;
1705         us += nowt.tv_usec;
1706         if (us - cptr->lw.tv_usec > 500000)
1707           cptr->flags &= ~FLAGS_BLOCKED;
1708 #endif /* pyr */
1709       }
1710 #ifdef USE_POLL
1711       if (added)
1712         currfd_index++;
1713 #endif /* USE_POLL */
1714     }
1715
1716     if (udpfd >= 0)
1717     {
1718       RFD_SET(udpfd, &read_set, currfd_index, NULL);
1719 #ifdef USE_POLL
1720       udpfdindex = currfd_index;
1721       currfd_index++;
1722 #endif /* USE_POLL */
1723     }
1724     if (resfd >= 0)
1725     {
1726       RFD_SET(resfd, &read_set, currfd_index, NULL);
1727 #ifdef USE_POLL
1728       resfdindex = currfd_index;
1729       currfd_index++;
1730 #endif /* USE_POLL */
1731     }
1732
1733     wait.tv_sec = MIN(delay2, delay);
1734     wait.tv_usec = usec;
1735 #ifndef USE_POLL
1736 #ifdef  HPUX
1737     nfds = select(FD_SETSIZE, (int *)&read_set, (int *)&write_set, 0, &wait);
1738 #else
1739     nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
1740 #endif
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 */
1745     now = time(NULL);
1746     if (nfds == -1 && errno == EINTR)
1747       return -1;
1748     else if (nfds >= 0)
1749       break;
1750     report_error("select %s: %s", &me);
1751     res++;
1752     if (res > 5)
1753       restart("too many select errors");
1754     sleep(10);
1755     now += 10;
1756   }
1757
1758   if (udpfd >= 0 && RFD_ISSET(udpfd, &read_set, udpfdindex))
1759   {
1760     polludp();
1761     nfds--;
1762     RFD_CLR_OUT(udpfd, &read_set, udpfdindex);
1763   }
1764   /*
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.
1768    * -Run
1769    */
1770   for (i = HIGHEST_INDEX; (ping > 0) && (i >= 0); i--)
1771   {
1772     if (!(cptr = LOC_CLIENTS(i)))
1773       continue;
1774     if (!IsPing(cptr))
1775       continue;
1776     ping--;
1777     if ((nfds > 0) && RFD_ISSET(cptr->fd, &read_set, i))
1778     {
1779       nfds--;
1780       RFD_CLR_OUT(cptr->fd, &read_set, i);
1781       read_ping(cptr);          /* This can RunFree(cptr) ! */
1782     }
1783     else if ((nfds > 0) && WFD_ISSET(cptr->fd, &write_set, i))
1784     {
1785       nfds--;
1786       cptr->lasttime = now;
1787       WFD_CLR_OUT(cptr->fd, &write_set, i);
1788       send_ping(cptr);          /* This can RunFree(cptr) ! */
1789     }
1790   }
1791   if (resfd >= 0 && RFD_ISSET(resfd, &read_set, resfdindex))
1792   {
1793     do_dns_async();
1794     nfds--;
1795     RFD_CLR_OUT(resfd, &read_set, resfdindex);
1796   }
1797   /*
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.
1800    * -avalon
1801    */
1802   for (i = HIGHEST_INDEX; (auth > 0) && (i >= 0); i--)
1803   {
1804     if (!(cptr = LOC_CLIENTS(i)))
1805       continue;
1806     if (cptr->authfd < 0)
1807       continue;
1808     auth--;
1809     if ((nfds > 0) && WFD_ISSET(cptr->authfd, &write_set, i))
1810     {
1811       nfds--;
1812       send_authports(cptr);
1813     }
1814     else if ((nfds > 0) && RFD_ISSET(cptr->authfd, &read_set, i))
1815     {
1816       nfds--;
1817       read_authports(cptr);
1818     }
1819   }
1820   for (i = HIGHEST_INDEX; i >= 0; i--)
1821     if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) &&
1822         IsListening(cptr))
1823     {
1824       RFD_CLR_OUT(i, &read_set, i);
1825       nfds--;
1826       cptr->lasttime = now;
1827       /*
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.
1837        */
1838       if ((fd = accept(LOC_FD(i), NULL, NULL)) < 0)
1839       {
1840         if (errno != EWOULDBLOCK)
1841           report_error("accept() failed%s: %s", NULL);
1842         break;
1843       }
1844 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECTS)
1845       {                         /* get an early log of all connections   --dl */
1846         static struct sockaddr_in peer;
1847         static int len;
1848         len = sizeof(peer);
1849         getpeername(fd, (struct sockaddr *)&peer, &len);
1850         syslog(LOG_DEBUG, "Conn: %s", inetntoa(peer.sin_addr));
1851       }
1852 #endif
1853       ircstp->is_ac++;
1854       if (fd >= MAXCLIENTS)
1855       {
1856         /* Don't send more messages then one every 10 minutes */
1857         static int count;
1858         static time_t last_time;
1859         ircstp->is_ref++;
1860         ++count;
1861         if (last_time < now - (time_t) 600)
1862         {
1863           if (count > 0)
1864           {
1865             if (!last_time)
1866               last_time = me.since;
1867             sendto_ops
1868                 ("All connections in use!  Had to refuse %d clients in the last "
1869                 STIME_T_FMT " minutes", count, (now - last_time) / 60);
1870           }
1871           else
1872             sendto_ops("All connections in use. (%s)", cptr->name);
1873           count = 0;
1874           last_time = now;
1875         }
1876         send(fd, "ERROR :All connections in use\r\n", 32, 0);
1877         close(fd);
1878         break;
1879       }
1880       /*
1881        * Use of add_connection (which never fails :) meLazy
1882        */
1883 #ifdef  UNIXPORT
1884       if (IsUnixSocket(cptr))
1885         add_unixconnection(cptr, fd);
1886       else
1887 #endif
1888       if (!add_connection(cptr, fd, ADCON_SOCKET))
1889         continue;
1890       nextping = now;
1891       if (!cptr->acpt)
1892         cptr->acpt = &me;
1893     }
1894
1895   for (i = HIGHEST_INDEX; i >= 0; i--)
1896   {
1897     if (!(cptr = LOC_CLIENTS(i)) || IsMe(cptr))
1898       continue;
1899 #ifdef USE_POLL
1900     if (DoingDNS(cptr) || DoingAuth(cptr) || !(cptr = loc_clients[LOC_FD(i)]))
1901       continue;
1902 #endif /* USE_POLL */
1903 #ifdef DEBUGMODE
1904     if (IsLog(cptr))
1905       continue;
1906 #endif
1907     if (WFD_ISSET(i, &write_set, i))
1908     {
1909       int write_err = 0;
1910       nfds--;
1911       /*
1912        *  ...room for writing, empty some queue then...
1913        */
1914       cptr->flags &= ~FLAGS_BLOCKED;
1915       if (IsConnecting(cptr))
1916         write_err = completed_connection(cptr);
1917       if (!write_err)
1918       {
1919         if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
1920           list_next_channels(cptr, 64);
1921         send_queued(cptr);
1922       }
1923       if (IsDead(cptr) || write_err)
1924       {
1925       deadsocket:
1926         if (RFD_ISSET(i, &read_set, i))
1927         {
1928           nfds--;
1929           RFD_CLR_OUT(i, &read_set, i);
1930         }
1931         exit_client(cptr, cptr, &me,
1932             IsDead(cptr) ? LastDeadComment(cptr) : strerror(get_sockerr(cptr)));
1933         continue;
1934       }
1935     }
1936     length = 1;                 /* for fall through case */
1937     if ((!NoNewLine(cptr) || RFD_ISSET(i, &read_set, i)) && !IsDead(cptr))
1938 #ifndef USE_POLL
1939       length = read_packet(cptr, &read_set);
1940 #else /* USE_POLL */
1941       length = read_packet(cptr, i);
1942 #endif /* USE_POLL */
1943 #if 0
1944     /* Bullshit, why would we want to flush sockets while using non-blocking?
1945      * This uses > 4% cpu! --Run */
1946     if (length > 0)
1947       flush_connections(LOC_FD(i));
1948 #endif
1949     if ((length != CPTR_KILLED) && IsDead(cptr))
1950       goto deadsocket;
1951     if (!RFD_ISSET(i, &read_set, i) && length > 0)
1952       continue;
1953     nfds--;
1954     readcalls++;
1955     if (length > 0)
1956       continue;
1957
1958     /*
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
1966      */
1967     Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
1968
1969     if (length == CPTR_KILLED)
1970       continue;
1971
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);
1975     else
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");
1979   }
1980   return 0;
1981 }
1982
1983 /*
1984  * connect_server
1985  */
1986 int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp)
1987 {
1988   Reg1 struct sockaddr *svp;
1989   Reg2 aClient *cptr, *c2ptr;
1990   Reg3 char *s;
1991   int errtmp, len;
1992
1993   Debug((DEBUG_NOTICE, "Connect to %s[%s] @%s",
1994       aconf->name, aconf->host, inetntoa(aconf->ipnum)));
1995
1996   if ((c2ptr = FindClient(aconf->name)))
1997   {
1998     if (IsServer(c2ptr) || IsMe(c2ptr))
1999     {
2000       sendto_ops("Server %s already present from %s",
2001           aconf->name, c2ptr->from->name);
2002       if (by && IsUser(by) && !MyUser(by))
2003       {
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);
2008         else
2009 #endif
2010           sendto_one(by, "%s NOTICE %s%s :Server %s already present from %s",
2011               NumServ(&me), NumNick(by), aconf->name, c2ptr->from->name);
2012       }
2013       return -1;
2014     }
2015     else if (IsHandshake(c2ptr) || IsConnecting(c2ptr))
2016     {
2017       if (by && IsUser(by))
2018       {
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);
2022         else
2023           sendto_one(by,
2024               "%s NOTICE %s%s :Connection to %s already in progress",
2025               NumServ(&me), NumNick(by), c2ptr->name);
2026       }
2027       return -1;
2028     }
2029   }
2030
2031   /*
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.
2034    */
2035   if ((!aconf->ipnum.s_addr)
2036 #ifdef UNIXPORT
2037       && ((aconf->host[2]) != '/')      /* needed for Unix domain -- dl */
2038 #endif
2039       )
2040   {
2041     Link lin;
2042
2043     lin.flags = ASYNC_CONNECT;
2044     lin.value.aconf = aconf;
2045     nextdnscheck = 1;
2046     s = strchr(aconf->host, '@');
2047     s++;                        /* should NEVER be NULL */
2048     if ((aconf->ipnum.s_addr = inet_addr(s)) == INADDR_NONE)
2049     {
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));
2054       if (!hp)
2055         return 0;
2056       memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2057     }
2058   }
2059   cptr = make_client(NULL, STAT_UNKNOWN);
2060   cptr->hostp = hp;
2061   /*
2062    * Copy these in so we have something for error detection.
2063    */
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;
2068
2069 #ifdef  UNIXPORT
2070   if (aconf->host[2] == '/')    /* (/ starts a 2), Unix domain -- dl */
2071     svp = connect_unix(aconf, cptr, &len);
2072   else
2073     svp = connect_inet(aconf, cptr, &len);
2074 #else
2075   svp = connect_inet(aconf, cptr, &len);
2076 #endif
2077
2078   if (!svp)
2079   {
2080     if (cptr->fd >= 0)
2081       close(cptr->fd);
2082     cptr->fd = -2;
2083     if (by && IsUser(by) && !MyUser(by))
2084     {
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);
2089       else
2090 #endif
2091         sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
2092             NumServ(&me), NumNick(by), cptr->name);
2093     }
2094     free_client(cptr);
2095     return -1;
2096   }
2097
2098   set_non_blocking(cptr->fd, cptr);
2099   set_sock_opts(cptr->fd, cptr);
2100   signal(SIGALRM, dummy);
2101   alarm(4);
2102   if (connect(cptr->fd, svp, len) < 0 && errno != EINPROGRESS)
2103   {
2104     int err = get_sockerr(cptr);
2105     errtmp = errno;             /* other system calls may eat errno */
2106     alarm(0);
2107     report_error("Connect to host %s failed: %s", cptr);
2108     if (by && IsUser(by) && !MyUser(by))
2109     {
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));
2114       else
2115 #endif
2116         sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
2117             NumServ(&me), NumNick(by), cptr->name, strerror(err));
2118     }
2119     close(cptr->fd);
2120     cptr->fd = -2;
2121     free_client(cptr);
2122     errno = errtmp;
2123     if (errno == EINTR)
2124       errno = ETIMEDOUT;
2125     return -1;
2126   }
2127   alarm(0);
2128
2129   /*
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
2136    */
2137   attach_confs_host(cptr, aconf->host,
2138       CONF_NOCONNECT_SERVER | CONF_CONNECT_SERVER);
2139
2140   if (!find_conf_host(cptr->confs, aconf->host, CONF_NOCONNECT_SERVER) ||
2141       !find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
2142   {
2143     sendto_ops("Host %s is not enabled for connecting:no C/N-line",
2144                aconf->name);
2145     if (by && IsUser(by) && !MyUser(by))
2146     {
2147 #ifndef NO_PROTOCOL9
2148       if (Protocol(by->from) < 10)
2149         sendto_one(by,
2150             ":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
2151             me.name, by->name, cptr->name);
2152       else
2153 #endif
2154         sendto_one(by,
2155             "%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
2156             NumServ(&me), NumNick(by), cptr->name);
2157     }
2158     det_confs_butmask(cptr, 0);
2159     close(cptr->fd);
2160     cptr->fd = -2;
2161     free_client(cptr);
2162     return (-1);
2163   }
2164   /*
2165    * The socket has been connected or connect is in progress.
2166    */
2167   make_server(cptr);
2168   if (by && IsUser(by))
2169   {
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;
2174     by->user->refcnt++;
2175   }
2176   else
2177   {
2178     *cptr->serv->by = '\0';
2179     if (cptr->serv->user)
2180       free_user(cptr->serv->user, NULL);
2181     cptr->serv->user = NULL;
2182   }
2183   cptr->serv->up = &me;
2184   if (cptr->fd > highest_fd)
2185     highest_fd = cptr->fd;
2186   loc_clients[cptr->fd] = cptr;
2187   cptr->acpt = &me;
2188   SetConnecting(cptr);
2189
2190   get_sockhost(cptr, aconf->host);
2191   Count_newunknown(nrof);
2192   add_client_to_list(cptr);
2193   hAddClient(cptr);
2194   nextping = now;
2195
2196   return 0;
2197 }
2198
2199 static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
2200 {
2201   static struct sockaddr_in server;
2202   Reg3 struct hostent *hp;
2203
2204   /*
2205    * Might as well get sockhost from here, the connection is attempted
2206    * with it so if it fails its useless.
2207    */
2208   alarm(2);
2209   cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
2210   alarm(0);
2211   if (cptr->fd == -1 && errno == EAGAIN)
2212   {
2213     sendto_ops("opening stream socket to server %s: No more sockets",
2214         cptr->name);
2215     return NULL;
2216   }
2217   if (cptr->fd == -1)
2218   {
2219     report_error("opening stream socket to server %s: %s", cptr);
2220     return NULL;
2221   }
2222   if (cptr->fd >= MAXCLIENTS)
2223   {
2224     sendto_ops("No more connections allowed (%s)", cptr->name);
2225     return NULL;
2226   }
2227   mysk.sin_port = 0;
2228
2229   memset(&server, 0, sizeof(server));
2230   server.sin_family = AF_INET;
2231   get_sockhost(cptr, aconf->host);
2232
2233 #ifdef VIRTUAL_HOST
2234   mysk.sin_addr = vserv.sin_addr;
2235 #endif
2236
2237   /*
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#.
2241    */
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
2246    */
2247 #ifdef VIRTUAL_HOST
2248   /*
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
2252    */
2253   if (bind(cptr->fd, (struct sockaddr *)&mysk, sizeof(mysk)) == -1)
2254   {
2255     report_error("error binding to local port for %s: %s", cptr);
2256     return NULL;
2257   }
2258 #endif
2259
2260   /*
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.
2264    */
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)
2268   {
2269     hp = cptr->hostp;
2270     if (!hp)
2271     {
2272       Debug((DEBUG_FATAL, "%s: unknown host", aconf->host));
2273       return NULL;
2274     }
2275     memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2276   }
2277   memcpy(&server.sin_addr, &aconf->ipnum, sizeof(struct in_addr));
2278   memcpy(&cptr->ip, &aconf->ipnum, sizeof(struct in_addr));
2279 #ifdef TESTNET
2280   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum) + 10000);
2281 #else
2282   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum));
2283 #endif
2284   *lenp = sizeof(server);
2285   return (struct sockaddr *)&server;
2286 }
2287
2288 #ifdef  UNIXPORT
2289 /*
2290  * connect_unix
2291  *
2292  * Build a socket structure for cptr so that it can connet to the unix
2293  * socket defined by the conf structure aconf.
2294  */
2295 static struct sockaddr *connect_unix(aConfItem *aconf, aClient *cptr, int *lenp)
2296 {
2297   static struct sockaddr_un sock;
2298
2299   alarm(2);
2300   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
2301   alarm(0);
2302   if (cptr->fd == -1 && errno == EAGAIN)
2303   {
2304     sendto_ops("Unix domain connect to host %s failed: No more sockets",
2305         cptr->name);
2306     return NULL;
2307   }
2308   if (cptr->fd == -1)
2309   {
2310     report_error("Unix domain connect to host %s failed: %s", cptr);
2311     return NULL;
2312   }
2313   else if (cptr->fd >= MAXCLIENTS)
2314   {
2315     sendto_ops("No more connections allowed (%s)", cptr->name);
2316     return NULL;
2317   }
2318
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;
2325
2326   SetUnixSock(cptr);
2327   return (struct sockaddr *)&sock;
2328 }
2329
2330 #endif
2331
2332 /*
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.
2336  */
2337 void get_my_name(aClient *cptr)
2338 {
2339   struct ConfItem* aconf = find_me();
2340   /*
2341    * Setup local socket structure to use for binding to.
2342    */
2343   memset(&mysk, 0, sizeof(mysk));
2344   mysk.sin_family = AF_INET;
2345   mysk.sin_addr.s_addr = INADDR_ANY; 
2346
2347   if (!aconf || BadPtr(aconf->host))
2348     return;
2349   strncpy(me.name, aconf->host, sizeof(me.name) - 1);
2350
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;
2355 #ifdef VIRTUAL_HOST
2356     memcpy(&vserv, &mysk, sizeof(struct sockaddr_in));
2357 #endif
2358   }
2359   Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
2360 }
2361
2362 /*
2363  * Setup a UDP socket and listen for incoming packets
2364  */
2365 int setup_ping(void)
2366 {
2367   struct sockaddr_in from;
2368   int on = 1;
2369
2370   memset(&from, 0, sizeof(from));
2371 #ifdef VIRTUAL_HOST
2372   from.sin_addr = vserv.sin_addr;
2373 #else
2374   from.sin_addr.s_addr = htonl(INADDR_ANY);
2375 #endif
2376 #ifdef TESTNET
2377   from.sin_port = htons(atoi(UDP_PORT) + 10000);
2378 #else
2379   from.sin_port = htons(atoi(UDP_PORT));
2380 #endif
2381   from.sin_family = AF_INET;
2382
2383   if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2384   {
2385     Debug((DEBUG_ERROR, "socket udp : %s", strerror(errno)));
2386     return -1;
2387   }
2388   if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR,
2389       (OPT_TYPE *)&on, sizeof(on)) == -1)
2390   {
2391 #ifdef  USE_SYSLOG
2392     syslog(LOG_ERR, "setsockopt udp fd %d : %m", udpfd);
2393 #endif
2394     Debug((DEBUG_ERROR, "setsockopt so_reuseaddr : %s", strerror(errno)));
2395     close(udpfd);
2396     udpfd = -1;
2397     return -1;
2398   }
2399   on = 0;
2400   setsockopt(udpfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on));
2401   if (bind(udpfd, (struct sockaddr *)&from, sizeof(from)) == -1)
2402   {
2403 #ifdef  USE_SYSLOG
2404     syslog(LOG_ERR, "bind udp.%d fd %d : %m", from.sin_port, udpfd);
2405 #endif
2406     Debug((DEBUG_ERROR, "bind : %s", strerror(errno)));
2407     close(udpfd);
2408     udpfd = -1;
2409     return -1;
2410   }
2411   if (fcntl(udpfd, F_SETFL, FNDELAY) == -1)
2412   {
2413     Debug((DEBUG_ERROR, "fcntl fndelay : %s", strerror(errno)));
2414     close(udpfd);
2415     udpfd = -1;
2416     return -1;
2417   }
2418   return udpfd;
2419 }
2420
2421 /*
2422  * max # of pings set to 15/sec.
2423  */
2424 static void polludp(void)
2425 {
2426   Reg1 char *s;
2427   struct sockaddr_in from;
2428   int n;
2429   size_t fromlen = sizeof(from);
2430   static time_t last = 0;
2431   static int cnt = 0, mlen = 0;
2432
2433   /*
2434    * find max length of data area of packet.
2435    */
2436   if (!mlen)
2437   {
2438     mlen = sizeof(readbuf) - strlen(me.name) - strlen(version);
2439     mlen -= 6;
2440     if (mlen < 0)
2441       mlen = 0;
2442   }
2443   Debug((DEBUG_DEBUG, "udp poll"));
2444
2445   n = recvfrom(udpfd, readbuf, mlen, 0, (struct sockaddr *)&from, &fromlen);
2446   if (now == last)
2447     if (++cnt > 14)
2448       return;
2449   cnt = 0;
2450   last = now;
2451
2452   if (n == -1)
2453   {
2454     if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
2455       return;
2456     else
2457     {
2458       report_error("udp port recvfrom (%s): %s", &me);
2459       return;
2460     }
2461   }
2462   ircstp->is_udp++;
2463   if (n < 19)
2464     return;
2465
2466   s = readbuf + n;
2467   /*
2468    * attach my name and version for the reply
2469    */
2470   *readbuf |= 1;
2471   strcpy(s, me.name);
2472   s += strlen(s) + 1;
2473   strcpy(s, version);
2474   s += strlen(s);
2475   sendto(udpfd, readbuf, s - readbuf, 0,
2476       (struct sockaddr *)&from, sizeof(from));
2477   return;
2478 }
2479
2480 /*
2481  * do_dns_async
2482  *
2483  * Called when the fd returned from init_resolver() has been selected for
2484  * reading.
2485  */
2486 static void do_dns_async(void)
2487 {
2488   static Link ln;
2489   aClient *cptr;
2490   aConfItem *aconf;
2491   struct hostent *hp;
2492
2493   ln.flags = ASYNC_NONE;
2494   hp = get_res((char *)&ln);
2495
2496   Debug((DEBUG_DNS, "%p = get_res(%d,%p)", hp, ln.flags, ln.value.cptr));
2497
2498   switch (ln.flags)
2499   {
2500     case ASYNC_NONE:
2501       /*
2502        * No reply was processed that was outstanding or had a client
2503        * still waiting.
2504        */
2505       break;
2506     case ASYNC_CLIENT:
2507       if ((cptr = ln.value.cptr))
2508       {
2509         del_queries((char *)cptr);
2510         ClearDNS(cptr);
2511         if (!DoingAuth(cptr))
2512           SetAccess(cptr);
2513         cptr->hostp = hp;
2514       }
2515       break;
2516     case ASYNC_CONNECT:
2517       aconf = ln.value.aconf;
2518       if (hp && aconf)
2519       {
2520         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2521         connect_server(aconf, NULL, hp);
2522       }
2523       else
2524         sendto_ops("Connect to %s failed: host lookup",
2525             (aconf) ? aconf->host : "unknown");
2526       break;
2527     case ASYNC_PING:
2528       cptr = ln.value.cptr;
2529       del_queries((char *)cptr);
2530       if (hp)
2531       {
2532         memcpy(&cptr->ip, hp->h_addr, sizeof(struct in_addr));
2533         if (ping_server(cptr) == -1)
2534           end_ping(cptr);
2535       }
2536       else
2537       {
2538         sendto_ops("Udp ping to %s failed: host lookup", cptr->sockhost);
2539         end_ping(cptr);
2540       }
2541       break;
2542     case ASYNC_CONF:
2543       aconf = ln.value.aconf;
2544       if (hp && aconf)
2545         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2546       break;
2547     default:
2548       break;
2549   }
2550 }