mirror of
https://github.com/yrutschle/sslh.git
synced 2026-10-22 18:12:10 +03:00
sslh-ev: keep track of forked processes
This commit is contained in:
1 parent
eb6a3c6724
commit
2624877232
7 files changed
+72
-37
No files matched your search
@@ -46,6 +46,7 @@
|
||||
|
||||
#if 0
|
||||
#define DEBUG 1
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
typedef void* hash_item;
|
||||
@@ -169,7 +170,7 @@ int hash_insert(hash* h, hash_item new)
|
||||
if (distance(index, h, curr_item) < distance(index, h, new)) {
|
||||
gap_set(h->data, index, new);
|
||||
#if DEBUG
|
||||
fprintf(stderr, "intermediate insert [%d] at %d\n", new->pid, index);
|
||||
fprintf(stderr, "intermediate insert at %d\n", index);
|
||||
#endif
|
||||
new = curr_item;
|
||||
}
|
||||
|
||||
+21
-18
@@ -26,6 +26,14 @@
|
||||
#include "probe.h"
|
||||
#include "log.h"
|
||||
|
||||
/* Struct to keep track of an association of a forked PID to its
|
||||
* listening socket and its protocol */
|
||||
struct pid2proto {
|
||||
pid_t pid;
|
||||
struct listen_endpoint* endpoint;
|
||||
struct sslhcfg_protocols_item* proto;
|
||||
};
|
||||
|
||||
|
||||
int tidy_connection(struct connection *cnx, struct loop_info* fd_info)
|
||||
{
|
||||
@@ -130,10 +138,7 @@ static int pid_cmp(hash_item item1, hash_item item2)
|
||||
|
||||
/* When a child has died, update the counts appropriately */
|
||||
void decrease_forked_connection(struct loop_info* loop, pid_t pid) {
|
||||
struct pid2proto p2p = {
|
||||
.pid = pid,
|
||||
.proto = NULL
|
||||
};
|
||||
struct pid2proto p2p = { .pid = pid };
|
||||
struct pid2proto* found = hash_find(loop->pid2proto, &p2p);
|
||||
dec_proto_connections(found->proto);
|
||||
dec_listen_connections(found->endpoint);
|
||||
@@ -142,20 +147,18 @@ void decrease_forked_connection(struct loop_info* loop, pid_t pid) {
|
||||
free(found);
|
||||
}
|
||||
|
||||
/* Check if SIGCHLD was received, find which PID and reap appropriately */
|
||||
extern volatile sig_atomic_t received_sigchld;
|
||||
void sigchld_process(struct loop_info* loop)
|
||||
|
||||
typedef struct pid2proto* hash_item;
|
||||
#include "hash.h"
|
||||
void remember_child_data(struct loop_info* fd_info,
|
||||
struct connection* cnx, pid_t pid)
|
||||
{
|
||||
int chld;
|
||||
if (received_sigchld) {
|
||||
received_sigchld = 0;
|
||||
do {
|
||||
chld = waitpid(-1, NULL, WNOHANG);
|
||||
CHECK_RES_RETURN(chld, "waitpid", );
|
||||
if (chld) {
|
||||
decrease_forked_connection(loop, chld);
|
||||
}
|
||||
} while (chld);
|
||||
struct pid2proto* pid2proto = malloc(sizeof(*pid2proto));
|
||||
pid2proto->pid = pid;
|
||||
pid2proto->proto = cnx->proto;
|
||||
pid2proto->endpoint = cnx->endpoint;
|
||||
if (hash_insert(fd_info->pid2proto, pid2proto)) {
|
||||
/* TODO something if it fails */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +173,7 @@ void loop_init(struct loop_info* loop)
|
||||
|
||||
loop->pid2proto = hash_init(32, pid_make_key, pid_cmp);
|
||||
if (!loop->pid2proto) {
|
||||
/* do something! (we're also not doing anything for UDP) */
|
||||
/* TODO do something! (we're also not doing anything for UDP) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -33,7 +33,8 @@ struct connection* cnx_accept_process(struct loop_info* fd_info, struct listen_e
|
||||
int tidy_connection(struct connection *cnx, struct loop_info* fd_info);
|
||||
void loop_init(struct loop_info* loop);
|
||||
|
||||
void sigchld_process(struct loop_info* loop);
|
||||
void remember_child_data(struct loop_info* fd_info,
|
||||
struct connection* cnx, pid_t pid);
|
||||
|
||||
/* These must be declared in the loop handler, sslh-ev or sslh-select */
|
||||
void watchers_add_read(watchers* w, int fd);
|
||||
|
||||
@@ -129,6 +129,26 @@ static void cnx_accept_cb(EV_P_ ev_io *w, int revents)
|
||||
cnx_accept_process(info, gap_get(info->watchers->fd2ls, w->fd));
|
||||
}
|
||||
|
||||
|
||||
void sigchld_cb(EV_P_ ev_child *w, int revents)
|
||||
{
|
||||
printf("sigchld_cb %d\n", w->pid);
|
||||
struct loop_info* info = ev_userdata(EV_A);
|
||||
ev_child_stop(EV_A_ w);
|
||||
|
||||
decrease_forked_connection(info, w->pid);
|
||||
free(w);
|
||||
}
|
||||
|
||||
void watcher_sigchld(struct loop_info* fd_info, struct connection* cnx, pid_t pid)
|
||||
{
|
||||
ev_child* cw = malloc(sizeof(*cw));
|
||||
|
||||
ev_child_init(cw, sigchld_cb, pid, 0);
|
||||
ev_child_start(EV_DEFAULT_ cw);
|
||||
}
|
||||
|
||||
|
||||
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
{
|
||||
struct loop_info ev_info;
|
||||
|
||||
@@ -88,8 +88,31 @@ void watchers_del_write(watchers* w, int fd)
|
||||
FD_CLR(fd, &w->fds_w);
|
||||
}
|
||||
|
||||
void watcher_sigchld(struct loop_info* fd_info, struct connection* cnx, pid_t pid)
|
||||
{
|
||||
/* Nothing to do, watcher is processed in the event loop when select() is
|
||||
* interrupted by the signal */
|
||||
}
|
||||
|
||||
/* /end watchers */
|
||||
|
||||
/* Check if SIGCHLD was received, find which PID and reap appropriately */
|
||||
extern volatile sig_atomic_t received_sigchld;
|
||||
static void sigchld_process(struct loop_info* loop)
|
||||
{
|
||||
int chld;
|
||||
printf("sigchld_process\n");
|
||||
if (received_sigchld) {
|
||||
received_sigchld = 0;
|
||||
do {
|
||||
chld = waitpid(-1, NULL, WNOHANG);
|
||||
CHECK_RES_RETURN(chld, "waitpid", );
|
||||
if (chld) {
|
||||
decrease_forked_connection(loop, chld);
|
||||
}
|
||||
} while (chld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-9
@@ -26,8 +26,6 @@
|
||||
#include "log.h"
|
||||
|
||||
|
||||
typedef struct pid2proto* hash_item;
|
||||
#include "hash.h"
|
||||
|
||||
/* Removes cnx from probing list */
|
||||
static void remove_probing_cnx(struct loop_info* fd_info, struct connection* cnx)
|
||||
@@ -309,15 +307,12 @@ void fork_shoveling_process(struct loop_info* fd_info, struct connection* cnx) {
|
||||
case -1: print_message(msg_system_error, "fork failed: err %d: %s\n", errno, strerror(errno));
|
||||
break;
|
||||
default: /* parent */
|
||||
struct pid2proto* pid2proto = malloc(sizeof(*pid2proto));
|
||||
pid2proto->pid = pid;
|
||||
pid2proto->proto = cnx->proto;
|
||||
if (hash_insert(fd_info->pid2proto, pid2proto)) {
|
||||
/* TODO something if it fails */
|
||||
}
|
||||
remember_child_data(fd_info, cnx, pid);
|
||||
watcher_sigchld(fd_info, cnx, pid);
|
||||
break;
|
||||
}
|
||||
/* Free file descriptor, but do not reduce protocol count */
|
||||
/* Free file descriptor (used only in child), but do not reduce connection
|
||||
* counts */
|
||||
cnx->proto = NULL;
|
||||
cnx->endpoint = NULL;
|
||||
tidy_connection(cnx, fd_info);
|
||||
|
||||
@@ -5,14 +5,6 @@
|
||||
#include "collection.h"
|
||||
#include "tcp-probe.h"
|
||||
|
||||
/* Struct to keep track of an association of a forked PID to its
|
||||
* listening socket and its protocol */
|
||||
struct pid2proto {
|
||||
pid_t pid;
|
||||
struct listen_endpoint* endpoint;
|
||||
struct sslhcfg_protocols_item* proto;
|
||||
};
|
||||
|
||||
void tcp_read_process(struct loop_info* fd_info, int fd);
|
||||
struct connection* accept_new_connection(struct listen_endpoint* endpoint, struct loop_info* fd_info);
|
||||
void probing_read_process(struct connection* cnx, struct loop_info* fd_info);
|
||||
|
||||
Reference in new issue
Block a user