Пример #1
1
int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    struct sigaction old_sigint, new_sigint;
    struct sigaction old_sigchld, new_sigchld;

    /* sets up the dump for when ctrl+c is hit */
    sigset_t set;
    new_sigint.sa_handler = exit_dump;
    new_sigint.sa_flags = 0;
    new_sigint.sa_mask = set;
    sigaction(SIGINT, &new_sigint, &old_sigint);

    /* sets up handling SIGCHLD */
    sigset_t set2;
    new_sigchld.sa_handler = handle_sigchld;
    new_sigchld.sa_flags = SA_RESTART;
    new_sigchld.sa_mask = set2;
    sigaction(SIGCHLD, &new_sigchld, &old_sigchld);

    if(argc < 2)
    {
        fprintf(stderr, "ERROR, no port provided\n");
        exit(1);
    }

    /* creates the socket sockfd using the internet, TCP,
     * and default protocol */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) error("ERROR opening socket");

    /* fills serv_addr with 0's */
    bzero((char *)&serv_addr, sizeof(serv_addr));

    /* converts the port number argument to an int */
    portno = atoi(argv[1]);

    /* protocol = internet */
    serv_addr.sin_family = AF_INET;
    /* accept any IP address */
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    /* ensure the information from port portno has the right endian-ness */
    serv_addr.sin_port = htons(portno);

    /* binds the port we're going to listen on to the socket */
    if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR on binding");

    printf("I am the personality test server and my pid number is %d\n", getpid());

    /* wait for connection, give it to the socket, accept up to 5 */
    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    /* infinite loop of peace, love, and acceptance */
    while(1)
    {
        /* accepts a connection to a client so we can get info */
        newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
        if(newsockfd < 0) error("ERROR on accept");

        int childpid = fork();
        if(childpid == -1) error("ERROR forking off a new child");
        if(childpid == 0)
        {
            /* deals with the connection to client */
            handle_connection(newsockfd);
            exit(0);
        } else {
            printf("A connection! My child #%d will take care of it\n", childpid);
            close(newsockfd);
        }
    }
    return 0;
}
Пример #2
0
void main( int argc,  char*  argv[] )
{
   int i, ready, sock1, sock2, length; 
   /* This receiver process will receive connection requests on these two sockets */ 
   int msgsock ; 

   fd_set fdin;
   struct timeval TO ; 

   struct sockaddr_in server, server2;  

   /* CREATE FIRST SOCKET 				   			*/
   sock1  = socket(AF_INET, SOCK_STREAM,0); 

   if ( sock1 < 0 ) { 
      perror("Problem in creating the first socket");
       exit(0); 
    } 

   server.sin_addr.s_addr = INADDR_ANY ; 
   server.sin_port = 0 ; 
   if ( bind(sock1,(struct sockaddr *)&server, sizeof(server))) {   /* Bind socket to a port */ 
      perror ( "Binding stream socket");
      exit(0);
   }

   length = sizeof(server); 
   if ( getsockname(sock1,(struct sockaddr *)&server, &length)) {  /* get the port number assigned to this socket */ 
        perror("Getting socket's port number");
        exit(0);
   }

   fprintf(stderr, "Socket 1 is connected to port%5d\n\n", ntohs(server.sin_port)); 

   /* CREATE SECOND SOCKET 				 			*/
   sock2 = socket(AF_INET, SOCK_STREAM, 0);
 
   if ( sock2 < 0 ) {
      perror("problem in creating the second  socket");
      exit(0);
   } 

   server2.sin_addr.s_addr = INADDR_ANY; 
   server2.sin_port = 0 ; 
   if ( bind(sock2, (struct sockaddr * )&server2,sizeof(server2))){ /* bind second socket to a port */
        perror("Binding stream socket");
        exit(0);
   }

   length = sizeof(server2);
   if ( getsockname(sock2,(struct sockaddr *)&server2,&length)){  /* get the port number for socket2 */
      perror("getting socket's port number");
      exit(0);
    }

    fprintf(stderr,"Socket 2  is connected to port %5d\n", ntohs(server2.sin_port));

    /* Initialize socket fo receiving messages.						*/
    /*  ready to accept connection to sock1, up to 3 requests can be kept buffered */
    listen(sock1,3);     
    listen(sock2,3);     

    /* Continuously wait for receiving messages on either of the two sockets.		*/
    while (1) { 
        FD_ZERO( &fdin );
        FD_SET( sock1, &fdin);
        FD_SET( sock2, &fdin);
        TO.tv_sec = 10 ; 
        TO.tv_usec = 0 ; 
  
        select(32, (fd_set *)&fdin, 0, 0, &TO);  /* Block to receive call on either sock1 or sock2 */
                       /* timeout and continue after 10 seconds if no connection requests */

        if (FD_ISSET(sock1, &fdin )) {   /* check if connection requests for sock1  */ 
             printf("\nMessage on the first socket\n");

             /* accept connection on sock1. This will return a new socket indentifier, stored 
             in msgsock for the connection. All I/O for that connection is through msgsock.  */
              handle_connection(sock1);
              FD_CLR(sock1, &fdin);
         }
         else if (FD_ISSET(sock2, &fdin)) {    /* check if connection requests for sock2  */
              printf("\nMessage on the second socket\n");
              /* accept connection on sock2. This will return a new socket indentifier, stored 
              in msgsock for the connection. All I/O for that connection is through msgsock.  */

              handle_connection(sock2);
              FD_CLR(sock2,  &fdin);
             } 
            else  /* Select call completed due to timeout and there is no connection on any socket */
                  printf("\nTimeout occured\n"); 
      };

}  
Пример #3
0
static void accept_connection(int sock, void *unused) {
	int new_sd;
	pid_t pid;
	struct sockaddr addr;
	struct sockaddr_in *nptr;
	socklen_t addrlen;
	int rc;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	/* DO NOT REMOVE! 01/29/2007 single process daemon will fail if this is removed */
	if (mode == SINGLE_PROCESS_DAEMON)
		register_read_handler(sock, accept_connection, NULL);

	/* wait for a connection request */
	while (1) {

		/* we got a live one... */
		if ((new_sd = accept(sock, 0, 0)) >= 0)
			break;

		/* handle the error */
		else {

			/* bail out if necessary */
			if (sigrestart == TRUE || sigshutdown == TRUE)
				return;

			/* try and handle temporary errors */
			if (errno == EWOULDBLOCK || errno == EINTR || errno == ECHILD) {
				if (mode == MULTI_PROCESS_DAEMON)
					sleep(1);
				else
					return;
			} else
				break;
		}
	}

	/* hey, there was an error... */
	if (new_sd < 0) {

		/* log error to syslog facility */
		syslog(LOG_ERR, "Network server accept failure (%d: %s)", errno, strerror(errno));

		/* close socket prior to exiting */
		close(sock);
		if (mode == MULTI_PROCESS_DAEMON)
			do_exit(STATE_CRITICAL);
		return;
	}

#ifdef HAVE_LIBWRAP

	/* Check whether or not connections are allowed from this host */
	request_init(&req, RQ_DAEMON, "nsca", RQ_FILE, new_sd, 0);
	fromhost(&req);

	if (!hosts_access(&req)) {
		/* refuse the connection */
		syslog(LOG_ERR, "refused connect from %s", eval_client(&req));
		close(new_sd);
		return;
	}
#endif


	/* fork() if we have to... */
	if (mode == MULTI_PROCESS_DAEMON) {

		pid = fork();
		if (pid) {
			/* parent doesn't need the new connection */
			close(new_sd);
			return;
		} else {
			/* child does not need to listen for connections */
			close(sock);
		}
	}

	/* find out who just connected... */
	addrlen = sizeof(addr);
	rc = getpeername(new_sd, &addr, &addrlen);

	if (rc < 0) {
		/* log error to syslog facility */
		syslog(LOG_ERR, "Error: Network server getpeername() failure (%d: %s)", errno, strerror(errno));

		/* close socket prior to exiting */
		close(new_sd);
		if (mode == MULTI_PROCESS_DAEMON)
			do_exit(STATE_CRITICAL);
		return;
	}

	nptr = (struct sockaddr_in *)&addr;

	/* log info to syslog facility */
	if (debug == TRUE)
		syslog(LOG_DEBUG, "Connection from %s port %d", inet_ntoa(nptr->sin_addr), nptr->sin_port);

	/* handle the connection */
	if (mode == SINGLE_PROCESS_DAEMON)
		/* mark the connection as ready to be handled */
		register_write_handler(new_sd, handle_connection, NULL);
	else
		/* handle the client connection */
		handle_connection(new_sd, NULL);

	return;
}
Пример #4
0
int main(int argc, char **argv) {
	char buffer[MAX_INPUT_BUFFER];
	int result;
	uid_t uid = -1;
	gid_t gid = -1;


	/* process command-line arguments */
	result = process_arguments(argc, argv);

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE) {

		if (result != OK)
			printf("Incorrect command line arguments supplied\n");
		printf("\n");
		printf("NSCA - Nagios Service Check Acceptor for Icinga\n");
		printf("Copyright (c) 2010-2012 Icinga Development Team and Community Contributors (http://www.icinga.org)\n");
		printf("Copyright (c) 2009-2012 Nagios Core Development Team and Community Contributors\n");
		printf("Copyright (c) 2000-2009 Ethan Galstad\n");
		printf("Version: %s\n", PROGRAM_VERSION);
		printf("Last Modified: %s\n", MODIFICATION_DATE);
		printf("License: GPL v2\n");
		printf("Encryption Routines: ");
#ifdef HAVE_LIBMCRYPT
		printf("AVAILABLE");
#else
		printf("NOT AVAILABLE");
#endif
		printf("\n");
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
	}

	if (result != OK || show_help == TRUE) {
		printf("Usage: %s -c <config_file> [mode]\n", argv[0]);
		printf("\n");
		printf("Options:\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" [mode]        = Determines how NSCA should run. Valid modes:\n");
		printf("   --inetd     = Run as a service under inetd or xinetd\n");
		printf("   --daemon    = Run as a standalone multi-process daemon\n");
		printf("   --single    = Run as a standalone single-process daemon (default)\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to accept passive check results from\n");
		printf("remote hosts that use the send_nsca utility.  Can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon.\n");
		printf("\n");
	}

	if (show_license == TRUE)
		display_license();

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
		do_exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility may be overridden later */
	get_log_facility(NSCA_LOG_FACILITY);
	openlog("nsca", LOG_PID | LOG_NDELAY, log_facility);

	/* make sure the config file uses an absolute path */
	if (config_file[0] != '/') {

		/* save the name of the config file */
		strncpy(buffer, config_file, sizeof(buffer));
		buffer[sizeof(buffer) - 1] = '\0';

		/* get absolute path of current working directory */
		strcpy(config_file, "");
		getcwd(config_file, sizeof(config_file));

		/* append a forward slash */
		strncat(config_file, "/", sizeof(config_file) - 2);
		config_file[sizeof(config_file) - 1] = '\0';

		/* append the config file to the path */
		strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1);
		config_file[sizeof(config_file) - 1] = '\0';
	}

	/* read the config file */
	result = read_config_file(config_file);

	/* exit if there are errors... */
	if (result == ERROR)
		do_exit(STATE_CRITICAL);

	/* generate the CRC 32 table */
	generate_crc32_table();


	/* how should we handle client connections? */
	switch (mode) {

	case INETD:
		/* chroot if configured */
		do_chroot();

		/* if we're running under inetd, handle one connection and get out */
		handle_connection(0, NULL);
		break;

	case MULTI_PROCESS_DAEMON:

		/* older style, mult-process daemon */
		/* execution cascades below... */
		install_child_handler();

		/*     |
		       |
		       |     */
	case SINGLE_PROCESS_DAEMON:
		/*     |
		       |
		       V     */

		/* daemonize and start listening for requests... */
		if (fork() == 0) {

			/* we're a daemon - set up a new process group */
			setsid();

			/* handle signals */
			signal(SIGQUIT, sighandler);
			signal(SIGTERM, sighandler);
			signal(SIGHUP, sighandler);
			
			signal(SIGPIPE, SIG_IGN);

			/* close standard file descriptors */
			close(0);
			close(1);
			close(2);

			/* redirect standard descriptors to /dev/null */
			open("/dev/null", O_RDONLY);
			open("/dev/null", O_WRONLY);
			open("/dev/null", O_WRONLY);

			/* get group information before chrooting */
			get_user_info(nsca_user, &uid);
			get_group_info(nsca_group, &gid);

			/* write pid file */
			if (write_pid_file(uid, gid) == ERROR)
				return STATE_CRITICAL;

			/* chroot if configured */
			do_chroot();

			/* drop privileges */
			if (drop_privileges(nsca_user, uid, gid) == ERROR)
				do_exit(STATE_CRITICAL);

			do {

				/* reset flags */
				sigrestart = FALSE;
				sigshutdown = FALSE;

				/* wait for connections */
				wait_for_connections();

				if (sigrestart == TRUE) {

					/* free memory */
					free_memory();

					/* re-read the config file */
					result = read_config_file(config_file);

					/* exit if there are errors... */
					if (result == ERROR) {
						syslog(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file);
						break;
					}
				}

			} while (sigrestart == TRUE && sigshutdown == FALSE);

			/* remove pid file */
			remove_pid_file();

			syslog(LOG_NOTICE, "Daemon shutdown\n");
		}
		break;

	default:
		break;
	}

	/* we are now running in daemon mode, or the connection handed over by inetd has been completed, so the parent process exits */
	do_exit(STATE_OK);

	/* keep the compilers happy... */
	return STATE_OK;
}
Пример #5
0
static int ncat_listen_stream(int proto)
{
    int rc, i, fds_ready;
    fd_set listen_fds;

    /* clear out structs */
    FD_ZERO(&master_readfds);
    FD_ZERO(&master_writefds);
    FD_ZERO(&master_broadcastfds);
    FD_ZERO(&listen_fds);
#ifdef HAVE_OPENSSL
    FD_ZERO(&sslpending_fds);
#endif
    zmem(&client_fdlist, sizeof(client_fdlist));
    zmem(&broadcast_fdlist, sizeof(broadcast_fdlist));

#ifdef WIN32
    set_pseudo_sigchld_handler(decrease_conn_count);
#else
    /* Reap on SIGCHLD */
    Signal(SIGCHLD, sigchld_handler);
    /* Ignore the SIGPIPE that occurs when a client disconnects suddenly and we
       send data to it before noticing. */
    Signal(SIGPIPE, SIG_IGN);
#endif

#ifdef HAVE_OPENSSL
    if (o.ssl)
        setup_ssl_listen();
#endif

    /* We need a list of fds to keep current fdmax. The second parameter is a
       number added to the supplied connection limit, that will compensate
       maxfds for the added by default listen and stdin sockets. */
    init_fdlist(&client_fdlist, sadd(o.conn_limit, num_listenaddrs + 1));

    for (i = 0; i < NUM_LISTEN_ADDRS; i++)
        listen_socket[i] = -1;

    for (i = 0; i < num_listenaddrs; i++) {
        /* setup the main listening socket */
        listen_socket[i] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]);

        /* Make our listening socket non-blocking because there are timing issues
         * which could cause us to block on accept() even though select() says it's
         * readable.  See UNPv1 2nd ed, p422 for more.
         */
        unblock_socket(listen_socket[i]);

        /* setup select sets and max fd */
        FD_SET(listen_socket[i], &master_readfds);
        add_fd(&client_fdlist, listen_socket[i]);

        FD_SET(listen_socket[i], &listen_fds);
    }
    add_fd(&client_fdlist, STDIN_FILENO);

    init_fdlist(&broadcast_fdlist, o.conn_limit);

    while (1) {
        /* We pass these temporary descriptor sets to fselect, since fselect
           modifies the sets it receives. */
        fd_set readfds = master_readfds, writefds = master_writefds;
        struct fdinfo *fdi = NULL;

        if (o.debug > 1)
            logdebug("selecting, fdmax %d\n", client_fdlist.fdmax);

        if (o.debug > 1 && o.broker)
            logdebug("Broker connection count is %d\n", get_conn_count());

        fds_ready = fselect(client_fdlist.fdmax + 1, &readfds, &writefds, NULL, NULL);

        if (o.debug > 1)
            logdebug("select returned %d fds ready\n", fds_ready);

        /*
         * FIXME: optimize this loop to look only at the fds in the fd list,
         * doing it this way means that if you have one descriptor that is very
         * large, say 500, and none close to it, that you'll loop many times for
         * nothing.
         */
        for (i = 0; i <= client_fdlist.fdmax && fds_ready > 0; i++) {
            /* Loop through descriptors until there's something to read */
            if (!FD_ISSET(i, &readfds) && !FD_ISSET(i, &writefds))
                continue;

            if (o.debug > 1)
                logdebug("fd %d is ready\n", i);

#ifdef HAVE_OPENSSL
            /* Is this an ssl socket pending a handshake? If so handle it. */
            if (o.ssl && FD_ISSET(i, &sslpending_fds)) {
                FD_CLR(i, &master_readfds);
                FD_CLR(i, &master_writefds);
                fdi = get_fdinfo(&client_fdlist, i);
                switch(ssl_handshake(fdi)){
                case NCAT_SSL_HANDSHAKE_COMPLETED:
                    /* Clear from sslpending_fds once ssl is established */
                    FD_CLR(i, &sslpending_fds);
                    rm_fd(&client_fdlist, i);
                    post_handle_connection(*fdi);
                    break;
                case NCAT_SSL_HANDSHAKE_PENDING_WRITE:
                    FD_SET(i, &master_writefds);
                    break;
                case NCAT_SSL_HANDSHAKE_PENDING_READ:
                    FD_SET(i, &master_readfds);
                    break;
                case NCAT_SSL_HANDSHAKE_FAILED:
                default:
                    SSL_free(fdi->ssl);
                    Close(fdi->fd);
                    FD_CLR(i, &sslpending_fds);
                    FD_CLR(i, &master_readfds);
                    rm_fd(&client_fdlist, i);
                    /* Are we in single listening mode(without -k)? If so
                       then we should quit also. */
                    if (!o.keepopen && !o.broker)
                        return 1;
                    --conn_inc;
                    break;
                }
            } else
#endif
            if (FD_ISSET(i, &listen_fds)) {
                /* we have a new connection request */
                handle_connection(i);
            } else if (i == STDIN_FILENO) {
                if(o.broker) {
                    read_and_broadcast(i);
                }else {
                    /* Read from stdin and write to all clients. */
                    rc = read_stdin();
                    if (rc == 0 && o.sendonly)
                        /* There will be nothing more to send. If we're not
                           receiving anything, we can quit here. */
                        return 0;
                    if (rc < 0)
                        return 1;
                }
            } else if (!o.sendonly) {
                if(o.broker) {
                    read_and_broadcast(i);
                }else {
                    /* Read from a client and write to stdout. */
                    rc = read_socket(i);
                    if (rc <= 0 && !o.keepopen)
                        return rc == 0 ? 0 : 1;
                }
            }

            fds_ready--;
        }
    }

    return 0;
}
Пример #6
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
	char *env_string=NULL;
