Example #1
0
/*
 *  epoll_server()
 *	wait on connections and read data
 */
static void epoll_server(
	const int child,
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name,
	const pid_t ppid)
{
	int efd = -1, sfd = -1, rc = EXIT_SUCCESS;
	int so_reuseaddr = 1;
	int port = opt_epoll_port + child + (max_servers * instance);
	struct sigaction new_action;
	struct epoll_event *events = NULL;
	struct sockaddr *addr = NULL;
	socklen_t addr_len = 0;

	new_action.sa_handler = handle_socket_sigalrm;
	sigemptyset(&new_action.sa_mask);
	new_action.sa_flags = 0;
	if (sigaction(SIGALRM, &new_action, NULL) < 0) {
		pr_fail_err(name, "sigaction");
		rc = EXIT_FAILURE;
		goto die;
	}
	if ((sfd = socket(opt_epoll_domain, SOCK_STREAM, 0)) < 0) {
		pr_fail_err(name, "socket");
		rc = EXIT_FAILURE;
		goto die;
	}
	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr)) < 0) {
		pr_fail_err(name, "setsockopt");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	stress_set_sockaddr(name, instance, ppid,
		opt_epoll_domain, port, &addr, &addr_len);

	if (bind(sfd, addr, addr_len) < 0) {
		pr_fail_err(name, "bind");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (epoll_set_fd_nonblock(sfd) < 0) {
		pr_fail_err(name, "setting socket to non-blocking");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (listen(sfd, SOMAXCONN) < 0) {
		pr_fail_err(name, "listen");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if ((efd = epoll_create1(0)) < 0) {
		pr_fail_err(name, "epoll_create1");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (epoll_ctl_add(efd, sfd) < 0) {
		pr_fail_err(name, "epoll ctl add");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if ((events = calloc(MAX_EPOLL_EVENTS, sizeof(struct epoll_event))) == NULL) {
		pr_fail_err(name, "epoll ctl add");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	do {
		int n, i;

		memset(events, 0, MAX_EPOLL_EVENTS * sizeof(struct epoll_event));
		errno = 0;

		/*
		 * Wait for 100ms for an event, allowing us to
		 * to break out if opt_do_run has been changed
		 */
		n = epoll_wait(efd, events, MAX_EPOLL_EVENTS, 100);
		if (n < 0) {
			if (errno != EINTR) {
				pr_fail_err(name, "epoll_wait");
				rc = EXIT_FAILURE;
				goto die_close;
			}
			break;
		}

		for (i = 0; i < n; i++) {
			if ((events[i].events & EPOLLERR) ||
			    (events[i].events & EPOLLHUP) ||
			    (!(events[i].events & EPOLLIN))) {
				/*
				 *  Error has occurred or fd is not
				 *  for reading anymore.. so reap fd
				 */
				(void)close(events[i].data.fd);
			} else if (sfd == events[i].data.fd) {
				/*
				 *  The listening socket has notification(s)
				 *  pending, so handle incoming connections
				 */
				if (epoll_notification(name, efd, sfd) < 0)
					break;
			} else {
				/*
				 *  The fd has data available, so read it
				 */
				epoll_recv_data(events[i].data.fd);
			}
		}
	} while (opt_do_run && (!max_ops || *counter < max_ops));

die_close:
	if (efd != -1)
		(void)close(efd);
	if (sfd != -1)
		(void)close(sfd);
die:
#ifdef AF_UNIX
	if (addr && (opt_epoll_domain == AF_UNIX)) {
		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
		(void)unlink(addr_un->sun_path);
	}
#endif
	free(events);

	exit(rc);
}
int
main (int argc, char *argv[])
{
    int sfd, s;
    int efd;
    struct epoll_event event;
    struct epoll_event *events;
    
    if (argc != 2)
    {
        fprintf (stderr, "Usage: %s [port]\n", argv[0]);
        exit (EXIT_FAILURE);
    }
    
    sfd = create_and_bind (argv[1]);
    if (sfd == -1)
        abort ();
    
    s = make_socket_non_blocking (sfd);
    if (s == -1)
        abort ();
    
    s = listen (sfd, SOMAXCONN);
    if (s == -1)
    {
        perror ("listen");
        abort ();
    }
    
    efd = epoll_create1 (0);
    if (efd == -1)
    {
        perror ("epoll_create");
        abort ();
    }
    
    event.data.fd = sfd;
    event.events = EPOLLIN | EPOLLET;
    s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
    if (s == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
    
    /* Buffer where events are returned */
    events = calloc (MAXEVENTS, sizeof event);
    
    /* The event loop */
    while (1)
    {
        int n, i;
        
        n = epoll_wait (efd, events, MAXEVENTS, -1);
        for (i = 0; i < n; i++)
        {
            if ((events[i].events & EPOLLERR) ||
                (events[i].events & EPOLLHUP) ||
                (!(events[i].events & EPOLLIN)))
            {
                /* An error has occured on this fd, or the socket is not
                 ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error\n");
                close (events[i].data.fd);
                continue;
            }
            
            else if (sfd == events[i].data.fd)
            {
                /* We have a notification on the listening socket, which
                 means one or more incoming connections. */
                while (1)
                {
                    struct sockaddr in_addr;
                    socklen_t in_len;
                    int infd;
                    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
                    
                    in_len = sizeof in_addr;
                    infd = accept (sfd, &in_addr, &in_len);
                    if (infd == -1)
                    {
                        if ((errno == EAGAIN) ||
                            (errno == EWOULDBLOCK))
                        {
                            /* We have processed all incoming
                             connections. */
                            break;
                        }
                        else
                        {
                            perror ("accept");
                            break;
                        }
                    }
                    
                    s = getnameinfo (&in_addr, in_len,
                                     hbuf, sizeof hbuf,
                                     sbuf, sizeof sbuf,
                                     NI_NUMERICHOST | NI_NUMERICSERV);
                    if (s == 0)
                    {
                        printf("Accepted connection on descriptor %d "
                               "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                    }
                    
                    /* Make the incoming socket non-blocking and add it to the
                     list of fds to monitor. */
                    s = make_socket_non_blocking (infd);
                    if (s == -1)
                        abort ();
                    
                    event.data.fd = infd;
                    event.events = EPOLLIN | EPOLLET;
                    s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                    if (s == -1)
                    {
                        perror ("epoll_ctl");
                        abort ();
                    }
                }
                continue;
            }
            else
            {
                /* We have data on the fd waiting to be read. Read and
                 display it. We must read whatever data is available
                 completely, as we are running in edge-triggered mode
                 and won't get a notification again for the same
                 data. */
                int done = 0;
                
                while (1)
                {
                    ssize_t count;
                    char buf[512];
                    
                    count = read (events[i].data.fd, buf, sizeof buf);
                    if (count == -1)
                    {
                        /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                        if (errno != EAGAIN)
                        {
                            perror ("read");
                            done = 1;
                        }
                        break;
                    }
                    else if (count == 0)
                    {
                        /* End of file. The remote has closed the
                         connection. */
                        done = 1;
                        break;
                    }
                    
                    /* Write the buffer to standard output */
                    handle_client_request(buf, count);
                }
                
                if (done)
                {
                    printf ("Closed connection on descriptor %d\n",
                            events[i].data.fd);
                    
                    /* Closing the descriptor will make epoll remove it
                     from the set of descriptors which are monitored. */
                    close (events[i].data.fd);
                }
            }
        }
    }
    
    free (events);
    
    close (sfd);
    
    return EXIT_SUCCESS;
}
Example #3
0
int fi_ibv_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
		   struct fid_eq **eq, void *context)
{
	struct fi_ibv_eq *_eq;
	struct epoll_event event;
	int ret;

	_eq = calloc(1, sizeof *_eq);
	if (!_eq)
		return -ENOMEM;

	_eq->fab = container_of(fabric, struct fi_ibv_fabric,
				util_fabric.fabric_fid);

	fastlock_init(&_eq->lock);
	ret = dlistfd_head_init(&_eq->list_head);
	if (ret) {
		VERBS_INFO(FI_LOG_EQ, "Unable to initialize dlistfd\n");
		goto err1;
	}

	_eq->epfd = epoll_create1(0);
	if (_eq->epfd < 0) {
		ret = -errno;
		goto err2;
	}

	memset(&event, 0, sizeof(event));
	event.events = EPOLLIN;

	if (epoll_ctl(_eq->epfd, EPOLL_CTL_ADD,
		      _eq->list_head.signal.fd[FI_READ_FD], &event)) {
		ret = -errno;
		goto err3;
	}

	switch (attr->wait_obj) {
	case FI_WAIT_NONE:
	case FI_WAIT_UNSPEC:
	case FI_WAIT_FD:
		_eq->channel = rdma_create_event_channel();
		if (!_eq->channel) {
			ret = -errno;
			goto err3;
		}

		ret = fi_fd_nonblock(_eq->channel->fd);
		if (ret)
			goto err4;

		if (epoll_ctl(_eq->epfd, EPOLL_CTL_ADD, _eq->channel->fd, &event)) {
			ret = -errno;
			goto err4;
		}

		break;
	default:
		ret = -FI_ENOSYS;
		goto err1;
	}

	_eq->flags = attr->flags;
	_eq->eq_fid.fid.fclass = FI_CLASS_EQ;
	_eq->eq_fid.fid.context = context;
	_eq->eq_fid.fid.ops = &fi_ibv_eq_fi_ops;
	_eq->eq_fid.ops = &fi_ibv_eq_ops;

	*eq = &_eq->eq_fid;
	return 0;
err4:
	if (_eq->channel)
		rdma_destroy_event_channel(_eq->channel);
err3:
	close(_eq->epfd);
err2:
	dlistfd_head_free(&_eq->list_head);
err1:
	fastlock_destroy(&_eq->lock);
	free(_eq);
	return ret;
}
Example #4
0
int
main(int argc, char **argv) {
    int n, nfds, res;
    struct itimerspec timerits;
    struct epoll_event events[MAX_EVENTS];
    struct epoll_event timerevent;
    IxpClient* client;
    struct sb sb;

    signals_setup(&quit_handler);

    struct sb_entry sbe_sda = {
        .sbe_path = "/rbar/60_sda",
        .sbe_private = "sda",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    struct sb_entry sbe_sdb = {
        .sbe_path = "/rbar/61_sdb",
        .sbe_private = "sdb",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    struct sb_entry sbe_sdc = {
        .sbe_path = "/rbar/62_sdc",
        .sbe_private = "sdc",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    int epollfd = epoll_create1(EPOLL_CLOEXEC);
    if(epollfd == -1) {
        perror("epoll_create");
        abort();
    }

    int timerfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
    if(timerfd == -1) {
        perror("timerfd_create");
        abort();
    }
    timerevent.events = EPOLLIN;
    timerevent.data.fd = timerfd;
    timerits.it_interval.tv_sec = 0;
    timerits.it_interval.tv_nsec = 250 * 1000 * 1000;
    timerits.it_value.tv_sec = timerits.it_interval.tv_sec;
    timerits.it_value.tv_nsec = timerits.it_interval.tv_nsec;

    client = ixp_nsmount("wmii");
    if(client == NULL) {
        printf("ixp_nsmount: %s\n", ixp_errbuf());
        abort();
    }

    res = epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &timerevent);
    if(res == -1) {
        perror("epoll_ctl");
        abort();
    }
        
    res = timerfd_settime(timerfd, 0, &timerits, NULL);
    if(res == -1) {
        perror("timerfd_settime");
        abort();
    }

    sb_init(&sb, client);
    sb_add(&sb, &sbe_sda);
    sb_add(&sb, &sbe_sdb);
    sb_add(&sb, &sbe_sdc);

    while(1) {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if(nfds == -1) {
		    if(errno != EINTR) {
                perror("epoll_wait");
                abort();
			}
        }

        if(should_quit) {
            break;
        }
        
        for (n = 0; n < nfds; n++) {
            if(events[n].data.fd == timerfd) {
                uint64_t x;
                read(timerfd, &x, sizeof(x));
                sb_update(&sb);
            }
        }
    }

    sb_finish(&sb);

    ixp_unmount(client);

    return 0;
}
int main(int argc, char *argv[])
{
	int listenfd;
	int longindex = 0;
	int c;
	int count  = 1000000;
	pid_t pid = getpid();

	/* Epoll variables */
	struct epoll_event ev;
	int epollfd;

	/* Default settings */
	int addr_family = AF_INET; /* Default address family */
	uint16_t listen_port = 6666;

	/* Support for both IPv4 and IPv6.
	 *  sockaddr_storage: Can contain both sockaddr_in and sockaddr_in6
	 */
	struct sockaddr_storage listen_addr;

	memset(&listen_addr, 0, sizeof(listen_addr));

	/* Parse commands line args */
	while ((c = getopt_long(argc, argv, "c:l:64swv:",
			long_options, &longindex)) != -1) {
		if (c == 0) { /* optional handling "flag" options */
			if (verbose) {
				printf("Flag option %s",
				       long_options[longindex].name);
				if (optarg) printf(" with arg %s", optarg);
				printf("\n");
			}
		}
		if (c == 'c') count       = atoi(optarg);
		if (c == 'l') listen_port = atoi(optarg);
		if (c == '4') addr_family = AF_INET;
		if (c == '6') addr_family = AF_INET6;
		if (c == 'w') write_something = 1;
		if (c == 'v') (optarg) ? verbose = atoi(optarg) : (verbose = 1);
		if (c == '?') return usage(argv);
	}

	if (verbose > 0)
		printf("IP%s TCP listen port %d PID:[%d]\n",
		       (addr_family == AF_INET6) ? "v6":"v4",
		       listen_port, pid);

	/* Socket setup stuff */
	listenfd = Socket(addr_family, SOCK_STREAM, IPPROTO_IP);

	/* Enable use of SO_REUSEPORT for multi-process testing  */
	if (so_reuseport) {
		if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT,
				&so_reuseport, sizeof(so_reuseport))) < 0) {
			printf("ERROR: No support for SO_REUSEPORT\n");
			perror("- setsockopt(SO_REUSEPORT)");
			exit(EXIT_FAIL_SOCKOPT);
		} else if (verbose) {
			printf(" - Enabled SO_REUSEPORT\n");
		}
	}

	/* Setup listen_addr depending on IPv4 or IPv6 address */
	//setup_sockaddr(addr_family, &listen_addr, "0.0.0.0", listen_port);
	if (addr_family == AF_INET) {
		struct sockaddr_in *addr4 = (struct sockaddr_in *)&listen_addr;
		addr4->sin_family      = addr_family;
		addr4->sin_port        = htons(listen_port);
		addr4->sin_addr.s_addr = htonl(INADDR_ANY);
	} else if (addr_family == AF_INET6) {
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&listen_addr;
		addr6->sin6_family= addr_family;
		addr6->sin6_port  = htons(listen_port);
	}

	Bind(listenfd, &listen_addr);

	/* Notice "backlog" limited by: /proc/sys/net/core/somaxconn */
	listen(listenfd, 1024);

	/* Epoll */
	if (use_epoll) {
		epollfd = epoll_create1(0);
		if (epollfd == -1) {
			perror("epoll_create");
			exit(EXIT_FAILURE);
		}

		/* Add listen socket */
		ev.events = EPOLLIN;
		ev.data.fd = listenfd;
		if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) {
			perror(" - epoll_ctl: cannot add listen sock");
			exit(EXIT_FAILURE);
		}

		epoll_connections(epollfd, &ev, listenfd, count);

		close(epollfd);

	} else {
		wait_for_connections(listenfd, count);
	}

	close(listenfd);
	return 0;
}
// receive each one block from all sender
void* ExpandableBlockStreamExchangeEpoll::receiver(void* arg){
	ExpandableBlockStreamExchangeEpoll* Pthis=(ExpandableBlockStreamExchangeEpoll*)arg;

	struct epoll_event event;
	struct epoll_event *events;

	int status;

	/** create epoll **/
	Pthis->epoll_fd_ = epoll_create1(0);
	if (Pthis->epoll_fd_ == -1)
	{
		Pthis->logging_->elog("epoll create error!\n");
		return 0;
	}

	event.data.fd = Pthis->sock_fd;
	event.events = EPOLLIN | EPOLLET;
	status = epoll_ctl(Pthis->epoll_fd_, EPOLL_CTL_ADD, Pthis->sock_fd, &event);
	if (status == -1)
	{
		Pthis->logging_->elog("epoll ctl error!\n");
		return 0;
	}


	events=(epoll_event*)calloc(Pthis->nlowers,sizeof(epoll_event));
	int fd_cur=0;
	ticks start=curtick();
	std::vector<int> finish_times;//in ms
	while(true){
		usleep(1);
		const int event_count = epoll_wait(Pthis->epoll_fd_, events, Pthis->nlowers, -1);
		for (int i = 0; i < event_count; i++)
		{
			if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN)))
			{
				if (errno == EINTR)
				{
					continue;
				}
				Pthis->logging_->elog("[%ld] epoll error,reason:%s\n", Pthis->state.exchange_id_, strerror(errno));
				FileClose(events[i].data.fd);
				std::cout << "in " << __FILE__ << ":" << __LINE__;
				printf("-----for debug:close fd %d.\n", events[i].data.fd);
				continue;
			}
			else if (Pthis->sock_fd == events[i].data.fd)
			{
				/* We have a notification on the listening socket, which means one or more incoming connections.*/
				while (true)
				{
					sockaddr in_addr;
					socklen_t in_len;
					int infd;
					char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

					in_len = sizeof in_addr;
					infd = accept(Pthis->sock_fd, &in_addr, &in_len);
					if (infd == -1)
					{
						if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
						{
							/* all the incoming connections are processed.*/
							break;
						}
						else
						{
							Pthis->logging_->elog("accept error!  ");
							break;
						}
					}
					status=getnameinfo(&in_addr,in_len,hbuf,sizeof(hbuf),sbuf,sizeof(sbuf),NI_NUMERICHOST|NI_NUMERICSERV);
					if(status==0){
						Pthis->logging_->log("[%ld] Accepted connection on descriptor %d (host=%s, port=%s),id=%d\n",Pthis->state.exchange_id_, infd, hbuf, sbuf,Pthis->state.exchange_id_);
						Pthis->lower_ip_array.push_back(hbuf);
						Pthis->lower_sock_fd_to_index[infd]=Pthis->lower_ip_array.size()-1;
						assert(Pthis->lower_ip_array.size()<=Pthis->state.lower_id_list_.size());
					}
					/*Make the incoming socket non-blocking and add it to the list of fds to monitor.*/
					if (!Pthis->SetSocketNonBlocking(infd))
					{
						return 0;
					}
					event.data.fd = infd;
					event.events = EPOLLIN | EPOLLET;
					status = epoll_ctl(Pthis->epoll_fd_, EPOLL_CTL_ADD, infd, &event);
					if (status == -1)
					{
						Pthis->logging_->elog("epoll_ctl");
						return 0;
					}
				}
				continue;
			}
			else
			{
				/* We have data on the fd waiting to be read.*/
				int done = 0;
				while (true)
				{
					int byte_received;

					int socket_fd_index=Pthis->lower_sock_fd_to_index[events[i].data.fd];

					byte_received=read(events[i].data.fd,
					                   (char*)Pthis->block_for_socket_[socket_fd_index]->getBlock()+Pthis->block_for_socket_[socket_fd_index]->GetCurSize(),
					                   Pthis->block_for_socket_[socket_fd_index]->GetRestSize());
					if(byte_received==-1){
						if(errno==EAGAIN){
							/*We have read all the data,so go back to the loop.*/
							break;
						}
						Pthis->logging_->elog("read error!\n");
						done = 1;
					}
					else if (byte_received == 0)
					{
						/* End of file. The remote has closed the connection.*/
						done = 1;
						break;
					}

					/* The data is successfully read.*/

					Pthis->block_for_socket_[socket_fd_index]->IncreaseActualSize(byte_received);
					if (Pthis->block_for_socket_[socket_fd_index]->GetRestSize() > 0)
					{
						/** the current block is not read entirely from the sender, so continue the loop to read.**/
						continue;
					}

					/** a block is completely read. **/

					Pthis->logging_->log("[%ld] The %d-th block is received from Lower[%s]", Pthis->state.exchange_id_, Pthis->debug_received_block[socket_fd_index],
							Pthis->lower_ip_array[socket_fd_index].c_str());
					Pthis->debug_received_block[socket_fd_index]++;

					/** deserialize the data block from sender to the blockstreambase (received_block_stream_) **/
					Pthis->received_block_stream_->deserialize((Block*) Pthis->block_for_socket_[socket_fd_index]);

					/** mark block_for_socket_[socket_fd_index] to be empty so that it can accommodate the subsequent data **/
					Pthis->block_for_socket_[socket_fd_index]->reset();

					/** In the current implementation, a empty block stream means End-Of-File**/
					const bool eof=Pthis->received_block_stream_->Empty();
					if(!eof){
						/** the newly obtained data block is validate, so we insert it into the buffer and post
						 * sem_new_block_or_eof_ so that all the threads waiting for the semaphore continue. **/
						Pthis->buffer->insertBlock(Pthis->received_block_stream_);

						//??? why is all ,not 1
						// multiple threads will still compete with lock
						Pthis->sem_new_block_or_eof_.post(Pthis->number_of_registered_expanded_threads_);
					}
					else
					{
						/** The newly obtained data block is the end-of-file.  **/
						Pthis->logging_->log("[%ld] *****This block is the last one.", Pthis->state.exchange_id_);

						finish_times.push_back((int)getMilliSecond(start));

						/** update the exhausted senders count and post sem_new_block_or_eof_ so that all the
						 * threads waiting for the semaphore continue.
						 **/
						Pthis->nexhausted_lowers++;
						Pthis->sem_new_block_or_eof_.post(Pthis->number_of_registered_expanded_threads_);

						if (Pthis->nexhausted_lowers == Pthis->nlowers)
						{
							/*
							 * When all the exchange lowers are exhausted, notify the buffer
							 * that the input data is completely received.
							 */
							Pthis->buffer->setInputComplete();

							/* print the finish times */
							for(unsigned i=0;i<finish_times.size();i++){
								printf("%d\t",finish_times[i]);
							}
							printf("\t Var:%5.4f\n",get_stddev(finish_times));
						}


						Pthis->logging_->log(
                "[%ld] <<<<<<<<<<<<<<<<nexhausted_lowers=%d>>>>>>>>>>>>>>>>exchange=(%d,%d)",
                Pthis->state.exchange_id_, Pthis->nexhausted_lowers,
                Pthis->state.exchange_id_, Pthis->partition_offset);

						/** tell the sender that all the block are consumed so that the sender can close the socket**/
						Pthis->SendBlockAllConsumedNotification(events[i].data.fd);

						Pthis->logging_->log("[%ld] This notification (all the blocks in the socket buffer are consumed) is send to the lower[%s] exchange=(%d,%d).\n",
								Pthis->state.exchange_id_, Pthis->lower_ip_array[socket_fd_index].c_str(), Pthis->state.exchange_id_, Pthis->partition_offset);


					}
				}
				if (done)
				{
					Pthis->logging_->log("[%ld] Closed connection on descriptor %d[%s]\n", Pthis->state.exchange_id_, events[i].data.fd,
							Pthis->lower_ip_array[Pthis->lower_sock_fd_to_index[events[i].data.fd]].c_str());
					/* Closing the descriptor will make epoll remove it
					 from the set of descriptors which are monitored. */
					FileClose(events[i].data.fd);
				}
			}
		}
	}

}
Example #7
0
int main (int argc, char *argv[])
{
	struct epoll_event event, *events;
	int sfd, s;
	int efd;

	struct stat st;
	char *fifo = "event.fifo";

	if (lstat (fifo, &st) == 0) {
		if ((st.st_mode & S_IFMT) == S_IFREG) {
			errno = EEXIST;
			err_sys("lstat");
			exit (1);
		}
	}

	unlink (fifo);
	if (mkfifo (fifo, 0600) == -1) {
		err_sys("mkfifo");
		exit (1);
	}

	/* Linux pipes are broken, we need O_RDWR instead of O_RDONLY */
	sfd = open (fifo, O_RDWR | O_NONBLOCK, 0);

	if (sfd == -1) {
		err_sys("open");
		exit (1);
	}

	s = make_socket_non_blocking (sfd);
	if (s == -1)
	{
		err_sys("socket error");
		exit(1);
	}

	efd = epoll_create1 (0);
	if (efd == -1)
	{
		err_sys("epoll_create");
		exit(1);
	}

	event.data.fd = sfd;
	event.events = EPOLLIN | EPOLLET;
	s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
	if (s == -1)
	{
		err_sys("epoll_ctl");
		exit(1);
	}
	/* Buffer where events are returned */
	events = calloc (MAX_EVENTS, sizeof event);
	//events = (struct epoll_event *)calloc (MAX_EVENTS, sizeof event);
	/* The event loop */
	while (1)
	{
		int n, i;

		n = epoll_wait (efd, events, MAX_EVENTS, -1);
		for (i = 0; i < n; i++)
		{
			if ((events[i].events & EPOLLERR) ||
					(events[i].events & EPOLLHUP) ||
					(!(events[i].events & EPOLLIN)))
			{
				/* An error has occured on this fd, or the socket is not
				   ready for reading (why were we notified then?) */
				fprintf (stderr, "epoll error\n");
				close (events[i].data.fd);
				continue;
			}
			else
			{
				/* We have data on the fd waiting to be read. Read and
				   display it. We must read whatever data is available
				   completely, as we are running in edge-triggered mode
				   and won't get a notification again for the same
				   data. */
				while (1)
				{
					ssize_t count;
					char buf[2];

					count = read (events[i].data.fd, buf, sizeof buf);
					if (count == -1)
					{
						/* If errno == EAGAIN, that means we have read all
						   data. So go back to the main loop. */
						if (errno != EAGAIN)
						{
							err_sys("read");
						}
						break;
					}
					/* Write the buffer to standard output */
					s = write (1, buf, count);
					if (s == -1)
					{
						perror ("write");
						abort ();
					}
				}

			}
		}
	}


	pause();

	return 0;
}
Example #8
0
int main(int argc, char *argv[])
{
    struct epoll_event ev;
    struct epoll_event *evs;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: epoll port\n");
        exit(1);
    }

    int socketfd = create_socket_and_bind_port(argv[1]);
    if (socketfd == -1)
    {
        exit(EXIT_FAILURE);
    }

    if (make_fd_nonblock(socketfd) == -1)
    {
        exit(EXIT_FAILURE);
    }

    if (listen_socket(socketfd, MAXLISTEN) == -1)
    {
        exit(EXIT_FAILURE);
    }

    int epollfd;
    if ((epollfd = epoll_create1(0)) == -1)
    {
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    ev.events    = EPOLLIN | EPOLLET;
    ev.data.fd   = socketfd;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, socketfd, &ev) == -1)
    {
        perror("epoll_ctl"); 
        exit(EXIT_FAILURE);
    }

    evs= calloc(sizeof (struct epoll_event), MAXEVENTS);
    if (!evs)
    {
        perror("calloc");
        exit(EXIT_FAILURE);
    }
    
    for ( ; ;)
    {
        int nret; 
        nret = epoll_wait(epollfd, evs, MAXEVENTS, -1);
        int i;
        for (i = 0; i < nret; ++i)
        {
            ev = evs[i];
            if ((ev.events & EPOLLERR) || 
                 (ev.events & EPOLLHUP) || 
                (!(ev.events & EPOLLIN)))
            {
                fprintf(stderr, "epoll error: %u\n", ev.events); 
                epoll_ctl(epollfd, EPOLL_CTL_DEL, ev.data.fd, NULL);
                close(ev.data.fd); 
                continue;
            }

            if (ev.data.fd == socketfd)
            {  
                for (; ;)
                {
                    int newfd;
                    struct sockaddr sa;
                    socklen_t sa_len = sizeof(struct sockaddr);
                    newfd = accept(socketfd, &sa, &sa_len);
                    if (newfd == -1)
                    {
                        if ( errno == EAGAIN || errno == EWOULDBLOCK)
                        {
                            break;
                        }
                        perror("accept");
                        break;
                    }

                    char ip[INET6_ADDRSTRLEN];
                    void *addr = get_in_addr(&sa);
                    inet_ntop(sa.sa_family, addr, ip, sizeof(ip));
                    printf("Accept connection %s on descriptor %d\n", ip, newfd);
                    
                    if (make_fd_nonblock(newfd) == -1)
                    {
                        exit(EXIT_FAILURE);
                    }

                    struct epoll_event newev;
                    newev.data.fd = newfd;
                    newev.events = EPOLLIN | EPOLLET;
                    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newfd, &newev) == -1)
                    {
                        perror("epoll_ctl");
                        exit(EXIT_FAILURE);
                    }
                } // END FOR
            } // END IF
            else
            {
                int done = 0;
                for ( ; ;)
                {
                    ssize_t count;
                    char buf[BUFSIZ];

                    count = read(ev.data.fd, buf, BUFSIZ);
                    if (count == -1)
                    {
                        if (errno != EAGAIN)
                        {
                            perror("read");
                            done = 1;        
                        }
                        break;
                    } 
                    else if (count == 0)
                    {
                        done = 1;
                        break;
                    }

                    int nw = write(STDOUT_FILENO, buf, count); // write buf to standard output
                    if (nw == -1)
                    {
                        perror("write");
                        exit(EXIT_FAILURE);
                    }
                } // END FOR

                if (done == 1)
                {
                    printf("Closed connection on descriptor %d\n", ev.data.fd);
                    del_and_close_fd_from_epoll(epollfd, ev.data.fd);
                    continue;
                }
            } // END ELSE
        }
    }
}
Example #9
0
io_service::io_service() {
  int flags = 0;
  efd = epoll_create1(flags);
}
Example #10
0
static int server_init(Server *s, unsigned n_sockets) {
        int r;
        unsigned i;

        assert(s);
        assert(n_sockets > 0);

        zero(*s);

        s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (s->epoll_fd < 0) {
                r = log_error_errno(errno,
                                    "Failed to create epoll object: %m");
                goto fail;
        }

        for (i = 0; i < n_sockets; i++) {
                struct epoll_event ev;
                Fifo *f;
                int fd;

                fd = SD_LISTEN_FDS_START+i;

                r = sd_is_fifo(fd, NULL);
                if (r < 0) {
                        log_error_errno(r, "Failed to determine file descriptor type: %m");
                        goto fail;
                }

                if (!r) {
                        log_error("Wrong file descriptor type.");
                        r = -EINVAL;
                        goto fail;
                }

                f = new0(Fifo, 1);
                if (!f) {
                        r = -ENOMEM;
                        log_error_errno(errno, "Failed to create fifo object: %m");
                        goto fail;
                }

                f->fd = -1;

                zero(ev);
                ev.events = EPOLLIN;
                ev.data.ptr = f;
                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
                        r = -errno;
                        fifo_free(f);
                        log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
                        goto fail;
                }

                f->fd = fd;
                LIST_PREPEND(fifo, s->fifos, f);
                f->server = s;
                s->n_fifos++;
        }

        r = bus_connect_system_systemd(&s->bus);
        if (r < 0) {
                log_error_errno(r, "Failed to get D-Bus connection: %m");
                r = -EIO;
                goto fail;
        }

        return 0;

