Beispiel #1
0
/**
 * Main routine, start of the program execution.
 * \param argc the number of arguments
 * \param argv pointer to the arguments array
 * \return don't return on sucess, -1 on error
 * \see main_loop
 */
int main(int argc, char** argv)
{
    /* configure by default logging to syslog */
    int cfg_log_stderr = 0;
    FILE* cfg_stream;
    int c,r;
    char *tmp;
    int tmp_len;
    int port;
    int proto;
    char *options;
    int ret;
    unsigned int seed;
    int rfd;

    /*init*/
    ret=-1;
    my_argc=argc;
    my_argv=argv;

    /*init pkg mallocs (before parsing cfg or cmd line !)*/
    if (init_pkg_mallocs()==-1)
        goto error00;

    init_route_lists();
    /* process command line (get port no, cfg. file path etc) */
    opterr=0;
    options="f:cCm:b:l:n:N:rRvdDETSVhw:t:u:g:P:G:W:o:";

    while((c=getopt(argc,argv,options))!=-1) {
        switch(c) {
        case 'f':
            cfg_file=optarg;
            break;
        case 'C':
            config_check |= 2;
        case 'c':
            if (config_check==3)
                break;
            config_check |= 1;
            cfg_log_stderr=1; /* force stderr logging */
            break;
        case 'm':
            shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
            if (tmp &&(*tmp)) {
                LM_ERR("bad shmem size number: -m %s\n", optarg);
                goto error00;
            };

            break;
        case 'b':
            maxbuffer=strtol(optarg, &tmp, 10);
            if (tmp &&(*tmp)) {
                LM_ERR("bad max buffer size number: -b %s\n", optarg);
                goto error00;
            }
            break;
        case 'l':
            if (parse_phostport(optarg, strlen(optarg), &tmp, &tmp_len,
                                &port, &proto)<0) {
                LM_ERR("bad -l address specifier: %s\n", optarg);
                goto error00;
            }
            tmp[tmp_len]=0; /* null terminate the host */
            /* add a new addr. to our address list */
            if (add_listen_iface(tmp, port, proto, 0, 0, 0)!=0) {
                LM_ERR("failed to add new listen address\n");
                goto error00;
            }
            break;
        case 'n':
            children_no=strtol(optarg, &tmp, 10);
            if ((tmp==0) ||(*tmp)) {
                LM_ERR("bad process number: -n %s\n", optarg);
                goto error00;
            }
            break;
        case 'v':
            check_via=1;
            break;
        case 'r':
            received_dns|=DO_DNS;
            break;
        case 'R':
            received_dns|=DO_REV_DNS;
        case 'd':
#ifdef CHANGEABLE_DEBUG_LEVEL
            (*debug)++;
#else
            debug++;
#endif
            break;
        case 'D':
            dont_fork=1;
            break;
        case 'E':
            cfg_log_stderr=1;
            break;
        case 'T':
#ifdef USE_TCP
            tcp_disable=1;
#else
            LM_WARN("tcp support not compiled in\n");
#endif
            break;
        case 'S':
#ifdef USE_SCTP
            sctp_disable=1;
#else
            LM_WARN("sctp support not compiled in\n");
#endif
            break;
        case 'N':
#ifdef USE_TCP
            tcp_children_no=strtol(optarg, &tmp, 10);
            if ((tmp==0) ||(*tmp)) {
                LM_ERR("bad process number: -N %s\n", optarg);
                goto error00;
            }
#else
            LM_WARN("tcp support not compiled in\n");
#endif
            break;
        case 'W':
#ifdef USE_TCP
            tcp_poll_method=get_poll_type(optarg);
            if (tcp_poll_method==POLL_NONE) {
                LM_ERR("bad poll method name: -W %s\ntry "
                       "one of %s.\n", optarg, poll_support);
                goto error00;
            }
#else
            LM_WARN("tcp support not compiled in\n");
#endif
            break;
        case 'V':
            printf("version: %s\n", version);
            printf("flags: %s\n", flags );
            print_ct_constants();
            printf("%s\n",id);
            printf("%s compiled on %s with %s\n", __FILE__,
                   compiled, COMPILER );

            exit(0);
            break;
        case 'h':
            printf("version: %s\n", version);
            printf("%s",help_msg);
            exit(0);
            break;
        case 'w':
            working_dir=optarg;
            break;
        case 't':
            chroot_dir=optarg;
            break;
        case 'u':
            user=optarg;
            break;
        case 'g':
            group=optarg;
            break;
        case 'P':
            pid_file=optarg;
            break;
        case 'G':
            pgid_file=optarg;
            break;
        case 'o':
            if (add_arg_var(optarg) < 0)
                LM_ERR("cannot add option %s\n", optarg);
            break;
        case '?':
            if (isprint(optopt))
                LM_ERR("Unknown option `-%c`.\n", optopt);
            else
                LM_ERR("Unknown option character `\\x%x`.\n", optopt);
            goto error00;
        case ':':
            LM_ERR("Option `-%c` requires an argument.\n", optopt);
            goto error00;
        default:
            abort();
        }
    }

    log_stderr = cfg_log_stderr;

    /* fill missing arguments with the default values*/
    if (cfg_file==0) cfg_file=CFG_FILE;

    /* load config file or die */
    cfg_stream=fopen (cfg_file, "r");
    if (cfg_stream==0) {
        LM_ERR("loading config file(%s): %s\n", cfg_file,
               strerror(errno));
        goto error00;
    }

    /* seed the prng, try to use /dev/urandom if possible */
    /* no debugging information is logged, because the standard
       log level prior the config file parsing is L_NOTICE */
    seed=0;
    if ((rfd=open("/dev/urandom", O_RDONLY))!=-1) {
try_again:
        if (read(rfd, (void*)&seed, sizeof(seed))==-1) {
            if (errno==EINTR) goto try_again; /* interrupted by signal */
            LM_WARN("could not read from /dev/urandom (%d)\n", errno);
        }
        LM_DBG("initialize the pseudo random generator from "
               "/dev/urandom\n");
        LM_DBG("read %u from /dev/urandom\n", seed);
        close(rfd);
    } else {
        LM_WARN("could not open /dev/urandom (%d)\n", errno);
        LM_WARN("using a unsafe seed for the pseudo random number generator");
    }
    seed+=getpid()+time(0);
    LM_DBG("seeding PRNG with %u\n", seed);
    srand(seed);
    LM_DBG("test random number %u\n", rand());

    /*register builtin  modules*/
    register_builtin_modules();

#ifdef USE_TLS
    /* initialize default TLS domains,
       must be done before reading the config */
    if (pre_init_tls()<0) {
        LM_CRIT("could not pre_init_tls, exiting...\n");
        goto error00;
    }
#endif /* USE_TLS */

    if (preinit_black_lists()!=0) {
        LM_CRIT("failed to alloc black list's anchor\n");
        goto error00;
    }

    /* parse the config file, prior to this only default values
       e.g. for debugging settings will be used */
    yyin=cfg_stream;
    if ((yyparse()!=0)||(cfg_errors)) {
        LM_ERR("bad config file (%d errors)\n", cfg_errors);
        goto error00;
    }

    if (config_check>1 && check_rls()!=0) {
        LM_ERR("bad function call in config file\n");
        return ret;
    }
#ifdef EXTRA_DEBUG
    print_rl();
#endif

    /* init the resolver, before fixing the config */
    resolv_init();

    /* fix parameters */
    if (port_no<=0) port_no=SIP_PORT;
#ifdef USE_TLS
    if (tls_port_no<=0) tls_port_no=SIPS_PORT;
#endif


    if (children_no<=0) children_no=CHILD_NO;
#ifdef USE_TCP
    if (!tcp_disable) {
        if (tcp_children_no<=0) tcp_children_no=children_no;
    }
#endif

    if (working_dir==0) working_dir="/";

    /* get uid/gid */
    if (user) {
        if (user2uid(&uid, &gid, user)<0) {
            LM_ERR("bad user name/uid number: -u %s\n", user);
            goto error00;
        }
    }
    if (group) {
        if (group2gid(&gid, group)<0) {
            LM_ERR("bad group name/gid number: -u %s\n", group);
            goto error00;
        }
    }
    if (fix_all_socket_lists()!=0) {
        LM_ERR("failed to initialize list addresses\n");
        goto error00;
    }
    /* print all the listen addresses */
    printf("Listening on \n");
    print_all_socket_lists();
    printf("Aliases: \n");
    /*print_aliases();*/
    print_aliases();
    printf("\n");

    if (dont_fork) {
        LM_WARN("no fork mode %s\n",
                (udp_listen)?(
                    (udp_listen->next)?" and more than one listen address found"
                    "(will use only the first one)":""
                ):"and no udp listen address found" );
    }
    if (config_check) {
        LM_NOTICE("config file ok, exiting...\n");
        return 0;
    }


    time(&startup_time);

    /*init shm mallocs
     *  this must be here
     *     -to allow setting shm mem size from the command line
     *       => if shm_mem should be settable from the cfg file move
     *       everything after
     *     -it must be also before init_timer and init_tcp
     *     -it must be after we know uid (so that in the SYSV sems case,
     *        the sems will have the correct euid)
     * --andrei */
    if (init_shm_mallocs()==-1)
        goto error;
    /*init timer, before parsing the cfg!*/
    if (init_timer()<0) {
        LM_CRIT("could not initialize timer, exiting...\n");
        goto error;
    }

#ifdef USE_TCP
    if (!tcp_disable) {
        /*init tcp*/
        if (init_tcp()<0) {
            LM_CRIT("could not initialize tcp, exiting...\n");
            goto error;
        }
    }
#ifdef USE_TLS
    if (!tls_disable) {
        /* init tls*/
        if (init_tls()<0) {
            LM_CRIT("could not initialize tls, exiting...\n");
            goto error;
        }
    }
#endif /* USE_TLS */
#endif /* USE_TCP */

    /* init_daemon? */
    if (!dont_fork) {
        if ( daemonize((log_name==0)?argv[0]:log_name, &own_pgid) <0 )
            goto error;
    }

    /* install signal handlers */
    if (install_sigs() != 0) {
        LM_ERR("could not install the signal handlers\n");
        goto error;
    }

#ifdef CHANGEABLE_DEBUG_LEVEL
#ifdef SHM_MEM
    debug=shm_malloc(sizeof(int));
    if (debug==0) {
        LM_ERR("ERROR: out of memory\n");
        goto error;
    }
    *debug = debug_init;
#else
    LM_WARN("no shm mem support compiled -> changeable debug "
            "level turned off\n");
#endif
#endif

    if (disable_core_dump) set_core_dump(0, 0);
    else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024);
    if (open_files_limit>0) {
        if(increase_open_fds(open_files_limit)<0) {
            LM_ERR("ERROR: error could not increase file limits\n");
            goto error;
        }
    }

    /* print OpenSIPS version to log for history tracking */
    LM_NOTICE("version: %s\n", version);

    /* print some data about the configuration */
