From 536a1c03a55cc30e41dd12041238ec75706a8998 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Sun, 19 Jul 2020 21:02:35 +0200 Subject: nDPIsrvd: getting events from epoll and accepting new connections Signed-off-by: Toni Uhlig --- nDPIsrvd.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) (limited to 'nDPIsrvd.c') diff --git a/nDPIsrvd.c b/nDPIsrvd.c index 59ecba355..0c35100eb 100644 --- a/nDPIsrvd.c +++ b/nDPIsrvd.c @@ -8,10 +8,27 @@ #include #include #include +#include #include #include #include +enum ev_type { JSON_SOCK, SERV_SOCK }; + +struct event { + enum ev_type type; + union { + struct { + int json_sockfd; + struct sockaddr_un peer; + } event_json; + struct { + int serv_sockfd; + struct sockaddr_in peer; + } event_serv; + }; +}; + static char json_sockpath[UNIX_PATH_MAX] = "/tmp/ndpid-collector.sock"; static char serv_listen_addr[INET6_ADDRSTRLEN] = "127.0.0.1"; static uint16_t serv_listen_port = 7000; @@ -75,6 +92,20 @@ static int create_listen_sockets(void) return 1; } + int json_flags = fcntl(json_sockfd, F_GETFL, 0); + int serv_flags = fcntl(serv_sockfd, F_GETFL, 0); + if (json_flags == -1 || serv_flags == -1) + { + syslog(LOG_DAEMON | LOG_ERR, "Error getting fd flags: %s", strerror(errno)); + return 1; + } + if (fcntl(json_sockfd, F_SETFL, json_flags | O_NONBLOCK) == -1 || + fcntl(serv_sockfd, F_SETFL, serv_flags | O_NONBLOCK) == -1) + { + syslog(LOG_DAEMON | LOG_ERR, "Error setting fd flags: %s", strerror(errno)); + return 1; + } + return 0; } @@ -87,7 +118,67 @@ int main(void) return 1; } - getchar(); + int epollfd = epoll_create1(0); + if (epollfd < 0) + { + syslog(LOG_DAEMON | LOG_ERR, "Error creating epoll: %s", strerror(errno)); + return 1; + } + + struct epoll_event accept_event; + accept_event.data.fd = json_sockfd; + accept_event.events = EPOLLIN; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, json_sockfd, &accept_event) < 0) + { + syslog(LOG_DAEMON | LOG_ERR, "Error adding JSON fd to epoll: %s", strerror(errno)); + return 1; + } + accept_event.data.fd = serv_sockfd; + accept_event.events = EPOLLIN; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, serv_sockfd, &accept_event) < 0) + { + syslog(LOG_DAEMON | LOG_ERR, "Error adding INET fd to epoll: %s", strerror(errno)); + return 1; + } + + struct epoll_event events[32]; + size_t const events_size = sizeof(events) / sizeof(events[0]); + struct event remotes[64]; + size_t const remotes_size = sizeof(remotes) / sizeof(remotes[0]); + size_t remotes_used = 0; + struct event * remote_curr; + while (1) + { + int nready = epoll_wait(epollfd, events, events_size, -1); + + for (int i = 0; i < nready; i++) + { + if (events[i].events & EPOLLERR) + { + syslog(LOG_DAEMON | LOG_ERR, "Epoll event error: %s", strerror(errno)); + return 1; + } + + if (events[i].data.fd == json_sockfd || + events[i].data.fd == serv_sockfd) + { + if (remotes_used == remotes_size) { + syslog(LOG_DAEMON | LOG_ERR, "Max number of connections reached: %zu", remotes_used); + continue; + } + remote_curr = &remotes[remotes_used++]; + + enum ev_type type = (events[i].data.fd == json_sockfd ? JSON_SOCK : SERV_SOCK); + int sockfd = (events[i].data.fd == json_sockfd ? json_sockfd : serv_sockfd); + socklen_t peer_addr_len; + + int newsockfd = accept(sockfd, (type == JSON_SOCK ? (struct sockaddr *)&remote_curr->event_json.peer + : (struct sockaddr *)&remote_curr->event_serv.peer), + &peer_addr_len); + syslog(LOG_DAEMON, "New connection"); + } + } + } close(json_sockfd); close(serv_sockfd); -- cgit v1.2.3