fail:
        server_done(s);

        return r;
}
/* Handles a number of connections for a thread.
 *
 * data  The thread data.
 */
static void *ThreadHandler(void *data)
{
    int                 ret;
    socklen_t           socketfd = -1;
    int                 efd;
    struct epoll_event  event;
    struct epoll_event  event_conn;
    struct epoll_event* events = NULL;
    ThreadData*         threadData = (ThreadData*)data;
#ifdef WOLFSSL_ASYNC_CRYPT
    WOLF_EVENT*         wolfEvents[MAX_WOLF_EVENTS];
#endif

    /* Initialize wolfSSL and create a context object. */
    if (WolfSSLCtx_Init(version, ourCert, ourKey, verifyCert, cipherList,
                        &threadData->devId, &threadData->ctx) == -1) {
        exit(EXIT_FAILURE);
    }

    /* Allocate space for EPOLL events to be stored. */
    events = (struct epoll_event*)malloc(EPOLL_NUM_EVENTS * sizeof(*events));
    if (events == NULL)
        exit(EXIT_FAILURE);

    /* Create a socket and listen for a client. */
    if (CreateSocketListen(port, numClients, &socketfd) == EXIT_FAILURE)
        exit(EXIT_FAILURE);

    /* Create an EPOLL file descriptor. */
    efd = epoll_create1(0);
    if (efd == -1) {
        fprintf(stderr, "ERROR: failed to create epoll\n");
        exit(EXIT_FAILURE);
    }

    /* Add the event for communications on listening socket. */
    memset(&event, 0, sizeof(event));
    event.events = EPOLLIN;
    event.data.ptr = NULL;
    ret = epoll_ctl(efd, EPOLL_CTL_ADD, socketfd, &event);
    if (ret == -1) {
        fprintf(stderr, "ERROR: failed to add event to epoll\n");
        exit(EXIT_FAILURE);
    }
    threadData->accepting = 1;

    /* Keep handling clients until done. */
    while (!SSLConn_Done(sslConnCtx)) {
        int n;
        int i;

#ifdef WOLFSSL_ASYNC_CRYPT
        do {
            double diff, start = current_time(1);
            ret = wolfSSL_CTX_AsyncPoll(threadData->ctx, wolfEvents,
                                        MAX_WOLF_EVENTS,
                                        WOLF_POLL_FLAG_CHECK_HW, &n);
            diff = current_time(0) - start;
            pthread_mutex_lock(&sslConnMutex);
            sslConnCtx->asyncTime += diff;
            pthread_mutex_unlock(&sslConnMutex);
            for (i = 0; i < n; i++) {
                SSLConn* sslConn = threadData->sslConn;

                while (sslConn != NULL) {
                    if (sslConn->ssl != wolfEvents[i]->context) {
                        sslConn = sslConn->next;
                        continue;
                    }

                    SSLConn_ReadWrite(sslConnCtx, threadData, sslConn);
                    break;
                }
            }
        } while (n > 0);
#endif

        SSLConn_FreeSSLConn(threadData);

#ifdef WOLFSSL_ASYNC_CRYPT
        /* Look for events. */
        n = epoll_wait(efd, events, EPOLL_NUM_EVENTS, 0);
#else
        /* Wait a second for events. */
        n = epoll_wait(efd, events, EPOLL_NUM_EVENTS, 1);
#endif
        /* Process all returned events. */
        for (i = 0; i < n; i++) {
            /* Error event on socket. */
            if (!(events[i].events & EPOLLIN)) {
                if (events[i].data.ptr == NULL) {
                    /* Not a client, therefore the listening connection. */
                    close(socketfd);
                    socketfd = -1;
                }
                else {
                    /* Client connection. */
                    SSLConn_Close(sslConnCtx, threadData, events[i].data.ptr);
                    ret = epoll_ctl(efd, EPOLL_CTL_ADD, socketfd, &event);
                }
            }
            else if (events[i].data.ptr == NULL) {
                SSLConn* sslConn;

                /* Accept a new client on the listener. */
                ret = SSLConn_Accept(threadData, threadData->ctx, socketfd,
                                     &sslConn);
                if (ret  == EXIT_SUCCESS) {
                    /* Set EPOLL to check for events on the new socket. */
                    memset(&event_conn, 0, sizeof(event_conn));
                    event_conn.events = EPOLLIN | EPOLLET;
                    event_conn.data.ptr = sslConn;
                    ret = epoll_ctl(efd, EPOLL_CTL_ADD, sslConn->sockfd,
                                    &event_conn);
                    if (ret == -1) {
                        fprintf(stderr, "ERROR: failed add event to epoll\n");
                        exit(EXIT_FAILURE);
                    }
                }

                if (threadData->cnt == sslConnCtx->numConns) {
                    /* Don't accept any more TCP connections. */
                    ret = epoll_ctl(efd, EPOLL_CTL_DEL, socketfd, &event);
                    if (ret == -1) {
                        fprintf(stderr, "ERROR: failed delete epoll event\n");
                        exit(EXIT_FAILURE);
                    }
                    threadData->accepting = 0;
                }
            }
            else {
                if (sslConnCtx->totalTime == 0) {
                    pthread_mutex_lock(&sslConnMutex);
                    if (sslConnCtx->totalTime == 0)
                        sslConnCtx->totalTime = current_time(1);
                    pthread_mutex_unlock(&sslConnMutex);
                }
                ret = SSLConn_ReadWrite(sslConnCtx, threadData,
                                        events[i].data.ptr);
            }
        }

        /* Accept more connections again up to the maximum concurrent. */
        if (!threadData->accepting &&
            threadData->cnt < sslConnCtx->numConns) {
            ret = epoll_ctl(efd, EPOLL_CTL_ADD, socketfd, &event);
            if (ret == -1) {
                fprintf(stderr, "ERROR: failed add event to epoll\n");
                exit(EXIT_FAILURE);
            }
            threadData->accepting = 1;
        }
    }

    if (socketfd != -1)
        close(socketfd);
    free(events);

    return NULL;
}
Example #12
0
File: lwan.c Project: lpereira/lwan
static void lwan_fd_watch_init(struct lwan *l)
{
    l->epfd = epoll_create1(EPOLL_CLOEXEC);
    if (l->epfd < 0)
        lwan_status_critical_perror("epoll_create1");
}
Example #13
0
static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
                                        apr_uint32_t size,
                                        apr_pool_t *p,
                                        apr_uint32_t flags)
{
    apr_status_t rv;
    int fd;

#ifdef HAVE_EPOLL_CREATE1
    fd = epoll_create1(EPOLL_CLOEXEC);
#else
    fd = epoll_create(size);
#endif
    if (fd < 0) {
        pollset->p = NULL;
        return apr_get_netos_error();
    }

#ifndef HAVE_EPOLL_CREATE1
    {
        int fd_flags;

        if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
            rv = errno;
            close(fd);
            pollset->p = NULL;
            return rv;
        }

        fd_flags |= FD_CLOEXEC;
        if (fcntl(fd, F_SETFD, fd_flags) == -1) {
            rv = errno;
            close(fd);
            pollset->p = NULL;
            return rv;
        }
    }