#ifdef HAVE_SSL
	DH *dh;
	char seedfile[FILENAME_MAX];
	int i,c;
#endif

	/* set some environment variables */
	asprintf(&env_string,"NRPE_MULTILINESUPPORT=1");
	putenv(env_string);
	asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION);
	putenv(env_string);

	/* process command-line args */
	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
#ifndef HAVE_LIBWRAP
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE!  **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe [-n] -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n            = Do not use SSL\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		/* Updates help section to indicate how to start under SRC on AIX */
		printf("   -d -s       =    Run as a subsystem under AIX\n");        
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility name may be overridden later */
	get_log_facility(NRPE_LOG_FACILITY);
        openlog("nrpe",LOG_PID,log_facility); 

	/* make sure the config file uses an absolute path */
	if(config_file[0]!='/'){

		/* save the name of the config file */
		strncpy(buffer,config_file,sizeof(buffer));
		buffer[sizeof(buffer)-1]='\x0';

		/* get absolute path of current working directory */
		strcpy(config_file,"");
		getcwd(config_file,sizeof(config_file));

		/* append a forward slash */
		strncat(config_file,"/",sizeof(config_file)-2);
		config_file[sizeof(config_file)-1]='\x0';

		/* append the config file to the path */
		strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1);
		config_file[sizeof(config_file)-1]='\x0';
	        }

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file);
		return STATE_CRITICAL;
		}

        /* generate the CRC 32 table */
        generate_crc32_table();

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();

		/* use week random seed if necessary */
		if(allow_weak_random_seed && (RAND_status()==0)){

			if(RAND_file_name(seedfile,sizeof(seedfile)-1))
				if(RAND_load_file(seedfile,-1))
					RAND_write_file(seedfile);

			if(RAND_status()==0){
				syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged");
				srand(time(NULL));
				for(i=0;i<500 && RAND_status()==0;i++){
					for(c=0;c<sizeof(seedfile);c+=sizeof(int)){
						*((int *)(seedfile+c))=rand();
					        }
					RAND_seed(seedfile,sizeof(seedfile));
					}
				}
			}

		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

		/* use anonymous DH ciphers */
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* if we're running under inetd... */
	if(use_inetd==TRUE){

		/* make sure we're not root */
		check_privileges();

		/* redirect STDERR to /dev/null */
		close(2);
		open("/dev/null",O_WRONLY);

		/* handle the connection */
		handle_connection(0);
	        }

	/* if we're running under SRC... 
	   we don't fork but does drop-privileges*/
	else if (use_src==TRUE){

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;

		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();
			
			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }

		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }            


	/* else daemonize and start listening for requests... */
	else if(fork()==0){
		
		/* we're a daemon - set up a new process group */
		setsid();

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;
		
		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();

			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }
	
		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
