Exemplo n.º 1
0
int start_server(int fd){
     int child_indx,pid,i,status;
     int childs,freeservers,used,maxrequests;

     ci_proc_mutex_init(&accept_mutex);
     if(!create_childs_queue(&childs_queue,MAX_CHILDS)){
	  debug_printf(1,"Can't init shared memory.Fatal error, exiting!\n");
	  exit(0);
     }

     pid=1;


#ifdef MULTICHILD 

     for(i=0;i< START_CHILDS; i++){
	  if(pid)
	       pid=start_child(fd);
     }
     if(pid!=0){
	  main_signals();

	  while(1){
	       sleep(1); /*Must be replaced by nanosleep. */
	       childs_queue_stats(&childs_queue,&childs,&freeservers, &used, &maxrequests);
	       debug_printf(10,"Server stats: \n\t Childs:%d\n\t Free servers:%d\n\tUsed servers:%d\n\tRequests served:%d\n",
			    childs, freeservers,used, maxrequests);
	       if( (freeservers<=MIN_FREE_SERVERS && childs<MAX_CHILDS) ||childs<START_CHILDS){
		    debug_printf(8,"Going to start a child .....\n");
		    pid=start_child(fd);
	       }
	       else if(freeservers>=MAX_FREE_SERVERS&& childs>START_CHILDS){
		    child_indx=find_an_idle_child(&childs_queue);
		    childs_queue.childs[child_indx].to_be_killed=GRACEFULLY;
		    kill(childs_queue.childs[child_indx].pid,SIGINT);
		    debug_printf(8,"Going to stop child %d .....\n",childs_queue.childs[child_indx].pid);
		    //kill a server ...
	       }    
	  }
	  for(i=0;i<START_CHILDS;i++){
	       pid=wait(&status);
	       debug_printf(5,"The child %d died with status %d\n",pid,status);
	  }
     }
#else
     child_data=(child_shared_data_t *)malloc(sizeof(child_shared_data_t));     
     child_data->pid=0;
     child_data->freeservers=START_SERVERS;
     child_data->usedservers=0;
     child_data->requests=0;
     child_data->connections=0;
     child_data->to_be_killed=0;
     child_data->idle=1;     
     child_main(fd);
#endif


}
Exemplo n.º 2
0
int bbs_entry(void) {
    KBS_SOCKADDR_IN sin;
    socklen_t sinlen;
    setuid(BBSUID);
    setgid(BBSGID);
    main_signals();
    sinlen=sizeof(KBS_SOCKADDR_IN);
    atexit(ssh_exit);
    proxy_getpeername(0,(struct sockaddr*)&sin,&sinlen);
    KBS_SET_FROMHOST(sin,getSession()->fromhost);
    return bbs_main(saved_argv[0]);
}
Exemplo n.º 3
0
int start_server()
{
     int child_indx, pid, i, ctl_socket;
     int childs, freeservers, used, maxrequests, ret;
     char command_buffer[COMMANDS_BUFFER_SIZE];
     int user_informed = 0;

     ctl_socket = ci_named_pipe_create(CONF.COMMANDS_SOCKET);
     if (ctl_socket < 0) {
          ci_debug_printf(1,
                          "Error opening control socket %s. Fatal error, exiting!\n",
                          CONF.COMMANDS_SOCKET);
          exit(0);
     }

     if (!ci_proc_mutex_init(&accept_mutex)) {
          ci_debug_printf(1,
                          "Can't init mutex for accepting conenctions. Fatal error, exiting!\n");
          exit(0);
     }
     childs_queue = malloc(sizeof(struct childs_queue));
     if (!create_childs_queue(childs_queue, 2 * CONF.MAX_SERVERS)) {
          ci_proc_mutex_destroy(&accept_mutex);
          ci_debug_printf(1,
                          "Can't init shared memory. Fatal error, exiting!\n");
          exit(0);
     }

     init_commands();
     pid = 1;
#ifdef MULTICHILD
     if (CONF.START_SERVERS > CONF.MAX_SERVERS)
          CONF.START_SERVERS = CONF.MAX_SERVERS;

     for (i = 0; i < CONF.START_SERVERS; i++) {
          if (pid)
               pid = start_child(LISTEN_SOCKET);
     }
     if (pid != 0) {
          main_signals();

          while (1) {
               if ((ret = wait_for_commands(ctl_socket, command_buffer, 1)) > 0) {
                    ci_debug_printf(5, "I received the command: %s\n",
                                    command_buffer);
                    handle_monitor_process_commands(command_buffer);
               }
               if (ret < 0) {  /*Eof received on pipe. Going to reopen ... */
                    ci_named_pipe_close(ctl_socket);
                    ctl_socket = ci_named_pipe_open(CONF.COMMANDS_SOCKET);
                    if (ctl_socket < 0) {
                         ci_debug_printf(1,
                                         "Error opening control socket. We are unstable and going down!");
                         c_icap_going_to_term = 1;
                    }
               }

               if (c_icap_going_to_term)
                    break;
               childs_queue_stats(childs_queue, &childs, &freeservers, &used,
                                  &maxrequests);
               ci_debug_printf(10,
                               "Server stats: \n\t Children: %d\n\t Free servers: %d\n"
                               "\tUsed servers:%d\n\tRequests served:%d\n",
                               childs, freeservers, used, maxrequests);
               if (MAX_REQUESTS_PER_CHILD > 0 && (child_indx =
                                                  find_a_child_nrequests
                                                  (childs_queue,
                                                   MAX_REQUESTS_PER_CHILD)) >=
                   0) {
                    ci_debug_printf(8,
                                    "Max requests reached for child :%d of pid :%d\n",
                                    child_indx,
                                    childs_queue->childs[child_indx].pid);
                    pid = start_child(LISTEN_SOCKET);
                    //         usleep(500);
                    childs_queue->childs[child_indx].father_said = GRACEFULLY;
                    /*kill a server ... */
                    kill(childs_queue->childs[child_indx].pid, SIGTERM);

               }
               else if ((freeservers <= CONF.MIN_SPARE_THREADS && childs < CONF.MAX_SERVERS)
                        || childs < CONF.START_SERVERS) {
                    ci_debug_printf(8,
                                    "Free Servers: %d, children: %d. Going to start a child .....\n",
                                    freeservers, childs);
                    pid = start_child(LISTEN_SOCKET);
               }
               else if (freeservers >= CONF.MAX_SPARE_THREADS &&
                        childs > CONF.START_SERVERS &&
                        (freeservers - CONF.THREADS_PER_CHILD) > CONF.MIN_SPARE_THREADS) {

                    if ((child_indx = find_an_idle_child(childs_queue)) >= 0) {
                         childs_queue->childs[child_indx].father_said =
                             GRACEFULLY;
                         ci_debug_printf(8,
                                         "Free Servers: %d, children: %d. Going to stop child %d(index: %d)\n",
                                         freeservers, childs,
                                         childs_queue->childs[child_indx].pid,
                                         child_indx);
                         /*kill a server ... */
                         kill(childs_queue->childs[child_indx].pid, SIGTERM);
			 user_informed = 0;
                    }
               }
               else if (childs == CONF.MAX_SERVERS && freeservers < CONF.MIN_SPARE_THREADS) {
		 if(! user_informed) {
		         ci_debug_printf(1,
					 "ATTENTION!!!! Not enough available servers (children %d, free servers %d, used servers %d)!!!!! "
					 "Maybe you should increase the MaxServers and the "
					 "ThreadsPerChild values in c-icap.conf file!!!!!!!!!",childs , freeservers, used);
			 user_informed = 1;
		 }
               }
               if (c_icap_going_to_term)
                    break;
               check_for_exited_childs();
               if (c_icap_reconfigure) {
                    c_icap_reconfigure = 0;
                    if (!server_reconfigure()) {
			ci_debug_printf(1, "Error while reconfiguring, exiting!\n");
			 break;
		    }
               }
          }
          /*Main process exit point */
          ci_debug_printf(1,
                          "Possibly a term signal received. Monitor process going to term all children\n");
          kill_all_childs();
	  system_shutdown();
	  ci_debug_printf(1, "Exiting....\n");
          return 1;
     }
#else
     child_data = (child_shared_data_t *) malloc(sizeof(child_shared_data_t));
     child_data->pid = 0;
     child_data->freeservers = CONF.THREADS_PER_CHILD;
     child_data->usedservers = 0;
     child_data->requests = 0;
     child_data->connections = 0;
     child_data->to_be_killed = 0;
     child_data->father_said = 0;
     child_data->idle = 1;
     child_data->stats_size = ci_stat_memblock_size();
     child_data->stats = malloc(child_data->stats_size);
     child_data->stats->sig = MEMBLOCK_SIG;
     ci_stat_attach_mem(child_data->stats, child_data->stats_size, NULL);
     child_main(LISTEN_SOCKET, 0);
     ci_proc_mutex_destroy(&accept_mutex);
     destroy_childs_queue(childs_queue);
#endif
     return 1;
}
Exemplo n.º 4
0
static int bbs_standalone_main(char* argv) {
    KBS_SOCKADDR_IN sin;
    socklen_t sinlen;
    char addr_buf[IPLEN];
    int sockfd,count;
    time_t lasttime,now;
    lasttime=time(NULL);
    count=0;
    while (1) {
        sinlen=sizeof(KBS_SOCKADDR_IN);
#ifdef SMTH
        if ((now=time(NULL))!=lasttime)
            count=0;
        else {
            if (count>5)
                sleep(1);
        }
#endif /* SMTH */
        sockfd=accept(SOCKFD,(struct sockaddr*)&sin,&sinlen);
        count++;
        if (sockfd==-1)
            continue;
        proxy_getpeername(sockfd,(struct sockaddr*)&sin,&sinlen);
#ifdef CHECK_IP_LINK
#ifdef HAVE_IPV6_SMTH
        if (check_IP_lists(sin.sin6_addr)==1) {
#else /* ! HAVE_IPV6_SMTH */
        if (check_IP_lists(sin.sin_addr.s_addr)==1) {
#endif /* HAVE_IPV6_SMTH */
            close(sockfd);
            continue;
        }
#endif /* CHECK_IP_LINK */
        if (!no_fork) {
            switch (fork()) {
                case -1:
                    exit(3);
                case 0:
                    break;
                default:
                    close(sockfd);
                    continue;
            }
        }
        KBS_SET_FROMHOST(sin,addr_buf);
        bbslog("0Connect","connect from %d (%d) in port %d",addr_buf,htons(KBS_SIN_MEMBER(sin,port)),mport);
        setsid();
        if (dup2(sockfd,0)==-1)     /* dup tcp link to fd 0 and then in the main_bbs func also to fd 1 */
            exit(2);
        close(3);                   /* close listen sock fd in child session */
        close(4);                   /* close pid file fd in child session */
        close(sockfd);              /* close accept peer fd in child session */
        break;                      /* leave fd 2 still open holding /dev/null */
    }
    KBS_SET_FROMHOST(sin,getSession()->fromhost);
    telnet_init();
    return bbs_main(argv);
}
int main(int argc,char **argv) {
    char addr[STRLEN];
    int ret,inetd,port;
    addr[0]=0;inetd=0;port=23;
    while ((ret=getopt(argc,argv,"idha:p:"))!=-1) {
        switch (ret) {
            case 'i':
                inetd=1;
                break;
            case 'd':
                no_fork=1;
                break;
            case 'h':
                puts("usage: bbsd [-i] [-d] [-h] [-a <addr>] [-p <port>]");
                return 0;
            case 'a':
                if (optarg[0])
                    snprintf(addr,STRLEN,"%s",optarg);
                break;
            case 'p':
                if (!isdigit(optarg[0]))
                    return -1;
                port=atoi(optarg);
                break;
            case '?':
                return -1;
        }
    }
#ifndef HAVE_IPV6_SMTH
    inaddr_any.s_addr=htonl(INADDR_ANY);
#endif /* HAVE_IPV6_SMTH */
    start_daemon(inetd,port,(!addr[0]?NULL:addr));
    main_signals();
    return (!inetd?bbs_standalone_main(argv[0]):bbs_inet_main(argv[0]));
}