#endif

    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
#if APR_HAS_THREADS
    if ((flags & APR_POLLSET_THREADSAFE) &&
        !(flags & APR_POLLSET_NOCOPY) &&
        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                       APR_THREAD_MUTEX_DEFAULT,
                                       p)) != APR_SUCCESS)) {
        close(fd);
        pollset->p = NULL;
        return rv;
    }
#else
    if (flags & APR_POLLSET_THREADSAFE) {
        close(fd);
        pollset->p = NULL;
        return APR_ENOTIMPL;
    }
#endif
    pollset->p->epoll_fd = fd;
    pollset->p->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));

    if (!(flags & APR_POLLSET_NOCOPY)) {
        APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
        APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
        APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link);
    }
    return APR_SUCCESS;
}
Example #14
0
	PollEpoll::PollEpoll():activeEv_(kMaxEvents)
	{
		evId_ = epoll_create1(EPOLL_CLOEXEC);
	}
Example #15
0
void Engine::init(const char *fname)
{
	DLOG(INFO) << "Loading configuration";
	try
	{
		config.readFile(fname);
	}
	catch (const FileIOException &fioex)
	{
		throw std::runtime_error("I/O error while reading file.");
	}
	catch (const ParseException &pex)
	{
		throw std::runtime_error("Parse configuration file error");
	}

	//Load server configuration here
	int number_of_worker;
	Setting &sconf = config.getRoot()["general"];
	if (!sconf.lookupValue("number_of_worker", number_of_worker))
	{
		number_of_worker = 10;
		DLOG(ERROR) << "Fail to load number_of_worker parameter from configuration file";
	}

	for (int i = 0; i < number_of_worker; i++)
	{
		boost::shared_ptr<Worker> w(new Worker(i));
		workers.push_back(w);
	}

	int task_queue_size;
	if (!sconf.lookupValue("task_queue_size", task_queue_size))
	{
		task_queue_size = 100;
		DLOG(ERROR) << "Use default EventQueue size: 100";
	}
	tasks.init(task_queue_size);

	if (!sconf.lookupValue("max_event", max_event))
	{
		max_event = 512;
		DLOG(ERROR) << "Use default max_event: 512";
	}

	/* register services */
	REGISTER_SERVICE(CoreService);

	/* create epoll */
	epoll_fd = epoll_create1(0);
	if (epoll_fd == -1)
	{
		throw std::runtime_error("Error in epoll_create");
	}

	/* init components */
	for (component_map::iterator it = components.begin(); it != components.end(); it++)
	{
		DLOG(INFO) << "Component:" << it->second->get_id();
		it->second->init();
	}
}
Example #16
0
void str_cli(FILE *fp, int sockfd)
{
  char sendline[MAXLINE], recvline[MAXLINE];
  int epollfd = epoll_create1(EPOLL_CLOEXEC);
  struct epoll_event event1;
  bzero(&event1, sizeof(event1));
  event1.data.fd = sockfd;
  event1.events = EPOLLIN | EPOLLET;   // 设为 et 模式
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &event1))
  {
    perror("epoll_ctl: sockfd");
  }
  setnonblocking(sockfd);

  printf("file fd: %d\n", fileno(fp));
  struct epoll_event event2;
  bzero(&event2, sizeof(event2));
  event2.data.fd = fileno(fp);
  event2.events = EPOLLIN | EPOLLET;
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fileno(fp), &event2) < 0)
  {
    perror("epoll_ctl: fp");
  }
  printf("file fd: %d\n", fileno(fp));
  setnonblocking(fileno(fp));
  
  struct epoll_event events[events_size];
  for ( ; ; )
  {
    int eventNums = epoll_wait(epollfd, events, events_size, timeoutMs);
    printf("after epoll\n");
    int i, ret = 0, n = 0;
    for (i = 0; i < eventNums; i ++)
    {
      ret = n = 0;
      // socket 可读, et 模式下这次事件不会重复触发, 必须循环全部读取出来
      if (events[i].data.fd == sockfd)
      {
        printf("sockfd ...\n");
        bzero(recvline, MAXLINE);
        while ((ret = read(sockfd, recvline+n, MAXLINE)) > 0)
        {
          n += ret;
          printf("after sockfd read, ret = %d, n = %d; ...\n", ret, n);
        }
	    if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
        {
          perror("str_cli: server terminated prematurely");
	    }
        fputs(recvline, stdout);
      }
      // 终端数据可读
      else if (events[i].data.fd == fileno(fp))
      {
        printf("terminal ...\n");
        if (fgets(sendline, MAXLINE, fp) == NULL)
        {
          perror("fgets error");
        }
        n = strlen(sendline);
        while (n > 0)
        {
          ret = write(sockfd, sendline+ret, n);
          printf("after sockfd write, ret = %d, n = %d; ...\n", ret, n);
          if (ret < n)
          {
            if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
            {
              perror("str_cli: write error");
            }
            break;
          }
          n -= ret;
        }
      }
    }
  }
}
Example #17
0
int main(int argc, char *argv[]) {
    printf("%s", "start\n");
    int listen_fd;
    int rcode;
    struct epoll_event *events;
    
    if (argc != 2) {
        fprintf(stderr, "usage: %s [port]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = SIG_IGN;
    sa.sa_flags = 0;
    if (sigaction(SIGPIPE, &sa, NULL)) {
        printf("ignore SIGPIPE\n");
    }
    
    struct sockaddr_in client_addr;
    socklen_t client_len = 1;
    memset(&client_addr, 0, sizeof(struct sockaddr_in));
    
    /* create and bind the port, and then set the socket to non blocking mode */
    listen_fd = open_listenfd(atoi(argv[1]));
    debug("listen fd = %d", listen_fd);
    rcode = make_socket_non_blocking(listen_fd);
    if (rcode == -1) {
        log_err("error when making socket non blocking");
        abort();
    }
    
    /* create epoll event */
    int efd = epoll_create1(0);
    if (efd == -1) {
        log_err("epoll_create");
        abort();
    }
    struct epoll_event event;

    events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * MAXEVENTS);
    
    http_request_t *request = (http_request_t *)malloc(sizeof(http_request_t));
    http_request_init(request, listen_fd);
    
    event.data.ptr = (void *)request;
    event.events = EPOLLIN | EPOLLET;
    
    /* register the listen event */
    rcode = epoll_ctl(efd, EPOLL_CTL_ADD, listen_fd, &event);
    if (rcode == -1) {
        perror("epoll_ctl");
        abort();
    }
    
    threadpool_t *tp = threadpool_init(NUM_OF_THREADS);
    
    /* event loop */
    while (1) {
        int n = epoll_wait(efd, events, MAXEVENTS, -1);
        
        /* process each incoming IO event */
        int i;
        for (i = 0; i < n; i++) {
            http_request_t *r = (http_request_t *)events[i].data.ptr;
            int fd = r->fd;
            debug("event fd = %d", fd);
            if (fd == listen_fd) {  /* incoming connection event */
                
                while (1) {
                    int client_fd;
                    debug("waiting for accept");
                    client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_len);
                    
                    if (client_fd == -1) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK) {
                            // we have already processed the incoming connection
                            debug("incoming connection processed\n");
                            break;
                        }
                        else {
                            log_err("error occured when accepting connection\n");
                            break;
                        }
                    }
                    
                    rcode = make_socket_non_blocking(client_fd);
                    if (rcode == -1) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK)
                            // we have already processed the incoming connection
                            break;
                        log_err("fail to accept the connection\n");
                        break;
                    }
                    debug("new connection fd %d", client_fd);
                    
                    http_request_t *request = (http_request_t *)malloc(sizeof(http_request_t));
                    http_request_init(request, client_fd);
                    event.data.ptr = (void *)request;
                    event.events = EPOLLIN | EPOLLET;
                    /* add the new event into epoll */
                    rcode = epoll_ctl(efd, EPOLL_CTL_ADD, client_fd, &event);
                    if (rcode == - 1) {
                        log_err("fail in epoll_ctl in epoll_wait");
                        abort();
                    }
                }
                debug("end accept");
            }
            else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
                /* an error has occured on this fd, or the socket is not ready for reading */
                log_err("error events: %d", events[i].events);
                if (events[i].events & EPOLLERR)
                    log_err("EPOLLERR");
                if (events[i].events & EPOLLHUP)
                    log_err("EPOLLHUP");
                if (!(events[i].events & EPOLLIN))
                    log_err("EPOLLIN");
                close(fd);
                continue;
            }
            else {  /* incoming data read event */
                /* add the event to the thread pool list */
                threadpool_add(tp, handle_http, events[i].data.ptr);
                debug("thread count: %d", tp->thread_count);
                debug("thread queue size: %d", tp->queue_size);
            }
        }
    }
    
    threadpool_destroy(tp);
    return 0;
}
Example #18
0
void *runServer(void* value)
{
    int i = 0;

    Settings *settings = (Settings *)value;
    struct sockaddr_in sockAddr;
    sockAddr.sin_family = AF_INET;
    sockAddr.sin_port = htons(settings->port);

    int master = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (0 >= inet_pton(AF_INET, settings->ip, &sockAddr.sin_addr.s_addr))
        fprintf(stderr,"ERROR: wrong IP address\n");

    bind(master, (struct sockaddr *)(&sockAddr), sizeof(sockAddr));
    setNonblock(master);
    listen(master, SOMAXCONN);

    int epoll = epoll_create1(0);

    struct epoll_event epollEvent;
    epollEvent.data.fd = master;
    epollEvent.events = EPOLLIN;
    epoll_ctl(epoll, EPOLL_CTL_ADD, master, &epollEvent);

    while(1) {
        struct epoll_event events[EPOLL_SIZE];

        int numEvents = epoll_wait(epoll, events, EPOLL_SIZE, -1);

        for (i = 0; i < numEvents; ++i) {
            if (events[i].data.fd == master) {
                int slave = accept (master, 0, 0);
                struct epoll_event event;
                event.data.fd = slave;
                event.events = EPOLLIN;

                setNonblock (slave);
                epoll_ctl(epoll, EPOLL_CTL_ADD, slave, &event);
            } else {
                char query[BUF_LEN];
                memset(query, 0, sizeof(query));
                if (0 < recv(events[i].data.fd, query, BUF_LEN, MSG_NOSIGNAL)) {
                    int start = 0;
                    int queryLen = strlen(query);

                    toLog("query src:   ", query);

                    while((query[start] != '/') && (start < queryLen))
                        start++;

                    int finish = start;
                    while((query[finish] != ' ')
                          && (query[finish] != '?')
                          && (finish < queryLen))
                        finish++;

                    char queryPath[BUF_LEN];
                    memset(queryPath, 0, sizeof(queryPath));
                    strcat(queryPath, settings->path);

                    int pathLen = strlen(queryPath);
                    strncpy(queryPath + pathLen, query+start, finish-start);
                    queryPath[pathLen + finish-start] = '\0';

                    toLog("queryPath: ", queryPath);

                    FILE *f = fopen(queryPath, "r");
                    struct stat statbuf;
                    stat(queryPath, &statbuf);

                    if((f != NULL) && !S_ISDIR(statbuf.st_mode)) {
                        toLog("TRY to read:", queryPath);

                        char *buf;
                        size_t len;
                        fseek(f, 0, SEEK_END);
                        len = ftell(f);
                        int respLen = strlen(Resp_200);
                        buf = (char *) malloc(len + respLen + 1);
                        memset(buf, 0, sizeof(len + respLen));

                        strcpy(buf, Resp_200);
                        fseek(f, 0, SEEK_SET);
                        fread(buf + respLen, 1, len, f);
                        fclose(f);

                        buf[len + respLen] = '\0';

                        toLog("buf send: ", buf);

                        send(events[i].data.fd, buf, strlen(buf), MSG_NOSIGNAL);
                    } else {
                        toLog("WRONG: ", Resp_404);
                        send(events[i].data.fd, Resp_404, strlen(Resp_404), MSG_NOSIGNAL);
                    }

                    shutdown(events[i].data.fd, SHUT_RDWR);
                    close(events[i].data.fd);
                } else if (errno != EAGAIN) {
                    shutdown(events[i].data.fd, SHUT_RDWR);
                    close(events[i].data.fd);
                }
            }
        }
    }

}
Example #19
0
int main(int argc, char **argv)
{
char path[64] = "/home/box/final";
char  ip[16] = "127.0.0.1";
int port = 12345;
int opt;
int server_socket, conn_socket;
struct epoll_event events[MAX_EVENTS];
struct epoll_event event;
struct sockaddr_in sock_addr;
int epollfd, nfds, i, robin = 0;
int pid;
int on = 1;
int sv[2][2];

pid = fork();
if(pid != 0) return 0;

pid = fork();
if(pid != 0) return 0;

while ((opt = getopt(argc, argv, "h:p:d:")) != -1) {
               switch (opt) {
               case 'h':
			//ip.assign( optarg) ;
			sprintf(ip,"%s", optarg);
                  	 break;
               case 'p':
                   port = atoi(optarg);
                   break;
               case 'd':
                   //path.assign(optarg);
		   sprintf(path, "%s", optarg);
                   break;
               default: /* '?' */
                  //std::cout << "Usage: " << argv[0] << " [-h host_ip] [-p host_port] [-d directory]" << std::endl;
			printf("Ussage: %s [-h host_ip] [-p host_port][-d directory]",argv[0]);
                  return -1;
               }
           }


for(i = 0; i < 1 ; i++){
    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv[i]) < 0) {
       // printf("socketpair error");
        exit(1);
    }
    switch ((pid = fork())) {
    case 0:
        close(sv[i][0]);
        worker(sv[i][1], path);
        return 0;
    case -1:
        //printf("fork error");
        exit(1);
    default:
        close(sv[i][1]);
       /// parent(sv[i][0]);
        break;
    }
}

    server_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);   
    setsockopt ( server_socket,  SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on));
    sock_addr.sin_family = AF_INET;
    sock_addr.sin_port = htons(port);
    sock_addr.sin_addr.s_addr = inet_addr(ip);
     //inet_pton(AF_INET, ip, &sock_addr);
   
    bind(server_socket, (struct sockaddr *) (&sock_addr), sizeof(sock_addr));
   
    set_nonblock(server_socket);
   
    listen(server_socket, SOMAXCONN);
   
    epollfd = epoll_create1(0);
      if (epollfd == -1) {
                            goto error;
           }

    event.data.fd = server_socket;
    event.events = EPOLLIN;
    if(epoll_ctl (epollfd, EPOLL_CTL_ADD, server_socket, &event) == -1) {
               goto error;
           }
   
    while (1) {
        
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
	if(nfds == -1){
		goto error;
	}       

        for (i = 0; i < nfds; ++ i) {
            if (events[i].data.fd == server_socket) {
                conn_socket = accept(server_socket, 0, 0); 
                if (conn_socket == -1) {
                           goto error;
                       }
                
                set_nonblock(conn_socket);      
                    
                event.data.fd = conn_socket;
                event.events = EPOLLIN | EPOLLET;
                if(epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_socket, & event) == -1){
		    goto error;
                }
               
            }
            else {
			epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
			if(robin ) robin = 0;
			else robin = 1;	
  			 sock_fd_write(sv[robin][0], "1", 1, events[i].data.fd);
			
            }
        }
}