#ifdef SHM_MEM
    LM_INFO("using %ld Mb shared memory\n", ((shm_mem_size/1024)/1024));
#endif
    LM_INFO("using %i Mb private memory per process\n", ((PKG_MEM_POOL_SIZE/1024)/1024));

    /* init avps */
    if (init_extra_avps() != 0) {
        LM_ERR("error while initializing avps\n");
        goto error;
    }

    /* init serial forking engine */
    if (init_serialization()!=0) {
        LM_ERR("failed to initialize serialization\n");
        goto error;
    }
    /* Init statistics */
    if (init_stats_collector()<0) {
        LM_ERR("failed to initialize statistics\n");
        goto error;
    }
    /* Init MI */
    if (init_mi_core()<0) {
        LM_ERR("failed to initialize MI core\n");
        goto error;
    }

    /* Register core events */
    if (evi_register_core() != 0) {
        LM_ERR("failed register core events\n");
        goto error;
    }

    /* init black list engine */
    if (init_black_lists()!=0) {
        LM_CRIT("failed to init black lists\n");
        goto error;
    }
    /* init resolver's blacklist */
    if (resolv_blacklist_init()!=0) {
        LM_CRIT("failed to create DNS blacklist\n");
        goto error;
    }

    /* init modules */
    if (init_modules() != 0) {
        LM_ERR("error while initializing modules\n");
        goto error;
    }

    /* register route timers */
    if(register_route_timers() < 0) {
        LM_ERR("Failed to register timer\n");
        goto error;
    }

    /* check pv context list */
    if(pv_contextlist_check() != 0) {
        LM_ERR("used pv context that was not defined\n");
        goto error;
    }

    /* init query list now in shm
     * so all processes that will be forked from now on
     * will have access to it
     *
     * if it fails, give it a try and carry on */
    if (init_ql_support() != 0) {
        LM_ERR("failed to initialise buffering query list\n");
        query_buffer_size = 0;
        *query_list = NULL;
    }

    /* init multi processes support */
    if (init_multi_proc_support()!=0) {
        LM_ERR("failed to init multi-proc support\n");
        goto error;
    }

