mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-22 11:40:29 +03:00
refactor: move udp timeout management to udp module
This commit is contained in:
parent
d4d9dbb8e7
commit
207d482189
6
Makefile
6
Makefile
@ -27,10 +27,10 @@ CC ?= gcc
|
||||
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV)
|
||||
|
||||
LIBS=-lm -lpcre2-8
|
||||
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o gap.o
|
||||
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o
|
||||
FORK_OBJS=sslh-fork.o $(OBJS)
|
||||
SELECT_OBJS=sslh-select.o $(OBJS) processes.o
|
||||
EV_OBJS=sslh-ev.o $(OBJS) processes.o
|
||||
SELECT_OBJS=sslh-select.o $(OBJS) processes.o udp-listener.o
|
||||
EV_OBJS=sslh-ev.o $(OBJS) processes.o udp-listener.o
|
||||
|
||||
CONDITIONAL_TARGETS=
|
||||
|
||||
|
@ -224,7 +224,7 @@ int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen
|
||||
break;
|
||||
|
||||
case SOCK_DGRAM:
|
||||
new_fd = udp_c2s_forward(fd, fd_info->collection, watchers_maxfd(fd_info->watchers));
|
||||
new_fd = udp_c2s_forward(fd, fd_info);
|
||||
print_message(msg_fd, "new_fd %d\n", new_fd);
|
||||
if (new_fd == -1)
|
||||
return -1;
|
||||
|
@ -30,8 +30,6 @@
|
||||
|
||||
#define __LINUX__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "probe.h"
|
||||
#include "udp-listener.h"
|
||||
@ -113,41 +111,6 @@ static int fd_is_in_range(int fd) {
|
||||
|
||||
|
||||
|
||||
/* Check all connections to see if a UDP connections has timed out, then free
|
||||
* it. At the same time, keep track of the closest, next timeout. Only do the
|
||||
* search through connections if that timeout actually happened. If the
|
||||
* connection that would have timed out has had activity, it doesn't matter: we
|
||||
* go through connections to find the next timeout, which was needed anyway. */
|
||||
static void udp_timeouts(struct loop_info* fd_info)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now < fd_info->next_timeout) return;
|
||||
|
||||
time_t next_timeout = INT_MAX;
|
||||
|
||||
for (int i = 0; i < watchers_maxfd(fd_info->watchers); i++) {
|
||||
/* if it's either in read or write set, there is a connection
|
||||
* behind that file descriptor */
|
||||
struct connection* cnx = collection_get_cnx_from_fd(fd_info->collection, i);
|
||||
if (cnx) {
|
||||
time_t timeout = udp_timeout(cnx);
|
||||
if (!timeout) continue; /* Not a UDP connection */
|
||||
if (cnx && (timeout <= now)) {
|
||||
print_message(msg_fd, "timed out UDP %d\n", cnx->target_sock);
|
||||
close(cnx->target_sock);
|
||||
watchers_del_read(fd_info->watchers, i);
|
||||
watchers_del_write(fd_info->watchers, i);
|
||||
collection_remove_cnx(fd_info->collection, cnx);
|
||||
} else {
|
||||
if (timeout < next_timeout) next_timeout = timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (next_timeout != INT_MAX)
|
||||
fd_info->next_timeout = next_timeout;
|
||||
}
|
||||
|
||||
/* Main loop: the idea is as follow:
|
||||
* - fds_r and fds_w contain the file descriptors to monitor in read and write
|
||||
@ -192,10 +155,6 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
if (res < 0)
|
||||
perror("select");
|
||||
|
||||
|
||||
/* UDP timeouts: clear out connections after some idle time */
|
||||
udp_timeouts(&fd_info);
|
||||
|
||||
/* Check main socket for new connections */
|
||||
for (i = 0; i < num_addr_listen; i++) {
|
||||
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
||||
|
@ -20,12 +20,58 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "probe.h"
|
||||
#include "sslh-conf.h"
|
||||
#include "udp-listener.h"
|
||||
|
||||
|
||||
/* returns date at which this socket times out. */
|
||||
static int udp_timeout(struct connection* cnx)
|
||||
{
|
||||
if (cnx->type != SOCK_DGRAM) return 0; /* Not a UDP connection */
|
||||
|
||||
return cnx->proto->udp_timeout + cnx->last_active;
|
||||
}
|
||||
|
||||
/* Check all connections to see if a UDP connections has timed out, then free
|
||||
* it. At the same time, keep track of the closest, next timeout. Only do the
|
||||
* search through connections if that timeout actually happened. If the
|
||||
* connection that would have timed out has had activity, it doesn't matter: we
|
||||
* go through connections to find the next timeout, which was needed anyway. */
|
||||
void udp_timeouts(struct loop_info* fd_info)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now < fd_info->next_timeout) return;
|
||||
|
||||
time_t next_timeout = INT_MAX;
|
||||
|
||||
for (int i = 0; i < watchers_maxfd(fd_info->watchers); i++) {
|
||||
/* if it's either in read or write set, there is a connection
|
||||
* behind that file descriptor */
|
||||
struct connection* cnx = collection_get_cnx_from_fd(fd_info->collection, i);
|
||||
if (cnx) {
|
||||
time_t timeout = udp_timeout(cnx);
|
||||
if (!timeout) continue; /* Not a UDP connection */
|
||||
if (cnx && (timeout <= now)) {
|
||||
print_message(msg_fd, "timed out UDP %d\n", cnx->target_sock);
|
||||
close(cnx->target_sock);
|
||||
watchers_del_read(fd_info->watchers, i);
|
||||
watchers_del_write(fd_info->watchers, i);
|
||||
collection_remove_cnx(fd_info->collection, cnx);
|
||||
} else {
|
||||
if (timeout < next_timeout) next_timeout = timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (next_timeout != INT_MAX)
|
||||
fd_info->next_timeout = next_timeout;
|
||||
}
|
||||
|
||||
/* Find if the specified source has been seen before. -1 if not found
|
||||
*
|
||||
* TODO This is linear search and needs to be changed to something better for
|
||||
@ -53,12 +99,14 @@ static int known_source(cnx_collection* collection, int max_fd, struct sockaddr*
|
||||
* Returns: >= 0 sockfd of newly allocated socket, for new connections
|
||||
* -1 otherwise
|
||||
* */
|
||||
int udp_c2s_forward(int sockfd, cnx_collection* collection, int max_fd)
|
||||
int udp_c2s_forward(int sockfd, struct loop_info* fd_info)
|
||||
{
|
||||
char addr_str[NI_MAXHOST+1+NI_MAXSERV+1];
|
||||
struct sockaddr src_addr;
|
||||
struct addrinfo addrinfo;
|
||||
struct sslhcfg_protocols_item* proto;
|
||||
cnx_collection* collection = fd_info->collection;
|
||||
int max_fd = watchers_maxfd(fd_info->watchers);
|
||||
struct connection* cnx;
|
||||
ssize_t len;
|
||||
socklen_t addrlen;
|
||||
@ -67,6 +115,8 @@ int udp_c2s_forward(int sockfd, cnx_collection* collection, int max_fd)
|
||||
This will do. Dynamic allocation is possible with the MSG_PEEK flag in recvfrom(2), but that'd imply
|
||||
malloc/free overhead for each packet, when really 64K is not that much */
|
||||
|
||||
udp_timeouts(fd_info);
|
||||
|
||||
addrlen = sizeof(src_addr);
|
||||
len = recvfrom(sockfd, data, sizeof(data), 0, &src_addr, &addrlen);
|
||||
if (len < 0) {
|
||||
@ -125,12 +175,3 @@ void udp_s2c_forward(struct connection* cnx)
|
||||
cnx->last_active = time(NULL);
|
||||
}
|
||||
|
||||
|
||||
/* returns date at which this socket times out. */
|
||||
int udp_timeout(struct connection* cnx)
|
||||
{
|
||||
if (cnx->type != SOCK_DGRAM) return 0; /* Not a UDP connection */
|
||||
|
||||
return cnx->proto->udp_timeout + cnx->last_active;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define UDPLISTENER_H
|
||||
|
||||
#include "collection.h"
|
||||
#include "processes.h"
|
||||
#include "common.h"
|
||||
|
||||
/* UDP listener: upon incoming packet, find where it should go
|
||||
@ -15,15 +16,9 @@ void udp_listener(struct listen_endpoint* endpoint, int num_endpoints, int activ
|
||||
* Returns: >= 0 sockfd of newly allocated socket, for new connections
|
||||
* -1 otherwise
|
||||
* */
|
||||
int udp_c2s_forward(int sockfd, cnx_collection* collection, int max_fd);
|
||||
int 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);
|
||||
|
||||
|
||||
/* returns how many seconds before socket times out. Negative if timed out
|
||||
* already.
|
||||
*/
|
||||
int udp_timeout(struct connection* cnx);
|
||||
|
||||
#endif /* UDPLISTENER_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user