Пример #7
0
/* wait for incoming connection requests */
void wait_for_connections(void){
	struct sockaddr_in myname;
	struct sockaddr_in *nptr;
	struct sockaddr addr;
	int rc;
	int sock, new_sd;
	socklen_t addrlen;
	pid_t pid;
	int flag=1;
	fd_set fdread;
	struct timeval timeout;
	int retval;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	/* create a socket for listening */
	sock=socket(AF_INET,SOCK_STREAM,0);

	/* exit if we couldn't create the socket */
	if(sock<0){
	        syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno));
	        exit(STATE_CRITICAL);
		}

	/* socket should be non-blocking */
	fcntl(sock,F_SETFL,O_NONBLOCK);

        /* set the reuse address flag so we don't get errors when restarting */
        flag=1;
        if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
		syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
		exit(STATE_UNKNOWN);
	        }

	myname.sin_family=AF_INET;
	myname.sin_port=htons(server_port);
 	bzero(&myname.sin_zero,8);

	/* what address should we bind to? */
        if(!strlen(server_address))
		myname.sin_addr.s_addr=INADDR_ANY;

	else if(!my_inet_aton(server_address,&myname.sin_addr)){
		syslog(LOG_ERR,"Server address is not a valid IP address\n");
		exit(STATE_CRITICAL);
                }

	/* bind the address to the Internet socket */
	if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){
		syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
	        exit(STATE_CRITICAL);
	        }

	/* open the socket for listening */
	if(listen(sock,5)<0){
	    	syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno));
	        exit(STATE_CRITICAL);
		}

	/* log warning about command arguments */
