int EpollSocket::handle_accept_event(int &epollfd, epoll_event &event, EpollSocketWatcher &socket_handler) {
    int sockfd = event.data.fd;

    std::string client_ip;
    int conn_sock = accept_socket(sockfd, client_ip);
    if (conn_sock == -1) {
        return -1;
    }
    setNonblocking(conn_sock);
    LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

    EpollContext *epoll_context = new EpollContext();
    epoll_context->fd = conn_sock;
    epoll_context->client_ip = client_ip;

    socket_handler.on_accept(*epoll_context);

    struct epoll_event conn_sock_ev;
    conn_sock_ev.events = EPOLLIN | EPOLLET;
    conn_sock_ev.data.ptr = epoll_context;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
        perror("epoll_ctl: conn_sock");
        exit(EXIT_FAILURE);
    }

    return 0;
}
Exemple #2
0
static void server_work(struct work_struct *work)
{
    struct socket *server_socket;
    struct socket *slave_socket;
    kkv_server *server;
    kkv_session *session;

    server=container_of(work,kkv_server,work);
    server_socket=server->socket;
again:
    slave_socket=accept_socket(server_socket);
    if (!slave_socket)
        return;

    session=create_session(session_work_socket,slave_socket);
    if(!session) {
#ifdef DEBUG_KKV_NETWORK
        printk("create_session() failed\n");
#endif
        goto out;
    }

    set_slave_sk_callbacks(slave_socket,session);
    goto again;
out:
    slave_socket->ops->shutdown(slave_socket,SHUT_RDWR);
    sock_release(slave_socket);
}
Exemple #3
0
int CEpollSocket::handle_accept_event(int epollfd, epoll_event &event, CEpollSocketWatcher &socket_handler) {
    int sockfd = event.data.fd;

    std::string client_ip;
    int conn_sock = accept_socket(sockfd, client_ip);
    if (conn_sock == -1) {
        return -1;
    }
    setNonblocking(conn_sock);
    LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

    CEpollContext *epoll_context = new CEpollContext();
    epoll_context->fd = conn_sock;
    epoll_context->client_ip = client_ip;

    socket_handler.on_accept(*epoll_context);

    struct epoll_event conn_sock_ev;
    conn_sock_ev.events = EPOLLIN;
    conn_sock_ev.data.ptr = epoll_context;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
        LOG_ERROR("epoll_ctl: conn_sock:%s", strerror(errno));
        return -1;
    }

    return 0;
}
Exemple #4
0
client_t OPJ_CALLCONV accept_connection( dec_server_record_t *rec)
{
  client_t client;
  
  client = accept_socket( rec->listening_socket);
  if( client == -1)
    fprintf( stderr, "error: failed to connect to client\n");
  
  return client;
}
Exemple #5
0
static gpointer listen_thread (gpointer data)
{
    HTTPServer *http_server = (HTTPServer *)data;
    struct epoll_event event_list[kMaxRequests];
    gint n, i;

    for (;;) {
        n = epoll_wait (http_server->epollfd, event_list, kMaxRequests, -1);
        if (n == -1) {
            GST_WARNING ("epoll_wait error %s", g_strerror (errno));
            continue;
        }
        for (i = 0; i < n; i++) {
            RequestData *request_data;

            if (event_list[i].data.ptr == NULL) {
                /* new request arrived */
                accept_socket (http_server);
                continue;
            }

            request_data = *(RequestData **)(event_list[i].data.ptr);
            g_mutex_lock (&(request_data->events_mutex));
            request_data->events |= event_list[i].events;
            g_mutex_unlock (&(request_data->events_mutex));

            /* push to thread pool queue */
            if ((event_list[i].events & EPOLLIN) && (request_data->status == HTTP_CONNECTED)) {
                GError *err = NULL;

                GST_DEBUG ("event on sock %d events %d", request_data->sock, request_data->events);
                request_data->status = HTTP_REQUEST;
                g_thread_pool_push (http_server->thread_pool, event_list[i].data.ptr, &err);
                if (err != NULL) {
                    GST_FIXME ("Thread pool push error %s", err->message);
                    g_error_free (err);
                }
            } 

            if (event_list[i].events & (EPOLLOUT | EPOLLIN | EPOLLHUP | EPOLLERR)) {
                if ((request_data->status == HTTP_BLOCK) || (request_data->status == HTTP_REQUEST)) {
                    g_mutex_lock (&(http_server->block_queue_mutex));
                    g_cond_signal (&(http_server->block_queue_cond));
                    g_mutex_unlock (&(http_server->block_queue_mutex));
                }
            }

            GST_DEBUG ("event on sock %d events %s", request_data->sock, epoll_event_string (event_list[i]));
        }
    }

    return NULL;
}
void start_server(int port, void (*post_cb) (post_content_t*))
{
    int listen_fd;
    listen_fd = get_tcp_socket();
    set_enable_port_reuse(listen_fd);
    bind_socket(listen_fd, port);
    prepare_listen(listen_fd, 5);

    intlist_t* socklist = intlist_add(NULL, listen_fd);

    fd_set readfds;
    int r;
    int max;
    while(true){
        FD_ZERO(&readfds);
        intlist_t* cursor = socklist;
        while(cursor != NULL){
            FD_SET(cursor->value, &readfds);
            cursor = cursor->next;
        }
        max = intlist_max(socklist);
        r = select(max + 1,
                   &readfds,
                   NULL,
                   NULL,
                   NULL);
        if(r == -1){
            perror("select error");
            exit(EXIT_FAILURE);
        }
        else{
            intlist_t* cursor = socklist;
            while(cursor != NULL){
                if(FD_ISSET(cursor->value, &readfds)){
                    if(cursor->value == listen_fd){
                        int client_fd = accept_socket(cursor->value);
                        intlist_add(socklist, client_fd);
                    }
                    else{
                        read_socket(cursor->value, post_cb);
                        // TODO: write HTTP/1.1 200 OK if read success
                        close(cursor->value);
                        intlist_del(socklist, cursor->value);
                    }
                }
                cursor = cursor->next;
            }
        }
    }
}
void ServerSocket::run_socket(void){
    listen_socket(10);

    while(1){
        connfd = accept_socket((struct sockaddr*)&client_addr, sizeof(client_addr)); //casting on pointers
        std::cout << "Accepted connection status: " << connfd << "\n";
        if(connfd < 0){
           exit(1);
        };
        printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
        printf("port is: %d\n", (int) ntohs(client_addr.sin_port));

    };
};
Exemple #8
0
MODULE accept_client_connection (THREAD *thread)
{
    sock_t
        slave_socket;                   /*  Connected socket                 */

    tcb = thread-> tcb;                 /*  Point to thread's context        */
    slave_socket = accept_socket (tcb-> handle);
    if (slave_socket != INVALID_SOCKET)
      {
        close_socket (tcb-> handle);
        tcb-> handle = slave_socket;
      }
    else
    if (sockerrno != EAGAIN)
        raise_exception (exception_event);
}
void tcp_server_fd_isset(tcp_server_ctx_t* ctx, fd_set *readfds)
{
    /* 1. check client sockets */
    socketlist_t* cursor = ctx->client_sockets;
    while(cursor != NULL){
        if(FD_ISSET(cursor->socket, readfds)){
            read_socket(ctx, cursor);
        }
        cursor = cursor->next;
    }

    /* 2. check listen socket */
    if(FD_ISSET(ctx->listen_socket, readfds)){
        accept_socket(ctx);
    }
}
Exemple #10
0
MODULE reply_ok_result (THREAD *thread)
{
    SOCK_HANDLE_ITEM
        *socket;
    char
        *error_text;
    int
        rc;

    tcb = thread-> tcb;                 /*  Point to thread's context        */

    /*  We rely here on tcb-> handle being the master socket for an accept   */
    /*  and zero for any other request.                                      */
    if (tcb-> handle)
      {
        socket = memt_alloc (NULL, sizeof (SOCK_HANDLE_ITEM));
        socket-> links     = 0;
        socket-> handle    = accept_socket (tcb-> handle);
        socket-> error_msg = NULL;

        assign_pointer (& tcb-> result-> value, & sock_handle_class, socket);
      }

    if (tcb-> sock_handle)
        rc = store_sock_error (tcb-> sock_handle,
                               tcb-> gsl_thread,
                               tcb-> context,
                               tcb-> error,
                               NULL,
                               &error_text);
    else
        rc = store_module_error (tcb-> gsl_thread,
                                 tcb-> context,
                                 tcb-> error,
                                 NULL,
                                 &error_text);

    if (rc)
        lsend_ggcode_call_error (& tcb-> gsl_thread-> queue-> qid, NULL,
                                 NULL, NULL, NULL, 0,
                                 NULL, 0,
                                 error_text);
    else
        lsend_ggcode_call_ok (& tcb-> gsl_thread-> queue-> qid, NULL,
                              NULL, NULL, NULL, 0);
}
int
main(int argc, char** argv)
{
        int sd = accept_socket();

        if(sd < 0) {
                return 1;
        } else {
                IOPlexer ioplexer;
                if(!ioplexer.set(sd, IOHandler::EVENT_ACCEPT, do_accept)) {
                        perror("ioplexer");
                } else {
                        ioplexer.loop(30000);
                        printf("exit dispatch loop after being idle for 30s\n");
                }
                close(sd);
        }
        return 0;
}
Exemple #12
0
void
handle(reg fd)
{
	client.socket = accept_socket(fd,(server.http_sock == fd ? NULL : server.tls));
	close(fd);	// close the parent fd, as we'll never accept again
	nodelay(client.socket->fd);
	
#ifdef LINUX
	client.kq = epoll_create1(0);
#else
	client.kq = kqueue();
#endif
	client.request = open_request(client.socket);
	add_read_socket(client.socket->fd);
	timeout(IDLE_TIMEOUT,0);
	timer();
	while (!client.socket->closed && !client.alarm) run();
	exit(JAWAS_EXIT_DONE);
}
Exemple #13
0
void NetResMgr::OnTcpAccept(std::unique_ptr<tcp::AcceptBuffer> buffer) {
  auto listen_handle = buffer->handle();
  auto listen_socket = GetTcpSocket(listen_handle);
  if (!listen_socket) {
    return;
  }
  TcpSocketPtr accept_socket(buffer->accept_socket());
  if (!AsyncTcpAccept(listen_handle, listen_socket, std::move(buffer))) {
    callback_->OnTcpError(listen_handle, 1);
  }
  if (accept_socket->SetAccepted(listen_socket->socket()) && iocp_.BindToIocp((HANDLE)accept_socket->socket())) {
    auto accept_handle = INVALID_TCP_HANDLE;
    if (AddTcpSocket(accept_socket, accept_handle)) {
      callback_->OnTcpAccepted(listen_handle, accept_handle);
      if (!AsyncTcpRecv(accept_handle, accept_socket, nullptr)) {
        RemoveTcpSocket(accept_handle);
        callback_->OnTcpError(accept_handle, 2);
      }
    }
  }
}
Exemple #14
0
struct web_client *web_client_create_on_listenfd(int listener) {
    struct web_client *w;

