- added new_hash2 (faster & better distrib. hash)
[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
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <ctype.h>
33 #include <string.h>
34 #include <netdb.h>
35 #include <unistd.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include <sys/utsname.h>
40 #include <sys/types.h>
41 #include <sys/mman.h>
42 #include <sys/fcntl.h>
43 #include <sys/time.h>
44 #include <sys/wait.h>
45 #include <pwd.h>
46 #include <grp.h>
47 #include <signal.h>
48
49 #include <sys/ioctl.h>
50 #include <net/if.h>
51 #ifdef __sun
52 #include <sys/sockio.h>
53 #endif
54
55 #include "config.h"
56 #include "dprint.h"
57 #include "route.h"
58 #include "udp_server.h"
59 #include "globals.h"
60 #include "mem/mem.h"
61 #ifdef SHM_MEM
62 #include "mem/shm_mem.h"
63 #endif
64 #include "sr_module.h"
65 #include "timer.h"
66 #include "parser/msg_parser.h"
67 #include "ip_addr.h"
68 #include "resolve.h"
69 #include "parser/parse_hname2.h"
70 #include "parser/digest/digest_parser.h"
71 #include "fifo_server.h"
72 #include "name_alias.h"
73 #include "hash_func.h"
74 #include "pt.h"
75
76
77 #include "stats.h"
78
79 #ifdef DEBUG_DMALLOC
80 #include <dmalloc.h>
81 #endif
82
83 static char id[]="@(#) $Id$";
84 static char version[]=  NAME " " VERSION " (" ARCH "/" OS ")" ;
85 static char compiled[]= __TIME__ __DATE__ ;
86 static char flags[]=
87 "STATS:"
88 #ifdef STATS
89 "On"
90 #else
91 "Off"
92 #endif
93 #ifdef USE_IPV6
94 ", USE_IPV6"
95 #endif
96 #ifdef NO_DEBUG
97 ", NO_DEBUG"
98 #endif
99 #ifdef NO_LOG
100 ", NO_LOG"
101 #endif
102 #ifdef EXTRA_DEBUG
103 ", EXTRA_DEBUG"
104 #endif
105 #ifdef DNS_IP_HACK
106 ", DNS_IP_HACK"
107 #endif
108 #ifdef SHM_MEM
109 ", SHM_MEM"
110 #endif
111 #ifdef SHM_MMAP
112 ", SHM_MMAP"
113 #endif
114 #ifdef PKG_MALLOC
115 ", PKG_MALLOC"
116 #endif
117 #ifdef VQ_MALLOC
118 ", VQ_MALLOC"
119 #endif
120 #ifdef F_MALLOC
121 ", F_MALLOC"
122 #endif
123 #ifdef USE_SHM_MEM
124 ", USE_SHM_MEM"
125 #endif
126 #ifdef DBG_QM_MALLOC
127 ", DBG_QM_MALLOC"
128 #endif
129 #ifdef DEBUG_DMALLOC
130 ", DEBUG_DMALLOC"
131 #endif
132 #ifdef FAST_LOCK
133 ", FAST_LOCK"
134 #ifdef BUSY_WAIT
135 "-BUSY_WAIT"
136 #endif
137 #ifdef ADAPTIVE_WAIT
138 "-ADAPTIVE_WAIT"
139 #endif
140 #ifdef NOSMP
141 "-NOSMP"
142 #endif
143 #endif /*FAST_LOCK*/
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     -p port      Listen on the specified port (default: 5060)\n\
151                  applies to the last address in -l and to all \n\
152                  following that do not have a corespponding -p\n\
153     -l address   Listen on the specified address (multiple -l mean\n\
154                  listening on more addresses). The default behaviour\n\
155                  is to listen on the addresses returned by uname(2)\n\
156 \n\
157     -n processes Number of child processes to fork per interface\n\
158                  (default: 8)\n\
159 \n\
160     -r           Use dns to check if is necessary to add a \"received=\"\n\
161                  field to a via\n\
162     -R           Same as `-r` but use reverse dns;\n\
163                  (to use both use `-rR`)\n\
164 \n\
165     -v           Turn on \"via:\" host checking when forwarding replies\n\
166     -d           Debugging mode (multiple -d increase the level)\n\
167     -D           Do not fork into daemon mode\n\
168     -E           Log to stderr\n\
169     -V           Version number\n\
170     -h           This help message\n\
171     -b nr        Maximum receive buffer size which will not be exceeded by\n\
172                  auto-probing procedure even if  OS allows\n\
173     -m nr        Size of shared memory allocated in Megabytes\n\
174     -w  dir      change the working directory to \"dir\" (default \"/\")\n\
175     -t  dir      chroot to \"dir\"\n\
176     -u uid       change uid \n\
177     -g gid       change gid \n\
178     -P file      create a pid file\n\
179     -i fifo_path create a fifo (usefull for monitoring " NAME ") \n"
180 #ifdef STATS
181 "    -s file     File to which statistics is dumped (disabled otherwise)\n"
182 #endif
183 ;
184
185 /* print compile-time constants */
186 void print_ct_constants()
187 {
188 #ifdef ADAPTIVE_WAIT
189         printf("ADAPTIVE_WAIT_LOOPS=%d, ", ADAPTIVE_WAIT_LOOPS);
190 #endif
191 /*
192 #ifdef SHM_MEM
193         printf("SHM_MEM_SIZE=%d, ", SHM_MEM_SIZE);
194 #endif
195 */
196         printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d,"
197                         " MAX_URI_SIZE %d, BUF_SIZE %d\n",
198                 MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, 
199                 BUF_SIZE );
200 }
201
202 /* debuging function */
203 /*
204 void receive_stdin_loop()
205 {
206         #define BSIZE 1024
207         char buf[BSIZE+1];
208         int len;
209
210         while(1){
211                 len=fread(buf,1,BSIZE,stdin);
212                 buf[len+1]=0;
213                 receive_msg(buf, len);
214                 printf("-------------------------\n");
215         }
216 }
217 */
218
219 /* global vars */
220
221 char* cfg_file = 0;
222 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
223                                                                                                   not want to exceed durig the
224                                                                                                   auto-probing procedure; may 
225                                                                                                   be re-configured */
226 int children_no = 0;                    /* number of children processing requests */
227 struct process_table *pt=0;             /*array with childrens pids, 0= main proc,
228                                                                         alloc'ed in shared mem if possible*/
229 int sig_flag = 0;              /* last signal received */
230 int debug = 0;
231 int dont_fork = 0;
232 int log_stderr = 0;
233 /* check if reply first via host==us */
234 int check_via =  0;        
235 /* shall use stateful synonym branches? faster but not reboot-safe */
236 int syn_branch = 1;
237 /* debugging level for memory stats */
238 int memlog = L_DBG;
239 /* should replies include extensive warnings? by default yes,
240    good for trouble-shooting
241 */
242 int sip_warning = 1;
243 /* should localy-generated messages include server's signature?
244    be default yes, good for trouble-shooting
245 */
246 int server_signature=1;
247 /* use dns and/or rdns or to see if we need to add 
248    a ;received=x.x.x.x to via: */
249 int received_dns = 0;      
250 char* working_dir = 0;
251 char* chroot_dir = 0;
252 char* user=0;
253 char* group=0;
254 int uid = 0;
255 int gid = 0;
256 /* a hint to reply modules whether they should send reply
257    to IP advertised in Via or IP from which a request came
258 */
259 int reply_to_via=0;
260
261 #if 0
262 char* names[MAX_LISTEN];              /* our names */
263 int names_len[MAX_LISTEN];            /* lengths of the names*/
264 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
265 int addresses_no=0;                   /* number of names/ips */
266 #endif
267 struct socket_info sock_info[MAX_LISTEN];/*all addresses we listen/send from*/
268 int sock_no=0; /* number of addresses/open sockets*/
269 struct socket_info* bind_address; /* pointer to the crt. proc.
270                                                                          listening address*/
271 int bind_idx; /* same as above but index in the bound[] array */
272 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
273 struct socket_info* sendipv6; /* same as above for ipv6 */
274
275 unsigned short port_no=0; /* default port*/
276
277 struct host_alias* aliases=0; /* name aliases list */
278
279 /* ipc related globals */
280 int process_no = 0;
281 /* process_bm_t process_bit = 0; */
282 #ifdef ROUTE_SRV
283 #endif
284
285 /* cfg parsing */
286 int cfg_errors=0;
287
288 /* shared memory (in MB) */
289 unsigned int shm_mem_size=SHM_MEM_SIZE * 1024 * 1024;
290
291 #define MAX_FD 32 /* maximum number of inherited open file descriptors,
292                     (normally it shouldn't  be bigger  than 3) */
293
294
295 extern FILE* yyin;
296 extern int yyparse();
297
298
299 int is_main=0; /* flag = is this the  "main" process? */
300
301 char* pid_file = 0; /* filename as asked by use */
302
303 /* daemon init, return 0 on success, -1 on error */
304 int daemonize(char*  name)
305 {
306         FILE *pid_stream;
307         pid_t pid;
308         int r, p;
309
310
311         p=-1;
312
313
314         if (chroot_dir&&(chroot(chroot_dir)<0)){
315                 LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
316                 goto error;
317         }
318         
319         if (chdir(working_dir)<0){
320                 LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
321                 goto error;
322         }
323
324         if (gid&&(setgid(gid)<0)){
325                 LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
326                 goto error;
327         }
328         
329         if(uid&&(setuid(uid)<0)){
330                 LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
331                 goto error;
332         }
333
334         /* fork to become!= group leader*/
335         if ((pid=fork())<0){
336                 LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
337                 goto error;
338         }else if (pid!=0){
339                 /* parent process => exit*/
340                 exit(0);
341         }
342         /* become session leader to drop the ctrl. terminal */
343         if (setsid()<0){
344                 LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
345         }
346         /* fork again to drop group  leadership */
347         if ((pid=fork())<0){
348                 LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
349                 goto error;
350         }else if (pid!=0){
351                 /*parent process => exit */
352                 exit(0);
353         }
354
355         /* added by noh: create a pid file for the main process */
356         if (pid_file!=0){
357                 
358                 if ((pid_stream=fopen(pid_file, "r"))!=NULL){
359                         fscanf(pid_stream, "%d", &p);
360                         fclose(pid_stream);
361                         if (p==-1){
362                                 LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
363                                         " pid number\n", pid_file);
364                                 goto error;
365                         }
366                         if (kill((pid_t)p, 0)==0 || errno==EPERM){
367                                 LOG(L_CRIT, "running process found in the pid file %s\n",
368                                         pid_file);
369                                 goto error;
370                         }else{
371                                 LOG(L_WARN, "pid file contains old pid, replacing pid\n");
372                         }
373                 }
374                 pid=getpid();
375                 if ((pid_stream=fopen(pid_file, "w"))==NULL){
376                         LOG(L_WARN, "unable to create pid file %s: %s\n", 
377                                 pid_file, strerror(errno));
378                         goto error;
379                 }else{
380                         fprintf(pid_stream, "%i\n", (int)pid);
381                         fclose(pid_stream);
382                 }
383         }
384         
385         /* close any open file descriptors */
386         for (r=0;r<MAX_FD; r++){
387                         if ((r==2) && log_stderr)  continue;
388                         close(r);
389         }
390         
391         if (log_stderr==0)
392                 openlog(name, LOG_PID|LOG_CONS, LOG_LOCAL1 /*LOG_DAEMON*/);
393                 /* LOG_CONS, LOG_PERRROR ? */
394         return  0;
395
396 error:
397         return -1;
398 }
399
400
401
402 void handle_sigs()
403 {
404         pid_t   chld;
405         int     chld_status;
406
407         switch(sig_flag){
408                 case 0: break; /* do nothing*/
409                 case SIGINT:
410                 case SIGPIPE:
411                 case SIGTERM:
412                         /* we end the program in all these cases */
413                         if (sig_flag==SIGINT)
414                                 DBG("INT received, program terminates\n");
415                         else if (sig_flag==SIGPIPE)
416                                 DBG("SIGPIPE received, program terminates\n");
417                         else
418                                 DBG("SIGTERM received, program terminates\n");
419                                 
420                         /* first of all, kill the children also */
421                         kill(0, SIGTERM);
422
423                              /* Wait for all the children to die */
424                         while(wait(0) > 0);
425
426                         destroy_modules();
427 #ifdef PKG_MALLOC
428                         LOG(memlog, "Memory status (pkg):\n");
429                         pkg_status();
430 #endif
431 #ifdef SHM_MEM
432                         LOG(memlog, "Memory status (shm):\n");
433                         shm_status();
434                         /* zero all shmem alloc vars that we still use */
435                         pt=0;
436                         shm_mem_destroy();
437 #endif
438                         if (pid_file) unlink(pid_file);
439                         dprint("Thank you for flying " NAME "\n");
440                         exit(0);
441                         break;
442                         
443                 case SIGUSR1:
444 #ifdef STATS
445                         dump_all_statistic();
446 #endif
447 #ifdef PKG_MALLOC
448                         LOG(memlog, "Memory status (pkg):\n");
449                         pkg_status();
450 #endif
451 #ifdef SHM_MEM
452                         LOG(memlog, "Memory status (shm):\n");
453                         shm_status();
454 #endif
455                         break;
456                         
457                 case SIGCHLD:
458                         while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
459                                 if (WIFEXITED(chld_status)) 
460                                         LOG(L_INFO, "child process %d exited normally,"
461                                                         " status=%d\n", chld, 
462                                                         WEXITSTATUS(chld_status));
463                                 else if (WIFSIGNALED(chld_status)) {
464                                         LOG(L_INFO, "child process %d exited by a signal"
465                                                         " %d\n", chld, WTERMSIG(chld_status));
466 #ifdef WCOREDUMP
467                                         LOG(L_INFO, "core was %sgenerated\n",
468                                                          WCOREDUMP(chld_status) ?  "" : "not " );
469 #endif
470                                 }else if (WIFSTOPPED(chld_status)) 
471                                         LOG(L_INFO, "child process %d stopped by a"
472                                                                 " signal %d\n", chld,
473                                                                  WSTOPSIG(chld_status));
474                         }
475 #ifndef STOP_JIRIS_CHANGES
476                         if (dont_fork) {
477                                 LOG(L_INFO, "INFO: dont_fork turned on, living on\n");
478                                 break;
479                         } 
480                         LOG(L_INFO, "INFO: terminating due to SIGCHLD\n");
481 #endif
482                         /* exit */
483                         kill(0, SIGTERM);
484                         DBG("terminating due to SIGCHLD\n");
485                         exit(0);
486                         break;
487                 
488                 case SIGHUP: /* ignoring it*/
489                                         DBG("SIGHUP received, ignoring it\n");
490                                         break;
491                 default:
492                         LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
493         }
494         sig_flag=0;
495 }
496
497
498
499 /* main loop */
500 int main_loop()
501 {
502         int r, i;
503         pid_t pid;
504 #ifdef WITH_SNMP_MOD
505         int (*snmp_start)();
506
507         /* initialize snmp module */
508         snmp_start = (int(*)())find_export("snmp_start", 0);
509         if(snmp_start)
510                 if(snmp_start() == -1)
511                         LOG(L_ERR, "ERROR: Couldn't start snmp agent\n");
512 #endif
513                 
514
515         /* one "main" process and n children handling i/o */
516
517
518         if (dont_fork){
519 #ifdef STATS
520                 setstats( 0 );
521 #endif
522                 /* only one address, we ignore all the others */
523                 if (udp_init(&sock_info[0])==-1) goto error;
524                 bind_address=&sock_info[0];
525                 bind_idx=0;
526                 if (sock_no>1){
527                         LOG(L_WARN, "WARNING: using only the first listen address"
528                                                 " (no fork)\n");
529                 }
530
531                 /* process_no now initialized to zero -- increase from now on
532                    as new processes are forked (while skipping 0 reserved for main 
533                 */
534
535                 /* we need another process to act as the timer*/
536                 if (timer_list){
537                                 process_no++;
538                                 if ((pid=fork())<0){
539                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
540                                         goto error;
541                                 }
542                                 
543                                 if (pid==0){
544                                         /* child */
545                                         /* timer!*/
546                                         /* process_bit = 0; */
547                                         for(;;){
548                                                 sleep(TIMER_TICK);
549                                                 timer_ticker();
550                                         }
551                                 }else{
552                                                 pt[process_no].pid=pid; /*should be shared mem anway*/
553                                                 strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
554                                 }
555                 }
556
557                 /* if configured to do so, start a server for accepting FIFO commands */
558                 if (open_fifo_server()<0) {
559                         LOG(L_ERR, "opening fifo server failed\n");
560                         goto error;
561                 }
562                 /* main process, receive loop */
563                 process_no=0; /*main process number*/
564                 pt[process_no].pid=getpid();
565                 snprintf(pt[process_no].desc, MAX_PT_DESC, 
566                         "stand-alone receiver @ %s:%s", 
567                          bind_address->name.s, bind_address->port_no_str.s );
568                 
569                 
570                      /* We will call child_init even if we
571                       * do not fork
572                       */
573
574                 if (init_child(0) < 0) {
575                         LOG(L_ERR, "init_child failed\n");
576                         goto error;
577                 }
578
579                 is_main=1; /* hack 42: call init_child with is_main=0 in case
580                                          some modules wants to fork a child */
581                 
582                 return udp_rcv_loop();
583         }else{
584                 /* process_no now initialized to zero -- increase from now on
585                    as new processes are forked (while skipping 0 reserved for main )
586                 */
587                 for(r=0;r<sock_no;r++){
588                         /* create the listening socket (for each address)*/
589                         if (udp_init(&sock_info[r])==-1) goto error;
590                         /* get first ipv4/ipv6 socket*/
591                         if ((sendipv4==0)&&(sock_info[r].address.af==AF_INET))
592                                 sendipv4=&sock_info[r];
593         #ifdef USE_IPV6
594                         if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
595                                 sendipv6=&sock_info[r];
596         #endif
597                         /* all procs should have access to all the sockets (for sending)
598                          * so we open all first*/
599                 }
600                 for(r=0; r<sock_no;r++){
601                         for(i=0;i<children_no;i++){
602                                 process_no++;
603                                 if ((pid=fork())<0){
604                                         LOG(L_CRIT,  "main_loop: Cannot fork\n");
605                                         goto error;
606                                 }else if (pid==0){
607                                              /* child */
608                                         bind_address=&sock_info[r]; /* shortcut */
609                                         bind_idx=r;
610                                         if (init_child(i) < 0) {
611                                                 LOG(L_ERR, "init_child failed\n");
612                                                 goto error;
613                                         }
614 #ifdef STATS
615                                         setstats( i+r*children_no );
616 #endif
617                                         return udp_rcv_loop();
618                                 }else{
619                                                 pt[process_no].pid=pid; /*should be in shared mem.*/
620                                                 snprintf(pt[process_no].desc, MAX_PT_DESC,
621                                                         "receiver child=%d sock=%d @ %s:%s", i, r,      
622                                                         sock_info[r].name.s, sock_info[r].port_no_str.s );
623                                 }
624                         }
625                         /*parent*/
626                         /*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
627                 }
628         }
629
630         /*this is the main process*/
631         bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, */
632         bind_idx=0;                                     /* if it does it will use the first address */
633         /* if configured to do so, start a server for accepting FIFO commands */
634         if (open_fifo_server()<0) {
635                 LOG(L_ERR, "opening fifo server failed\n");
636                 goto error;
637         }
638
639         if (timer_list){
640                 /* fork again for the attendant process*/
641                 process_no++;
642                 if ((pid=fork())<0){
643                         LOG(L_CRIT, "main_loop: cannot fork timer process\n");
644                         goto error;
645                 }else if (pid==0){
646                         /* child */
647                         /* is_main=0; */
648                         for(;;){
649                                 /* debug:  instead of doing something usefull */
650                                 /* (placeholder for timers, etc.) */
651                                 sleep(TIMER_TICK);
652                                 /* if we received a signal => TIMER_TICK may have not elapsed*/
653                                 timer_ticker();
654                         }
655                 }else{
656                         pt[process_no].pid=pid;
657                         strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
658                 }
659         }
660
661         /* main */
662         pt[0].pid=getpid();
663         strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
664         /*DEBUG- remove it*/
665 #ifdef DEBUG
666         printf("\n% 3d processes, % 3d children * % 3d listening addresses + main"
667                         " + fifo %s\n", process_no+1, children_no, sock_no,
668                         (timer_list)?"+ timer":"");
669         for (r=0; r<=process_no; r++){
670                 printf("% 3d   % 5d\n", r, pt[r].pid);
671         }
672 #endif
673         process_no=0; 
674         /* process_bit = 0; */
675         is_main=1;
676         
677         for(;;){
678                         pause();
679                         handle_sigs();
680         }
681         
682         
683         /*return 0; */
684  error:
685         return -1;
686
687 }
688
689
690 /* added by jku; allows for regular exit on a specific signal;
691    good for profiling which only works if exited regularly and
692    not by default signal handlers
693     - modified by andrei: moved most of the stuff to handle_sigs, 
694        made it safer for the "fork" case
695 */
696 static void sig_usr(int signo)
697 {
698
699
700         if (is_main){
701                 if (sig_flag==0) sig_flag=signo;
702                 else /*  previous sig. not processed yet, ignoring? */
703                         return; ;
704                 if (dont_fork) 
705                                 /* only one proc, doing everything from the sig handler,
706                                 unsafe, but this is only for debugging mode*/
707                         handle_sigs();
708         }else{
709                 /* process the important signals */
710                 switch(signo){
711                         case SIGINT:
712                         case SIGPIPE:
713                         case SIGTERM:
714                                         /* print memory stats for non-main too */
715                                         #ifdef PKG_MALLOC
716                                         LOG(memlog, "Memory status (pkg):\n");
717                                         pkg_status();
718                                         #endif
719                                         exit(0);
720                                         break;
721                         case SIGUSR1:
722                                 /* statistics, do nothing, printed only from the main proc */
723                                         break;
724                                 /* ignored*/
725                         case SIGUSR2:
726                         case SIGHUP:
727                                         break;
728                         case SIGCHLD:
729 #ifndef                         STOP_JIRIS_CHANGES
730                                         LOG(L_INFO, "INFO: SIGCHLD received: "
731                                                 "we do not worry about grand-children\n");
732 #else
733                                         exit(0); /* terminate if one child died */
734 #endif
735                 }
736         }
737 }
738
739
740
741 /* add all family type addresses of interface if_name to the socket_info array
742  * if if_name==0, adds all addresses on all interfaces
743  * WARNING: it only works with ipv6 addresses on FreeBSD
744  * return: -1 on error, 0 on success
745  */
746 int add_interfaces(char* if_name, int family, unsigned short port)
747 {
748         struct ifconf ifc;
749         struct ifreq* ifr;
750         struct ifreq ifrcopy;
751         char*  last;
752         int size;
753         int lastlen;
754         int s;
755         char* tmp;
756         struct ip_addr addr;
757         int ret;
758
759 #ifdef __FreeBSD__
760         #define MAX(a,b) ( ((a)>(b))?(a):(b))
761 #endif
762         /* ipv4 or ipv6 only*/
763         s=socket(family, SOCK_DGRAM, 0);
764         ret=-1;
765         lastlen=0;
766         ifc.ifc_req=0;
767         for (size=10; ; size*=2){
768                 ifc.ifc_len=size*sizeof(struct ifreq);
769                 ifc.ifc_req=(struct ifreq*) malloc(size*sizeof(struct ifreq));
770                 if (ifc.ifc_req==0){
771                         fprintf(stderr, "memory allocation failure\n");
772                         goto error;
773                 }
774                 if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
775                         if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
776                         fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
777                         goto error;
778                 }
779                 if  ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,
780                                                                                                                    len not changed*/
781                 lastlen=ifc.ifc_len;
782                 /* try a bigger array*/
783                 free(ifc.ifc_req);
784         }
785         
786         last=(char*)ifc.ifc_req+ifc.ifc_len;
787         for(ifr=ifc.ifc_req; (char*)ifr<last;
788                         ifr=(struct ifreq*)((char*)ifr+sizeof(ifr->ifr_name)+
789                         #ifdef  __FreeBSD__
790                                 MAX(ifr->ifr_addr.sa_len, sizeof(struct sockaddr))
791                         #else
792                                 ( (ifr->ifr_addr.sa_family==AF_INET)?
793                                         sizeof(struct sockaddr_in):
794                                         ((ifr->ifr_addr.sa_family==AF_INET6)?
795                                                 sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )
796                         #endif
797                                 )
798                 )
799         {
800                 if (ifr->ifr_addr.sa_family!=family){
801                         /*printf("strange family %d skipping...\n",
802                                         ifr->ifr_addr.sa_family);*/
803                         continue;
804                 }
805                 
806                 if (if_name==0){ /* ignore down ifs only if listening on all of them*/
807                         memcpy(&ifrcopy, ifr, sizeof(ifrcopy));
808                         /*get flags*/
809                         if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1){ /* ignore errors */
810                                 /* if if not up, skip it*/
811                                 if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
812                         }
813                 }
814                 
815                 
816                 
817                 if ((if_name==0)||
818                         (strncmp(if_name, ifr->ifr_name, sizeof(ifr->ifr_name))==0)){
819                         
820                                 /*add address*/
821                         if (sock_no<MAX_LISTEN){
822                                 sockaddr2ip_addr(&addr, &ifr->ifr_addr);
823                                 if ((tmp=ip_addr2a(&addr))==0) goto error;
824                                 /* fill the strings*/
825                                 sock_info[sock_no].name.s=(char*)malloc(strlen(tmp)+1);
826                                 if(sock_info[sock_no].name.s==0){
827                                         fprintf(stderr, "Out of memory.\n");
828                                         goto error;
829                                 }
830                                 /* fill in the new name and port */
831                                 sock_info[sock_no].name.len=strlen(tmp);
832                                 strncpy(sock_info[sock_no].name.s, tmp, 
833                                                         sock_info[sock_no].name.len+1);
834                                 sock_info[sock_no].port_no=port;
835                                 sock_no++;
836                                 ret=0;
837                         }else{
838                                 fprintf(stderr, "Too many addresses (max %d)\n", MAX_LISTEN);
839                                 goto error;
840                         }
841                 }
842                         /*
843                         printf("%s:\n", ifr->ifr_name);
844                         printf("        ");
845                         print_sockaddr(&(ifr->ifr_addr));
846                         printf("        ");
847                         ls_ifflags(ifr->ifr_name, family, options);
848                         printf("\n");*/
849         }
850         free(ifc.ifc_req); /*clean up*/
851         close(s);
852         return  ret;
853 error:
854         if (ifc.ifc_req) free(ifc.ifc_req);
855         close(s);
856         return -1;
857 }
858
859
860
861 int main(int argc, char** argv)
862 {
863
864         FILE* cfg_stream;
865         struct hostent* he;
866         int c,r,t;
867         char *tmp;
868         char** h;
869         struct host_alias* a;
870         struct utsname myname;
871         char *options;
872         char port_no_str[MAX_PORT_LEN];
873         int port_no_str_len;
874         int ret;
875         struct passwd *pw_entry;
876         struct group  *gr_entry;
877
878         /*init*/
879         port_no_str_len=0;
880         ret=-1;
881         
882         /* added by jku: add exit handler */
883         if (signal(SIGINT, sig_usr) == SIG_ERR ) {
884                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
885                 goto error;
886         }
887         /* if we debug and write to a pipe, we want to exit nicely too */
888         if (signal(SIGPIPE, sig_usr) == SIG_ERR ) {
889                 DPrint("ERROR: no SIGINT signal handler can be installed\n");
890                 goto error;
891         }
892
893         if (signal(SIGUSR1, sig_usr)  == SIG_ERR ) {
894                 DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
895                 goto error;
896         }
897         if (signal(SIGCHLD , sig_usr)  == SIG_ERR ) {
898                 DPrint("ERROR: no SIGCHLD signal handler can be installed\n");
899                 goto error;
900         }
901         if (signal(SIGTERM , sig_usr)  == SIG_ERR ) {
902                 DPrint("ERROR: no SIGTERM signal handler can be installed\n");
903                 goto error;
904         }
905         if (signal(SIGHUP , sig_usr)  == SIG_ERR ) {
906                 DPrint("ERROR: no SIGHUP signal handler can be installed\n");
907                 goto error;
908         }
909         if (signal(SIGUSR2 , sig_usr)  == SIG_ERR ) {
910                 DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
911                 goto error;
912         }
913 #ifdef DBG_MSG_QA
914         fprintf(stderr, "WARNING: ser startup: "
915                 "DBG_MSG_QA enabled, ser may exit abruptly\n");
916 #endif
917
918
919
920         /* process command line (get port no, cfg. file path etc) */
921         opterr=0;
922         options=
923 #ifdef STATS
924         "s:"
925 #endif
926         "f:p:m:b:l:n:rRvdDEVhw:t:u:g:P:i:";
927         
928         while((c=getopt(argc,argv,options))!=-1){
929                 switch(c){
930                         case 'f':
931                                         cfg_file=optarg;
932                                         break;
933                         case 's':
934                                 #ifdef STATS
935                                         stat_file=optarg;
936                                 #endif
937                                         break;
938                         case 'p':
939                                         port_no=strtol(optarg, &tmp, 10);
940                                         if (tmp &&(*tmp)){
941                                                 fprintf(stderr, "bad port number: -p %s\n", optarg);
942                                                 goto error;
943                                         }
944                                         if (sock_no>0) sock_info[sock_no-1].port_no=port_no;
945                                         break;
946
947                         case 'm':
948                                         shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
949                                         if (tmp &&(*tmp)){
950                                                 fprintf(stderr, "bad shmem size number: -m %s\n",
951                                                                                 optarg);
952                                                 goto error;
953                                         };
954                                         LOG(L_INFO, "ser: shared memory allocated: %d MByte\n",
955                                                                         shm_mem_size );
956                                         break;
957
958                         case 'b':
959                                         maxbuffer=strtol(optarg, &tmp, 10);
960                                         if (tmp &&(*tmp)){
961                                                 fprintf(stderr, "bad max buffer size number: -p %s\n",
962                                                                                         optarg);
963                                                 goto error;
964                                         }
965                                         break;
966                         case 'l':
967                                         /* add a new addr. to our address list */
968                                         if (sock_no < MAX_LISTEN){
969                                                 sock_info[sock_no].name.s=
970                                                                                 (char*)malloc(strlen(optarg)+1);
971                                                 if (sock_info[sock_no].name.s==0){
972                                                         fprintf(stderr, "Out of memory.\n");
973                                                         goto error;
974                                                 }
975                                                 strncpy(sock_info[sock_no].name.s, optarg,
976                                                                                                 strlen(optarg)+1);
977                                                 sock_info[sock_no].name.len=strlen(optarg);
978                                                 /* set default port */
979                                                 sock_info[sock_no].port_no=port_no;
980                                                 sock_no++;
981                                         }else{
982                                                 fprintf(stderr, 
983                                                                         "Too many addresses (max. %d).\n",
984                                                                         MAX_LISTEN);
985                                                 goto error;
986                                         }
987                                         break;
988                         case 'n':
989                                         children_no=strtol(optarg, &tmp, 10);
990                                         if ((tmp==0) ||(*tmp)){
991                                                 fprintf(stderr, "bad process number: -n %s\n",
992                                                                         optarg);
993                                                 goto error;
994                                         }
995                                         break;
996                         case 'v':
997                                         check_via=1;
998                                         break;
999                         case 'r':
1000                                         received_dns|=DO_DNS;
1001                                         break;
1002                         case 'R':
1003                                         received_dns|=DO_REV_DNS;
1004                         case 'd':
1005                                         debug++;
1006                                         break;
1007                         case 'D':
1008                                         dont_fork=1;
1009                                         break;
1010                         case 'E':
1011                                         log_stderr=1;
1012                                         break;
1013                         case 'V':
1014                                         printf("version: %s\n", version);
1015                                         printf("flags: %s\n", flags );
1016                                         print_ct_constants();
1017                                         printf("%s\n",id);
1018                                         printf("%s compiled on %s with %s\n", __FILE__,
1019                                                         compiled, COMPILER );
1020                                         
1021                                         exit(0);
1022                                         break;
1023                         case 'h':
1024                                         printf("version: %s\n", version);
1025                                         printf("%s",help_msg);
1026                                         exit(0);
1027                                         break;
1028                         case 'w':
1029                                         working_dir=optarg;
1030                                         break;
1031                         case 't':
1032                                         chroot_dir=optarg;
1033                                         break;
1034                         case 'u':
1035                                         user=optarg;
1036                                         break;
1037                         case 'g':
1038                                         group=optarg;
1039                                         break;
1040                         case 'P':
1041                                         pid_file=optarg;
1042                                         break;
1043                         case 'i':
1044                                         fifo=optarg;
1045                                         break;
1046                         case '?':
1047                                         if (isprint(optopt))
1048                                                 fprintf(stderr, "Unknown option `-%c´.\n", optopt);
1049                                         else
1050                                                 fprintf(stderr, 
1051                                                                 "Unknown option character `\\x%x´.\n",
1052                                                                 optopt);
1053                                         goto error;
1054                         case ':':
1055                                         fprintf(stderr, 
1056                                                                 "Option `-%c´ requires an argument.\n",
1057                                                                 optopt);
1058                                         goto error;
1059                         default:
1060                                         abort();
1061                 }
1062         }
1063         
1064         /* fill missing arguments with the default values*/
1065         if (cfg_file==0) cfg_file=CFG_FILE;
1066
1067         /* load config file or die */
1068         cfg_stream=fopen (cfg_file, "r");
1069         if (cfg_stream==0){
1070                 fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
1071                                 strerror(errno));
1072                 goto error;
1073         }
1074
1075
1076         init_hfname_parser();
1077         init_digest_parser();
1078
1079         /* init hash fucntion */
1080         if (init_hash()<0) {
1081                 LOG(L_ERR, "ERROR: init_hash failed\n");
1082                 goto error;
1083         }
1084
1085         /*init mallocs (before parsing cfg !)*/
1086         if (init_mallocs()==-1)
1087                 goto error;
1088
1089         /*init timer, before parsing the cfg!*/
1090         if (init_timer()<0){
1091                 LOG(L_CRIT, "could not initialize timer, exiting...\n");
1092                 goto error;
1093         }
1094
1095         /* register a diagnostic FIFO command */
1096         if (register_core_fifo()<0) {
1097                 LOG(L_CRIT, "unable to register core FIFO commands\n");
1098                 goto error;
1099         }
1100
1101         /*register builtin  modules*/
1102         register_builtin_modules();
1103
1104         yyin=cfg_stream;
1105         if ((yyparse()!=0)||(cfg_errors)){
1106                 fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
1107                 goto error;
1108         }
1109
1110
1111
1112         print_rl();
1113
1114         /* fix parameters */
1115         if (port_no<=0) port_no=SIP_PORT;
1116
1117         
1118         if (children_no<=0) children_no=CHILD_NO;
1119 #ifdef _OBSOLETED
1120         else if (children_no >= MAX_PROCESSES ) {
1121                 fprintf(stderr, "ERROR: too many children processes configured;"
1122                                 " maximum is %d\n",
1123                         MAX_PROCESSES-1 );
1124                 goto error;
1125         }
1126 #endif
1127         
1128         if (working_dir==0) working_dir="/";
1129         
1130         /* get uid/gid */
1131         if (user){
1132                 uid=strtol(user, &tmp, 10);
1133                 if ((tmp==0) ||(*tmp)){
1134                         /* maybe it's a string */
1135                         pw_entry=getpwnam(user);
1136                         if (pw_entry==0){
1137                                 fprintf(stderr, "bad user name/uid number: -u %s\n", user);
1138                                 goto error;
1139                         }
1140                         uid=pw_entry->pw_uid;
1141                         gid=pw_entry->pw_gid;
1142                 }
1143         }
1144         if (group){
1145                 gid=strtol(user, &tmp, 10);
1146                 if ((tmp==0) ||(*tmp)){
1147                         /* maybe it's a string */
1148                         gr_entry=getgrnam(group);
1149                         if (gr_entry==0){
1150                                 fprintf(stderr, "bad group name/gid number: -u %s\n", group);
1151                                 goto error;
1152                         }
1153                         gid=gr_entry->gr_gid;
1154                 }
1155         }
1156
1157         if (sock_no==0) {
1158                 /* try to get all listening ipv4 interfaces */
1159                 if (add_interfaces(0, AF_INET, 0)==-1){
1160                         /* if error fall back to get hostname*/
1161                         /* get our address, only the first one */
1162                         if (uname (&myname) <0){
1163                                 fprintf(stderr, "cannot determine hostname, try -l address\n");
1164                                 goto error;
1165                         }
1166                         sock_info[sock_no].name.s=(char*)malloc(strlen(myname.nodename)+1);
1167                         if (sock_info[sock_no].name.s==0){
1168                                 fprintf(stderr, "Out of memory.\n");
1169                                 goto error;
1170                         }
1171                         sock_info[sock_no].name.len=strlen(myname.nodename);
1172                         strncpy(sock_info[sock_no].name.s, myname.nodename,
1173                                         sock_info[sock_no].name.len+1);
1174                         sock_no++;
1175                 }
1176         }
1177
1178         /* try to change all the interface names into addresses
1179          *  --ugly hack */
1180         for (r=0; r<sock_no;){
1181                 if (add_interfaces(sock_info[r].name.s, AF_INET,
1182                                         sock_info[r].port_no)!=-1){
1183                         /* success => remove current entry (shift the entire array)*/
1184                         free(sock_info[r].name.s);
1185                         memmove(&sock_info[r], &sock_info[r+1], 
1186                                                 (sock_no-r)*sizeof(struct socket_info));
1187                         sock_no--;
1188                         continue;
1189                 }
1190                 r++;
1191         }
1192         /* get ips & fill the port numbers*/
1193 #ifdef EXTRA_DEBUG
1194         printf("Listening on \n");
1195 #endif
1196         for (r=0; r<sock_no;r++){
1197                 he=resolvehost(sock_info[r].name.s);
1198                 if (he==0){
1199                         DPrint("ERROR: could not resolve %s\n", sock_info[r].name.s);
1200                         goto error;
1201                 }
1202                 /* check if we got the official name */
1203                 if (strcasecmp(he->h_name, sock_info[r].name.s)!=0){
1204                         if (add_alias(sock_info[r].name.s, sock_info[r].name.len)<0){
1205                                 LOG(L_ERR, "ERROR: main: add_alias failed\n");
1206                         }
1207                         /* change the oficial name */
1208                         free(sock_info[r].name.s);
1209                         sock_info[r].name.s=(char*)malloc(strlen(he->h_name)+1);
1210                         if (sock_info[r].name.s==0){
1211                                 fprintf(stderr, "Out of memory.\n");
1212                                 goto error;
1213                         }
1214                         sock_info[r].name.len=strlen(he->h_name);
1215                         strncpy(sock_info[r].name.s, he->h_name, sock_info[r].name.len+1);
1216                 }
1217                 /* add the aliases*/
1218                 for(h=he->h_aliases; h && *h; h++)
1219                         if (add_alias(*h, strlen(*h))<0){
1220                                 LOG(L_ERR, "ERROR: main: add_alias failed\n");
1221                         }
1222                 hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr 
1223                                                                                                                  format*/
1224                 if ((tmp=ip_addr2a(&sock_info[r].address))==0) goto error;
1225                 sock_info[r].address_str.s=(char*)malloc(strlen(tmp)+1);
1226                 if (sock_info[r].address_str.s==0){
1227                         fprintf(stderr, "Out of memory.\n");
1228                         goto error;
1229                 }
1230                 strncpy(sock_info[r].address_str.s, tmp, strlen(tmp)+1);
1231                 /* set is_ip (1 if name is an ip address, 0 otherwise) */
1232                 sock_info[r].address_str.len=strlen(tmp);
1233                 if      (       (sock_info[r].address_str.len==sock_info[r].name.len)&&
1234                                 (strncasecmp(sock_info[r].address_str.s, sock_info[r].name.s,
1235                                                  sock_info[r].address_str.len)==0)
1236                         ){
1237                                 sock_info[r].is_ip=1;
1238                                 /* do rev. dns on it (for aliases)*/
1239                                 he=rev_resolvehost(&sock_info[r].address);
1240                                 if (he==0){
1241                                         DPrint("WARNING: could not rev. resolve %s\n",
1242                                                         sock_info[r].name.s);
1243                                 }else{
1244                                         /* add the aliases*/
1245                                         if (add_alias(he->h_name, strlen(he->h_name))<0){
1246                                                 LOG(L_ERR, "ERROR: main: add_alias failed\n");
1247                                         }
1248                                         for(h=he->h_aliases; h && *h; h++)
1249                                                 if (add_alias(*h, strlen(*h))<0){
1250                                                         LOG(L_ERR, "ERROR: main: add_alias failed\n");
1251                                                 }
1252                                 }
1253                 }else{ sock_info[r].is_ip=0; };
1254                         
1255                 if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
1256                 port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
1257                                                                         (unsigned short) sock_info[r].port_no);
1258                 if (port_no_str_len<0){
1259                         fprintf(stderr, "ERROR: bad port number: %d\n", 
1260                                                 sock_info[r].port_no);
1261                         goto error;
1262                 }
1263                 /* on some systems snprintf returns really strange things if it does 
1264                   not have  enough space */
1265                 port_no_str_len=
1266                                 (port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
1267                 sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
1268                 if (sock_info[r].port_no_str.s==0){
1269                         fprintf(stderr, "Out of memory.\n");
1270                         goto error;
1271                 }
1272                 strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
1273                 sock_info[r].port_no_str.len=strlen(port_no_str);
1274                 
1275 #ifdef EXTRA_DEBUG
1276                 printf("              %.*s [%s]:%s\n", sock_info[r].name.len, 
1277                                 sock_info[r].name.s,
1278                                 sock_info[r].address_str.s, sock_info[r].port_no_str.s);
1279 #endif
1280         }
1281         /* removing duplicate addresses*/
1282         for (r=0; r<sock_no; r++){
1283                 for (t=r+1; t<sock_no;){
1284                         if ((sock_info[r].port_no==sock_info[t].port_no) &&
1285                                 (sock_info[r].address.af==sock_info[t].address.af) &&
1286                                 (memcmp(sock_info[r].address.u.addr, 
1287                                                 sock_info[t].address.u.addr,
1288                                                 sock_info[r].address.len)  == 0)
1289                                 ){
1290 #ifdef EXTRA_DEBUG
1291                                 printf("removing duplicate (%d) %s [%s] == (%d) %s [%s]\n",
1292                                                 r, sock_info[r].name.s, sock_info[r].address_str.s,
1293                                                 t, sock_info[t].name.s, sock_info[t].address_str.s);
1294 #endif
1295                                 /* add the name to the alias list*/
1296                                 if ((!sock_info[t].is_ip) && (
1297                                                 (sock_info[t].name.len!=sock_info[r].name.len)||
1298                                                 (strncmp(sock_info[t].name.s, sock_info[r].name.s,
1299                                                                  sock_info[r].name.len)!=0))
1300                                         )
1301                                         add_alias(sock_info[t].name.s, sock_info[t].name.len);
1302                                                 
1303                                 /* free space*/
1304                                 free(sock_info[t].name.s);
1305                                 free(sock_info[t].address_str.s);
1306                                 free(sock_info[t].port_no_str.s);
1307                                 /* shift the array*/
1308                                 memmove(&sock_info[t], &sock_info[t+1], 
1309                                                         (sock_no-t)*sizeof(struct socket_info));
1310                                 sock_no--;
1311                                 continue;
1312                         }
1313                         t++;
1314                 }
1315         }
1316         /* print all the listen addresses */
1317         printf("Listening on \n");
1318         for (r=0; r<sock_no; r++)
1319                 printf("              %s [%s]:%s\n",sock_info[r].name.s,
1320                                 sock_info[r].address_str.s, sock_info[r].port_no_str.s);
1321
1322         printf("Aliases: ");
1323         for(a=aliases; a; a=a->next) printf("%.*s ", a->alias.len, a->alias.s);
1324         printf("\n");
1325         if (sock_no==0){
1326                 fprintf(stderr, "ERROR: no listening sockets");
1327                 goto error;
1328         }
1329         if (dont_fork){
1330                 fprintf(stderr, "WARNING: no fork mode %s\n", 
1331                                 (sock_no>1)?" and more than one listen address found (will"
1332                                                         " use only the the first one)":"");
1333         }
1334         
1335         /* init_daemon? */
1336         if (!dont_fork){
1337                 if ( daemonize(argv[0]) <0 ) goto error;
1338         }
1339         if (init_modules() != 0) {
1340                 fprintf(stderr, "ERROR: error while initializing modules\n");
1341                 goto error;
1342         }
1343         
1344         /*alloc pids*/
1345 #ifdef SHM_MEM
1346         pt=shm_malloc(sizeof(struct process_table)*process_count());
1347 #else
1348         pt=malloc(sizeof(struct process_table)*process_count());
1349 #endif
1350         if (pt==0){
1351                 fprintf(stderr, "ERROR: out  of memory\n");
1352                 goto error;
1353         }
1354         memset(pt, 0, sizeof(struct process_table)*process_count());
1355         /* fix routing lists */
1356         if ( (r=fix_rls())!=0){
1357                 fprintf(stderr, "ERROR: error %x while trying to fix configuration\n",
1358                                                 r);
1359                 goto error;
1360         };
1361
1362 #ifdef STATS
1363         if (init_stats(  dont_fork ? 1 : children_no  )==-1) goto error;
1364 #endif
1365         
1366         ret=main_loop();
1367         /*kill everything*/
1368         kill(0, SIGTERM);
1369         return ret;
1370
1371 error:
1372         /*kill everything*/
1373         kill(0, SIGTERM);
1374         return -1;
1375
1376 }
1377