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