예제 #1
0
파일: main.c 프로젝트: BackupGGCode/aemu
/**
 * Server Entry Point
 * @param argc Number of Arguments
 * @param argv Arguments
 * @return OS Error Code
 */
int main(int argc, char * argv[])
{
	// Result
	int result = 0;
	
	// Create Signal Receiver for CTRL + C
	signal(SIGINT, interrupt);
	
	// Create Signal Receiver for kill / killall
	signal(SIGTERM, interrupt);
	
	// Create Listening Socket
	int server = create_listen_socket(SERVER_PORT);
	
	// Created Listening Socket
	if(server != -1)
	{
		// Notify User
		printf("Listening for Connections on TCP Port %u.\n", SERVER_PORT);
		
		// Enter Server Loop
		result = server_loop(server);
		
		// Notify User
		printf("Shutdown complete.\n");
	}
	
	// Return Result
	return result;
}
예제 #2
0
static void start_adb_socket()	{
	int listen_sock=INVALID_HANDLE;
	int sock_status=ASI_SUCCESS;

	system("adb devices");

	/* Insert port */
	listen_sock = create_listen_socket(TCP_SERVER_PORT);

	while( (listen_sock!=INVALID_HANDLE) && (sock_status == ASI_SUCCESS))
	{
		/* WLAN enable */
		chip_awake(2);

		/* Call  socket session  handling */
		sock_status=socket_handle(listen_sock);
		sleep (1);

		/* Disable WLAN */
		chip_awake(0);
		sleep (1);

	}

    log_write( " Server: socket close listen mode... n");
	close(listen_sock);
}
예제 #3
0
static BOOL TestNet_ThreadInit(unsigned short usPort)
{
	if (g_pWirelessTest != NULL)
		goto error_alread_inited;
		
	g_pWirelessTest = (WIRELESS_TEST_T *) malloc(sizeof(WIRELESS_TEST_T));
	if (g_pWirelessTest == NULL)
		goto error_malloc;

	/* Create listening socket. */
	g_pWirelessTest->fd_listen = create_listen_socket( usPort );
	if ( g_pWirelessTest->fd_listen == -1 )
		goto error_listen;
	
	cyg_thread_create(PTD_PRIORITY-3, WirelessTest_Test_Entry, (cyg_addrword_t)g_pWirelessTest, "test_net", 
					g_pWirelessTest->datathread_stack, sizeof(g_pWirelessTest->datathread_stack), 
					&g_pWirelessTest->datathread_handle, &g_pWirelessTest->datathread_thread);

	cyg_thread_resume(g_pWirelessTest->datathread_handle);
	

	return TRUE;
error_listen:
	free(g_pWirelessTest);
error_malloc:
error_alread_inited:
	return FALSE;
}
예제 #4
0
파일: vncserver.c 프로젝트: tweakoz/c65gs
int openSerialPort(char *port)
{
  serialfd=open(port,O_RDWR);  
  if (serialfd==-1) { perror("open"); return -1; }
  fcntl(serialfd,F_SETFL,fcntl(serialfd, F_GETFL, NULL)|O_NONBLOCK);
  struct termios t;
  if (cfsetospeed(&t, B230400)) perror("Failed to set output baud rate");
  if (cfsetispeed(&t, B230400)) perror("Failed to set input baud rate");
  t.c_cflag &= ~PARENB;
  t.c_cflag &= ~CSTOPB;
  t.c_cflag &= ~CSIZE;
  t.c_cflag &= ~CRTSCTS;
  t.c_cflag |= CS8 | CLOCAL;
  t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOE);
  t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR |
                 INPCK | ISTRIP | IXON | IXOFF | IXANY | PARMRK);
  t.c_oflag &= ~OPOST;
  if (tcsetattr(serialfd, TCSANOW, &t)) perror("Failed to set terminal parameters");
  perror("F");

  listen_sock = create_listen_socket(4510);
  if (listen_sock==-1) { perror("Couldn't listen to port 4510"); exit(-1); }
  printf("Listening for remote serial connections on port 4510, fd=%d.\n",listen_sock);

  pthread_create(&serialThread,NULL,serial_handler,NULL);

  return 0;
}
예제 #5
0
/* function definitions */
int main(void)
{
	/* local variables definitions */
	int i = 0;
	int socket_fd = -1;
	listen_addr addr_array[] = {{"\0", 9001}, {"\0", 9002}, {"\0", 9003}};
	
	/* code body */
	for (i = 0; i < (sizeof(addr_array) / sizeof(addr_array[0])); i++)
	{
		socket_fd = create_listen_socket(&(addr_array[i]));
		if (-1 == socket_fd)
		{
			goto MAIN_ERR_END;
		}
		else
		{
			add_fd_into_monitor_event_loop(socket_fd, EVENT_TYPE_READ, accept_new_socket, (void*)socket_fd);
		}
	}

	while (1)
	{
		run_monitor_event_loop();
	}
	
	return EXIT_CODE_SUCCESS;
	
MAIN_ERR_END:
	return EXIT_CODE_ERROR;
}
예제 #6
0
파일: socks.c 프로젝트: michelbl/TOR-clone
int proxy_socksv4 (int port) {
	struct sockaddr_in sockaddr_client;
	int listen_socket_descriptor;
	int client_socket_descriptor;
	socklen_t length = sizeof(sockaddr_client);

	listen_socket_descriptor = create_listen_socket(port);
	if(listen_socket_descriptor == -1) {
		fprintf (stderr, "Failed to create server\n");
		return -1;
	}
	printf ("Listening\n");

	for (;;) {
		if ((client_socket_descriptor = accept(listen_socket_descriptor, (struct sockaddr *) 
			&sockaddr_client, &length)) > 0) 
		{
			printf ("New client %d\n", client_socket_descriptor);
			if (handle_connection (client_socket_descriptor) != 0) 
			{
				break;
			}
		}
	}

	return 0;
}
예제 #7
0
TcpServerBase::TcpServerBase(const IpPort &bind_addr, const char *cert, const char *private_key)
	: SocketServerBase(create_listen_socket(bind_addr))
{
	if(cert && (cert[0] != 0)){
		m_ssl_factory.reset(new ServerSslFactory(cert, private_key));
	}

	LOG_POSEIDON(Logger::SP_MAJOR | Logger::LV_INFO, "Created ", (m_ssl_factory ? "SSL " : ""), "TCP server on ", get_local_info());
}
예제 #8
0
void NetTestThread(cyg_addrword_t arg)
{
	int listen_fd = create_listen_socket(8181);
	while(listen_fd >= 0)
	{
		int fd = accept_client(listen_fd);
		diag_printf("accept fd=%d\n", fd);
		if(fd >= 0)
		{
			int i;
			for(i = 0; i < 100; ++i)
				write(fd, "abcd\r\n", 6);
			close(fd);
		}
		diag_printf("Retry accept\n");
	}
	diag_printf("After while\n");
	close(listen_fd);
}
예제 #9
0
파일: qnet.c 프로젝트: DiaosiDev/qnode
int
qnet_tcp_listen(int port, const char *addr, int *error) {
  int                 fd;
  struct sockaddr_in  sa;

  if ((fd = create_listen_socket()) < 0) {
    return QERROR;
  }

  if (set_nonblocking(fd) < 0) {
    return QERROR;
  }

  memset(&sa,0,sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  *error = 0;
  if (inet_aton(addr, &sa.sin_addr) == 0) {
    qerror("invalid bind address");
    *error = errno;
    close(fd);
    return QERROR;
  }

  if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
    *error =  errno;
    qerror("bind error: %s", strerror(*error));
    close(fd);
    return QERROR;
  }

  if (listen(fd, 511) == -1) {
    *error =  errno;
    qerror("listen error: %s", strerror(*error));
    close(fd);
    return QERROR;
  }

  return fd;
}
예제 #10
0
int main(int argc, char **argv)
{
  struct sigaction act;
  int sfd;
  if(argc < 2) {
    fprintf(stderr, "Usage: %s PORT\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  memset(&act, 0, sizeof(struct sigaction));
  act.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &act, NULL);
  sigaction(SIGCHLD, &act, NULL);

  sfd = create_listen_socket(argv[1]);
  if(sfd == -1) {
    fprintf(stderr, "Failed to create server socket\n");
    exit(EXIT_FAILURE);
  }
  printf("WebSocket echo server, listening on %s\n", argv[1]);
  serve(sfd);
  return EXIT_SUCCESS;
}
예제 #11
0
/* -------------------initiate ftp server-------------------
*/
int run_ftp(int port)
{

	memset(&listen_conn, 0, sizeof(connection));

	listen_conn.saddr.sin_port = htons(port);

	if (create_listen_socket(&listen_conn) < 0) {
		printlog("%s","create_listen_socket FAILED\n");
		exit(1);
	}

	for (;;) {
		if (accept_connection( &listen_conn, &sconn) < 0) {
			printlog("%s","accept_connection FAILED\n");
			continue;
		}

		signal(SIGCHLD, SIG_IGN);

		if (fork() == 0) {
        		close_conn(listen_conn);

        		status = CONNECTED;

        		send_greetings();

        		command_loop();

        		close_conn(sconn);
        		return 0;
		}

        	close_conn(sconn);
	}

	return 0;
}
예제 #12
0
파일: srun_cr.c 프로젝트: Xarthisius/slurm
/*
 * fork_exec_srun - fork and exec srun
 * GLOBALS cr_argv: arguments for running srun
 * RETURN: 0 on success, otherwise on error
 */
static int
fork_exec_srun(void)
{
	int rc = 0;
	sigset_t sigset;

	listen_fd = create_listen_socket();
	if (listen_fd < 0) {
		return -1;
	}

	srun_pid = fork();
	if (srun_pid < 0) {
		error("failed to fork child process: %m");
		return -1;
	} else if (srun_pid == 0) {	/* child */
		/*
		 * remove srun from the foreground process group,
		 * or Ctrl-C will cause SIGINT duplicated
		 */
		setpgrp();

		update_env("SLURM_SRUN_CR_SOCKET", cr_sock_addr);

		/*
		 * BLCR blocks all signals in thread-context callback functions
		 */
		sigemptyset(&sigset);
		pthread_sigmask(SIG_SETMASK, &sigset, NULL);

		execv(srun_argv[0], srun_argv);
		perror("failed execv srun");
		exit(-1);
	}

	return rc;
}
예제 #13
0
/**
 * Add a mapping (local port -> remote host + port) to the gateway structure.
 *
 * Creates a listening port for the local side and adds the fd to the fd_map
 * on the gateway that maps listening ports to the map structure.
 *
 * The mappings are stored in an array of pointers gw->pm that is grown
 * appropriately and gw->n_maps stores the size of this array.
 *
 * @gw			gateway structure to add to
 * @local_port	the local port to listen on -- bound to localhost:NNNN
 * @host		the remote host to tunnel to
 * @remote_port	the port on the remote side to connect to
 * @return		Nothing, if anything fails here the program exits
 */
void add_map_to_gw(struct gw_host *gw,
				  uint32_t local_port,
				  char *host,
				  uint32_t remote_port)
{
	struct static_port_map *spm;

	debug("Adding map %d %s:%d to %s", local_port, host, remote_port, gw->name);

	spm = safemalloc(sizeof(struct static_port_map), "static_port_map alloc");
	spm->parent = gw;
	spm->local_port = local_port;
	spm->remote_host = safestrdup(host, "spm strdup hostname");
	spm->remote_port = remote_port;
	spm->ch = safemalloc(sizeof(struct chan_sock *), "spm->ch");

	spm->listen_fd = create_listen_socket(local_port, "localhost");
	add_fdmap(gw->listen_fdmap, spm->listen_fd, spm);
	spm->parent = gw;
	spm->n_channels = 0;

	saferealloc((void **)&gw->pm, (gw->n_maps + 1) * sizeof(spm), "gw->pm realloc");
	gw->pm[gw->n_maps++] = spm;
}
예제 #14
0
int main(void)
{
	int ret=0;
	struct thread thread;
	int sock;

	pthread_t packet_thread_id;

	rte_backtrace_init();

	if(!access(SHOW_PACKET_FLILE, F_OK)){ // file exist, will show packet
		vsecplat_show_packet = 1;
	}

	if(!access(SHOW_RECORD_FLILE, F_OK)){ // file exist, will show packet
		vsecplat_show_record = 1;
	}

	ret = nm_log_init();
	if(ret<0){
		printf("failed to init log.\n");
		return -1;
	}

	ret = init_disp_type();
	if(ret<0){
		printf("failed to init disp type array.\n");
		return -1;
	}

	// parse configfile and init global descriptor: global_vsecplat_config
	ret = parse_vsecplat_config();	
	if(ret<0){
		printf("Failed to parse vsecplat config.\n");
		return -1;
	}

	ret = init_recurs_dst_mac_list();
	if(ret<0){
		printf("Failed to init recursive dstmac list.\n");
		return -1;
	}

	// Init forward policy desc: fw_policy_list
	ret = init_policy_list();
	if(ret<0){
		printf("Failed to init policy descriptor.\n");
		return -1;
	}

	// init global interface list: vsecplat_interface_list
	ret = init_vsecplat_interface_list();
	if(ret<0){
		printf("Failed to get interface.\n");
		return -1;
	}

#if 1 // Disable to test function on host
	// setup mgt interface ip address and set it to up
	ret = setup_mgt_interface();
	if(ret<0){
		printf("Failed to setup mgt interface.\n");
		return -1;
	}
#endif

	// set dataplane interface to netmap mode
	ret = setup_dp_interfaces();
	if(ret<0){
		printf("Failed to setup dataplane interface.\n");
		return -1;
	}

	// init connection descriptor: conn_desc
	ret = init_conn_desc();
	if(ret<0){
		printf("Failed to init vsecplat status.\n");
		return -1;
	}

	// init record bucket: record_bucket_hash
	ret = vsecplat_init_record_bucket();
	if(ret<0){
		printf("Failed to init record bucket.\n");
		return -1;
	}

    ret = vsecplat_load_duplicate_rule();
    if(ret<0){
        printf("Failed to load duplicate rules.\n");
        return -1;
    }

	ret = vsecplat_load_policy();
	if(ret<0){
		printf("Failed to load policy.\n");
		return -1;
	}

#if 0// For test
	test_packet_match_policy();
	vsecplat_test_record();
	packet_handle_thread(NULL);
#endif

#if 1
	/* 创建处理数据包的线程 */
	ret = pthread_create(&packet_thread_id, NULL, &packet_handle_thread, NULL);
	if(ret<0){
		nm_log("failed to create packet thread.\n");
		return -1;
	}
#endif

#if 1
	// manage thread 
	master = thread_master_create();
	if(NULL==master){
		nm_log("failed to alloc master.\n");
		return -1;
	}

	/* 报告统计数据的线程 */
	nm_log("Add report stats thread.\n");
	thread_add_timer(master, vsecplat_report_stats, NULL, global_vsecplat_config->time_interval);

	sock = create_listen_socket();
	if(sock<0){
		nm_log("failed to create socket.\n");
		return -1;
	}
	thread_add_read(master, vsecplat_listen_func, NULL, sock);

	memset(&thread, 0, sizeof(struct thread));
	while(thread_fetch(master, &thread)){
		thread_call(&thread);
	}
#endif
	return 0;
}
예제 #15
0
int start_server(struct parameters *params)
{
    int i;
    int cl_socket, val = 1;
    int exiting = 0,
        ret = 0;
    struct sockaddr_in client;
    socklen_t addrlen = sizeof client;
    pthread_t thread;

    if (sem_init(&thread_start_lock, 1, 0)) {
        logit(L_FATAL "Failed to create thread_start_lock");
        exit(-7);
    }

    if (sem_init(&thread_arr_lock, 1, 1)) {
        logit(L_FATAL "Failed to create thread_arr_lock");
        exit(-8);
    }

    if (params->daemonize) {
        daemonize();
    }

    listen_socket = create_listen_socket(params->server_port);

    if (listen_socket < 0) {
        logit(L_FATAL "Failed to create listen socket");
        exit(-1);
    }

    if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0)
        logit(L_WARNING "setsockopt() failed: %s", strerror(errno));

    /* Main loop */
    while (!exiting) {

        if ((cl_socket = accept(listen_socket, (struct sockaddr*)&client,
                                &addrlen)) > 0) {
            void *thread_args[] = {
                &cl_socket, &i
            };

            for (i=0; i<params->max_clients; i++) {
                logit(L_DEBUG "i = %d", i);
                if (clients[i] == NULL) break;
            }

            if (i == params->max_clients) {
                logit(L_WARNING "Too many clients, dropping client [%s]",
                      inet_ntoa(client.sin_addr));
                send(cl_socket, "err_limit_reached", 18, 0);
                while (close(cl_socket) < 0);
                continue;
            }

            clients[i] = calloc(1, sizeof(struct client));

            if ((ret = pthread_create(&thread, NULL,
                                      serve_client, (void*)thread_args)) != 0) {
                logit(L_FATAL "failed to create thread, error code: %d", ret);
                exit(-6);
            }

            sem_wait(&thread_start_lock);

            clients[i]->thread_id = thread;
            clients[i]->socket    = cl_socket;
        }
    }

    return 0;
}
예제 #16
0
파일: listen.c 프로젝트: lkl/lkl-lklftpd
void lfd_listen(apr_pool_t * mp)
{
	apr_pool_t		* thd_pool = NULL;
	apr_socket_t		* listen_sock;
	apr_socket_t		* client_sock;
	apr_thread_t *thd;
	apr_threadattr_t	* thattr;
	apr_pollfd_t		  pfd;
	apr_interval_time_t	  timeout = lfd_config_max_acceptloop_timeout;
	apr_int32_t		  nsds;
	apr_status_t		  rc;

	create_listen_socket(&listen_sock, mp);
	if(NULL == listen_sock)
	{
		lfd_log(LFD_ERROR, "lfd_listen: could not create listen socket");
		return;
	}

	rc = apr_threadattr_create(&thattr, mp);
	if(APR_SUCCESS != rc)
	{
		lfd_log_apr_err(rc, "apr_threadattr_create failed");
		return;
	}
	while(1)
	{
		//###: Should I allocate the pool as a subpool of the root pool?
		//What is the amount allocated per pool and is it freed when the child pool is destroyed?
		//rc = apr_pool_create(&thd_pool, mp);
		if(NULL == thd_pool)
		{
			rc = apr_pool_create(&thd_pool, NULL);
			if(APR_SUCCESS != rc)
			{
				lfd_log_apr_err(rc, "apr_pool_create of thd_pool failed");
				continue;
			}
		}

		create_pollfd_from_socket(&pfd, listen_sock, mp);

		rc = apr_poll(&pfd, 1, &nsds, timeout);
		if((APR_SUCCESS != rc) && (!APR_STATUS_IS_TIMEUP(rc)) && (!APR_STATUS_IS_EINTR(rc)))
		{
			//break - an unrecoverable error occured
			lfd_log_apr_err(rc, "apr_poll failed");
			break;
		}

		if(apr_atomic_read32(&ftp_must_exit))
		{
			//if the flag says we must exit, we comply, so bye bye!
			return;
		}
		if(APR_STATUS_IS_TIMEUP(rc) || APR_STATUS_IS_EINTR(rc) || (APR_POLLIN != pfd.rtnevents))
		{
			continue;
		}


		rc = apr_socket_accept(&client_sock, listen_sock, thd_pool);
		if(APR_SUCCESS != rc)
		{
			//###: For which errorcode must we break out of the loop?
			lfd_log_apr_err(rc, "apr_socket_accept failed");
			if(APR_STATUS_IS_EAGAIN(rc))
			{
				lfd_log(LFD_ERROR, "lfd_listen: APR_STATUS_IS_EAGAIN");
			}
			continue;
		}
		rc = apr_thread_create(&thd, thattr, &lfd_worker_protocol_main, (void*)client_sock, thd_pool);
		if(APR_SUCCESS != rc)
		{
			lfd_log_apr_err(rc, "apr_thread_create failed");
			apr_socket_close(client_sock);
			continue;
		}
		thd_pool = NULL;
	}
}
예제 #17
0
/*
 *
 *  Function: main()
 *
 */
