Esempio n. 1
0
void reload_cmd(sock_t fd, char *options, unsigned int nb_options)
{
	char *msg;
	
	if (get_active_threads_size() > 0) {
		msg = "Threads still active, cannot reload";
		proxenet_write(fd, (void*)msg, strlen(msg));
		return;
	}

	proxy_state = SLEEPING;
	
	proxenet_destroy_plugins_vm();
	proxenet_delete_list_plugins();

	if( proxenet_initialize_plugins_list() < 0) {
		msg = "Failed to reinitilize plugins";
		proxenet_write(fd, (void*)msg, strlen(msg));
		proxy_state = INACTIVE;
		return;
	}

	proxenet_initialize_plugins();

	proxy_state = ACTIVE;

	msg = "Plugins list successfully reloaded\n";
	proxenet_write(fd, (void*)msg, strlen(msg));

	return;
}
Esempio n. 2
0
void xloop(sock_t sock, sock_t ctl_sock)
{
	fd_set sock_set;
	int retcode;
	pthread_attr_t pattr;
	int tid;
	sock_t conn;
	sigset_t curmask, oldmask;
	sock_t ctl_cli_sock = -1;

	/* prepare threads  */
	proxenet_xzero(threads, sizeof(pthread_t) * MAX_THREADS);
	
	if (pthread_attr_init(&pattr)) {
		xlog(LOG_ERROR, "%s\n", "Failed to pthread_attr_init");
		return;
	}
	
	pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE);

	/* block useful signal */
	sigemptyset(&curmask);
	sigaddset(&curmask, SIGTERM);
	sigaddset(&curmask, SIGINT);
	sigaddset(&curmask, SIGCHLD);
	if (pthread_sigmask(SIG_BLOCK, &curmask, &oldmask) < 0) {
		xlog(LOG_ERROR, "sigprocmask failed : %s\n", strerror(errno));
		return;
	}

	/* proxenet is now running :) */
	proxy_state = ACTIVE;
	
	/* big loop  */
	while (proxy_state != INACTIVE) {
		conn = -1;
		retcode = -1;	
		
		FD_ZERO(&sock_set);

		FD_SET(sock, &sock_set);
		FD_SET(ctl_sock, &sock_set);
		if (ctl_cli_sock > 0)
			FD_SET(ctl_cli_sock, &sock_set);

		purge_zombies();
		
		/* set asynchronous listener */
		struct timespec timeout = {
			.tv_sec = 5,
			.tv_nsec = 0
		};
		
		retcode = pselect(FD_SETSIZE, &sock_set, NULL, NULL, &timeout, &oldmask);
		
		if (retcode < 0) {
			if (errno != EINTR) {
				xlog(LOG_ERROR, "[main] pselect() returned %d: %s\n", retcode, strerror(errno));
				proxy_state = INACTIVE;
				break;
			} else {
				continue;
			}
		}
		
		if (retcode == 0)
			continue;

		if (proxy_state == INACTIVE)
			break;
		
		/* event on the listening socket -> new request */
		if( FD_ISSET(sock, &sock_set) && proxy_state != SLEEPING) {
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "Incoming listening event");
#endif

			tid = get_new_thread_id();
			if(tid < 0) {
				continue;
			}
			
			struct sockaddr addr;
			socklen_t addrlen = 0;

			proxenet_xzero(&addr, sizeof(struct sockaddr));

			conn = accept(sock, &addr, &addrlen); 
			if (conn < 0) {
				if(errno != EINTR)
					xlog(LOG_ERROR, "[main] accept() failed: %s\n", strerror(errno));
				continue;
			}
			
			retcode = proxenet_start_new_thread(conn, tid, &threads[tid], &pattr);
			if (retcode < 0) {
				xlog(LOG_ERROR, "[main] %s\n", "Error while spawn new thread");
				continue;
			}
			
		} /* end if _socket_event */
		
		
		/* event on control listening socket */
		if( FD_ISSET(ctl_sock, &sock_set) ) {
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "Incoming control event");
#endif
			struct sockaddr_un sun_cli;
			socklen_t sun_cli_len = 0;
			int new_conn = -1;
			
			proxenet_xzero(&sun_cli, sizeof(struct sockaddr_un));

			new_conn = accept(ctl_sock, (struct sockaddr *)&sun_cli, &sun_cli_len);
			if (new_conn < 0) {
				xlog(LOG_ERROR, "[main] control accept() failed: %s\n", strerror(errno));
				continue;
			}
			
			if (ctl_cli_sock < 0) {
				ctl_cli_sock = new_conn;
				xlog(LOG_INFO, "%s\n", "New connection on Control socket");
				proxenet_write(ctl_cli_sock, CONTROL_MOTD, strlen(CONTROL_MOTD));
				proxenet_write(ctl_cli_sock, CONTROL_PROMPT, strlen(CONTROL_PROMPT));
				
			} else {
				if(new_conn > 0) {
					xlog(LOG_ERROR, "%s\n", "Denied control connection: already established");
					if(close_socket(new_conn) < 0) {
						xlog(LOG_ERROR, "Failed to close socket: %s\n", strerror(errno));
					}
				}
			}
			
		}/* end if _control_listening_event */

		
		/* event on control socket */
		if( ctl_cli_sock > 0 && FD_ISSET(ctl_cli_sock, &sock_set) ) {
			
			if (proxenet_handle_control_event(&ctl_cli_sock) < 0) {
				close_socket(ctl_cli_sock);
				ctl_cli_sock = -1;
			}
			
		} /* end if _control_event */
		
	}  /* endof while(!INACTIVE) */
	
	
	kill_zombies();
	proxenet_destroy_plugins_vm();
	pthread_attr_destroy(&pattr);
	
	return;
}


