mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-12 15:17:14 +03:00
linked list sorted by timeout times
This commit is contained in:
parent
cd5d75fed9
commit
449fabba51
9
common.h
9
common.h
@ -92,6 +92,12 @@ struct queue {
|
||||
int deferred_data_size;
|
||||
};
|
||||
|
||||
/* Double linked list for timeout management */
|
||||
typedef struct {
|
||||
struct connection* head;
|
||||
struct connection* tail;
|
||||
} dl_list;
|
||||
|
||||
struct connection {
|
||||
int type; /* SOCK_DGRAM | SOCK_STREAM */
|
||||
struct sslhcfg_protocols_item* proto; /* Where to connect to */
|
||||
@ -113,6 +119,9 @@ struct connection {
|
||||
|
||||
time_t last_active;
|
||||
|
||||
/* double linked list of timeouts */
|
||||
struct connection *timeout_prev, *timeout_next;
|
||||
|
||||
/* We need one local socket for each target server, so we know where to
|
||||
* forward server responses */
|
||||
int target_sock;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 10 08:52:30 2022.
|
||||
* on Mon Apr 18 21:21:32 2022.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2021 Yves Rutschle
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||
* on Sun Apr 10 08:52:30 2022.
|
||||
* on Mon Apr 18 21:21:32 2022.
|
||||
|
||||
# conf2struct: generate libconf parsers that read to structs
|
||||
# Copyright (C) 2018-2021 Yves Rutschle
|
||||
@ -72,6 +72,7 @@ struct sslhcfg_protocols_item {
|
||||
T_PROBE* probe;
|
||||
struct addrinfo* saddr;
|
||||
void* data;
|
||||
dl_list timeouts;
|
||||
};
|
||||
|
||||
struct sslhcfg_item {
|
||||
|
@ -160,6 +160,9 @@ static void config_protocols()
|
||||
(const char**) cfg.protocols[i].alpn_protocols,
|
||||
cfg.protocols[i].alpn_protocols_len);
|
||||
}
|
||||
|
||||
p->timeouts.head = NULL;
|
||||
p->timeouts.tail = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,8 @@ config: {
|
||||
# Runtime data
|
||||
{ name: "probe"; type: "runtime"; c_type: "T_PROBE*" },
|
||||
{ name: "saddr"; type: "runtime"; c_type: "struct addrinfo*" },
|
||||
{ name: "data"; type: "runtime"; c_type: "void*" }
|
||||
{ name: "data"; type: "runtime"; c_type: "void*" },
|
||||
{ name: "timeouts"; type: "runtime"; c_type: "dl_list" }
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -117,6 +117,61 @@ static int new_source(hash* h, struct connection* new)
|
||||
}
|
||||
|
||||
|
||||
/* Double linked list utilities: push element at tail of list */
|
||||
static void list_push(dl_list* list, struct connection* cnx)
|
||||
{
|
||||
cnx->timeout_next = NULL;
|
||||
|
||||
if (!list->head) {
|
||||
cnx->timeout_prev = NULL;
|
||||
list->head = cnx;
|
||||
}
|
||||
|
||||
if (list->tail) {
|
||||
list->tail->timeout_next = cnx;
|
||||
cnx->timeout_prev = list->tail;
|
||||
}
|
||||
|
||||
list->tail = cnx;
|
||||
}
|
||||
|
||||
/* Double linked list utilities: remove element */
|
||||
static void list_remove(dl_list* list, struct connection* cnx)
|
||||
{
|
||||
if (list->head == cnx) list->head = cnx->timeout_next;
|
||||
if (list->tail == cnx) list->tail = cnx->timeout_prev;
|
||||
|
||||
if (cnx->timeout_prev)
|
||||
cnx->timeout_prev->timeout_next = cnx->timeout_next;
|
||||
|
||||
if (cnx->timeout_next)
|
||||
cnx->timeout_next->timeout_prev = cnx->timeout_prev;
|
||||
}
|
||||
|
||||
static void list_dump(void) {
|
||||
int now = time(NULL);
|
||||
static int cnt = 0;
|
||||
|
||||
if (cnt++ < 1000) {
|
||||
return;
|
||||
}
|
||||
cnt = 0;
|
||||
|
||||
FILE * f = fopen("/tmp/list.tmp", "w");
|
||||
fprintf(f, "time: %d\n", time(NULL));
|
||||
for (int i = 0; i < cfg.protocols_len; i++) {
|
||||
struct connection* c = cfg.protocols[i].timeouts.head;
|
||||
fprintf(f, "p %d %s list %p %p\n", i, cfg.protocols[i].name, cfg.protocols[i].timeouts.head, cfg.protocols[i].timeouts.tail);
|
||||
while (c) {
|
||||
fprintf(f, "%p %d(%d) %p %p\n", c, c->last_active, now - c->last_active, c->timeout_prev, c->timeout_next);
|
||||
c = c->timeout_next;
|
||||
}
|
||||
fprintf(f, "/list\n");
|
||||
}
|
||||
fclose(f);
|
||||
rename("/tmp/list.tmp", "/tmp/list");
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
@ -152,8 +207,9 @@ void udp_timeouts(struct loop_info* fd_info)
|
||||
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);
|
||||
hash_remove(fd_info->hash_sources, cnx);
|
||||
list_remove(&cnx->proto->timeouts, cnx);
|
||||
collection_remove_cnx(fd_info->collection, cnx);
|
||||
} else {
|
||||
if (timeout < next_timeout) next_timeout = timeout;
|
||||
}
|
||||
@ -164,10 +220,18 @@ void udp_timeouts(struct loop_info* fd_info)
|
||||
fd_info->next_timeout = next_timeout;
|
||||
}
|
||||
|
||||
|
||||
/* Mark the connection was active */
|
||||
static void mark_active(struct connection* cnx)
|
||||
{
|
||||
cnx->last_active = time(NULL);
|
||||
|
||||
dl_list* list = &cnx->proto->timeouts;
|
||||
|
||||
list_remove(list, cnx);
|
||||
list_push(list, cnx);
|
||||
|
||||
list_dump();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user