error:
shutdown(server_socket, SHUT_RDWR);
close(server_socket); 
 
return 0;
}
Example #20
0
         *  would be a pain to fix.
         */

        STRV_FOREACH(address, arg_listen) {
                log_info("Opening address %s", *address);

                fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
                if (fd < 0) {
                        log_error("Failed to open '%s': %s", *address, strerror(-fd));
                        return fd;
                }

                count ++;
        }

        *epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (*epoll_fd < 0) {
                log_error("Failed to create epoll object: %m");
                return -errno;
        }

        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + count; fd++) {
                int r = add_epoll(*epoll_fd, fd);
                if (r < 0)
                        return r;
        }

        return count;
}

static int launch(char* name, char **argv, char **env, int fds) {
Example #21
0
int main(void)
{
    memset(clients, 0, sizeof(Client) * MAXCLIENTS);
    signal(SIGCHLD, SIG_IGN);
    //signal(SIGPIPE, ) // FIXME

    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP. "| AI_ADDRCONFIG"
    hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    hints.ai_family = AF_INET6; // IPv4 addresses will be like ::ffff:127.0.0.1

    struct addrinfo *servinfo;
    getaddrinfo(NULL, PORT, &hints, &servinfo);

#if DEBUG
    for(struct addrinfo *p = servinfo; p != NULL; p = p->ai_next)
    {
        char ipstr[INET6_ADDRSTRLEN];
        inet_ntop(p->ai_family, get_in_addr(p->ai_addr), ipstr, sizeof(ipstr)); // convert the IP to a string
        printf(" %s\n", ipstr);
    }
#endif

    struct addrinfo *servinfo2 = servinfo; //servinfo->ai_next;
    char ipstr[INET6_ADDRSTRLEN];
    inet_ntop(servinfo2->ai_family, get_in_addr(servinfo2->ai_addr), ipstr, sizeof(ipstr));
    printf("Waiting for connections on [%s]:%s\n", ipstr, PORT);

    int sockfd = socket(servinfo2->ai_family, servinfo2->ai_socktype, servinfo2->ai_protocol);

#if 1
    int yes_1 = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes_1, sizeof(yes_1));
#endif

    bind(sockfd, servinfo2->ai_addr, servinfo2->ai_addrlen);
    freeaddrinfo(servinfo); // all done with this structure
    setnonblocking(sockfd);
    listen(sockfd, 10);

    int efd = epoll_create1(0);
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &event);

    struct epoll_event events[MAXEVENTS];

    for(;;)
    {
        int nfd = epoll_wait(efd, events, MAXEVENTS, -1);
        for(int n = 0; n < nfd; ++n)
        {
            if(events[n].data.fd == sockfd) // listener
            {
                int idx = new_client();
                struct sockaddr_storage their_addr; // connector's address information
                socklen_t addr_size = sizeof(their_addr);
                clients[idx].socket = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
                setnonblocking(clients[idx].socket); // maybe try accept4(2)

                char ipstr[INET6_ADDRSTRLEN];
                inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), ipstr, sizeof(ipstr));
                printf("Got a connection from %s [%d]\n", ipstr, clients[idx].socket);

                const char hello_msg[] = "<rembash2>\n";
                send(clients[idx].socket, hello_msg, sizeof(hello_msg) - 1, 0);

                struct itimerspec new_value;
                struct timespec now;

                clock_gettime(CLOCK_REALTIME, &now);
                new_value.it_value.tv_sec = now.tv_sec + 10;
                new_value.it_value.tv_nsec = now.tv_nsec;
                new_value.it_interval.tv_sec = 0;
                new_value.it_interval.tv_nsec = 0;

                clients[idx].timer = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
                timerfd_settime(clients[idx].timer, TFD_TIMER_ABSTIME, &new_value, NULL);

                EventData ed;
                ed.fd = clients[idx].socket;
                ed.idx = idx;
                EventUnion eu;
                eu.d = ed;
                event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
                event.data.u64 = eu.u64;
                epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event);

                ed.fd = clients[idx].timer;
                eu.d = ed;
                event.events = EPOLLIN | EPOLLET;
                event.data.u64 = eu.u64;
                epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event);
            }
            else // client socket or pty or timer
            {
                char buf[BUFFERSIZE];
                EventUnion eu;
                eu.u64 = events[n].data.u64;
                if(!clients[eu.d.idx].isvalid)
                {
                    printf("Something bad happend on file [%d] for client [%d]\n", eu.d.fd, eu.d.idx);
                    continue;
                }

                if (eu.d.fd == clients[eu.d.idx].timer)
                {
                    printf("Time out for [%d]\n", eu.d.idx);
                    if(clients[eu.d.idx].state == 0)
                    {
                        const char timer_msg[] = "TIMEOUT !\n";
                        send(clients[eu.d.idx].socket, timer_msg, sizeof(timer_msg) - 1, 0);
                        printf("Client [%d] disconnected.\n", eu.d.idx);
                        close(clients[eu.d.idx].socket);
                        clients[eu.d.idx].isvalid = 0;
                    }
                    continue;
                }

                if(clients[eu.d.idx].state == 0)
                {
                    // assert(eu.d.fd == clients[eu.d.idx].socket)
                    int nbytes = recv(eu.d.fd, buf, 255, 0); // it's not 100% guaranteed to work! must use readline.
                    if(nbytes < 1)
                    {
                        printf("Client [%d] disconnected.\n", eu.d.idx);
                        close(eu.d.fd);
                        clients[eu.d.idx].isvalid = 0;
                        continue;
                    }
                    buf[nbytes - 1] = '\0';
                    printf("Received %s from [%d]\n", buf, eu.d.fd);

                    if(strcmp(buf, SECRET) != 0)
                    {
                        const char secret_msg[] = "WRONG SECRET KEY !\n";
                        send(eu.d.fd, secret_msg, sizeof(secret_msg) - 1, 0);
                        printf("Shared key check failed for [%d]\n", eu.d.idx);
                        printf("Client [%d] disconnected.\n", eu.d.idx);
                        close(eu.d.fd);
                        clients[eu.d.idx].isvalid = 0;
                        continue;
                    }

                    const char ok_msg[] = "<ok>\n";
                    send(eu.d.fd, ok_msg, sizeof(ok_msg) - 1, 0);
                    clients[eu.d.idx].state = 1;

                    clients[eu.d.idx].pid = forkpty(&clients[eu.d.idx].pty, NULL, NULL, NULL);

                    if(clients[eu.d.idx].pid == 0) // child
                    {
                        close(sockfd); // child doesn't need the listener
                        close(efd); // child doesn't need epoll
                        setsid();
                        execl("/bin/bash", "bash", NULL);
                        _exit(0);
                        return 0;
                    }
                    else
                    {
                        EventData ed;
                        ed.fd = clients[eu.d.idx].pty;
                        ed.idx = eu.d.idx;
                        EventUnion eu;
                        eu.d = ed;
                        event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
                        event.data.u64 = eu.u64;
                        epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event);
                        const char ready_msg[] = "<ready>\n";
                        send(clients[eu.d.idx].socket, ready_msg, sizeof(ready_msg) - 1, 0);
                    }
                } // if(client->state == 0)
                else // if(client->state == 1)
                {
                    // FIXME: EPOLLHUP or EPOLLRDHUP ?!!
                    if((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP))
                    {
                        printf("Client [%d] disconnected.\n", eu.d.idx);
                        close(clients[eu.d.idx].socket);
                        close(clients[eu.d.idx].pty);
                        kill(clients[eu.d.idx].pid, SIGTERM);
                        clients[eu.d.idx].isvalid = 0;
                        continue;
                    }
                    else if(events[i].events & EPOLLIN)
                    {
                        int bytes_available = 0;
                        ioctl(eu.d.fd, FIONREAD, &bytes_available);
                        exchange_data(eu.d.fd, eu.d.idx);
                    }
                    else if(events[i].events & EPOLLOUT)
                    {
                        exchange_data(eu.d.fd == clients[eu.d.idx].socket ? clients[eu.d.idx].pty : clients[eu.d.idx].socket, eu.d.idx);
                    }
                    else
                    {
                        printf("Client [%d] ???.\n", eu.d.idx);
                    }
                }
            } // if(events[n].data.fd == sockfd)
        } // for(int n = 0; n < nfd; ++n)
    } // for(;;)

    return 0;
}
Example #22
0
int main(int argc, char* const argv[])
{
	memset(&config, 0, sizeof(config));

	const char *pidfile = "/var/run/6relayd.pid";
	bool daemonize = false;
	int verbosity = 0;
	int c;
	while ((c = getopt(argc, argv, "ASR:D:Nsucn::l:a:rt:m:oi:p:dvh")) != -1) {
		switch (c) {
		case 'A':
			config.enable_router_discovery_relay = true;
			config.enable_dhcpv6_relay = true;
			config.enable_ndp_relay = true;
			config.send_router_solicitation = true;
			config.enable_route_learning = true;
			break;

		case 'S':
			config.enable_router_discovery_relay = true;
			config.enable_router_discovery_server = true;
			config.enable_dhcpv6_relay = true;
			config.enable_dhcpv6_server = true;
			break;

		case 'R':
			config.enable_router_discovery_relay = true;
			if (!strcmp(optarg, "server"))
				config.enable_router_discovery_server = true;
			else if (strcmp(optarg, "relay"))
				return print_usage(argv[0]);
			break;

		case 'D':
			config.enable_dhcpv6_relay = true;
			if (!strcmp(optarg, "server"))
				config.enable_dhcpv6_server = true;
			else if (strcmp(optarg, "relay"))
				return print_usage(argv[0]);
			break;

		case 'N':
			config.enable_ndp_relay = true;
			break;

		case 's':
			config.send_router_solicitation = true;
			break;

		case 'u':
			config.always_announce_default_router = true;
			break;

		case 'c':
			config.deprecate_ula_if_public_avail = true;
			break;

		case 'n':
			config.always_rewrite_dns = true;
			if (optarg)
				inet_pton(AF_INET6, optarg, &config.dnsaddr);
			break;

		case 'l':
			config.dhcpv6_statefile = strtok(optarg, ",");
			if (config.dhcpv6_statefile)
				config.dhcpv6_cb = strtok(NULL, ",");
			break;

		case 'a':
			config.dhcpv6_lease = realloc(config.dhcpv6_lease,
					sizeof(char*) * ++config.dhcpv6_lease_len);
			config.dhcpv6_lease[config.dhcpv6_lease_len - 1] = optarg;
			break;

		case 'r':
			config.enable_route_learning = true;
			break;

		case 't':
			config.static_ndp = realloc(config.static_ndp,
					sizeof(char*) * ++config.static_ndp_len);
			config.static_ndp[config.static_ndp_len - 1] = optarg;
			break;

		case 'm':
			config.ra_managed_mode = atoi(optarg);
			break;

		case 'o':
			config.ra_not_onlink = true;
			break;

		case 'i':
			if (!strcmp(optarg, "low"))
				config.ra_preference = -1;
			else if (!strcmp(optarg, "high"))
				config.ra_preference = 1;
			break;

		case 'p':
			pidfile = optarg;
			break;

		case 'd':
			daemonize = true;
			break;

		case 'v':
			verbosity++;
			break;

		default:
			return print_usage(argv[0]);
		}
	}

	openlog("6relayd", LOG_PERROR | LOG_PID, LOG_DAEMON);
	if (verbosity == 0)
		setlogmask(LOG_UPTO(LOG_WARNING));
	else if (verbosity == 1)
		setlogmask(LOG_UPTO(LOG_INFO));

	if (argc - optind < 1)
		return print_usage(argv[0]);

	if (getuid() != 0) {
		syslog(LOG_ERR, "Must be run as root. stopped.");
		return 2;
	}

#if defined(__NR_epoll_create1) && defined(EPOLL_CLOEXEC)
	epoll = epoll_create1(EPOLL_CLOEXEC);
#else
	epoll = epoll_create(32);
	epoll = fflags(epoll, O_CLOEXEC);
#endif
	if (epoll < 0) {
		syslog(LOG_ERR, "Unable to open epoll: %s", strerror(errno));
		return 2;
	}

#ifdef SOCK_CLOEXEC
	ioctl_sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
#else
	ioctl_sock = socket(AF_INET6, SOCK_DGRAM, 0);
	ioctl_sock = fflags(ioctl_sock, O_CLOEXEC);
#endif

	if ((rtnl_socket = relayd_open_rtnl_socket()) < 0) {
		syslog(LOG_ERR, "Unable to open socket: %s", strerror(errno));
		return 2;
	}

	if (open_interface(&config.master, argv[optind++], false))
		return 3;

	config.slavecount = argc - optind;
	config.slaves = calloc(config.slavecount, sizeof(*config.slaves));

	for (size_t i = 0; i < config.slavecount; ++i) {
		const char *name = argv[optind + i];
		bool external = (name[0] == '~');
		if (external)
			++name;

		if (open_interface(&config.slaves[i], name, external))
			return 3;
	}

	if ((urandom_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) < 0)
		return 4;

	struct sigaction sa = {.sa_handler = SIG_IGN};
	sigaction(SIGUSR1, &sa, NULL);

	if (init_router_discovery_relay(&config))
		return 4;

	if (init_dhcpv6_relay(&config))
		return 4;

	if (init_ndp_proxy(&config))
		return 4;

	if (epoll_registered == 0) {
		syslog(LOG_WARNING, "No relays enabled or no slave "
				"interfaces specified. stopped.");
		return 5;
	}

	if (daemonize) {
		openlog("6relayd", LOG_PID, LOG_DAEMON); // Disable LOG_PERROR
		if (daemon(0, 0)) {
			syslog(LOG_ERR, "Failed to daemonize: %s",
					strerror(errno));
			return 6;
		}
		FILE *fp = fopen(pidfile, "w");
		if (fp) {
			fprintf(fp, "%i\n", getpid());
			fclose(fp);
		}
	}

	signal(SIGTERM, set_stop);
	signal(SIGHUP, set_stop);
	signal(SIGINT, set_stop);
	signal(SIGCHLD, wait_child);

	// Main loop
	while (!do_stop) {
		struct epoll_event ev[16];
		int len = epoll_wait(epoll, ev, 16, -1);
		for (int i = 0; i < len; ++i) {
			struct relayd_event *event = ev[i].data.ptr;
			if (event->handle_event)
				event->handle_event(event);
			else if (event->handle_dgram)
				relayd_receive_packets(event);
		}
	}

	syslog(LOG_WARNING, "Termination requested by signal.");

	deinit_ndp_proxy();
	deinit_router_discovery_relay();
	free(config.slaves);
	close(urandom_fd);
	return 0;
}
Example #23
0
int main(int argc, char *argv[]) {
  int sfd, s;
  int efd;
  struct epoll_event event;
  struct epoll_event *events;

  if(argc != 2) {
    fprintf(stderr, "Usage: %s [port]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  sfd = create_and_bind(argv[1]);
  if(sfd == -1) 
    abort();

  s = make_socket_non_blocking(sfd);
  if(s == -1) 
    abort();

  s = listen(sfd, SOMAXCONN);
  if(s == -1) {
    perror("listen");
    abort();  
  }

  efd = epoll_create1(0);
  if(efd == -1) {
    perror("epoll_create1");
    abort();
  }
  event.data.fd = sfd;
  event.events = EPOLLIN | EPOLLET;
  s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event);
  if(s == -1) {
    perror("epoll_ctl");
    abort();
  }

  events = calloc(MAXEVENTS, sizeof(event));
  /* The event loop */
  while(1) {
    int n, i;
    
    n = epoll_wait(efd, events, MAXEVENTS, -1);
    for(i = 0; i < n; i++) {
      if((events[i].events & EPOLLERR) || 
	(events[i].events & EPOLLHUP) || 
	(!(events[i].events & EPOLLIN))) {
        /*An error occurred, notified but no ready*/
        fprintf(stderr, "epoll error\n");
        close(events[i].data.fd);
        continue;
      }
      else if(sfd == events[i].data.fd) {
        /*listener port is notified, which means incoming connection*/
        while(1) {
          struct sockaddr in_addr;
          socklen_t in_len;
          int infd;
          char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
   
          in_len = sizeof(in_addr);
          infd = accept(sfd, &in_addr, &in_len);
          if(infd == -1) {
            if((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
              /*we have processed all incoming connections*/
              break;
            }
            else {
              perror("accept");
              break;
            }
          }

          s = getnameinfo(&in_addr, in_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
          if(s == 0) {
            printf("Accepted connection on descriptor %d (host=%s, port=%s)\n", infd, hbuf, sbuf);
          }

          /*make the socket non-blocking and add it to monitor list*/
          s = make_socket_non_blocking(infd);
          if(s == -1)
            abort();
  
          event.data.fd = infd;
          event.events = EPOLLIN | EPOLLET;
          s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
          if(s == -1) {
            perror("epoll_ctl");
            abort();
          }
        }
        continue;
      }
      else {
        /*read is ready*/ 
        int done = 0;
        while(1) {
          ssize_t count;
          char buf[512];

          count = read(events[i].data.fd, buf, sizeof(buf));
          if(count == -1) {
            if(errno != EAGAIN) {
              perror("read");
              done = 1;
            }
            break;
          }
          else if(count == 0) {
            /*End of file*/
            done = 1;
            break;
          }
          /*Write the buffer to stdout*/
          s = write(1, buf, count);
          if(s == -1) {
            perror("write");
            abort();
          }
        }

        if(done) {
          printf("closed connection on descriptor %d\n", events[i].data.fd);
          /*close connection*/
          close(events[i].data.fd);
        }
      }
    }
  }

  free(events);
  close(sfd);
  
  return EXIT_SUCCESS;
}
Example #24
0
int
main(int argc, char **argv)
{
	struct timespec mtime = { 0 };
	sigset_t mask, sigmask_orig;
	int c, fd;
	int ep_timeout   = 0;
	int ignore_timer = 0;
	int new_events   = 0;

	char *eventdir, *prog, **prog_args;

	struct option long_options[] = {
		{ "help", no_argument, 0, 'h' },
		{ "version", no_argument, 0, 'V' },
		{ "foreground", no_argument, 0, 'f' },
		{ "loglevel", required_argument, 0, 'L' },
		{ "logfile", required_argument, 0, 'l' },
		{ "pidfile", required_argument, 0, 'p' },
		{ "timeout", required_argument, 0, 't' },
		{ 0, 0, 0, 0 }
	};

	while ((c = getopt_long(argc, argv, "hVfL:l:p:", long_options, NULL)) != -1) {
		switch (c) {
			case 't':
				timeout = atoi(optarg);
				if (!timeout)
					timeout = DEFAULT_TIMEOUT;
				break;
			case 'p':
				pidfile = optarg;
				break;
			case 'l':
				logfile = optarg;
				break;
			case 'L':
				log_priority = logging_level(optarg);
				break;
			case 'f':
				daemonize = 0;
				break;
			case 'V':
				printf("%s %s\n", PROGRAM_NAME, VERSION);
				return EXIT_SUCCESS;
			default:
			case 'h':
				printf("Usage: %s [options] DIRECTORY PROGRAM [ARGS...]\n"
				       "\nThe utility monitors the DIRECTORY and when\n"
				       "new files appear run the PROGRAM.\n\n"
				       "Options:\n"
				       " -p, --pidfile=FILE   pid file location;\n"
				       " -l, --logfile=FILE   log file;\n"
				       " -L, --loglevel=LVL   logging level;\n"
				       " -t, --timeout=SEC    number of seconds that need to wait"
				       "                      for files before the PROGRAM launch;\n"
				       " -f, --foreground     stay in the foreground;\n"
				       " -V, --version        print program version and exit;\n"
				       " -h, --help           show this text and exit.\n"
				       "\n",
				       PROGRAM_NAME);
				return EXIT_SUCCESS;
		}
	}

	if (optind >= argc)
		error(EXIT_FAILURE, 0, "You must specify the directory");

	eventdir = argv[optind++];

	if (optind >= argc)
		error(EXIT_FAILURE, 0, "You must specify the program");

	prog = canonicalize_file_name(argv[optind]);
	if (!prog)
		error(EXIT_FAILURE, errno, "Bad program");

	argv[optind] = strrchr(prog, '/');
	if (!argv[optind])
		argv[optind] = prog;

	prog_args = argv + optind;

	if (!log_priority)
		log_priority = logging_level("info");

	if (pidfile && check_pid(pidfile))
		error(EXIT_FAILURE, 0, "%s: already running", PROGRAM_NAME);

	if (chdir("/") < 0)
		error(EXIT_FAILURE, errno, "%s: chdir(/)", PROGRAM_NAME);

	close(STDIN_FILENO);

	if ((fd = open("/dev/null", O_RDONLY)) < 0)
		error(EXIT_FAILURE, errno, "%s: open(/dev/null)", PROGRAM_NAME);

	if (fd != STDIN_FILENO) {
		dup2(fd, STDIN_FILENO);
		close(fd);
	}

	if (daemonize && daemon(0, 1) < 0)
		error(EXIT_FAILURE, errno, "%s: daemon", PROGRAM_NAME);

	logging_init();

	info("starting version %s", VERSION);

	if (pidfile && write_pid(pidfile) == 0)
		return EXIT_FAILURE;

	sigfillset(&mask);
	sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);

	sigdelset(&mask, SIGABRT);
	sigdelset(&mask, SIGSEGV);

	if ((fd_ep = epoll_create1(EPOLL_CLOEXEC)) < 0)
		fatal("epoll_create1: %m");

	if ((fd_signal = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC)) < 0)
		fatal("signalfd: %m");

	epollin_add(fd_ep, fd_signal);

	if ((fd_eventdir = inotify_init1(IN_NONBLOCK | IN_CLOEXEC)) < 0)
		fatal("inotify_init1: %m");

	if (inotify_add_watch(fd_eventdir, eventdir, IN_ONLYDIR | IN_DONT_FOLLOW | IN_MOVED_TO | IN_CLOSE_WRITE) < 0)
		fatal("inotify_add_watch: %m");

	epollin_add(fd_ep, fd_eventdir);

	ignore_timer = is_dir_not_empty(eventdir);

	if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
		fatal("clock_gettime: %m");
	last.tv_sec = now.tv_sec;

	while (!do_exit) {
		struct epoll_event ev[42];
		int i, fdcount;
		ssize_t size;

		if ((fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), ep_timeout)) < 0)
			continue;

		if (!ep_timeout)
			ep_timeout = timeout * 1000;

		for (i = 0; i < fdcount; i++) {

			if (!(ev[i].events & EPOLLIN)) {
				continue;

			} else if (ev[i].data.fd == fd_signal) {
				struct signalfd_siginfo fdsi;

				size = TEMP_FAILURE_RETRY(read(fd_signal,
				                               &fdsi, sizeof(struct signalfd_siginfo)));

				if (size != sizeof(struct signalfd_siginfo)) {
					err("unable to read signal info");
					continue;
				}

				handle_signal(fdsi.ssi_signo);

			} else if (ev[i].data.fd == fd_eventdir) {
				read_inotify_events(fd_eventdir);
				new_events += 1;
			}
		}

		if (new_events) {
			struct stat sb;

			new_events = 0;

			if (lstat(eventdir, &sb) < 0)
				fatal("lstat: %s: %m", eventdir);

			if (mtime.tv_sec != sb.st_mtim.tv_sec || mtime.tv_nsec != sb.st_mtim.tv_nsec) {
				if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
					fatal("clock_gettime: %m");
				last.tv_sec = now.tv_sec;
			}

			mtime.tv_sec  = sb.st_mtim.tv_sec;
			mtime.tv_nsec = sb.st_mtim.tv_nsec;
		}

		if (worker_pid)
			continue;

		if (!ignore_timer) {
			if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
				fatal("clock_gettime: %m");

			if (now.tv_sec < last.tv_sec || (now.tv_sec - last.tv_sec) < timeout)
				continue;
		}
		ignore_timer = 0;

		if ((worker_pid = spawn_worker(prog, prog_args)) < 0)
			fatal("spawn_worker: %m");

		dbg("Run worker %d", worker_pid);
	}

	epollin_remove(fd_ep, fd_signal);
	epollin_remove(fd_ep, fd_eventdir);

	free(prog);

	if (pidfile)
		remove_pid(pidfile);

	logging_close();

	return EXIT_SUCCESS;
}
Example #25
0
void str_cli(FILE *fp, int sockfd)
{
	char 	sendline[MAXLINE], recvline[MAXLINE];
	int		ret, n, i;
	size_t	len;

    int                 efd;
    struct epoll_event  event;
    struct epoll_event  events[2];


    // Same with epoll_create(), except the argument size is ignored.
    if ((efd = epoll_create1(0)) == -1) {
        perror ("epoll_create");
		exit(EXIT_FAILURE);
    }

    if(make_socket_non_blocking (fileno(stdin)) == -1) exit(EXIT_FAILURE);
    if(make_socket_non_blocking (sockfd) == -1) exit(EXIT_FAILURE);

    event.data.fd = fileno(stdin);   // stdin
    event.events = EPOLLIN;// | EPOLLET;
    if (epoll_ctl(efd, EPOLL_CTL_ADD, fileno(stdin), &event) == -1) {
        perror("epoll_ctl");
		exit(EXIT_FAILURE);
    }
    event.data.fd = sockfd;   // stdin
    event.events = EPOLLIN;// | EPOLLET;
    if (epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &event) == -1) {
        perror("epoll_ctl");
		exit(EXIT_FAILURE);
    }

	for (;;) {
        n = epoll_wait (efd, events, 2, -1);  // only stdin+sockfd
        for (i = 0; i < n; i++) {
            if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
                /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error\n");
                close (events[i].data.fd);
                exit(EXIT_FAILURE);
            }

            if (sockfd == events[i].data.fd) {   // socket is readable.
                ret = readline(sockfd, recvline, MAXLINE);
                if (ret == 0) {
                    fprintf(stderr, "str_cli: server terminated prematurely\n");
                    exit(EXIT_FAILURE);
                } else if (ret < 0) {
                    fprintf(stderr, "str_cli error\n");
                    exit(EXIT_FAILURE);
                }

                fputs("socket: ", stdout);
                if (fputs(recvline, stdout) == EOF) {
                    fprintf(stderr, "fputs error\n");
                    exit(EXIT_FAILURE);
                }
            }

            if (fileno(stdin) == events[i].data.fd) {   // input is readable.
                if (fgets(sendline, MAXLINE, fp) == NULL) {
                    if (ferror(fp)) {           // stream errors.
                        fprintf(stderr, "fgets error\n");
                        exit(EXIT_FAILURE);
                    } else {                    // end of file.
                        return;
                    }
                }
                fputs("stdin : ", stdout);
                if (fputs(sendline, stdout) == EOF) {
                    fprintf(stderr, "fputs error\n");
                    exit(EXIT_FAILURE);
                }

                len = strlen(sendline);
                if (writen(sockfd, sendline, len) != len) {
                    fprintf(stderr, "writen error\n");
                    exit(EXIT_FAILURE);
                }
            }
        }
    }
}
Example #26
0
	DEFiRet;
	free(*ppEvtLst);
	*ppEvtLst = NULL;
	RETiRet;
}


