mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-13 15:47:15 +03:00
sslh-select: support forking for particular protocols
To keep the code simple, use the same event loop in the child process as in the parent process but close all irrelevant file descriptors.
This commit is contained in:
parent
0929d39a34
commit
2544f20bdf
20
probe.c
20
probe.c
@ -45,16 +45,16 @@ static int is_true(const char *p, int len, struct proto* proto) { return 1; }
|
||||
/* Table of protocols that have a built-in probe
|
||||
*/
|
||||
static struct proto builtins[] = {
|
||||
/* description service saddr log_level keepalive probe */
|
||||
{ "ssh", "sshd", NULL, 1, 0, is_ssh_protocol},
|
||||
{ "openvpn", NULL, NULL, 1, 0, is_openvpn_protocol },
|
||||
{ "tinc", NULL, NULL, 1, 0, is_tinc_protocol },
|
||||
{ "xmpp", NULL, NULL, 1, 0, is_xmpp_protocol },
|
||||
{ "http", NULL, NULL, 1, 0, is_http_protocol },
|
||||
{ "ssl", NULL, NULL, 1, 0, is_tls_protocol },
|
||||
{ "tls", NULL, NULL, 1, 0, is_tls_protocol },
|
||||
{ "adb", NULL, NULL, 1, 0, is_adb_protocol },
|
||||
{ "anyprot", NULL, NULL, 1, 0, is_true }
|
||||
/* description service saddr log_level keepalive fork probe */
|
||||
{ "ssh", "sshd", NULL, 1, 0, 1, is_ssh_protocol},
|
||||
{ "openvpn", NULL, NULL, 1, 0, 1, is_openvpn_protocol },
|
||||
{ "tinc", NULL, NULL, 1, 0, 1, is_tinc_protocol },
|
||||
{ "xmpp", NULL, NULL, 1, 0, 0, is_xmpp_protocol },
|
||||
{ "http", NULL, NULL, 1, 0, 0, is_http_protocol },
|
||||
{ "ssl", NULL, NULL, 1, 0, 0, is_tls_protocol },
|
||||
{ "tls", NULL, NULL, 1, 0, 0, is_tls_protocol },
|
||||
{ "adb", NULL, NULL, 1, 0, 0, is_adb_protocol },
|
||||
{ "anyprot", NULL, NULL, 1, 0, 0, is_true }
|
||||
};
|
||||
|
||||
static struct proto *protocols;
|
||||
|
1
probe.h
1
probe.h
@ -24,6 +24,7 @@ struct proto {
|
||||
* 1: Log incoming connection
|
||||
*/
|
||||
int keepalive; /* 0: No keepalive ; 1: Set Keepalive for this connection */
|
||||
int fork; /* 0: Connection can run within shared process ; 1: Separate process required for this connection */
|
||||
|
||||
/* function to probe that protocol; parameters are buffer and length
|
||||
* containing the data to probe, and a pointer to the protocol structure */
|
||||
|
@ -123,14 +123,15 @@ static void printsettings(void)
|
||||
|
||||
for (p = get_first_protocol(); p; p = p->next) {
|
||||
fprintf(stderr,
|
||||
"%s addr: %s. libwrap service: %s log_level: %d family %d %d [%s]\n",
|
||||
"%s addr: %s. libwrap service: %s log_level: %d family %d %d [%s] [%s]\n",
|
||||
p->description,
|
||||
sprintaddr(buf, sizeof(buf), p->saddr),
|
||||
p->service,
|
||||
p->log_level,
|
||||
p->saddr->ai_family,
|
||||
p->saddr->ai_addr->sa_family,
|
||||
p->keepalive ? "keepalive" : "");
|
||||
p->keepalive ? "keepalive" : "",
|
||||
p->fork ? "fork" : "");
|
||||
}
|
||||
fprintf(stderr, "listening on:\n");
|
||||
for (a = addr_listen; a; a = a->ai_next) {
|
||||
@ -307,6 +308,7 @@ static int config_protocols(config_t *config, struct proto **prots)
|
||||
p->description = name;
|
||||
config_setting_lookup_string(prot, "service", &(p->service));
|
||||
config_setting_lookup_bool(prot, "keepalive", &p->keepalive);
|
||||
config_setting_lookup_bool(prot, "fork", &p->fork);
|
||||
|
||||
if (config_setting_lookup_int(prot, "log_level", &p->log_level) == CONFIG_FALSE) {
|
||||
p->log_level = 1;
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
const char* server_type = "sslh-select";
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* cnx_num_alloc is the number of connection to allocate at once (at start-up,
|
||||
* and then every time we get too many simultaneous connections: e.g. start
|
||||
* with 100 slots, then if we get more than 100 connections allocate another
|
||||
@ -319,6 +321,24 @@ void main_loop(int listen_sockets[], int num_addr_listen)
|
||||
check_access_rights(in_socket, cnx[i].proto->service)) {
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
} else if (cnx[i].proto->fork) {
|
||||
if (!fork()) {
|
||||
struct connection *cnx_i = &cnx[i];
|
||||
for (i = 0; i < num_addr_listen; i++) {
|
||||
FD_CLR(listen_sockets[i], &fds_r);
|
||||
close(listen_sockets[i]);
|
||||
}
|
||||
num_addr_listen = 0;
|
||||
for (i = 0; i < num_cnx; i++)
|
||||
if (&cnx[i] != cnx_i)
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
num_probing = 0;
|
||||
res = connect_queue(cnx_i, &fds_r, &fds_w);
|
||||
max_fd = MAX(cnx_i->q[0].fd, cnx_i->q[1].fd) + 1;
|
||||
} else {
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
}
|
||||
} else {
|
||||
res = connect_queue(&cnx[i], &fds_r, &fds_w);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user