Пример #1
0
int init_uds_server(const char* srv_name, struct uds_msg* msg) {

    memset(msg, 0, sizeof(struct uds_msg));

    if((msg->sock = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
        lmice_error_log("UDS socket create failed.");
        return 1;
    }

    msg->local_un.sun_family = AF_UNIX;
    strncpy(msg->local_un.sun_path, srv_name, strlen(srv_name));
    unlink(srv_name);

    if(bind(msg->sock, (struct sockaddr*)&(msg->local_un), sizeof(msg->local_un)) == -1) {
        lmice_error_log("UDS socket bind failed.");
        return 1;
    }

    chmod(srv_name, 0666);

    if( make_socket_non_blocking(msg->sock) == -1) {
        lmice_error_log("UDS socket nonblock failed.");
        return 1;
    }

    return 0;
}
Пример #2
0
CRoute_manager::CRoute_manager()
{
	readconf("./conf.json");

	if( (maintain_servfd = create_bind_socket("8080")) == -1 )
		exit(-1);

	if(listen(maintain_servfd, 10) == -1)
		exit(-1);

	if( (info_fd = create_bind_socket("9090")) == -1 )
		exit(-1);

	if(make_socket_non_blocking(info_fd) == -1)
		exit(1);      

	if(listen(info_fd, SOMAXCONN) == -1)
		exit(-1);

	if( pthread_create(&mt_thread_id,NULL,maintain_thread,(void*)this) != 0 )
		exit(-1);

	if( pthread_create(&info_thread_id,NULL,cellinfo_thread,(void*)this) != 0 )
		exit(-1);

	// if( pthread_create(&thread_id,NULL,request_cellinfo_thread,(void*)this) != 0 )
	// 	exit(-1);		
	

}
Пример #3
0
/**
 * @brief We have a notification on the listening socket, which
	      means one or more incoming connections. 
 *
 * @return 
 */
static int new_connect(int listen_fd, int efd)
{
	int infd;
	int ret = 0;

	infd = accept(listen_fd, NULL, 0);
	if (infd == -1)
	{
		printf("infd is -1\n");
		if ((errno == EAGAIN) ||
			(errno == EWOULDBLOCK))
		{
			/* We have processed all incoming
			   connections. */
		}
		else
		{
			DEBUG_ERROR("accept");
		}

		return -1;
	}

	/* Make the incoming socket non-blocking and add it to the
	 *  list of fds to be monitored. 
	 */
	ret = make_socket_non_blocking(infd);
	if (ret == -1)
	{
		DEBUG_ERROR("set none blocking error\n");
		return ret;
	}

	return add2epoll(efd, EPOLLIN | EPOLLET, infd);
}
Пример #4
0
/* accept pending connection requests */
void accept_connection()
{
        int tfd;
        int ret;
        struct sockaddr_in addr;
        struct epoll_event ev;
        socklen_t len;

        for(;;) {
                tfd = accept(_listening_fd, (struct sockaddr*)&addr, &len);
                if(tfd == -1) {
                        break;
                } else {
                        make_socket_non_blocking(tfd);

                        ev.events = EPOLLIN | EPOLLET;
                        ev.data.fd = tfd;
                        epoll_ctl(_efd, EPOLL_CTL_ADD, tfd, &ev);

                        /* tell the client who he is
                         * we use the fd number as a the client id
                         */
                        do {
                               ret = write(tfd, &tfd, sizeof tfd);
                        }while(EAGAIN == ret || EWOULDBLOCK == ret);

                        printf("connection established with %d\n", tfd);
                }

        }

}
Пример #5
0
void acceptfun(struct schedule *s, void *ud)
{
	int *lfd = (int *)ud;
	int *pcfd;
	struct sockaddr_in clientaddr; 
    memset(&clientaddr, 0, sizeof(struct sockaddr_in)); 
    socklen_t len = sizeof(clientaddr);
    while(1){
    	//printf("start accept..\n");
    	pcfd = (int *)malloc(sizeof(int));
    	*pcfd = accept(*lfd, (struct sockaddr *)&clientaddr, &len);
    	//printf("%d\n", *pcfd);
    	if(*pcfd == -1){
    		free(pcfd);
    		if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                coroutine_yield(s);
            }
            else {
                break;
            }
    	}
    	else {
    		make_socket_non_blocking(*pcfd);
    		int co = coroutine_new(s, dorequest, (void *)pcfd);
    	}
    }
}
Пример #6
0
/* create socket for listening incoming connections*/
int create_server_socket(unsigned short port, int nqueued)
{
        int fd;
        struct sockaddr_in addr;

        fd = socket(AF_INET, SOCK_STREAM, 0);
        if(fd == -1) {
                perror(NULL);
                return E_NET_ERR;
        }

        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addr.sin_port = htons(port);

        if(0 != bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
                perror(NULL);
                return E_NET_ERR;
        }

        make_socket_non_blocking(fd);

        if(listen(fd, nqueued) == -1) {
                perror(NULL);
                return E_NET_ERR;
        }

        return fd;
}
Пример #7
0
struct cetimer * cetimer_create(unsigned int nextvalue, unsigned int interval, int wfd, int reconnwfd){
	if(s_timer == NULL){
		struct cetimer * timer = (struct cetimer *)malloc(sizeof(struct cetimer));
		timer->tnexttime.tv_sec = nextvalue;
		timer->tinterval.tv_sec = interval;
		timer->timer.it_interval = timer->tinterval;
		timer->timer.it_value = timer->tnexttime;
		setitimer(ITIMER_REAL, &timer->timer, 0);
		timer->handler = checkstatus;
		make_socket_non_blocking(wfd);
		timer->wfd = wfd;
		make_socket_non_blocking(reconnwfd);
		timer->reconnwfd = reconnwfd;

		s_timer = timer;
	}