/* -END--------------------------- helpers for event list ------------------------------------ */


/* Standard-Constructor
 */
BEGINobjConstruct(nsdpoll_ptcp) /* be sure to specify the object type also in END macro! */
#if defined(EPOLL_CLOEXEC) && defined(HAVE_EPOLL_CREATE1)
	DBGPRINTF("nsdpoll_ptcp uses epoll_create1()\n");
	pThis->efd = epoll_create1(EPOLL_CLOEXEC);
	if(pThis->efd < 0 && errno == ENOSYS)
#endif
	{
		DBGPRINTF("nsdpoll_ptcp uses epoll_create()\n");
		pThis->efd = epoll_create(100); /* size is ignored in newer kernels, but 100 is not bad... */
	}

	if(pThis->efd < 0) {
		DBGPRINTF("epoll_create1() could not create fd\n");
		ABORT_FINALIZE(RS_RET_IO_ERROR);
	}
	pthread_mutex_init(&pThis->mutEvtLst, NULL);
finalize_it:
ENDobjConstruct(nsdpoll_ptcp)
Example #27
0
int
main (int argc, char *argv[])
{

    /* initialization code */
    cvect_t *dyn_vect = ccache_init();
    assert(dyn_vect);

    int sfd, s;
    int efd;
    struct epoll_event event;
    struct epoll_event *events;

    char buf[BUFFER_SIZE];
    char localbuf[BUFFER_SIZE];

    if (argc != 2)
    {
      fprintf (stderr, "Usage: %s [port]\n", argv[0]);
      exit (EXIT_FAILURE);
    }

    sfd = create_and_bind (argv[1]);
    if (sfd == -1) abort ();

    s = make_socket_non_blocking (sfd);
    if (s == -1) abort ();

    s = listen (sfd, SOMAXCONN);
    if (s == -1)
    {
        perror ("listen");
        abort ();
    }

    efd = epoll_create1 (0);
    if (efd == -1)
    {
      perror ("epoll_create");
      abort ();
    }

    event.data.fd = sfd;
    event.events = EPOLLIN | EPOLLET;
    s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
    if (s == -1)
    {
      perror ("epoll_ctl");
      abort ();
    }

    /* Buffer where events are returned */
    events = calloc (MAXEVENTS, sizeof event);

    /* The event loop */
    while (1)
    {
        int n, i;

        n = epoll_wait (efd, events, MAXEVENTS, -1);
        for (i = 0; i < n; i++)
        {   
        if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN)))
        {
              /* An error has occured on this fd, or the socket is not
                 ready for reading (why were we notified then?) */
            fprintf (stderr, "epoll error\n");
            close (events[i].data.fd);
            continue;
        }

        else if (sfd == events[i].data.fd)
        {
              /* We have a notification on the listening socket, which
                 means one or more incoming connections. */
                while (1)
                {
                    struct sockaddr in_addr;
                    socklen_t in_len;
                    int infd;
                    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

                    in_len = sizeof in_addr;
                    infd = accept (sfd, &in_addr, &in_len);
                    if (infd == -1)
                    {
                      if ((errno == EAGAIN) ||
                          (errno == EWOULDBLOCK))
                        {
                          /* We have processed all incoming
                             connections. */
                          break;
                        }
                      else
                        {
                          perror ("accept");
                          break;
                        }
                    }

                    s = getnameinfo (&in_addr, in_len,
                                   hbuf, sizeof hbuf,
                                   sbuf, sizeof sbuf,
                                   NI_NUMERICHOST | NI_NUMERICSERV);
                    if (s == 0)
                    {
                        printf("Accepted connection on descriptor %d "
                             "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                    }

                  /* Make the incoming socket non-blocking and add it to the
                     list of fds to monitor. */
                    s = make_socket_non_blocking (infd);
                    if (s == -1) abort ();

                    event.data.fd = infd;
                    event.events = EPOLLIN | EPOLLET;
                    s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                    if (s == -1)
                    {
                        perror ("epoll_ctl");
                        abort ();
                    }
                }
                continue;
            }
            else
            {
              /* We have data on the fd waiting to be read. Read and
                 process it. We must read whatever data is available
                 completely, as we are running in edge-triggered mode
                 and won't get a notification again for the same
                 data. */
                int done = 0;


                while (1)
                {
                    ssize_t count;
                    bzero(buf,BUFFER_SIZE); //zero out the buffer every time 


                    count = read (events[i].data.fd, buf, sizeof buf);
                    if (count == -1)
                    {
                      /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                        if (errno != EAGAIN)
                        {
                          perror ("read");
                          done = 1;
                        }
                        break;
                    }
                    else if (count == 0)
                    {
                      /* End of file. The remote has closed the
                         connection. */
                      done = 1;
                      break;
                    }


                    /* Process the buffered request and write the results to the output */
                    
                    buf[strlen(buf)-1] = '\0'; //remove trailing newline
                    /* Make sure this request is complete - can do special handling based on creq_type then */
                    strcpy(localbuf, buf);
                    ccmd_t type = get_creq_type(localbuf);
                    strcpy(localbuf, buf);

                    if(type == CSET) {
                        creq_t *creq = (creq_t *) malloc(sizeof(creq_t));

                        creq = ccache_req_parse(buf); //now process that actual buffer

                        /* Write Header and Footer to socket */
                        printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header));
                        if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error;

                        if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){
                            if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error;
                        }
                    }
                    /* CGET */
                    else if(type == CGET){
                        /* split multiple requests into single requests and process them */
                        char * pch;
                        int counter = 0;
                        pch = strtok(localbuf, " ");
                        while(pch != NULL){
                            
                            if(counter != 0){
                                /* formulate this new request and then skip the parsing step */
                                creq_t *creq = (creq_t *) malloc(sizeof(creq_t));
                                strcpy(creq->key, pch);
                                creq->type = CGET;

                                creq = ccache_get(creq);
                                        
                                /* Write Header and Footer to socket */
                                //printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header));
                                if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error;
                               

                                if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){
                                    if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error;
                                }
                            }
                            pch = strtok(NULL, " ");
                            counter++;
                        }
                        /* now that we're done transmitting all the CGET reqs - transmit END */
                        if((s = write (events[i].data.fd, "END\r\n", strlen("END\r\n"))) == -1) goto write_error;
                    }
                    else if(type == CDELETE || type == INVALID){
                        creq_t *creq = (creq_t *) malloc(sizeof(creq_t));

                        creq = ccache_req_parse(buf); //now process that actual buffer

                        /* Write Header and Footer to socket */
                        printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header));
                        if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error;

                        if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){
                            if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error;
                            
                        }
                        /* cleanup from delete */
                        free(creq);
                    }
                    else{
                        printf("error! exiting\n");
                        exit(1);
                    }
                    
                    
                }

                if (done)
                {
                    printf ("Closed connection on descriptor %d\n",
                          events[i].data.fd);

                    /* Closing the descriptor will make epoll remove it
                     from the set of descriptors which are monitored. */
                    close (events[i].data.fd);
                }
            }
        }
    }

    free (events);

    close (sfd);

    return EXIT_SUCCESS;

    write_error:
    if (s == -1)
    {
        perror ("write");
        abort ();
    }
    return -1;
}
Example #28
0
int stx_queue_create()
{
    return epoll_create1(0);
}
Example #29
0
/**
 * Open a target connection
 *
 * @see glip_open()
 */