#ifdef PKG_MALLOC
    /* init stats support for pkg mem */
    if (init_pkg_stats(counted_processes)!=0) {
        LM_ERR("failed to init stats for pkg\n");
        goto error;
    }
#endif

    /* fix routing lists */
    if ( (r=fix_rls())!=0) {
        LM_ERR("failed to fix configuration with err code %d\n", r);
        goto error;
    };

    ret=main_loop();

error:

    /*kill everything*/
    kill_all_children(SIGTERM);
    /*clean-up*/
    cleanup(0);
error00:
    return ret;
}
Beispiel #2
0
/**
 * Main routine, start of the program execution.
 * \param argc the number of arguments
 * \param argv pointer to the arguments array
 * \return don't return on sucess, -1 on error
 * \see main_loop
 */
int main(int argc, char** argv)
{
	/* configure by default logging to syslog */
	int cfg_log_stderr = 1;
	FILE* cfg_stream;
	int c,r;
	char *tmp;
	int tmp_len;
	int port;
	int proto;
	char *options;
	int ret;
	unsigned int seed;
	int rfd;

	/*init*/
	ret=-1;
	my_argc=argc; my_argv=argv;

	/* process pkg mem size from command line */
	opterr=0;
	options="f:cCm:M:b:l:n:N:rRvdDFETSVhw:t:u:g:P:G:W:o:";

	while((c=getopt(argc,argv,options))!=-1){
		switch(c){
			case 'M':
					pkg_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
					if (tmp &&(*tmp)){
						LM_ERR("bad pkgmem size number: -m %s\n", optarg);
						goto error00;
					};

					break;
		}
	}
	/*init pkg mallocs (before parsing cfg but after parsing cmd line !)*/
	if (init_pkg_mallocs()==-1)
		goto error00;

	init_route_lists();

	/* process command line (get port no, cfg. file path etc) */
	/* first reset getopt */
	optind = 1;
	while((c=getopt(argc,argv,options))!=-1){
		switch(c){
			case 'f':
					cfg_file=optarg;
					break;
			case 'C':
					config_check |= 2;
			case 'c':
					if (config_check==3)
						break;
					config_check |= 1;
					cfg_log_stderr=1; /* force stderr logging */
					break;
			case 'm':
					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
					if (tmp &&(*tmp)){
						LM_ERR("bad shmem size number: -m %s\n", optarg);
						goto error00;
					};
					break;
			case 'M':
					/* ignoring it, parsed previously */
					break;
			case 'b':
					maxbuffer=strtol(optarg, &tmp, 10);
					if (tmp &&(*tmp)){
						LM_ERR("bad max buffer size number: -b %s\n", optarg);
						goto error00;
					}
					break;
			case 'l':
					if (parse_phostport(optarg, strlen(optarg), &tmp, &tmp_len,
											&port, &proto)<0){
						LM_ERR("bad -l address specifier: %s\n", optarg);
						goto error00;
					}
					tmp[tmp_len]=0; /* null terminate the host */
					/* add a new addr. to our address list */
					if (add_cmd_listener(tmp, port, proto)!=0){
						LM_ERR("failed to add new listen address\n");
						goto error00;
					}
					break;
			case 'n':
					children_no=strtol(optarg, &tmp, 10);
					if ((tmp==0) ||(*tmp)){
						LM_ERR("bad process number: -n %s\n", optarg);
						goto error00;
					}
					break;
			case 'v':
					check_via=1;
					break;
			case 'r':
					received_dns|=DO_DNS;
					break;
			case 'R':
					received_dns|=DO_REV_DNS;
				    break;
			case 'd':
					*log_level = debug_mode ? L_DBG : (*log_level)+1;
					break;
			case 'D':
					debug_mode=1;
					*log_level = L_DBG;
					break;
			case 'F':
					no_daemon_mode=1;
					break;
			case 'E':
					cfg_log_stderr=1;
					break;
			case 'N':
					tcp_children_no=strtol(optarg, &tmp, 10);
					if ((tmp==0) ||(*tmp)){
						LM_ERR("bad process number: -N %s\n", optarg);
						goto error00;
					}
					break;
			case 'W':
					io_poll_method=get_poll_type(optarg);
					if (io_poll_method==POLL_NONE){
						LM_ERR("bad poll method name: -W %s\ntry "
							"one of %s.\n", optarg, poll_support);
						goto error00;
					}
					break;
			case 'V':
					printf("version: %s\n", version);
					printf("flags: %s\n", flags );
					print_ct_constants();
					printf("%s compiled on %s with %s\n", __FILE__,
							compiled, COMPILER );
					exit(0);
					break;
			case 'h':
					printf("version: %s\n", version);
					printf("%s",help_msg);
					exit(0);
					break;
			case 'w':
					working_dir=optarg;
					break;
			case 't':
					chroot_dir=optarg;
					break;
			case 'u':
					user=optarg;
					break;
			case 'g':
					group=optarg;
					break;
			case 'P':
					pid_file=optarg;
					break;
			case 'G':
					pgid_file=optarg;
					break;
			case 'o':
					if (add_arg_var(optarg) < 0)
						LM_ERR("cannot add option %s\n", optarg);
					break;
			case '?':
					if (isprint(optopt))
						LM_ERR("Unknown option `-%c`.\n", optopt);
					else
						LM_ERR("Unknown option character `\\x%x`.\n", optopt);
					goto error00;
			case ':':
					LM_ERR("Option `-%c` requires an argument.\n", optopt);
					goto error00;
			default:
					abort();
		}
	}

	log_stderr = cfg_log_stderr;

	/* fill missing arguments with the default values*/
	if (cfg_file==0) cfg_file=CFG_FILE;

	/* load config file or die */
	cfg_stream=fopen (cfg_file, "r");
	if (cfg_stream==0){
		LM_ERR("loading config file(%s): %s\n", cfg_file,
				strerror(errno));
		goto error00;
	}

	/* seed the prng, try to use /dev/urandom if possible */
	/* no debugging information is logged, because the standard
	   log level prior the config file parsing is L_NOTICE */
	seed=0;
	if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){
try_again:
		if (read(rfd, (void*)&seed, sizeof(seed))==-1){
			if (errno==EINTR) goto try_again; /* interrupted by signal */
			LM_WARN("could not read from /dev/urandom (%d)\n", errno);
		}
		LM_DBG("initialize the pseudo random generator from "
			"/dev/urandom\n");
		LM_DBG("read %u from /dev/urandom\n", seed);
			close(rfd);
	}else{
		LM_WARN("could not open /dev/urandom (%d)\n", errno);
		LM_WARN("using a unsafe seed for the pseudo random number generator");
	}
	seed+=getpid()+time(0);
	LM_DBG("seeding PRNG with %u\n", seed);
	srand(seed);
	LM_DBG("test random number %u\n", rand());

	/*register builtin  modules*/
	register_builtin_modules();

	/* init avps */
	if (init_global_avps() != 0) {
		LM_ERR("error while initializing avps\n");
		goto error;
	}

	/* used for parser debugging */
