Do not use select() anymore

This commit is contained in:
2022-08-17 22:34:01 +02:00
parent f0b27b3b37
commit 170337d4d5
4 changed files with 44 additions and 24 deletions

View File

@ -20,7 +20,7 @@
#include "lib/compress.h" #include "lib/compress.h"
#include <string.h> #include <string.h>
#include <sys/select.h> #include <poll.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
@ -28,13 +28,13 @@
#include <signal.h> #include <signal.h>
#include <arpa/inet.h> #include <arpa/inet.h>
int server_keep_alive = 1; int server_keep_alive = 1;
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0}; struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
int server_keep_alive; int server_keep_alive;
char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip; char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str; char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
struct timeval client_timeout;
host_config *get_host_config(const char *host) { host_config *get_host_config(const char *host) {
for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) { for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) {
@ -91,12 +91,8 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
clock_gettime(CLOCK_MONOTONIC, &begin); clock_gettime(CLOCK_MONOTONIC, &begin);
fd_set socket_fds; ret = sock_poll_read(&client, NULL, 1, CLIENT_TIMEOUT * 1000);
FD_ZERO(&socket_fds);
FD_SET(client->socket, &socket_fds);
client_timeout.tv_sec = CLIENT_TIMEOUT;
client_timeout.tv_usec = 0;
ret = select(client->socket + 1, &socket_fds, NULL, NULL, &client_timeout);
http_add_header_field(&res.hdr, "Date", http_get_date(buf0, sizeof(buf0))); http_add_header_field(&res.hdr, "Date", http_get_date(buf0, sizeof(buf0)));
http_add_header_field(&res.hdr, "Server", SERVER_STR); http_add_header_field(&res.hdr, "Server", SERVER_STR);
if (ret <= 0) { if (ret <= 0) {

View File

@ -12,6 +12,7 @@
#include <string.h> #include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <poll.h>
int sock_enc_error(sock *s) { int sock_enc_error(sock *s) {
return (int) s->enc ? SSL_get_error(s->ssl, (int) s->_last_ret) : 0; return (int) s->enc ? SSL_get_error(s->ssl, (int) s->_last_ret) : 0;
@ -117,3 +118,28 @@ int sock_check(sock *s) {
char buf; char buf;
return recv(s->socket, &buf, 1, MSG_PEEK | MSG_DONTWAIT) == 1; return recv(s->socket, &buf, 1, MSG_PEEK | MSG_DONTWAIT) == 1;
} }
int sock_poll(sock *sockets[], sock *ready[], short events, int n_sock, int timeout_ms) {
struct pollfd fds[n_sock];
for (int i = 0; i < n_sock; i++) {
fds[i].fd = sockets[i]->socket;
fds[i].events = events;
}
int ret = poll(fds, n_sock, timeout_ms);
if (ret < 0 || ready == NULL) return ret;
for (int i = 0, j = 0; i < ret; j++) {
if (fds[i].revents & events)
ready[i++] = sockets[j];
}
return ret;
}
int sock_poll_read(sock *sockets[], sock *readable[], int n_sock, int timeout_ms) {
return sock_poll(sockets, readable, POLLIN, n_sock, timeout_ms);
}
int sock_poll_write(sock *sockets[], sock *writable[], int n_sock, int timeout_ms) {
return sock_poll(sockets, writable, POLLOUT, n_sock, timeout_ms);
}

View File

@ -37,4 +37,10 @@ int sock_close(sock *s);
int sock_check(sock *s); int sock_check(sock *s);
int sock_poll(sock *sockets[], sock *readable[], short events, int n_sock, int timeout_ms);
int sock_poll_read(sock *sockets[], sock *readable[], int n_sock, int timeout_ms);
int sock_poll_write(sock *sockets[], sock *writable[], int n_sock, int timeout_ms);
#endif //NECRONDA_SERVER_SOCK_H #endif //NECRONDA_SERVER_SOCK_H

View File

@ -22,7 +22,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <sys/select.h> #include <poll.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -34,6 +34,7 @@
#include <openssl/conf.h> #include <openssl/conf.h>
#include <dirent.h> #include <dirent.h>
int active = 1; int active = 1;
const char *config_file; const char *config_file;
int sockets[NUM_SOCKETS]; int sockets[NUM_SOCKETS];
@ -153,8 +154,7 @@ void terminate() {
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
const int YES = 1; const int YES = 1;
fd_set socket_fds, read_socket_fds; struct pollfd poll_fds[NUM_SOCKETS];
int max_socket_fd = 0;
int ready_sockets_num; int ready_sockets_num;
long client_num = 0; long client_num = 0;
char buf[1024]; char buf[1024];
@ -169,8 +169,6 @@ int main(int argc, const char *argv[]) {
memset(children, 0, sizeof(children)); memset(children, 0, sizeof(children));
memset(mmdbs, 0, sizeof(mmdbs)); memset(mmdbs, 0, sizeof(mmdbs));
struct timeval timeout;
const struct sockaddr_in6 addresses[2] = { const struct sockaddr_in6 addresses[2] = {
{.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(80)}, {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(80)},
{.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(443)} {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(443)}
@ -338,29 +336,23 @@ int main(int argc, const char *argv[]) {
} }
} }
FD_ZERO(&socket_fds);
for (int i = 0; i < NUM_SOCKETS; i++) { for (int i = 0; i < NUM_SOCKETS; i++) {
FD_SET(sockets[i], &socket_fds); poll_fds[i].fd = sockets[i];
if (sockets[i] > max_socket_fd) { poll_fds[i].events = POLLIN;
max_socket_fd = sockets[i];
}
} }
fprintf(stderr, "Ready to accept connections\n"); fprintf(stderr, "Ready to accept connections\n");
while (active) { while (active) {
timeout.tv_sec = 1; ready_sockets_num = poll(poll_fds, NUM_SOCKETS, 1000);
timeout.tv_usec = 0;
read_socket_fds = socket_fds;
ready_sockets_num = select(max_socket_fd + 1, &read_socket_fds, NULL, NULL, &timeout);
if (ready_sockets_num < 0) { if (ready_sockets_num < 0) {
fprintf(stderr, ERR_STR "Unable to select sockets: %s" CLR_STR "\n", strerror(errno)); fprintf(stderr, ERR_STR "Unable to poll sockets: %s" CLR_STR "\n", strerror(errno));
terminate(); terminate();
return 1; return 1;
} }
for (int i = 0; i < NUM_SOCKETS; i++) { for (int i = 0; i < NUM_SOCKETS; i++) {
if (FD_ISSET(sockets[i], &read_socket_fds)) { if (poll_fds[i].revents & POLLIN) {
client_fd = accept(sockets[i], (struct sockaddr *) &client_addr, &client_addr_len); client_fd = accept(sockets[i], (struct sockaddr *) &client_addr, &client_addr_len);
if (client_fd < 0) { if (client_fd < 0) {
fprintf(stderr, ERR_STR "Unable to accept connection: %s" CLR_STR "\n", strerror(errno)); fprintf(stderr, ERR_STR "Unable to accept connection: %s" CLR_STR "\n", strerror(errno));