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