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