mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-04 19:30:04 +03:00
made echosrv independant from common.o and with its own configuration
This commit is contained in:
parent
4c570e8d57
commit
c3d019284d
9
Makefile
9
Makefile
@ -80,7 +80,7 @@ sslh: sslh-fork sslh-select
|
||||
|
||||
$(OBJS): version.h common.h collection.h sslh-conf.h gap.h
|
||||
|
||||
sslh-conf.c: sslhconf.cfg
|
||||
sslh-conf.c sslh-conf.h: sslhconf.cfg
|
||||
conf2struct sslhconf.cfg
|
||||
|
||||
sslh-fork: version.h $(OBJS) sslh-fork.o Makefile
|
||||
@ -94,8 +94,11 @@ sslh-select: version.h $(OBJS) sslh-select.o Makefile
|
||||
systemd-sslh-generator: systemd-sslh-generator.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o systemd-sslh-generator systemd-sslh-generator.o -lconfig
|
||||
|
||||
echosrv: version.h $(OBJS) echosrv.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o echosrv echosrv.o sslh-conf.o probe.o common.o tls.o argtable3.o $(LIBS)
|
||||
echosrv-conf.c echosrv-conf.h: echosrv.cfg
|
||||
conf2struct echosrv.cfg
|
||||
|
||||
echosrv: version.h echosrv-conf.c echosrv.o echosrv-conf.o argtable3.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o echosrv echosrv.o echosrv-conf.o argtable3.o $(LIBS)
|
||||
|
||||
$(MAN): sslh.pod Makefile
|
||||
pod2man --section=8 --release=$(VERSION) --center=" " sslh.pod | gzip -9 - > $(MAN)
|
||||
|
157
echosrv.c
157
echosrv.c
@ -27,9 +27,13 @@
|
||||
#include <syslog.h>
|
||||
#include <libgen.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define cfg sslhcfg
|
||||
#include "common.h"
|
||||
#include "sslh-conf.h"
|
||||
#undef cfg
|
||||
|
||||
#include "echosrv-conf.h"
|
||||
|
||||
/* Added to make the code compilable under CYGWIN
|
||||
* */
|
||||
@ -37,7 +41,24 @@
|
||||
#define SA_NOCLDWAIT 0
|
||||
#endif
|
||||
|
||||
const char* server_type = "echsrv"; /* keep setup_syslog happy */
|
||||
struct echocfg_item cfg;
|
||||
|
||||
void check_res_dump(int res, struct addrinfo *addr, char* syscall)
|
||||
{
|
||||
char buf[NI_MAXHOST];
|
||||
|
||||
if (res == -1) {
|
||||
if (addr)
|
||||
fprintf(stderr, "error %s:%s: %s\n",
|
||||
sprintaddr(buf, sizeof(buf), addr),
|
||||
syscall,
|
||||
strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "Dying just because\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void start_echo(int fd)
|
||||
{
|
||||
@ -80,7 +101,7 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
while (1)
|
||||
{
|
||||
in_socket = accept(listen_sockets[i].socketfd, 0, 0);
|
||||
if (cfg.verbose) fprintf(stderr, "accepted fd %d\n", in_socket);
|
||||
CHECK_RES_DIE(in_socket, "accept");
|
||||
|
||||
if (!fork())
|
||||
{
|
||||
@ -95,6 +116,132 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||
wait(NULL);
|
||||
}
|
||||
|
||||
/* Following is a number of utility functions copied from common.c: linking
|
||||
* against common.o directly means echosrv has to work with sslh config struct,
|
||||
* which makes it all too awkward */
|
||||
|
||||
/* simplified from common.c */
|
||||
char* sprintaddr(char* buf, size_t size, struct addrinfo *a)
|
||||
{
|
||||
char host[NI_MAXHOST], serv[NI_MAXSERV];
|
||||
int res;
|
||||
|
||||
res = getnameinfo(a->ai_addr, a->ai_addrlen,
|
||||
host, sizeof(host),
|
||||
serv, sizeof(serv),
|
||||
0 );
|
||||
|
||||
if (res) {
|
||||
/* Name resolution failed: do it numerically instead */
|
||||
res = getnameinfo(a->ai_addr, a->ai_addrlen,
|
||||
host, sizeof(host),
|
||||
serv, sizeof(serv),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
/* should not fail but... */
|
||||
if (res) {
|
||||
strcpy(host, "?");
|
||||
strcpy(serv, "?");
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, size, "%s:%s", host, serv);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/* simplified from common.c */
|
||||
int listen_single_addr(struct addrinfo* addr, int keepalive, int udp)
|
||||
{
|
||||
struct sockaddr_storage *saddr;
|
||||
int sockfd, one, res;
|
||||
|
||||
saddr = (struct sockaddr_storage*)addr->ai_addr;
|
||||
|
||||
sockfd = socket(saddr->ss_family, udp ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
check_res_dump(sockfd, addr, "socket");
|
||||
|
||||
one = 1;
|
||||
res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one));
|
||||
check_res_dump(res, addr, "setsockopt(SO_REUSEADDR)");
|
||||
|
||||
if (addr->ai_addr->sa_family == AF_INET6) {
|
||||
res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&one, sizeof(one));
|
||||
check_res_dump(res, addr, "setsockopt(IPV6_V6ONLY)");
|
||||
}
|
||||
|
||||
res = bind(sockfd, addr->ai_addr, addr->ai_addrlen);
|
||||
check_res_dump(res, addr, "bind");
|
||||
|
||||
if (!udp) {
|
||||
res = listen (sockfd, 50);
|
||||
check_res_dump(res, addr, "listen");
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/* simplified from common.c */
|
||||
int resolve_split_name(struct addrinfo **out, char* host, char* serv)
|
||||
{
|
||||
struct addrinfo hint;
|
||||
char *end;
|
||||
int res;
|
||||
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
hint.ai_family = PF_UNSPEC;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
/* If it is a RFC-Compliant IPv6 address ("[1234::12]:443"), remove brackets
|
||||
* around IP address */
|
||||
if (host[0] == '[') {
|
||||
end = strrchr(host, ']');
|
||||
if (!end) {
|
||||
fprintf(stderr, "%s: no closing bracket in IPv6 address?\n", host);
|
||||
return -1;
|
||||
}
|
||||
host++; /* skip first bracket */
|
||||
*end = 0; /* remove last bracket */
|
||||
}
|
||||
|
||||
res = getaddrinfo(host, serv, &hint, out);
|
||||
|
||||
if (res)
|
||||
fprintf(stderr, "%s `%s:%s'\n", gai_strerror(res), host, serv);
|
||||
return res;
|
||||
}
|
||||
|
||||
int start_listen_sockets(struct listen_endpoint *sockfd[])
|
||||
{
|
||||
struct addrinfo *addr, *start_addr;
|
||||
char buf[NI_MAXHOST];
|
||||
int i, res;
|
||||
int num_addr = 0, keepalive = 0, udp = 0;
|
||||
|
||||
*sockfd = NULL;
|
||||
|
||||
fprintf(stderr, "Listening to:\n");
|
||||
|
||||
for (i = 0; i < cfg.listen_len; i++) {
|
||||
udp = cfg.udp;
|
||||
|
||||
|
||||
res = resolve_split_name(&start_addr, cfg.listen[i].host, cfg.listen[i].port);
|
||||
if (res) exit(4);
|
||||
|
||||
for (addr = start_addr; addr; addr = addr->ai_next) {
|
||||
num_addr++;
|
||||
*sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd));
|
||||
(*sockfd)[num_addr-1].socketfd = listen_single_addr(addr, keepalive, udp);
|
||||
(*sockfd)[num_addr-1].type = udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||
fprintf(stderr, "%d:\t%s\n", (*sockfd)[num_addr-1].socketfd, sprintaddr(buf, sizeof(buf), addr));
|
||||
}
|
||||
freeaddrinfo(start_addr);
|
||||
}
|
||||
|
||||
return num_addr;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@ -105,10 +252,10 @@ int main(int argc, char *argv[])
|
||||
struct listen_endpoint *listen_sockets;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
if (sslhcfg_cl_parse(argc, argv, &cfg))
|
||||
if (echocfg_cl_parse(argc, argv, &cfg))
|
||||
exit(1);
|
||||
|
||||
sslhcfg_fprint(stdout, &cfg, 0);
|
||||
echocfg_fprint(stdout, &cfg, 0);
|
||||
|
||||
num_addr_listen = start_listen_sockets(&listen_sockets);
|
||||
|
||||
|
37
echosrv.cfg
Normal file
37
echosrv.cfg
Normal file
@ -0,0 +1,37 @@
|
||||
# conf2struct for echosrv
|
||||
|
||||
header: "echosrv-conf.h";
|
||||
parser: "echosrv-conf.c";
|
||||
|
||||
printer: true;
|
||||
|
||||
conffile_option: ("F", "config");
|
||||
|
||||
config: {
|
||||
name: "echocfg",
|
||||
type: "list",
|
||||
items: (
|
||||
{name: "udp", type: "bool"; default: false; },
|
||||
{name: "prefix", type: "string"; },
|
||||
{ name: "listen",
|
||||
type: "list",
|
||||
items: (
|
||||
{ name: "host"; type: "string"; var: true; },
|
||||
{ name: "port"; type: "string"; var: true; }
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
cl_groups: (
|
||||
{ name: "listen"; pattern: "(.+):(\w+)"; description: "Listen on host:port";
|
||||
short: "p"; argdesc: "<host:port>";
|
||||
list: "listen";
|
||||
# no override, this just adds to the list (and thus can be specified several times)
|
||||
targets: (
|
||||
{ path: "host"; value: "$1" },
|
||||
{ path: "port"; value: "$2" }
|
||||
);
|
||||
}
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user