示例#1
0
/*
 * called in the OpenSIPS initialization phase by the main process.
 * forks the binary packet UDP receivers.
 *
 * @return: 0 on success
 */
int start_bin_receivers(void)
{
	pid_t pid;
	int i;

	if (udp_init_listener(bin, 0) != 0)
		return -1;

	for (i = 1; i <= bin_children; i++) {
		if ((pid = internal_fork("BIN receiver")) < 0) {
			LM_CRIT("Cannot fork binary packet receiver process!\n");
			return -1;
		}

		if (pid == 0) {
			LM_DBG("CHILD sock: %d\n", bin->socket);

			child_index = i;
			set_proc_attrs("BIN receiver %.*s ",
							bin->sock_str.len,
							bin->sock_str.s);
			bind_address = bin;

			if (init_child(PROC_BIN) < 0) {
				LM_ERR("init_child failed for BIN listener\n");
				report_failure_status();
				exit(-1);
			}

			bin_receive_loop();
			exit(-1);
		} else
			LM_DBG("PARENT sock: %d\n", bin->socket);
	}

	return 0;
}
示例#2
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int  i;
	pid_t pid;
	struct socket_info* si;
	int* startup_done = NULL;
	atomic_t *load_p;

	chd_rank=0;

	if (dont_fork){
		if (udp_listen==0){
			LM_ERR("no fork mode requires at least one"
					" udp listen address, exiting...\n");
			goto error;
		}
		/* only one address, we ignore all the others */
		if (udp_init(udp_listen)==-1) goto error;
		bind_address=udp_listen;
		sendipv4=bind_address;
		sendipv6=bind_address; /*FIXME*/
		if (udp_listen->next){
			LM_WARN("using only the first listen address (no fork)\n");
		}

		/* try to drop privileges */
		if (do_suid(uid, gid)==-1)
			goto error;

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		/* we need another process to act as the timer*/
		if (start_timer_processes()!=0) {
			LM_CRIT("cannot start timer process(es)\n");
			goto error;
		}

		/* main process, receive loop */
		set_proc_attrs("stand-alone SIP receiver %.*s", 
			 bind_address->sock_str.len, bind_address->sock_str.s );

		/* We will call child_init even if we
		 * do not fork - and it will be called with rank 1 because
		 * in fact we behave like a child, not like main process */
		if (init_child(1) < 0) {
			LM_ERR("init_child failed in don't fork\n");
			goto error;
		}

		if (startup_rlist.a)
			run_startup_route();

		is_main=1;
		load_p = shm_malloc(sizeof(atomic_t));
		if (!load_p) {
		/* highly improbable */
			LM_ERR("no more shm\n");
			goto error;
		}
		memset(load_p,0,sizeof(atomic_t));
		pt[process_no].load = load_p;

		register_udp_load_stat(&udp_listen->sock_str,load_p);
		return udp_rcv_loop();
	} else {  /* don't fork */

		for(si=udp_listen;si;si=si->next){
			/* create the listening socket (for each address)*/
			/* udp */
			if (udp_init(si)==-1) goto error;
			/* get first ipv4/ipv6 socket*/
			if ((si->address.af==AF_INET)&&
					((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
				sendipv4=si;
			#ifdef USE_IPV6
			if((sendipv6==0)&&(si->address.af==AF_INET6))
				sendipv6=si;
			#endif
		}
		#ifdef USE_TCP
		if (!tcp_disable){
			for(si=tcp_listen; si; si=si->next){
				/* same thing for tcp */
				if (tcp_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
					sendipv4_tcp=si;
				#ifdef USE_IPV6
				if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
					sendipv6_tcp=si;
				#endif
			}
		}
		#ifdef USE_TLS
		if (!tls_disable){
			for(si=tls_listen; si; si=si->next){
				/* same as for tcp*/
				if (tls_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
					sendipv4_tls=si;
				#ifdef USE_IPV6
				if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
					sendipv6_tls=si;
				#endif
			}
		}
		#endif /* USE_TLS */
		#endif /* USE_TCP */
		#ifdef USE_SCTP
		if (!sctp_disable){
			for(si=sctp_listen; si; si=si->next){
				/* same thing for sctp */
				if (sctp_server_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_sctp==0)||(sendipv4_sctp->flags&SI_IS_LO)))
					sendipv4_sctp=si;
			#ifdef USE_IPV6
				if((sendipv6_sctp==0)&&(si->address.af==AF_INET6))
					sendipv6_sctp=si;
			#endif
			}
		}
		#endif /* USE_SCTP */

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

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		if(startup_rlist.a) {/* if a startup route was defined */
			startup_done = (int*)shm_malloc(sizeof(int));
			if(startup_done == NULL)
			{
				LM_ERR("No more shared memory\n");
				goto error;
			}
			*startup_done = 0;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){
			load_p = shm_malloc(sizeof(atomic_t));
			if (!load_p) {
			/* highly improbable */
				LM_ERR("no more shm\n");
				goto error;
			}
			memset(load_p,0,sizeof(atomic_t));
			register_udp_load_stat(&si->sock_str,load_p);

			for(i=0;i<children_no;i++){
				chd_rank++;
				if ( (pid=internal_fork( "UDP receiver"))<0 ) {
					LM_CRIT("cannot fork UDP process\n");
					goto error;
				} else {
					if (pid==0) {
						/* new UDP process */
						/* set a more detailed description */
						set_proc_attrs("SIP receiver %.*s ",
							si->sock_str.len, si->sock_str.s);
						bind_address=si; /* shortcut */
						if (init_child(chd_rank) < 0) {
							LM_ERR("init_child failed for UDP listener\n");
							exit(-1);
						}

						if(chd_rank == 1 && startup_rlist.a) {
							if(run_startup_route()< 0) {
								LM_ERR("Startup route processing failed\n");
								exit(-1);
							}
							*startup_done = 1;
						}

						/* all UDP listeners on same interface
						 * have same SHM load pointer */
						pt[process_no].load = load_p;
						udp_rcv_loop();
						exit(-1);
					}
					else {
						/* if the first process that runs startup_route*/
						if(chd_rank == 1 && startup_rlist.a) {
							while(!startup_done) {
								usleep(5);
							}
							shm_free(startup_done);
						}
					}
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

	#ifdef USE_SCTP
	if(!sctp_disable){
		for(si=sctp_listen; si; si=si->next){
			for(i=0;i<children_no;i++){
				chd_rank++;
				if ( (pid=internal_fork( "SCTP receiver"))<0 ) {
					LM_CRIT("cannot fork SCTP process\n");
					goto error;
				} else if (pid==0){
					/* new SCTP process */
					/* set a more detailed description */
					set_proc_attrs("SIP receiver %.*s ",
						si->sock_str.len, si->sock_str.s);
					bind_address=si; /* shortcut */
					if (init_child(chd_rank) < 0) {
						LM_ERR("init_child failed\n");
						exit(-1);
					}
					sctp_server_rcv_loop();
					exit(-1);
				}
			}
		}
	}
	#endif /* USE_SCTP */

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	#ifdef USE_TCP
	if (!tcp_disable){
		/* start tcp  & tls receivers */
		if (tcp_init_children(&chd_rank)<0) goto error;
		/* start tcp+tls master proc */
		if ( (pid=internal_fork( "TCP main"))<0 ) {
			LM_CRIT("cannot fork tcp main process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* close the TCP inter-process sockets */
			close(unix_tcp_sock);
			unix_tcp_sock = -1;
			close(pt[process_no].unix_sock);
			pt[process_no].unix_sock = -1;
			/* init modules */
			if (init_child(PROC_TCP_MAIN) < 0) {
				LM_ERR("error in init_child for tcp main\n");
				exit(-1);
			}
			tcp_main_loop();
			exit(-1);
		}
	}
	#endif

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		LM_ERR("error in init_child for PROC_MAIN\n");
		goto error;
	}

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	return -1;

}
示例#3
0
void httpd_proc(int rank)
{
#ifdef LIBMICROHTTPD
	int status;
	fd_set rs;
	fd_set ws;
	fd_set es;
	int max;
#endif
	struct httpd_cb *cb = httpd_cb_list;

	/*child's initial settings*/
	if (init_mi_child()!=0) {
		LM_ERR("failed to init the mi child process\n");
		return;
	}

	/* Allocating http response buffer */
	buffer.s = (char*)pkg_malloc(sizeof(char)*buffer.len);
	if (buffer.s==NULL) {
		LM_ERR("oom\n");
		return;
	}

	while(cb) {
		if (cb->init_proc_callback)
			cb->init_proc_callback();
		cb = cb->next;
	}

#ifdef LIBMICROHTTPD
	struct timeval tv;
	struct sockaddr_in saddr_in;

	memset(&saddr_in, 0, sizeof(saddr_in));
	if (ip.s)
		saddr_in.sin_addr.s_addr = inet_addr(ip.s);
	else
		saddr_in.sin_addr.s_addr = INADDR_ANY;
	saddr_in.sin_family = AF_INET;
	saddr_in.sin_port = htons(port);

	LM_DBG("init_child [%d] - [%d] HTTP Server init [%s:%d]\n",
		rank, getpid(), (ip.s?ip.s:"INADDR_ANY"), port);
	set_proc_attrs("HTTPD %s:%d", (ip.s?ip.s:"INADDR_ANY"), port);
	dmn = MHD_start_daemon(MHD_NO_FLAG|MHD_USE_DEBUG, port, NULL, NULL,
			&(answer_to_connection), NULL,
			MHD_OPTION_SOCK_ADDR, &saddr_in,
			MHD_OPTION_END);

	if (NULL == dmn) {
		LM_ERR("unable to start http daemon\n");
		return;
	}

	while(1) {
		max = 0;
		FD_ZERO (&rs);
		FD_ZERO (&ws);
		FD_ZERO (&es);
		if (MHD_YES != MHD_get_fdset (dmn, &rs, &ws, &es, &max)) {
			LM_ERR("unable to get file descriptors\n");
			return;
		}
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		//LM_DBG("select(%d,%p,%p,%p,%p)\n",max+1, &rs, &ws, &es, &tv);
		status = select(max+1, &rs, &ws, &es, &tv);
		if (status < 0) {
			switch(errno){
				case EINTR:
					LM_DBG("error returned by select:"
							" [%d] [%d][%s]\n",
							status, errno, strerror(errno));
					break;
				default:
					LM_WARN("error returned by select:"
							" [%d] [%d][%s]\n",
							status, errno, strerror(errno));
					return;
			}
		}
		//LM_DBG("select returned %d\n", status);
		status = MHD_run(dmn);
		if (status == MHD_NO) {
			LM_ERR("unable to run http daemon\n");
			return;
		}
	}
#endif
	LM_DBG("HTTP Server stopped!\n");
}
示例#4
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
    static int chd_rank;
    int* startup_done = NULL;

    chd_rank=0;

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

    if (dont_fork) {

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

        if (udp_init_nofork() < 0) {
            LM_ERR("failed to init UDP for no fork mode\n");
            goto error;
        }

        /* try to drop privileges */
        if (do_suid(uid, gid)==-1)
            goto error;

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        /* we need another process to act as the timer*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        is_main=1;

        udp_start_nofork();
        /* udp_start_nofork() returns only if error */

        /* in case of failed startup, behave as "attendant" to trigger
         * proper cleanup sequance (and proper signal handler !!!).
         * So, reset the dont_fork (as it will force inline signal handling)*/
        dont_fork = 0;
        return -1;

    } else {  /* don't fork */

        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; /* try to drop privileges */

        if (start_module_procs()!=0) {
            LM_ERR("failed to fork module processes\n");
            goto error;
        }

        if(startup_rlist.a) {/* if a startup route was defined */
            startup_done = (int*)shm_malloc(sizeof(int));
            if(startup_done == NULL) {
                LM_ERR("No more shared memory\n");
                goto error;
            }
            *startup_done = 0;
        }

        if (fix_socket_list(&bin) != 0) {
            LM_ERR("failed to initialize binary interface socket list!\n");
            goto error;
        }

        /* OpenSIPS <--> OpenSIPS communication interface */
        if (bin && start_bin_receivers() != 0) {
            LM_CRIT("cannot start binary interface receiver processes!\n");
            goto error;
        }

        /* fork for the timer process*/
        if (start_timer_processes()!=0) {
            LM_CRIT("cannot start timer process(es)\n");
            goto error;
        }

        /* fork all processes required by UDP network layer */
        if (udp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }

        /* fork all processes required by TCP network layer */
        if (tcp_start_processes( &chd_rank, startup_done)<0) {
            LM_CRIT("cannot start TCP processes\n");
            goto error;
        }
    }

    /* this is the main process -> it shouldn't send anything */
    bind_address=0;

    if (startup_done) {
        if (*startup_done==0)
            LM_CRIT("BUG: startup route defined, but not run :( \n");
        shm_free(startup_done);
    }

    /* main process left */
    is_main=1;
    set_proc_attrs("attendant");

    if (init_child(PROC_MAIN) < 0) {
        LM_ERR("error in init_child for PROC_MAIN\n");
        report_failure_status();
        goto error;
    }

    report_conditional_status( (!no_daemon_mode), 0);

    for(;;) {
        handle_sigs();
        pause();
    }

    /*return 0; */
error:
    is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
    report_conditional_status( (!dont_fork), -1);
    return -1;

}
示例#5
0
/*! \brief starts the tcp processes */
int tcp_init_children(int *chd_rank)
{
	int r;
	//int sockfd[2];
	int reader_fd[2]; /* for comm. with the tcp children read  */
	pid_t pid;
	struct socket_info *si;
	atomic_t *load_p;
	
	/* estimate max fd. no:
	 * 1 tcp send unix socket/all_proc, 
	 *  + 1 udp sock/udp proc + 1 tcp_child sock/tcp child*
	 *  + no_listen_tcp */
	for(r=0, si=tcp_listen; si; si=si->next, r++);
#ifdef USE_TLS
	if (! tls_disable)
		for (si=tls_listen; si; si=si->next, r++);
#endif
	
	tcp_max_fd_no=counted_processes*2 +r-1 /* timer */ +3; /* stdin/out/err*/
	tcp_max_fd_no+=tcp_max_connections;
	
	/* create the tcp sock_info structures */
	/* copy the sockets --moved to main_loop*/
	
	load_p = shm_malloc(sizeof(atomic_t));
	if (!load_p)
		goto error;
	memset(load_p,0,sizeof(atomic_t));
	register_tcp_load_stat(load_p);

	/* fork children & create the socket pairs*/
	for(r=0; r<tcp_children_no; r++){
		/*if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}*/
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}
		
		(*chd_rank)++;
		pid=internal_fork("SIP receiver TCP");
		if (pid<0){
			LM_ERR("fork failed\n");
			goto error;
		}else if (pid>0){
			/* parent */
			close(reader_fd[1]);
			tcp_children[r].pid=pid;
			tcp_children[r].proc_no=process_no;
			tcp_children[r].busy=0;
			tcp_children[r].n_reqs=0;
			tcp_children[r].unix_sock=reader_fd[0];
		}else{
			/* child */
			set_proc_attrs("TCP receiver");
			pt[process_no].idx=r;
			pt[process_no].load = load_p;
			bind_address=0; /* force a SEGFAULT if someone uses a non-init.
							   bind address on tcp */
			if (init_child(*chd_rank) < 0) {
				LM_ERR("init_children failed\n");
				exit(-1);
			}
	
			tcp_receive_loop(reader_fd[1]);
			exit(-1);
		}
	}
	return 0;
error:
	return -1;
}
示例#6
0
文件: net_tcp.c 项目: Danfx/opensips
int tcp_start_processes(int *chd_rank, int *startup_done)
{
	int r, n;
	int reader_fd[2]; /* for comm. with the tcp children read  */
	pid_t pid;
	struct socket_info *si;
	stat_var *load_p = NULL;

	if (tcp_disabled)
		return 0;

	/* estimate max fd. no:
	 * 1 tcp send unix socket/all_proc,
	 *  + 1 udp sock/udp proc + 1 tcp_child sock/tcp child*
	 *  + no_listen_tcp */
	for( r=0,n=PROTO_FIRST ; n<PROTO_LAST ; n++ )
		if ( is_tcp_based_proto(n) )
			for(si=protos[n].listeners; si ; si=si->next,r++ );

	if (register_tcp_load_stat( &load_p )!=0) {
		LM_ERR("failed to init tcp load statistic\n");
		goto error;
	}

	/* start the TCP workers & create the socket pairs */
	for(r=0; r<tcp_children_no; r++){
		/* create sock to communicate from TCP main to worker */
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
			LM_ERR("socketpair failed: %s\n", strerror(errno));
			goto error;
		}

		(*chd_rank)++;
		pid=internal_fork("SIP receiver TCP");
		if (pid<0){
			LM_ERR("fork failed\n");
			goto error;
		}else if (pid>0){
			/* parent */
			close(reader_fd[1]);
			tcp_children[r].pid=pid;
			tcp_children[r].proc_no=process_no;
			tcp_children[r].busy=0;
			tcp_children[r].n_reqs=0;
			tcp_children[r].unix_sock=reader_fd[0];
		}else{
			/* child */
			set_proc_attrs("TCP receiver");
			pt[process_no].idx=r;
			pt[process_no].load = load_p;
			if (init_child(*chd_rank) < 0) {
				LM_ERR("init_children failed\n");
				report_failure_status();
				if (startup_done)
					*startup_done = -1;
				exit(-1);
			}

			/* was startup route executed so far ? */
			if (startup_done!=NULL && *startup_done==0 && r==0) {
				LM_DBG("runing startup for first TCP\n");
				if(run_startup_route()< 0) {
					LM_ERR("Startup route processing failed\n");
					report_failure_status();
					*startup_done = -1;
					exit(-1);
				}
				*startup_done = 1;
			}

			report_conditional_status( 1, 0);

			tcp_worker_proc( reader_fd[1] );
			exit(-1);
		}
	}

	/* wait for the startup route to be executed */
	if (startup_done)
		while (!(*startup_done)) {
			usleep(5);
			handle_sigs();
		}

	/* start the TCP manager process */
	if ( (pid=internal_fork( "TCP main"))<0 ) {
		LM_CRIT("cannot fork tcp main process\n");
		goto error;
	}else if (pid==0){
			/* child */
		/* close the TCP inter-process sockets */
		close(unix_tcp_sock);
		unix_tcp_sock = -1;
		close(pt[process_no].unix_sock);
		pt[process_no].unix_sock = -1;

		report_conditional_status( (!no_daemon_mode), 0);

		tcp_main_server();
		exit(-1);
	}

	return 0;
error:
	return -1;
}
示例#7
0
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int  i,rc;
	pid_t pid;
	struct socket_info* si;
	int* startup_done = NULL;
	stat_var *load_p = NULL;

	chd_rank=0;

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

	if (dont_fork){

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

		if (udp_listen==0){
			LM_ERR("no fork mode requires at least one"
					" udp listen address, exiting...\n");
			goto error;
		}
		/* only one address, we ignore all the others */
		if (udp_init(udp_listen)==-1) goto error;
		bind_address=udp_listen;
		sendipv4=bind_address;
		sendipv6=bind_address; /*FIXME*/
		if (udp_listen->next){
			LM_WARN("using only the first listen address (no fork)\n");
		}

		/* try to drop privileges */
		if (do_suid(uid, gid)==-1)
			goto error;

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		/* we need another process to act as the timer*/
		if (start_timer_processes()!=0) {
			LM_CRIT("cannot start timer process(es)\n");
			goto error;
		}

		/* main process, receive loop */
		set_proc_attrs("stand-alone SIP receiver %.*s",
			 bind_address->sock_str.len, bind_address->sock_str.s );

		/* We will call child_init even if we
		 * do not fork - and it will be called with rank 1 because
		 * in fact we behave like a child, not like main process */
		if (init_child(1) < 0) {
			LM_ERR("init_child failed in don't fork\n");
			goto error;
		}

		if (startup_rlist.a)
			run_startup_route();

		is_main=1;

		if (register_udp_load_stat(&udp_listen->sock_str,
		&pt[process_no].load, 1)!=0) {
			LM_ERR("failed to init udp load statistics\n");
			goto error;
		}

		clean_write_pipeend();
		LM_DBG("waiting for status code from children\n");
		rc = wait_for_all_children();
		if (rc < 0) {
			LM_ERR("failed to succesfully init children\n");
			return rc;
		}

		return udp_rcv_loop();
	} else {  /* don't fork */

		for(si=udp_listen;si;si=si->next){
			/* create the listening socket (for each address)*/
			/* udp */
			if (udp_init(si)==-1) goto error;
			/* get first ipv4/ipv6 socket*/
			if ((si->address.af==AF_INET)&&
					((sendipv4==0)||(sendipv4->flags&SI_IS_LO)))
				sendipv4=si;
			#ifdef USE_IPV6
			if((sendipv6==0)&&(si->address.af==AF_INET6))
				sendipv6=si;
			#endif
		}
		#ifdef USE_TCP
		if (!tcp_disable){
			for(si=tcp_listen; si; si=si->next){
				/* same thing for tcp */
				if (tcp_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&
						((sendipv4_tcp==0)||(sendipv4_tcp->flags&SI_IS_LO)))
					sendipv4_tcp=si;
				#ifdef USE_IPV6
				if((sendipv6_tcp==0)&&(si->address.af==AF_INET6))
					sendipv6_tcp=si;
				#endif
			}
		}
		#ifdef USE_TLS
		if (!tls_disable){
			for(si=tls_listen; si; si=si->next){
				/* same as for tcp*/
				if (tls_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_tls==0)||(sendipv4_tls->flags&SI_IS_LO)))
					sendipv4_tls=si;
				#ifdef USE_IPV6
				if((sendipv6_tls==0)&&(si->address.af==AF_INET6))
					sendipv6_tls=si;
				#endif
			}
		}
		#endif /* USE_TLS */
		#endif /* USE_TCP */
		#ifdef USE_SCTP
		if (!sctp_disable){
			for(si=sctp_listen; si; si=si->next){
				/* same thing for sctp */
				if (sctp_server_init(si)==-1)  goto error;
				/* get first ipv4/ipv6 socket*/
				if ((si->address.af==AF_INET)&&
						((sendipv4_sctp==0)||(sendipv4_sctp->flags&SI_IS_LO)))
					sendipv4_sctp=si;
			#ifdef USE_IPV6
				if((sendipv6_sctp==0)&&(si->address.af==AF_INET6))
					sendipv6_sctp=si;
			#endif
			}
		}
		#endif /* USE_SCTP */

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

		if (start_module_procs()!=0) {
			LM_ERR("failed to fork module processes\n");
			goto error;
		}

		if(startup_rlist.a) {/* if a startup route was defined */
			startup_done = (int*)shm_malloc(sizeof(int));
			if(startup_done == NULL) {
				LM_ERR("No more shared memory\n");
				goto error;
			}
			*startup_done = 0;
		}

		if (fix_socket_list(&bin) != 0) {
			LM_ERR("failed to initialize binary interface socket list!\n");
			goto error;
		}

		/* OpenSIPS <--> OpenSIPS communication interface */
		if (bin && start_bin_receivers() != 0) {
			LM_CRIT("cannot start binary interface receiver processes!\n");
			goto error;
		}

		/* udp processes */
		for(si=udp_listen; si; si=si->next){

			if(register_udp_load_stat(&si->sock_str,&load_p,si->children)!=0){
				LM_ERR("failed to init load statistics\n");
				goto error;
			}

			for(i=0;i<si->children;i++){
				chd_rank++;
				if ( (pid=internal_fork( "UDP receiver"))<0 ) {
					LM_CRIT("cannot fork UDP process\n");
					goto error;
				} else {
					if (pid==0) {
						/* new UDP process */
						/* set a more detailed description */
						set_proc_attrs("SIP receiver %.*s ",
							si->sock_str.len, si->sock_str.s);
						bind_address=si; /* shortcut */
						if (init_child(chd_rank) < 0) {
							LM_ERR("init_child failed for UDP listener\n");
							if (send_status_code(-1) < 0)
								LM_ERR("failed to send status code\n");
							clean_write_pipeend();
							if (chd_rank == 1 && startup_done)
								*startup_done = -1;
							exit(-1);
						}

						/* first UDP proc runs statup_route (if defined) */
						if(chd_rank == 1 && startup_done!=NULL) {
							LM_DBG("runing startup for first UDP\n");
							if(run_startup_route()< 0) {
								if (send_status_code(-1) < 0)
									LM_ERR("failed to send status code\n");
								clean_write_pipeend();
								*startup_done = -1;
								LM_ERR("Startup route processing failed\n");
								exit(-1);
							}
							*startup_done = 1;
						}

						if (!no_daemon_mode && send_status_code(0) < 0)
							LM_ERR("failed to send status code\n");
						clean_write_pipeend();


						/* all UDP listeners on same interface
						 * have same SHM load pointer */
						pt[process_no].load = load_p;
						udp_rcv_loop();
						exit(-1);
					}
					else {
						/* wait for first proc to finish the startup route */
						if(chd_rank == 1 && startup_done!=NULL)
							while( !(*startup_done) ) {usleep(5);handle_sigs();}
					}
				}
			}
			/*parent*/
			/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/
		}
	}

	#ifdef USE_SCTP
	if(!sctp_disable){
		for(si=sctp_listen; si; si=si->next){
			for(i=0;i<si->children;i++){
				chd_rank++;
				if ( (pid=internal_fork( "SCTP receiver"))<0 ) {
					LM_CRIT("cannot fork SCTP process\n");
					goto error;
				} else if (pid==0){
					/* new SCTP process */
					/* set a more detailed description */
					set_proc_attrs("SIP receiver %.*s ",
						si->sock_str.len, si->sock_str.s);
					bind_address=si; /* shortcut */
					if (init_child(chd_rank) < 0) {
						LM_ERR("init_child failed\n");
						if (send_status_code(-1) < 0)
							LM_ERR("failed to send status code\n");
						clean_write_pipeend();
						if( (si==sctp_listen && i==0) && startup_done)
							*startup_done = -1;
						exit(-1);
					}

					/* was startup route executed so far ? if not, run it only by the
					 * first SCTP proc (first proc from first interface) */
					if( (si==sctp_listen && i==0) && startup_done!=NULL && *startup_done==0) {
						LM_DBG("runing startup for first SCTP\n");
						if(run_startup_route()< 0) {
							LM_ERR("Startup route processing failed\n");
							if (send_status_code(-1) < 0)
								LM_ERR("failed to send status code\n");
							clean_write_pipeend();
							*startup_done = -1;
							exit(-1);
						}
						*startup_done = 1;
					}

					if (!no_daemon_mode && send_status_code(0) < 0)
						LM_ERR("failed to send status code\n");
					clean_write_pipeend();

					sctp_server_rcv_loop();
					exit(-1);
				} else {
					/* wait for first proc to finish the startup route */
					if( (si==sctp_listen && i==0) && startup_done!=NULL)
						while( !(*startup_done) ) {usleep(5);handle_sigs();}
				}
			}
		}
	}
	#endif /* USE_SCTP */

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	#ifdef USE_TCP
	if (!tcp_disable){
		/* start tcp  & tls receivers */
		if (tcp_init_children(&chd_rank, startup_done)<0) goto error;
		/* wait for the startup route to be executed */
		if( startup_done!=NULL)
			while( !(*startup_done) ) {usleep(5);handle_sigs();}
		/* start tcp+tls master proc */
		if ( (pid=internal_fork( "TCP main"))<0 ) {
			LM_CRIT("cannot fork tcp main process\n");
			goto error;
		}else if (pid==0){
			/* child */
			/* close the TCP inter-process sockets */
			close(unix_tcp_sock);
			unix_tcp_sock = -1;
			close(pt[process_no].unix_sock);
			pt[process_no].unix_sock = -1;
			/* init modules */
			if (init_child(PROC_TCP_MAIN) < 0) {
				LM_ERR("error in init_child for tcp main\n");
				if (send_status_code(-1) < 0)
					LM_ERR("failed to send status code\n");
				clean_write_pipeend();

				exit(-1);
			}

			if (!no_daemon_mode && send_status_code(0) < 0)
				LM_ERR("failed to send status code\n");
			clean_write_pipeend();

			tcp_main_loop();
			exit(-1);
		}
	}
	#endif

	if (startup_done) {
		if (*startup_done==0)
			LM_CRIT("BUG: startup route defined, but not run :( \n");
		shm_free(startup_done);
	}

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		if (send_status_code(-1) < 0)
			LM_ERR("failed to send status code\n");
		clean_write_pipeend();
		LM_ERR("error in init_child for PROC_MAIN\n");
		goto error;
	}

	if (!no_daemon_mode && send_status_code(0) < 0)
		LM_ERR("failed to send status code\n");
	clean_write_pipeend();

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	if (!dont_fork && send_status_code(-1) < 0)
		LM_ERR("failed to send status code\n");
	clean_write_pipeend();

	return -1;

}
示例#8
0
文件: timer.c 项目: KISSMonX/opensips
static void run_timer_process(struct sr_timer_process *tpl)
{
	unsigned int multiple;
	unsigned int cnt;
	struct timeval o_tv;
	struct timeval tv;
	utime_t  drift;
	utime_t  uinterval;
	utime_t  wait;

/* timer re-calibration to compensate drifting */
#define compute_wait_with_drift(_tv,_type) \
	do {                                                         \
		if ( drift > ITIMER_TICK ) {                             \
			wait = (drift >= uinterval) ? 0 : uinterval-drift;   \
			_tv.tv_sec = wait / 1000000;                         \
			_tv.tv_usec = wait % 1000000;                        \
			drift -= uinterval-wait;                             \
		} else {                                                 \
			_tv = o_tv;                                          \
		}                                                        \
	}while(0)


	if ( (tpl->utimer_list==NULL) || ((TIMER_TICK*1000000) == UTIMER_TICK) ) {
		o_tv.tv_sec = TIMER_TICK;
		o_tv.tv_usec = 0;
		multiple = 1;
	} else {
		o_tv.tv_sec = UTIMER_TICK / 1000000;
		o_tv.tv_usec = UTIMER_TICK % 1000000;
		multiple = (( TIMER_TICK * 1000000 ) / UTIMER_TICK ) / 1000000;
	}

	if (tpl->utimer_list && tpl->utimer_list->label) {
		set_proc_attrs("timer: %s", tpl->utimer_list->label);
	} else if (tpl->timer_list && tpl->timer_list->label) {
		set_proc_attrs("timer: %s", tpl->timer_list->label);
	}

	LM_DBG("tv = %ld, %ld , m=%d\n",
		(long)o_tv.tv_sec,(long)o_tv.tv_usec,multiple);

	drift = 0;
	uinterval = o_tv.tv_sec * 1000000 + o_tv.tv_usec;

	if (tpl->utimer_list==NULL) {
		/* only TIMERs, ticking at TIMER_TICK */
		for( ; ; ) {
			compute_wait_with_drift( tv, 0);
			select( 0, 0, 0, 0, &tv);
			timer_ticker( tpl->timer_list, &drift);
		}

	} else
	if (tpl->timer_list==NULL) {
		/* only UTIMERs, ticking at UTIMER_TICK */
		for( ; ; ) {
			compute_wait_with_drift( tv, 1);
			select( 0, 0, 0, 0, &tv);
			utimer_ticker( tpl->utimer_list, &drift);
		}

	} else
	if (multiple==1) {
		/* TIMERs and UTIMERs, ticking together TIMER_TICK (synced) */
		for( ; ; ) {
			compute_wait_with_drift( tv, 2);
			select( 0, 0, 0, 0, &tv);
			timer_ticker( tpl->timer_list, &drift);
			utimer_ticker( tpl->utimer_list, &drift);
		}

	} else {
		/* TIMERs and UTIMERs, TIMER_TICK is multiple of UTIMER_TICK */
		for( cnt=1 ; ; cnt++ ) {
			compute_wait_with_drift( tv, 3);
			select( 0, 0, 0, 0, &tv);
			utimer_ticker(tpl->utimer_list, &drift);
			if (cnt==multiple) {
				timer_ticker(tpl->timer_list, &drift);
				cnt = 0;
			}
		}
	}
}
示例#9
0
文件: main.c 项目: Parantido/opensips
/**
 * Main loop, forks the children, bind to addresses,
 * handle signals.
 * \return don't return on sucess, -1 on error
 */
