mirror of
https://github.com/yrutschle/sslh.git
synced 2026-10-22 18:12:10 +03:00
keep track of next UDP timeout to only go through all connections when that happens
This commit is contained in:
1 parent
e4936454c5
commit
40da147efd
3 files changed
+36
-18
No files matched your search
+29
-6
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#define __LINUX__
|
#define __LINUX__
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "probe.h"
|
#include "probe.h"
|
||||||
#include "udp-listener.h"
|
#include "udp-listener.h"
|
||||||
@@ -51,6 +53,8 @@ struct select_info {
|
|||||||
|
|
||||||
fd_set fds_r, fds_w; /* reference fd sets (used to init working copies) */
|
fd_set fds_r, fds_w; /* reference fd sets (used to init working copies) */
|
||||||
cnx_collection* collection; /* Collection of connections linked to this loop */
|
cnx_collection* collection; /* Collection of connections linked to this loop */
|
||||||
|
|
||||||
|
time_t next_timeout; /* time at which next UDP connection times out */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -460,22 +464,41 @@ void cnx_accept_process(struct select_info* fd_info, struct listen_endpoint* lis
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void udp_timeouts(struct select_info* fd_info)
|
/* 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 select_info* fd_info)
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
if (now < fd_info->next_timeout) return;
|
||||||
|
|
||||||
for (int i = 0; i < fd_info->max_fd; i++) {
|
for (int i = 0; i < fd_info->max_fd; i++) {
|
||||||
|
time_t next_timeout = INT_MAX;
|
||||||
|
|
||||||
/* if it's either in read or write set, there is a connection
|
/* if it's either in read or write set, there is a connection
|
||||||
* behind that file descriptor */
|
* behind that file descriptor */
|
||||||
if (FD_ISSET(i, &fd_info->fds_r) || FD_ISSET(i, &fd_info->fds_w)) {
|
if (FD_ISSET(i, &fd_info->fds_r) || FD_ISSET(i, &fd_info->fds_w)) {
|
||||||
struct connection* cnx = collection_get_cnx_from_fd(fd_info->collection, i);
|
struct connection* cnx = collection_get_cnx_from_fd(fd_info->collection, i);
|
||||||
if (cnx && udp_timedout(now, cnx)) {
|
if (cnx) {
|
||||||
close(cnx->target_sock);
|
time_t timeout = udp_timeout(cnx);
|
||||||
FD_CLR(i, &fd_info->fds_r);
|
if (cnx && (timeout <= now)) {
|
||||||
FD_CLR(i, &fd_info->fds_w);
|
if (cfg.verbose > 3)
|
||||||
collection_remove_cnx(fd_info->collection, cnx);
|
fprintf(stderr, "timed out UDP %d\n", cnx->target_sock);
|
||||||
|
close(cnx->target_sock);
|
||||||
|
FD_CLR(i, &fd_info->fds_r);
|
||||||
|
FD_CLR(i, &fd_info->fds_w);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-9
@@ -128,17 +128,11 @@ void udp_s2c_forward(struct connection* cnx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks if a connection timed out, in which case close the socket and return
|
/* returns date at which this socket times out. */
|
||||||
* 1; otherwise return 0. */
|
int udp_timeout(struct connection* cnx)
|
||||||
int udp_timedout(time_t now, struct connection* cnx)
|
|
||||||
{
|
{
|
||||||
if (cnx->type != SOCK_DGRAM) return 0; /* Not a UDP connection */
|
if (cnx->type != SOCK_DGRAM) return 0; /* Not a UDP connection */
|
||||||
|
|
||||||
if ((now - cnx->last_active > cnx->proto->udp_timeout)) {
|
return cnx->proto->udp_timeout + cnx->last_active;
|
||||||
if (cfg.verbose > 3)
|
|
||||||
fprintf(stderr, "timed out UDP %d\n", cnx->target_sock);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+4
-3
@@ -20,8 +20,9 @@ int udp_c2s_forward(int sockfd, cnx_collection* collection, int max_fd);
|
|||||||
void udp_s2c_forward(struct connection* cnx);
|
void udp_s2c_forward(struct connection* cnx);
|
||||||
|
|
||||||
|
|
||||||
/* Checks if a connection timed out, in which case close the socket and return
|
/* returns how many seconds before socket times out. Negative if timed out
|
||||||
* 1; otherwise return 0. */
|
* already.
|
||||||
int udp_timedout(time_t now, struct connection* cnx);
|
*/
|
||||||
|
int udp_timeout(struct connection* cnx);
|
||||||
|
|
||||||
#endif /* UDPLISTENER_H */
|
#endif /* UDPLISTENER_H */
|
||||||
Reference in new issue
Block a user