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