b85b73cf2bfde7d0d1f07fff77d2abbb38c3cee3
[sip-router] / main.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * -------
29  *  2002-01-29  argc/argv globalized via my_{argc|argv} (jiri)
30  *  2003-01-23  mhomed added (jiri)
31  *  2003-03-19  replaced all malloc/frees w/ pkg_malloc/pkg_free (andrei)
32  *  2003-03-29  pkg cleaners for fifo and script callbacks introduced (jiri)
33  *  2003-03-31  removed snmp part (obsolete & no place in core) (andrei)
34  *  2003-04-06  child_init called in all processes (janakj)
35  *  2003-04-08  init_mallocs split into init_{pkg,shm}_mallocs and 
36  *               init_shm_mallocs called after cmd. line parsing (andrei)
37  *  2003-04-15  added tcp_disable support (andrei)
38  *  2003-05-09  closelog() before openlog to force opening a new fd 
39  *               (needed on solaris) (andrei)
40  *  2003-06-11  moved all signal handlers init. in install_sigs and moved it
41  *               after daemonize (so that we won't catch anymore our own
42  *               SIGCHLD generated when becoming session leader) (andrei)
43  *              changed is_main default value to 1 (andrei)
44  *  2003-06-28  kill_all_children is now used instead of kill(0, sig)
45  *                see comment above it for explanations. (andrei)
46  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
47  *  2003-10-10  added switch for config check (-c) (andrei)
48  *  2003-10-24  converted to the new socket_info lists (andrei)
49  *  2004-03-30  core dump is enabled by default
50  *              added support for increasing the open files limit    (andrei)
51  *  2004-04-28  sock_{user,group,uid,gid,mode} added
52  *              user2uid() & user2gid() added  (andrei)
53  *  2004-09-11  added timeout on children shutdown and final cleanup
54  *               (if it takes more than 60s => something is definitely wrong
55  *                => kill all or abort)  (andrei)
56  *              force a shm_unlock before cleaning-up, in case we have a
57  *               crashed childvwhich still holds the lock  (andrei)
58  *  2004-12-02  removed -p, extended -l to support [proto:]address[:port],
59  *               added parse_phostport, parse_proto (andrei)
60  *  2005-06-16  always record the pid in pt[process_no].pid twice: once in the
61  *               parent & once in the child to avoid a short window when one
62  *               of them might use it "unset" (andrei)
63  *  2005-07-25  use sigaction for setting the signal handlers (andrei)
64  */
65
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <errno.h>
70 #include <ctype.h>
71 #include <string.h>
72 #include <netdb.h>
73 #include <unistd.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
76 #if defined(HAVE_NETINET_IN_SYSTM)
77 #include <netinet/in_systm.h>
78 #endif
79 #include <netinet/in.h>
80 #include <netinet/ip.h>
81 #include <arpa/inet.h>
82 #include <sys/utsname.h>
83 #include <sys/stat.h>
84 #include <sys/mman.h>
85 #include <fcntl.h>
86 #include <sys/time.h>
87 #include <sys/wait.h>
88 #include <pwd.h>
89 #include <grp.h>
90 #include <signal.h>
91
92 #include <sys/ioctl.h>
93 #include <net/if.h>
94 #ifdef HAVE_SYS_SOCKIO_H
95 #include <sys/sockio.h>
96 #endif
97
98 #include "config.h"
99 #include "dprint.h"
100 #include "daemonize.h"
101 #include "route.h"
102 #include "udp_server.h"
103 #include "globals.h"
104 #include "mem/mem.h"
105 #ifdef SHM_MEM
106 #include "mem/shm_mem.h"
107 #endif
108 #include "sr_module.h"
109 #include "timer.h"
110 #include "parser/msg_parser.h"
111 #include "ip_addr.h"
112 #include "resolve.h"
113 #include "parser/parse_hname2.h"
114 #include "parser/digest/digest_parser.h"
115 #include "fifo_server.h"
116 #include "unixsock_server.h"
117 #include "name_alias.h"
118 #include "hash_func.h"
119 #include "pt.h"
120 #include "script_cb.h"
121 #include "ut.h"
122 #include "signals.h"
123 #ifdef USE_TCP
124 #include "poll_types.h"
125 #include "tcp_init.h"
126 #ifdef USE_TLS
127 #include "tls/tls_init.h"
128 #endif
129 #endif
130 #include "usr_avp.h"
131
132
133 #include "stats.h"
134
135 #ifdef DEBUG_DMALLOC
136 #include <dmalloc.h>
137 #endif
138 #include "version.h"
139
140 static char id[]="@(#) $Id$";
141 static char* version=SER_FULL_VERSION;
142 static char* flags=SER_COMPILE_FLAGS;
143 char compiled[]= __TIME__ " " __DATE__ ;
144
145
146 static char help_msg[]= "\
147 Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
148 Options:\n\
149     -f file      Configuration file (default " CFG_FILE ")\n\
150     -c           Check configuration file for errors\n\
151     -l address   Listen on the specified address/interface (multiple -l\n\
152                   mean listening on more addresses).  The address format is\n\
153                   [proto:]addr[:port], where proto=udp|tcp and \n\
154                   addr= host|ip_address|interface_name. E.g: -l locahost, \n\
155                   -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
156                   is to listen on all the interfaces.\n\
157     -n processes Number of child processes to fork per interface\n\
158                   (default: 8)\n\
159     -r           Use dns to check if is necessary to add a \"received=\"\n\
160                   field to a via\n\
161     -R           Same as `-r` but use reverse dns;\n\
162                   (to use both use `-rR`)\n\
163     -v           Turn on \"via:\" host checking when forwarding replies\n\
164     -d           Debugging mode (multiple -d increase the level)\n\
165     -D           Do not fork into daemon mode\n\
166     -E           Log to stderr\n"
167 #ifdef USE_TCP
168 "    -T           Disable tcp\n\
169     -N           Number of tcp child processes (default: equal to `-n`)\n\
170     -W           poll method\n"
171 #endif
172 "    -V           Version number\n\
173     -h           This help message\n\
174     -b nr        Maximum receive buffer size which will not be exceeded by\n\
175                   auto-probing procedure even if  OS allows\n\
176     -m nr        Size of shared memory allocated in Megabytes\n\
177     -w dir       Change the working directory to \"dir\" (default \"/\")\n\
178     -t dir       Chroot to \"dir\"\n\
179     -u uid       Change uid \n\
180     -g gid       Change gid \n\
181     -P file      Create a pid file\n\
182     -G file      Create a pgid file\n\
183     -i fifo_path Create a fifo (useful for monitoring " NAME ") \n\
184     -x socket    Create a unix domain socket \n"
185 #ifdef STATS
186 "    -s file     File to which statistics is dumped (disabled otherwise)\n"
187 #endif
188 ;
189
190 /* print compile-time constants */
191 void print_ct_constants()
192 {
193 #ifdef ADAPTIVE_WAIT
194         printf("ADAPTIVE_WAIT_LOOPS=%d, ", ADAPTIVE_WAIT_LOOPS);
195 #endif
196 /*
197 #ifdef SHM_MEM
198         printf("SHM_MEM_SIZE=%d, ", SHM_MEM_SIZE);
199 #endif
200 */
201         printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d,"
202                         " MAX_URI_SIZE %d, BUF_SIZE %d\n",
203                 MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, 
204                 BUF_SIZE );
205 #ifdef USE_TCP
206         printf("poll method support: %s.\n", poll_support);
207 #endif
208 }
209
210 /* debugging function */
211 /*
212 void receive_stdin_loop()
213 {
214         #define BSIZE 1024
215         char buf[BSIZE+1];
216         int len;
217
218         while(1){
219                 len=fread(buf,1,BSIZE,stdin);
220                 buf[len+1]=0;
221                 receive_msg(buf, len);
222                 printf("-------------------------\n");
223         }
224 }
225 */
226
227 /* global vars */
228
229 int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
230                                          to use kill(0, sig) */
231 char* cfg_file = 0;
232 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
233                                                                                                   not want to exceed during the
234                                                                                                   auto-probing procedure; may 
235                                                                                                   be re-configured */
236 int children_no = 0;                    /* number of children processing requests */
237 #ifdef USE_TCP
238 int tcp_children_no = 0;
239 int tcp_disable = 0; /* 1 if tcp is disabled */
240 #endif
241 #ifdef USE_TLS
242 int tls_disable = 0; /* 1 if tls is disabled */
243 #endif
244 struct process_table *pt=0;             /*array with children pids, 0= main proc,
245                                                                         alloc'ed in shared mem if possible*/
246 int sig_flag = 0;              /* last signal received */
247 int debug = L_NOTICE;
248 int dont_fork = 0;
249 int log_stderr = 0;
250 /* log facility (see syslog(3)) */
251 int log_facility = LOG_DAEMON;
252 int config_check = 0;
253 /* check if reply first via host==us */
254 int check_via =  0;        
255 /* shall use stateful synonym branches? faster but not reboot-safe */
256 int syn_branch = 1;
257 /* debugging level for memory stats */
258 int memlog = L_DBG;
259 /* debugging level for timer debugging */
260 int timerlog = L_WARN;
261 /* should replies include extensive warnings? by default yes,
262    good for trouble-shooting
263 */
264 int sip_warning = 1;
265 /* should localy-generated messages include server's signature?
266    be default yes, good for trouble-shooting
267 */
268 int server_signature=1;
269 /* should ser try to locate outbound interface on multihomed
270  * host? by default not -- too expensive
271  */
272 int mhomed=0;
273 /* use dns and/or rdns or to see if we need to add 
274    a ;received=x.x.x.x to via: */
275 int received_dns = 0;      
276 char* working_dir = 0;
277 char* chroot_dir = 0;
278 char* user=0;
279 char* group=0;
280 int uid = 0;
281 int gid = 0;
282 char* sock_user=0;
283 char* sock_group=0;
284 int sock_uid= -1;
285 int sock_gid= -1;
286 int sock_mode= S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP; /* rw-rw---- */
287
288 /* more config stuff */
289 int disable_core_dump=0; /* by default enabled */
290 int open_files_limit=-1; /* don't touch it by default */
291 /* a hint to reply modules whether they should send reply
292    to IP advertised in Via or IP from which a request came
293 */
294 int reply_to_via=0;
295
296 #ifdef USE_MCAST
297 int mcast_loopback = 0;
298 int mcast_ttl = -1; /* if -1, don't touch it, use the default (usually 1) */
299 #endif /* USE_MCAST */
300
301 int tos = IPTOS_LOWDELAY;
302
303 #if 0
304 char* names[MAX_LISTEN];              /* our names */
305 int names_len[MAX_LISTEN];            /* lengths of the names*/
306 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
307 int addresses_no=0;                   /* number of names/ips */
308 #endif
309 struct socket_info* udp_listen=0;
310 #ifdef USE_TCP
311 struct socket_info* tcp_listen=0;
312 #endif
313 #ifdef USE_TLS
314 struct socket_info* tls_listen=0;
315 #endif
316 struct socket_info* bind_address=0; /* pointer to the crt. proc.
317                                                                          listening address*/
318 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
319 struct socket_info* sendipv6; /* same as above for ipv6 */
320 #ifdef USE_TCP
321 struct socket_info* sendipv4_tcp; 
322 struct socket_info* sendipv6_tcp; 
323 #endif
324 #ifdef USE_TLS
325 struct socket_info* sendipv4_tls;
326 struct socket_info* sendipv6_tls;
327 #endif
328
329 unsigned short port_no=0; /* default port*/
330 #ifdef USE_TLS
331 unsigned short tls_port_no=0; /* default port */
332 #endif
333
334 struct host_alias* aliases=0; /* name aliases list */
335
336 /* ipc related globals */
337 int process_no = 0;
338 /* process_bm_t process_bit = 0; */
339 #ifdef ROUTE_SRV
340 #endif
341
342 /* cfg parsing */
343 int cfg_errors=0;
344
345 /* shared memory (in MB) */
346 unsigned long shm_mem_size=SHM_MEM_SIZE * 1024 * 1024;
347
348 /* export command-line to anywhere else */
349 int my_argc;
350 char **my_argv;
351
352 #define MAX_FD 32 /* maximum number of inherited open file descriptors,
353                     (normally it shouldn't  be bigger  than 3) */
354
355
356 extern FILE* yyin;
357 extern int yyparse();
358
359
360 int is_main=1; /* flag = is this the  "main" process? */
361
362 char* pid_file = 0; /* filename as asked by use */
363 char* pgid_file = 0;
364
365
366 /* call it before exiting; if show_status==1, mem status is displayed */
367 void cleanup(show_status)
368 {
369         /*clean-up*/
370         if (mem_lock) 
371                 shm_unlock(); /* hack: force-unlock the shared memory lock in case
372                                          some process crashed and let it locked; this will 
373                                          allow an almost gracious shutdown */
374         destroy_modules();
375 #ifdef USE_TCP
376         destroy_tcp();
377 #endif
378 #ifdef USE_TLS
379         destroy_tls();
380 #endif
381         destroy_timer();
382         close_unixsock_server();
383         destroy_fifo();
384         destroy_script_cb();
385 #ifdef PKG_MALLOC
386         if (show_status){
387                 LOG(memlog, "Memory status (pkg):\n");
388                 pkg_status();
389         }
390 #endif
391 #ifdef SHM_MEM
392         if (pt) shm_free(pt);
393         pt=0;
394         if (show_status){
395                         LOG(memlog, "Memory status (shm):\n");
396                         shm_status();
397         }
398         /* zero all shmem alloc vars that we still use */
399         shm_mem_destroy();
400 #endif
401         if (pid_file) unlink(pid_file);
402         if (pgid_file) unlink(pgid_file);
403 }
404
405
406 /* tries to send a signal to all our processes
407  * if daemonized  is ok to send the signal to all the process group,
408  * however if not daemonized we might end up sending the signal also
409  * to the shell which launched us => most signals will kill it if 
410  * it's not in interactive mode and we don't want this. The non-daemonized 
411  * case can occur when an error is encountered before daemonize is called 
412  * (e.g. when parsing the config file) or when ser is started in "dont-fork"
413  *  mode. Sending the signal to all the processes in pt[] will not work
414  *  for processes forked from modules (which have no correspondent entry in 
415  *  pt), but this can happen only in dont_fork mode (which is only for
416  *  debugging). So in the worst case + "dont-fork" we might leave some
417  *  zombies. -- andrei */
418 static void kill_all_children(int signum)
419 {
420         int r;
421
422         if (own_pgid) kill(0, signum);
423         else if (pt)
424                 for (r=1; r<process_count(); r++)
425                         if (pt[r].pid) kill(pt[r].pid, signum);
426 }
427
428
429
430 /* if this handler is called, a critical timeout has occured while
431  * waiting for the children to finish => we should kill everything and exit */
432 static void sig_alarm_kill(int signo)
433 {
434         kill_all_children(SIGKILL); /* this will kill the whole group
435                                                                   including "this" process;
436                                                                   for debugging replace with SIGABRT
437                                                                   (but warning: it might generate lots
438                                                                    of cores) */
439 }
440
441
442 /* like sig_alarm_kill, but the timeout has occured when cleaning up
443  * => try to leave a core for future diagnostics */
444 static void sig_alarm_abort(int signo)
445 {
446         /* LOG is not signal safe, but who cares, we are abort-ing anyway :-) */
447         LOG(L_CRIT, "BUG: shutdown timeout triggered, dying...");
448         abort();
449 }
450
451
452
453 void handle_sigs()
454 {
455         pid_t   chld;
456         int     chld_status;
457
458         switch(sig_flag){
459                 case 0: break; /* do nothing*/
460                 case SIGPIPE:
461                                 /* SIGPIPE might be rarely received on use of
462                                    exec module; simply ignore it
463                                  */
464                                 LOG(L_WARN, "WARNING: SIGPIPE received and ignored\n");
465                                 break;
466                 case SIGINT:
467                 case SIGTERM:
468                         /* we end the program in all these cases */
469                         if (sig_flag==SIGINT)
470                                 DBG("INT received, program terminates\n");
471                         else
472                                 DBG("SIGTERM received, program terminates\n");
473                                 
474                         /* first of all, kill the children also */
475                         kill_all_children(SIGTERM);
476
477                              /* Wait for all the children to die */
478                         while(wait(0) > 0);
479                         
480                         cleanup(1); /* cleanup & show status*/
481                         dprint("Thank you for flying " NAME "\n");
482                         exit(0);
483                         break;
484                         
485                 case SIGUSR1:
486 #ifdef STATS
487                         dump_all_statistic();
488 #endif
489 #ifdef PKG_MALLOC
490                         LOG(memlog, "Memory status (pkg):\n");
491                         pkg_status();
492 #endif
493 #ifdef SHM_MEM
494                         LOG(memlog, "Memory status (shm):\n");
495                         shm_status();
496 #endif
497                         break;
498                         
499                 case SIGCHLD:
500                         while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
501                                 if (WIFEXITED(chld_status)) 
502                                         LOG(L_INFO, "child process %d exited normally,"
503                                                         " status=%d\n", chld, 
504                                                         WEXITSTATUS(chld_status));
505                                 else if (WIFSIGNALED(chld_status)) {
506                                         LOG(L_INFO, "child process %d exited by a signal"
507                                                         " %d\n", chld, WTERMSIG(chld_status));
508 #ifdef WCOREDUMP
509                                         LOG(L_INFO, "core was %sgenerated\n",
510                                                          WCOREDUMP(chld_status) ?  "" : "not " );
511 #endif
512                                 }else if (WIFSTOPPED(chld_status)) 
513                                         LOG(L_INFO, "child process %d stopped by a"
514                                                                 " signal %d\n", chld,
515                                                                  WSTOPSIG(chld_status));
516                         }
517 #ifndef STOP_JIRIS_CHANGES
518                         if (dont_fork) {
519                                 LOG(L_INFO, "INFO: dont_fork turned on, living on\n");
520                                 break;
521                         } 
522                         LOG(L_INFO, "INFO: terminating due to SIGCHLD\n");
523 #endif
524                         /* exit */
525                         kill_all_children(SIGTERM);
526                         if (set_sig_h(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
527                                 LOG(L_ERR, "ERROR: could not install SIGALARM handler\n");
528                                 /* continue, the process will die anyway if no
529                                  * alarm is installed which is exactly what we want */
530                         }
531                         alarm(60); /* 1 minute close timeout */
532                         while(wait(0) > 0); /* wait for all the children to terminate*/
533                         set_sig_h(SIGALRM, sig_alarm_abort);
534                         cleanup(1); /* cleanup & show status*/
535                         alarm(0);
536                         set_sig_h(SIGALRM, SIG_IGN);
537                         DBG("terminating due to SIGCHLD\n");
538                         exit(0);
539                         break;
540                 
541                 case SIGHUP: /* ignoring it*/
542                                         DBG("SIGHUP received, ignoring it\n");
543                                         break;
544                 default:
545                         LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
546         }
547         sig_flag=0;
548 }
549
550
551
552 /* added by jku; allows for regular exit on a specific signal;
553    good for profiling which only works if exited regularly and
554    not by default signal handlers
555     - modified by andrei: moved most of the stuff to handle_sigs, 
556        made it safer for the "fork" case
557 */
558 static void sig_usr(int signo)
559 {
560
561
562         if (is_main){
563                 if (sig_flag==0) sig_flag=signo;
564                 else /*  previous sig. not processed yet, ignoring? */
565                         return; ;
566                 if (dont_fork) 
567                                 /* only one proc, doing everything from the sig handler,
568                                 unsafe, but this is only for debugging mode*/
569                         handle_sigs();
570         }else{
571                 /* process the important signals */
572                 switch(signo){
573                         case SIGPIPE:
574                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
575                                 break;
576                         case SIGINT:
577                         case SIGTERM:
578                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
579                                         /* print memory stats for non-main too */
580                                         #ifdef PKG_MALLOC
581                                         LOG(memlog, "Memory status (pkg):\n");
582                                         pkg_status();
583                                         #endif
584                                         exit(0);
585                                         break;
586                         case SIGUSR1:
587                                 /* statistics, do nothing, printed only from the main proc */
588                                         break;
589                                 /* ignored*/
590                         case SIGUSR2:
591                         case SIGHUP:
592                                         break;
593                         case SIGCHLD:
594 #ifndef                         STOP_JIRIS_CHANGES
595                                         DBG("SIGCHLD received: "
596                                                 "we do not worry about grand-children\n");
597 #else
598                                         exit(0); /* terminate if one child died */
599 #endif
600                 }
601         }
602 }
603
604
605
606 /* install the signal handlers, returns 0 on success, -1 on error */
607 int install_sigs()
608 {
609         /* added by jku: add exit handler */
610         if (set_sig_h(SIGINT, sig_usr) == SIG_ERR ) {
611                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
612                 goto error;
613         }
614         /* if we debug and write to a pipe, we want to exit nicely too */
615         if (set_sig_h(SIGPIPE, sig_usr) == SIG_ERR ) {
616                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
617                 goto error;
618         }
619         if (set_sig_h(SIGUSR1, sig_usr)  == SIG_ERR ) {
620                 DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
621                 goto error;
622         }
623         if (set_sig_h(SIGCHLD , sig_usr)  == SIG_ERR ) {
624                 DPrint("ERROR: no SIGCHLD signal handler can be installed\n");
625                 goto error;
626         }
627         if (set_sig_h(SIGTERM , sig_usr)  == SIG_ERR ) {
628                 DPrint("ERROR: no SIGTERM signal handler can be installed\n");
629                 goto error;
630         }
631         if (set_sig_h(SIGHUP , sig_usr)  == SIG_ERR ) {
632                 DPrint("ERROR: no SIGHUP signal handler can be installed\n");
633                 goto error;
634         }
635         if (set_sig_h(SIGUSR2 , sig_usr)  == SIG_ERR ) {
636                 DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
637                 goto error;
638         }
639         return 0;
640 error:
641         return -1;
642 }
643
644
645
646 /* converts a username into uid:gid,
647  * returns -1 on error & 0 on success */
648 static int user2uid(int* uid, int* gid, char* user)
649 {
650         char* tmp;
651         struct passwd *pw_entry;
652         
653         if (user){
654                 *uid=strtol(user, &tmp, 10);
655                 if ((tmp==0) ||(*tmp)){
656                         /* maybe it's a string */
657                         pw_entry=getpwnam(user);
658                         if (pw_entry==0){
659                                 goto error;
660                         }
661                         *uid=pw_entry->pw_uid;
662                         if (gid) *gid=pw_entry->pw_gid;
663                 }
664                 return 0;
665         }
666 error:
667         return -1;
668 }
669
670
671
672 /* converts a group name into a gid
673  * returns -1 on error, 0 on success */
674 static int group2gid(int* gid, char* group)
675 {
676         char* tmp;
677         struct group  *gr_entry;
678         
679         if (group){
680                 *gid=strtol(group, &tmp, 10);
681                 if ((tmp==0) ||(*tmp)){
682                         /* maybe it's a string */
683                         gr_entry=getgrnam(group);
684                         if (gr_entry==0){
685                                 goto error;
686                         }
687                         *gid=gr_entry->gr_gid;
688                 }
689                 return 0;
690         }
691 error:
692         return -1;
693 }
694
695
696
697 /* returns -1 on error, 0 on success
698  * sets proto */
699 static int parse_proto(unsigned char* s, long len, int* proto)
700 {
701 #define PROTO2UINT(a, b, c) ((  (((unsigned int)(a))<<16)+ \
702                                                                 (((unsigned int)(b))<<8)+  \
703                                                                 ((unsigned int)(c)) ) | 0x20202020)
704         unsigned int i;
705         if (len!=3) return -1;
706         i=PROTO2UINT(s[0], s[1], s[2]);
707         switch(i){
708                 case PROTO2UINT('u', 'd', 'p'):
709                         *proto=PROTO_UDP;
710                         break;
711 #ifdef USE_TCP
712                 case PROTO2UINT('t', 'c', 'p'):
713                         *proto=PROTO_TCP;
714                         break;
715 #ifdef USE_TLS
716                 case PROTO2UINT('t', 'l', 's'):
717                         *proto=PROTO_TLS;
718                         break;
719 #endif
720 #endif
721                 default:
722                         return -1;
723         }
724         return 0;
725 }
726
727
728
729 /*
730  * parses [proto:]host[:port]
731  * where proto= udp|tcp|tls
732  * returns 0 on success and -1 on failure
733  */
734 static int parse_phostport(char* s, char** host, int* hlen, int* port,
735                                                         int* proto)
736 {
737         char* first; /* first ':' occurrence */
738         char* second; /* second ':' occurrence */
739         char* p;
740         int bracket;
741         char* tmp;
742         
743         first=second=0;
744         bracket=0;
745         
746         /* find the first 2 ':', ignoring possible ipv6 addresses
747          * (substrings between [])
748          */
749         for(p=s; *p; p++){
750                 switch(*p){
751                         case '[':
752                                 bracket++;
753                                 if (bracket>1) goto error_brackets;
754                                 break;
755                         case ']':
756                                 bracket--;
757                                 if (bracket<0) goto error_brackets;
758                                 break;
759                         case ':':
760                                 if (bracket==0){
761                                         if (first==0) first=p;
762                                         else if( second==0) second=p;
763                                         else goto error_colons;
764                                 }
765                                 break;
766                 }
767         }
768         if (p==s) return -1;
769         if (*(p-1)==':') goto error_colons;
770         
771         if (first==0){ /* no ':' => only host */
772                 *host=s;
773                 *hlen=(int)(p-s);
774                 *port=0;
775                 *proto=0;
776                 return 0;
777         }
778         if (second){ /* 2 ':' found => check if valid */
779                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
780                 *port=strtol(second+1, &tmp, 10);
781                 if ((tmp==0)||(*tmp)||(tmp==second+1)) goto error_port;
782                 *host=first+1;
783                 *hlen=(int)(second-*host);
784                 return 0;
785         }
786         /* only 1 ':' found => it's either proto:host or host:port */
787         *port=strtol(first+1, &tmp, 10);
788         if ((tmp==0)||(*tmp)||(tmp==first+1)){
789                 /* invalid port => it's proto:host */
790                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
791                 *port=0;
792                 *host=first+1;
793                 *hlen=(int)(p-*host);
794         }else{
795                 /* valid port => its host:port */
796                 *proto=0;
797                 *host=s;
798                 *hlen=(int)(first-*host);
799         }
800         return 0;
801 error_brackets:
802         LOG(L_ERR, "ERROR: parse_phostport: too many brackets in %s\n", s);
803         return -1;
804 error_colons:
805         LOG(L_ERR, "ERROR: parse_phostport: too many colons in %s\n", s);
806         return -1;
807 error_proto:
808         LOG(L_ERR, "ERROR: parse_phostport: bad protocol in %s\n", s);
809         return -1;
810 error_port:
811         LOG(L_ERR, "ERROR: parse_phostport: bad port number in %s\n", s);
812         return -1;
813 }
814
815
816
817 /* main loop */
818 int main_loop()
819 {
820         int  i;
821         pid_t pid;
822         struct socket_info* si;
823 #ifdef USE_TCP
824         int sockfd[2];
825 #endif
826 #ifdef EXTRA_DEBUG
827         int r;
828 #endif
829
830         /* one "main" process and n children handling i/o */
831
832         is_main=0;
833         if (dont_fork){
834 #ifdef STATS
835                 setstats( 0 );
836 #endif
837                 if (udp_listen==0){
838                         LOG(L_ERR, "ERROR: no fork mode requires at least one"
839                                         " udp listen address, exiting...\n");
840                         goto error;
841                 }
842                 /* only one address, we ignore all the others */
843                 if (udp_init(udp_listen)==-1) goto error;
844                 bind_address=udp_listen;
845                 sendipv4=bind_address;
846                 sendipv6=bind_address; /*FIXME*/
847                 if (udp_listen->next){
848                         LOG(L_WARN, "WARNING: using only the first listen address"
849                                                 " (no fork)\n");
850                 }
851                 /* initialize fifo server -- we need to open the fifo before
852                  * do_suid() and start the fifo server after all the socket 
853                  * are initialized, to inherit them*/
854                 if (init_fifo_server()<0) {
855                         LOG(L_ERR, "initializing fifo server failed\n");
856                         goto error;
857                 }
858                  /* Initialize Unix domain socket server */
859                 if (init_unixsock_socket()<0) {
860                         LOG(L_ERR, "Error while creating unix domain sockets\n");
861                         goto error;
862                 }
863                 if (do_suid()==-1) goto error; /* try to drop privileges */
864                 /* process_no now initialized to zero -- increase from now on
865                    as new processes are forked (while skipping 0 reserved for main 
866                 */
867
868 #ifdef USE_SLOW_TIMER
869                 /* we need another process to act as the "slow" timer*/
870                                 process_no++;
871                                 if ((pid=fork())<0){
872                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
873                                         goto error;
874                                 }
875                                 if (pid==0){
876                                         /* child */
877                                         pt[process_no].pid=getpid();
878                                         /* timer!*/
879                                         /* process_bit = 0; */
880                                         if (init_child(PROC_TIMER) < 0) {
881                                                 LOG(L_ERR, "slow timer: init_child failed\n");
882                                                 goto error;
883                                         }
884                                         
885                                         if (arm_slow_timer()<0) goto error;
886                                         slow_timer_main();
887                                 }else{
888                                         pt[process_no].pid=pid; /*should be shared mem anyway*/
889                                         strncpy(pt[process_no].desc, "slow timer", MAX_PT_DESC );
890                                         slow_timer_pid=pid;
891                                         
892                                 }
893 #endif
894                                 /* we need another process to act as the "main" timer*/
895                                 process_no++;
896                                 if ((pid=fork())<0){
897                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
898                                         goto error;
899                                 }
900                                 if (pid==0){
901                                         /* child */
902                                         /* record pid twice to avoid the child using it, before
903                                          * parent gets a chance to set it*/
904                                         pt[process_no].pid=getpid();
905                                         /* timer!*/
906                                         /* process_bit = 0; */
907                                         if (init_child(PROC_TIMER) < 0) {
908                                                 LOG(L_ERR, "timer: init_child failed\n");
909                                                 goto error;
910                                         }
911                                         
912                                         if (arm_timer()<0) goto error;
913                                         timer_main();
914                                 }else{
915                                                 pt[process_no].pid=pid; /*should be shared mem anyway*/
916                                                 strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
917                                 }
918
919                 /* if configured, start a server for accepting FIFO commands,
920                  * we need to do it after all the sockets are initialized, to 
921                  * inherit them*/
922                 if (start_fifo_server()<0) {
923                         LOG(L_ERR, "starting fifo server failed\n");
924                         goto error;
925                 }
926
927                 if (init_unixsock_children()<0) {
928                         LOG(L_ERR, "Error while initializing Unix domain socket server\n");
929                         goto error;
930                 }
931
932                 /* main process, receive loop */
933                 process_no=0; /*main process number*/
934                 pt[process_no].pid=getpid();
935                 snprintf(pt[process_no].desc, MAX_PT_DESC, 
936                         "stand-alone receiver @ %s:%s", 
937                          bind_address->name.s, bind_address->port_no_str.s );
938                 
939                 
940                      /* We will call child_init even if we
941                       * do not fork - and it will be called with rank 1 because
942                       * in fact we behave like a child, not like main process
943                       */
944
945                 if (init_child(1) < 0) {
946                         LOG(L_ERR, "main_dontfork: init_child failed\n");
947                         goto error;
948                 }
949
950                 is_main=1; /* hack 42: call init_child with is_main=0 in case
951                                          some modules wants to fork a child */
952                 
953                 return udp_rcv_loop();
954         }else{
955                 /* process_no now initialized to zero -- increase from now on
956                    as new processes are forked (while skipping 0 reserved for main )
957                 */
958
959                 for(si=udp_listen;si;si=si->next){
960                         /* create the listening socket (for each address)*/
961                         /* udp */
962                         if (udp_init(si)==-1) goto error;
963                         /* get first ipv4/ipv6 socket*/
964                         if ((si->address.af==AF_INET)&&
965                                         ((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
966                                 sendipv4=si;
967         #ifdef USE_IPV6
968                         if((sendipv6==0)&&(si->address.af==AF_INET6))
969                                 sendipv6=si;
970         #endif
971                 }
972 #ifdef USE_TCP
973                 if (!tcp_disable){
974                         for(si=tcp_listen; si; si=si->next){
975                                 /* same thing for tcp */
976                                 if (tcp_init(si)==-1)  goto error;
977                                 /* get first ipv4/ipv6 socket*/
978                                 if ((si->address.af==AF_INET)&&
979                                                 ((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
980                                         sendipv4_tcp=si;
981                 #ifdef USE_IPV6
982                                 if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
983                                         sendipv6_tcp=si;
984                 #endif
985                         }
986                 }
987 #ifdef USE_TLS
988                 if (!tls_disable){
989                         for(si=tls_listen; si; si=si->next){
990                                 /* same as for tcp*/
991                                 if (tls_init(si)==-1)  goto error;
992                                 /* get first ipv4/ipv6 socket*/
993                                 if ((si->address.af==AF_INET)&&
994                                                 ((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
995                                         sendipv4_tls=si;
996                 #ifdef USE_IPV6
997                                 if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
998                                         sendipv6_tls=si;
999                 #endif
1000                         }
1001                 }
1002 #endif /* USE_TLS */
1003 #endif /* USE_TCP */
1004
1005                 /* initialize fifo server -- we need to open the fifo before
1006                  * do_suid() and start the fifo server after all the socket 
1007                  * are initialized, to inherit them*/
1008                 if (init_fifo_server()<0) {
1009                         LOG(L_ERR, "initializing fifo server failed\n");
1010                         goto error;
1011                 }
1012                  /* Initialize Unix domain socket server */
1013                      /* Create the unix domain sockets */
1014                 if (init_unixsock_socket()<0) {
1015                         LOG(L_ERR, "ERROR: Could not create unix domain sockets\n");
1016                         goto error;
1017                 }
1018
1019                         /* all processes should have access to all the sockets (for sending)
1020                          * so we open all first*/
1021                 if (do_suid()==-1) goto error; /* try to drop privileges */
1022
1023                 /* if configured, start a server for accepting FIFO commands,
1024                  * we need to do it after all the sockets are initialized, to 
1025                  * inherit them*/
1026                 if (start_fifo_server()<0) {
1027                         LOG(L_ERR, "starting fifo server failed\n");
1028                         goto error;
1029                 }
1030                      /* Spawn children listening on unix domain socket if and only if
1031                       * the unix domain socket server has not been disabled (i == 0)
1032                       */
1033                 if (init_unixsock_children()<0) {
1034                         LOG(L_ERR, "ERROR: Could not initialize unix domain socket server\n");
1035                         goto error;
1036                 }
1037
1038                 /* udp processes */
1039                 for(si=udp_listen; si; si=si->next){
1040                         for(i=0;i<children_no;i++){
1041                                 process_no++;
1042 #ifdef USE_TCP
1043                                 if(!tcp_disable){
1044                                         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
1045                                                 LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
1046                                                         strerror(errno));
1047                                                 goto error;
1048                                         }
1049                                 }
1050 #endif
1051                                 if ((pid=fork())<0){
1052                                         LOG(L_CRIT,  "main_loop: Cannot fork\n");
1053                                         goto error;
1054                                 }else if (pid==0){
1055                                              /* child */
1056 #ifdef USE_TCP
1057                                         if (!tcp_disable){
1058                                                 close(sockfd[0]);
1059                                                 unix_tcp_sock=sockfd[1];
1060                                         }
1061 #endif
1062                                         /* record pid twice to avoid the child using it, before
1063                                          * parent gets a chance to set it*/
1064                                         pt[process_no].pid=getpid();
1065                                         bind_address=si; /* shortcut */
1066                                         if (init_child(i + 1) < 0) {
1067                                                 LOG(L_ERR, "init_child failed\n");
1068                                                 goto error;
1069                                         }
1070 #ifdef STATS
1071                                         setstats( i+r*children_no );
1072 #endif
1073                                         return udp_rcv_loop();
1074                                 }else{
1075                                                 pt[process_no].pid=pid; /*should be in shared mem.*/
1076                                                 snprintf(pt[process_no].desc, MAX_PT_DESC,
1077                                                         "receiver child=%d sock= %s:%s", i,     
1078                                                         si->name.s, si->port_no_str.s );
1079 #ifdef USE_TCP
1080                                                 if (!tcp_disable){
1081                                                         close(sockfd[1]);
1082                                                         pt[process_no].unix_sock=sockfd[0];
1083                                                         pt[process_no].idx=-1; /* this is not a "tcp"
1084                                                                                                           process*/
1085                                                 }
1086 #endif
1087                                 }
1088                         }
1089                         /*parent*/
1090                         /*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
1091                 }
1092         }
1093
1094         /*this is the main process*/
1095         bind_address=0;                         /* main proc -> it shouldn't send anything, */
1096         
1097
1098         {
1099 #ifdef USE_SLOW_TIMER
1100 #ifdef USE_TCP
1101                 if (!tcp_disable){
1102                         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
1103                                 LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
1104                                         strerror(errno));
1105                                 goto error;
1106                         }
1107                 }
1108 #endif
1109                 /* fork again for the "slow" timer process*/
1110                 process_no++;
1111                 if ((pid=fork())<0){
1112                         LOG(L_CRIT, "main_loop: cannot fork \"slow\" timer process\n");
1113                         goto error;
1114                 }else if (pid==0){
1115                         /* child */
1116                         /* is_main=0; */
1117 #ifdef USE_TCP
1118                         if (!tcp_disable){
1119                                 close(sockfd[0]);
1120                                 unix_tcp_sock=sockfd[1];
1121                         }
1122 #endif
1123                         /* record pid twice to avoid the child using it, before
1124                          * parent gets a chance to set it*/
1125                         pt[process_no].pid=getpid();
1126                         if (init_child(PROC_TIMER) < 0) {
1127                                 LOG(L_ERR, "slow timer: init_child failed\n");
1128                                 goto error;
1129                         }
1130                         if (arm_slow_timer()<0) goto error;
1131                         slow_timer_main();
1132                 }else{
1133                         pt[process_no].pid=pid;
1134                         strncpy(pt[process_no].desc, "slow timer", MAX_PT_DESC );
1135                         slow_timer_pid=pid;
1136 #ifdef USE_TCP
1137                         if(!tcp_disable){
1138                                                 close(sockfd[1]);
1139                                                 pt[process_no].unix_sock=sockfd[0];
1140                                                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1141                         }
1142 #endif
1143                 }
1144 #endif /* USE_SLOW_TIMER */
1145         
1146                 /* fork again for the "main" timer process*/
1147 #ifdef USE_TCP
1148                 if (!tcp_disable){
1149                         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
1150                                 LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
1151                                         strerror(errno));
1152                                 goto error;
1153                         }
1154                 }
1155 #endif
1156                 process_no++;
1157                 if ((pid=fork())<0){
1158                         LOG(L_CRIT, "main_loop: cannot fork timer process\n");
1159                         goto error;
1160                 }else if (pid==0){
1161                         /* child */
1162                         /* is_main=0; */
1163 #ifdef USE_TCP
1164                         if (!tcp_disable){
1165                                 close(sockfd[0]);
1166                                 unix_tcp_sock=sockfd[1];
1167                         }
1168 #endif
1169                         /* record pid twice to avoid the child using it, before
1170                          * parent gets a chance to set it*/
1171                         pt[process_no].pid=getpid();
1172                         if (init_child(PROC_TIMER) < 0) {
1173                                 LOG(L_ERR, "timer: init_child failed\n");
1174                                 goto error;
1175                         }
1176                         if (arm_timer()<0) goto error;
1177                         timer_main();
1178                 }else{
1179                         pt[process_no].pid=pid;
1180                         strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
1181 #ifdef USE_TCP
1182                         if(!tcp_disable){
1183                                                 close(sockfd[1]);
1184                                                 pt[process_no].unix_sock=sockfd[0];
1185                                                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1186                         }
1187 #endif
1188                 }
1189         }
1190 #ifdef USE_TCP
1191                 if (!tcp_disable){
1192                                 /* start tcp  & tls receivers */
1193                         if (tcp_init_children()<0) goto error;
1194                                 /* start tcp+tls master proc */
1195                         process_no++;
1196                         if ((pid=fork())<0){
1197                                 LOG(L_CRIT, "main_loop: cannot fork tcp main process\n");
1198                                 goto error;
1199                         }else if (pid==0){
1200                                 /* child */
1201                                 /* is_main=0; */
1202                                 /* record pid twice to avoid the child using it, before
1203                                  * parent gets a chance to set it*/
1204                                 pt[process_no].pid=getpid();
1205                                 if (init_child(PROC_TCP_MAIN) < 0) {
1206                                         LOG(L_ERR, "tcp_main: error in init_child\n");
1207                                         goto error;
1208                                 }
1209                                 tcp_main_loop();
1210                         }else{
1211                                 pt[process_no].pid=pid;
1212                                 strncpy(pt[process_no].desc, "tcp main process", MAX_PT_DESC );
1213                                 pt[process_no].unix_sock=-1;
1214                                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1215                                 unix_tcp_sock=-1;
1216                         }
1217                 }
1218 #endif
1219         /* main */
1220         pt[0].pid=getpid();
1221         strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
1222 #ifdef USE_TCP
1223         if(!tcp_disable){
1224                 pt[process_no].unix_sock=-1;
1225                 pt[process_no].idx=-1; /* this is not a "tcp" process*/
1226                 unix_tcp_sock=-1;
1227         }
1228 #endif
1229         /*DEBUG- remove it*/
1230 #ifdef EXTRA_DEBUG
1231         fprintf(stderr, "\n% 3d processes (%3d), % 3d children * "
1232                         "listening addresses + tcp listeners + tls listeners"
1233                         "+ main + fifo + timer"
1234 # ifdef USE_SLOW_TIMER
1235                         " + slow_timer"
1236 # endif
1237                         "\n", process_no+1, process_count(), children_no);
1238         for (r=0; r<=process_no; r++){
1239                 fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
1240         }
1241 #endif
1242         process_no=0; 
1243         /* process_bit = 0; */
1244         is_main=1;
1245         
1246         if (init_child(PROC_MAIN) < 0) {
1247                 LOG(L_ERR, "main: error in init_child\n");
1248                 goto error;
1249         }
1250         for(;;){
1251                         pause();
1252                         handle_sigs();
1253         }
1254         
1255         
1256         /*return 0; */
1257  error:
1258         is_main=1;  /* if we are here, we are the "main process",
1259                                   any forked children should exit with exit(-1) and not
1260                                   ever use return */
1261         return -1;
1262
1263 }
1264
1265
1266
1267
1268 int main(int argc, char** argv)
1269 {
1270
1271         FILE* cfg_stream;
1272         int c,r;
1273         char *tmp;
1274         int tmp_len;
1275         int port;
1276         int proto;
1277         char *options;
1278         int ret;
1279         unsigned int seed;
1280         int rfd;
1281
1282         /*init*/
1283         ret=-1;
1284         my_argc=argc; my_argv=argv;
1285         
1286         /*init pkg mallocs (before parsing cfg or cmd line !)*/
1287         if (init_pkg_mallocs()==-1)
1288                 goto error;
1289
1290 #ifdef DBG_MSG_QA
1291         fprintf(stderr, "WARNING: ser startup: "
1292                 "DBG_MSG_QA enabled, ser may exit abruptly\n");
1293 #endif
1294
1295
1296
1297         /* process command line (get port no, cfg. file path etc) */
1298         opterr=0;
1299         options=
1300 #ifdef STATS
1301         "s:"
1302 #endif
1303         "f:cm:b:l:n:N:rRvdDETVhw:t:u:g:P:G:i:x:W:";
1304         
1305         while((c=getopt(argc,argv,options))!=-1){
1306                 switch(c){
1307                         case 'f':
1308                                         cfg_file=optarg;
1309                                         break;
1310                         case 'c':
1311                                         config_check=1;
1312                                         log_stderr=1; /* force stderr logging */
1313                                         break;
1314                         case 's':
1315                                 #ifdef STATS
1316                                         stat_file=optarg;
1317                                 #endif
1318                                         break;
1319                         case 'm':
1320                                         shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
1321                                         if (tmp &&(*tmp)){
1322                                                 fprintf(stderr, "bad shmem size number: -m %s\n",
1323                                                                                 optarg);
1324                                                 goto error;
1325                                         };
1326                                         LOG(L_INFO, "ser: shared memory: %ld bytes\n",
1327                                                                         shm_mem_size );
1328                                         break;
1329
1330                         case 'b':
1331                                         maxbuffer=strtol(optarg, &tmp, 10);
1332                                         if (tmp &&(*tmp)){
1333                                                 fprintf(stderr, "bad max buffer size number: -p %s\n",
1334                                                                                         optarg);
1335                                                 goto error;
1336                                         }
1337                                         break;
1338                         case 'l':
1339                                         if (parse_phostport(optarg, &tmp, &tmp_len,
1340                                                                                         &port, &proto)<0){
1341                                                 fprintf(stderr, "bad -l address specifier: %s\n",
1342                                                                                 optarg);
1343                                                 goto error;
1344                                         }
1345                                         tmp[tmp_len]=0; /* null terminate the host */
1346                                         /* add a new addr. to our address list */
1347                                         if (add_listen_iface(tmp, port, proto, 0)!=0){
1348                                                 fprintf(stderr, "failed to add new listen address\n");
1349                                                 goto error;
1350                                         }
1351                                         break;
1352                         case 'n':
1353                                         children_no=strtol(optarg, &tmp, 10);
1354                                         if ((tmp==0) ||(*tmp)){
1355                                                 fprintf(stderr, "bad process number: -n %s\n",
1356                                                                         optarg);
1357                                                 goto error;
1358                                         }
1359                                         break;
1360                         case 'v':
1361                                         check_via=1;
1362                                         break;
1363                         case 'r':
1364                                         received_dns|=DO_DNS;
1365                                         break;
1366                         case 'R':
1367                                         received_dns|=DO_REV_DNS;
1368                         case 'd':
1369                                         debug++;
1370                                         break;
1371                         case 'D':
1372                                         dont_fork=1;
1373                                         break;
1374                         case 'E':
1375                                         log_stderr=1;
1376                                         break;
1377                         case 'T':
1378 #ifdef USE_TCP
1379                                         tcp_disable=1;
1380 #else
1381                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1382 #endif
1383                                         break;
1384                         case 'N':
1385 #ifdef USE_TCP
1386                                         tcp_children_no=strtol(optarg, &tmp, 10);
1387                                         if ((tmp==0) ||(*tmp)){
1388                                                 fprintf(stderr, "bad process number: -N %s\n",
1389                                                                         optarg);
1390                                                 goto error;
1391                                         }
1392 #else
1393                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1394 #endif
1395                                         break;
1396                         case 'W':
1397 #ifdef USE_TCP
1398                                         tcp_poll_method=get_poll_type(optarg);
1399                                         if (tcp_poll_method==POLL_NONE){
1400                                                 fprintf(stderr, "bad poll method name: -W %s\ntry "
1401                                                                                 "one of %s.\n", optarg, poll_support);
1402                                                 goto error;
1403                                         }
1404 #else
1405                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
1406 #endif
1407                                         break;
1408                         case 'V':
1409                                         printf("version: %s\n", version);
1410                                         printf("flags: %s\n", flags );
1411                                         print_ct_constants();
1412                                         printf("%s\n",id);
1413                                         printf("%s compiled on %s with %s\n", __FILE__,
1414                                                         compiled, COMPILER );
1415                                         
1416                                         exit(0);
1417                                         break;
1418                         case 'h':
1419                                         printf("version: %s\n", version);
1420                                         printf("%s",help_msg);
1421                                         exit(0);
1422                                         break;
1423                         case 'w':
1424                                         working_dir=optarg;
1425                                         break;
1426                         case 't':
1427                                         chroot_dir=optarg;
1428                                         break;
1429                         case 'u':
1430                                         user=optarg;
1431                                         break;
1432                         case 'g':
1433                                         group=optarg;
1434                                         break;
1435                         case 'P':
1436                                         pid_file=optarg;
1437                                         break;
1438                         case 'G':
1439                                         pgid_file=optarg;
1440                                         break;
1441                         case 'i':
1442                                         fifo=optarg;
1443                                         break;
1444                         case 'x':
1445                                         unixsock_name=optarg;
1446                                         break;
1447                         case '?':
1448                                         if (isprint(optopt))
1449                                                 fprintf(stderr, "Unknown option `-%c´.\n", optopt);
1450                                         else
1451                                                 fprintf(stderr, 
1452                                                                 "Unknown option character `\\x%x´.\n",
1453                                                                 optopt);
1454                                         goto error;
1455                         case ':':
1456                                         fprintf(stderr, 
1457                                                                 "Option `-%c´ requires an argument.\n",
1458                                                                 optopt);
1459                                         goto error;
1460                         default:
1461                                         abort();
1462                 }
1463         }
1464         
1465         /* fill missing arguments with the default values*/
1466         if (cfg_file==0) cfg_file=CFG_FILE;
1467
1468         /* load config file or die */
1469         cfg_stream=fopen (cfg_file, "r");
1470         if (cfg_stream==0){
1471                 fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
1472                                 strerror(errno));
1473                 goto error;
1474         }
1475
1476         /* seed the prng */
1477         /* try to use /dev/urandom if possible */
1478         seed=0;
1479         if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){
1480 try_again:
1481                 if (read(rfd, (void*)&seed, sizeof(seed))==-1){
1482                         if (errno==EINTR) goto try_again; /* interrupted by signal */
1483                         LOG(L_WARN, "WARNING: could not read from /dev/urandom (%d)\n",
1484                                                 errno);
1485                 }
1486                 DBG("read %u from /dev/urandom\n", seed);
1487                         close(rfd);
1488         }else{
1489                 LOG(L_WARN, "WARNING: could not open /dev/urandom (%d)\n", errno);
1490         }
1491         seed+=getpid()+time(0);
1492         DBG("seeding PRNG with %u\n", seed);
1493         srand(seed);
1494         DBG("test random number %u\n", rand());
1495         
1496         
1497         
1498         /* register a diagnostic FIFO command  - moved to fifo server - bogdan
1499         if (register_core_fifo()<0) {
1500                 LOG(L_CRIT, "unable to register core FIFO commands\n");
1501                 goto error;
1502         }*/
1503
1504         /*register builtin  modules*/
1505         register_builtin_modules();
1506
1507         yyin=cfg_stream;
1508         if ((yyparse()!=0)||(cfg_errors)){
1509                 fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
1510                 goto error;
1511         }
1512         
1513         
1514         
1515         print_rl();
1516         
1517         /* init the resolver, before fixing the config */
1518         resolv_init();
1519         /* fix parameters */
1520         if (port_no<=0) port_no=SIP_PORT;
1521 #ifdef USE_TLS
1522         if (tls_port_no<=0) tls_port_no=SIPS_PORT;
1523 #endif
1524         
1525         
1526         if (children_no<=0) children_no=CHILD_NO;
1527 #ifdef USE_TCP
1528         if (!tcp_disable){
1529                 if (tcp_children_no<=0) tcp_children_no=children_no;
1530         }
1531 #endif
1532         
1533         if (working_dir==0) working_dir="/";
1534         
1535         /* get uid/gid */
1536         if (user){
1537                 if (user2uid(&uid, &gid, user)<0){
1538                         fprintf(stderr, "bad user name/uid number: -u %s\n", user);
1539                         goto error;
1540                 }
1541         }
1542         if (group){
1543                 if (group2gid(&gid, group)<0){
1544                                 fprintf(stderr, "bad group name/gid number: -u %s\n", group);
1545                         goto error;
1546                 }
1547         }
1548         /* fix sock/fifo uid/gid */
1549         if (sock_user){
1550                 if (user2uid(&sock_uid, 0, sock_user)<0){
1551                         fprintf(stderr, "bad socket user name/uid number %s\n", user);
1552                         goto error;
1553                 }
1554         }
1555         if (sock_group){
1556                 if (group2gid(&sock_gid, sock_group)<0){
1557                         fprintf(stderr, "bad group name/gid number: -u %s\n", group);
1558                         goto error;
1559                 }
1560         }
1561         if (fix_all_socket_lists()!=0){
1562                 fprintf(stderr,  "failed to initialize list addresses\n");
1563                 goto error;
1564         }
1565         /* print all the listen addresses */
1566         printf("Listening on \n");
1567         print_all_socket_lists();
1568         printf("Aliases: \n");
1569         /*print_aliases();*/
1570         print_aliases();
1571         printf("\n");
1572         
1573         if (dont_fork){
1574                 fprintf(stderr, "WARNING: no fork mode %s\n", 
1575                                 (udp_listen)?(
1576                                 (udp_listen->next)?" and more than one listen address found"
1577                                 "(will use only the the first one)":""
1578                                 ):"and no udp listen address found" );
1579         }
1580         if (config_check){
1581                 fprintf(stderr, "config file ok, exiting...\n");
1582                 goto error;
1583         }
1584
1585
1586         /*init shm mallocs
1587          *  this must be here 
1588          *     -to allow setting shm mem size from the command line
1589          *       => if shm_mem should be settable from the cfg file move
1590          *       everything after
1591          *     -it must be also before init_timer and init_tcp
1592          *     -it must be after we know uid (so that in the SYSV sems case,
1593          *        the sems will have the correct euid)
1594          * --andrei */
1595         if (init_shm_mallocs()==-1)
1596                 goto error;
1597         /*init timer, before parsing the cfg!*/
1598         if (init_timer()<0){
1599                 LOG(L_CRIT, "could not initialize timer, exiting...\n");
1600                 goto error;
1601         }
1602         
1603         if (init_avps()<0) goto error;
1604
1605 #ifdef USE_TCP
1606         if (!tcp_disable){
1607                 /*init tcp*/
1608                 if (init_tcp()<0){
1609                         LOG(L_CRIT, "could not initialize tcp, exiting...\n");
1610                         goto error;
1611                 }
1612         }
1613 #ifdef USE_TLS
1614         if (!tls_disable){
1615                 /* init tls*/
1616                 if (init_tls()<0){
1617                         LOG(L_CRIT, "could not initialize tls, exiting...\n");
1618                         goto error;
1619                 }
1620         }
1621 #endif /* USE_TLS */
1622 #endif /* USE_TCP */
1623         /* init_daemon? */
1624         if (!dont_fork){
1625                 if ( daemonize(argv[0]) <0 ) goto error;
1626         }
1627         if (install_sigs() != 0){
1628                 fprintf(stderr, "ERROR: could not install the signal handlers\n");
1629                 goto error;
1630         }
1631         
1632         
1633         /*alloc pids*/
1634 #ifdef SHM_MEM
1635         pt=shm_malloc(sizeof(struct process_table)*process_count());
1636 #else
1637         pt=pkg_malloc(sizeof(struct process_table)*process_count());
1638 #endif
1639         if (pt==0){
1640                 fprintf(stderr, "ERROR: out  of memory\n");
1641                 goto error;
1642         }
1643         memset(pt, 0, sizeof(struct process_table)*process_count());
1644
1645         if (disable_core_dump) set_core_dump(0, 0);
1646         else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024);
1647         if (open_files_limit>0){
1648                 if(increase_open_fds(open_files_limit)<0){ 
1649                         fprintf(stderr, "ERROR: error could not increase file limits\n");
1650                         goto error;
1651                 }
1652         }
1653         
1654         if (init_modules() != 0) {
1655                 fprintf(stderr, "ERROR: error while initializing modules\n");
1656                 goto error;
1657         }
1658         /* fix routing lists */
1659         if ( (r=fix_rls())!=0){
1660                 fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
1661                                                 r);
1662                 goto error;
1663         };
1664
1665 #ifdef STATS
1666         if (init_stats(  dont_fork ? 1 : children_no  )==-1) goto error;
1667 #endif
1668         
1669         ret=main_loop();
1670         /*kill everything*/
1671         kill_all_children(SIGTERM);
1672         /*clean-up*/
1673         cleanup(0);
1674         return ret;
1675
1676 error:
1677         /*kill everything*/
1678         kill_all_children(SIGTERM);
1679         /*clean-up*/
1680         cleanup(0);
1681         return -1;
1682
1683 }
1684