#ifdef ENABLE_COMMAND_ARGUMENTS
	if(allow_arguments==TRUE)
		syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!");
#ifdef ENABLE_BASH_COMMAND_SUBSTITUTION
	if(TRUE==allow_bash_command_substitution) {
		if(TRUE==allow_arguments)
			syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments with bash command substitutions!");
		else
			syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments with bash command substitutions, but is not configured to accept command argements from clients. Enable command arguments if you wish to allow command arguments with bash command substitutions.");
		}
#endif
#endif

	syslog(LOG_INFO,"Listening for connections on port %d\n",htons(myname.sin_port));

	if(allowed_hosts)
		syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts);

	/* listen for connection requests - fork() if we get one */
	while(1){

		/* wait for a connection request */
	        while(1){

			/* wait until there's something to do */
			FD_ZERO(&fdread);
			FD_SET(sock,&fdread);
			timeout.tv_sec=0;
			timeout.tv_usec=500000;
			retval=select(sock+1,&fdread,NULL,&fdread,&timeout);

			/* bail out if necessary */
			if(sigrestart==TRUE || sigshutdown==TRUE)
				break;

			/* error */
			if(retval<0)
				continue;

			/* accept a new connection request */
			new_sd=accept(sock,0,0);

			/* some kind of error occurred... */
			if(new_sd<0){

				/* bail out if necessary */
				if(sigrestart==TRUE || sigshutdown==TRUE)
					break;

				/* retry */
				if(errno==EWOULDBLOCK || errno==EINTR)
					continue;

				/* socket is nonblocking and we don't have a connection yet */
				if(errno==EAGAIN)
					continue;

				/* fix for HP-UX 11.0 - just retry */
				if(errno==ENOBUFS)
					continue;

				/* else handle the error later */
				break;
			        }

			/* connection was good */
			break;
		        }

		/* bail out if necessary */
		if(sigrestart==TRUE || sigshutdown==TRUE)
			break;

		/* child process should handle the connection */
    		pid=fork();
    		if(pid==0){

			/* fork again so we don't create zombies */
			pid=fork();
			if(pid==0){

				/* hey, there was an error... */
				if(new_sd<0){

					/* log error to syslog facility */
					syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno));

					/* close socket prioer to exiting */
					close(sock);
			
					return;
				        }

				/* handle signals */
				signal(SIGQUIT,child_sighandler);
				signal(SIGTERM,child_sighandler);
				signal(SIGHUP,child_sighandler);

				/* grandchild does not need to listen for connections, so close the socket */
				close(sock);  

				/* find out who just connected... */
				addrlen=sizeof(addr);
				rc=getpeername(new_sd,&addr,&addrlen);

				if(rc<0){

				        /* log error to syslog facility */
					syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno));

				        /* close socket prior to exiting */
					close(new_sd);

					return;
		                        }

				nptr=(struct sockaddr_in *)&addr;

				/* log info to syslog facility */
				if(debug==TRUE)
					syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port);

				/* is this is a blessed machine? */
				if(allowed_hosts){
                	switch(nptr->sin_family) {
                    	case AF_INET:
                        	if(!is_an_allowed_host(nptr->sin_addr)) {
                            	/* log error to syslog facility */
                            	syslog(LOG_ERR,"Host %s is not allowed to talk to us!",inet_ntoa(nptr->sin_addr));

								/* log info to syslog facility */
								if ( debug==TRUE )
                                	syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));

								/* close socket prior to exiting */
								close(new_sd);
								exit(STATE_OK);
								} else {
									/* log info to syslog facility */
									if(debug==TRUE)
										syslog(LOG_DEBUG,"Host address is in allowed_hosts");

								}
							break;
                           
						case AF_INET6:
							syslog(LOG_DEBUG,"Connection from %s closed. We don't support AF_INET6 addreess family in ACL\n", inet_ntoa(nptr->sin_addr));
							break;
					}
				}