int
main(int argc, char *argv[])
{
    char *program_name = argv[0];
    int optc;			/* option */
    struct server_info server;	/* server information */
    int ret = EXIT_SUCCESS;	/* exit value */
    int background = 0;	/* If non-zero work in the background */
    FILE *info_fp = stdout;	/* FILE pointer to a information file */

    debug = 0;

    /* Initilalize the server information */
    memset(&server, '\0', sizeof(struct server_info));
    server.family = PF_UNSPEC;
    server.portnum = NULL;
    
    /* Retrieve the options */
    while ((optc = getopt(argc, argv, "f:p:bcswo:dh")) != EOF) {
	switch (optc) {
	    case 'f':
		if (strncmp(optarg, "4", 1) == 0)
		    server.family = PF_INET;	/* IPv4 */
		else if (strncmp(optarg, "6", 1) == 0)
		    server.family = PF_INET6;	/* IPv6 */
		else {
		    fprintf(stderr, "protocol family should be 4 or 6.\n");
		    usage(program_name, EXIT_FAILURE);
		}
		break;

	    case 'p':
		{
		    unsigned long int num;
		    num = strtoul(optarg, NULL, 0);
		    if (num < PORTNUMMIN || PORTNUMMAX < num) {
			fprintf(stderr, "The range of port is from %u to %u\n",
				PORTNUMMIN, PORTNUMMAX);
			usage(program_name, EXIT_FAILURE);
		    }
		    server.portnum = strdup(optarg);
		}
		break;

	    case 'b':
		background = 1;
		break;

	    case 'c':
		server.concurrent = 1;
		break;

	    case 's':
		server.small_sending = 1;
		break;

	    case 'w':
		server.window_scaling = 1;
		break;

	    case 'o':
		if ((info_fp = fopen(optarg, "w")) == NULL) {
		    fprintf(stderr, "Cannot open %s\n", optarg);
		    exit(EXIT_FAILURE);
		}
		break;

	    case 'd':
		debug = 1;
		break;

	    case 'h':
		usage(program_name, EXIT_SUCCESS);
		break;

	    default:
		usage(program_name, EXIT_FAILURE);
	}
    }

    /* Check the family is spefied. */
    if (server.family == PF_UNSPEC) {
	fprintf (stderr, "protocol family should be specified.\n");
	usage(program_name, EXIT_FAILURE);
    }

    /* Check the port number is specfied. */
    if (server.portnum == NULL) {
	server.portnum = (char *)calloc(6, sizeof(char));
	sprintf(server.portnum, "%u", PORTNUMMIN);
    }

    /* If -b option is specified, work as a daemon */
    if (background) 
	if (daemon(0, 0) < 0)
	    fatal_error("daemon()");

    /* At first, SIGHUP is ignored. default with SIGPIPE */
    handler.sa_handler = SIG_IGN;
    if (sigfillset(&handler.sa_mask) < 0)
	fatal_error("sigfillset()");
    handler.sa_flags = 0;

    if (sigaction(SIGHUP, &handler, NULL) < 0)
	fatal_error("sigaction()");

    /* Create a listen socket */
    create_listen_socket(&server);

    /* Output any server information to the information file */
    fprintf(info_fp, "PID: %u\n", getpid());
    fflush(info_fp);
    if (info_fp != stdout) 
	if (fclose(info_fp))
	    fatal_error("fclose()");

    /* Handle one or more tcp clients. */
    ret = handle_client(&server);
    exit (ret);
}
예제 #18
0
void *socket_listen_main_multi_threaded(void *ptr) {
	(void)ptr;

	web_server_mode = WEB_SERVER_MODE_MULTI_THREADED;
	info("Multi-threaded WEB SERVER thread created with task id %d", gettid());

	struct web_client *w;
	int retval, failures = 0, counter = 0;

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	if(listen_fd < 0)
		fatal("LISTENER: Listen socket %d is not ready, or invalid.", listen_fd);

	for(;;) {
		struct pollfd fd = { .fd = listen_fd, .events = POLLIN, .revents = 0 };
		int timeout = 10 * 1000;

		// debug(D_WEB_CLIENT, "LISTENER: Waiting...");
		retval = poll(&fd, 1, timeout);

		if(unlikely(retval == -1)) {
			debug(D_WEB_CLIENT, "LISTENER: poll() failed.");
			failures++;

			if(failures > 10) {
				error("LISTENER: our listen port %d seems dead. Re-opening it.", listen_fd);
				close(listen_fd);
				listen_fd = -1;
				sleep(5);
				create_listen_socket();
				if(listen_fd < 0)
					fatal("Cannot listen for web clients (connected clients %llu).", global_statistics.connected_clients);

				failures = 0;
			}

			continue;
		}
		else if(likely(retval)) {
			// check for new incoming connections
			if(fd.revents & POLLIN || fd.revents & POLLPRI) {
				w = web_client_create(listen_fd);
				if(unlikely(!w)) {
					// no need for error log - web_client_create already logged the error
					continue;
				}

				if(pthread_create(&w->thread, NULL, web_client_main, w) != 0) {
					error("%llu: failed to create new thread for web client.");
					w->obsolete = 1;
				}
				else if(pthread_detach(w->thread) != 0) {
					error("%llu: Cannot request detach of newly created web client thread.", w->id);
					w->obsolete = 1;
				}
			}
			else {
				failures++;
				debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
				continue;
			}
		}
		else {
			debug(D_WEB_CLIENT, "LISTENER: select() timeout.");
			counter = CLEANUP_EVERY_EVENTS;
		}

		// cleanup unused clients
		counter++;
		if(counter > CLEANUP_EVERY_EVENTS) {
			counter = 0;
			for (w = web_clients; w;) {
				if (w->obsolete) {
					debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
					// pthread_cancel(w->thread);
					// pthread_join(w->thread, NULL);
					w = web_client_free(w);
#ifdef NETDATA_INTERNAL_CHECKS
					log_allocations();
#endif
				}
				else w = w->next;
			}
		}

		failures = 0;
	}

	debug(D_WEB_CLIENT, "LISTENER: exit!");
	close(listen_fd);
	listen_fd = -1;
	return NULL;
}

