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