#ifdef HAVE_LIBWRAP

				/* Check whether or not connections are allowed from this host */
				request_init(&req,RQ_DAEMON,"nrpe",RQ_FILE,new_sd,0);
				fromhost(&req);

				if(!hosts_access(&req)){

					syslog(LOG_DEBUG,"Connection refused by TCP wrapper");

					/* refuse the connection */
					refuse(&req);
					close(new_sd);

					/* should not be reached */
					syslog(LOG_ERR,"libwrap refuse() returns!");
					exit(STATE_CRITICAL);
					}
#endif

				/* handle the client connection */
				handle_connection(new_sd);

				/* log info to syslog facility */
				if(debug==TRUE)
					syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));

				/* close socket prior to exiting */
				close(new_sd);

				exit(STATE_OK);
    			        }

			/* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */
			else
				exit(STATE_OK);
		        }
		
		/* parent ... */
		else{
			/* parent doesn't need the new connection */
			close(new_sd);

			/* parent waits for first child to exit */
			waitpid(pid,NULL,0);
		        }
  		}

	/* close the socket we're listening on */
	close(sock);

	return;
	}
Пример #8
0
void udpapp_appcall(void)
{
	handle_connection();
}
Пример #9
0
bool CWebserver::run(void)
{
	if(!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS))
	{
		dperror("Socket cannot bind and listen. Abort.\n");
		return false;
	}
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE

	// initialize values for select
	int listener = listenSocket.get_socket();// Open Listener
    	struct timeval tv;			// timeout struct
	FD_SET(listener, &master);		// add the listener to the master set
	fdmax = listener;			// init max fd
	fcntl(listener, F_SETFD , O_NONBLOCK); 	// listener master socket non-blocking
	int timeout_counter = 0;		// Counter for Connection Timeout checking
	int test_counter = 0;			// Counter for Testing long running Connections
	
	// main Webserver Loop
	while(!terminate)
	{
		// select : init vars
		read_fds 	= master; 	// copy it
		tv.tv_usec	= 10000;	// microsec: Timeout for select ! for re-use / keep-alive socket
		tv.tv_sec	= 0;		// seconds
		int fd 		= -1;
		
		// select : wait for socket activity	
		if(open_connections <= 0)	// No open Connection. Wait in select.
			fd = select(fdmax+1,&read_fds, NULL, NULL, NULL);// wait for socket activity
		else
			fd = select(fdmax+1,&read_fds, NULL, NULL, &tv);// wait for socket activity or timeout

		// too much to do : sleep
		if(open_connections >= HTTPD_MAX_CONNECTIONS-1)
			sleep(1);

		// Socket Error?
		if(fd == -1 && errno != EINTR)
		{
            		perror("select");
            		return false;
		}

		// Socket Timeout?
		if(fd == 0)
		{
			// Testoutput for long living threads
			if(++test_counter >= MAX_TIMEOUTS_TO_TEST)
			{
				for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++) 
					if(SocketList[j] != NULL) 		// here is a socket
						log_level_printf(2,"FD-TEST sock:%d handle:%d open:%d\n",SocketList[j]->get_socket(),
							SocketList[j]->handling,SocketList[j]->isOpened);
				test_counter=0;
			}
			// some connection closing previous missed?
			if(++timeout_counter >= MAX_TIMEOUTS_TO_CLOSE)
			{
				CloseConnectionSocketsByTimeout();
				timeout_counter=0;
			}
			continue;		// main loop again	
		}
		//----------------------------------------------------------------------------------------
		// Check all observed descriptors & check new or re-use Connections 
		//----------------------------------------------------------------------------------------
		for(int i = listener; i <= fdmax; i++)
		{
			int slot = -1;
			if(FD_ISSET(i, &read_fds)) 				// Socket observed?
			{ // we got one!!
				if (i == listener)				// handle new connections
					slot = AcceptNewConnectionSocket();
				else 						// Connection on an existing open Socket = reuse (keep-alive)
				{
					slot = SL_GetExistingSocket(i);
					if(slot>=0)
						log_level_printf(2,"FD: reuse con fd:%d\n",SocketList[slot]->get_socket());
				}
				// prepare Connection handling
				if(slot>=0)
					if(SocketList[slot] != NULL && !SocketList[slot]->handling && SocketList[slot]->isValid)
					{
						log_level_printf(2,"FD: START CON HANDLING con fd:%d\n",SocketList[slot]->get_socket());
						FD_CLR(SocketList[slot]->get_socket(), &master); // remove from master set
						SocketList[slot]->handling = true;	// prepares for thread-handling
						if(!handle_connection(SocketList[slot]))// handle this activity
						{	// Can not handle more threads
							char httpstr[]=HTTP_PROTOCOL " 503 Service Unavailable\r\n\r\n";
							SocketList[slot]->Send(httpstr, strlen(httpstr));
							SL_CloseSocketBySlot(slot);
						}	
					}
			}
		}// for
		CloseConnectionSocketsByTimeout();	// Check connections to close

	}//while