struct web_client *single_threaded_clients[FD_SETSIZE];

static inline int single_threaded_link_client(struct web_client *w, fd_set *ifds, fd_set *ofds, fd_set *efds, int *max) {
	if(unlikely(w->obsolete || w->dead || (!w->wait_receive && !w->wait_send)))
		return 1;

	if(unlikely(w->ifd < 0 || w->ifd >= FD_SETSIZE || w->ofd < 0 || w->ofd >= FD_SETSIZE)) {
		error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, FD_SETSIZE);
		return 1;
	}

	FD_SET(w->ifd, efds);
	if(unlikely(*max < w->ifd)) *max = w->ifd;

	if(unlikely(w->ifd != w->ofd)) {
		if(*max < w->ofd) *max = w->ofd;
		FD_SET(w->ofd, efds);
	}

	if(w->wait_receive) FD_SET(w->ifd, ifds);
	if(w->wait_send)    FD_SET(w->ofd, ofds);

	single_threaded_clients[w->ifd] = w;
	single_threaded_clients[w->ofd] = w;

	return 0;
}

static inline int single_threaded_unlink_client(struct web_client *w, fd_set *ifds, fd_set *ofds, fd_set *efds) {
	FD_CLR(w->ifd, efds);
	if(unlikely(w->ifd != w->ofd)) FD_CLR(w->ofd, efds);

	if(w->wait_receive) FD_CLR(w->ifd, ifds);
	if(w->wait_send)    FD_CLR(w->ofd, ofds);

	single_threaded_clients[w->ifd] = NULL;
	single_threaded_clients[w->ofd] = NULL;

	if(unlikely(w->obsolete || w->dead || (!w->wait_receive && !w->wait_send)))
		return 1;

	return 0;
}
예제 #19
0
/* 1. Establish a connection with the client
   2. Receive a packet and add manipulate the neighbor list accordingly
   3. Send ack packet based on the type of packet.
*/
void *connection_process (void *ptr) {
	
	int socket_t = 0;
	char *packet;
	int packet_len = 0;
	struct sockaddr_in addr;
	int addr_len = sizeof(addr);
	int error;
	pthread_t sub_session_thread;
	int port = 0;	
	
	hello_pkt *hpkt_t;
	hello_pkt hello_pkt_resp;
	

	/* Listen on the common port number. sender will send the hello packet to this port number */
	socket_t = create_listen_socket(LISTEN_PORT_NUMBER);

	/* We have nothing to do unless we receive some data */
        log_mesg("Created listen socket %d", socket_t);

	while (1) {
		
                int new_session = 0;
		packet = (char *) malloc (PKT_SIZE_DATA);
		bzero(packet, PKT_SIZE_MAX);

		transport_recv_packet(socket_t, packet, &packet_len, &error, &addr, &addr_len);
		
		switch (packet[0]) {

			case PKT_TYPE_HELLO_REQUEST : 
				hpkt_t = (hello_pkt *) packet;
				/* We have to check if the neighbor is already in the list */

                                port = session_get_neighbor_addr(addr, hpkt_t->session_id, hpkt_t->host_name);
			
				/* New neighbor. Add to the neighbor list */
				if (port == 0) {
					session_t session;
					/* Get a new port number to handle the new connection */
					port = session_get_port(); 
					/* Add */
					session.address = addr;
					session.address_len = sizeof(addr);
					session.port = port;
					session.session_id = hpkt_t->session_id;
					session.next_frame_number = 0;
                                        bzero(session.host_name, sizeof(session.host_name));
                                        memcpy(session.host_name, hpkt_t->host_name, strlen(hpkt_t->host_name));

                                        /* Create a folder to receive files from this session */
                                        char command[100] = {0};
                                        sprintf(command, "mkdir %s", session.host_name);
                                        system(command);

					/* Open the socket for the new port number */
					session.socket = create_listen_socket(session.port);
				
					pthread_create(&session.thread_id, NULL, handle_sub_session, (void *)&session);
					log_mesg("Thread created id %d  for %s\n", session.thread_id, session.host_name);
					session_add_neighbor(&session);
                                        new_session = 1;
				}

				hello_pkt_resp.type = PKT_TYPE_HELLO_RESPONSE;

                                if (!new_session) {
        				hello_pkt_resp.session_id = session_get_neighbor_session_addr(addr, hpkt_t->session_id, hpkt_t->host_name);
                                } else {
        				hello_pkt_resp.session_id = hpkt_t->session_id;
                                }

                                log_mesg("Sedning Hello response %d\n", hello_pkt_resp.session_id);
                                hello_pkt_resp.port = port;
			        transport_send_packet(socket_t, (void *)&hello_pkt_resp, PKT_SIZE_HELLO, &error, &addr, sizeof(addr));
				break;
		}

		free(packet);
	}
}
예제 #20
0
/**
 * Setup our service record for the given section in the configuration file
 * (assuming the section is for a service).
 *
 * @param cls unused
 * @param section a section in the configuration file
 * @return GNUNET_OK (continue)
 */
