mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-12 23:27:15 +03:00
abstracted collection management to its own file
This commit is contained in:
parent
1c63b06cc8
commit
5b93e4ab55
2
Makefile
2
Makefile
@ -28,7 +28,7 @@ CC ?= gcc
|
||||
CFLAGS ?=-Wall -g $(CFLAGS_COV)
|
||||
|
||||
LIBS=
|
||||
OBJS=sslh-conf.o common.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o
|
||||
OBJS=sslh-conf.o common.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o
|
||||
|
||||
CONDITIONAL_TARGETS=
|
||||
|
||||
|
131
collection.c
Normal file
131
collection.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
collection.c: management of a collection of connections, for sslh-select
|
||||
|
||||
# Copyright (C) 2021 Yves Rutschle
|
||||
#
|
||||
# This program is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be
|
||||
# useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
# PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# The full text for the General Public License is here:
|
||||
# http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "collection.h"
|
||||
#include "sslh-conf.h"
|
||||
|
||||
|
||||
/* Info to keep track of all connections */
|
||||
struct cnx_collection {
|
||||
int num_cnx; /* Number of connections in *cnx */
|
||||
struct connection *cnx; /* pointer to array of connections */
|
||||
};
|
||||
|
||||
/* 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
|
||||
* 100 slots, and so on). We never free up connection structures. We try to
|
||||
* allocate as many structures at once as will fit in one page (which is 102
|
||||
* in sslh 1.9 on Linux on x86)
|
||||
*/
|
||||
static long cnx_num_alloc;
|
||||
|
||||
|
||||
|
||||
/* Allocates and initialises a new collection of connections. */
|
||||
cnx_collection* collection_init(void)
|
||||
{
|
||||
int i;
|
||||
cnx_collection* collection;
|
||||
|
||||
collection = malloc(sizeof(*collection));
|
||||
CHECK_ALLOC(collection, "malloc(collection)");
|
||||
|
||||
memset(collection, 0, sizeof(*collection));
|
||||
cnx_num_alloc = getpagesize() / sizeof(struct connection);
|
||||
|
||||
collection->num_cnx = cnx_num_alloc; /* Start with a set pool of slots */
|
||||
collection->cnx = malloc(collection->num_cnx * sizeof(struct connection));
|
||||
CHECK_ALLOC(collection->cnx, "malloc(collection->cnx)");
|
||||
|
||||
for (i = 0; i < collection->num_cnx; i++) {
|
||||
init_cnx(&collection->cnx[i]);
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
void collection_destroy(cnx_collection* collection)
|
||||
{
|
||||
free(collection);
|
||||
}
|
||||
|
||||
/* Increases the number of slots available in a collection of connections
|
||||
* After calling, collection->cnx might have moved
|
||||
* */
|
||||
static int collection_extend(struct cnx_collection* collection)
|
||||
{
|
||||
struct connection* new;
|
||||
int i, new_length = collection->num_cnx + cnx_num_alloc;
|
||||
|
||||
if (cfg.verbose)
|
||||
fprintf(stderr, "allocating %ld more slots (target: %d).\n", cnx_num_alloc, new_length);
|
||||
new = realloc(collection->cnx, new_length * sizeof(collection->cnx[0]));
|
||||
if (!new) return -1;
|
||||
|
||||
collection->cnx = new;
|
||||
|
||||
for (i = collection->num_cnx; i < new_length; i++) {
|
||||
init_cnx(&collection->cnx[i]);
|
||||
}
|
||||
collection->num_cnx = new_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int collection_add_fd(struct cnx_collection* collection, int fd)
|
||||
{
|
||||
int free, res;
|
||||
struct connection* cnx = collection->cnx;
|
||||
|
||||
/* Find an empty slot */
|
||||
for (free = 0; (free < collection->num_cnx) && (cnx[free].q[0].fd != -1); free++) {
|
||||
/* nothing */
|
||||
}
|
||||
if (free >= collection->num_cnx) {
|
||||
res = collection_extend(collection);
|
||||
if (res) {
|
||||
log_message(LOG_ERR, "unable to extend collection -- dropping connection\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
collection->cnx[free].q[0].fd = fd;
|
||||
collection->cnx[free].state = ST_PROBING;
|
||||
collection->cnx[free].probe_timeout = time(NULL) + cfg.timeout;
|
||||
|
||||
if (cfg.verbose)
|
||||
fprintf(stderr, "accepted fd %d on slot %d\n", fd, free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the indexed connection in the collection */
|
||||
struct connection* collection_get_cnx(struct cnx_collection* collection, int index)
|
||||
{
|
||||
return & collection->cnx[index];
|
||||
}
|
||||
|
||||
/* Returns the number of connections in the collection */
|
||||
int collection_get_length(cnx_collection* collection)
|
||||
{
|
||||
return collection->num_cnx;
|
||||
}
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "probe.h"
|
||||
#include "collection.h"
|
||||
|
||||
const char* server_type = "sslh-select";
|
||||
|
||||
@ -36,58 +37,6 @@ struct select_info {
|
||||
fd_set fds_r, fds_w; /* reference fd sets (used to init working copies) */
|
||||
};
|
||||
|
||||
/* Info to keep track of all connections */
|
||||
struct cnx_collection {
|
||||
int num_cnx; /* Number of connections in *cnx */
|
||||
struct connection *cnx; /* pointer to array of connections */
|
||||
};
|
||||
|
||||
/* 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
|
||||
* 100 slots, and so on). We never free up connection structures. We try to
|
||||
* allocate as many structures at once as will fit in one page (which is 102
|
||||
* in sslh 1.9 on Linux on x86)
|
||||
*/
|
||||
static long cnx_num_alloc;
|
||||
|
||||
static void init_collection(struct cnx_collection* collection)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(collection, 0, sizeof(*collection));
|
||||
cnx_num_alloc = getpagesize() / sizeof(struct connection);
|
||||
|
||||
collection->num_cnx = cnx_num_alloc; /* Start with a set pool of slots */
|
||||
collection->cnx = malloc(collection->num_cnx * sizeof(struct connection));
|
||||
CHECK_ALLOC(collection->cnx, "malloc");
|
||||
|
||||
for (i = 0; i < collection->num_cnx; i++) {
|
||||
init_cnx(&collection->cnx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Increases the number of slots available in a collection of connections
|
||||
* After calling, collection->cnx might have moved
|
||||
* */
|
||||
static int extend_collection(struct cnx_collection* collection)
|
||||
{
|
||||
struct connection* new;
|
||||
int i, new_length = collection->num_cnx + cnx_num_alloc;
|
||||
|
||||
if (cfg.verbose)
|
||||
fprintf(stderr, "allocating %ld more slots (target: %d).\n", cnx_num_alloc, new_length);
|
||||
new = realloc(collection->cnx, new_length * sizeof(collection->cnx[0]));
|
||||
if (!new) return -1;
|
||||
|
||||
collection->cnx = new;
|
||||
|
||||
for (i = collection->num_cnx; i < new_length; i++) {
|
||||
init_cnx(&collection->cnx[i]);
|
||||
}
|
||||
collection->num_cnx = new_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -142,8 +91,7 @@ static int fd_is_in_range(int fd) {
|
||||
* connexion */
|
||||
static int accept_new_connection(int listen_socket, struct cnx_collection *collection)
|
||||
{
|
||||
int in_socket, free, res;
|
||||
struct connection* cnx = collection->cnx;
|
||||
int in_socket, res;
|
||||
|
||||
in_socket = accept(listen_socket, 0, 0);
|
||||
CHECK_RES_RETURN(in_socket, "accept", -1);
|
||||
@ -159,24 +107,11 @@ static int accept_new_connection(int listen_socket, struct cnx_collection *colle
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find an empty slot */
|
||||
for (free = 0; (free < collection->num_cnx) && (cnx[free].q[0].fd != -1); free++) {
|
||||
/* nothing */
|
||||
res = collection_add_fd(collection, in_socket);
|
||||
if (res == -1) {
|
||||
close(in_socket);
|
||||
return -1;
|
||||
}
|
||||
if (free >= collection->num_cnx) {
|
||||
res = extend_collection(collection);
|
||||
if (res) {
|
||||
log_message(LOG_ERR, "unable to extend collection -- dropping connection\n");
|
||||
close(in_socket);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
collection->cnx[free].q[0].fd = in_socket;
|
||||
collection->cnx[free].state = ST_PROBING;
|
||||
collection->cnx[free].probe_timeout = time(NULL) + cfg.timeout;
|
||||
|
||||
if (cfg.verbose)
|
||||
fprintf(stderr, "accepted fd %d on slot %d\n", in_socket, free);
|
||||
|
||||
return in_socket;
|
||||
}
|
||||
@ -431,7 +366,7 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
struct timeval tv;
|
||||
int i, j, res;
|
||||
int in_socket = 0;
|
||||
struct cnx_collection collection;
|
||||
cnx_collection* collection;
|
||||
|
||||
fd_info.num_probing = 0;
|
||||
FD_ZERO(&fd_info.fds_r);
|
||||
@ -443,7 +378,7 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
}
|
||||
fd_info.max_fd = listen_sockets[num_addr_listen-1].socketfd + 1;
|
||||
|
||||
init_collection(&collection);
|
||||
collection = collection_init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -464,7 +399,7 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
/* Check main socket for new connections */
|
||||
for (i = 0; i < num_addr_listen; i++) {
|
||||
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
||||
in_socket = accept_new_connection(listen_sockets[i].socketfd, &collection);
|
||||
in_socket = accept_new_connection(listen_sockets[i].socketfd, collection);
|
||||
if (in_socket > 0) {
|
||||
fd_info.num_probing++;
|
||||
FD_SET(in_socket, &fd_info.fds_r);
|
||||
@ -475,8 +410,8 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
}
|
||||
|
||||
/* Check all sockets for write activity */
|
||||
for (i = 0; i < collection.num_cnx; i++) {
|
||||
struct connection* cnx = &collection.cnx[i];
|
||||
for (i = 0; i < collection_get_length(collection); i++) {
|
||||
struct connection* cnx = collection_get_cnx(collection, i);
|
||||
if (cnx->q[0].fd != -1) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (is_fd_active(cnx->q[j].fd, &writefds)) {
|
||||
@ -500,8 +435,8 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
}
|
||||
|
||||
/* Check all sockets for read activity */
|
||||
for (i = 0; i < collection.num_cnx; i++) {
|
||||
struct connection* cnx = &collection.cnx[i];
|
||||
for (i = 0; i < collection_get_length(collection); i++) {
|
||||
struct connection* cnx = collection_get_cnx(collection, i);
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (is_fd_active(cnx->q[j].fd, &readfds) ||
|
||||
((cnx->state == ST_PROBING) && (cnx->probe_timeout < time(NULL)))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user