static int main_loop(void)
{
	static int chd_rank;
	int* startup_done = NULL;

	chd_rank=0;

	if (start_module_procs()!=0) {
		LM_ERR("failed to fork module processes\n");
		goto error;
	}

	if(startup_rlist.a) {/* if a startup route was defined */
		startup_done = (int*)shm_malloc(sizeof(int));
		if(startup_done == NULL) {
			LM_ERR("No more shared memory\n");
			goto error;
		}
		*startup_done = 0;
	}

	/* fork for the timer process*/
	if (start_timer_processes()!=0) {
		LM_CRIT("cannot start timer process(es)\n");
		goto error;
	}

	/* fork all processes required by UDP network layer */
	if (udp_start_processes( &chd_rank, startup_done)<0) {
		LM_CRIT("cannot start TCP processes\n");
		goto error;
	}

	/* fork all processes required by TCP network layer */
	if (tcp_start_processes( &chd_rank, startup_done)<0) {
		LM_CRIT("cannot start TCP processes\n");
		goto error;
	}

	/* this is the main process -> it shouldn't send anything */
	bind_address=0;

	if (startup_done) {
		if (*startup_done==0)
			LM_CRIT("BUG: startup route defined, but not run :( \n");
		shm_free(startup_done);
	}

	/* main process left */
	is_main=1;
	set_proc_attrs("attendant");

	if (init_child(PROC_MAIN) < 0) {
		LM_ERR("error in init_child for PROC_MAIN\n");
		report_failure_status();
		goto error;
	}

	report_conditional_status( (!no_daemon_mode), 0);

	for(;;){
			handle_sigs();
			pause();
	}

	/*return 0; */
error:
	is_main=1;  /* if we are here, we are the "main process",
				  any forked children should exit with exit(-1) and not
				  ever use return */
	report_failure_status();
	return -1;

}