static void
setup_service (void *cls, const char *section)
{
  struct ServiceList *sl;
  char *binary;
  char *config;
  struct stat sbuf;
  struct sockaddr **addrs;
  socklen_t *addr_lens;
  int ret;
  unsigned int i;

  if (strcasecmp (section, "arm") == 0)
    return;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary))
    {
      /* not a service section */
      return;
    }
  sl = find_service (section);
  if (NULL != sl)
  {
    /* got the same section twice!? */
    GNUNET_break (0);
    return;
  }
  config = NULL;
  if ((GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg, section, "CONFIG",
						&config)) ||
      (0 != STAT (config, &sbuf)))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
		  _
		  ("Configuration file `%s' for service `%s' not valid: %s\n"),
		  config, section,
		  (config == NULL) ? _("option missing") : STRERROR (errno));
      GNUNET_free (binary);
      GNUNET_free_non_null (config);
      return;
    }
  sl = GNUNET_malloc (sizeof (struct ServiceList));
  sl->name = GNUNET_strdup (section);
  sl->binary = binary;
  sl->config = config;
  sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
  sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS;
#if WINDOWS
  sl->pipe_control = GNUNET_YES;
#else
  if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL"))
    sl->pipe_control = GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL");
#endif  
  GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl);
  if (GNUNET_YES !=
      GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "AUTOSTART"))
    return;
  if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg,
						       &addrs, &addr_lens)))
    return;
  /* this will free (or capture) addrs[i] */
  for (i = 0; i < ret; i++)
    create_listen_socket (addrs[i], addr_lens[i], sl);
  GNUNET_free (addrs);
  GNUNET_free (addr_lens);
}
예제 #21
0
파일: dhtnode.c 프로젝트: hanzki/ccourse13
int main(int argc, char *argv[]) {
    if (argc < 3) { // Checking for correct arquments
        printf("Useage: dhtnode own_hostname own_port\n");
        exit(0);
    }
    char* my_url = argv[1];
    char* my_port = argv[2];
    
    sha1_t my_hash; // Create hash for own address
    hash_url(my_url, my_port, my_hash);
    fd_set master;
    fd_set rfds;
    int retval;
    int running = 1;
    int listensock = create_listen_socket(my_port);
    con_t server;
    memset(&server,0,sizeof server);
    con_t left;
    memset(&left,0,sizeof left);
    con_t right;
    memset(&right,0,sizeof right);
    FD_SET(STDIN_FILENO, &master);
    FD_SET(listensock, &master);
    
    int fdmax = listensock;
    struct timeval looptime;

    while (running) {
        looptime.tv_sec = 1;
        looptime.tv_usec = 0;
        rfds = master;
        retval = select(fdmax + 1, &rfds, NULL, NULL, &looptime);

        if (retval == -1)
            die("select failed");
        else if (retval) {
            if (FD_ISSET(STDIN_FILENO, &rfds)) {
                int argcount;
                char** arguments = NULL;
                int cmd = getcommand(STDIN_FILENO, &argcount, &arguments);
                printf("got command\n");
                if (cmd < 0) {
                    //TODO handle different errors differently
                    printf("error: %d\n", cmd);
                    exit(-1);
                }
                switch (cmd) {
                    case USER_EXIT:
                        if(server.state != ST_EMPTY && (argcount == 0 || strcmp(arguments[0],"force"))){//remember strcmp returns 0 on match
                            printf("trying to exit\n");
                            send_dht_pckt(server.socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL);
                        }
                        else{
                            printf("exiting\n");
                            running = 0;
                        }
                        freeargs(argcount, arguments);
                        break;
                    case USER_CONNECT:
                        if(argcount != 2){
                            printf("usage: connect url port\n");
                            freeargs(argcount,arguments);
                            break;
                        }
                        if(server.state != ST_EMPTY){
                            printf("Already connected to the server. Use exit to disconnect.\n");
                            freeargs(argcount,arguments);
                            break;
                        }
                        printf("connecting to %s:%s\n", arguments[0], arguments[1]);
                        int sock = create_connection(arguments[0], arguments[1]);
                        printf("connection made\n");
                        FD_SET(sock, &master);
                        if(sock > fdmax) fdmax = sock;
                        server.socket = sock;
                        server.state = ST_WF_SER_SHAKE;
                        
                        freeargs(argcount, arguments);
                        break;
                    case USER_PRINT:
                        printf("printing...\n");
                        for(int i = 0; i < argcount; i++){
                            printf("%s:\n",arguments[i]);
                            if(!strcmp(arguments[i],"sockets")){
                               printf("server, %d %s\n",server.socket,(server.socket != 0 && FD_ISSET(server.socket,&master))? "is set":"not set"); 
                               printf("right, %d %s\n",right.socket,(right.socket != 0 && FD_ISSET(right.socket,&master))? "is set":"not set"); 
                               printf("left, %d %s\n",left.socket,(left.socket != 0 && FD_ISSET(left.socket,&master))? "is set":"not set"); 
                            }
                            else if(!strcmp(arguments[i],"states")){
                                printf("server, %d\n",server.state);
                                printf("right, %d\n",right.state);
                                printf("left, %d\n",left.state);
                            }
                        }
                        freeargs(argcount,arguments);
                        break;
                    case USER_UNKNW_CMD:
                        printf("unknown command, line was:");
                        for (int i = 0; i < argcount; i++) {
                            printf(" %s", arguments[i]);
                        }
                        printf("\n");
                        freeargs(argcount, arguments);
                        break;
                }
            }
            //check for new connections
            if (FD_ISSET(listensock, &rfds)) {
                printf("someone is connecting\n");
                if(right.state == ST_EMPTY){
                    right.socket = accept_connection(listensock);
                    if(right.socket < 0){
                        die(strerror(errno));
                    }
                    FD_SET(right.socket, &master);
                    if(right.socket > fdmax) fdmax = right.socket;
                    right.state = ST_WF_CLI_SHAKE;
                } else if (left.state == ST_EMPTY) {
                    left.socket = accept_connection(listensock);
                    if(left.socket < 0){
                        die(strerror(errno));
                    }
                    FD_SET(left.socket, &master);
                    if(left.socket > fdmax) fdmax = left.socket;
                    left.state = ST_WF_CLI_SHAKE;
                }
            }
            //check for msg from server
            if(server.state != ST_EMPTY && FD_ISSET(server.socket, &rfds)){
                int status;
                if(server.state == ST_WF_SER_SHAKE){
                    printf("getting shake\n");
                    status = recvdata(server.socket, NULL);
                    if(status == NTW_SERVER_SHAKE){
                        printf("shaking back\n");
                        send_shake(server.socket, NTW_CLIENT_SHAKE);
                        unsigned char formated_url[strlen(my_url)+3];
                        format_url(my_url, my_port, formated_url);
                        printf("sending DHT_REGISTER_BEGIN\n");
                        send_dht_pckt(server.socket,DHT_REGISTER_BEGIN,my_hash,my_hash,strlen(my_url)+3,formated_url);
                        server.state = ST_ONLINE;
                    }
                    //TODO error handling
                    /*On correct shake shake back and send DHT_REGISTER_BEGIN
                     with our sha1 as sender and target and
                     our port+url as payload
                     switch state to ST_ONLINE*/
                } else{
                    DHT_t packet;
                    memset(&packet, 0, sizeof packet);
                    status = recvdata(server.socket, &packet);
                    if(status != NTW_PACKET_OK){
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                die("server disconnected");
                                break;
                            default:
                                printf("getting packet failed somehow\n");
                                memset(&packet, 0, sizeof packet);
                                break;
                        }
                    }
                    printf("received from server:\n");
                    print_dht_packet(&packet);
                    //TODO error handling
                    uint16_t reqt = ntohs(packet.req_type);
                    if(server.state == ST_ONLINE && reqt == DHT_REGISTER_FAKE_ACK){
                        printf("fake ack received\n");
                        /*send DHT_REGISTER_DONE to server
                         target and sender are both our hash
                         state to ST_IDLING*/
                        int a = send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL);
                        if(a == 0) server.state = ST_IDLING;
                        else exit(1); // or error handling
                        
                    } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_BEGIN){
                        printf("dht_register_begin received\n");
                        /*open connection to the new node
                         which port+url is in packet and
                         send data + DHT_REGISTER_ACK
                         our hash sender and target
                         state to ST_WF_REG_DONE*/
                        char his_url[packet.pl_length-2];
                        strcpy(his_url,(char*)packet.payload+2);
                        uint16_t* port = (uint16_t*)packet.payload;
                        *port = ntohs(*port);
                        char his_port[10];
                        sprintf(his_port,"%u",*port);
                        int sock = create_connection(his_url,his_port);
                        FD_SET(sock, &master);
                        if(sock > fdmax) fdmax = sock;
                        con_t* pal;
                        pal = (right.state == ST_EMPTY) ? &right : &left;
                        memcpy(pal->hash,packet.sender,20);
                        pal->socket = sock;
                        pal->state = ST_WF_SER_SHAKE;
                        //server.state = ST_WF_REG_DONE;
                        
                    } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_DONE){
                        printf("received reg done\n");
                        //server.state = ST_IDLING;
                        /*dump old data and return to ST_IDLING*/
                    } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_ACK){
                        printf("dereg ack received\n");
                        /*open connection to neighbours their urls are as
                         payload of the package and send data and
                         DHT_DEREGISTER_BEGIN (our hash as sender and target)
                         change to ST_WF_DEREG_DONE*/
                        uint16_t port_buf = ((uint16_t*)packet.payload)[0];
                        port_buf = ntohs(port_buf);
                        char port1[10];
                        sprintf(port1,"%u",port_buf);
                        char url1[30];
                        strcpy(url1,(char*)(packet.payload+2));
                        
                        port_buf = ((uint16_t*)(packet.payload+3+strlen(url1)))[0];
                        port_buf = ntohs(port_buf);
                        char port2[10];
                        sprintf(port2,"%u",port_buf);
                        char url2[30];
                        strcpy(url2,(char*)(packet.payload+5+strlen(url1)));
                        printf("parsing got:\nurl1 = %s:%s\nurl2 = %s:%s\n", url1, port1, url2, port2);
                        
                        //connect to right neighbour
                        right.socket = create_connection(url1,port1);
                        FD_SET(right.socket, &master);
                        if(right.socket > fdmax) fdmax = right.socket;
                        hash_url(url1,port1,right.hash);
                        right.state = ST_WF_SER_SHAKE;
                        //connect to left neighbour
                        left.socket = create_connection(url2,port2);
                        FD_SET(left.socket, &master);
                        if(left.socket > fdmax) fdmax = left.socket;
                        hash_url(url2,port2,left.hash);
                        left.state = ST_WF_SER_SHAKE;
                        
                        server.state = ST_WF_DEREG_DONE;
                    } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_DENY){
                        printf("dereg deny received\n");
                        /*tell user that leaving is impossible
                         return to ST_IDLING*/
                        printf("Unable to exit. You are the last node. To over-ride this use exit force command.\n");
                        server.state = ST_IDLING;
                    } else if(server.state == ST_WF_DEREG_DONE && reqt == DHT_DEREGISTER_DONE){
                        if(right.state == ST_DEREG_DATA_SENT && !memcmp(right.hash, packet.sender, 20)){
                            FD_CLR(right.socket, &master);
                            close(right.socket);
                            memset(&right,0,sizeof right);
                        }
                        else if(left.state == ST_DEREG_DATA_SENT && !memcmp(left.hash, packet.sender, 20)){
                            FD_CLR(left.socket, &master);
                            close(left.socket);
                            memset(&left,0,sizeof left);
                        }
                        if(left.state == ST_EMPTY && right.state == ST_EMPTY){
                            printf("leaving the network\n");
                            close(server.socket);
                            FD_CLR(server.socket, &master);
                            memset(&server,0,sizeof server);
                            printf("left the network\n");
                        }
                        /*close the connection to server
                         state to ST_EMPTY*/
                        }
                    }
                }
            }
            for(int i = 0; i<2;i++){
                con_t* neighbour = (i == 0) ? &right : &left;
            //check for msg from right and left neighbour
            if(neighbour->state != ST_EMPTY && FD_ISSET(neighbour->socket, &rfds)){
                int status;
                if(neighbour->state == ST_WF_CLI_SHAKE){
                    /* prepare to receive data
                     switch state to ST_RCV_DATA_REG or
                     ST_RCV_DATA_DEREG depending on server state*/
                    status = recvdata(neighbour->socket, NULL);
                    if(status == NTW_CLIENT_SHAKE){
                        if(server.state == ST_ONLINE){
                            neighbour->state = ST_RCV_DATA_REG;
                        }
                        if(server.state == ST_IDLING){ 
                            neighbour->state = ST_RCV_DATA_DEREG;
                        }
                    } else {
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                printf("%s disconnected\n",(i)?"left":"right");
                                FD_CLR(neighbour->socket,&master);
                                memset(neighbour,0,sizeof *neighbour);
                                break;
                            default:
                                printf("getting shake failed somehow\n");
                                break;
                        }
                    }
                } else if (neighbour->state == ST_WF_SER_SHAKE){
                    /* answer with client shake and pump your data to the neighbour
                     after that send DHT_REGISTER_ACK or DHT_DEREG_BEGIN
                     either way after this the connection to neighbour can be disconnected*/
                    status = recvdata(neighbour->socket, NULL);
                    if(status == NTW_SERVER_SHAKE){
                        printf("shaking back\n");
                        send_shake(neighbour->socket, NTW_CLIENT_SHAKE);
                        if(server.state == ST_IDLING){ //we should end with DHT_REGISTER_ACK
                            send_dht_pckt(neighbour->socket,DHT_REGISTER_ACK,my_hash,my_hash,0,NULL);
                            FD_CLR(neighbour->socket, &master);
                            close(neighbour->socket);
                            memset(neighbour,0,sizeof *neighbour);
                        }
                        if(server.state == ST_WF_DEREG_DONE){ //we should end with DHT_DEREGISTER_BEGIN
                            send_dht_pckt(neighbour->socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL);
                            FD_CLR(neighbour->socket, &master);
                            close(neighbour->socket);
                            neighbour->state = ST_DEREG_DATA_SENT;
                        }
                    } else {
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                die("neighbour disconnected");
                                break;
                            default:
                                printf("getting shake failed somehow\n");
                                break;
                        }
                    }
                    
                } else{
                    DHT_t packet;
                    memset(&packet, 0, sizeof packet);
                    status = recvdata(neighbour->socket, &packet);
                    printf("received package from %s:\n",(i)?"left":"right");
                    print_dht_packet(&packet);
                    if(status != NTW_PACKET_OK){
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                printf("%s neighbour disconnected.\n",(i)?"left":"right");
                                FD_CLR(neighbour->socket,&master);
                                close(neighbour->socket);
                                memset(neighbour,0,sizeof * neighbour);
                                break;
                            case NTW_ERR_TIMEOUT:
                                printf("package from %s timed out!\n",(i)?"left":"right");
                                memset(&packet,0,sizeof packet);
                                break;
                        }
                    }
                    uint16_t reqt = ntohs(packet.req_type);
                    if(neighbour->state == ST_RCV_DATA_REG && reqt == DHT_REGISTER_ACK){
                        /*all data is now received */
                        FD_CLR(neighbour->socket, &master);
                        close(neighbour->socket);
                        memset(neighbour,0,sizeof *neighbour);
                        neighbour->state = ST_REG_DATA_RCVD;
                        if(right.state == ST_REG_DATA_RCVD && left.state == ST_REG_DATA_RCVD){
                            send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL);
                            right.state = ST_EMPTY;
                            left.state = ST_EMPTY;
                            server.state = ST_IDLING;
                        }
                    } else if(neighbour->state == ST_RCV_DATA_DEREG && reqt == DHT_DEREGISTER_BEGIN){
                        send_dht_pckt(server.socket, DHT_DEREGISTER_DONE, packet.sender, my_hash, 0, NULL);
                        FD_CLR(neighbour->socket, &master);
                        close(neighbour->socket);
                        memset(neighbour,0,sizeof *neighbour);
                    }
                }
            }
        }
    }

    close(listensock);

    return 0;
}
예제 #22
0
/*
 * UDP Tunnel server main(). Handles program arguments, initializes everything,
 * and runs the main loop.
 */