int gb_tcp_open(struct glip_ctx *ctx, unsigned int num_channels)
{
    struct glip_backend_ctx *bctx = ctx->backend_ctx;

    int rv;
    const char* hostname;
    unsigned int port_data;
    unsigned int port_ctrl;

    if (bctx->data_sfd >= 0 || bctx->ctrl_sfd >= 0) {
        err(ctx, "Already connected, disconnect first!\n");
        return -1;
    }

    /* get hostname and port from options */
    if (glip_option_get_char(ctx, "hostname", &hostname) != 0) {
        dbg(ctx, "No 'hostname' option set, using default %s.\n",
            DEFAULT_HOSTNAME);
        hostname = DEFAULT_HOSTNAME;
    }
    if (glip_option_get_uint32(ctx, "port", &port_data) != 0) {
        dbg(ctx, "No 'port' option set, using default %u\n",
            DEFAULT_PORT_DATA);
        port_data = DEFAULT_PORT_DATA;
    }
    port_ctrl = port_data + 1;

    /* connect to data channel */
    bctx->data_sfd = 0;
    rv = gl_util_connect_to_host(ctx, hostname, port_data, &bctx->data_sfd);
    if (rv != 0) {
        return -1;
    }
    rv = gl_util_fd_nonblock(ctx, bctx->data_sfd);
    if (rv != 0) {
        return -1;
    }

    /* setup polling (for blocking I/O on data channel) */
    bctx->data_efd = epoll_create1(0);
    if (bctx->data_efd == -1) {
        err(ctx, "Unable to create epoll fd for the data channel: %s\n",
            strerror(errno));
        return -1;
    }
    bctx->data_ev.data.fd = bctx->data_sfd;
    struct epoll_event ev;
    ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLPRI | EPOLLET;
    rv = epoll_ctl(bctx->data_efd, EPOLL_CTL_ADD, bctx->data_sfd, &ev);
    if (rv != 0) {
        return -1;
    }

    /* connect to control channel */
    bctx->ctrl_sfd = 0;
    rv = gl_util_connect_to_host(ctx, hostname, port_ctrl, &bctx->ctrl_sfd);
    if (rv != 0) {
        return -1;
    }
    rv = gl_util_fd_nonblock(ctx, bctx->ctrl_sfd);
    if (rv != 0) {
        return -1;
    }

    return 0;
}
Example #30
0
/*
// Name: main
// In: argv, the arguments sent to the program.
//	   argc, the number of arguments sent to the program.
*/
int main (int argc, char **argv) {
	char port[6];
	char ssl_port[6];
	if(!arguments(argv, argc, port, ssl_port)) {
		printf("Usage: chat_server [port] [ssl port]\n");
		return 0;
	}
	char topic[MAXTOKENSIZE];
	memset(topic, '\0', MAXTOKENSIZE);
	// Set the signal handler.
	signal(SIGINT, signal_handler);
	server_socket = -1;
	ssl_socket = -1;
	server_socket_fd;
	int epoll_fd;
	struct epoll_event event, ssl_event;
	BIO *sbio;
	SSL *ssl;
	// Initialize ssl context.
	ctx=init_ctx();
	memset(&event, 0, sizeof event);
	memset(&ssl_event, 0, sizeof event);
	printf("Trying to create socket.\n");
	server_socket_fd = create_socket("telnet", port);
	ssl_socket_fd = create_socket("telnet", ssl_port);
	printf("Created socket.\n");
	// Check if sockets couldn't be created.
	if(server_socket_fd<0 || ssl_socket_fd<0) {
		fprintf(stderr, "Socket could not be created!\n");
		return -1;
	}
	// Set the socket to be non-blocking.
	server_socket = unblock_socket(server_socket_fd);
	ssl_socket = unblock_socket(ssl_socket_fd);
	if(server_socket<0 || ssl_socket<0) {
		fprintf(stderr, "Could not make socket non blocking.\n");
		return -1;
	}
	printf("Listening...\n");
	// Listen for incoming connections.
	server_socket = listen(server_socket_fd, NUMBER_PENDING_CONNECTIONS);
	ssl_socket = listen(ssl_socket_fd, NUMBER_PENDING_CONNECTIONS);
	if(server_socket < 0 || ssl_socket<0) {
		fprintf(stderr, "Could not listen to incoming connections.\n");
		return -1;
	}
	epoll_fd = epoll_create1(0);
	event.data.fd = server_socket_fd;
	// Run as edge-triggered, meaning that epoll_wait will return only on
	// new events.
	event.events = EPOLLIN | EPOLLET;
	// Create epoll control interface for the unsecure socket.
	server_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 
								server_socket_fd, &event);
	ssl_event.data.fd=ssl_socket_fd;
	ssl_event.events = EPOLLIN | EPOLLET;
	// Create epoll control interface for the secure socket.
	ssl_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ssl_socket_fd, &ssl_event);
	if(server_socket<0 || ssl_socket<0) {
		fprintf(stderr, "Could not create control interface for polling.\n");
		return -1;
	}
	events = calloc(MAXEVENTS, sizeof event);
	// Create hash map for storing connected clients.
	clients = hash_empty(MAXCLIENTS);
	struct sockaddr client_addr;
	socklen_t client_len;
	int insocket_fd;
	int client_socket;
	char host[MAXHOST_LEN], serv[MAXSERV_LEN];
	client_len = sizeof client_addr;
	// Main loop listening from events generated by epoll.
	while(1) {
		int n,i;
		// Wait for new events.
		n = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
		for(i=0;i<n;i++) {
			if((events[i].events & EPOLLERR) || 
				events[i].events & EPOLLHUP || 
				(!(events[i].events & EPOLLIN))) {
				fprintf(stderr, "An error occured at an event.\n");
				clientconn_t *c;
				// If the an error-event occured at a connected client.
				if((c = hash_get(events[i].data.fd, clients))!=NULL) {
					client_close(c);
					hash_remove(c, clients);
				}
				close(events[i].data.fd);
				continue;
			}
			// If an a connection is made on the unsecure socket.
			else if(server_socket_fd == events[i].data.fd) {
				while(1) {
					// Accept connection.
					insocket_fd = accept(server_socket_fd, 
									&client_addr, &client_len);
					if(insocket_fd<0) {
						if(!(errno == EAGAIN || errno == EWOULDBLOCK)) {
							fprintf(stderr, "Could not accept "
											"input connection");
							break;
						} else {
							// If the whole handshake could not be made, 
							// keep trying to accept.
							break;
						}
					}
					// The address information.
					server_socket = getnameinfo(&client_addr, client_len, host,
							sizeof host, serv, sizeof serv, 
							NI_NUMERICHOST|NI_NUMERICSERV);
					if(server_socket==0) {
						printf("Connection accepted!\n");
					}
					// Make client socket non-blocking.
					server_socket = unblock_socket(insocket_fd);
					if(server_socket <0) {
						fprintf(stderr, "Could not make client socket "
								"non-blocking\n");
						return -1;
					}
					// Create an epoll interface for the client socket.
					event.data.fd = insocket_fd;
					event.events = EPOLLIN|EPOLLET;
					server_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 
									insocket_fd, &event);
					if(server_socket<0) {
						fprintf(stderr, "Could not create epoll "
										"interface for client\n");
						return -1;
					}
					printf("Added client(%d)!\n", insocket_fd);
					// Store client in the hash map.
					c = create_client(insocket_fd, &client_addr);
					hash_insert(c, clients);
				}
				continue;
			}
			// If a connection is made on the secure socket.
			else if(ssl_socket_fd == events[i].data.fd) {
				printf("Someone connected through ssl!\n");
				while(1) {
					// Accept in the same way as the unsecure socket.
					insocket_fd = accept(ssl_socket_fd, 
										&client_addr, &client_len);
					if(insocket_fd<0) {
						if(!(errno == EAGAIN || errno == EWOULDBLOCK)) {
							fprintf(stderr, "Could not accept input "
											"connection\n");
							break;
						} else {
							break;
						}
					}
					ssl_socket = getnameinfo(&client_addr, client_len, host, 
							sizeof host, serv, sizeof serv, 
							NI_NUMERICHOST|NI_NUMERICSERV);
					if(ssl_socket==0) {
						printf("Connection accepted!\n");
					}
					// Make socket non-blocking
					ssl_socket = unblock_socket(insocket_fd);
					if(ssl_socket<0){
						fprintf(stderr, "Could not make secure client "
										"socket non-blocking.\n");
						return -1;
					}
					// Create epoll interface for the secure client connection
					ssl_event.data.fd = insocket_fd;
					ssl_event.events = EPOLLIN;
					ssl_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD,
											insocket_fd, &ssl_event);
					if(ssl_socket<0) {
						fprintf(stderr, "Could not create "
										"epoll interface for client.\n");
						return -1;
					}
					printf("Added client!(%d)\n", insocket_fd);
					c = create_client(insocket_fd, &client_addr);
					// Set up ssl.
					c->ssl_status=STATUS_HANDSHAKE;
					c->ssl = SSL_new(ctx);
					SSL_set_fd(c->ssl, insocket_fd);
					SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
					hash_insert(c, clients);
				}
				continue;
			}
			// If an incoming message has caused an event.
			else {
				int done = 0;
				while (1) {
					ssize_t count;
					char buf[MAXBUFSIZE];
					memset(buf, '\0', MAXBUFSIZE);
					clientconn_t *c = hash_get(events[i].data.fd, clients);
					// If the client is trying to make an ssl handshake.
					if(c->ssl_status==STATUS_HANDSHAKE) {
						int r=1;
						r=SSL_accept(c->ssl);
						if (r<0) {
							if(SSL_get_error(c->ssl, r)!=SSL_ERROR_WANT_READ &&
							  SSL_get_error(c->ssl, r)!=SSL_ERROR_WANT_WRITE ){
									done=1;
									printf("Could not accept ssl "
											"connection\n");
								break;
							}
						} else {
							// Handshake is done.
							c->ssl_status=STATUS_ACCEPTED;
						}
					}
					else {
						// Read data from client.
						int count = client_read(c, buf, sizeof buf);
						if(count<0) {
							if(errno!=EAGAIN) {
								fprintf(stderr, "Could not read"
											" from socket!\n");
								done=1;
							}
							break;
						}
						if(buf[MAXBUFSIZE-1] != '\0') {
							write(events[i].data.fd, "* BAD Buffer will "
													"overflow\r\n", 28);
							break;
						}
						else if (count==0) {
							done=1;
							break;
						}
						if (handle_input(events[i].data.fd, 
								buf, count, clients, topic)==CLIENTCLOSED) {
							done=1;
							break;
						}
						if(server_socket<0) {
							fprintf(stderr, "Could get input.\n");
							return -1;
						}
					}
				}
				// Client connection is done, wants to disconnect.
				if(done) {
					printf("Closed connection!\n");
					clientconn_t *closeclient = hash_get(events[i].data.fd, 
															clients);
					if(closeclient != NULL) {
						hash_remove(closeclient, clients);
						client_close(closeclient);
					}
					close(events[i].data.fd);
				}
			}
		}
	}
	free(events);
	close(server_socket_fd);
	return 0;
}