	return s_timer;
}
Пример #8
0
int create_server(int port)
{
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	int s, sfd;
	char port_str[12] = {'\0'};
	
	sprintf(port_str, "%d", port);

	memset(&hints, 0, sizeof (struct addrinfo));
	hints.ai_family		= AF_UNSPEC;	/* Return IPv4 and IPv6 choices */
	hints.ai_socktype	= SOCK_STREAM;	/* We want a TCP socket */
	hints.ai_flags		= AI_PASSIVE;	/* All interfaces */

	if((s = getaddrinfo(NULL, port_str, &hints, &result)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror (s));
		return -1;
	}

	for(rp = result; rp != NULL; rp = rp->ai_next) {
		if ((sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
			continue;

		if(set_reuseaddr(sfd) == -1)
			abort();

		if((s = bind(sfd, rp->ai_addr, rp->ai_addrlen)) == 0)
			break;

		close(sfd);
	}

	if(rp == NULL) {
		fprintf(stderr, "Could not bind\n");
		return -1;
	}

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

	if((s = listen(sfd, SOMAXCONN)) == -1) {
		perror("listen");
		return -1;
	}
	
	freeaddrinfo(result);
	printf("Server started on port %d using fd %d\n", port, sfd);
	return sfd;
}
Пример #9
0
struct epoll_event_handler*
create_client_socket_handler(int client_socket_fd,
                             int epoll_fd,
                             char* backend_addr,
                             char* backend_port_str) {
    make_socket_non_blocking(client_socket_fd);

    struct client_socket_event_data* closure = malloc(sizeof(struct client_socket_event_data));
    struct epoll_event_handler* result = malloc(sizeof(struct epoll_event_handler));
    result->fd = client_socket_fd;
    result->handle = handle_client_socket_event;
    result->closure = closure;

    closure->backend_handler = connect_to_backend(result, epoll_fd, backend_addr, backend_port_str);

    return result;
}
Пример #10
0
int Serv::bind_and_listen(const char *serv_port) 
{ 
	int n; const int on = 1; 
	struct addrinfo hints;
    struct addrinfo	*res = NULL, *ressave = NULL; 
	bzero(&hints, sizeof(struct addrinfo));
	hints.ai_flags= AI_PASSIVE;
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if((n = getaddrinfo(NULL, serv_port, &hints, &res)) != 0){
		WARNING_LOG("tcp listen error for %s : %s", serv_port, gai_strerror(n));
	}
	ressave = res;
	do{
		listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if(listenfd < 0){
			continue;
		}
		if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){
			WARNING_LOG("setsockopt REUSEADDR error!");
			break;
		}
		if(bind(listenfd, res->ai_addr, res->ai_addrlen) == 0){
			break;
		}
		close(listenfd);
	}while( (res = res->ai_next) != NULL );
	if(res == NULL){
		WARNING_LOG("tcp listen error for %s", serv_port);
		return -1;
	}
	make_socket_non_blocking(listenfd);
	listen(listenfd, 1024);
	/*
	if(addrlenp){
		*addrlenp = res->ai_addrlen;
	}
	*/
	freeaddrinfo(ressave);
	return listenfd;
}
Пример #11
0
static void handle_accepting_connection(int server_fd)
{
    sockaddr_in clientaddr;
    socklen_t clientlen = sizeof(clientaddr);

    int client_fd = accept(server_fd, (sockaddr*)&clientaddr, &clientlen);
    check_errors("accept", client_fd);

    char client_address[NI_MAXHOST], client_port[NI_MAXSERV];
    int error_code = getnameinfo ((sockaddr*)&clientaddr, clientlen,
                                  client_address, sizeof client_address,
                                  client_port, sizeof client_port,
                                  NI_NUMERICHOST | NI_NUMERICSERV);

    make_socket_non_blocking(client_fd);
    connection_data *connection = allocate_connection(client_fd);

    connections++;

    if (global_accept_handler != NULL)
        global_accept_handler(error_code, connection, client_address, client_port);
}
Пример #12
0
static void new_handle_accepting_connection(int server_fd, struct epoll_event &client_event,
        struct epoll_event &server_event)
{
    sockaddr_in clientaddr;
    socklen_t clientlen = sizeof(clientaddr);

    int client_fd = accept(server_fd, (sockaddr*)&clientaddr, &clientlen);
    assert(client_fd > 0 || (client_fd == -1 && errno == EAGAIN));

    if (client_fd > 0)
    {
        char client_address[NI_MAXHOST], client_port[NI_MAXSERV];
        int error_code = getnameinfo ((sockaddr*)&clientaddr, clientlen,
                                      client_address, sizeof client_address,
                                      client_port, sizeof client_port,
                                      NI_NUMERICHOST | NI_NUMERICSERV);

        make_socket_non_blocking(client_fd);
        connection_data *connection = allocate_connection(client_fd);

        connections++;

//        epoll_event event;
//        event.events = EPOLLIN | EPOLLET;
//        event.data.ptr = connection;

//        int return_code = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event);
//        assert(return_code >= 0);

        int return_code = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, server_fd, &server_event);
        assert(return_code >= 0);

        if (global_accept_handler != NULL)
            global_accept_handler(error_code, connection, client_address, client_port);
    }
}
Пример #13
0
int main()
{
	int listenfd, optval = 1;
	int i;
	int port = 9500;
	struct sockaddr_in serveraddr;
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));

	bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons((unsigned short)port);

    bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    listen(listenfd, 1024);

    make_socket_non_blocking(listenfd);

    struct schedule * S = coroutine_open();
    printf("start..\n");
    int co1 = coroutine_new(S, acceptfun, (void *)&listenfd);
    printf("%d\n", S->cap);
    printf("%d\n", co1);
    for(i = 0; i < S->cap; i++) {
    	if(coroutine_status(S, i)) {
    		coroutine_resume(S,i);
    	}
    	if(i == S->cap - 1)
    		i = -1;
    }
    coroutine_close(S);
    close(listenfd);
    return 0;
}
Пример #14
0
int main(int argc, char *argv[]){

	if (argc < 2)
		error("ERROR, no port provided\n");

	int listen_socket;

	if ((listen_socket = create_and_bind_socket(argv[1])) == -1)
		error("Failed in create_and_bind_socket");

	if (make_socket_non_blocking(listen_socket) == -1)
		error("Error in setting non_block");

     	if (listen(listen_socket,SOMAXCONN) == -1)
		error("Listen failed");


//THREADING INITIALIZATION

      struct sockaddr_in cli_addr;
      socklen_t addrlen;

      struct arg_struct {
      	int conn_socket;
      	pthread_key_t thr_id_key;
      	int * thread_id;
      };

	struct arg_struct args;

	pthread_t thread;
	int * thread_id;
	pthread_key_t thr_id_key;
	thread_id = (int * ) malloc(sizeof(int));
	pthread_key_create(&thr_id_key, NULL);

	pthread_attr_t thread_attr;
	pthread_attr_init(&thread_attr);
	pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);

	int epollfd, nfds, i, conn_socket;
	struct epoll_event event;
	struct epoll_event events[MAX_EVENTS];
	
	if( (epollfd = epoll_create1 (0)) == -1)
		error ("epoll_create");
	
    //typedef union epoll_data {
    //	void    *ptr;
    //	int      fd;
    //	uint32_t u32;
    //	uint64_t u64;
    //} epoll_data_t;
    //
    //struct epoll_event {
    //	uint32_t     events;    /* Epoll events */
    //	epoll_data_t data;      /* User data variable */
    //	};

	event.events = EPOLLIN|EPOLLET;
	event.data.fd = listen_socket;

	if (epoll_ctl (epollfd, EPOLL_CTL_ADD, listen_socket, &event) == -1)
		error ("epoll_ctl fail");
	
	int count = 0;
	
	while(1){
		
		//printf("Waiting for connections[%d]....\n", count);
		
		if((nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1)) == -1)    //Returns number of events waiting
			error("epoll_pwait");

		for (i = 0; i < nfds; i++){
			count++;
			printf("Process connection [%d]\n", count);

			if (events[i].data.fd == listen_socket) {

				if((conn_socket = accept(listen_socket, (struct sockaddr *) &cli_addr, &addrlen)) == -1)
					error("accept failed");

				if (make_socket_non_blocking(conn_socket) == -1)
					error("Error in setting non_block");
			
				event.events = EPOLLIN|EPOLLET;
				event.data.fd = conn_socket;

				if ((epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_socket, &event)) == -1)
					error("epoll_ctl: conn_socket failed");
			}

			else{
				args.conn_socket = events[i].data.fd;
				args.thread_id = thread_id;

				if(pthread_create (&thread, &thread_attr, talk_to_client, &args) != 0)
					error("Error creating a thread.");
			}
		}
				
	}//end of while

	printf("Exited while(1) ?!?!? \n");
	pthread_exit(NULL);
	return 0; 					//should never get here
}
int main (int argc, char *argv[])
{
	struct epoll_event event, *events;
	int sfd, s;
	int efd;

	/* Set up listening socket, 'listen_sock' (socket(),
	   bind(), listen()) */

	sfd = create_and_bind ("8888");
	if (sfd == -1)
		abort ();

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

	s = listen (sfd, SOMAXCONN);
	if (s == -1)
	{
		err_sys("listen");
		exit(-1);
	}

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

	event.data.fd = sfd;
	//event.events = EPOLLIN | EPOLLET;
	event.events = EPOLLIN;
	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 (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;
					event.events = EPOLLIN;
					s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
					if (s == -1)
					{
						err_sys("epoll_ctl");
					}
				}
				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[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)
						{
							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 */
					s = write (1, buf, count);
					if (s == -1)
					{
						err_sys("write");
					}
				}

				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);
				}
			}
		}
	}

	return 0;
}
Пример #16
0
int main(int argc, const char** argv) {
  setvbuf(stdout, NULL, _IONBF, 0);

  int portnum = 9090;
  if (argc >= 2) {
    portnum = atoi(argv[1]);
  }
  printf("Serving on port %d\n", portnum);

  int listener_sockfd = listen_inet_socket(portnum);
  make_socket_non_blocking(listener_sockfd);

  int epollfd = epoll_create1(0);
  if (epollfd < 0) {
    perror_die("epoll_create1");
  }

  struct epoll_event accept_event;
  accept_event.data.fd = listener_sockfd;
  accept_event.events = EPOLLIN;
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listener_sockfd, &accept_event) < 0) {
    perror_die("epoll_ctl EPOLL_CTL_ADD");
  }

  struct epoll_event* events = calloc(MAXFDS, sizeof(struct epoll_event));
  if (events == NULL) {
    die("Unable to allocate memory for epoll_events");
  }

  while (1) {
    int nready = epoll_wait(epollfd, events, MAXFDS, -1);
    for (int i = 0; i < nready; i++) {
      if (events[i].events & EPOLLERR) {
        perror_die("epoll_wait returned EPOLLERR");
      }

      if (events[i].data.fd == listener_sockfd) {
        // The listening socket is ready; this means a new peer is connecting.

        struct sockaddr_in peer_addr;
        socklen_t peer_addr_len = sizeof(peer_addr);
        int newsockfd = accept(listener_sockfd, (struct sockaddr*)&peer_addr,
                               &peer_addr_len);
        if (newsockfd < 0) {
          if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // This can happen due to the nonblocking socket mode; in this
            // case don't do anything, but print a notice (since these events
            // are extremely rare and interesting to observe...)
            printf("accept returned EAGAIN or EWOULDBLOCK\n");
          } else {
            perror_die("accept");
          }
        } else {
          make_socket_non_blocking(newsockfd);
          if (newsockfd >= MAXFDS) {
            die("socket fd (%d) >= MAXFDS (%d)", newsockfd, MAXFDS);
          }

          fd_status_t status =
              on_peer_connected(newsockfd, &peer_addr, peer_addr_len);
          struct epoll_event event = {0};
          event.data.fd = newsockfd;
          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }

          if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newsockfd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_ADD");
          }
        }
      } else {
        // A peer socket is ready.
        if (events[i].events & EPOLLIN) {
          // Ready for reading.
          int fd = events[i].data.fd;
          fd_status_t status = on_peer_ready_recv(fd);
          struct epoll_event event = {0};
          event.data.fd = fd;
          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }
          if (event.events == 0) {
            printf("socket %d closing\n", fd);
            if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) {
              perror_die("epoll_ctl EPOLL_CTL_DEL");
            }
            close(fd);
          } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_MOD");
          }
        } else if (events[i].events & EPOLLOUT) {
          // Ready for writing.
          int fd = events[i].data.fd;
          fd_status_t status = on_peer_ready_send(fd);
          struct epoll_event event = {0};
          event.data.fd = fd;

          if (status.want_read) {
            event.events |= EPOLLIN;
          }
          if (status.want_write) {
            event.events |= EPOLLOUT;
          }
          if (event.events == 0) {
            printf("socket %d closing\n", fd);
            if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) {
              perror_die("epoll_ctl EPOLL_CTL_DEL");
            }
            close(fd);
          } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) {
            perror_die("epoll_ctl EPOLL_CTL_MOD");
          }
        }
      }
    }
  }

  return 0;
}
int main(int argc, char *argv[])
{
  int sfd, s;
  int efd;
  int so_rcvbuf = 0;
  int verbose = 0;
  struct epoll_event event;
  struct epoll_event *events;
  struct edata {
    int fd;
    int content_length;
    int content_offset;
    char *header_buf;
    int header_off;
    int header_max;
  };

  if (argc < 2 || argc > 3)
    {
      fprintf(stderr, "Usage: %s [port] [rcvbuf]\n", argv[0]);
      exit(EXIT_FAILURE);
    }

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

  if (argc == 3)
      so_rcvbuf = atoi(argv[2]);

  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();
    }

  struct edata *ed = malloc(sizeof(*ed));
  ed->fd = sfd;
  ed->header_buf = 0;

  event.data.ptr = ed;
  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++)
	{
	  struct edata *ed = events[i].data.ptr;
	  int fd = ed->fd;

	  if ((events[i].events & EPOLLERR) ||
              (events[i].events & EPOLLHUP) ||
              (!(events[i].events & EPOLLIN)))
	    {
	      fprintf(stderr, "epoll error\n");

	      s = epoll_ctl(efd, EPOLL_CTL_DEL, fd, 0);
	      if (s == -1)
		{
		  perror("epoll_ctl");
		  abort();
		}
	      close(fd);
	      free(ed);
	      continue;
	    }

	  else if (sfd == fd)
	    {
              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))
                        {
                          break;
                        }
                      else
                        {
                          perror("accept");
                          break;
                        }
                    }

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

		  if (so_rcvbuf)
		    if (setsockopt(infd, SOL_SOCKET, SO_RCVBUF, &so_rcvbuf,
				   sizeof(so_rcvbuf)))
		      {
			perror("setsocopt");
			abort();
		      }
                  s = make_socket_non_blocking(infd);
                  if (s == -1)
                    abort();
		  ed = malloc(sizeof(*ed));
		  ed->fd = infd;
		  ed->content_length = -1;
		  ed->header_max = 999;
		  ed->header_buf = malloc(ed->header_max + 1);
		  ed->header_off = 0;
		  event.data.ptr = ed;
                  event.events = EPOLLIN | EPOLLET;
                  s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
                  if (s == -1)
                    {
                      perror("epoll_ctl");
                      abort();
                    }
                }
              continue;
            }
          else
            {
              int done = 0;
              while (1)
                {
                  ssize_t count;
                  char buf[32768];

		  if (ed->content_length == -1)
		    {
		      count = read(fd, ed->header_buf + ed->header_off,
				   ed->header_max - ed->header_off);

		    }
		  else
		    {
		      count = read(fd, buf, sizeof buf);
		    }
                  if (count == -1)
                    {
                      if (errno != EAGAIN)
                        {
                          perror("read");
                          done = 1;
                        }
                      break;
                    }
                  else if (count == 0)
                    {
                      done = 1;
                      break;
                    }
		  else
		    {
		      if (ed->content_length == -1)
			{
			  const char *cp2;
			  ed->header_off += count;
			  ed->header_buf[ed->header_off] = '\0';
			  cp2 = strstr(ed->header_buf, "\r\n\r\n");
			  if (cp2)
			    cp2 += 4;
			  else if (!cp2)
			    {
			      cp2 = strstr(ed->header_buf, "\n\n");
			      if (cp2)
				cp2 += 2;
			    }
			  if (cp2) /* complete header? */
			    {
			      const char *cp1 =
				strstr(ed->header_buf, "\nContent-Length:");
			      if (!cp1)
				cp1 = strstr(ed->header_buf, "\nContent-length:");
			      if (cp1 && cp1 < cp2)
				ed->content_length = atoi(cp1 + 16);
			      else
				ed->content_length = 0;
			      ed->content_offset = ed->header_off -
				(cp2 - ed->header_buf);

			      if (ed->content_offset == 0)
				{
				  if (strstr(ed->header_buf,
					     "\nExpect: 100-continue"))
				    {
				      char buf[64];
				      strcpy(buf, "HTTP/1.1 100 Continue\r\n\r\n");
				      write(fd, buf, strlen(buf));
				    }
				}
			      if (verbose)
				printf("complete header length=%d\n",
				       ed->content_length);
			    }
			  else
			    {
			      if (ed->header_off == ed->header_max)
				{
				  printf("Too big header\n");
				  done = 1;
				}
			    }
			}
		      else
			{
			  ed->content_offset += count;
			}
		      if (ed->content_length != -1 &&
			  ed->content_offset == ed->content_length)
			{
			  if (verbose)
			    printf("Got all content %d\n",
				   ed->content_length);
			  done = 1;
			}
		    }
                }

              if (done)
                {
		  if (verbose)
		    printf("Closing descriptor %d\n", fd);
		  char buf[1000];

		  strcpy(buf, "HTTP/1.0 200 OK\r\n"
			 "Content-Length: 0\r\n"
			 "Connection: Close\r\n"
			 "\r\n");
		  write(fd, buf, strlen(buf));

                  s = epoll_ctl(efd, EPOLL_CTL_DEL, fd, 0);
                  if (s == -1)
                    {
                      perror("epoll_ctl");
                      abort();
                    }
                  close(fd);
		  free(ed->header_buf);
		  free(ed);
                }
            }
        }
    }

  free(events);

  close(sfd);

  return EXIT_SUCCESS;
}
Пример #18
0
static void
accept_handler(connections_head_t *head, connection_t *conn)
{
    struct sockaddr in_addr;
    socklen_t in_len;
    int infd, lsfd;
    int ret;
    connection_t *new_conn;
    struct epoll_event event;
    char hbuf[64], sbuf[64];

    /* We have a notification on the listening socket, which
     * means one or more incoming connections.
     */
    while (1)
    {
        in_len = sizeof(struct sockaddr);
        lsfd = conn->fd;

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

        ret = getnameinfo(&in_addr, in_len,
                hbuf, sizeof hbuf,
                sbuf, sizeof sbuf,
                NI_NUMERICHOST | NI_NUMERICSERV);
        if (0 == ret) {
            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
         */
        ret = make_socket_non_blocking(infd);
        if (-1 == ret) {
            ERROR_MSG("make_socket_non_blocking\n");
            abort();
        }

        new_conn = get_connection(head);
        if (NULL == new_conn) {
            ERROR_MSG("get_connection\n");
            abort();
        }

        new_conn->fd = infd;
        new_conn->ssl = NULL;
        //new_conn->handler = rdwr_handler;
        new_conn->handler = do_ssl_accept;

        event.data.ptr = new_conn;
        event.events = EPOLLIN | EPOLLET;
        ret = epoll_ctl(head->epfd, EPOLL_CTL_ADD, infd, &event);
        if (-1 == ret) {
            ERROR_MSG("epoll_ctl\n");
            abort();
        }
    }
}
Пример #19
0
int main(int argc, char *argv[]) {
    if (argc != 2) {
        print_err("Arguments failure");
    }

    pid_t main_pid = fork();
    switch(main_pid) {
        case 0:
            break;
        case -1:
            print_err("Can't fork main");
        default:
            exit(0);
    }

    if(setsid()<0) {
        print_err("Can't start new session");
    }
    pid_t nsession_pid = fork();
    switch(nsession_pid) {
        case 0:
            break;
        case -1:
            print_err("Can't fork from deamon");
        default:
            return 0;
    }

    pid_t daemon_pid = getpid();
    int tmp_fd = open("/tmp/netsh.pid", O_WRONLY | O_CREAT);
    char* buf = new char[64];
    int digits = sprintf(buf, "%d\n", daemon_pid);
    ssize_t written_count = write(tmp_fd, buf, digits);
    if (written_count == -1) {
        close(tmp_fd);
        print_err("Failed to write pid to file");
    }
    close(tmp_fd);
    //Done pre part

    const int epoll_size = 32;
    struct epoll_event event;
    struct epoll_event *events;

    //prepare socket
    int socket_fd = create_and_bind(argv[1]);
    make_socket_non_blocking(socket_fd);
    if (listen(socket_fd, SOMAXCONN) == -1) {
        print_err("Can't setup listener");
    }

    //Setup epoll
    int epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        print_err("Can't create epoll");
    }
    event.data.fd = socket_fd;
    event.events = EPOLLIN | EPOLLET;
    int ectl_status = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &event);
    if (ectl_status == -1) {
        print_err("Can't register fd in epoll");
    }

    events = calloc(epoll_size, sizeof(event));

    while (1)
    {
        int n, i;

        n = epoll_wait (epoll_fd, events, epoll_size, -1);
        for (i = 0; i < n; i++)
        {
            if ((events[i].events & EPOLLERR) ||
                (events[i].events & EPOLLHUP) ||
                (!(events[i].events & EPOLLIN)))
            {
                close (events[i].data.fd);
                continue;
            }

            else if (socket_fd == events[i].data.fd)
            {
                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 (socket_fd, &in_addr, &in_len);
                    if (infd == -1)
                    {
                        if ((errno == EAGAIN) ||
                            (errno == EWOULDBLOCK))
                        {
                            break;
                        }
                        else
                        {
                            perror ("Can't accept");
                            break;
                        }
                    }
                    int unblock_status = make_socket_non_blocking (infd);
                    if (unblock_status == -1)
                        print_err("Can't unblock socket");

                    event.data.fd = infd;
                    event.events = EPOLLIN | EPOLLET;
                    int epc_status = epoll_ctl (epoll_fd, EPOLL_CTL_ADD, infd, &event);
                    if (epc_status == -1)
                    {
                        print_err("Can't add flags");
                    }
                }
                continue;
            }
            else if (events[i].events == EPOLLIN)
            {
                int done = 0;
                read_and_exec(events[i].data.fd);

                if (1)
                {
                    close (events[i].data.fd);
                }
            } else if (events[i].events == EPOLLOUT) {

            }
        }
    }
    return 0;
}
Пример #20
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;
}
Пример #21
0
void*
sock_boot (void *v_options)
{
  int sfd, s;
  int efd;
  struct epoll_event event;
  struct epoll_event *events;

  s_options* options = (s_options *) v_options;
  sfd = create_and_bind (options->port);
  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_create (1);
  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;
                    }

                  char c_payload_size[9];
                  memcpy(c_payload_size,&buf[0],8);
                  c_payload_size[8] = '\0';
                  char *e;
                  unsigned long int payload_size = strtoul(c_payload_size,&e,16);
                  clients_data[i].payload_size = payload_size;
                  memcpy(clients_data[i].buffer,&buf[8],payload_size);


                  t_split *directives = ksplit(clients_data[i].buffer,"\x0d\x0a");
                  int j;
                  for (j=0; j < directives->count; ++j) {
  
                    memcpy(&received_data_queue[received_data_queue_tail++],directives->splited_ary[j],payload_size);
                    if (received_data_queue_tail > MAX_RECEIVE_QUEUE) received_data_queue_tail = 0;
                    //strcpy(clients_data[i].buffer,&buf[8]);
  #ifdef DEBUG
                    //printf("payload_size:[%d] | ",payload_size);
                    //printf("clients_data[%d].payload_size:[%lu] | ",i,payload_size);
                    printf("clients_data[%d].buffer:[%s]\n",i,directives->splited_ary[j]);
  #endif
                  }
                }

              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;
}
Пример #22
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;
}
Пример #23
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);
                }
            }
        }
    }
}
Пример #24
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;
}
Пример #25
0
// 可能作为服务器接收Cell请求
void * cellinfo_thread(void* p)
{
	CRoute_manager* pCRoute = (CRoute_manager*)p;
 
	struct epoll_event event;
	struct epoll_event* events;
	int efd;

	efd = epoll_create(20);

	event.data.fd = pCRoute->info_fd;
	event.events = EPOLLIN | EPOLLET;  //设置成边沿触发
	if(epoll_ctl(efd,EPOLL_CTL_ADD,pCRoute->info_fd,&event) == -1)
		exit(-1);

	events = (epoll_event*)calloc(EVENTSNUM, sizeof(epoll_event));

    while(1) 
	{
        int n = epoll_wait(efd,events,EVENTSNUM,-1);
        for(int i = 0; i < n; i++)
        {
        	if((events[i].events & EPOLLERR) ||  
              (events[i].events & EPOLLHUP) ||  
              (!(events[i].events & EPOLLIN))) 
        	{
            	perror("epoll error!");
              	close(events[i].data.fd); 
              	continue;
          	}
          	else if(events[i].data.fd == pCRoute->info_fd)
          	{
          		while(1)
          		{
          			struct sockaddr in_addr;  
				    socklen_t in_len;  
				    int infd;  
			
				    in_len = sizeof(in_addr); 
				    infd = accept (pCRoute->info_fd, &in_addr, &in_len); 
				    if (infd == -1)  
                    {  
                      if ((errno == EAGAIN) || (errno == EWOULDBLOCK))  
                        {  
                          /* We have processed all incoming 
                             connections. */  
                          break;  
                        }  
                      else  
                        {  
                          perror ("accept");  
                          break;  
                        }  
                    } 

	                if(make_socket_non_blocking (infd) == -1)  
	                	exit(-1);

	                event.data.fd = infd;
	                event.events = EPOLLIN | EPOLLET;
	                if(epoll_ctl(efd,EPOLL_CTL_ADD,infd,&event) == -1)
	                	exit(-1);
          		}
          		continue;
          	}
          	else if(events[i].events & EPOLLIN)
          	{
          		int n = 0; 
          		int nread; 
          		int fd = events[i].data.fd;

				while ((nread = read(fd, pCRoute->infobuf + n, BUFLEN)) > 0) 
				{  
				    n += nread;  
				}  
				if (nread == -1 && errno != EAGAIN) 
				{  
				    perror("read error"); 
				    continue;
				}  
				if (nread == 0)
				{
					event.data.fd = fd;
	                event.events = EPOLLIN | EPOLLET;
					epoll_ctl(efd,EPOLL_CTL_DEL,fd,&event);

					close(fd);
					continue;
				}

				event.data.fd = fd;
                event.events = EPOLLOUT | EPOLLET;
				epoll_ctl(efd,EPOLL_CTL_MOD,fd,&event);

          	}
          	else if(events[i].events & EPOLLOUT)
          	{
          		int nwrite, data_size = strlen(pCRoute->infobuf);  
				int n = data_size;  
				int fd = events[i].data.fd;
				while (n > 0) 
				{  
				    nwrite = write(fd, pCRoute->infobuf + data_size - n, n);  
				    if (nwrite < n) 
				    {  
				        if (nwrite == -1 && errno != EAGAIN)
				        {  
				            perror("write error");  
				            break;
				        }  
				         
				    }  
				    if(nwrite == 0)  // the other side closed
				    {
				    	event.data.fd = fd;
		                event.events = EPOLLOUT | EPOLLET;
						epoll_ctl(efd,EPOLL_CTL_DEL,fd,&event);

						close(fd);
						break;
				    }
				    n -= nwrite;  
				}
				// 重新监听EPOLLIN事件
				if(n == 0)  //
				{
					event.data.fd = fd;
                	event.events = EPOLLIN | EPOLLET;
					epoll_ctl(efd,EPOLL_CTL_MOD,fd,&event);
				}
          	}

        }
    }
}
Пример #26
0
int main(int argc, char **argv)
{
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = SIG_IGN;
	sa.sa_flags = 0;
	if(sigaction(SIGPIPE, &sa, NULL)) {
		LOG_ERR("SIGPIPE ERR");
		return 0;
	}

	int listenfd;
	listenfd = open_listenfd(8888);

	make_socket_non_blocking(listenfd);

	int epfd = tiny_epoll_create(0);
	struct epoll_event event;
	event.data.fd = listenfd;
	event.events = EPOLLIN | EPOLLET;
	tiny_epoll_add(epfd, listenfd, &event);

	tiny_threadpool_t *tp = threadpool_init(2);

	while(1) {
		int n = tiny_epoll_wait(epfd, events, MAXEVENTS, -1);
		int i = 0;
		for(;i < n;++i){
			if (listenfd == events[i].data.fd) {
				while(1) {
					struct sockaddr_in clientaddr;
					socklen_t inlen = sizeof(clientaddr);

					int infd = accept(listenfd, (struct sockaddr*)&clientaddr,&inlen);
					if (infd == -1) {
						if((errno == EAGAIN) || (errno == EWOULDBLOCK))
							break;
						else{
							LOG_ERR("accept err");
							break;
						}
					}
					LOG_INFO("new client fd : %d",infd);

					make_socket_non_blocking(infd);

					event.data.fd = infd;
					event.events = EPOLLIN | EPOLLET;
					tiny_epoll_add(epfd, infd, &event);
				}
			}
			else {
				if((events[i].events & EPOLLERR)
						|| (events[i].events & EPOLLHUP)
						|| !(events[i].events & EPOLLIN)) {
					LOG_ERR("epoll error fd : %d",events[i].data.fd);
					close(events[i].data.fd);
					continue;
				}

				LOG_INFO("new task from fd : %d", events[i].data.fd);
				threadpool_add(tp,accept_request,&(events[i].data.fd));
			}
		}
	}
	LOG_INFO("begin destroy");
	if(threadpool_destroy(tp,1) < 0)
		LOG_ERR("idestroy err");

	return 0;

}
Пример #27
0
void EpollServer::serve() {

#ifdef THREADED_SERVE
	init_thread();
#endif

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

	sfd = makeSvrSocket();
	if (sfd == -1)
		abort();

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

	reuseSock(sfd);

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

	event.data.ptr = new EpollData(sfd, NULL);
	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 = (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++) {

			EpollData *edata = (EpollData*) events[i].data.ptr;

			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(edata->fd());
				delete edata;
				continue;
			} else if (sfd == edata->fd()) {

				if (_tcp == true) {
					/* We have a notification on the listening socket, which
					 means one or more incoming connections. */
					while (1) {

						sockaddr *in_addr = (sockaddr *) calloc(1,
								sizeof(struct sockaddr));
						socklen_t in_len = sizeof(struct sockaddr);

						int infd = accept(sfd, in_addr, &in_len);
						if (infd == -1) {

							free(in_addr);

							if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {

								/* We have processed all incoming connections. */
								break;
							} else {

								perror("accept");
								break;
							}
						}

						/* fprintf(stdout,
						 "sin_family[%hu], sin_zero[%s], sin_addr.s_addr[%u], sin_port[%hu]\n",
						 in_addr.sin_family, in_addr.sin_zero,
						 in_addr.sin_addr.s_addr, in_addr.sin_port);
						 */

						/*
						 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
						 getnameinfo(in_addr, in_len, hbuf, sizeof hbuf, sbuf,
						 sizeof sbuf, 0);

						 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) {

							free(in_addr);
							abort();
						}

						reuseSock(infd);

						event.data.ptr = new EpollData(infd, in_addr);
						event.events = EPOLLIN | EPOLLET;
						s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event);
						if (s == -1) {

							free(in_addr);
							perror("epoll_ctl");
							abort();
						}
					}
					continue;
				} else {

					int done = 0;

					while (1) {

						char buf[Env::BUF_SIZE];
						memset(buf, 0, sizeof(buf));
						//char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char));

						sockaddr fromaddr;
						socklen_t sender_len = sizeof(struct sockaddr);
						ssize_t count = recvfrom(edata->fd(), buf, sizeof buf,
								0, &fromaddr, &sender_len);
						//cout << "EpollServer.cpp: serve(): received "<< count << " bytes."<<endl;
						if (count == -1) {

							if (errno != EAGAIN) {

								perror("read");
								done = 1;
							}

						} else if (count == 0) {

							done = 1;
							break;

						} else {

#ifdef BIG_MSG
							bool ready = false;
							string bd = pbrb->getBdStr(sfd, buf, count, ready);

							if (ready) {

#ifdef THREADED_SERVE
								EventData eventData(edata->fd(), bd.c_str(), bd.size(),
										fromaddr);
								_eventQueue.push(eventData);

#else
								_ZProcessor->process(edata->fd(), bd.c_str(),
										fromaddr);
#endif
							}
#endif

#ifdef SML_MSG
#ifdef THREADED_SERVE
							EventData eventData(edata->fd(), buf, sizeof(buf),
									fromaddr);
							_eventQueue.push(eventData);

#else
							string bufstr(buf);
							_ZProcessor->process(edata->fd(), bufstr.c_str(),
									fromaddr);
#endif
#endif
						}

						//memset(buf, 0, sizeof(buf));
						//free(buf);
					}

					/*if (done) {

					 close(edata->fd());
					 delete edata;
					 }*/
				}

			} else {

				if (_tcp == true) {

					/* 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) {

						char buf[Env::BUF_SIZE];
						memset(buf, 0, sizeof(buf));
						//char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char));

						ssize_t count = recv(edata->fd(), buf, sizeof(buf), 0);

						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;
							} /*else {

							 printf(
							 "Closed connection on descriptor %d, -1<--recv\n",
							 edata->fd());

							 close(edata->fd());
							 delete edata;
							 }*/
							break;
						} else if (count == 0) {

							/* End of file. The remote has closed the
							 connection. */
							done = 1;
							break;
						} else {

#ifdef BIG_MSG
							bool ready = false;
							string bd = pbrb->getBdStr(sfd, buf, count, ready);

							if (ready) {

#ifdef THREADED_SERVE
								EventData eventData(edata->fd(), bd.c_str(), bd.size(),
										*edata->sender());
								_eventQueue.push(eventData);
#else
								_ZProcessor->process(edata->fd(), bd.c_str(),
										*edata->sender());
#endif
							}
#endif

#ifdef SML_MSG
#ifdef THREADED_SERVE
							EventData eventData(edata->fd(), buf, sizeof(buf),
									*edata->sender());
							_eventQueue.push(eventData);
#else
							string bufstr(buf);
							_ZProcessor->process(edata->fd(), bufstr.c_str(),
									*edata->sender());
#endif
#endif
						}

						//memset(buf, 0, sizeof(buf));
						//free(buf);
					}

					if (done) {

						/*printf("Closed connection on descriptor %d, done.\n",
						 edata->fd());*/

						/* Closing the descriptor will make epoll remove it
						 from the set of descriptors which are monitored. */
						close(edata->fd());
						delete edata;
					}
				} //if TCP == true
			}
		}
	}

	free(events);

	close(sfd);

	EpollData *edata = (EpollData*) event.data.ptr;
	delete edata;
}
Пример #28
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_create");
        abort ();
    }
    event.data.fd = sfd;
    event.events = EPOLLIN | EPOLLET;
    // READ AND ET
    s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
    if (s == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
    /* Buffer where events are returned */
    /* function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. */
    /* max event is 64 */
    events = calloc (MAXEVENTS, sizeof event);
    /* The event loop */
    while (1)
    {
        printf("wait here\n");
        int n, i;
        // RETURN THE ERADY NUMBS
        // ET AND LT only for the epoll_wait
        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;
                    // if there is connection wait to process it will return the
                    // infd
                    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;
                        }
                    }
                    //it converts a socket address to a corresponding host and service
                    //return numeric host and service
                    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 */
                    s = write (1, buf, count);
                    if (s == -1)
                    {
                        perror ("write");
                        abort ();
                    }
                }
                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;
}
Пример #29
0
int main(int argc, char **argv) 
{
	int listenfd, connfd, port, clientlen;
	struct sockaddr_in clientaddr;

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

	/* Check command line args */
	if (argc != 2) {
		fprintf(stderr, "usage: %s <port>\n", argv[0]);
		exit(1);
	}
	port = atoi(argv[1]);

	Signal(SIGCHLD, sigchld_handler);
	listenfd = Open_listenfd(port);
	s = make_socket_non_blocking(listenfd);
	if (s == -1)
		exit(1);

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

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

	/* Buffer where events are returned */
	events = calloc(MAXEVENTS, sizeof event);
	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(listenfd == events[i].data.fd)
			{
				/* We have a notification on the listening socket, which
					 means one or more incoming connections. */
				while (1)
				{
					int infd;

					clientlen = sizeof(clientaddr);
					infd = accept(listenfd, (SA *)&clientaddr, (socklen_t*)&clientlen);
					if (infd == -1)
					{
						if ((errno == EAGAIN) ||
								(errno == EWOULDBLOCK))
						{
							/* We have processed all incoming
								 connections. */
							break;
						}
						else
						{
							perror("accept");
							break;
						}
					}

					/* 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. */

				doit(events[i].data.fd);		/* Child serves client */
				Close(events[i].data.fd);		/* Child closes connection with client */
			}
		}
	}

	free(events);
	Close(connfd);			/* Parent closes connected socket (signicant!) */
}
Пример #30
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;
}