    w = web_client_get_from_cache_or_allocate();
    w->ifd = w->ofd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_allow_connections_from);

    if(unlikely(!*w->client_ip))   strcpy(w->client_ip,   "-");
    if(unlikely(!*w->client_port)) strcpy(w->client_port, "-");

    if (w->ifd == -1) {
        if(errno == EPERM)
            web_server_log_connection(w, "ACCESS DENIED");
        else {
            web_server_log_connection(w, "CONNECTION FAILED");
            error("%llu: Failed to accept new incoming connection.", w->id);
        }

        web_client_release(w);
        return NULL;
    }

    web_client_initialize_connection(w);
    return(w);
}
Exemple #15
0
int CXSPAsyncSocket::AcceptSocket(struct sockaddr *addrp)
{
	return accept_socket(&m_socket, addrp);
}
Exemple #16
0
bool sbbs_t::ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest)
{
	char		cmd[512];
	char		rsp[512];
	char		path[MAX_PATH+1];
	char		buf[4097];
	int			rd;
	int			result;
	ulong		total=0;
	SOCKET		data_sock;
	union xp_sockaddr	addr;
	socklen_t	addr_len;
	FILE*		fp=NULL;
	bool		error=false;
	struct timeval	tv;
	fd_set			socket_set;

	SAFECOPY(path,src);

	if(!fexistcase(path))
		return(false);

	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET) {
		bprintf("ftp: failure, line %d",__LINE__);
		return(false);
	}

	if(csi->ftp_mode&CS_FTP_PASV) {

#if 0	// Debug
		bprintf("Connecting to %s:%hd\r\n"
			,inet_ntoa(addr.in.sin_addr)
			,ntohs(addr.in.sin_port));
#endif

		if(connect(data_sock,&addr.addr,sizeof(addr.in))!=0) {
			bprintf("ftp: failure, line %d",__LINE__);
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(false);
		}
	}

	if((fp=fopen(path,"rb"))==NULL) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	sprintf(cmd,"STOR %s",dest);

	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=150 /* Open data connection */) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	if(!(csi->ftp_mode&CS_FTP_PASV)) {	/* Normal (Active) FTP */

		/* Setup for select() */
		tv.tv_sec=TIMEOUT_SOCK_LISTEN;
		tv.tv_usec=0;

		FD_ZERO(&socket_set);
		FD_SET(data_sock,&socket_set);

		result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
		if(result<1) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		SOCKET accept_sock;

		addr_len=sizeof(addr);
		if((accept_sock=accept_socket(data_sock,&addr,&addr_len))
			==INVALID_SOCKET) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		close_socket(data_sock);
		data_sock=accept_sock;
	}

	while(online && !feof(fp)) {

		rd=fread(buf,sizeof(char),sizeof(buf),fp);
		if(rd<1) /* EOF or READ error */
			break;

		if(!socket_check(ctrl_sock,NULL,NULL,0))
			break; /* Control connection lost */

		if(sendsocket(data_sock,buf,rd)<1) {
			error=true;
			break;
		}

		total+=rd;
		
		if(csi->ftp_mode&CS_FTP_HASH)
			outchar('#');
	}

	if(csi->ftp_mode&CS_FTP_HASH) {
		CRLF;
	}

	fclose(fp);

	close_socket(data_sock);

	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
		|| atoi(rsp)!=226 /* Upload complete */)
		return(false);

	if(!error)
		bprintf("ftp: %lu bytes sent.\r\n", total);

	return(!error);
}
Exemple #17
0
bool sbbs_t::ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir)
{
	char		cmd[512];
	char		rsp[512];
	char		buf[4097];
	int			rd;
	int			result;
	BOOL		data_avail;
	ulong		total=0;
	SOCKET		data_sock;
	union xp_sockaddr	addr;
	socklen_t	addr_len;
	FILE*		fp=NULL;
	struct timeval	tv;
	fd_set			socket_set;

	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET)
		return(false);

	if(csi->ftp_mode&CS_FTP_PASV) {

#if 0	// Debug
		bprintf("Connecting to %s:%hd\r\n"
			,inet_ntoa(addr.in.sin_addr)
			,ntohs(addr.in.sin_port));
#endif

		/* TODO: IPv6 */
		if(connect(data_sock,&addr.addr,sizeof(SOCKADDR_IN))!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(false);
		}
	}

	if(dir)
		sprintf(cmd,"LIST %s",src);
	else
		sprintf(cmd,"RETR %s",src);

	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=150 /* Open data connection */) {
		close_socket(data_sock);
		return(false);
	}

	if(!(csi->ftp_mode&CS_FTP_PASV)) {	/* Normal (Active) FTP */

		/* Setup for select() */
		tv.tv_sec=TIMEOUT_SOCK_LISTEN;
		tv.tv_usec=0;

		FD_ZERO(&socket_set);
		FD_SET(data_sock,&socket_set);

		result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
		if(result<1) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		SOCKET accept_sock;

		addr_len=sizeof(addr);
		if((accept_sock=accept_socket(data_sock,&addr,&addr_len))
			==INVALID_SOCKET) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		close_socket(data_sock);
		data_sock=accept_sock;
	}

	if(!dir)
		if((fp=fopen(dest,"wb"))==NULL) {
			close_socket(data_sock);
			return(false);
		}

	while(online) {

		if(!socket_check(ctrl_sock,NULL,NULL,0))
			break; /* Control connection lost */

		if(!socket_check(data_sock,&data_avail,NULL,100))
			break; /* Data connection lost */

		if(!data_avail)
			continue;
	
		if((rd=recv(data_sock, buf, sizeof(buf)-1, 0))<1)
			break;

		if(dir) {
			buf[rd]=0;
			bputs(buf);
		} else
			fwrite(buf,1,rd,fp);

		total+=rd;
		
		if(!dir && csi->ftp_mode&CS_FTP_HASH)
			outchar('#');
	}

	if(!dir && csi->ftp_mode&CS_FTP_HASH) {
		CRLF;
	}

	if(fp!=NULL)
		fclose(fp);

	close_socket(data_sock);

	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
		|| atoi(rsp)!=226 /* Download complete */)
		return(false);

	bprintf("ftp: %lu bytes received.\r\n", total);

	return(true);
}
void redrobd_rc_net_server_thread::handle_clients(void)
{
  long rc;
  socket_address client_sa;
  char client_ip[DOTTED_IP_ADDR_LEN];
  ostringstream oss_msg;

  while (1) {
    
    oss_msg << "Wait for client on port:" << dec << m_server_port;
    redrobd_log_writeln(get_name() + " : " + oss_msg.str());
    oss_msg.str("");

    // Wait for client to connect
    rc = accept_socket(m_server_sd,
		       &m_client_sd,
		       &client_sa);
   
    // Check if controlled server shutdown
    if ( (rc != SOCKET_SUPPORT_SUCCESS) &&
	 (m_shutdown_requested) ) {

      // This was a controlled shutdown.
      // Quit server thread with no error.
      break;
    }
    else if (rc != SOCKET_SUPPORT_SUCCESS) {
      // This was not a controlled shutdown.
      // Quit server thread with error.
      THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED,
		"Accept server socket failed in thread %s",
		get_name().c_str());
    }
    else {
      m_client_connected = true;
    }

    // Get address info for connected client
    if (to_ip_address(client_sa.net_addr,
		      client_ip,
		      DOTTED_IP_ADDR_LEN) != SOCKET_SUPPORT_SUCCESS) {
      THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED,
		"Client address for server socket failed in thread %s",
		get_name().c_str());
    }
    oss_msg << "Client connected => " << client_ip
	    << ", port:" << dec << client_sa.port;
    redrobd_log_writeln(get_name() + " : " + oss_msg.str());
    oss_msg.str("");

    // Handle client commands
    bool handle_command = true;
    while (handle_command) {      
      
      try {
	uint16_t client_command;	

	// Wait for command
	recv_client((void *)&client_command,
		    sizeof(client_command));

	ntoh16(&client_command);

	// Handle command
	if (client_command == CLI_CMD_STEER) {
	  uint8_t steer_code;

	  // Get steer code
	  recv_client((void *)&steer_code,
		      sizeof(steer_code));

	  // Update latest steer code
	  pthread_mutex_lock(&m_steer_code_mutex);
	  m_steer_code = steer_code;
	  pthread_mutex_unlock(&m_steer_code_mutex);
	  	  
	}
	else if (client_command == CLI_CMD_GET_VOLTAGE) {
	  uint16_t voltage;

	  // Reply with latest voltage
	  pthread_mutex_lock(&m_voltage_mutex);
	  voltage = m_voltage;
	  pthread_mutex_unlock(&m_voltage_mutex);

	  hton16(&voltage);

	  send_client((void *)&voltage,
		      sizeof(voltage));
	}
	else if (client_command == CLI_CMD_CAMERA) {
	  uint8_t camera_code;

	  // Get camera code
	  recv_client((void *)&camera_code,
		      sizeof(camera_code));

	  // Update latest camera code
	  pthread_mutex_lock(&m_camera_code_mutex);
	  m_camera_code = camera_code;
	  pthread_mutex_unlock(&m_camera_code_mutex);
	}
	else if (client_command == CLI_CMD_GET_SYS_STATS) {
	  RC_NET_SYS_STAT sys_stat;

	  // Reply with latest system statistics
	  pthread_mutex_lock(&m_sys_stat_mutex);
	  memcpy(&sys_stat, &m_sys_stat, sizeof(m_sys_stat));	  
	  pthread_mutex_unlock(&m_sys_stat_mutex);

	  hton32(&sys_stat.mem_used);
	  hton16(&sys_stat.irq);
	  hton32(&sys_stat.uptime);
	  hton32(&sys_stat.cpu_temp);
	  hton16(&sys_stat.cpu_voltage);
	  hton16(&sys_stat.cpu_freq);

	  send_client((void *)&sys_stat,
		      sizeof(sys_stat));
	}
	else {
	  oss_msg << "Unknown client command : 0x"
		  << hex << (unsigned)client_command;
	  redrobd_log_writeln(get_name() + " : " + oss_msg.str());
	  oss_msg.str("");

	  handle_command = false;
	}
      }
      catch (...) {
	handle_command = false;
      }
    }
    
    if (m_shutdown_requested) {
      // This was a controlled shutdown.
      // Quit server thread with no error.
      break;
    }

    // Shutdown client socket
    if (shutdown_socket(m_client_sd,
			true,
			true) != SOCKET_SUPPORT_SUCCESS) {
      THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED,
		"Shutdown client socket failed in thread %s",
		get_name().c_str());
    }
    
    // Close client socket
    if (close_socket(m_client_sd) != SOCKET_SUPPORT_SUCCESS) {
      THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED,
		"Close client socket failed in thread %s",
		get_name().c_str());
    }

    m_client_connected = false;
  }
}
int EpollSocket::start_epoll(int port, EpollSocketWatcher &socket_handler, int backlog) {
	int sockfd = this->listen_on(port, backlog);

	struct epoll_event ev;
	int epollfd = epoll_create(10);
	if (epollfd == -1) {
		perror("epoll_create");
		exit(EXIT_FAILURE);
	}

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

	epoll_event events[10];

	while(1) {
		int fds_num = epoll_wait(epollfd, events, 10, -1);
		if(fds_num == -1) {
			perror("epoll_pwait");
			exit(EXIT_FAILURE);
		}

		for (int i = 0; i < fds_num; i++) {
			if(events[i].data.fd == sockfd) {
				int conn_sock = accept_socket(sockfd);
				setNonblocking(conn_sock);
				LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

				EpollContext *epoll_context = new EpollContext();
				epoll_context->fd = conn_sock;

				socket_handler.on_accept(*epoll_context);

				epoll_event conn_sock_ev;
				conn_sock_ev.events = EPOLLIN | EPOLLET;
				conn_sock_ev.data.ptr = epoll_context;

				if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
				   perror("epoll_ctl: conn_sock");
				   exit(EXIT_FAILURE);
				}

			} else if(events[i].events & EPOLLIN ){ // readable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;

				int buffer_size = 1024;
				char read_buffer[buffer_size];
				memset(read_buffer, 0, buffer_size);
				int read_size = 0;

				while((read_size = recv(fd, read_buffer, buffer_size, 0)) > 0) {
					LOG_DEBUG("read success which read size:%d", read_size);

					int ret = socket_handler.on_readable(*epoll_context, read_buffer, buffer_size, read_size);
					if(ret != 0) {
						close_and_release(epollfd, events[i], socket_handler);
						continue;
					}
					memset(read_buffer, 0, buffer_size); // reset buffer for next read
				}

				if(read_size == 0 /* connect close*/ || (read_size == -1 && errno != EAGAIN) /* io error*/) {
					LOG_DEBUG("read_size not normal which size:%d", read_size);
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLOUT | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);

			} else if(events[i].events & EPOLLOUT) { // writeable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;
				LOG_DEBUG("start write data");

				int ret = socket_handler.on_writeable(*epoll_context);
				if(ret != 0) {
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLIN | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);
			} else {
				LOG_INFO("unkonw events :%d", events[i].events);
				continue;
			}
		}
	}
}