mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-13 07:37:15 +03:00
refactor more code from sslh-select to processes.c
This commit is contained in:
parent
3389000ff3
commit
ec033efbbc
13
Makefile
13
Makefile
@ -27,7 +27,7 @@ CC ?= gcc
|
|||||||
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV)
|
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV)
|
||||||
|
|
||||||
LIBS=-lm -lpcre2-8
|
LIBS=-lm -lpcre2-8
|
||||||
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o gap.o
|
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o gap.o processes.o
|
||||||
|
|
||||||
CONDITIONAL_TARGETS=
|
CONDITIONAL_TARGETS=
|
||||||
|
|
||||||
@ -70,21 +70,26 @@ all: sslh $(MAN) echosrv $(CONDITIONAL_TARGETS)
|
|||||||
version.h:
|
version.h:
|
||||||
./genver.sh >version.h
|
./genver.sh >version.h
|
||||||
|
|
||||||
sslh: sslh-fork sslh-select
|
sslh: sslh-fork sslh-select # sslh-ev
|
||||||
|
|
||||||
$(OBJS): version.h common.h collection.h sslh-conf.h gap.h
|
$(OBJS): version.h common.h collection.h sslh-conf.h gap.h
|
||||||
|
|
||||||
sslh-conf.c sslh-conf.h: sslhconf.cfg
|
sslh-conf.c sslh-conf.h: sslhconf.cfg
|
||||||
conf2struct sslhconf.cfg
|
conf2struct sslhconf.cfg
|
||||||
|
|
||||||
sslh-fork: version.h $(OBJS) sslh-fork.o Makefile
|
FORK_OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o gap.o
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o sslh-fork sslh-fork.o $(OBJS) $(LIBS)
|
sslh-fork: version.h sslh-fork.o Makefile $(FORK_OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o sslh-fork sslh-fork.o $(FORK_OBJS) $(LIBS)
|
||||||
#strip sslh-fork
|
#strip sslh-fork
|
||||||
|
|
||||||
sslh-select: version.h $(OBJS) sslh-select.o Makefile
|
sslh-select: version.h $(OBJS) sslh-select.o Makefile
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o sslh-select sslh-select.o $(OBJS) $(LIBS)
|
$(CC) $(CFLAGS) $(LDFLAGS) -o sslh-select sslh-select.o $(OBJS) $(LIBS)
|
||||||
#strip sslh-select
|
#strip sslh-select
|
||||||
|
|
||||||
|
sslh-ev: version.h $(OBJS) sslh-ev.o Makefile
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o sslh-ev sslh-ev.o $(OBJS) $(LIBS)
|
||||||
|
#strip sslh-select
|
||||||
|
|
||||||
systemd-sslh-generator: systemd-sslh-generator.o
|
systemd-sslh-generator: systemd-sslh-generator.o
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o systemd-sslh-generator systemd-sslh-generator.o -lconfig
|
$(CC) $(CFLAGS) $(LDFLAGS) -o systemd-sslh-generator systemd-sslh-generator.o -lconfig
|
||||||
|
|
||||||
|
130
processes.c
130
processes.c
@ -20,7 +20,9 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "udp-listener.h"
|
||||||
#include "processes.h"
|
#include "processes.h"
|
||||||
|
#include "probe.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
/* Removes cnx from probing list */
|
/* Removes cnx from probing list */
|
||||||
@ -36,6 +38,65 @@ void add_probing_cnx(struct loop_info* fd_info, struct connection* cnx)
|
|||||||
fd_info->num_probing++;
|
fd_info->num_probing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the queue index that contains the specified file descriptor */
|
||||||
|
static int active_queue(struct connection* cnx, int fd)
|
||||||
|
{
|
||||||
|
if (cnx->q[0].fd == fd) return 0;
|
||||||
|
if (cnx->q[1].fd == fd) return 1;
|
||||||
|
|
||||||
|
print_message(msg_int_error, "file descriptor %d not found in connection object\n", fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tidy_connection(struct connection *cnx, struct loop_info* fd_info)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
if (cnx->q[i].fd != -1) {
|
||||||
|
print_message(msg_fd, "closing fd %d\n", cnx->q[i].fd);
|
||||||
|
|
||||||
|
watchers_del_read(fd_info->watchers, cnx->q[i].fd);
|
||||||
|
watchers_del_write(fd_info->watchers, cnx->q[i].fd);
|
||||||
|
close(cnx->q[i].fd);
|
||||||
|
if (cnx->q[i].deferred_data)
|
||||||
|
free(cnx->q[i].deferred_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collection_remove_cnx(fd_info->collection, cnx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* shovels data from active fd to the other
|
||||||
|
returns after one socket closed or operation would block
|
||||||
|
*/
|
||||||
|
static void shovel(struct connection *cnx, int active_fd, struct loop_info* fd_info)
|
||||||
|
{
|
||||||
|
struct queue *read_q, *write_q;
|
||||||
|
|
||||||
|
read_q = &cnx->q[active_fd];
|
||||||
|
write_q = &cnx->q[1-active_fd];
|
||||||
|
|
||||||
|
print_message(msg_fd, "activity on fd%d\n", read_q->fd);
|
||||||
|
|
||||||
|
switch(fd2fd(write_q, read_q)) {
|
||||||
|
case -1:
|
||||||
|
case FD_CNXCLOSED:
|
||||||
|
tidy_connection(cnx, fd_info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FD_STALLED:
|
||||||
|
watchers_add_write(fd_info->watchers, write_q->fd);
|
||||||
|
watchers_del_read(fd_info->watchers, read_q->fd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* Nothing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Process a connection that is active in read */
|
/* Process a connection that is active in read */
|
||||||
static void tcp_read_process(struct loop_info* fd_info,
|
static void tcp_read_process(struct loop_info* fd_info,
|
||||||
int fd)
|
int fd)
|
||||||
@ -107,8 +168,8 @@ void cnx_write_process(struct loop_info* fd_info, int fd)
|
|||||||
/* If no deferred data is left, stop monitoring the fd
|
/* If no deferred data is left, stop monitoring the fd
|
||||||
* for write, and restart monitoring the other one for reads*/
|
* for write, and restart monitoring the other one for reads*/
|
||||||
if (!cnx->q[queue].deferred_data_size) {
|
if (!cnx->q[queue].deferred_data_size) {
|
||||||
watchers_del_write(&fd_info->watchers, cnx->q[queue].fd);
|
watchers_del_write(fd_info->watchers, cnx->q[queue].fd);
|
||||||
watchers_add_read(&fd_info->watchers, cnx->q[1-queue].fd);
|
watchers_add_read(fd_info->watchers, cnx->q[1-queue].fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +206,7 @@ static struct connection* accept_new_connection(int listen_socket, struct cnx_co
|
|||||||
* (For UDP, this means all traffic coming from remote clients)
|
* (For UDP, this means all traffic coming from remote clients)
|
||||||
* Returns new file descriptor, or -1
|
* Returns new file descriptor, or -1
|
||||||
* */
|
* */
|
||||||
void cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket)
|
int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket)
|
||||||
{
|
{
|
||||||
int fd = listen_socket->socketfd;
|
int fd = listen_socket->socketfd;
|
||||||
int type = listen_socket->type;
|
int type = listen_socket->type;
|
||||||
@ -163,50 +224,22 @@ void cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* liste
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SOCK_DGRAM:
|
case SOCK_DGRAM:
|
||||||
new_fd = udp_c2s_forward(fd, fd_info->collection, fd_info->watchers.max_fd);
|
new_fd = udp_c2s_forward(fd, fd_info->collection, watchers_maxfd(fd_info->watchers));
|
||||||
print_message(msg_fd, "new_fd %d\n", new_fd);
|
print_message(msg_fd, "new_fd %d\n", new_fd);
|
||||||
if (new_fd == -1)
|
if (new_fd == -1)
|
||||||
return;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print_message(msg_int_error, "Inconsistent cnx type: %d\n", type);
|
print_message(msg_int_error, "Inconsistent cnx type: %d\n", type);
|
||||||
exit(1);
|
exit(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watchers_add_read(&fd_info->watchers, new_fd);
|
watchers_add_read(fd_info->watchers, new_fd);
|
||||||
|
return new_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* shovels data from active fd to the other
|
|
||||||
returns after one socket closed or operation would block
|
|
||||||
*/
|
|
||||||
static void shovel(struct connection *cnx, int active_fd, struct loop_info* fd_info)
|
|
||||||
{
|
|
||||||
struct queue *read_q, *write_q;
|
|
||||||
|
|
||||||
read_q = &cnx->q[active_fd];
|
|
||||||
write_q = &cnx->q[1-active_fd];
|
|
||||||
|
|
||||||
print_message(msg_fd, "activity on fd%d\n", read_q->fd);
|
|
||||||
|
|
||||||
switch(fd2fd(write_q, read_q)) {
|
|
||||||
case -1:
|
|
||||||
case FD_CNXCLOSED:
|
|
||||||
tidy_connection(cnx, fd_info);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FD_STALLED:
|
|
||||||
watchers_add_write(&fd_info->watchers, write_q->fd);
|
|
||||||
watchers_del_read(&fd_info->watchers, read_q->fd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* Nothing */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shovels data from one fd to the other and vice-versa
|
/* shovels data from one fd to the other and vice-versa
|
||||||
returns after one socket closed
|
returns after one socket closed
|
||||||
*/
|
*/
|
||||||
@ -293,6 +326,33 @@ static void connect_proxy(struct connection *cnx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Connect queue 1 of connection to SSL; returns new file descriptor */
|
||||||
|
static int connect_queue(struct connection* cnx,
|
||||||
|
struct loop_info* fd_info)
|
||||||
|
{
|
||||||
|
struct queue *q = &cnx->q[1];
|
||||||
|
|
||||||
|
q->fd = connect_addr(cnx, cnx->q[0].fd, NON_BLOCKING);
|
||||||
|
if (q->fd != -1) {
|
||||||
|
log_connection(NULL, cnx);
|
||||||
|
flush_deferred(q);
|
||||||
|
if (q->deferred_data) {
|
||||||
|
/*
|
||||||
|
FD_SET(q->fd, &fd_info->watchers->fds_w);
|
||||||
|
FD_CLR(cnx->q[0].fd, &fd_info->watchers->fds_r); */
|
||||||
|
watchers_add_write(fd_info->watchers, q->fd);
|
||||||
|
watchers_del_read(fd_info->watchers, cnx->q[0].fd);
|
||||||
|
}
|
||||||
|
/* FD_SET(q->fd, &fd_info->watchers->fds_r); */
|
||||||
|
watchers_add_read(fd_info->watchers, q->fd);
|
||||||
|
collection_add_fd(fd_info->collection, cnx, q->fd);
|
||||||
|
return q->fd;
|
||||||
|
} else {
|
||||||
|
tidy_connection(cnx, fd_info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Process read activity on a socket in probe state
|
/* Process read activity on a socket in probe state
|
||||||
* IN/OUT cnx: connection data, updated if connected
|
* IN/OUT cnx: connection data, updated if connected
|
||||||
|
21
processes.h
21
processes.h
@ -1,14 +1,13 @@
|
|||||||
#ifndef PROCESSES_H
|
#ifndef PROCESSES_H
|
||||||
#define PROCESSES_H
|
#define PROCESSES_H
|
||||||
|
|
||||||
#ifndef WATCHERS_TYPE_DEFINED
|
|
||||||
#error Define watchers type before including processes.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "collection.h"
|
#include "collection.h"
|
||||||
#include "gap.h"
|
#include "gap.h"
|
||||||
|
|
||||||
|
/* Provided by event loop, sslh-ev or sslh-select, for implementation-dependant
|
||||||
|
* data */
|
||||||
|
typedef struct watchers watchers;
|
||||||
|
|
||||||
/* Global state for a loop */
|
/* Global state for a loop */
|
||||||
struct loop_info {
|
struct loop_info {
|
||||||
@ -17,7 +16,7 @@ struct loop_info {
|
|||||||
* select() */
|
* select() */
|
||||||
gap_array* probing_list; /* Pointers to cnx that are in probing mode */
|
gap_array* probing_list; /* Pointers to cnx that are in probing mode */
|
||||||
|
|
||||||
watchers watchers;
|
watchers* watchers;
|
||||||
|
|
||||||
cnx_collection* collection; /* Collection of connections linked to this loop */
|
cnx_collection* collection; /* Collection of connections linked to this loop */
|
||||||
|
|
||||||
@ -26,10 +25,20 @@ struct loop_info {
|
|||||||
|
|
||||||
void cnx_read_process(struct loop_info* fd_info, int fd);
|
void cnx_read_process(struct loop_info* fd_info, int fd);
|
||||||
void cnx_write_process(struct loop_info* fd_info, int fd);
|
void cnx_write_process(struct loop_info* fd_info, int fd);
|
||||||
void cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket);
|
int cnx_accept_process(struct loop_info* fd_info, struct listen_endpoint* listen_socket);
|
||||||
void probing_read_process(struct connection* cnx, struct loop_info* fd_info);
|
void probing_read_process(struct connection* cnx, struct loop_info* fd_info);
|
||||||
|
|
||||||
void remove_probing_cnx(struct loop_info* fd_info, struct connection* cnx);
|
void remove_probing_cnx(struct loop_info* fd_info, struct connection* cnx);
|
||||||
void add_probing_cnx(struct loop_info* fd_info, struct connection* cnx);
|
void add_probing_cnx(struct loop_info* fd_info, struct connection* cnx);
|
||||||
|
int tidy_connection(struct connection *cnx, struct loop_info* fd_info);
|
||||||
|
|
||||||
|
|
||||||
|
/* These must be declared in the loop handler, sslh-ev or sslh-select */
|
||||||
|
void watchers_init(watchers** w);
|
||||||
|
void watchers_add_read(watchers* w, int fd);
|
||||||
|
void watchers_del_read(watchers* w, int fd);
|
||||||
|
void watchers_add_write(watchers* w, int fd);
|
||||||
|
void watchers_del_write(watchers* w, int fd);
|
||||||
|
int watchers_maxfd(watchers* w);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
103
sslh-select.c
103
sslh-select.c
@ -42,18 +42,19 @@
|
|||||||
const char* server_type = "sslh-select";
|
const char* server_type = "sslh-select";
|
||||||
|
|
||||||
/* watcher type for a select() loop */
|
/* watcher type for a select() loop */
|
||||||
typedef struct watchers {
|
struct watchers {
|
||||||
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) */
|
||||||
int max_fd; /* Highest fd number to pass to select() */
|
int max_fd; /* Highest fd number to pass to select() */
|
||||||
} watchers;
|
};
|
||||||
#define WATCHERS_TYPE_DEFINED /* To notify processes.h */
|
#define WATCHERS_TYPE_DEFINED /* To notify processes.h */
|
||||||
|
|
||||||
#include "processes.h"
|
#include "processes.h"
|
||||||
|
|
||||||
void watchers_init(watchers* w)
|
void watchers_init(watchers** w)
|
||||||
{
|
{
|
||||||
FD_ZERO(&w->fds_r);
|
*w = malloc(sizeof(**w));
|
||||||
FD_ZERO(&w->fds_w);
|
FD_ZERO(&(*w)->fds_r);
|
||||||
|
FD_ZERO(&(*w)->fds_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void watchers_add_read(watchers* w, int fd)
|
void watchers_add_read(watchers* w, int fd)
|
||||||
@ -79,32 +80,22 @@ void watchers_del_write(watchers* w, int fd)
|
|||||||
{
|
{
|
||||||
FD_CLR(fd, &w->fds_w);
|
FD_CLR(fd, &w->fds_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To remove after moving UDP lookups to hash table */
|
||||||
|
int watchers_maxfd(watchers* w)
|
||||||
|
{
|
||||||
|
return w->max_fd;
|
||||||
|
}
|
||||||
|
|
||||||
/* /end watchers */
|
/* /end watchers */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int tidy_connection(struct connection *cnx, struct loop_info* fd_info)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (cnx->q[i].fd != -1) {
|
|
||||||
print_message(msg_fd, "closing fd %d\n", cnx->q[i].fd);
|
|
||||||
|
|
||||||
watchers_del_read(&fd_info->watchers, cnx->q[i].fd);
|
|
||||||
watchers_del_write(&fd_info->watchers, cnx->q[i].fd);
|
|
||||||
close(cnx->q[i].fd);
|
|
||||||
if (cnx->q[i].deferred_data)
|
|
||||||
free(cnx->q[i].deferred_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
collection_remove_cnx(fd_info->collection, cnx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if fd becomes higher than FD_SETSIZE, things won't work so well with FD_SET
|
/* if fd becomes higher than FD_SETSIZE, things won't work so well with FD_SET
|
||||||
* and FD_CLR. Need to drop connections if we go above that limit */
|
* and FD_CLR. Need to drop connections if we go above that limit */
|
||||||
|
#warning strange things will happen if more than FD_SETSIZE descriptors are used
|
||||||
|
/* This test is currently not done */
|
||||||
static int fd_is_in_range(int fd) {
|
static int fd_is_in_range(int fd) {
|
||||||
if (fd >= FD_SETSIZE) {
|
if (fd >= FD_SETSIZE) {
|
||||||
print_message(msg_system_error, "too many open file descriptor to monitor them all -- dropping connection\n");
|
print_message(msg_system_error, "too many open file descriptor to monitor them all -- dropping connection\n");
|
||||||
@ -115,40 +106,6 @@ static int fd_is_in_range(int fd) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect queue 1 of connection to SSL; returns new file descriptor */
|
|
||||||
static int connect_queue(struct connection* cnx,
|
|
||||||
struct loop_info* fd_info)
|
|
||||||
{
|
|
||||||
struct queue *q = &cnx->q[1];
|
|
||||||
|
|
||||||
q->fd = connect_addr(cnx, cnx->q[0].fd, NON_BLOCKING);
|
|
||||||
if ((q->fd != -1) && fd_is_in_range(q->fd)) {
|
|
||||||
log_connection(NULL, cnx);
|
|
||||||
flush_deferred(q);
|
|
||||||
if (q->deferred_data) {
|
|
||||||
FD_SET(q->fd, &fd_info->watchers.fds_w);
|
|
||||||
FD_CLR(cnx->q[0].fd, &fd_info->watchers.fds_r);
|
|
||||||
}
|
|
||||||
FD_SET(q->fd, &fd_info->watchers.fds_r);
|
|
||||||
collection_add_fd(fd_info->collection, cnx, q->fd);
|
|
||||||
return q->fd;
|
|
||||||
} else {
|
|
||||||
tidy_connection(cnx, fd_info);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns the queue index that contains the specified file descriptor */
|
|
||||||
int active_queue(struct connection* cnx, int fd)
|
|
||||||
{
|
|
||||||
if (cnx->q[0].fd == fd) return 0;
|
|
||||||
if (cnx->q[1].fd == fd) return 1;
|
|
||||||
|
|
||||||
print_message(msg_int_error, "file descriptor %d not found in connection object\n", fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Check all connections to see if a UDP connections has timed out, then free
|
/* Check all connections to see if a UDP connections has timed out, then free
|
||||||
@ -164,10 +121,10 @@ static void udp_timeouts(struct loop_info* fd_info)
|
|||||||
|
|
||||||
time_t next_timeout = INT_MAX;
|
time_t next_timeout = INT_MAX;
|
||||||
|
|
||||||
for (int i = 0; i < fd_info->watchers.max_fd; i++) {
|
for (int i = 0; i < fd_info->watchers->max_fd; i++) {
|
||||||
/* 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->watchers.fds_r) || FD_ISSET(i, &fd_info->watchers.fds_w)) {
|
if (FD_ISSET(i, &fd_info->watchers->fds_r) || FD_ISSET(i, &fd_info->watchers->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) {
|
if (cnx) {
|
||||||
time_t timeout = udp_timeout(cnx);
|
time_t timeout = udp_timeout(cnx);
|
||||||
@ -175,8 +132,8 @@ static void udp_timeouts(struct loop_info* fd_info)
|
|||||||
if (cnx && (timeout <= now)) {
|
if (cnx && (timeout <= now)) {
|
||||||
print_message(msg_fd, "timed out UDP %d\n", cnx->target_sock);
|
print_message(msg_fd, "timed out UDP %d\n", cnx->target_sock);
|
||||||
close(cnx->target_sock);
|
close(cnx->target_sock);
|
||||||
watchers_del_read(&fd_info->watchers, i);
|
watchers_del_read(fd_info->watchers, i);
|
||||||
watchers_del_write(&fd_info->watchers, i);
|
watchers_del_write(fd_info->watchers, i);
|
||||||
collection_remove_cnx(fd_info->collection, cnx);
|
collection_remove_cnx(fd_info->collection, cnx);
|
||||||
} else {
|
} else {
|
||||||
if (timeout < next_timeout) next_timeout = timeout;
|
if (timeout < next_timeout) next_timeout = timeout;
|
||||||
@ -216,23 +173,23 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
watchers_init(&fd_info.watchers);
|
watchers_init(&fd_info.watchers);
|
||||||
|
|
||||||
for (i = 0; i < num_addr_listen; i++) {
|
for (i = 0; i < num_addr_listen; i++) {
|
||||||
watchers_add_read(&fd_info.watchers, listen_sockets[i].socketfd);
|
watchers_add_read(fd_info.watchers, listen_sockets[i].socketfd);
|
||||||
set_nonblock(listen_sockets[i].socketfd);
|
set_nonblock(listen_sockets[i].socketfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_info.collection = collection_init(fd_info.watchers.max_fd);
|
fd_info.collection = collection_init(fd_info.watchers->max_fd);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
tv.tv_sec = cfg.timeout;
|
tv.tv_sec = cfg.timeout;
|
||||||
|
|
||||||
memcpy(&readfds, &fd_info.watchers.fds_r, sizeof(readfds));
|
memcpy(&readfds, &fd_info.watchers->fds_r, sizeof(readfds));
|
||||||
memcpy(&writefds, &fd_info.watchers.fds_w, sizeof(writefds));
|
memcpy(&writefds, &fd_info.watchers->fds_w, sizeof(writefds));
|
||||||
|
|
||||||
print_message(msg_fd, "selecting... max_fd=%d num_probing=%d\n",
|
print_message(msg_fd, "selecting... max_fd=%d num_probing=%d\n",
|
||||||
fd_info.watchers.max_fd, fd_info.num_probing);
|
fd_info.watchers->max_fd, fd_info.num_probing);
|
||||||
res = select(fd_info.watchers.max_fd, &readfds, &writefds,
|
res = select(fd_info.watchers->max_fd, &readfds, &writefds,
|
||||||
NULL, fd_info.num_probing ? &tv : NULL);
|
NULL, fd_info.num_probing ? &tv : NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
perror("select");
|
perror("select");
|
||||||
@ -246,17 +203,13 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
||||||
cnx_accept_process(&fd_info, &listen_sockets[i]);
|
cnx_accept_process(&fd_info, &listen_sockets[i]);
|
||||||
|
|
||||||
if (!fd_is_in_range(0 /*TODO: retrieve fd */ )) {
|
|
||||||
/* TODO: drop the connection */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't also process it as a read socket */
|
/* don't also process it as a read socket */
|
||||||
FD_CLR(listen_sockets[i].socketfd, &readfds);
|
FD_CLR(listen_sockets[i].socketfd, &readfds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check all sockets for write activity */
|
/* Check all sockets for write activity */
|
||||||
for (i = 0; i < fd_info.watchers.max_fd; i++) {
|
for (i = 0; i < fd_info.watchers->max_fd; i++) {
|
||||||
if (FD_ISSET(i, &writefds)) {
|
if (FD_ISSET(i, &writefds)) {
|
||||||
cnx_write_process(&fd_info, i);
|
cnx_write_process(&fd_info, i);
|
||||||
}
|
}
|
||||||
@ -278,11 +231,11 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check all sockets for read activity */
|
/* Check all sockets for read activity */
|
||||||
for (i = 0; i < fd_info.watchers.max_fd; i++) {
|
for (i = 0; i < fd_info.watchers->max_fd; i++) {
|
||||||
/* Check if it's active AND currently monitored (if a connection
|
/* Check if it's active AND currently monitored (if a connection
|
||||||
* died, it gets tidied, which closes both sockets, but readfs does
|
* died, it gets tidied, which closes both sockets, but readfs does
|
||||||
* not know about that */
|
* not know about that */
|
||||||
if (FD_ISSET(i, &readfds) && FD_ISSET(i, &fd_info.watchers.fds_r)) {
|
if (FD_ISSET(i, &readfds) && FD_ISSET(i, &fd_info.watchers->fds_r)) {
|
||||||
cnx_read_process(&fd_info, i);
|
cnx_read_process(&fd_info, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define UDPLISTENER_H
|
#define UDPLISTENER_H
|
||||||
|
|
||||||
#include "collection.h"
|
#include "collection.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* UDP listener: upon incoming packet, find where it should go
|
/* UDP listener: upon incoming packet, find where it should go
|
||||||
* This is run in its own process and never returns.
|
* This is run in its own process and never returns.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user