void handle_sock_from_epoll(LISTEN_SOCK *listen_sock, EPOLL_VARS *epoll_vars, void (*first_conn)(EPOLL_VARS *epoll_vars), void (*after_first_conn)(EPOLL_VARS *epoll_vars, int32_t which)) { int32_t conn_sock, nfds; /* nfds for notify file descriptors */ while(true) { nfds = epoll_wait(epoll_vars->epollfd, epoll_vars->events, MAX_EVENTS, -1); if (-1 == nfds) { printf("%s:%d\n",strerror(errno),errno); error("ERROR: By epoll_pwait!"); exit(EXIT_FAILURE); } for (int32_t i = 0; i < nfds; ++i) { if (epoll_vars->events[i].data.fd == listen_sock->listen_sock) { conn_sock = accept(listen_sock->listen_sock, (struct sockaddr *) &listen_sock->cli_addr, &listen_sock->clilen); if (-1 == conn_sock) { error("ERROR: By accept!"); exit(EXIT_FAILURE); } setnonblocking(conn_sock); epoll_vars->ev.events = EPOLLIN | EPOLLET; epoll_vars->ev.data.fd = conn_sock; if (-1 != epoll_ctl(epoll_vars->epollfd, EPOLL_CTL_ADD, conn_sock, &epoll_vars->ev)) { first_conn(epoll_vars); } else { error("ERROR: By epoll_ctl conn_sock!"); exit(EXIT_FAILURE); } } else { after_first_conn(epoll_vars, i); } } } close(listen_sock->listen_sock); }
// Get an element by socket struct proxied_connection *get_conn(int sock, struct proxied_connection *conns) { int index; conns = first_conn(conns); for(conns; conns->next; conns = conns->next) { if(conns->fsock == sock || conns->tsock == sock) return conns; } return NULL; }