• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

main.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of SIP-router, a free SIP server.
00007  *
00008  * SIP-router is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * SIP-router is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * -------
00024  *  2002-01-29  argc/argv globalized via my_{argc|argv} (jiri)
00025  *  2003-01-23  mhomed added (jiri)
00026  *  2003-03-19  replaced all malloc/frees w/ pkg_malloc/pkg_free (andrei)
00027  *  2003-03-29  pkg cleaners for fifo and script callbacks introduced (jiri)
00028  *  2003-03-31  removed snmp part (obsolete & no place in core) (andrei)
00029  *  2003-04-06  child_init called in all processes (janakj)
00030  *  2003-04-08  init_mallocs split into init_{pkg,shm}_mallocs and
00031  *               init_shm_mallocs called after cmd. line parsing (andrei)
00032  *  2003-04-15  added tcp_disable support (andrei)
00033  *  2003-05-09  closelog() before openlog to force opening a new fd
00034  *               (needed on solaris) (andrei)
00035  *  2003-06-11  moved all signal handlers init. in install_sigs and moved it
00036  *               after daemonize (so that we won't catch anymore our own
00037  *               SIGCHLD generated when becoming session leader) (andrei)
00038  *              changed is_main default value to 1 (andrei)
00039  *  2003-06-28  kill_all_children is now used instead of kill(0, sig)
00040  *                see comment above it for explanations. (andrei)
00041  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
00042  *  2003-10-10  added switch for config check (-c) (andrei)
00043  *  2003-10-24  converted to the new socket_info lists (andrei)
00044  *  2004-03-30  core dump is enabled by default
00045  *              added support for increasing the open files limit    (andrei)
00046  *  2004-04-28  sock_{user,group,uid,gid,mode} added
00047  *              user2uid() & user2gid() added  (andrei)
00048  *  2004-09-11  added timeout on children shutdown and final cleanup
00049  *               (if it takes more than 60s => something is definitely wrong
00050  *                => kill all or abort)  (andrei)
00051  *              force a shm_unlock before cleaning-up, in case we have a
00052  *               crashed childvwhich still holds the lock  (andrei)
00053  *  2004-12-02  removed -p, extended -l to support [proto:]address[:port],
00054  *               added parse_phostport, parse_proto (andrei)
00055  *  2005-06-16  always record the pid in pt[process_no].pid twice: once in the
00056  *               parent & once in the child to avoid a short window when one
00057  *               of them might use it "unset" (andrei)
00058  *  2005-07-25  use sigaction for setting the signal handlers (andrei)
00059  *  2006-07-13  added dns cache/failover init. (andrei)
00060  *  2006-10-13  added global variables stun_refresh_interval, stun_allow_stun
00061  *               and stun_allow_fp (vlada)
00062  *  2006-10-25  don't log messages from signal handlers if NO_SIG_DEBUG is
00063  *               defined; improved exit kill timeout (andrei)
00064  *              init_childs(PROC_MAIN) before starting tcp_main, to allow
00065  *               tcp usage for module started processes (andrei)
00066  * 2007-01-18  children shutdown procedure moved into shutdown_children;
00067  *               safer shutdown on start-up error (andrei)
00068  * 2007-02-09  TLS support split into tls-in-core (CORE_TLS) and generic TLS
00069  *             (USE_TLS)  (andrei)
00070  * 2007-06-07  added support for locking pages in mem. and using real time
00071  *              scheduling policies (andrei)
00072  * 2007-07-30  dst blacklist and DNS cache measurements added (Gergo)
00073  * 2008-08-08  sctp support (andrei)
00074  * 2008-08-19  -l support for mmultihomed addresses/addresses lists
00075  *                (e.g. -l (eth0, 1.2.3.4, foo.bar) ) (andrei)
00076  * 2010-04-19  added daemon_status_fd pipe to communicate the parent process
00077  *              with the main process in daemonize mode, so the parent process
00078  *              can return the proper exit status code (ibc)
00079  * 2010-08-19  moved the daemon status stuff to daemonize.c (andrei)
00080  */
00081 
00093 #include <stdio.h>
00094 #include <stdlib.h>
00095 #include <errno.h>
00096 #include <ctype.h>
00097 #include <string.h>
00098 #include <netdb.h>
00099 #include <unistd.h>
00100 #include <sys/types.h>
00101 #include <sys/socket.h>
00102 #if defined(HAVE_NETINET_IN_SYSTM)
00103 #include <netinet/in_systm.h>
00104 #endif
00105 #include <netinet/in.h>
00106 #include <netinet/ip.h>
00107 #include <arpa/inet.h>
00108 #include <sys/utsname.h>
00109 #include <sys/stat.h>
00110 #include <sys/mman.h>
00111 #include <fcntl.h>
00112 #include <sys/time.h>
00113 #include <sys/wait.h>
00114 #include <pwd.h>
00115 #include <grp.h>
00116 #include <signal.h>
00117 
00118 #include <sys/ioctl.h>
00119 #include <net/if.h>
00120 #ifdef HAVE_SYS_SOCKIO_H
00121 #include <sys/sockio.h>
00122 #endif
00123 
00124 #include "config.h"
00125 #include "dprint.h"
00126 #include "daemonize.h"
00127 #include "route.h"
00128 #include "udp_server.h"
00129 #include "globals.h"
00130 #include "mem/mem.h"
00131 #ifdef SHM_MEM
00132 #include "mem/shm_mem.h"
00133 #include "shm_init.h"
00134 #endif /* SHM_MEM */
00135 #include "sr_module.h"
00136 #include "timer.h"
00137 #include "parser/msg_parser.h"
00138 #include "ip_addr.h"
00139 #include "resolve.h"
00140 #include "parser/parse_hname2.h"
00141 #include "parser/digest/digest_parser.h"
00142 #include "name_alias.h"
00143 #include "hash_func.h"
00144 #include "pt.h"
00145 #include "script_cb.h"
00146 #include "nonsip_hooks.h"
00147 #include "ut.h"
00148 #include "signals.h"
00149 #ifdef USE_RAW_SOCKS
00150 #include "raw_sock.h"
00151 #endif /* USE_RAW_SOCKS */
00152 #ifdef USE_TCP
00153 #include "poll_types.h"
00154 #include "tcp_init.h"
00155 #include "tcp_options.h"
00156 #ifdef CORE_TLS
00157 #include "tls/tls_init.h"
00158 #define tls_has_init_si() 1
00159 #define tls_loaded() 1
00160 #else
00161 #include "tls_hooks_init.h"
00162 #endif /* CORE_TLS */
00163 #endif /* USE_TCP */
00164 #ifdef USE_SCTP
00165 #include "sctp_options.h"
00166 #include "sctp_server.h"
00167 #endif
00168 #include "usr_avp.h"
00169 #include "rpc_lookup.h"
00170 #include "core_cmd.h"
00171 #include "flags.h"
00172 #include "lock_ops_init.h"
00173 #include "atomic_ops_init.h"
00174 #ifdef USE_DNS_CACHE
00175 #include "dns_cache.h"
00176 #endif
00177 #ifdef USE_DST_BLACKLIST
00178 #include "dst_blacklist.h"
00179 #endif
00180 #include "rand/fastrand.h" /* seed */
00181 
00182 #include "stats.h"
00183 #include "counters.h"
00184 #include "cfg/cfg.h"
00185 #include "cfg/cfg_struct.h"
00186 #include "cfg_core.h"
00187 #include "endianness.h" /* init */
00188 #include "basex.h" /* init */
00189 #include "pvapi.h" /* init PV api */
00190 #include "pv_core.h" /* register core pvars */
00191 #include "ppcfg.h"
00192 #include "sock_ut.h"
00193 
00194 #ifdef DEBUG_DMALLOC
00195 #include <dmalloc.h>
00196 #endif
00197 #include "ver.h"
00198 
00199 /* define SIG_DEBUG by default */
00200 #ifdef NO_SIG_DEBUG
00201 #undef SIG_DEBUG
00202 #else
00203 #define SIG_DEBUG
00204 #endif
00205 
00206 
00207 
00208 static char help_msg[]= "\
00209 Usage: " NAME " [options]\n\
00210 Options:\n\
00211     -f file      Configuration file (default: " CFG_FILE ")\n\
00212     -L path      Modules search path (default: " MODS_DIR ")\n\
00213     -c           Check configuration file for errors\n\
00214     -l address   Listen on the specified address/interface (multiple -l\n\
00215                   mean listening on more addresses).  The address format is\n\
00216                   [proto:]addr_lst[:port], where proto=udp|tcp|tls|sctp, \n\
00217                   addr_lst= addr|(addr, addr_lst) and \n\
00218                   addr= host|ip_address|interface_name. \n\
00219                   E.g: -l locahost, -l udp:127.0.0.1:5080, -l eth0:5062,\n\
00220                   -l \"sctp:(eth0)\", -l \"(eth0, eth1, 127.0.0.1):5065\".\n\
00221                   The default behaviour is to listen on all the interfaces.\n\
00222     -n processes Number of child processes to fork per interface\n\
00223                   (default: 8)\n\
00224     -r           Use dns to check if is necessary to add a \"received=\"\n\
00225                   field to a via\n\
00226     -R           Same as `-r` but use reverse dns;\n\
00227                   (to use both use `-rR`)\n\
00228     -v           Turn on \"via:\" host checking when forwarding replies\n\
00229     -d           Debugging mode (multiple -d increase the level)\n\
00230     -D no        1..do not fork (almost) anyway, 2..do not daemonize creator\n\
00231                   3..daemonize (default)\n\
00232     -E           Log to stderr\n"
00233 #ifdef USE_TCP
00234 "    -T           Disable tcp\n\
00235     -N           Number of tcp child processes (default: equal to `-n')\n\
00236     -W type      poll method (depending on support in OS, it can be: poll,\n\
00237                   epoll_lt, epoll_et, sigio_rt, select, kqueue, /dev/poll)\n"
00238 #endif
00239 #ifdef USE_SCTP
00240 "    -S           disable sctp\n\
00241     -Q            Number of sctp child processes (default: equal to `-n')\n"
00242 #endif /* USE_SCTP */
00243 "    -V           Version number\n\
00244     -h           This help message\n\
00245     -b nr        Maximum receive buffer size which will not be exceeded by\n\
00246                   auto-probing procedure even if  OS allows\n\
00247     -m nr        Size of shared memory allocated in Megabytes\n\
00248     -M nr        Size of private memory allocated, in Megabytes\n\
00249     -w dir       Change the working directory to \"dir\" (default: \"/\")\n\
00250     -t dir       Chroot to \"dir\"\n\
00251     -u uid       Change uid \n\
00252     -g gid       Change gid \n\
00253     -P file      Create a pid file\n\
00254     -G file      Create a pgid file\n\
00255     -O nr        Script optimization level (debugging option)\n\
00256     -a mode      Auto aliases mode: enable with yes or on,\n\
00257                   disable with no or off\n\
00258     -A define    Add config pre-processor define (e.g., -A WITH_AUTH)\n"
00259 #ifdef STATS
00260 "    -s file     File to which statistics is dumped (disabled otherwise)\n"
00261 #endif
00262 ;
00263 
00264 
00265 /* print compile-time constants */
00266 void print_ct_constants(void)
00267 {
00268 #ifdef ADAPTIVE_WAIT
00269         printf("ADAPTIVE_WAIT_LOOPS=%d, ", ADAPTIVE_WAIT_LOOPS);
00270 #endif
00271 /*
00272 #ifdef SHM_MEM
00273         printf("SHM_MEM_SIZE=%d, ", SHM_MEM_SIZE);
00274 #endif
00275 */
00276         printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d,"
00277                         " MAX_URI_SIZE %d, BUF_SIZE %d, DEFAULT PKG_SIZE %uMB\n",
00278                 MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE,
00279                 BUF_SIZE, PKG_MEM_SIZE);
00280 #ifdef USE_TCP
00281         printf("poll method support: %s.\n", poll_support);
00282 #endif
00283 }
00284 
00285 /* print compile-time constants */
00286 void print_internals(void)
00287 {
00288         printf("Print out of %s internals\n", NAME);
00289         printf("  Version: %s\n", full_version);
00290         printf("  Default config: %s\n", CFG_FILE);
00291         printf("  Default paths to modules: %s\n", MODS_DIR);
00292         printf("  Compile flags: %s\n", ver_flags );
00293         printf("  MAX_RECV_BUFFER_SIZE=%d\n", MAX_RECV_BUFFER_SIZE);
00294         printf("  MAX_LISTEN=%d\n", MAX_LISTEN);
00295         printf("  MAX_URI_SIZE=%d\n", MAX_URI_SIZE);
00296         printf("  BUF_SIZE=%d\n", BUF_SIZE);
00297         printf("  DEFAULT PKG_SIZE=%uMB\n", PKG_MEM_SIZE);
00298 #ifdef SHM_MEM
00299         printf("  DEFAULT SHM_SIZE=%uMB\n", SHM_MEM_SIZE);
00300 #endif
00301 #ifdef ADAPTIVE_WAIT
00302         printf("  ADAPTIVE_WAIT_LOOPS=%d\n", ADAPTIVE_WAIT_LOOPS);
00303 #endif
00304 #ifdef USE_TCP
00305         printf("  TCP poll methods: %s\n", poll_support);
00306 #endif
00307         printf("  Source code revision ID: %s\n", ver_id);
00308         printf("  Compiled with: %s\n", ver_compiler);
00309         printf("  Compiled on: %s\n", ver_compiled_time);
00310         printf("Thank you for flying %s!\n", NAME);
00311 }
00312 
00313 /* debugging function */
00314 /*
00315 void receive_stdin_loop(void)
00316 {
00317         #define BSIZE 1024
00318         char buf[BSIZE+1];
00319         int len;
00320 
00321         while(1){
00322                 len=fread(buf,1,BSIZE,stdin);
00323                 buf[len+1]=0;
00324                 receive_msg(buf, len);
00325                 printf("-------------------------\n");
00326         }
00327 }
00328 */
00329 
00330 /* global vars */
00331 
00332 int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
00333                                          to use kill(0, sig) */
00334 
00335 char* mods_dir = MODS_DIR;  /* search path for dyn. loadable modules */
00336 
00337 char* cfg_file = 0;
00338 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
00339                                                                                                   not want to exceed during the
00340                                                                                                   auto-probing procedure; may
00341                                                                                                   be re-configured */
00342 unsigned int sql_buffer_size = 65535; /* Size for the SQL buffer. Defaults to 64k. 
00343                                          This may be re-configured */
00344 int socket_workers = 0;         /* number of workers processing requests for a socket
00345                                                            - it's reset everytime with a new listen socket */
00346 int children_no = 0;            /* number of children processing requests */
00347 #ifdef USE_TCP
00348 int tcp_cfg_children_no = 0; /* set via config or command line option */
00349 int tcp_children_no = 0; /* based on socket_workers and tcp_cfg_children_no */
00350 int tcp_disable = 0; /* 1 if tcp is disabled */
00351 #endif
00352 #ifdef USE_TLS
00353 #ifdef  CORE_TLS
00354 int tls_disable = 0;  /* tls enabled by default */
00355 #else
00356 int tls_disable = 1;  /* tls disabled by default */
00357 #endif /* CORE_TLS */
00358 #endif /* USE_TLS */
00359 #ifdef USE_SCTP
00360 int sctp_children_no = 0;
00361 int sctp_disable = 2; /* 1 if sctp is disabled, 2 if auto mode, 0 enabled */
00362 #endif /* USE_SCTP */
00363 
00364 struct process_table *pt=0;             /*array with children pids, 0= main proc,
00365                                                                         alloc'ed in shared mem if possible*/
00366 int *process_count = 0;                 /* Total number of SER processes currently
00367                                                                    running */
00368 gen_lock_t* process_lock;               /* lock on the process table */
00369 int process_no = 0;                             /* index of process in the pt */
00370 
00371 time_t up_since;
00372 int sig_flag = 0;              /* last signal received */
00373 int dont_fork = 0;
00374 int dont_daemonize = 0;
00375 int log_stderr = 0;
00376 /* set custom app name for syslog printing */
00377 char *log_name = 0;
00378 pid_t creator_pid = (pid_t) -1;
00379 int config_check = 0;
00380 /* check if reply first via host==us */
00381 int check_via =  0;
00382 /* translate user=phone URIs to TEL URIs */
00383 int phone2tel = 1;
00384 /* shall use stateful synonym branches? faster but not reboot-safe */
00385 int syn_branch = 1;
00386 /* debugging level for timer debugging */
00387 int timerlog = L_WARN;
00388 /* should replies include extensive warnings? by default no,
00389    good for trouble-shooting
00390 */
00391 int sip_warning = 0;
00392 /* should localy-generated messages include server's signature?
00393    be default yes, good for trouble-shooting
00394 */
00395 int server_signature=1;
00396 str server_hdr = {SERVER_HDR, SERVER_HDR_LEN};
00397 str user_agent_hdr = {USER_AGENT, USER_AGENT_LEN};
00398 /* should ser try to locate outbound interface on multihomed
00399  * host? by default not -- too expensive
00400  */
00401 int mhomed=0;
00402 /* use dns and/or rdns or to see if we need to add
00403    a ;received=x.x.x.x to via: */
00404 int received_dns = 0;
00405 /* add or not the rev dns names to aliases list */
00406 int sr_auto_aliases=1;
00407 char* working_dir = 0;
00408 char* chroot_dir = 0;
00409 char* user=0;
00410 char* group=0;
00411 int uid = 0;
00412 int gid = 0;
00413 char* sock_user=0;
00414 char* sock_group=0;
00415 int sock_uid= -1;
00416 int sock_gid= -1;
00417 int sock_mode= S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP; /* rw-rw---- */
00418 
00419 int server_id = 0; /* Configurable unique ID of the server */
00420 
00421 /* set timeval for each received sip message */
00422 int sr_msg_time = 1;
00423 
00424 /* more config stuff */
00425 int disable_core_dump=0; /* by default enabled */
00426 int open_files_limit=-1; /* don't touch it by default */
00427 
00428 /* memory options */
00429 int shm_force_alloc=0; /* force immediate (on startup) page allocation
00430                                                   (by writting 0 in the pages), useful if
00431                                                   mlock_pages is also 1 */
00432 int mlock_pages=0; /* default off, try to disable swapping */
00433 
00434 /* real time options */
00435 int real_time=0; /* default off, flags: 1 on only timer, 2  slow timer,
00436                                                                                 4 all procs (7=all) */
00437 int rt_prio=0;
00438 int rt_policy=0; /* SCHED_OTHER */
00439 int rt_timer1_prio=0;  /* "fast" timer */
00440 int rt_timer2_prio=0;  /* "slow" timer */
00441 int rt_timer1_policy=0; /* "fast" timer, SCHED_OTHER */
00442 int rt_timer2_policy=0; /* "slow" timer, SCHED_OTHER */
00443 
00444 
00445 /* a hint to reply modules whether they should send reply
00446    to IP advertised in Via or IP from which a request came
00447 */
00448 int reply_to_via=0;
00449 
00450 #ifdef USE_MCAST
00451 int mcast_loopback = 0;
00452 int mcast_ttl = -1; /* if -1, don't touch it, use the default (usually 1) */
00453 #endif /* USE_MCAST */
00454 
00455 int tos = IPTOS_LOWDELAY;
00456 int pmtu_discovery = 0;
00457 
00458 #ifdef USE_IPV6
00459 int auto_bind_ipv6 = 0;
00460 #endif
00461 
00462 #if 0
00463 char* names[MAX_LISTEN];              /* our names */
00464 int names_len[MAX_LISTEN];            /* lengths of the names*/
00465 struct ip_addr addresses[MAX_LISTEN]; /* our ips */
00466 int addresses_no=0;                   /* number of names/ips */
00467 #endif
00468 struct socket_info* udp_listen=0;
00469 #ifdef USE_TCP
00470 int tcp_main_pid=0; /* set after the tcp main process is started */
00471 struct socket_info* tcp_listen=0;
00472 #endif
00473 #ifdef USE_TLS
00474 struct socket_info* tls_listen=0;
00475 #endif
00476 #ifdef USE_SCTP
00477 struct socket_info* sctp_listen=0;
00478 #endif
00479 struct socket_info* bind_address=0; /* pointer to the crt. proc.
00480                                                                          listening address*/
00481 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
00482 struct socket_info* sendipv6; /* same as above for ipv6 */
00483 #ifdef USE_RAW_SOCKS
00484 int raw_udp4_send_sock = -1; /* raw socket used for sending udp4 packets */
00485 #endif /* USE_RAW_SOCKS */
00486 #ifdef USE_TCP
00487 struct socket_info* sendipv4_tcp;
00488 struct socket_info* sendipv6_tcp;
00489 #endif
00490 #ifdef USE_TLS
00491 struct socket_info* sendipv4_tls;
00492 struct socket_info* sendipv6_tls;
00493 #endif
00494 #ifdef USE_SCTP
00495 struct socket_info* sendipv4_sctp;
00496 struct socket_info* sendipv6_sctp;
00497 #endif
00498 
00499 unsigned short port_no=0; /* default port*/
00500 #ifdef USE_TLS
00501 unsigned short tls_port_no=0; /* default port */
00502 #endif
00503 
00504 #ifdef USE_STUN
00505 /* refresh interval in miliseconds */
00506 unsigned int stun_refresh_interval=0;
00507 /* stun can be switch off even if it is compiled */
00508 int stun_allow_stun=1;
00509 /* use or don't use fingerprint */
00510 int stun_allow_fp=1;
00511 #endif
00512 
00513 struct host_alias* aliases=0; /* name aliases list */
00514 
00515 /* Parameter to child_init */
00516 int child_rank = 0;
00517 
00518 /* how much to wait for children to terminate, before taking extreme measures*/
00519 int ser_kill_timeout=DEFAULT_SER_KILL_TIMEOUT;
00520 
00521 /* process_bm_t process_bit = 0; */
00522 #ifdef ROUTE_SRV
00523 #endif
00524 
00525 /* cfg parsing */
00526 int cfg_errors=0;
00527 int cfg_warnings=0;
00528 
00529 
00530 /* shared memory (in MB) */
00531 unsigned long shm_mem_size=0;
00532 /* private (pkg) memory (in MB) */
00533 unsigned long pkg_mem_size=0;
00534 
00535 /* export command-line to anywhere else */
00536 int my_argc;
00537 char **my_argv;
00538 
00539 /* set to 1 when the cfg framework and core cfg is initialized/registered */
00540 static int cfg_ok=0;
00541 
00542 #define MAX_FD 32 /* maximum number of inherited open file descriptors,
00543                     (normally it shouldn't  be bigger  than 3) */
00544 
00545 
00546 extern FILE* yyin;
00547 extern int yyparse(void);
00548 
00549 
00550 int is_main=1; /* flag = is this the  "main" process? */
00551 int fixup_complete=0; /* flag = is the fixup complete ? */
00552 
00553 char* pid_file = 0; /* filename as asked by use */
00554 char* pgid_file = 0;
00555 
00556 
00557 /* call it before exiting; if show_status==1, mem status is displayed */
00558 void cleanup(show_status)
00559 {
00560         int memlog;
00561         
00562         /*clean-up*/
00563 #ifndef SHM_SAFE_MALLOC
00564         if (mem_lock)
00565                 shm_unlock(); /* hack: force-unlock the shared memory lock in case
00566                                          some process crashed and let it locked; this will
00567                                          allow an almost gracious shutdown */
00568 #endif
00569         destroy_rpcs();
00570         destroy_modules();
00571 #ifdef USE_DNS_CACHE
00572         destroy_dns_cache();
00573 #endif
00574 #ifdef USE_DST_BLACKLIST
00575         destroy_dst_blacklist();
00576 #endif
00577         /* restore the original core configuration before the
00578          * config block is freed, otherwise even logging is unusable,
00579          * it can case segfault */
00580         if (cfg_ok){
00581                 cfg_update();
00582                 /* copy current config into default_core_cfg */
00583                 if (core_cfg)
00584                         default_core_cfg=*((struct cfg_group_core*)core_cfg);
00585         }
00586         core_cfg = &default_core_cfg;
00587         cfg_destroy();
00588 #ifdef USE_TCP
00589         destroy_tcp();
00590 #ifdef USE_TLS
00591         destroy_tls();
00592 #endif /* USE_TLS */
00593 #endif /* USE_TCP */
00594 #ifdef USE_SCTP
00595         destroy_sctp();
00596 #endif
00597         destroy_timer();
00598         pv_destroy_api();
00599         destroy_script_cb();
00600         destroy_nonsip_hooks();
00601         destroy_routes();
00602         destroy_atomic_ops();
00603         destroy_counters();
00604         memlog=cfg_get(core, core_cfg, memlog);
00605 #ifdef PKG_MALLOC
00606         if (show_status && memlog <= cfg_get(core, core_cfg, debug)){
00607                 if (cfg_get(core, core_cfg, mem_summary) & 1) {
00608                         LOG(memlog, "Memory status (pkg):\n");
00609                         pkg_status();
00610                 }
00611                 if (cfg_get(core, core_cfg, mem_summary) & 4) {
00612                         LOG(memlog, "Memory still-in-use summary (pkg):\n");
00613                         pkg_sums();
00614                 }
00615         }
00616 #endif
00617 #ifdef SHM_MEM
00618         if (pt) shm_free(pt);
00619         pt=0;
00620         if (show_status && memlog <= cfg_get(core, core_cfg, debug)){
00621                 if (cfg_get(core, core_cfg, mem_summary) & 2) {
00622                         LOG(memlog, "Memory status (shm):\n");
00623                         shm_status();
00624                 }
00625                 if (cfg_get(core, core_cfg, mem_summary) & 8) {
00626                         LOG(memlog, "Memory still-in-use summary (shm):\n");
00627                         shm_sums();
00628                 }
00629         }
00630         /* zero all shmem alloc vars that we still use */
00631         shm_mem_destroy();
00632 #endif
00633         destroy_lock_ops();
00634         if (pid_file) unlink(pid_file);
00635         if (pgid_file) unlink(pgid_file);
00636         destroy_pkg_mallocs();
00637 }
00638 
00639 
00640 /* tries to send a signal to all our processes
00641  * if daemonized  is ok to send the signal to all the process group,
00642  * however if not daemonized we might end up sending the signal also
00643  * to the shell which launched us => most signals will kill it if
00644  * it's not in interactive mode and we don't want this. The non-daemonized
00645  * case can occur when an error is encountered before daemonize is called
00646  * (e.g. when parsing the config file) or when ser is started in "dont-fork"
00647  *  mode. Sending the signal to all the processes in pt[] will not work
00648  *  for processes forked from modules (which have no correspondent entry in
00649  *  pt), but this can happen only in dont_fork mode (which is only for
00650  *  debugging). So in the worst case + "dont-fork" we might leave some
00651  *  zombies. -- andrei */
00652 static void kill_all_children(int signum)
00653 {
00654         int r;
00655 
00656         if (own_pgid) kill(0, signum);
00657         else if (pt){
00658                  /* lock processes table only if this is a child process
00659                   * (only main can add processes, so from main is safe not to lock
00660                   *  and moreover it avoids the lock-holding suicidal children problem)
00661                   */
00662                 if (!is_main) lock_get(process_lock);
00663                 for (r=1; r<*process_count; r++){
00664                         if (r==process_no) continue; /* try not to be suicidal */
00665                         if (pt[r].pid) {
00666                                 kill(pt[r].pid, signum);
00667                         }
00668                         else LOG(L_CRIT, "BUG: killing: %s > %d no pid!!!\n",
00669                                                         pt[r].desc, pt[r].pid);
00670                 }
00671                 if (!is_main) lock_release(process_lock);
00672         }
00673 }
00674 
00675 
00676 
00677 /* if this handler is called, a critical timeout has occurred while
00678  * waiting for the children to finish => we should kill everything and exit */
00679 static void sig_alarm_kill(int signo)
00680 {
00681         kill_all_children(SIGKILL); /* this will kill the whole group
00682                                                                   including "this" process;
00683                                                                   for debugging replace with SIGABRT
00684                                                                   (but warning: it might generate lots
00685                                                                    of cores) */
00686 }
00687 
00688 
00689 /* like sig_alarm_kill, but the timeout has occurred when cleaning up
00690  * => try to leave a core for future diagnostics */
00691 static void sig_alarm_abort(int signo)
00692 {
00693         /* LOG is not signal safe, but who cares, we are abort-ing anyway :-) */
00694         LOG(L_CRIT, "BUG: shutdown timeout triggered, dying...");
00695         abort();
00696 }
00697 
00698 
00699 
00700 static void shutdown_children(int sig, int show_status)
00701 {
00702         kill_all_children(sig);
00703         if (set_sig_h(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
00704                 LOG(L_ERR, "ERROR: shutdown: could not install SIGALARM handler\n");
00705                 /* continue, the process will die anyway if no
00706                  * alarm is installed which is exactly what we want */
00707         }
00708         alarm(ser_kill_timeout);
00709         while((wait(0) > 0) || (errno==EINTR)); /* wait for all the
00710                                                                                            children to terminate*/
00711         set_sig_h(SIGALRM, sig_alarm_abort);
00712         cleanup(show_status); /* cleanup & show status*/
00713         alarm(0);
00714         set_sig_h(SIGALRM, SIG_IGN);
00715 }
00716 
00717 
00718 
00719 void handle_sigs(void)
00720 {
00721         pid_t   chld;
00722         int     chld_status;
00723         int memlog;
00724 
00725         switch(sig_flag){
00726                 case 0: break; /* do nothing*/
00727                 case SIGPIPE:
00728                                 /* SIGPIPE might be rarely received on use of
00729                                    exec module; simply ignore it
00730                                  */
00731                                 LOG(L_WARN, "WARNING: SIGPIPE received and ignored\n");
00732                                 break;
00733                 case SIGINT:
00734                 case SIGTERM:
00735                         /* we end the program in all these cases */
00736                         if (sig_flag==SIGINT)
00737                                 DBG("INT received, program terminates\n");
00738                         else
00739                                 DBG("SIGTERM received, program terminates\n");
00740                         LOG(L_NOTICE, "Thank you for flying " NAME "!!!\n");
00741                         /* shutdown/kill all the children */
00742                         shutdown_children(SIGTERM, 1);
00743                         exit(0);
00744                         break;
00745 
00746                 case SIGUSR1:
00747 #ifdef STATS
00748                         dump_all_statistic();
00749 #endif
00750                 memlog=cfg_get(core, core_cfg, memlog);
00751 #ifdef PKG_MALLOC
00752                 if (memlog <= cfg_get(core, core_cfg, debug)){
00753                         if (cfg_get(core, core_cfg, mem_summary) & 1) {
00754                                 LOG(memlog, "Memory status (pkg):\n");
00755                                 pkg_status();
00756                         }
00757                         if (cfg_get(core, core_cfg, mem_summary) & 2) {
00758                                 LOG(memlog, "Memory still-in-use summary (pkg):\n");
00759                                 pkg_sums();
00760                         }
00761                 }
00762 #endif
00763 #ifdef SHM_MEM
00764                 if (memlog <= cfg_get(core, core_cfg, debug)){
00765                         if (cfg_get(core, core_cfg, mem_summary) & 1) {
00766                                 LOG(memlog, "Memory status (shm):\n");
00767                                 shm_status();
00768                         }
00769                         if (cfg_get(core, core_cfg, mem_summary) & 2) {
00770                                 LOG(memlog, "Memory still-in-use summary (shm):\n");
00771                                 shm_sums();
00772                         }
00773                 }
00774 #endif
00775                         break;
00776 
00777                 case SIGCHLD:
00778                         while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
00779                                 if (WIFEXITED(chld_status))
00780                                         LOG(L_ALERT, "child process %ld exited normally,"
00781                                                         " status=%d\n", (long)chld,
00782                                                         WEXITSTATUS(chld_status));
00783                                 else if (WIFSIGNALED(chld_status)) {
00784                                         LOG(L_ALERT, "child process %ld exited by a signal"
00785                                                         " %d\n", (long)chld, WTERMSIG(chld_status));
00786 #ifdef WCOREDUMP
00787                                         LOG(L_ALERT, "core was %sgenerated\n",
00788                                                          WCOREDUMP(chld_status) ?  "" : "not " );
00789 #endif
00790                                 }else if (WIFSTOPPED(chld_status))
00791                                         LOG(L_ALERT, "child process %ld stopped by a"
00792                                                                 " signal %d\n", (long)chld,
00793                                                                  WSTOPSIG(chld_status));
00794                         }
00795 #ifndef STOP_JIRIS_CHANGES
00796                         if (dont_fork) {
00797                                 LOG(L_INFO, "INFO: dont_fork turned on, living on\n");
00798                                 break;
00799                         }
00800                         LOG(L_INFO, "INFO: terminating due to SIGCHLD\n");
00801 #endif
00802                         /* exit */
00803                         shutdown_children(SIGTERM, 1);
00804                         DBG("terminating due to SIGCHLD\n");
00805                         exit(0);
00806                         break;
00807 
00808                 case SIGHUP: /* ignoring it*/
00809                                         DBG("SIGHUP received, ignoring it\n");
00810                                         break;
00811                 default:
00812                         LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
00813         }
00814         sig_flag=0;
00815 }
00816 
00817 
00818 
00819 /* added by jku; allows for regular exit on a specific signal;
00820    good for profiling which only works if exited regularly and
00821    not by default signal handlers
00822     - modified by andrei: moved most of the stuff to handle_sigs,
00823        made it safer for the "fork" case
00824 */
00825 void sig_usr(int signo)
00826 {
00827 
00828 #ifdef PKG_MALLOC
00829         int memlog;
00830 #endif
00831 
00832         if (is_main){
00833                 if (sig_flag==0) sig_flag=signo;
00834                 else /*  previous sig. not processed yet, ignoring? */
00835                         return; ;
00836                 if (dont_fork)
00837                                 /* only one proc, doing everything from the sig handler,
00838                                 unsafe, but this is only for debugging mode*/
00839                         handle_sigs();
00840         }else{
00841                 /* process the important signals */
00842                 switch(signo){
00843                         case SIGPIPE:
00844 #ifdef SIG_DEBUG /* signal unsafe stuff follows */
00845                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
00846 #endif
00847                                 break;
00848                         case SIGINT:
00849                         case SIGTERM:
00850 #ifdef SIG_DEBUG /* signal unsafe stuff follows */
00851                                         LOG(L_INFO, "INFO: signal %d received\n", signo);
00852                                         /* print memory stats for non-main too */
00853                                         #ifdef PKG_MALLOC
00854                                         /* make sure we have current cfg values, but update only
00855                                           the safe part (values not requiring callbacks), to
00856                                           account for processes that might not have registered
00857                                           config support */
00858                                         cfg_update_no_cbs();
00859                                         memlog=cfg_get(core, core_cfg, memlog);
00860                                         if (memlog <= cfg_get(core, core_cfg, debug)){
00861                                                 if (cfg_get(core, core_cfg, mem_summary) & 1) {
00862                                                         LOG(memlog, "Memory status (pkg):\n");
00863                                                         pkg_status();
00864                                                 }
00865                                                 if (cfg_get(core, core_cfg, mem_summary) & 2) {
00866                                                         LOG(memlog, "Memory still-in-use summary (pkg):"
00867                                                                         "\n");
00868                                                         pkg_sums();
00869                                                 }
00870                                         }
00871                                         #endif
00872 #endif
00873                                         _exit(0);
00874                                         break;
00875                         case SIGUSR1:
00876                                 /* statistics, do nothing, printed only from the main proc */
00877                                         break;
00878                                 /* ignored*/
00879                         case SIGUSR2:
00880                         case SIGHUP:
00881                                         break;
00882                         case SIGCHLD:
00883 #ifndef                         STOP_JIRIS_CHANGES
00884 #ifdef SIG_DEBUG /* signal unsafe stuff follows */
00885                                         DBG("SIGCHLD received: "
00886                                                 "we do not worry about grand-children\n");
00887 #endif
00888 #else
00889                                         _exit(0); /* terminate if one child died */
00890 #endif
00891                                         break;
00892                 }
00893         }
00894 }
00895 
00896 
00897 
00898 /* install the signal handlers, returns 0 on success, -1 on error */
00899 int install_sigs(void)
00900 {
00901         /* added by jku: add exit handler */
00902         if (set_sig_h(SIGINT, sig_usr) == SIG_ERR ) {
00903                 ERR("no SIGINT signal handler can be installed\n");
00904                 goto error;
00905         }
00906         /* if we debug and write to a pipe, we want to exit nicely too */
00907         if (set_sig_h(SIGPIPE, sig_usr) == SIG_ERR ) {
00908                 ERR("no SIGINT signal handler can be installed\n");
00909                 goto error;
00910         }
00911         if (set_sig_h(SIGUSR1, sig_usr)  == SIG_ERR ) {
00912                 ERR("no SIGUSR1 signal handler can be installed\n");
00913                 goto error;
00914         }
00915         if (set_sig_h(SIGCHLD , sig_usr)  == SIG_ERR ) {
00916                 ERR("no SIGCHLD signal handler can be installed\n");
00917                 goto error;
00918         }
00919         if (set_sig_h(SIGTERM , sig_usr)  == SIG_ERR ) {
00920                 ERR("no SIGTERM signal handler can be installed\n");
00921                 goto error;
00922         }
00923         if (set_sig_h(SIGHUP , sig_usr)  == SIG_ERR ) {
00924                 ERR("no SIGHUP signal handler can be installed\n");
00925                 goto error;
00926         }
00927         if (set_sig_h(SIGUSR2 , sig_usr)  == SIG_ERR ) {
00928                 ERR("no SIGUSR2 signal handler can be installed\n");
00929                 goto error;
00930         }
00931         return 0;
00932 error:
00933         return -1;
00934 }
00935 
00936 /* returns -1 on error, 0 on success
00937  * sets proto */
00938 static int parse_proto(unsigned char* s, long len, int* proto)
00939 {
00940 #define PROTO2UINT3(a, b, c) (( (((unsigned int)(a))<<16)+ \
00941                                                                 (((unsigned int)(b))<<8)+  \
00942                                                                 ((unsigned int)(c)) ) | 0x20202020)
00943 #define PROTO2UINT4(a, b ,c ,d) ((      (((unsigned int)(a))<<24)+ \
00944                                                                         (((unsigned int)(b))<<16)+ \
00945                                                                         (((unsigned int)(c))<< 8)+ \
00946                                                                         (((unsigned int)(d))) \
00947                                                                   )| 0x20202020 )
00948         unsigned int i;
00949         if (likely(len==3)){
00950                 i=PROTO2UINT3(s[0], s[1], s[2]);
00951                 switch(i){
00952                         case PROTO2UINT3('u', 'd', 'p'):
00953                                 *proto=PROTO_UDP;
00954                                 break;
00955 #ifdef USE_TCP
00956                         case PROTO2UINT3('t', 'c', 'p'):
00957                                 *proto=PROTO_TCP;
00958                                 break;
00959 #ifdef USE_TLS
00960                         case PROTO2UINT3('t', 'l', 's'):
00961                                 *proto=PROTO_TLS;
00962                                 break;
00963 #endif
00964 #endif
00965                         default:
00966                                 return -1;
00967                 }
00968         }
00969 #ifdef USE_SCTP
00970         else if (likely(len==4)){
00971                 i=PROTO2UINT4(s[0], s[1], s[2], s[3]);
00972                 if (i==PROTO2UINT4('s', 'c', 't', 'p'))
00973                         *proto=PROTO_SCTP;
00974                 else
00975                         return -1;
00976         }
00977 #endif /* USE_SCTP */
00978         else
00979                 return -1;
00980         return 0;
00981 }
00982 
00983 
00984 
00985 static struct name_lst* mk_name_lst_elem(char* name, int name_len, int flags)
00986 {
00987         struct name_lst* l;
00988         
00989         l=pkg_malloc(sizeof(struct name_lst)+name_len+1/* 0 */);
00990         if (l){
00991                 l->name=((char*)l)+sizeof(struct name_lst);
00992                 memcpy(l->name, name, name_len);
00993                 l->name[name_len]=0;
00994                 l->flags=flags;
00995                 l->next=0;
00996         }
00997         return l;
00998 }
00999 
01000 
01001 
01002 /* free a name_lst list with elements allocated with mk_name_lst_elem
01003  * (single block both for the structure and for the name) */
01004 static void free_name_lst(struct name_lst* lst)
01005 {
01006         struct name_lst* l;
01007         
01008         while(lst){
01009                 l=lst;
01010                 lst=lst->next;
01011                 pkg_free(l);
01012         }
01013 }
01014 
01015 
01016 
01017 /* parse h and returns a name lst (flags are set to SI_IS_MHOMED if
01018  * h contains more then one name or contains a name surrounded by '(' ')' )
01019  * valid formats:    "hostname"
01020  *                   "(hostname, hostname1, hostname2)"
01021  *                   "(hostname hostname1 hostname2)"
01022  *                   "(hostname)"
01023  */
01024 static struct name_lst* parse_name_lst(char* h, int h_len)
01025 {
01026         char* last;
01027         char* p;
01028         struct name_lst* n_lst;
01029         struct name_lst* l;
01030         struct name_lst** tail;
01031         int flags;
01032         
01033         n_lst=0;
01034         tail=&n_lst;
01035         last=h+h_len-1;
01036         flags=0;
01037         /* eat whitespace */
01038         for(; h<=last && ((*h==' ') || (*h=='\t')); h++);
01039         for(; last>h && ((*last==' ') || (*last=='\t')); last--);
01040         /* catch empty strings and invalid lens */
01041         if (h>last) goto error;
01042         
01043         if (*h=='('){
01044                 /* list mode */
01045                 if (*last!=')' || ((h+1)>(last-1)))
01046                         goto error;
01047                 h++;
01048                 last--;
01049                 flags=SI_IS_MHOMED;
01050                 for(p=h; p<=last; p++)
01051                         switch (*p){
01052                                 case ',':
01053                                 case ';':
01054                                 case ' ':
01055                                 case '\t':
01056                                         if ((int)(p-h)>0){
01057                                                 l=mk_name_lst_elem(h, (int)(p-h), flags);
01058                                                 if (l==0) 
01059                                                         goto error;
01060                                                 *tail=l;
01061                                                 tail=&l->next;
01062                                         }
01063                                         h=p+1;
01064                                         break;
01065                         }
01066         }else{
01067                 /* single addr. mode */
01068                 flags=0;
01069                 p=last+1;
01070         }
01071         if ((int)(p-h)>0){
01072                 l=mk_name_lst_elem(h, (int)(p-h), flags);
01073                 if (l==0) 
01074                         goto error;
01075                 *tail=l;
01076                 tail=&l->next;
01077         }
01078         return n_lst;
01079 error:
01080         if (n_lst) free_name_lst(n_lst);
01081         return 0;
01082 }
01083 
01084 
01085 
01086 /*
01087  * parses [proto:]host[:port]  or
01088  *  [proto:](host_1, host_2, ... host_n)[:port]
01089  * where proto= udp|tcp|tls
01090  * returns  fills proto, port, host and returns list of addresses on success
01091  * (pkg malloc'ed) and 0 on failure
01092  */
01107 int parse_phostport(char* s, char** host, int* hlen,
01108                                                                  int* port, int* proto)
01109 {
01110         char* first; /* first ':' occurrence */
01111         char* second; /* second ':' occurrence */
01112         char* p;
01113         int bracket;
01114         char* tmp;
01115 
01116         first=second=0;
01117         bracket=0;
01118 
01119         /* find the first 2 ':', ignoring possible ipv6 addresses
01120          * (substrings between [])
01121          */
01122         for(p=s; *p; p++){
01123                 switch(*p){
01124                         case '[':
01125                                 bracket++;
01126                                 if (bracket>1) goto error_brackets;
01127                                 break;
01128                         case ']':
01129                                 bracket--;
01130                                 if (bracket<0) goto error_brackets;
01131                                 break;
01132                         case ':':
01133                                 if (bracket==0){
01134                                         if (first==0) first=p;
01135                                         else if( second==0) second=p;
01136                                         else goto error_colons;
01137                                 }
01138                                 break;
01139                 }
01140         }
01141         if (p==s) return -1;
01142         if (*(p-1)==':') goto error_colons;
01143 
01144         if (first==0){ /* no ':' => only host */
01145                 *host=s;
01146                 *hlen=(int)(p-s);
01147                 *port=0;
01148                 *proto=0;
01149                 goto end;
01150         }
01151         if (second){ /* 2 ':' found => check if valid */
01152                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
01153                 *port=strtol(second+1, &tmp, 10);
01154                 if ((tmp==0)||(*tmp)||(tmp==second+1)) goto error_port;
01155                 *host=first+1;
01156                 *hlen=(int)(second-*host);
01157                 goto end;
01158         }
01159         /* only 1 ':' found => it's either proto:host or host:port */
01160         *port=strtol(first+1, &tmp, 10);
01161         if ((tmp==0)||(*tmp)||(tmp==first+1)){
01162                 /* invalid port => it's proto:host */
01163                 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
01164                 *port=0;
01165                 *host=first+1;
01166                 *hlen=(int)(p-*host);
01167         }else{
01168                 /* valid port => its host:port */
01169                 *proto=0;
01170                 *host=s;
01171                 *hlen=(int)(first-*host);
01172         }
01173 end:
01174         return 0;
01175 error_brackets:
01176         LOG(L_ERR, "ERROR: parse_phostport: too many brackets in %s\n", s);
01177         return -1;
01178 error_colons:
01179         LOG(L_ERR, "ERROR: parse_phostport: too many colons in %s\n", s);
01180         return -1;
01181 error_proto:
01182         LOG(L_ERR, "ERROR: parse_phostport: bad protocol in %s\n", s);
01183         return -1;
01184 error_port:
01185         LOG(L_ERR, "ERROR: parse_phostport: bad port number in %s\n", s);
01186         return -1;
01187 }
01188 
01189 
01190 
01206 static struct name_lst* parse_phostport_mh(char* s, char** host, int* hlen,
01207                                                                  int* port, int* proto)
01208 {
01209         if (parse_phostport(s, host, hlen, port, proto)==0)
01210                 return parse_name_lst(*host, *hlen);
01211         return 0;
01212 }
01213 
01214 
01215 
01228 int fix_cfg_file(void)
01229 {
01230         char* res = NULL;
01231         size_t max_len, cwd_len, cfg_len;
01232         
01233         if (cfg_file == NULL) cfg_file = CFG_FILE;
01234         if (cfg_file[0] == '/') return 0;
01235         
01236         /* cfg_file contains a relative pathname, get the current
01237          * working directory and add it at the beginning
01238          */
01239         cfg_len = strlen(cfg_file);
01240         
01241         max_len = pathmax();
01242         if ((res = malloc(max_len)) == NULL) goto error;
01243         
01244         if (getcwd(res, max_len) == NULL) goto error;
01245         cwd_len = strlen(res);
01246         
01247         /* Make sure that the buffer is big enough */
01248         if (cwd_len + 1 + cfg_len >= max_len) goto error;
01249         
01250         res[cwd_len] = '/';
01251         memcpy(res + cwd_len + 1, cfg_file, cfg_len);
01252         
01253         res[cwd_len + 1 + cfg_len] = '\0'; /* Add terminating zero */
01254         cfg_file = res;
01255         return 0;
01256         
01257  error:
01258         fprintf(stderr, "ERROR: Unable to fix cfg_file to contain full pathname\n");
01259         if (res) free(res);
01260         return -1;
01261 }
01262 
01263 
01264 /* main loop */
01265 int main_loop(void)
01266 {
01267         int  i;
01268         pid_t pid;
01269         struct socket_info* si;
01270         char si_desc[MAX_PT_DESC];
01271 #ifdef EXTRA_DEBUG
01272         int r;
01273 #endif
01274         int nrprocs;
01275 
01276         /* one "main" process and n children handling i/o */
01277         if (dont_fork){
01278 #ifdef STATS
01279                 setstats( 0 );
01280 #endif
01281                 if (udp_listen==0){
01282                         LOG(L_ERR, "ERROR: no fork mode requires at least one"
01283                                         " udp listen address, exiting...\n");
01284                         goto error;
01285                 }
01286                 /* only one address, we ignore all the others */
01287                 if (udp_init(udp_listen)==-1) goto error;
01288                 bind_address=udp_listen;
01289                 if (bind_address->address.af==AF_INET) {
01290                         sendipv4=bind_address;
01291 #ifdef USE_RAW_SOCKS
01292                 /* always try to have a raw socket opened if we are using ipv4 */
01293                 raw_udp4_send_sock = raw_socket(IPPROTO_RAW, 0, 0, 1);
01294                 if (raw_udp4_send_sock < 0) {
01295                         if ( default_core_cfg.udp4_raw > 0) {
01296                                 /* force use raw socket failed */
01297                                 ERR("could not initialize raw udp send socket (ipv4):"
01298                                                 " %s (%d)\n", strerror(errno), errno);
01299                                 if (errno == EPERM)
01300                                         ERR("could not initialize raw socket on startup"
01301                                                 " due to inadequate permissions, please"
01302                                                 " restart as root or with CAP_NET_RAW\n");
01303                                 goto error;
01304                         }
01305                         default_core_cfg.udp4_raw = 0; /* disabled */
01306                 } else {
01307                         register_fds(1);
01308                         if (default_core_cfg.udp4_raw < 0) {
01309                                 /* auto-detect => use it */
01310                                 default_core_cfg.udp4_raw = 1; /* enabled */
01311                                 DBG("raw socket possible => turning it on\n");
01312                         }
01313                         if (default_core_cfg.udp4_raw_ttl < 0) {
01314                                 /* auto-detect */
01315                                 default_core_cfg.udp4_raw_ttl = sock_get_ttl(sendipv4->socket);
01316                                 if (default_core_cfg.udp4_raw_ttl < 0)
01317                                         /* error, use some default value */
01318                                         default_core_cfg.udp4_raw_ttl = 63;
01319                         }
01320                 }
01321 #else
01322                 default_core_cfg.udp4_raw = 0;
01323 #endif /* USE_RAW_SOCKS */
01324                 } else
01325                         sendipv6=bind_address;
01326                 if (udp_listen->next){
01327                         LOG(L_WARN, "WARNING: using only the first listen address"
01328                                                 " (no fork)\n");
01329                 }
01330 
01331                 /* delay cfg_shmize to the last moment (it must be called _before_
01332                    forking). Changes to default cfgs after this point will be
01333                    ignored.
01334                 */
01335                 if (cfg_shmize() < 0) {
01336                         LOG(L_CRIT, "could not initialize shared configuration\n");
01337                         goto error;
01338                 }
01339         
01340                 /* Register the children that will keep updating their
01341                  * local configuration */
01342                 cfg_register_child(
01343                                 1   /* main = udp listener */
01344                                 + 1 /* timer */
01345 #ifdef USE_SLOW_TIMER
01346                                 + 1 /* slow timer */
01347 #endif
01348                         );
01349                 if (do_suid()==-1) goto error; /* try to drop privileges */
01350                 /* process_no now initialized to zero -- increase from now on
01351                    as new processes are forked (while skipping 0 reserved for main
01352                 */
01353 
01354                 /* Temporary set the local configuration of the main process
01355                  * to make the group instances available in PROC_INIT.
01356                  */
01357                 cfg_main_set_local();
01358 
01359                 /* init childs with rank==PROC_INIT before forking any process,
01360                  * this is a place for delayed (after mod_init) initializations
01361                  * (e.g. shared vars that depend on the total number of processes
01362                  * that is known only after all mod_inits have been executed )
01363                  * WARNING: the same init_child will be called latter, a second time
01364                  * for the "main" process with rank PROC_MAIN (make sure things are
01365                  * not initialized twice)*/
01366                 if (init_child(PROC_INIT) < 0) {
01367                         LOG(L_ERR, "ERROR: main_dontfork: init_child(PROC_INT) --"
01368                                                 " exiting\n");
01369                         cfg_main_reset_local();
01370                         goto error;
01371                 }
01372                 cfg_main_reset_local();
01373                 if (counters_prefork_init(get_max_procs()) == -1) goto error;
01374 
01375 #ifdef USE_SLOW_TIMER
01376                 /* we need another process to act as the "slow" timer*/
01377                                 pid = fork_process(PROC_TIMER, "slow timer", 0);
01378                                 if (pid<0){
01379                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
01380                                         goto error;
01381                                 }
01382                                 if (pid==0){
01383                                         /* child */
01384                                         /* timer!*/
01385                                         /* process_bit = 0; */
01386                                         if (real_time&2)
01387                                                 set_rt_prio(rt_timer2_prio, rt_timer2_policy);
01388 
01389                                         if (arm_slow_timer()<0) goto error;
01390                                         slow_timer_main();
01391                                 }else{
01392                                         slow_timer_pid=pid;
01393                                 }
01394 #endif
01395                                 /* we need another process to act as the "main" timer*/
01396                                 pid = fork_process(PROC_TIMER, "timer", 0);
01397                                 if (pid<0){
01398                                         LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
01399                                         goto error;
01400                                 }
01401                                 if (pid==0){
01402                                         /* child */
01403                                         /* timer!*/
01404                                         /* process_bit = 0; */
01405                                         if (real_time&1)
01406                                                 set_rt_prio(rt_timer1_prio, rt_timer1_policy);
01407                                         if (arm_timer()<0) goto error;
01408                                         timer_main();
01409                                 }else{
01410                                 }
01411 
01412                 /* main process, receive loop */
01413                 process_no=0; /*main process number*/
01414                 pt[process_no].pid=getpid();
01415                 snprintf(pt[process_no].desc, MAX_PT_DESC,
01416                         "stand-alone receiver @ %s:%s",
01417                          bind_address->name.s, bind_address->port_no_str.s );
01418 
01419                 /* call it also w/ PROC_MAIN to make sure modules that init things 
01420                  * only in PROC_MAIN get a chance to run */
01421                 if (init_child(PROC_MAIN) < 0) {
01422                         LOG(L_ERR, "ERROR: main_dontfork: init_child(PROC_MAIN) "
01423                                                 "-- exiting\n");
01424                         goto error;
01425                 }
01426 
01427                 /* We will call child_init even if we
01428                  * do not fork - and it will be called with rank 1 because
01429                  * in fact we behave like a child, not like main process
01430                  */
01431 
01432                 if (init_child(PROC_SIPINIT) < 0) {
01433                         LOG(L_ERR, "main_dontfork: init_child failed\n");
01434                         goto error;
01435                 }
01436                 return udp_rcv_loop();
01437         }else{ /* fork: */
01438 
01439                 /* Register the children that will keep updating their
01440                  * local configuration. (udp/tcp/sctp listeneres
01441                  * will be added later.) */
01442                 cfg_register_child(
01443                                 1   /* timer */
01444 #ifdef USE_SLOW_TIMER
01445                                 + 1 /* slow timer */
01446 #endif
01447                         );
01448 
01449                 for(si=udp_listen;si;si=si->next){
01450                         /* create the listening socket (for each address)*/
01451                         /* udp */
01452                         if (udp_init(si)==-1) goto error;
01453                         /* get first ipv4/ipv6 socket*/
01454                         if ((si->address.af==AF_INET)&&
01455                                         ((sendipv4==0)||(sendipv4->flags&(SI_IS_LO|SI_IS_MCAST))))
01456                                 sendipv4=si;
01457         #ifdef USE_IPV6
01458                         if ( ((sendipv6==0)||(sendipv6->flags&(SI_IS_LO|SI_IS_MCAST))) &&
01459                                         (si->address.af==AF_INET6))
01460                                 sendipv6=si;
01461         #endif
01462                         /* children_no per each socket */
01463                         cfg_register_child((si->workers>0)?si->workers:children_no);
01464                 }
01465 #ifdef USE_RAW_SOCKS
01466                 /* always try to have a raw socket opened if we are using ipv4 */
01467                 if (sendipv4) {
01468                         raw_udp4_send_sock = raw_socket(IPPROTO_RAW, 0, 0, 1);
01469                         if (raw_udp4_send_sock < 0) {
01470                                 if ( default_core_cfg.udp4_raw > 0) {
01471                                                 /* force use raw socket failed */
01472                                                 ERR("could not initialize raw udp send socket (ipv4):"
01473                                                                 " %s (%d)\n", strerror(errno), errno);
01474                                                 if (errno == EPERM)
01475                                                         ERR("could not initialize raw socket on startup"
01476                                                                 " due to inadequate permissions, please"
01477                                                                 " restart as root or with CAP_NET_RAW\n");
01478                                                 goto error;
01479                                         }
01480                                         default_core_cfg.udp4_raw = 0; /* disabled */
01481                         } else {
01482                                 register_fds(1);
01483                                 if (default_core_cfg.udp4_raw < 0) {
01484                                         /* auto-detect => use it */
01485                                         default_core_cfg.udp4_raw = 1; /* enabled */
01486                                         DBG("raw socket possible => turning it on\n");
01487                                 }
01488                                 if (default_core_cfg.udp4_raw_ttl < 0) {
01489                                         /* auto-detect */
01490                                         default_core_cfg.udp4_raw_ttl =
01491                                                 sock_get_ttl(sendipv4->socket);
01492                                         if (default_core_cfg.udp4_raw_ttl < 0)
01493                                                 /* error, use some default value */
01494                                                 default_core_cfg.udp4_raw_ttl = 63;
01495                                 }
01496                         }
01497                 }
01498 #else
01499                 default_core_cfg.udp4_raw = 0;
01500 #endif /* USE_RAW_SOCKS */
01501 #ifdef USE_SCTP
01502                 if (!sctp_disable){
01503                         for(si=sctp_listen; si; si=si->next){
01504                                 if (sctp_init_sock(si)==-1)  goto error;
01505                                 /* get first ipv4/ipv6 socket*/
01506                                 if ((si->address.af==AF_INET) &&
01507                                                 ((sendipv4_sctp==0) ||
01508                                                         (sendipv4_sctp->flags&(SI_IS_LO|SI_IS_MCAST))))
01509                                         sendipv4_sctp=si;
01510                 #ifdef USE_IPV6
01511                                 if( ((sendipv6_sctp==0) || 
01512                                                         (sendipv6_sctp->flags&(SI_IS_LO|SI_IS_MCAST))) &&
01513                                                 (si->address.af==AF_INET6))
01514                                         sendipv6_sctp=si;
01515                 #endif
01516                                 /* sctp_children_no per each socket */
01517                                 cfg_register_child((si->workers>0)?si->workers:sctp_children_no);
01518                         }
01519                 }
01520 #endif /* USE_SCTP */
01521 #ifdef USE_TCP
01522                 if (!tcp_disable){
01523                         for(si=tcp_listen; si; si=si->next){
01524                                 /* same thing for tcp */
01525                                 if (tcp_init(si)==-1)  goto error;
01526                                 /* get first ipv4/ipv6 socket*/
01527                                 if ((si->address.af==AF_INET)&&
01528                                                 ((sendipv4_tcp==0) ||
01529                                                         (sendipv4_tcp->flags&(SI_IS_LO|SI_IS_MCAST))))
01530                                         sendipv4_tcp=si;
01531                 #ifdef USE_IPV6
01532                                 if( ((sendipv6_tcp==0) ||
01533                                                         (sendipv6_tcp->flags&(SI_IS_LO|SI_IS_MCAST))) &&
01534                                                 (si->address.af==AF_INET6))
01535                                         sendipv6_tcp=si;
01536                 #endif
01537                         }
01538                         /* the number of sockets does not matter */
01539                         cfg_register_child(tcp_children_no + 1 /* tcp main */);
01540                 }
01541 #ifdef USE_TLS
01542                 if (!tls_disable && tls_has_init_si()){
01543                         for(si=tls_listen; si; si=si->next){
01544                                 /* same as for tcp*/
01545                                 if (tls_init(si)==-1)  goto error;
01546                                 /* get first ipv4/ipv6 socket*/
01547                                 if ((si->address.af==AF_INET)&&
01548                                                 ((sendipv4_tls==0) ||
01549                                                         (sendipv4_tls->flags&(SI_IS_LO|SI_IS_MCAST))))
01550                                         sendipv4_tls=si;
01551                 #ifdef USE_IPV6
01552                                 if( ((sendipv6_tls==0) ||
01553                                                         (sendipv6_tls->flags&(SI_IS_LO|SI_IS_MCAST))) &&
01554                                                 (si->address.af==AF_INET6))
01555                                         sendipv6_tls=si;
01556                 #endif
01557                         }
01558                 }
01559 #endif /* USE_TLS */
01560 #endif /* USE_TCP */
01561 
01562                         /* all processes should have access to all the sockets (for 
01563                          * sending) so we open all first*/
01564                 if (do_suid()==-1) goto error; /* try to drop privileges */
01565 
01566                 /* delay cfg_shmize to the last moment (it must be called _before_
01567                    forking). Changes to default cfgs after this point will be
01568                    ignored (cfg_shmize() will copy the default cfgs into shmem).
01569                 */
01570                 if (cfg_shmize() < 0) {
01571                         LOG(L_CRIT, "could not initialize shared configuration\n");
01572                         goto error;
01573                 }
01574 
01575                 /* Temporary set the local configuration of the main process
01576                  * to make the group instances available in PROC_INIT.
01577                  */
01578                 cfg_main_set_local();
01579 
01580                 /* init childs with rank==PROC_INIT before forking any process,
01581                  * this is a place for delayed (after mod_init) initializations
01582                  * (e.g. shared vars that depend on the total number of processes
01583                  * that is known only after all mod_inits have been executed )
01584                  * WARNING: the same init_child will be called latter, a second time
01585                  * for the "main" process with rank PROC_MAIN (make sure things are
01586                  * not initialized twice)*/
01587                 if (init_child(PROC_INIT) < 0) {
01588                         LOG(L_ERR, "ERROR: main: error in init_child(PROC_INT) --"
01589                                         " exiting\n");
01590                         cfg_main_reset_local();
01591                         goto error;
01592                 }
01593                 cfg_main_reset_local();
01594                 if (counters_prefork_init(get_max_procs()) == -1) goto error;
01595 
01596 
01597                 /* udp processes */
01598                 for(si=udp_listen; si; si=si->next){
01599                         nrprocs = (si->workers>0)?si->workers:children_no;
01600                         for(i=0;i<nrprocs;i++){
01601                                 if(si->address.af==AF_INET6) {
01602                                         if(si->useinfo.name.s)
01603                                                 snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
01604                                                         "sock=[%s]:%s (%s:%s)",
01605                                                         i, si->name.s, si->port_no_str.s,
01606                                                         si->useinfo.name.s, si->useinfo.port_no_str.s);
01607                                         else
01608                                                 snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
01609                                                         "sock=[%s]:%s",
01610                                                         i, si->name.s, si->port_no_str.s);
01611                                 } else {
01612                                         if(si->useinfo.name.s)
01613                                                 snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
01614                                                         "sock=%s:%s (%s:%s)",
01615                                                         i, si->name.s, si->port_no_str.s,
01616                                                         si->useinfo.name.s, si->useinfo.port_no_str.s);
01617                                         else
01618                                                 snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
01619                                                         "sock=%s:%s",
01620                                                         i, si->name.s, si->port_no_str.s);
01621                                 }
01622                                 child_rank++;
01623                                 pid = fork_process(child_rank, si_desc, 1);
01624                                 if (pid<0){
01625                                         LOG(L_CRIT,  "main_loop: Cannot fork\n");
01626                                         goto error;
01627                                 }else if (pid==0){
01628                                         /* child */
01629                                         bind_address=si; /* shortcut */
01630 #ifdef STATS
01631                                         setstats( i+r*children_no );
01632 #endif
01633                                         return udp_rcv_loop();
01634                                 }
01635                         }
01636                         /*parent*/
01637                         /*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
01638                 }
01639 #ifdef USE_SCTP
01640                 /* sctp processes */
01641                 if (!sctp_disable){
01642                         for(si=sctp_listen; si; si=si->next){
01643                                 nrprocs = (si->workers>0)?si->workers:sctp_children_no;
01644                                 for(i=0;i<nrprocs;i++){
01645                                         if(si->address.af==AF_INET6) {
01646                                                 snprintf(si_desc, MAX_PT_DESC, "sctp receiver child=%d "
01647                                                                 "sock=[%s]:%s",
01648                                                                 i, si->name.s, si->port_no_str.s);
01649                                         } else {
01650                                                 snprintf(si_desc, MAX_PT_DESC, "sctp receiver child=%d "
01651                                                                 "sock=%s:%s",
01652                                                                 i, si->name.s, si->port_no_str.s);
01653                                         }
01654                                         child_rank++;
01655                                         pid = fork_process(child_rank, si_desc, 1);
01656                                         if (pid<0){
01657                                                 LOG(L_CRIT,  "main_loop: Cannot fork\n");
01658                                                 goto error;
01659                                         }else if (pid==0){
01660                                                 /* child */
01661                                                 bind_address=si; /* shortcut */
01662 #ifdef STATS
01663                                                 setstats( i+r*children_no );
01664 #endif
01665                                                 return sctp_rcv_loop();
01666                                         }
01667                                 }
01668                         /*parent*/
01669                         /*close(sctp_sock)*/; /*if closed=>sendto invalid fd errors?*/
01670                         }
01671                 }
01672 #endif /* USE_SCTP */
01673 
01674                 /*this is the main process*/
01675                 bind_address=0; /* main proc -> it shouldn't send anything, */
01676 
01677 #ifdef USE_SLOW_TIMER
01678                 /* fork again for the "slow" timer process*/
01679                 pid = fork_process(PROC_TIMER, "slow timer", 1);
01680                 if (pid<0){
01681                         LOG(L_CRIT, "main_loop: cannot fork \"slow\" timer process\n");
01682                         goto error;
01683                 }else if (pid==0){
01684                         /* child */
01685                         if (real_time&2)
01686                                 set_rt_prio(rt_timer2_prio, rt_timer2_policy);
01687                         if (arm_slow_timer()<0) goto error;
01688                         slow_timer_main();
01689                 }else{
01690                         slow_timer_pid=pid;
01691                 }
01692 #endif /* USE_SLOW_TIMER */
01693 
01694                 /* fork again for the "main" timer process*/
01695                 pid = fork_process(PROC_TIMER, "timer", 1);
01696                 if (pid<0){
01697                         LOG(L_CRIT, "main_loop: cannot fork timer process\n");
01698                         goto error;
01699                 }else if (pid==0){
01700                         /* child */
01701                         if (real_time&1)
01702                                 set_rt_prio(rt_timer1_prio, rt_timer1_policy);
01703                         if (arm_timer()<0) goto error;
01704                         timer_main();
01705                 }
01706 
01707         /* init childs with rank==MAIN before starting tcp main (in case they want
01708          * to fork  a tcp capable process, the corresponding tcp. comm. fds in
01709          * pt[] must be set before calling tcp_main_loop()) */
01710                 if (init_child(PROC_MAIN) < 0) {
01711                         LOG(L_ERR, "ERROR: main: error in init_child\n");
01712                         goto error;
01713                 }
01714 
01715 #ifdef USE_TCP
01716                 if (!tcp_disable){
01717                                 /* start tcp  & tls receivers */
01718                         if (tcp_init_children()<0) goto error;
01719                                 /* start tcp+tls master proc */
01720                         pid = fork_process(PROC_TCP_MAIN, "tcp main process", 0);
01721                         if (pid<0){
01722                                 LOG(L_CRIT, "main_loop: cannot fork tcp main process: %s\n",
01723                                                         strerror(errno));
01724                                 goto error;
01725                         }else if (pid==0){
01726                                 /* child */
01727                                 tcp_main_loop();
01728                         }else{
01729                                 tcp_main_pid=pid;
01730                                 unix_tcp_sock=-1;
01731                         }
01732                 }
01733 #endif
01734                 /* main */
01735                 strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
01736 #ifdef USE_TCP
01737                 close_extra_socks(PROC_ATTENDANT, get_proc_no());
01738                 if(!tcp_disable){
01739                         /* main's tcp sockets are disabled by default from init_pt() */
01740                         unix_tcp_sock=-1;
01741                 }
01742 #endif
01743                 /* init cfg, but without per child callbacks support */
01744                 cfg_child_no_cb_init();
01745                 cfg_ok=1;
01746 
01747 #ifdef EXTRA_DEBUG
01748                 for (r=0; r<*process_count; r++){
01749                         fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
01750                 }
01751 #endif
01752                 DBG("Expect maximum %d  open fds\n", get_max_open_fds());
01753                 /* in daemonize mode send the exit code back to the parent process */
01754                 if (!dont_daemonize) {
01755                         if (daemon_status_send(0) < 0) {
01756                                 ERR("error sending daemon status: %s [%d]\n",
01757                                                 strerror(errno), errno);
01758                                 goto error;
01759                         }
01760                 }
01761                 for(;;){
01762                         handle_sigs();
01763                         pause();
01764                         cfg_update();
01765                 }
01766         
01767         }
01768 
01769         /*return 0; */
01770 error:
01771                                  /* if we are here, we are the "main process",
01772                                   any forked children should exit with exit(-1) and not
01773                                   ever use return */
01774         return -1;
01775 
01776 }
01777 
01778 /*
01779  * Calculate number of processes, this does not
01780  * include processes created by modules
01781  */
01782 static int calc_proc_no(void)
01783 {
01784         int udp_listeners;
01785         struct socket_info* si;
01786 #ifdef USE_TCP
01787         int tcp_listeners;
01788         int tcp_e_listeners;
01789 #endif
01790 #ifdef USE_SCTP
01791         int sctp_listeners;
01792 #endif
01793 
01794         for (si=udp_listen, udp_listeners=0; si; si=si->next)
01795                 udp_listeners += (si->workers>0)?si->workers:children_no;
01796 #ifdef USE_TCP
01797         for (si=tcp_listen, tcp_listeners=0, tcp_e_listeners=0; si; si=si->next) {
01798                 if(si->workers>0)
01799                         tcp_listeners += si->workers;
01800                 else
01801                          tcp_e_listeners = tcp_cfg_children_no;
01802         }
01803         tcp_listeners += tcp_e_listeners;
01804         tcp_children_no = tcp_listeners;
01805 #endif
01806 #ifdef USE_SCTP
01807         for (si=sctp_listen, sctp_listeners=0; si; si=si->next)
01808                 sctp_listeners += (si->workers>0)?si->workers:sctp_children_no;
01809 #endif
01810         return
01811                      /* receivers and attendant */
01812                 (dont_fork ? 1 : udp_listeners + 1)
01813                      /* timer process */
01814                 + 1 /* always, we need it in most cases, and we can't tell here
01815                        & now if we don't need it */
01816 #ifdef USE_SLOW_TIMER
01817                 + 1 /* slow timer process */
01818 #endif
01819 #ifdef USE_TCP
01820                 +((!tcp_disable)?( 1/* tcp main */ + tcp_listeners ):0)
01821 #endif
01822 #ifdef USE_SCTP
01823                 +((!sctp_disable)?sctp_listeners:0)
01824 #endif
01825                 ;
01826 }
01827 
01828 int main(int argc, char** argv)
01829 {
01830 
01831         FILE* cfg_stream;
01832         int c,r;
01833         char *tmp;
01834         int tmp_len;
01835         int port;
01836         int proto;
01837         char *options;
01838         int ret;
01839         unsigned int seed;
01840         int rfd;
01841         int debug_save, debug_flag;
01842         int dont_fork_cnt;
01843         struct name_lst* n_lst;
01844         char *p;
01845 
01846         /*init*/
01847         time(&up_since);
01848         creator_pid = getpid();
01849         ret=-1;
01850         my_argc=argc; my_argv=argv;
01851         debug_flag=0;
01852         dont_fork_cnt=0;
01853 
01854         daemon_status_init();
01855         /* command line options */
01856         options=  ":f:cm:M:dVIhEb:l:L:n:vrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:"
01857 #ifdef STATS
01858                 "s:"
01859 #endif
01860         ;
01861         /* Handle special command line arguments, that must be treated before
01862          * intializing the various subsystem or before parsing other arguments:
01863          *  - get the startup debug and log_stderr values
01864          *  - look if pkg mem size is overriden on the command line (-M) and get
01865          *    the new value here (before intializing pkg_mem).
01866          *  - look if there is a -h, e.g. -f -h construction won't be caught
01867          *    later
01868          */
01869         opterr = 0;
01870         while((c=getopt(argc,argv,options))!=-1) {
01871                 switch(c) {
01872                         case 'd':
01873                                         debug_flag = 1;
01874                                         default_core_cfg.debug++;
01875                                         break;
01876                         case 'E':
01877                                         log_stderr=1;
01878                                         break;
01879                         case 'M':
01880                                         pkg_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
01881                                         if (tmp &&(*tmp)){
01882                                                 fprintf(stderr, "bad private mem size number: -M %s\n",
01883                                                                                         optarg);
01884                                                 goto error;
01885                                         };
01886                                         break;
01887                         default:
01888                                         if (c == 'h' || (optarg && strcmp(optarg, "-h") == 0)) {
01889                                                 printf("version: %s\n", full_version);
01890                                                 printf("%s",help_msg);
01891                                                 exit(0);
01892                                         }
01893                                         break;
01894                 }
01895         }
01896         
01897         /*init pkg mallocs (before parsing cfg or the rest of the cmd line !)*/
01898         if (pkg_mem_size)
01899                 LOG(L_INFO, " private (per process) memory: %ld bytes\n",
01900                                                                 pkg_mem_size );
01901         if (init_pkg_mallocs()==-1)
01902                 goto error;
01903 
01904 #ifdef DBG_MSG_QA
01905         fprintf(stderr, "WARNING: ser startup: "
01906                 "DBG_MSG_QA enabled, ser may exit abruptly\n");
01907 #endif
01908 
01909         /* init counters / stats */
01910         if (init_counters() == -1)
01911                 goto error;
01912 #ifdef USE_TCP
01913         init_tcp_options(); /* set the defaults before the config */
01914 #endif
01915 #ifdef USE_SCTP
01916         init_sctp_options(); /* set defaults before the config */
01917 #endif
01918         /* process command line (cfg. file path etc) */
01919         optind = 1;  /* reset getopt */
01920         /* switches required before script processing */
01921         while((c=getopt(argc,argv,options))!=-1) {
01922                 switch(c) {
01923                         case 'f':
01924                                         cfg_file=optarg;
01925                                         break;
01926                         case 'c':
01927                                         config_check=1;
01928                                         log_stderr=1; /* force stderr logging */
01929                                         break;
01930                         case 'L':
01931                                         mods_dir = optarg;
01932                                         break;
01933                         case 'm':
01934                                         shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
01935                                         if (tmp &&(*tmp)){
01936                                                 fprintf(stderr, "bad shmem size number: -m %s\n",
01937                                                                                 optarg);
01938                                                 goto error;
01939                                         };
01940                                         LOG(L_INFO, "ser: shared memory: %ld bytes\n",
01941                                                                         shm_mem_size );
01942                                         break;
01943                         case 'M':
01944                                         /* ignore it, it was parsed immediately after startup,
01945                                            the pkg mem. is already initialized at this point */
01946                                         break;
01947                         case 'd':
01948                                         /* ignore it, was parsed immediately after startup */
01949                                         break;
01950                         case 'V':
01951                                         printf("version: %s\n", full_version);
01952                                         printf("flags: %s\n", ver_flags );
01953                                         print_ct_constants();
01954 #ifdef USE_SCTP
01955                                         tmp=malloc(256);
01956                                         if (tmp && (sctp_check_compiled_sockopts(tmp, 256)!=0))
01957                                                 printf("sctp unsupported socket options: %s\n", tmp);
01958                                         if (tmp) free(tmp);
01959 #endif
01960                                         printf("id: %s\n", ver_id);
01961                                         printf("compiled on %s with %s\n",
01962                                                         ver_compiled_time, ver_compiler );
01963 
01964                                         exit(0);
01965                                         break;
01966                         case 'I':
01967                                         print_internals();
01968                                         exit(0);
01969                                         break;
01970                         case 'E':
01971                                         /* ignore it, was parsed immediately after startup */
01972                                         break;
01973                         case 'O':
01974                                         scr_opt_lev=strtol(optarg, &tmp, 10);
01975                                         if (tmp &&(*tmp)){
01976                                                 fprintf(stderr, "bad optimization level: -O %s\n",
01977                                                                                 optarg);
01978                                                 goto error;
01979                                         };
01980                                         break;
01981                         case 'u':
01982                                         /* user needed for possible shm. pre-init */
01983                                         user=optarg;
01984                                         break;
01985                         case 'A':
01986                                         p = strchr(optarg, '=');
01987                                         if(p) {
01988                                                 *p = '\0';
01989                                         }
01990                                         pp_define_set_type(0);
01991                                         if(pp_define(strlen(optarg), optarg)<0) {
01992                                                 fprintf(stderr, "error at define param: -A %s\n",
01993                                                                 optarg);
01994                                                 goto error;
01995                                         }
01996                                         if(p) {
01997                                                 *p = '=';
01998                                                 p++;
01999                                                 if(pp_define_set(strlen(p), p)<0) {
02000                                                         fprintf(stderr, "error at define value: -A %s\n",
02001                                                                 optarg);
02002                                                         goto error;
02003                                                 }
02004                                         }
02005                                         break;
02006                         case 'b':
02007                         case 'l':
02008                         case 'n':
02009                         case 'v':
02010                         case 'r':
02011                         case 'R':
02012                         case 'D':
02013                         case 'T':
02014                         case 'N':
02015                         case 'W':
02016                         case 'w':
02017                         case 't':
02018                         case 'g':
02019                         case 'P':
02020                         case 'G':
02021                         case 'S':
02022                         case 'Q':
02023                         case 'a':
02024                         case 's':
02025                                         break;
02026                         case '?':
02027                                         if (isprint(optopt)) {
02028                                                 fprintf(stderr, "Unknown option `-%c'."
02029                                                                                 " Use -h for help.\n", optopt);
02030                                         } else {
02031                                                 fprintf(stderr, "Unknown option character `\\x%x'."
02032                                                                                 " Use -h for help.\n",
02033                                                         optopt);
02034                                         }
02035                                         goto error;
02036                         case ':':
02037                                         fprintf(stderr, "Option `-%c' requires an argument."
02038                                                                         " Use -h for help.\n",
02039                                                 optopt);
02040                                         goto error;
02041                         default:
02042                                         abort();
02043                 }
02044         }
02045 
02046         if (endianness_sanity_check() != 0){
02047                 fprintf(stderr, "BUG: endianness sanity tests failed\n");
02048                 goto error;
02049         }
02050         if (init_routes()<0) goto error;
02051         if (init_nonsip_hooks()<0) goto error;
02052         if (init_script_cb()<0) goto error;
02053         if (pv_init_api()<0) goto error;
02054         if (pv_register_core_vars()!=0) goto error;
02055         if (init_rpcs()<0) goto error;
02056         if (register_core_rpcs()!=0) goto error;
02057 
02058         /* Fix the value of cfg_file variable.*/
02059         if (fix_cfg_file() < 0) goto error;
02060 
02061         /* load config file or die */
02062         cfg_stream=fopen (cfg_file, "r");
02063         if (cfg_stream==0){
02064                 fprintf(stderr, "ERROR: loading config file(%s): %s\n", cfg_file,
02065                                 strerror(errno));
02066                 goto error;
02067         }
02068 
02069         /* seed the prng */
02070         /* try to use /dev/urandom if possible */
02071         seed=0;
02072         if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){
02073 try_again:
02074                 if (read(rfd, (void*)&seed, sizeof(seed))==-1){
02075                         if (errno==EINTR) goto try_again; /* interrupted by signal */
02076                         LOG(L_WARN, "WARNING: could not read from /dev/urandom (%d)\n",
02077                                                 errno);
02078                 }
02079                 DBG("read %u from /dev/urandom\n", seed);
02080                         close(rfd);
02081         }else{
02082                 LOG(L_WARN, "WARNING: could not open /dev/urandom (%d)\n", errno);
02083         }
02084         seed+=getpid()+time(0);
02085         DBG("seeding PRNG with %u\n", seed);
02086         srand(seed);
02087         fastrand_seed(rand());
02088         srandom(rand()+time(0));
02089         DBG("test random numbers %u %lu %u\n", rand(), random(), fastrand());
02090 
02091         /*register builtin  modules*/
02092         register_builtin_modules();
02093 
02094         /* init named flags */
02095         init_named_flags();
02096 
02097         yyin=cfg_stream;
02098         debug_save = default_core_cfg.debug;
02099         if ((yyparse()!=0)||(cfg_errors)){
02100                 fprintf(stderr, "ERROR: bad config file (%d errors)\n", cfg_errors);
02101 
02102                 goto error;
02103         }
02104         if (cfg_warnings){
02105                 fprintf(stderr, "%d config warnings\n", cfg_warnings);
02106         }
02107         if (debug_flag) default_core_cfg.debug = debug_save;
02108         print_rls();
02109 
02110         /* options with higher priority than cfg file */
02111         optind = 1;  /* reset getopt */
02112         while((c=getopt(argc,argv,options))!=-1) {
02113                 switch(c) {
02114                         case 'f':
02115                         case 'c':
02116                         case 'm':
02117                         case 'M':
02118                         case 'd':
02119                         case 'V':
02120                         case 'I':
02121                         case 'h':
02122                         case 'O':
02123                         case 'A':
02124                                         break;
02125                         case 'E':
02126                                         log_stderr=1;   /* use in both getopt switches,
02127                                                                            takes priority over config */
02128                                         break;
02129                         case 'b':
02130                                         maxbuffer=strtol(optarg, &tmp, 10);
02131                                         if (tmp &&(*tmp)){
02132                                                 fprintf(stderr, "bad max buffer size number: -b %s\n",
02133                                                                                         optarg);
02134                                                 goto error;
02135                                         }
02136                                         break;
02137                         case 'l':
02138                                         if ((n_lst=parse_phostport_mh(optarg, &tmp, &tmp_len,
02139                                                                                         &port, &proto))==0){
02140                                                 fprintf(stderr, "bad -l address specifier: %s\n",
02141                                                                                 optarg);
02142                                                 goto error;
02143                                         }
02144                                         /* add a new addr. to our address list */
02145                                         if (add_listen_iface(n_lst->name, n_lst->next,  port,
02146                                                                                         proto, n_lst->flags)!=0){
02147                                                 fprintf(stderr, "failed to add new listen address\n");
02148                                                 free_name_lst(n_lst);
02149                                                 goto error;
02150                                         }
02151                                         free_name_lst(n_lst);
02152                                         break;
02153                         case 'n':
02154                                         children_no=strtol(optarg, &tmp, 10);
02155                                         if ((tmp==0) ||(*tmp)){
02156                                                 fprintf(stderr, "bad process number: -n %s\n",
02157                                                                         optarg);
02158                                                 goto error;
02159                                         }
02160                                         break;
02161                         case 'v':
02162                                         check_via=1;
02163                                         break;
02164                         case 'r':
02165                                         received_dns|=DO_DNS;
02166                                         break;
02167                         case 'R':
02168                                         received_dns|=DO_REV_DNS;
02169                                         break;
02170                         case 'D':
02171                                         dont_fork_cnt++;
02172                                         break;
02173                         case 'T':
02174                                 #ifdef USE_TCP
02175                                         tcp_disable=1;
02176                                 #else
02177                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
02178                                 #endif
02179                                         break;
02180                         case 'N':
02181                                 #ifdef USE_TCP
02182                                         tcp_cfg_children_no=strtol(optarg, &tmp, 10);
02183                                         if ((tmp==0) ||(*tmp)){
02184                                                 fprintf(stderr, "bad process number: -N %s\n",
02185                                                                         optarg);
02186                                                 goto error;
02187                                         }
02188                                 #else
02189                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
02190                                 #endif
02191                                         break;
02192                         case 'W':
02193                                 #ifdef USE_TCP
02194                                         tcp_poll_method=get_poll_type(optarg);
02195                                         if (tcp_poll_method==POLL_NONE){
02196                                                 fprintf(stderr, "bad poll method name: -W %s\ntry "
02197                                                                                 "one of %s.\n", optarg, poll_support);
02198                                                 goto error;
02199                                         }
02200                                 #else
02201                                         fprintf(stderr,"WARNING: tcp support not compiled in\n");
02202                                 #endif
02203                                         break;
02204                         case 'S':
02205                                 #ifdef USE_SCTP
02206                                         sctp_disable=1;
02207                                 #else
02208                                         fprintf(stderr,"WARNING: sctp support not compiled in\n");
02209                                 #endif
02210                                         break;
02211                         case 'Q':
02212                                 #ifdef USE_SCTP
02213                                         sctp_children_no=strtol(optarg, &tmp, 10);
02214                                         if ((tmp==0) ||(*tmp)){
02215                                                 fprintf(stderr, "bad process number: -O %s\n",
02216                                                                         optarg);
02217                                                 goto error;
02218                                         }
02219                                 #else
02220                                         fprintf(stderr,"WARNING: sctp support not compiled in\n");
02221                                 #endif
02222                                         break;
02223                         case 'w':
02224                                         working_dir=optarg;
02225                                         break;
02226                         case 't':
02227                                         chroot_dir=optarg;
02228                                         break;
02229                         case 'u':
02230                                         user=optarg;
02231                                         break;
02232                         case 'g':
02233                                         group=optarg;
02234                                         break;
02235                         case 'P':
02236                                         pid_file=optarg;
02237                                         break;
02238                         case 'G':
02239                                         pgid_file=optarg;
02240                                         break;
02241                         case 'a':
02242                                         if(strcmp(optarg, "on")==0 || strcmp(optarg, "yes")==0)
02243                                                 sr_auto_aliases = 1;
02244                                         else if(strcmp(optarg, "off")==0 || strcmp(optarg, "no")==0)
02245                                                 sr_auto_aliases = 0;
02246                                         else {
02247                                                 fprintf(stderr,
02248                                                         "bad auto aliases parameter: %s (valid on, off, yes, no)\n",
02249                                                         optarg);
02250                                                 goto error;
02251                                         }
02252                                         break;
02253                         case 's':
02254                                 #ifdef STATS
02255                                         stat_file=optarg;
02256                                 #endif
02257                                         break;
02258                         default:
02259                                         break;
02260                 }
02261         }
02262 
02263         /* reinit if pv buffer size has been set in config */
02264         if (pv_reinit_buffer()<0)
02265                 goto error;
02266 
02267         if (dont_fork_cnt)
02268                 dont_fork = dont_fork_cnt;      /* override by command line */
02269 
02270         if (dont_fork > 0) {
02271                 dont_daemonize = dont_fork == 2;
02272                 dont_fork = dont_fork == 1;
02273         }
02274         /* init locks first */
02275         if (init_lock_ops()!=0)
02276                 goto error;
02277 #ifdef USE_TCP
02278 #ifdef USE_TLS
02279         if (tcp_disable)
02280                 tls_disable=1; /* if no tcp => no tls */
02281 #endif /* USE_TLS */
02282 #endif /* USE_TCP */
02283 #ifdef USE_SCTP
02284         if (sctp_disable!=1){
02285                 /* fix it */
02286                 if (sctp_check_support()==-1){
02287                         /* check if sctp support is auto, if not warn about disabling it */
02288                         if (sctp_disable!=2){
02289                                 fprintf(stderr, "ERROR: " "sctp enabled, but not supported by"
02290                                                                 " the OS\n");
02291                                 goto error;
02292                         }
02293                         sctp_disable=1;
02294                 }else{
02295                         /* sctp_disable!=1 and sctp supported => enable sctp */
02296                         sctp_disable=0;
02297                 }
02298         }
02299 #endif /* USE_SCTP */
02300         /* initialize the configured proto list */
02301         init_proto_order();
02302         /* init the resolver, before fixing the config */
02303         resolv_init();
02304         /* fix parameters */
02305         if (port_no<=0) port_no=SIP_PORT;
02306 #ifdef USE_TLS
02307         if (tls_port_no<=0) tls_port_no=SIPS_PORT;
02308 #endif
02309 
02310 
02311         if (children_no<=0) children_no=CHILD_NO;
02312 #ifdef USE_TCP
02313         if (!tcp_disable){
02314                 if (tcp_cfg_children_no<=0) tcp_cfg_children_no=children_no;
02315                 tcp_children_no = tcp_cfg_children_no;
02316         }
02317 #endif
02318 #ifdef USE_SCTP
02319         if (!sctp_disable){
02320                 if (sctp_children_no<=0) sctp_children_no=children_no;
02321         }
02322 #endif
02323 
02324         if (working_dir==0) working_dir="/";
02325 
02326         /* get uid/gid */
02327         if (user){
02328                 if (user2uid(&uid, &gid, user)<0){
02329                         fprintf(stderr, "bad user name/uid number: -u %s\n", user);
02330                         goto error;
02331                 }
02332         }
02333         if (group){
02334                 if (group2gid(&gid, group)<0){
02335                                 fprintf(stderr, "bad group name/gid number: -u %s\n", group);
02336                         goto error;
02337                 }
02338         }
02339         if (fix_all_socket_lists()!=0){
02340                 fprintf(stderr,  "failed to initialize list addresses\n");
02341                 goto error;
02342         }
02343         if (default_core_cfg.dns_try_ipv6 && !(socket_types & SOCKET_T_IPV6)){
02344                 /* if we are not listening on any ipv6 address => no point
02345                  * to try to resovle ipv6 addresses */
02346                 default_core_cfg.dns_try_ipv6=0;
02347         }
02348         /* print all the listen addresses */
02349         printf("Listening on \n");
02350         print_all_socket_lists();
02351         printf("Aliases: \n");
02352         /*print_aliases();*/
02353         print_aliases();
02354         printf("\n");
02355 
02356         if (dont_fork){
02357                 fprintf(stderr, "WARNING: no fork mode %s\n",
02358                                 (udp_listen)?(
02359                                 (udp_listen->next)?"and more than one listen address found "
02360                                 "(will use only the first one)":""
02361                                 ):"and no udp listen address found" );
02362         }
02363         if (config_check){
02364                 fprintf(stderr, "config file ok, exiting...\n");
02365                 return 0;
02366         }
02367 
02368 
02369         /*init shm mallocs
02370          *  this must be here
02371          *     -to allow setting shm mem size from the command line
02372          *       => if shm_mem should be settable from the cfg file move
02373          *       everything after
02374          *     -it must be also before init_timer and init_tcp
02375          *     -it must be after we know uid (so that in the SYSV sems case,
02376          *        the sems will have the correct euid)
02377          *  Note: shm can now be initialized when parsing the config script, that's
02378          *  why checking for a prior initialization is needed.
02379          * --andrei */
02380 #ifdef SHM_MEM
02381         if (!shm_initialized() && init_shm()<0)
02382                 goto error;
02383 #endif /* SHM_MEM */
02384         if (init_atomic_ops()==-1)
02385                 goto error;
02386         if (init_basex() != 0){
02387                 LOG(L_CRIT, "could not initialize base* framework\n");
02388                 goto error;
02389         }
02390         if (sr_cfg_init() < 0) {
02391                 LOG(L_CRIT, "could not initialize configuration framework\n");
02392                 goto error;
02393         }
02394         /* declare the core cfg before the module configs */
02395         if (cfg_declare("core", core_cfg_def, &default_core_cfg, cfg_sizeof(core),
02396                         &core_cfg)
02397         ) {
02398                 LOG(L_CRIT, "could not declare the core configuration\n");
02399                 goto error;
02400         }
02401 #ifdef USE_TCP
02402         if (tcp_register_cfg()){
02403                 LOG(L_CRIT, "could not register the tcp configuration\n");
02404                 goto error;
02405         }
02406 #endif /* USE_TCP */
02407 #ifdef USE_SCTP
02408         if (sctp_register_cfg()){
02409                 LOG(L_CRIT, "could not register the sctp configuration\n");
02410                 goto error;
02411         }
02412 #endif /* USE_SCTP */
02413         /*init timer, before parsing the cfg!*/
02414         if (init_timer()<0){
02415                 LOG(L_CRIT, "could not initialize timer, exiting...\n");
02416                 goto error;
02417         }
02418 #ifdef USE_DNS_CACHE
02419         if (init_dns_cache()<0){
02420                 LOG(L_CRIT, "could not initialize the dns cache, exiting...\n");
02421                 goto error;
02422         }
02423 #ifdef USE_DNS_CACHE_STATS
02424         /* preinitializing before the nubmer of processes is determined */
02425         if (init_dns_cache_stats(1)<0){
02426                 LOG(L_CRIT, "could not initialize the dns cache measurement\n");
02427                 goto error;
02428         }
02429 #endif /* USE_DNS_CACHE_STATS */
02430 #endif
02431 #ifdef USE_DST_BLACKLIST
02432         if (init_dst_blacklist()<0){
02433                 LOG(L_CRIT, "could not initialize the dst blacklist, exiting...\n");
02434                 goto error;
02435         }
02436 #ifdef USE_DST_BLACKLIST_STATS
02437         /* preinitializing before the number of processes is determined */
02438         if (init_dst_blacklist_stats(1)<0){
02439                 LOG(L_CRIT, "could not initialize the dst blacklist measurement\n");
02440                 goto error;
02441         }
02442 #endif /* USE_DST_BLACKLIST_STATS */
02443 #endif
02444         if (init_avps()<0) goto error;
02445         if (rpc_init_time() < 0) goto error;
02446 
02447 #ifdef USE_TCP
02448         if (!tcp_disable){
02449                 /*init tcp*/
02450                 if (init_tcp()<0){
02451                         LOG(L_CRIT, "could not initialize tcp, exiting...\n");
02452                         goto error;
02453                 }
02454         }
02455 #endif /* USE_TCP */
02456 #ifdef USE_SCTP
02457         if (!sctp_disable){
02458                 if (init_sctp()<0){
02459                         LOG(L_CRIT, "Could not initialize sctp, exiting...\n");
02460                         goto error;
02461                 }
02462         }
02463 #endif /* USE_SCTP */
02464         /* init_daemon? */
02465         if( !dont_fork && daemonize((log_name==0)?argv[0]:log_name, 1) < 0)
02466                 goto error;
02467         if (install_sigs() != 0){
02468                 fprintf(stderr, "ERROR: could not install the signal handlers\n");
02469                 goto error;
02470         }
02471 
02472         if (disable_core_dump) set_core_dump(0, 0);
02473         else set_core_dump(1, shm_mem_size+pkg_mem_size+4*1024*1024);
02474         if (open_files_limit>0){
02475                 if(increase_open_fds(open_files_limit)<0){
02476                         fprintf(stderr, "ERROR: error could not increase file limits\n");
02477                         goto error;
02478                 }
02479         }
02480         if (mlock_pages)
02481                 mem_lock_pages();
02482 
02483         if (real_time&4)
02484                         set_rt_prio(rt_prio, rt_policy);
02485 
02486         
02487         if (init_modules() != 0) {
02488                 fprintf(stderr, "ERROR: error while initializing modules\n");
02489                 goto error;
02490         }
02491         
02492         /* initialize process_table, add core process no. (calc_proc_no()) to the
02493          * processes registered from the modules*/
02494         if (init_pt(calc_proc_no())==-1)
02495                 goto error;
02496 #ifdef USE_TCP
02497 #ifdef USE_TLS
02498         if (!tls_disable){
02499                 if (!tls_loaded()){
02500                         LOG(L_WARN, "WARNING: tls support enabled, but no tls engine "
02501                                                 " available (forgot to load the tls module?)\n");
02502                         LOG(L_WARN, "WARNING: disabling tls...\n");
02503                         tls_disable=1;
02504                 }
02505                 /* init tls*/
02506                 if (init_tls()<0){
02507                         LOG(L_CRIT, "could not initialize tls, exiting...\n");
02508                         goto error;
02509                 }
02510         }
02511 #endif /* USE_TLS */
02512 #endif /* USE_TCP */
02513 
02514         /* The total number of processes is now known, note that no
02515          * function being called before this point may rely on the
02516          * number of processes !
02517          */
02518         DBG("Expect (at least) %d SER processes in your process list\n",
02519                         get_max_procs());
02520 
02521 #if defined USE_DNS_CACHE && defined USE_DNS_CACHE_STATS
02522         if (init_dns_cache_stats(get_max_procs())<0){
02523                 LOG(L_CRIT, "could not initialize the dns cache measurement\n");
02524                 goto error;
02525         }
02526 #endif
02527 #if defined USE_DST_BLACKLIST && defined USE_DST_BLACKLIST_STATS
02528         if (init_dst_blacklist_stats(get_max_procs())<0){
02529                 LOG(L_CRIT, "could not initialize the dst blacklist measurement\n");
02530                 goto error;
02531         }
02532 #endif
02533 
02534         /* fix routing lists */
02535         if ( (r=fix_rls())!=0){
02536                 fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
02537                                                 r);
02538                 goto error;
02539         };
02540         fixup_complete=1;
02541 
02542 #ifdef STATS
02543         if (init_stats(  dont_fork ? 1 : children_no  )==-1) goto error;
02544 #endif
02545 
02546         ret=main_loop();
02547         if (ret < 0)
02548                 goto error;
02549         /*kill everything*/
02550         if (is_main) shutdown_children(SIGTERM, 0);
02551         if (!dont_daemonize) {
02552                 if (daemon_status_send(0) < 0)
02553                         ERR("error sending exit status: %s [%d]\n",
02554                                         strerror(errno), errno);
02555         }
02556         /* else terminate process */
02557         return ret;
02558 
02559 error:
02560         /*kill everything*/
02561         if (is_main) shutdown_children(SIGTERM, 0);
02562         if (!dont_daemonize) {
02563                 if (daemon_status_send((char)-1) < 0)
02564                         ERR("error sending exit status: %s [%d]\n",
02565                                         strerror(errno), errno);
02566         }
02567         return -1;
02568 }

Generated on Tue May 22 2012 13:10:11 for SIP Router by  doxygen 1.7.1