From 750e828d4949053d8f58db25de52f67ce0afdd7e Mon Sep 17 00:00:00 2001 From: yrutschle Date: Sun, 22 May 2022 22:32:22 +0200 Subject: [PATCH] reinstate checking of FD_SETSIZE for sslh-select --- processes.c | 24 ++++++++++++++---------- processes.h | 2 +- sslh-select.c | 13 +++++++------ test.cfg | 4 ++-- udp-listener.c | 27 +++++++++++++++------------ udp-listener.h | 5 +++-- 6 files changed, 42 insertions(+), 33 deletions(-) diff --git a/processes.c b/processes.c index 0912d57..b7a748d 100644 --- a/processes.c +++ b/processes.c @@ -42,6 +42,13 @@ int tidy_connection(struct connection *cnx, struct loop_info* fd_info) free(cnx->q[i].deferred_data); } } + + if (cnx->type == SOCK_DGRAM) + udp_tidy(cnx, fd_info); + + if (gap_remove_ptr(fd_info->probing_list, cnx, fd_info->num_probing) != -1) + fd_info->num_probing--; + collection_remove_cnx(fd_info->collection, cnx); return 0; } @@ -73,28 +80,24 @@ void cnx_read_process(struct loop_info* fd_info, int fd) /* Process a connection that accepts a socket * (For UDP, this means all traffic coming from remote clients) - * Returns new file descriptor, or -1 + * Returns new connection object, or NULL * */ -int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket) +struct connection* cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket) { int fd = listen_socket->socketfd; int type = listen_socket->type; struct connection* cnx; - int new_fd = -1; switch (type) { case SOCK_STREAM: cnx = accept_new_connection(fd, fd_info); - if (!cnx) return -1; + if (!cnx) return NULL; - new_fd = cnx->q[0].fd; break; case SOCK_DGRAM: - new_fd = udp_c2s_forward(fd, fd_info); - print_message(msg_fd, "new_fd %d\n", new_fd); - if (new_fd == -1) - return -1; + cnx = udp_c2s_forward(fd, fd_info); + if (!cnx) return NULL; break; default: @@ -102,8 +105,9 @@ int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen exit(1); } + int new_fd = cnx->q[0].fd; watchers_add_read(fd_info->watchers, new_fd); - return new_fd; + return cnx; } diff --git a/processes.h b/processes.h index 6d3beef..b3c1ce8 100644 --- a/processes.h +++ b/processes.h @@ -27,7 +27,7 @@ struct loop_info { }; void cnx_read_process(struct loop_info* fd_info, int fd); -int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket); +struct connection* cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket); int tidy_connection(struct connection *cnx, struct loop_info* fd_info); diff --git a/sslh-select.c b/sslh-select.c index da1544a..2fcc0af 100644 --- a/sslh-select.c +++ b/sslh-select.c @@ -92,14 +92,12 @@ void watchers_del_write(watchers* w, int fd) /* if fd becomes higher than FD_SETSIZE, things won't work so well with FD_SET * and FD_CLR. Need to drop connections if we go above that limit */ -#warning strange things will happen if more than FD_SETSIZE descriptors are used -/* This test is currently not done */ -static int fd_is_in_range(int fd) { +static int fd_out_of_range(int fd) { if (fd >= FD_SETSIZE) { print_message(msg_system_error, "too many open file descriptor to monitor them all -- dropping connection\n"); - return 0; + return 1; } - return 1; + return 0; } @@ -155,7 +153,10 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen) /* Check main socket for new connections */ for (i = 0; i < num_addr_listen; i++) { if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) { - cnx_accept_process(&fd_info, &listen_sockets[i]); + struct connection* new_cnx = cnx_accept_process(&fd_info, &listen_sockets[i]); + + if (fd_out_of_range(new_cnx->q[0].fd)) + tidy_connection(new_cnx, &fd_info); /* don't also process it as a read socket */ FD_CLR(listen_sockets[i].socketfd, &readfds); diff --git a/test.cfg b/test.cfg index ecc4c74..c71a6b3 100644 --- a/test.cfg +++ b/test.cfg @@ -19,9 +19,9 @@ verbose-config-error: 1; # print configuration errors verbose-connections: 1; # trace established incoming address to forward address verbose-connections-error: 1; # connection errors verbose-connections-try: 1; # connection attempts towards targets -verbose-fd: 1; # file descriptor activity, open/close/whatnot +verbose-fd: 0; # file descriptor activity, open/close/whatnot verbose-packets: 1; # hexdump packets on which probing is done -verbose-probe-info: 1; # what's happening during the probe process +verbose-probe-info: 0; # what's happening during the probe process verbose-probe-error: 1; # failures and problems during probing verbose-system-error: 1; # system call problem, i.e. malloc, fork, failing verbose-int-error: 1; # internal errors, the kind that should never happen diff --git a/udp-listener.c b/udp-listener.c index ab5d3f1..e595718 100644 --- a/udp-listener.c +++ b/udp-listener.c @@ -173,9 +173,6 @@ void udp_timeouts(struct loop_info* fd_info) struct connection *cnx = cfg.protocols[i].timeouts.head; while (cnx && (now - cnx->last_active > cfg.protocols[i].udp_timeout)) { print_message(msg_fd, "timed out UDP %d\n", cnx->target_sock); - close(cnx->target_sock); - hash_remove(fd_info->hash_sources, cnx); - list_remove(&cnx->proto->timeouts, cnx); tidy_connection(cnx, fd_info); cnx = cfg.protocols[i].timeouts.head; @@ -183,6 +180,12 @@ void udp_timeouts(struct loop_info* fd_info) } } +void udp_tidy(struct connection* cnx, struct loop_info* fd_info) +{ + close(cnx->target_sock); + hash_remove(fd_info->hash_sources, cnx); + list_remove(&cnx->proto->timeouts, cnx); +} /* Mark the connection was active */ static void mark_active(struct connection* cnx) @@ -198,10 +201,10 @@ static void mark_active(struct connection* cnx) /* Process UDP coming from outside (client towards server) * If it's a new source, probe; otherwise, forward to previous target - * Returns: >= 0 sockfd of newly allocated socket, for new connections - * -1 otherwise + * Returns: newly allocate connections, for new connections + * NULL otherwise * */ -int udp_c2s_forward(int sockfd, struct loop_info* fd_info) +struct connection* udp_c2s_forward(int sockfd, struct loop_info* fd_info) { char addr_str[NI_MAXHOST+1+NI_MAXSERV+1]; struct sockaddr src_addr; @@ -223,7 +226,7 @@ int udp_c2s_forward(int sockfd, struct loop_info* fd_info) len = recvfrom(sockfd, data, sizeof(data), 0, &src_addr, &addrlen); if (len < 0) { perror("recvfrom"); - return -1; + return NULL; } target = known_source(fd_info->hash_sources, &src_addr, addrlen); addrinfo.ai_addr = &src_addr; @@ -238,14 +241,14 @@ int udp_c2s_forward(int sockfd, struct loop_info* fd_info) * run probes on packet sets */ print_message(msg_probe_info, "UDP probed: %d\n", res); if (res != PROBE_MATCH) { - return -1; + return NULL; } out = socket(proto->saddr->ai_family, SOCK_DGRAM, 0); res = set_nonblock(out); - CHECK_RES_RETURN(res, "udp:socket:nonblock", -1); + CHECK_RES_RETURN(res, "udp:socket:nonblock", NULL); struct connection* cnx = collection_alloc_cnx_from_fd(collection, out); - if (!cnx) return -1; + if (!cnx) return NULL; target = out; cnx->target_sock = out; cnx->proto = proto; @@ -258,7 +261,7 @@ int udp_c2s_forward(int sockfd, struct loop_info* fd_info) if (res == -1) { print_message(msg_connections_error, "Out of hash space for new incoming UDP connection -- increaѕe udp_max_connections"); collection_remove_cnx(collection, cnx); - return -1; + return NULL; } } cnx = collection_get_cnx_from_fd(collection, target); @@ -270,7 +273,7 @@ int udp_c2s_forward(int sockfd, struct loop_info* fd_info) print_message(msg_fd, "sending %d to %s\n", res, sprintaddr(data, sizeof(data), cnx->proto->saddr)); - return out; + return cnx; } void udp_s2c_forward(struct connection* cnx) diff --git a/udp-listener.h b/udp-listener.h index 57dcab2..51955a5 100644 --- a/udp-listener.h +++ b/udp-listener.h @@ -14,15 +14,16 @@ void udp_listener(struct listen_endpoint* endpoint, int num_endpoints, int activ /* Process UDP coming from outside (client towards server) * If it's a new source, probe; otherwise, forward to previous target - * Returns: >= 0 sockfd of newly allocated socket, for new connections + * Returns: newly allocate connections, for new connections * -1 otherwise * */ -int udp_c2s_forward(int sockfd, struct loop_info* fd_info); +struct connection* udp_c2s_forward(int sockfd, struct loop_info* fd_info); /* Process UDP coming from inside (server towards client) */ void udp_s2c_forward(struct connection* cnx); void udp_init(struct loop_info* fd_info); +void udp_tidy(struct connection* cnx, struct loop_info* fd_info); #endif /* UDPLISTENER_H */