/**
 *
 * @param signum
 */
void sighandler(int signum)
{
#ifdef DEBUG
	xlog(LOG_DEBUG, "Received signal %s [%d]\n", strsignal(signum), signum);
#endif
	
	switch(signum) {
		
		case SIGTERM: 
		case SIGINT:
			if (proxy_state != INACTIVE)
				proxy_state = INACTIVE;
			
			cfg->try_exit++;
			xlog(LOG_INFO, "%s, %d/%d\n", "Trying to leave", cfg->try_exit, cfg->try_exit_max);
			
			if (cfg->try_exit == cfg->try_exit_max) {
				xlog(LOG_CRITICAL, "%s\n", "Failed to exit properly");
				abort();
			}
			
			break;

		case SIGCHLD:
			purge_zombies();
			break;
	}
}
Esempio n. 3
0
/**
 * This function is called right after the configuration was parsed.
 * It simply:
 * - creates the main listening sockets (control and proxy)
 * - initialize the signal mask
 * - initialize all the VMs
 * - fill the plugin list with the valid plugins located in the autoload path
 * - then call the main thread loop
 * - once finished, it also cleans the structures
 *
 * @return 0 if everything went well, -1 otherwise with an error message
 */
int proxenet_start()
{
        sock_t control_socket, listening_socket;
        struct sigaction saction;

        /* create control socket */
        control_socket = proxenet_bind_control_socket();
        if (control_socket < 0) {
                xlog(LOG_CRITICAL, "Cannot create control socket: %s\n", strerror(errno));
                return -1;
        }

        if(cfg->verbose)
                xlog(LOG_INFO, "Control socket: %d\n", control_socket);

        /* create listening socket */
        listening_socket = proxenet_bind_socket(cfg->iface, cfg->port);
        if (listening_socket < 0) {
                xlog(LOG_CRITICAL, "Cannot create bind socket: %s\n", strerror(errno));
                return -1;
        }

        if(cfg->verbose)
                xlog(LOG_INFO, "Bind socket: %d\n", listening_socket);


        /* init everything */
        initialize_sigmask(&saction);

        plugins_list = NULL;
        proxy_state = INACTIVE;
        active_threads_bitmask = 0;

        /* set up plugins */
        if( proxenet_initialize_plugins_list() < 0 )
                return -1;

        /* this call *MUST* succeed or die */
        proxenet_initialize_plugins();

        /* setting request counter  */
        request_id = 0;

        /* we "artificially" allocate an ID 0 so that all new requests will be > 0 */
        /* for the child threads, a request id of 0 means not allocated */
        get_new_request_id();

        init_global_stats();

        /* prepare threads and start looping */
        xloop(listening_socket, control_socket);

        end_global_stats();

        if (cfg->verbose)
                print_global_stats();

        /* clean context */
        proxenet_destroy_plugins_vm();
        proxenet_free_all_plugins();

        proxenet_close_socket(listening_socket, NULL);
        proxenet_close_socket(control_socket, NULL);

        unlink(CFG_CONTROL_SOCK_PATH);
        return 0;
}