#else
	while(!terminate)
	{
		CySocket *newConnectionSock;
		if(!(newConnectionSock = listenSocket.accept() ))	//Now: Blocking wait
		{
			dperror("Socket accept error. Continue.\n");
			continue;
		}
		log_level_printf(3,"Socket connect from %s\n", (listenSocket.get_client_ip()).c_str() );
#ifdef Y_CONFIG_USE_OPEN_SSL
			if(Cyhttpd::ConfigList["SSL"]=="true")
				newConnectionSock->initAsSSL();	// make it a SSL-socket
#endif
		handle_connection(newConnectionSock);
	}
#endif
	return true;
}
Пример #10
0
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void)
{
#if PORT_APP_MAPPER
	struct httpd_state *s;
#else
	struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);
#endif


	if(uip_closed() || uip_aborted() || uip_timedout()) {
#if PORT_APP_MAPPER
//sendString("uip close/abort/timeout\r\n");
		if (uip_conn->appstate != -1)
		{
//sendString("uip close/abort/timeout - cleanup\r\n");
			httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
			uip_conn->appstate = -1;
		}
#endif
	} else if(uip_connected()) {
#if PORT_APP_MAPPER
		if ((uip_conn->appstate = alloc_state()) == -1)
		{
			// we are out of state space.  close the connection
			// hope the client tries back again
//sendString("Out of http stats\r\n");
			uip_abort();
			return;
		}
		// set the app state
		s = &(httpd_state_list[((int8_t)uip_conn->appstate)]);
#endif
		PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
		PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
		PT_INIT(&s->outputpt);
		s->state = STATE_WAITING;
	    /*    timer_set(&s->timer, CLOCK_SECOND * 100);*/
		s->timer = 0;
		handle_connection(s);
#if PORT_APP_MAPPER
	} else if (uip_conn->appstate != -1) {
		s = &(httpd_state_list[((int8_t)uip_conn->appstate)]);
#else
	} else if(s != NULL) {
#endif
		if(uip_poll()) {
			++s->timer;
			// if the client just hasn't sent
			// anything in a while we end up here
			// this is where we can clean up dead connections.
			// 20 seems like a long time - if(s->timer >= 20) {
			// 16 seems to be a good number wtih 5 status
			if(s->timer >= 16) {
#if PORT_APP_MAPPER
				if (uip_conn->appstate != -1)
				{
					httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
					uip_conn->appstate = -1;
				}
#endif
				uip_abort();
			}
    	} else {
			s->timer = 0;
		}
		handle_connection(s);
	} else {
#if PORT_APP_MAPPER
		if (uip_conn->appstate != -1)
		{
			httpd_state_list[((int8_t)uip_conn->appstate)].state = STATE_UNUSED;
			uip_conn->appstate = -1;
		}
#endif
		uip_abort();
	}
}
Пример #11
0
int
main (int argc, char *argv[])
{
  struct sockaddr_in servaddr;
  int port = 7777;
  int c;
  int err;

  if ((err = ossmix_init ()) < 0)
    {
      fprintf (stderr, "ossmix_init() failed, err=%d\n", err);
      exit (EXIT_FAILURE);
    }

  if ((err = ossmix_connect (NULL, 0)) < 0)	/* Force local connection */
    {
      fprintf (stderr, "ossmix_connect() failed, err=%d\n", err);
      exit (EXIT_FAILURE);
    }

  while ((c = getopt (argc, argv, "vp:")) != EOF)
    {
      switch (c)
	{
	case 'p':		/* TCP/IP port */
	  port = atoi (optarg);
	  if (port <= 0)
	    port = 9876;
	  break;

	case 'v':		/* Verbose */
	  verbose++;
	  break;
	}
    }

  printf ("Listening socket %d\n", port);

  if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("socket");
      exit (-1);
    }

  memset (&servaddr, 0, sizeof (servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
  servaddr.sin_port = htons (port);

  if (bind (listenfd, (struct sockaddr *) &servaddr, sizeof (servaddr)) == -1)
    {
      perror ("bind");
      exit (-1);
    }

  while (1)
    {

      if (!wait_connect ())
	exit (-1);

      handle_connection (connfd);
      close (connfd);
    }

  // close (listenfd); /* Not reached */
  exit (0);
}
Пример #12
0
PROCESS_THREAD(http_server, ev, data)
{
    connection_state_t *conn_state;

    PROCESS_BEGIN();

    /* if static routes are used rather than RPL */
#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET)
    set_global_address();
    configure_routing();
#endif /*!UIP_CONF_IPV6_RPL*/

#ifdef CONTIKI_TARGET_SKY
    PRINTF("##RF CHANNEL : %d##\n",RF_CHANNEL);
#endif //CONTIKI_TARGET_SKY

    tcp_listen(uip_htons(HTTP_PORT));

    /*
     * We loop for ever, accepting new connections.
     */
    while(1) {
        PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);

        conn_state = (connection_state_t *)data;

        if(uip_connected()) {
            PRINTF("##Connected##\n");

            if(init_buffer(HTTP_DATA_BUFF_SIZE)) {
                conn_state = (connection_state_t*)allocate_buffer(sizeof(connection_state_t));

                if (conn_state) {
                    tcp_markconn(uip_conn, conn_state);

                    /*initialize connection state*/
                    init_connection(conn_state);

                    /*-1 is needed to be able to null terminate the strings in the buffer, especially good for debugging (to have null terminated strings)*/
                    PSOCK_INIT(&(conn_state->sin), (uint8_t*)conn_state->inputbuf, sizeof(conn_state->inputbuf) - 1);
                    PSOCK_INIT(&(conn_state->sout), (uint8_t*)conn_state->inputbuf, sizeof(conn_state->inputbuf) - 1);
                    PT_INIT(&(conn_state->outputpt));

                    handle_connection(conn_state);
                } else {
                    PRINTF("Memory Alloc Error. Aborting!\n");
                    uip_abort();
                }
            }
        } else if (uip_aborted() || uip_closed() || uip_timedout()) {
            if (conn_state) {
                delete_buffer();

                /*Following 2 lines are needed since this part of code is somehow executed twice so it tries to free the same region twice.
                Potential bug in uip*/
                conn_state = NULL;
                tcp_markconn(uip_conn, conn_state);
            }
        } else {
            handle_connection(conn_state);
        }
    }

    PROCESS_END();
}
Пример #13
0
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void *state)
{
#if DEBUGLOGIC
  struct httpd_state *s; //Enter here for debugging with output directed to TCPBUF
  s = sg = (struct httpd_state *) memb_alloc(&conns);
  if (1) {
#else
  struct httpd_state *s = (struct httpd_state *) state;
  if (uip_closed() || uip_aborted() || uip_timedout()) {
    if (s != NULL) {
      if (s->fd >= 0) {
        httpd_fs_close(s->fd);
        s->fd = -1;
      }
      memb_free(&conns, s);
    }
  } else if (uip_connected()) {
    s = (struct httpd_state *) memb_alloc(&conns);
    if (s == NULL) {
      uip_abort();
      return;
    }
#endif
    tcp_markconn(uip_conn, s);
    PSOCK_INIT(&s->sin, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1);
    PSOCK_INIT(&s->sout, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1);
    PT_INIT(&s->outputpt);
    s->state = STATE_WAITING;
    s->timer = 0;
#if WEBSERVER_CONF_AJAX
    s->ajax_timeout = WEBSERVER_CONF_TIMEOUT;
#endif
    handle_connection(s);
  } else if (s != NULL) {
    if (uip_poll()) {
      ++s->timer;
#if WEBSERVER_CONF_AJAX
      if (s->timer >= s->ajax_timeout) {
#else
      if (s->timer >= WEBSERVER_CONF_TIMEOUT) {
#endif
        uip_abort();
        if (s->fd >= 0) {
          httpd_fs_close(s->fd);
          s->fd = -1;
        }
        memb_free(&conns, s);
      }
    } else {
      s->timer = 0;
    }
    handle_connection(s);
  } else {
    uip_abort();
  }
}
/*---------------------------------------------------------------------------*/
void
httpd_init(void)
{
  tcp_listen(UIP_HTONS(80));
  memb_init(&conns);
  PRINTD(" sizof(struct httpd_state) = %d\n",sizeof(struct httpd_state));
  PRINTA(" %d bytes used for httpd state storage\n", conns.size * conns.num);

}
Пример #14
0
int main(int argc, char *argv[])
{
	int listen_fd, fd;
	int yes = 1;
	int addrlen;
	struct sockaddr_in addr;
	fd_set master_fds, read_fds;

	printf("Server: init\n");

	/* get new socket & allow immediately reusing reserved port */
	listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

	/* server port and address */
	bzero(&addr, sizeof(addr));	
	addr.sin_family = AF_INET;	/* host byte order */
	addr.sin_port = htons(SERVER_PORT);	/* short, network byte order */
	addr.sin_addr.s_addr = INADDR_ANY;	/* host ip */

	if (bind(listen_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr))
								 == -1 ) {
		perror("Server: bind");
		exit(1);
	}

	if (listen(listen_fd, BACKLOG) == -1 ) {
		perror("Server: listen");
		exit(1);
	}

	/* keep record of connections */
	FD_ZERO(&master_fds);
	FD_SET(listen_fd, &master_fds);

	/* main loop */
	while (1) {

		/* select modifies read_fds */
		read_fds = master_fds;
		if (select(MAXFD+1, &read_fds, NULL, NULL, NULL) == -1) {
			perror("Server: select");
			continue;
		}

		/* iterate read_fds for new data/connection */
		for (fd = 0; fd <= MAXFD; fd++) {
			if (FD_ISSET(fd, &read_fds)) {
				if (fd == listen_fd) {
					/* create and store to master */
					new_connection(fd, &master_fds);
				} else {
					/* handle and delete from master */ 
					handle_connection(fd, &master_fds);
				}
			}
		}
	}

	/* should never get here */
	close(listen_fd);
}
Пример #15
0
int main(int argc, char *argv[])
{

	int optch;

	char format[] = "aevd:D:H:s:";

	struct sockaddr_in client;

	socklen_t client_len = sizeof(client);

	opterr = 1;

	while ((optch = getopt(argc, argv, format)) != -1)
		switch (optch) {
		case 'a':
			is_acquire = true;
			break;
		case 'e':
			extension_stripping = true;
			break;
		case 'v':
			verbose++;
			break;
		case 'd':
			plugin_dir = xstrdup(optarg);
			break;
		case 'D':
			pluginconf_dir = xstrdup(optarg);
			break;
		case 'H':
			host = xstrdup(optarg);
			break;
		case 's':
			spoolfetch_dir = xstrdup(optarg);
			break;
		}

	/* get default hostname if not precised */
	if ('\0' == *host) {
		int idx;

		host = xmalloc(HOST_NAME_MAX + 1);
		gethostname(host, HOST_NAME_MAX);

		/* going to lowercase */
		for (idx = 0; host[idx] != '\0'; idx++) {
			host[idx] = tolower((int) host[idx]);
		}
	}

	/* Prepare static plugin env vars once for all */
	setenvvars_system();

	/* Asked to acquire */
	if (is_acquire)
		return acquire_all();

	/* use a 1-shot stdin/stdout */
	if (0 == getpeername(STDIN_FILENO, (struct sockaddr *) &client,
			     &client_len))
		if (client.sin_family == AF_INET)
			client_ip = inet_ntoa(client.sin_addr);
	return handle_connection();
}
Пример #16
0
/* main loop of the Streaming server */
static int start_event_loop(void)
{
    int server_fd = 0, rtsp_server_fd = 0;
    int ret, delay;
    struct pollfd *poll_table, *poll_entry;
    RTSPContext *c, *c_next;

    if(!(poll_table = av_mallocz( 100 *sizeof(*poll_table)))) {
        http_log("Impossible to allocate a poll table handling %d connections.\n", 100);
        return -1;
    }

    if (my_rtsp_addr.sin_port) {
      rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
      if (rtsp_server_fd < 0) {
        http_log("HTTP and RTSP disabled.\n");
        return -1;
      }
    }

    printf("%s started.\n", program_name);

    for(;;) {
        poll_entry = poll_table;
        if (rtsp_server_fd) {
            poll_entry->fd = rtsp_server_fd;
            poll_entry->events = POLLIN;
            poll_entry++;
        }

        /* wait for events on each HTTP handle */
        c = first_rtsp_ctx;
        //delay = 1000;
        delay = 10;
        while (c != NULL) {
            int fd;
            fd = c->fd;
            switch(c->state) {
            case RTSPSTATE_SEND_REPLY:
            case RTSPSTATE_SEND_PACKET:
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLOUT;
                poll_entry++;
                break;
            case RTPSTATE_SEND_DATA:
                /* for TCP, we output as much as we can
                 * (may need to put a limit) */
                if (strcmp(c->protocol, "RTP/UDP") == 0) {
                  fd = c->udp_fd;
                }
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLOUT;
                poll_entry++;
                break;
            case RTSPSTATE_WAIT_REQUEST:
                /* need to catch errors */
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
                poll_entry->events = POLLIN;/* Maybe this will work */
                poll_entry++;
                break;
            default:
                c->poll_entry = NULL;
                break;
            }
            c = c->next;
        }

        /* wait for an event on one connection. We poll at least every
           second to handle timeouts */
        do {
            ret = poll(poll_table, poll_entry - poll_table, delay);
            if (ret < 0) {
              printf ("poll errorr \n");
              return -1;
            }
        } while (ret < 0);

        cur_time = av_gettime() / 1000;

        /* now handle the events */
        for(c = first_rtsp_ctx; c != NULL; c = c_next) {
            c_next = c->next;
            if (handle_connection(c) < 0) {
              /* close and free the connection */
                close_connection(c);
            }
        }

        // 처음에  rtsp_server_fd로 셋팅했던 거. 로 포인터 값 변경.
        poll_entry = poll_table;
        if (rtsp_server_fd) {
            /* new RTSP connection request ? */
            if (poll_entry->revents & POLLIN)
                new_connection(rtsp_server_fd);
        }
    }
}
Пример #17
0
static void connection_cb(struct ev_loop *loop, struct ev_io *w, int revents)
{
        handle_connection((server_generic_t *) w);
}