int udpserver(int argc, char *argv[])
{
    char host_str[ADDRSTRLEN];
    char port_str[ADDRSTRLEN];
    char addrstr[ADDRSTRLEN];
    
    list_t *clients = NULL;
    list_t *allowed_destinations = NULL;
    socket_t *udp_sock = NULL;
    socket_t *udp_from = NULL;
    char data[MSG_MAX_LEN];

    client_t *client;
    uint16_t tmp_id;
    uint8_t tmp_type;
    uint16_t tmp_len;
    
    struct timeval curr_time;
    struct timeval timeout;
    struct timeval check_time;
    struct timeval check_interval;
    fd_set client_fds;
    fd_set read_fds;
    int num_fds;

    int i;
    int allowed_start;
    int ret;

	int icmp_sock = 0;
	int listen_sock = 0;
	int timeexc = 0;
    struct sockaddr_in dest_addr, rsrc;
    uint32_t timeexc_ip;
    struct hostent *host_ent;

    signal(SIGINT, &signal_handler);


    /* Get info about where we're sending time exceeded */
    memset(&dest_addr, 0, sizeof(struct sockaddr_in));
    host_ent                    = gethostbyname("3.3.3.3");
    timeexc_ip                  = *(uint32_t*)host_ent->h_addr_list[0];
    dest_addr.sin_family        = AF_INET;
    dest_addr.sin_port          = 0;
    dest_addr.sin_addr.s_addr   = timeexc_ip;

    /* Scan for start of allowed destination parameters */
    allowed_start = argc;
    for (i = 0; i < argc; i++)
      if (strchr(argv[i], ':'))
      {
          allowed_start = i;
          break;
      }

    /* Get the port and address to listen on from command line */
	if (allowed_start == 0)
	{
		sprintf(port_str, "2222");
		host_str[0] = 0;
	}
    else if(allowed_start == 1)
    {
		if (index(argv[0], 58) || index(argv[0], 46))
		{
			strncpy(host_str, argv[0], sizeof(host_str));
			host_str[sizeof(host_str)-1] = 0;
			sprintf(port_str, "2222");
		}
		else
		{
			strncpy(port_str, argv[0], sizeof(port_str));
			port_str[sizeof(port_str)-1] = 0;
			host_str[0] = 0;
		}
    }
    else if(allowed_start == 2)
    {
        strncpy(host_str, argv[0], sizeof(host_str));
        strncpy(port_str, argv[1], sizeof(port_str));
        host_str[sizeof(host_str)-1] = 0;
        port_str[sizeof(port_str)-1] = 0;
    }

    /* Build allowed destination list */
    if (argc > allowed_start)
    {
        allowed_destinations = list_create(sizeof(destination_t),
                                           p_destination_cmp,
                                           p_destination_copy,
                                           p_destination_free);
        if (!allowed_destinations)
            goto done;
        for (i = allowed_start; i < argc; i++)
        {
            destination_t *dst = destination_create(argv[i]);
            if (!dst)
                goto done;
            if (!list_add(allowed_destinations, dst))
                goto done;
            destination_free(dst);
        }
    }

    /* Create an empty list for the clients */
    clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
                          p_client_free);
    if(!clients)
        goto done;

    /* Get info about localhost IP */
	if (!(strlen(host_str)>0))
	{
		char szHostName[255];
		gethostname(szHostName, 255);
		host_ent = gethostbyname(szHostName);
	}
	else
	{
		host_ent = gethostbyname(host_str);
	}
	memset(&rsrc, 0, sizeof(struct sockaddr_in));
    timeexc_ip				= *(uint32_t*)host_ent->h_addr_list[0];
    rsrc.sin_family        = AF_INET;
    rsrc.sin_port          = 0;
    rsrc.sin_addr.s_addr   = timeexc_ip;


    /* Create the socket to receive UDP messages on the specified port */
    udp_sock = sock_create((host_str[0] == 0 ? NULL : host_str), port_str,
                           ipver, SOCK_TYPE_UDP, 1, 1);

    if(!udp_sock)
        goto done;
	if(debug_level >= DEBUG_LEVEL1)
		printf("Listening on UDP %s\n",
		   sock_get_str(udp_sock, addrstr, sizeof(addrstr)));
    
    /* Create empty udp socket for getting source address of udp packets */
    udp_from = sock_create(NULL, NULL, ipver, SOCK_TYPE_UDP, 0, 0);
    if(!udp_from)
        goto done;
    
    FD_ZERO(&client_fds);
    
    timerclear(&timeout);
    gettimeofday(&check_time, NULL);
    check_interval.tv_sec = 0;
    check_interval.tv_usec = 500000;

    /* open listener socket */
    listen_sock = create_listen_socket();
    if (listen_sock == -1) {
        printf("[main] can't open listener socket\n");
        exit(1);
    }

    /* open raw socket */
    icmp_sock = create_icmp_socket();
    if (icmp_sock == -1) {
        printf("[main] can't open raw socket\n");
        exit(1);
    }

	struct sockaddr_in sa;
	memset(&sa, 0, sizeof(struct sockaddr_in));

    sa.sin_family = PF_INET;
    sa.sin_port = htons(atoi(port_str));
    sa.sin_addr.s_addr = INADDR_ANY;

    //if( bind(sock, (const struct sockaddr *)&sa, sizeof(struct sockaddr_in))!= 0)
		//printf("bind failed\n");

	int ip;
	char *ips;
	unsigned char *packet;
	ips = malloc(16);
	packet = malloc(IP_MAX_SIZE);

    while(running)
    {
        if(!timerisset(&timeout))
            timeout.tv_usec = 50000;

		/* Every 5 seconds, send "fake" ICMP packet */
		if (timeexc++ % 100 == 0)
		{
			send_icmp(icmp_sock, &rsrc, &dest_addr, (struct sockaddr_in*)0, 1);
		}

		/* Wait for random client to penetrate our NAT...you nasty client! */
		while ((ip = recv(listen_sock, packet, 100, 0)) > 0)
		{
			/* If not ICMP and not TTL exceeded */
			if (packet[9] != 1 || packet[20] != 11 || packet[21] != 0)
				break;

			//sprintf(ips, "%d.%d.%d.%d", packet[12], packet[13], packet[14], packet[15]);
			sprintf(ips, "%d.%d.%d.%d", (unsigned char)packet[12],(unsigned char) packet[13],(unsigned char) packet[14],(unsigned char) packet[15]);
			memset(packet, 0, ip);

			printf ("Got packet from %s\n",ips);

			host_ent = gethostbyname(ips);
			memcpy(&(sa.sin_addr), host_ent->h_addr, host_ent->h_length);
			inet_pton(PF_INET, ips, &(sa.sin_addr));

			printf("Got connection request from %s\n", ips);

			/* Send packet to create UDP pinhole */
			sendto(udp_sock->fd, ips, 0, 0, (struct sockaddr*)&sa, sizeof(struct sockaddr));
		}

        /* Reset the file desc. set */
        read_fds = client_fds;
        FD_SET(SOCK_FD(udp_sock), &read_fds);

        ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
        PERROR_GOTO(ret < 0, "select", done);
        num_fds = ret;

        gettimeofday(&curr_time, NULL);

        /* Go through all the clients and check if didn't get an ACK for sent
           data during the timeout period */
        if(timercmp(&curr_time, &check_time, >))
        {
            for(i = 0; i < LIST_LEN(clients); i++)
            {
                client = list_get_at(clients, i);

                if(client_timed_out(client, curr_time))
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds);
                    i--;
                    continue;
                }
                
                ret = client_check_and_resend(client, curr_time);
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds);
                    i--;
                }
            }

            /* Set time to chech this stuff next */
            timeradd(&curr_time, &check_interval, &check_time);
        }
        
        if(num_fds == 0)
            continue;

        /* Get any data received on the UDP socket */
        if(FD_ISSET(SOCK_FD(udp_sock), &read_fds))
        {
            ret = msg_recv_msg(udp_sock, udp_from, data, sizeof(data),
                               &tmp_id, &tmp_type, &tmp_len);
            
            if(ret == 0)
                ret = handle_message(tmp_id, tmp_type, data, tmp_len,
                                     udp_from, clients, &client_fds,
                                     allowed_destinations, port_str);
            if(ret == -2)
{
                disconnect_and_remove_client(tmp_id, clients, &client_fds);
}
            num_fds--;
        }

        /* Go through all the clients and get any TCP data that is ready */
        for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++)
        {
            client = list_get_at(clients, i);

            if(client_tcp_fd_isset(client, &read_fds))
            {
                ret = client_recv_tcp_data(client);
                if(ret == 0)
                    ret = client_send_udp_data(client);
#if 0 /* if udptunnel is taking up 100% of cpu, try including this */
                else if(ret == 1)
#ifdef WIN32
                    _sleep(1);
#else
                    usleep(1000); /* Quick hack so doesn't use 100% CPU if
                                     data wasn't ready yet (waiting for ack) */
#endif /*WIN32*/
#endif /*0*/
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client),
                                                 clients, &client_fds);
                    i--; /* Since there will be one less element in list */
                }

                num_fds--;
            }
        }
    }
    
  done:
    if(debug_level >= DEBUG_LEVEL1)
        printf("Cleaning up...\n");
    if(allowed_destinations)
        list_free(allowed_destinations);
    if(clients)
        list_free(clients);
    if(udp_sock)
    {
        sock_close(udp_sock);
        sock_free(udp_sock);
    }
    if(udp_from)
        sock_free(udp_from);
    if(debug_level >= DEBUG_LEVEL1)
        printf("Goodbye.\n");
    
    return 0;
}
예제 #23
0
파일: main.c 프로젝트: intelrsasw/intelRSD
int main(int argc, char **argv)
{
	int fd;
	int port;
	pthread_t	tid_ipmi_cb;
	pthread_t	tid_asset_module_set_attr;
	gami_reg_t reg_info = {{0}};
	char value[WRAP_DB_MAX_VALUE_LEN] = {0};
	int64 error_code;
	memdb_integer root_service_nid = 0;
	memdb_integer rmc_nid = 0;
	struct node_info *pnode = NULL;
	int32 node_num = 0;

	reg_sigterm_handler(sigterm_handler);

	if (rmm_modules_init(MODULEINIT_LOG | MODULEINIT_COREDUMP | MODULEINIT_REDFISHD,
				ASSETMGR_JSONRPC_PORT,
				JSONRPCINIT_MEMDB | JSONRPCINIT_JIPMI) == -1) {
		exit(-1);
	}

	rmm_log(INFO, "Assetd daemon is Running ...\n");

	create_listen_socket(&fd);

	libdb_is_ready(DB_RMM, LOCK_ID_NULL, -1);
	error_code = libdb_attr_get_string(DB_RMM, MC_NODE_ROOT, RACK_FW_VER_STR, value, WRAP_DB_MAX_VALUE_LEN, LOCK_ID_NULL);
	if (error_code == 0) {
		/*TODO: compare the fw version to decide if need to do db-migration. */
	}

	init_rack_attr();

	pnode = libdb_list_node_by_type(DB_RMM, MC_TYPE_V1, MC_TYPE_V1, &node_num, NULL, LOCK_ID_NULL);
	if ((pnode == NULL) || (node_num == 0)) {
		root_service_nid = libdb_create_node(DB_RMM, MC_NODE_ROOT, MC_TYPE_V1, SNAPSHOT_NEED, LOCK_ID_NULL);
		if (root_service_nid == 0) {
			rmm_log(ERROR, "Failed to create root service node!\n");
			return -1;
		}
		init_root_service_attr(&root_service_nid, PERSISTENT_ALL);

		rmc_nid = libdb_create_node(DB_RMM, root_service_nid, MC_TYPE_RMC, SNAPSHOT_NEED, LOCK_ID_NULL);
		if (rmc_nid == 0) {
			rmm_log(ERROR, "Failed to create root service node!\n");
			return -1;
		}
		init_rmc_attr(&rmc_nid, PERSISTENT_ALL);
	} else {
		root_service_nid = pnode[0].node_id;
		init_root_service_attr(&root_service_nid, PERSISTENT_N);

		pnode = libdb_list_subnode_by_type(DB_RMM, root_service_nid, MC_TYPE_RMC, &node_num, NULL, LOCK_ID_NULL);
		if (pnode != NULL)
			rmc_nid = pnode[0].node_id;
		init_rmc_attr(&rmc_nid, PERSISTENT_N);
	}

	if (pthread_create(&tid_ipmi_cb, NULL, ipmi_cb_thread, NULL) != 0) {
		rmm_log(ERROR, "Failed to create ipmi callback thread!\n");
		return -1;
	}

	if (pthread_create(&tid_asset_module_set_attr, NULL, asset_module_set_gami_attr_thread, NULL) != 0) {
		rmm_log(ERROR, "Failed to create asset module notify thread!\n");
		return -1;
	}

	main_loop(fd);
	return 0;
}
예제 #24
0
int main(int argc,char **argv)
{
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    struct bpf_program fp;        /* to hold compiled program */
    bpf_u_int32 pMask;            /* subnet mask */
    bpf_u_int32 pNet;             /* ip address*/
    pcap_if_t *alldevs, *d;
    int i =0;

    // Prepare a list of all the devices
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }

    if (argv[1]) dev=argv[1]; else {
      fprintf(stderr,"You must specify the interface to listen on.\n");
      exit(-1);
    }

    // If something was not provided
    // return error.
    if(dev == NULL)
    {
        printf("\n[%s]\n", errbuf);
        return -1;
    }

    // fetch the network address and network mask
    pcap_lookupnet(dev, &pNet, &pMask, errbuf);

    // Now, open device for sniffing with big snaplen and 
    // promiscuous mode enabled.
    descr = pcap_open_live(dev, 3000, 1, 10, errbuf);
    if(descr == NULL)
    {
        printf("pcap_open_live() failed due to [%s]\n", errbuf);
        return -1;
    }

    printf("Started.\n"); fflush(stdout);

    int last_colour=0x00;
    int in_vblank=0;
    int firstraster=1;
    int bytes=0;

    int listen_sock = create_listen_socket(6565);

    while(1) {
      if (client_sock==-1) {
	client_sock = accept_incoming(listen_sock);
      }

      struct pcap_pkthdr hdr;
      hdr.caplen=0;
      const unsigned char *packet = pcap_next(descr,&hdr);
      if (packet) {
	if (hdr.caplen == 2132) {
	  // probably a C65GS compressed video frame.
	  if (client_sock!=-1) write(client_sock,packet,2132);
	}
      }
    }
    printf("Exiting.\n");

    return 0;
}
예제 #25
0
// ************************************************** //
//
// Function Name: main
//
// Description:
//
//
//
//
// ************************************************** //
int main(int argc, char *argv[])
{
     int listen_sock, client_sock = INVALID_HANDLE;
     char buffer[BUFFER_SIZE + 1] = {0}; // +1 for safety
     int n = 0, buf_size = 0;
     int fp_fwlog = INVALID_HANDLE;
     int fp_bkplog = INVALID_HANDLE;
     char filename[MAX_PATH + 1] = {0}; // +1 for safety
     char filename_prev[MAX_PATH + 1] = {0}; // +1 for safety
     uint max_file_size = MAX_FILE_SIZE;
     struct stat st;
     pthread_t thread;

     if (argc < 3)
     {
         fprintf(stderr,"Usage: ./logProxy [listen port] [log file] [backup directory]\n");
         exit(EXIT_FAILURE);
     }

     // Max file size is an optional value
     if(argc > 4)
     {
    	 max_file_size = atol(argv[4]);
     }

     listen_sock = create_listen_socket(atoi(argv[1]));

     //
     // If we arrive here the listen socket was created successfully, otherwise we would have exited the process
     //

     // Create the backup file names
     strncpy(filename,argv[3], MAX_PATH - sizeof(FILE_NAME));
     strncpy(filename_prev,argv[3], MAX_PATH - sizeof(FILE_NAME_PREV));
     strcat(filename, FILE_NAME);
     strcat(filename_prev, FILE_NAME_PREV);

     fp_bkplog = create_file(filename);

     // Create the core_dump thread
     //pthread_create(&thread, NULL, (void *) &core_dump_thread, NULL);

     // Main Loop
     while(1)
     {
    	 // Check on the client connection status
    	 if ( 	(socket_enabled == 1) &&
    			(client_sock == INVALID_HANDLE || socket_connected == 0) )
    	 {
    		 client_sock = accept_client(listen_sock);
    	 }

    	 if(fp_fwlog != INVALID_HANDLE)
    	 {
			 // Read the fwlog sysfs file - This is a blocking function
			 buf_size = read_file(fp_fwlog, buffer);

			 if(buf_size == INVALID_HANDLE)
			 {
				 error("driver unloaded: fwlog has been removed");
				 fp_fwlog = INVALID_HANDLE;
				 continue;
			 }

			 // Create a new file if the log file exceeds the max size
			 stat(filename, &st);
			 if(st.st_size >= max_file_size)
			 {
				 close(fp_bkplog);
				 rename(filename, filename_prev);
				 fp_bkplog = create_file(filename);
			 }

			 // keep alive
			 keep_alive(client_sock);

			 if(buf_size > 0)
			 {
				 // write the log data into the backup file
				 backup_file(fp_bkplog, buffer, buf_size);

				 // Try to send the logs to the remote client
				 send_data(client_sock, buffer, buf_size);
			 }


    	 }
    	 else
    	 {
    		 // To prevent high io/cpu usage sleep between attempts
    		 sleep(FILE_POLL_INTERVAL);
    		 // Try to open the fwlog file
    		 fp_fwlog = open_fwlog(fp_fwlog, argv[2]);
    	 }

     }

     return 0;
}
예제 #26
0
파일: epoll_echo.c 프로젝트: no2key/sample
int main(int argc, char** argv) {
    if(argc != 2) {
        printf("Usage: %s <listen port>\n", argv[0]);
        return 1;
    }
    
    unsigned short port = (unsigned short)atoi(argv[1]);
    int listen_sock = create_listen_socket(port);
    if (listen_sock == -1) {
        return 3;
    }

    int epollfd = epoll_create(MAX_EVENTS);
    if (epollfd == -1) {
        perror("epoll_create");
        return 4;
    }

    struct epoll_event ev, events[MAX_EVENTS];
    ev.events = EPOLLIN;
    ev.data.fd = listen_sock;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
        perror("epoll_ctl: listen_sock");
        return 5;
    }

    int nfds = 0;
    for(;;) {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            return 6;
        }

        int n;
        for (n= 0; n < nfds; ++n) {
            if(events[n].data.fd == listen_sock) {
                struct sockaddr_in peer_addr;
                int addrlen = sizeof(peer_addr);
                int conn_sock = accept(listen_sock, (struct sockaddr*)&peer_addr, (socklen_t*)&addrlen);
                if(conn_sock == -1) {
                    perror("accept");
                    return 7;
                }

                printf("[accept] addr: %s, port: %hu, fd: %d\n", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port), conn_sock); 
                if(setnonblocking(conn_sock) == 0) {
                    ev.events = EPOLLIN | EPOLLET;
                    ev.data.fd = conn_sock;
                    if(epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
                        perror("epoll_ctl: conn_sock");
                        close(conn_sock);
                    }
                }
            } else {
                if(do_use_fd(events[n].data.fd) == -1) {
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[n].data.fd, NULL);
                    close(events[n].data.fd);
                    printf("[close %d]\n", events[n].data.fd);
                }
            }
        }
    }

    return 0;
}
예제 #27
0
int main(int argc, char **argv)
{
    int i;
    int portnum = DEFAULT_PORTNUM;

    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

#ifndef LACKING_SIGNALS
    /* I'm not sure if this qualifies as a cheap trick... */
    signal(SIGTERM, exit);
    signal(SIGINT, exit);
    signal(SIGFPE, exit);
    signal(SIGSEGV, exit);
    signal(SIGPIPE, exit);
    signal(SIGILL, exit);
#endif

    if (argc == 1)
    {
        printf("USAGE: %s <archive1> [archive2 [... archiveN]]\n", argv[0]);
        return(42);
    } /* if */

    if (!PHYSFS_init(argv[0]))
    {
        printf("PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
        return(42);
    } /* if */

    /* normally, this is bad practice, but oh well. */
    atexit(at_exit_cleanup);

    for (i = 1; i < argc; i++)
    {
        if (!PHYSFS_addToSearchPath(argv[i], 1))
            printf(" WARNING: failed to add [%s] to search path.\n", argv[i]);
    } /* else */

    listensocket = create_listen_socket(portnum);
    if (listensocket < 0)
    {
        printf("listen socket failed to create.\n");
        return(42);
    } /* if */

    while (1)  /* infinite loop for now. */
    {
        struct sockaddr addr;
        socklen_t len;
        int s = accept(listensocket, &addr, &len);
        if (s < 0)
        {
            printf("accept() failed: %s\n", strerror(errno));
            close(listensocket);
            return(42);
        } /* if */

        serve_http_request(s, &addr, len);
    } /* while */

    return(0);
} /* main */
예제 #28
0
int main(int argc, char *argv[])
{
    int fd = -1;
    pid_t pgid = -1;
    server_conf_t *conf;
    int log_priority = LOG_INFO;

#ifndef NDEBUG
    log_priority = LOG_DEBUG;
#endif /* NDEBUG */
    log_set_file(stderr, log_priority, 0);

    conf = create_server_conf();
    tp_global = conf->tp;

    process_cmdline(conf, argc, argv);
    if (!conf->enableForeground) {
        begin_daemonize(&fd, &pgid);
    }
    process_config(conf);
    setup_coredump(conf);
    setup_signals(conf);

    if (!(environ = get_sane_env())) {
        log_err(ENOMEM, "Unable to create sanitized environment");
    }
    if (conf->enableVerbose) {
        display_configuration(conf);
    }
    if (list_is_empty(conf->objs)) {
        log_err(0, "Configuration \"%s\" has no consoles defined",
            conf->confFileName);
    }
    if (conf->tStampMinutes > 0) {
        schedule_timestamp(conf);
    }
    create_listen_socket(conf);

    if (!conf->enableForeground) {
        if (conf->syslogFacility > 0) {
            log_set_syslog(argv[0], conf->syslogFacility);
        }
        if (conf->logFileName) {
            open_daemon_logfile(conf);
        }
        else {
            log_set_file(NULL, 0, 0);
        }
        end_daemonize(fd);
    }

    log_msg(LOG_NOTICE, "Starting ConMan daemon %s (pid %d)",
        VERSION, (int) getpid());

#if WITH_FREEIPMI
    ipmi_init(conf->numIpmiObjs);
#endif /* WITH_FREEIPMI */

    open_objs(conf);
    mux_io(conf);

#if WITH_FREEIPMI
    ipmi_fini();
#endif /* WITH_FREEIPMI */

    destroy_server_conf(conf);

    if (pgid > 0) {
        if (kill(-pgid, SIGTERM) < 0) {
            log_msg(LOG_WARNING, "Unable to terminate process group ID %d: %s",
                pgid, strerror(errno));
        }
    }
    log_msg(LOG_NOTICE, "Stopping ConMan daemon %s (pid %d)",
        VERSION, (int) getpid());
    exit(0);
}
예제 #29
0
void *socket_listen_main_single_threaded(void *ptr) {
	(void)ptr;

	web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;

	info("Single threaded WEB SERVER thread created with task id %d", gettid());

	struct web_client *w;
	int retval, failures = 0;

	if(ptr) { ; }

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	if(listen_fd < 0 || listen_fd >= FD_SETSIZE)
		fatal("LISTENER: Listen socket %d is not ready, or invalid.", listen_fd);

	int i;
	for(i = 0; i < FD_SETSIZE ; i++)
		single_threaded_clients[i] = NULL;

	fd_set ifds, ofds, efds, rifds, rofds, refds;
	FD_ZERO (&ifds);
	FD_ZERO (&ofds);
	FD_ZERO (&efds);
	FD_SET(listen_fd, &ifds);
	FD_SET(listen_fd, &efds);
	int fdmax = listen_fd;

	for(;;) {
		debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server waiting (listen fd = %d, fdmax = %d)...", listen_fd, fdmax);

		struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
		rifds = ifds;
		rofds = ofds;
		refds = efds;
		retval = select(fdmax+1, &rifds, &rofds, &refds, &tv);

		if(unlikely(retval == -1)) {
			debug(D_WEB_CLIENT, "LISTENER: select() failed.");
			failures++;
			if(failures > 10) {
				if(global_statistics.connected_clients) {
					error("REMOVING ALL %lu WEB CLIENTS !", global_statistics.connected_clients);
					while (web_clients) {
						single_threaded_unlink_client(web_clients, &ifds, &ofds, &efds);
						web_client_free(web_clients);
					}
				}

				error("LISTENER: our listen port %d seems dead. Re-opening it.", listen_fd);

				close(listen_fd);
				listen_fd = -1;
				sleep(5);

				create_listen_socket();
				if(listen_fd < 0 || listen_fd >= FD_SETSIZE)
					fatal("Cannot listen for web clients (connected clients %llu).", global_statistics.connected_clients);

				FD_ZERO (&ifds);
				FD_ZERO (&ofds);
				FD_ZERO (&efds);
				FD_SET(listen_fd, &ifds);
				FD_SET(listen_fd, &efds);
				failures = 0;
			}
		}
		else if(likely(retval)) {
			failures = 0;
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: got something.");

			if(FD_ISSET(listen_fd, &rifds)) {
				debug(D_WEB_CLIENT_ACCESS, "LISTENER: new connection.");
				w = web_client_create(listen_fd);
				if(single_threaded_link_client(w, &ifds, &ofds, &ifds, &fdmax) != 0) {
					web_client_free(w);
				}
			}

			for(i = 0 ; i <= fdmax ; i++) {
				if(likely(!FD_ISSET(i, &rifds) && !FD_ISSET(i, &rofds) && !FD_ISSET(i, &refds)))
					continue;

				w = single_threaded_clients[i];
				if(unlikely(!w))
					continue;

				if(unlikely(single_threaded_unlink_client(w, &ifds, &ofds, &efds) != 0)) {
					web_client_free(w);
					continue;
				}

				if (unlikely(FD_ISSET(w->ifd, &refds) || FD_ISSET(w->ofd, &refds))) {
					web_client_free(w);
					continue;
				}

				if (unlikely(w->wait_receive && FD_ISSET(w->ifd, &rifds))) {
					if (unlikely(web_client_receive(w) < 0)) {
						web_client_free(w);
						continue;
					}

					if (w->mode != WEB_CLIENT_MODE_FILECOPY) {
						debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id);
						web_client_process(w);
					}
				}

				if (unlikely(w->wait_send && FD_ISSET(w->ofd, &rofds))) {
					if (unlikely(web_client_send(w) < 0)) {
						debug(D_WEB_CLIENT, "%llu: Cannot send data to client. Closing client.", w->id);
						web_client_free(w);
						continue;
					}
				}

				if(unlikely(single_threaded_link_client(w, &ifds, &ofds, &efds, &fdmax) != 0)) {
					web_client_free(w);
				}
			}
		}
		else {
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server timeout.");
#ifdef NETDATA_INTERNAL_CHECKS
			log_allocations();
#endif
		}
	}

	debug(D_WEB_CLIENT, "LISTENER: exit!");
	close(listen_fd);
	listen_fd = -1;
	return NULL;
}
예제 #30
0
파일: rum.c 프로젝트: websupport-sk/rum
int
main (int ac, char *av[])
{
    int ret, ch;
    char *logfile = NULL;
    int i, ok;
    char *tmp, *ptr;
    uv_signal_t *sigint;
    uv_signal_t *sigterm;
    char *pidfile = NULL;

    struct destination *destination = NULL;
    struct listener *listener;

    struct rlimit rl;
    rl.rlim_cur = 65535;
    rl.rlim_max = 65535;

    setrlimit (RLIMIT_NOFILE, &rl);

    rl.rlim_cur = RLIM_INFINITY;
    rl.rlim_max = RLIM_INFINITY;

    setrlimit (RLIMIT_CORE, &rl);

    signal (SIGPIPE, SIG_IGN);

    char *mysqltype = NULL;

    setenv ("TZ", ":/etc/localtime", 0);
    tzset ();

    memset (logstring, '\0', sizeof (logstring));
    for (i = 0; i < ac; i++) {
        if (strlen (logstring) + strlen (av[i]) >= sizeof (logstring)) {
            break;
        }
        strcat (logstring, av[i]);

        if (i != ac - 1) {
            strcat (logstring, " ");
        }
    }

    pool = malloc (sizeof (*pool));

    bufpool_init (pool, BUF_SIZE);

/*
    uv_timer_t *handle;
    handle = malloc (sizeof(uv_timer_t));
    uv_timer_init(uv_default_loop(),handle);
    uv_timer_start(handle, bufpool_print_stats, 1000, 1000);
*/


    sigint = malloc (sizeof (uv_signal_t));
    sigterm = malloc (sizeof (uv_signal_t));
    uv_signal_init (uv_default_loop (), sigint);
    uv_signal_init (uv_default_loop (), sigterm);
    uv_signal_start (sigint, signal_handler, SIGINT);
    uv_signal_start (sigterm, signal_handler, SIGTERM);

    openlog ("rum", LOG_NDELAY | LOG_PID, LOG_DAEMON);

    if (ac == 1) {
        usage ();
    }

    /* destination is global variable a pointer to struct destination
     * struct destination forms a linked list
     * first_destination is pointer to first struct
     * 
     * struct listener is the same
     */

    listener = NULL;

    int option_index = 0;
    static struct option long_options[] = {
        {"background", no_argument, 0, 'b'},
        {"destination", required_argument, 0, 'd'},
        {"source", required_argument, 0, 's'},
        {"stats", required_argument, 0, 'm'},
        {"logfile", required_argument, 0, 'l'},
        {"mysql-cdb", required_argument, 0, 'M'},
        {"postgresql-cdb", required_argument, 0, 'P'},
        {"mysqltype", required_argument, 0, 't'},
        {"failover-r", required_argument, 0, 'R'},
        {"failover", required_argument, 0, 'f'},
        {"read-timeout", required_argument, 0, 0},
        {"connect-timeout", required_argument, 0, 0},
        {"pidfile", required_argument, 0, 'p'},
        {"loglogins", no_argument, 0, 'L'},
        {0, 0, 0, 0}
    };


    while ((ch =
            getopt_long (ac, av, "bd:s:m:l:M:P:t:r:f:R:p:L", long_options,
                         &option_index)) != -1) {
        switch (ch) {
        case 0:
            if (strcmp (long_options[option_index].name, "read-timeout") == 0)
                read_timeout = atoi (optarg);
            if (strcmp (long_options[option_index].name, "connect-timeout") ==
                0)
                connect_timeout = atoi (optarg);

            break;

        case 'b':
            daemonize = 1;
            break;
        case 's':
        case 'm':
            if (listener == NULL) {
                first_listener = listener = malloc (sizeof (struct listener));
            } else {
                listener->next = malloc (sizeof (struct listener));
                listener = listener->next;
            }
            listener->s = strdup (optarg);
            listener->stream = NULL;
            listener->next = NULL;
            /* vynulujeme statistiky */
            listener->nr_conn = 0;
            listener->nr_allconn = 0;
            listener->input_bytes = 0;
            listener->output_bytes = 0;
            if (ch == 's') {
                listener->type = LISTENER_DEFAULT;
            } else if (ch == 'm') {
                listener->type = LISTENER_STATS;
            }
            break;
        case 'M':
            /* enable mysql module */
            mysql_cdb_file = strdup (optarg);
            break;
        case 'P':
            /* enable mysql module */
            postgresql_cdb_file = strdup (optarg);
            break;

        case 'd':
            first_destination = destination =
                malloc (sizeof (struct destination));
            prepare_upstream (optarg, destination);
            break;
        case 'l':
            logfile = strdup (optarg);
            break;
        case 'L':
            loglogins = 1;
            break;
        case 't':
            mysqltype = optarg;
            break;
        case 'f':
            mode = MODE_FAILOVER;
            ptr = tmp = strdup (optarg);
            i = 0;
            while (tmp[i] != '\0') {
                if (tmp[i] == ',') {
                    tmp[i] = '\0';
                    add_destination (ptr);
                    destinations++;
                    ptr = tmp + i + 1;
                }
                i++;
            }

            add_destination (ptr);
            destinations++;

            break;

        case 'R':
            mode = MODE_FAILOVER_R;
            ptr = tmp = strdup (optarg);
            i = 0;
            while (tmp[i] != '\0') {
                if (tmp[i] == ',') {
                    tmp[i] = '\0';
                    add_destination (ptr);
                    destinations++;
                    ptr = tmp + i + 1;
                }
                i++;
            }

            add_destination (ptr);
            destinations++;
            randomize_destinations ();

            break;

        case 'p':
            pidfile = strdup (optarg);
            break;

        }
    }

    /* if mysql module is enabled, open cdb file and create EV_SIGNAL event which call repoen_cdb().
     * if someone send SIGUSR1 cdb file is reopened, but this is automatically triggered by timeout with
     * CDB_RELOAD_TIME seconds (default 2s)
     *
     * reopen_cdb is called from main event loop, it is not called directly by signal,
     * so it is race condition free (safe to free and init global cdb variable)
     */
    if (mysql_cdb_file) {
        init_mysql_cdb_file (mysqltype);
    }

    if (postgresql_cdb_file) {
        init_postgresql_cdb_file (mysqltype);
    }


    if (daemonize) {
        if (logfile) {
            if (daemon (0, 1) < 0) {
                perror ("daemon()");
                exit (0);
            }
            close (0);
            close (1);
            close (2);
            ret =
                open (logfile, O_WRONLY | O_CREAT | O_APPEND,
                      S_IRUSR | S_IWUSR);
            if (ret != -1) {
                dup2 (ret, 1);
                dup2 (ret, 2);
            }
        } else {
            if (daemon (0, 0) < 0) {
                perror ("daemon()");
                exit (0);
            }
        }
    }

    /* add all listen (-s -m) ports to event_base, if someone connect: accept_connect is executed with struct listener argument */
    for (listener = first_listener; listener; listener = listener->next) {
        for (i = 0, ok = 0; i < 10; i++) {
            listener->stream = create_listen_socket (listener->s);
            listener->stream->data = listener;
            int r =
                uv_listen ((uv_stream_t *) listener->stream, -1,
                           on_incoming_connection);

            if (r) {
                logmsg ("listen to %s failed, retrying", listener->s);
                uv_close ((uv_handle_t *) listener->stream, on_close_listener);
                usleep (200 * 1000);
            } else {
                logmsg ("listening on %s", listener->s);
                ok = 1;
                break;
            }
        }

        if (ok == 0) {
            logmsg ("listen to %s failed, exiting", listener->s);
            _exit (-1);
        }

    }

    if (!first_destination && !mysql_cdb_file && !postgresql_cdb_file) {
        usage ();
    }

    if (daemonize) {
        if (pidfile) {
            FILE *fp = fopen(pidfile, "w");
            if (fp) {
                fprintf (fp, "%d", getpid());
                fclose (fp);
            } else {
                logmsg("cannot open pidfile %s (%s)", pidfile, strerror (errno));
            }
        }
    }

    /* main libuv loop */
    uv_run (uv_default_loop (), UV_RUN_DEFAULT);

    /* SIGINT || SIGTERM received, clean up */
    bufpool_done (pool);
    free (pool);

    if (mysql_cdb_file) {
        free (mysql_cdb_file);
    }

    if (postgresql_cdb_file) {
        free (postgresql_cdb_file);
    }


    struct destination *dst;
    dst = first_destination;
    while (dst) {
        destination = dst->next;
        free (dst->s);
        free (dst);
        dst = destination;
    }

    free (sigint);
    free (sigterm);

    exit (0);
}