#ifdef DEBUG_PARSER
	yydebug = 1;
#endif

	/*
	 * initializes transport interfaces - we initialize them here because we
	 * can have listening interfaces declared in the command line
	 */
	if (trans_init() < 0) {
		LM_ERR("cannot initialize transport interface\n");
		goto error;
	}

		/* get uid/gid */
	if (user){
		if (user2uid(&uid, &gid, user)<0){
			LM_ERR("bad user name/uid number: -u %s\n", user);
			goto error00;
		}
	}
	if (group){
		if (group2gid(&gid, group)<0){
			LM_ERR("bad group name/gid number: -u %s\n", group);
			goto error00;
		}
	}

		/*init shm mallocs
	 *  this must be here
	 *     -to allow setting shm mem size from the command line
	 *     -it must be also before init_timer and init_tcp
	 *     -it must be after we know uid (so that in the SYSV sems case,
	 *        the sems will have the correct euid)
	 * --andrei */
	if (init_shm_mallocs()==-1)
		goto error;

	if (init_stats_collector() < 0) {
		LM_ERR("failed to initialize statistics\n");
		goto error;
	}

	/* parse the config file, prior to this only default values
	   e.g. for debugging settings will be used */
	yyin=cfg_stream;
	if ((yyparse()!=0)||(cfg_errors)){
		LM_ERR("bad config file (%d errors)\n", cfg_errors);
		goto error00;
	}

	if (config_check>1 && check_rls()!=0) {
		LM_ERR("bad function call in config file\n");
		return ret;
	}

	if (solve_module_dependencies(modules) != 0) {
		LM_ERR("failed to solve module dependencies\n");
		return -1;
	}

	/* init the resolver, before fixing the config */
	resolv_init();

	fix_poll_method( &io_poll_method );

	/* fix temporary listeners added in the cmd line */
	if (fix_cmd_listeners() < 0) {
		LM_ERR("cannot add temproray listeners\n");
		return ret;
	}

	/* load transport protocols */
	if (trans_load() < 0) {
		LM_ERR("cannot load transport protocols\n");
		goto error;
	}

	/* fix parameters */
	if (working_dir==0) working_dir="/";

	if (fix_all_socket_lists()!=0){
		LM_ERR("failed to initialize list addresses\n");
		goto error00;
	}
	/* print all the listen addresses */
	printf("Listening on \n");
	print_all_socket_lists();
	printf("Aliases: \n");
	/*print_aliases();*/
	print_aliases();
	printf("\n");

	if (config_check){
		LM_NOTICE("config file ok, exiting...\n");
		return 0;
	}

	time(&startup_time);

	/* Init statistics */
	init_shm_statistics();

	/*init UDP networking layer*/
	if (udp_init()<0){
		LM_CRIT("could not initialize tcp\n");
		goto error;
	}
	/*init TCP networking layer*/
	if (tcp_init()<0){
		LM_CRIT("could not initialize tcp\n");
		goto error;
	}

	if (create_status_pipe() < 0) {
		LM_ERR("failed to create status pipe\n");
		goto error;
	}

	if (debug_mode) {

		LM_NOTICE("DEBUG MODE activated\n");
		if (no_daemon_mode==0) {
			LM_NOTICE("disabling daemon mode (found enabled)\n");
			no_daemon_mode = 1;
		}
		if (log_stderr==0) {
			LM_NOTICE("enabling logging to standard error (found disabled)\n");
			log_stderr = 1;
		}
		if (*log_level<L_DBG) {
			LM_NOTICE("setting logging to debug level (found on %d)\n",
				*log_level);
			*log_level = L_DBG;
		}
		if (disable_core_dump) {
			LM_NOTICE("enabling core dumping (found off)\n");
			disable_core_dump = 0;
		}
		if (udp_count_processes()!=0) {
			if (children_no!=2) {
				LM_NOTICE("setting UDP children to 2 (found %d)\n",
					children_no);
				children_no = 2;
			}
		}
		if (tcp_count_processes()!=0) {
			if (tcp_children_no!=2) {
				LM_NOTICE("setting TCP children to 2 (found %d)\n",
					tcp_children_no);
				tcp_children_no = 2;
			}
		}

	} else { /* debug_mode */

		/* init_daemon */
		if ( daemonize((log_name==0)?argv[0]:log_name, &own_pgid) <0 )
			goto error;

	}

	/* install signal handlers */
	if (install_sigs() != 0){
		LM_ERR("could not install the signal handlers\n");
		goto error;
	}

	if (disable_core_dump) set_core_dump(0, 0);
	else set_core_dump(1, shm_mem_size+pkg_mem_size+4*1024*1024);
	if (open_files_limit>0) {
		if(set_open_fds_limit()<0){
			LM_ERR("ERROR: error could not increase file limits\n");
			goto error;
		}
	}

	/* print OpenSIPS version to log for history tracking */
	LM_NOTICE("version: %s\n", version);

	/* print some data about the configuration */
	LM_INFO("using %ld Mb shared memory\n", ((shm_mem_size/1024)/1024));
	LM_INFO("using %ld Mb private memory per process\n",
		((pkg_mem_size/1024)/1024));

	/* init async reactor */
	if (init_reactor_size()<0) {
		LM_CRIT("failed to init internal reactor, exiting...\n");
		goto error;
	}

	/* init timer */
	if (init_timer()<0){
		LM_CRIT("could not initialize timer, exiting...\n");
		goto error;
	}

	/* init serial forking engine */
	if (init_serialization()!=0) {
		LM_ERR("failed to initialize serialization\n");
		goto error;
	}
	/* Init MI */
	if (init_mi_core()<0) {
		LM_ERR("failed to initialize MI core\n");
		goto error;
	}

	/* Register core events */
	if (evi_register_core() != 0) {
		LM_ERR("failed register core events\n");
		goto error;
	}

	/* init black list engine */
	if (init_black_lists()!=0) {
		LM_CRIT("failed to init blacklists\n");
		goto error;
	}
	/* init resolver's blacklist */
	if (resolv_blacklist_init()!=0) {
		LM_CRIT("failed to create DNS blacklist\n");
		goto error;
	}

	/* init modules */
	if (init_modules() != 0) {
		LM_ERR("error while initializing modules\n");
		goto error;
	}

	/* register route timers */
	if(register_route_timers() < 0) {
		LM_ERR("Failed to register timer\n");
		goto error;
	}

	/* check pv context list */
	if(pv_contextlist_check() != 0) {
		LM_ERR("used pv context that was not defined\n");
		goto error;
	}

	/* init query list now in shm
	 * so all processes that will be forked from now on
	 * will have access to it
	 *
	 * if it fails, give it a try and carry on */
	if (init_ql_support() != 0) {
		LM_ERR("failed to initialise buffering query list\n");
		query_buffer_size = 0;
		*query_list = NULL;
	}

	/* init multi processes support */
	if (init_multi_proc_support()!=0) {
		LM_ERR("failed to init multi-proc support\n");
		goto error;
	}

	#ifdef PKG_MALLOC
	/* init stats support for pkg mem */
	if (init_pkg_stats(counted_processes)!=0) {
		LM_ERR("failed to init stats for pkg\n");
		goto error;
	}
	#endif

	/* init avps */
	if (init_extra_avps() != 0) {
		LM_ERR("error while initializing avps\n");
		goto error;
	}

	/* fix routing lists */
	if ( (r=fix_rls())!=0){
		LM_ERR("failed to fix configuration with err code %d\n", r);
		goto error;
	}

	if (init_log_level() != 0) {
		LM_ERR("failed to init logging levels\n");
		goto error;
	}

	if (trans_init_all_listeners()<0) {
		LM_ERR("failed to init all SIP listeners, aborting\n");
		goto error;
	}

	/* all processes should have access to all the sockets (for sending)
	 * so we open all first*/
	if (do_suid(uid, gid)==-1)
		goto error;

	ret = main_loop();

error:
	/*kill everything*/
	kill_all_children(SIGTERM);
	/*clean-up*/
	cleanup(0);
error00:
	LM_NOTICE("Exiting....\n");
	return ret;
}