d51d319d383c7bd30c9837d81fd2379e4436e7ee
[ircu2.10.12-pk.git] / ircd / listener.c
1 /************************************************************************
2  *   IRC - Internet Relay Chat, src/listener.c
3  *   Copyright (C) 1999 Thomas Helvey <tomh@inxpress.net>
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 1, or (at your option)
8  *   any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /** @file
20  * @brief Implementation for handling listening sockets.
21  * @version $Id$
22  */
23 #include "config.h"
24
25 #include "listener.h"
26 #include "client.h"
27 #include "ircd.h"
28 #include "ircd_alloc.h"
29 #include "ircd_events.h"
30 #include "ircd_features.h"
31 #include "ircd_log.h"
32 #include "ircd_osdep.h"
33 #include "ircd_reply.h"
34 #include "ircd_snprintf.h"
35 #include "ircd_string.h"
36 #include "match.h"
37 #include "numeric.h"
38 #include "s_bsd.h"
39 #include "s_conf.h"
40 #include "s_misc.h"
41 #include "s_stats.h"
42 #include "send.h"
43 #include "sys.h"         /* MAXCLIENTS */
44
45 /* #include <assert.h> -- Now using assert in ircd_log.h */
46 #include <stdio.h>
47 #include <string.h>
48 #include <errno.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <netdb.h>
52 #include <sys/socket.h>
53
54 /** List of listening sockets. */
55 struct Listener* ListenerPollList = 0;
56
57 static void accept_connection(struct Event* ev);
58
59 /** Allocate and initialize a new Listener structure for a particular
60  * socket address.
61  * @param[in] port Port number to listen on.
62  * @param[in] addr Local address to listen on.
63  * @return Newly allocated and initialized Listener.
64  */
65 static struct Listener* make_listener(int port, const struct irc_in_addr *addr)
66 {
67   struct Listener* listener =
68     (struct Listener*) MyMalloc(sizeof(struct Listener));
69   assert(0 != listener);
70
71   memset(listener, 0, sizeof(struct Listener));
72
73   listener->fd          = -1;
74   listener->addr.port   = port;
75   memcpy(&listener->addr.addr, addr, sizeof(listener->addr.addr));
76
77 #ifdef NULL_POINTER_NOT_ZERO
78   listener->next = NULL;
79   listener->conf = NULL;
80 #endif
81   return listener;
82 }
83
84 /** Deallocate a Listener structure.
85  * @param[in] listener Listener to be freed.
86  */
87 static void free_listener(struct Listener* listener)
88 {
89   assert(0 != listener);
90   MyFree(listener);
91 }
92
93 /** Maximum length for a port number. */
94 #define PORTNAMELEN 10  /* ":31337" */
95
96 /** Return displayable listener name and port.
97  * @param[in] listener %Listener to format as a text string.
98  * @return Pointer to a static buffer that contains "server.name:6667".
99  */
100 const char* get_listener_name(const struct Listener* listener)
101 {
102   static char buf[HOSTLEN + PORTNAMELEN + 4];
103   assert(0 != listener);
104   ircd_snprintf(0, buf, sizeof(buf), "%s:%u", cli_name(&me), listener->addr.port);
105   return buf;
106 }
107
108 /** Count allocated listeners and the memory they use.
109  * @param[out] count_out Receives number of allocated listeners.
110  * @param[out] size_out Receives bytes used by listeners.
111  */
112 void count_listener_memory(int* count_out, size_t* size_out)
113 {
114   struct Listener* l;
115   int              count = 0;
116   assert(0 != count_out);
117   assert(0 != size_out);
118   for (l = ListenerPollList; l; l = l->next)
119     ++count;
120   *count_out = count;
121   *size_out  = count * sizeof(struct Listener);
122 }
123
124 /** Report listening ports to a client.
125  * @param[in] sptr Client requesting statistics.
126  * @param[in] sd Stats descriptor for request (ignored).
127  * @param[in] param Extra parameter from user (port number to search for).
128  */
129 void show_ports(struct Client* sptr, const struct StatDesc* sd,
130                 char* param)
131 {
132   struct Listener *listener = 0;
133   char flags[8];
134   int show_hidden = IsOper(sptr);
135   int count = (IsOper(sptr) || MyUser(sptr)) ? 100 : 8;
136   int port = 0;
137
138   assert(0 != sptr);
139
140   if (param)
141     port = atoi(param);
142
143   for (listener = ListenerPollList; listener; listener = listener->next) {
144     if (port && port != listener->addr.port)
145       continue;
146     flags[0] = (listener->server) ? 'S' : 'C';
147     if (listener->hidden) {
148       if (!show_hidden)
149         continue;
150       flags[1] = 'H';
151       flags[2] = '\0';
152     }
153     else
154       flags[1] = '\0';
155
156     send_reply(sptr, RPL_STATSPLINE, listener->addr.port, listener->ref_count,
157                flags, (listener->active) ? "active" : "disabled");
158     if (--count == 0)
159       break;
160   }
161 }
162
163 /*
164  * inetport - create a listener socket in the AF_INET domain, 
165  * bind it to the port given in 'port' and listen to it  
166  * returns true (1) if successful false (0) on error.
167  *
168  * If the operating system has a define for SOMAXCONN, use it, otherwise
169  * use HYBRID_SOMAXCONN -Dianora
170  * NOTE: Do this in os_xxxx.c files
171  */
172 #ifdef SOMAXCONN
173 #define HYBRID_SOMAXCONN SOMAXCONN
174 #else
175 /** Maximum length of socket connection backlog. */
176 #define HYBRID_SOMAXCONN 64
177 #endif
178
179 /** Open listening socket for \a listener.
180  * @param[in,out] listener Listener to make a socket for.
181  * @return Non-zero on success, zero on failure.
182  */
183 static int inetport(struct Listener* listener)
184 {
185   int                fd;
186
187   /*
188    * At first, open a new socket
189    */
190   fd = os_socket(&listener->addr, SOCK_STREAM, get_listener_name(listener));
191   if (fd < 0)
192     return 0;
193   /*
194    * Set the buffer sizes for the listener. Accepted connections
195    * inherit the accepting sockets settings for SO_RCVBUF S_SNDBUF
196    * The window size is set during the SYN ACK so setting it anywhere
197    * else has no effect whatsoever on the connection.
198    * NOTE: this must be set before listen is called
199    */
200   if (!os_set_sockbufs(fd,
201                        (listener->server) ? feature_int(FEAT_SOCKSENDBUF) : CLIENT_TCP_WINDOW,
202                        (listener->server) ? feature_int(FEAT_SOCKRECVBUF) : CLIENT_TCP_WINDOW)) {
203     report_error(SETBUFS_ERROR_MSG, get_listener_name(listener), errno);
204     close(fd);
205     return 0;
206   }
207   if (!os_set_listen(fd, HYBRID_SOMAXCONN)) {
208     report_error(LISTEN_ERROR_MSG, get_listener_name(listener), errno);
209     close(fd);
210     return 0;
211   }
212   /*
213    * Set the TOS bits - this is nonfatal if it doesn't stick.
214    */
215   if (!os_set_tos(fd,feature_int((listener->server)?FEAT_TOS_SERVER : FEAT_TOS_CLIENT))) {
216     report_error(TOS_ERROR_MSG, get_listener_name(listener), errno);
217   }
218
219   if (!socket_add(&listener->socket, accept_connection, (void*) listener,
220                   SS_LISTENING, 0, fd)) {
221     /* Error should already have been reported to the logs */
222     close(fd);
223     return 0;
224   }
225
226   listener->fd = fd;
227
228   return 1;
229 }
230
231 /** Find the listener (if any) for a particular port and address.
232  * @param[in] port Port number to search for.
233  * @param[in] addr Local address to search for.
234  * @return Listener that matches (or NULL if none match).
235  */
236 static struct Listener* find_listener(int port, const struct irc_in_addr *addr)
237 {
238   struct Listener* listener;
239   for (listener = ListenerPollList; listener; listener = listener->next) {
240     if (port == listener->addr.port && !memcmp(addr, &listener->addr.addr, sizeof(*addr)))
241       return listener;
242   }
243   return 0;
244 }
245
246 /** Make sure we have a listener for \a port on \a vhost_ip.
247  * If one does not exist, create it.  Then mark it as active and set
248  * the peer mask, server, and hidden flags according to the other
249  * arguments.
250  * @param[in] port Port number to listen on.
251  * @param[in] vhost_ip Local address to listen on.
252  * @param[in] mask Address mask to accept connections from.
253  * @param[in] is_server Non-zero if the port should only accept server connections.
254  * @param[in] is_hidden Non-zero if the port should be hidden from /STATS P output.
255  */
256 void add_listener(int port, const char* vhost_ip, const char* mask,
257                   int is_server, int is_hidden)
258 {
259   struct Listener* listener;
260   struct irc_in_addr vaddr;
261
262   /*
263    * if no port in conf line, don't bother
264    */
265   if (0 == port)
266     return;
267
268   memset(&vaddr, 0, sizeof(vaddr));
269
270   if (!EmptyString(vhost_ip)
271       && strcmp(vhost_ip, "*")
272       && !ircd_aton(&vaddr, vhost_ip))
273       return;
274
275   listener = find_listener(port, &vaddr);
276   if (!listener)
277     listener = make_listener(port, &vaddr);
278   listener->active = 1;
279   listener->hidden = is_hidden;
280   listener->server = is_server;
281   if (mask)
282     ipmask_parse(mask, &listener->mask, &listener->mask_bits);
283   else
284     listener->mask_bits = 0;
285
286   if (listener->fd >= 0) {
287     /* If the listener is already open, do not try to re-open. */
288   }
289   else if (inetport(listener)) {
290     listener->next   = ListenerPollList;
291     ListenerPollList = listener;
292   }
293   else
294     free_listener(listener);
295 }
296
297 /** Mark all listeners as closing (inactive).
298  * This is done so unused listeners are closed after a rehash.
299  */
300 void mark_listeners_closing(void)
301 {
302   struct Listener* listener;
303   for (listener = ListenerPollList; listener; listener = listener->next)
304     listener->active = 0;
305 }
306
307 /** Close a single listener.
308  * @param[in] listener Listener to close.
309  */
310 void close_listener(struct Listener* listener)
311 {
312   assert(0 != listener);
313   /*
314    * remove from listener list
315    */
316   if (listener == ListenerPollList)
317     ListenerPollList = listener->next;
318   else {
319     struct Listener* prev = ListenerPollList;
320     for ( ; prev; prev = prev->next) {
321       if (listener == prev->next) {
322         prev->next = listener->next;
323         break; 
324       }
325     }
326   }
327   if (-1 < listener->fd)
328     close(listener->fd);
329   socket_del(&listener->socket);
330 }
331
332 /** Close all inactive listeners. */
333 void close_listeners(void)
334 {
335   struct Listener* listener;
336   struct Listener* listener_next = 0;
337   /*
338    * close all 'extra' listening ports we have
339    */
340   for (listener = ListenerPollList; listener; listener = listener_next) {
341     listener_next = listener->next;
342     if (0 == listener->active && 0 == listener->ref_count)
343       close_listener(listener);
344   }
345 }
346
347 /** Dereference the listener previously associated with a client.
348  * @param[in] listener Listener to dereference.
349  */
350 void release_listener(struct Listener* listener)
351 {
352   assert(0 != listener);
353   assert(0 < listener->ref_count);
354   if (0 == --listener->ref_count && !listener->active)
355     close_listener(listener);
356 }
357
358 /** Accept a connection on a listener.
359  * @param[in] ev Socket callback structure.
360  */
361 static void accept_connection(struct Event* ev)
362 {
363   struct Listener*    listener;
364   struct irc_sockaddr addr;
365   int                 fd;
366
367   assert(0 != ev_socket(ev));
368   assert(0 != s_data(ev_socket(ev)));
369
370   listener = (struct Listener*) s_data(ev_socket(ev));
371
372   if (ev_type(ev) == ET_DESTROY) /* being destroyed */
373     free_listener(listener);
374   else {
375     assert(ev_type(ev) == ET_ACCEPT || ev_type(ev) == ET_ERROR);
376
377     listener->last_accept = CurrentTime;
378     /*
379      * There may be many reasons for error return, but
380      * in otherwise correctly working environment the
381      * probable cause is running out of file descriptors
382      * (EMFILE, ENFILE or others?). The man pages for
383      * accept don't seem to list these as possible,
384      * although it's obvious that it may happen here.
385      * Thus no specific errors are tested at this
386      * point, just assume that connections cannot
387      * be accepted until some old is closed first.
388      *
389      * This piece of code implements multi-accept, based
390      * on the idea that poll/select can only be efficient,
391      * if we succeed in handling all available events,
392      * i.e. accept all pending connections.
393      *
394      * http://www.hpl.hp.com/techreports/2000/HPL-2000-174.html
395      */
396     while (1)
397     {
398       if ((fd = os_accept(listener->fd, &addr)) == -1)
399       {
400         if (errno == EAGAIN ||
401 #ifdef EWOULDBLOCK
402             errno == EWOULDBLOCK)
403 #endif
404           return;
405       /* Lotsa admins seem to have problems with not giving enough file
406        * descriptors to their server so we'll add a generic warning mechanism
407        * here.  If it turns out too many messages are generated for
408        * meaningless reasons we can filter them back.
409        */
410       sendto_opmask_butone(0, SNO_TCPCOMMON,
411                            "Unable to accept connection: %m");
412       return;
413       }
414       /*
415        * check for connection limit. If this fd exceeds the limit,
416        * all further accept()ed connections will also exceed it.
417        * Enable the server to clear out other connections before
418        * continuing to accept() new connections.
419        */
420       if (fd > MAXCLIENTS - 1)
421       {
422         ++ServerStats->is_ref;
423         send(fd, "ERROR :All connections in use\r\n", 32, 0);
424         close(fd);
425         return;
426       }
427       /*
428        * check to see if listener is shutting down. Continue
429        * to accept(), because it makes sense to clear our the
430        * socket's queue as fast as possible.
431        */
432       if (!listener->active)
433       {
434         ++ServerStats->is_ref;
435         send(fd, "ERROR :Use another port\r\n", 25, 0);
436         close(fd);
437         continue;
438       }
439       /*
440        * check to see if connection is allowed for this address mask
441        */
442       if (!ipmask_check(&addr.addr, &listener->mask, listener->mask_bits))
443       {
444         ++ServerStats->is_ref;
445         send(fd, "ERROR :Use another port\r\n", 25, 0);
446         close(fd);
447         continue;
448       }
449       ++ServerStats->is_ac;
450       /* nextping = CurrentTime; */
451       add_connection(listener, fd);
452     }
453   }
454 }