mirror of
https://github.com/samhocevar/rinetd.git
synced 2026-08-22 14:23:27 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af88e6fd4f | ||
|
|
ff41723590 | ||
|
|
d3dd35327f | ||
|
|
49bf544bad | ||
|
|
1060048fe8 | ||
|
|
e3b47d086a | ||
|
|
f91e34c3af | ||
|
|
5e8be95d8a | ||
|
|
7887c17096 |
17
CHANGES.md
17
CHANGES.md
@@ -1,20 +1,29 @@
|
|||||||
## Version 0.71
|
## Version 0.73 (2021/02/19)
|
||||||
|
|
||||||
|
* improve error reporting
|
||||||
|
* fixed another configuration parsing bug
|
||||||
|
|
||||||
|
## Version 0.72 (2021/02/16)
|
||||||
|
|
||||||
|
* fixed a configuration parsing bug making 0.71 almost unusable
|
||||||
|
|
||||||
|
## Version 0.71 (2021/02/14)
|
||||||
|
|
||||||
* IPv6 support
|
* IPv6 support
|
||||||
* fix a display overflow in data usage statistics
|
* fixed a display overflow in data usage statistics
|
||||||
* made the configuration parser more tolerant with service names that contain
|
* made the configuration parser more tolerant with service names that contain
|
||||||
dashes (e.g. snmp-trap) or hostnames with underscores (e.g. \_http.example.com).
|
dashes (e.g. snmp-trap) or hostnames with underscores (e.g. \_http.example.com).
|
||||||
* create the log file if it does not exist
|
* create the log file if it does not exist
|
||||||
* new Visual Studio project file
|
* new Visual Studio project file
|
||||||
|
|
||||||
## Version 0.70
|
## Version 0.70 (2017/09/09)
|
||||||
|
|
||||||
* UDP support
|
* UDP support
|
||||||
* source address binding support
|
* source address binding support
|
||||||
* use a real grammar for the configuration file and get rid of the hand-made
|
* use a real grammar for the configuration file and get rid of the hand-made
|
||||||
parser
|
parser
|
||||||
|
|
||||||
## Version 0.63
|
## Version 0.63 (2017/07/19)
|
||||||
|
|
||||||
* added a `-f` flag to run in the foreground
|
* added a `-f` flag to run in the foreground
|
||||||
* quit cleanly when `SIGINT` is received
|
* quit cleanly when `SIGINT` is received
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
AC_PREREQ(2.52)
|
AC_PREREQ(2.52)
|
||||||
AC_INIT(rinetd, 0.71, sam@hocevar.net)
|
AC_INIT(rinetd, 0.73, sam@hocevar.net)
|
||||||
AC_CONFIG_AUX_DIR(.auto)
|
AC_CONFIG_AUX_DIR(.auto)
|
||||||
AC_CONFIG_SRCDIR([src/rinetd.c])
|
AC_CONFIG_SRCDIR([src/rinetd.c])
|
||||||
AC_CONFIG_HEADER([src/config.h])
|
AC_CONFIG_HEADER([src/config.h])
|
||||||
|
|||||||
2
rinetd.8
2
rinetd.8
@@ -1,4 +1,4 @@
|
|||||||
.TH rinetd 8 "2021-02-14" "rinetd 0.71"
|
.TH rinetd 8 "2021-02-19" "rinetd 0.73"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
rinetd \- internet redirection server
|
rinetd \- internet redirection server
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<CompileAs>CompileAsC</CompileAs>
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<PreprocessorDefinitions>_CONSOLE;PACKAGE_VERSION="0.71";_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CONSOLE;PACKAGE_VERSION="0.73";_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ parse.c: parse.peg
|
|||||||
if which leg >/dev/null 2>&1; then leg -o $@ $^; else touch $@; fi
|
if which leg >/dev/null 2>&1; then leg -o $@ $^; else touch $@; fi
|
||||||
|
|
||||||
# _POSIX_C_SOURCE is for SA_RESTART and others
|
# _POSIX_C_SOURCE is for SA_RESTART and others
|
||||||
|
# _DARWIN_C_SOURCE is for NI_MAXHOST on OS X
|
||||||
# _XOPEN_SOURCE is for struct sigaction
|
# _XOPEN_SOURCE is for struct sigaction
|
||||||
# _GNU_SOURCE is for h_errno and gethostbyname-related macros
|
# _GNU_SOURCE is for h_errno and gethostbyname-related macros
|
||||||
___rinetd_CFLAGS = -std=c99 \
|
___rinetd_CFLAGS = -std=c99 -D_POSIX_C_SOURCE=200809L \
|
||||||
-D_XOPEN_SOURCE -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L \
|
-D_XOPEN_SOURCE -D_GNU_SOURCE -D_DARWIN_C_SOURCE \
|
||||||
-Wall -Wextra -Wwrite-strings
|
-Wall -Wextra -Wwrite-strings
|
||||||
|
|
||||||
|
|||||||
15
src/net.c
15
src/net.c
@@ -10,6 +10,7 @@
|
|||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
void setSocketDefaults(SOCKET fd) {
|
void setSocketDefaults(SOCKET fd) {
|
||||||
@@ -32,13 +33,23 @@ void setSocketDefaults(SOCKET fd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct addrinfo getAddrInfoHint(int protocol) {
|
int getAddrInfoWithProto(char *address, char *port, int protocol, struct addrinfo **ai)
|
||||||
return (struct addrinfo) {
|
{
|
||||||
|
struct addrinfo hints = {
|
||||||
.ai_family = AF_UNSPEC,
|
.ai_family = AF_UNSPEC,
|
||||||
.ai_protocol = protocol,
|
.ai_protocol = protocol,
|
||||||
.ai_socktype = protocol == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM,
|
.ai_socktype = protocol == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM,
|
||||||
.ai_flags = AI_PASSIVE,
|
.ai_flags = AI_PASSIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int ret = getaddrinfo(address, port, &hints, ai);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "rinetd: cannot resolve host \"%s\" port %s "
|
||||||
|
"(getaddrinfo() error: %s)\n",
|
||||||
|
address, port ? port : "<null>", gai_strerror(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b) {
|
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b) {
|
||||||
|
|||||||
@@ -85,6 +85,6 @@ static inline int GetLastError(void) {
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
void setSocketDefaults(SOCKET fd);
|
void setSocketDefaults(SOCKET fd);
|
||||||
struct addrinfo getAddrInfoHint(int protocol);
|
|
||||||
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b);
|
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b);
|
||||||
|
int getAddrInfoWithProto(char *address, char *port, int protocol, struct addrinfo **ai);
|
||||||
uint16_t getPort(struct addrinfo* ai);
|
uint16_t getPort(struct addrinfo* ai);
|
||||||
|
|||||||
606
src/parse.c
606
src/parse.c
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,10 @@
|
|||||||
result = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); \
|
result = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); \
|
||||||
}
|
}
|
||||||
#define PARSE_ERROR exit(1);
|
#define PARSE_ERROR exit(1);
|
||||||
|
#define MEMORY_ERROR { \
|
||||||
|
logError("could not allocate memory when parsing configuration.\n"); \
|
||||||
|
exit(1); \
|
||||||
|
}
|
||||||
|
|
||||||
#if defined __clang__
|
#if defined __clang__
|
||||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||||
@@ -53,7 +57,13 @@ server-rule = bind-address - bind-port - connect-address - connect-port (-? se
|
|||||||
yy->connectAddress, yy->connectPort, yy->connectProto,
|
yy->connectAddress, yy->connectPort, yy->connectProto,
|
||||||
yy->serverTimeout > 0 ? yy->serverTimeout : RINETD_DEFAULT_UDP_TIMEOUT,
|
yy->serverTimeout > 0 ? yy->serverTimeout : RINETD_DEFAULT_UDP_TIMEOUT,
|
||||||
yy->sourceAddress);
|
yy->sourceAddress);
|
||||||
|
free(yy->bindAddress);
|
||||||
|
free(yy->connectAddress);
|
||||||
|
free(yy->sourceAddress);
|
||||||
yy->bindAddress = yy->connectAddress = yy->sourceAddress = NULL;
|
yy->bindAddress = yy->connectAddress = yy->sourceAddress = NULL;
|
||||||
|
free(yy->bindPort);
|
||||||
|
free(yy->connectPort);
|
||||||
|
yy->bindPort = yy->connectPort = NULL;
|
||||||
yy->serverTimeout = 0;
|
yy->serverTimeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,13 +76,11 @@ server-options = "[" -? option-list -? "]"
|
|||||||
option-list = option (-? ',' -? option-list)?
|
option-list = option (-? ',' -? option-list)?
|
||||||
option = (option-timeout | option-source)
|
option = (option-timeout | option-source)
|
||||||
option-timeout = "timeout" -? "=" -? < number > { yy->serverTimeout = atoi(yytext); }
|
option-timeout = "timeout" -? "=" -? < number > { yy->serverTimeout = atoi(yytext); }
|
||||||
option-source = "src" -? "=" -? < address > { free(yy->sourceAddress);
|
option-source = "src" -? "=" -? < address > { yy->sourceAddress = strdup(yytext); }
|
||||||
yy->sourceAddress = strdup(yytext); }
|
|
||||||
|
|
||||||
full-port = port proto
|
full-port = port proto
|
||||||
|
|
||||||
port = < (number | service) > { free(yy->tmpPort);
|
port = < (number | service) > { yy->tmpPort = strdup(yytext); }
|
||||||
yy->tmpPort = strdup(yytext); }
|
|
||||||
proto = '/tcp' { yy->tmpProto = IPPROTO_TCP; }
|
proto = '/tcp' { yy->tmpProto = IPPROTO_TCP; }
|
||||||
| '/udp' { yy->tmpProto = IPPROTO_UDP; }
|
| '/udp' { yy->tmpProto = IPPROTO_UDP; }
|
||||||
| '' { yy->tmpProto = IPPROTO_TCP; }
|
| '' { yy->tmpProto = IPPROTO_TCP; }
|
||||||
@@ -82,11 +90,11 @@ auth-rule = auth-key - < pattern >
|
|||||||
allRules = (Rule *)
|
allRules = (Rule *)
|
||||||
realloc(allRules, sizeof(Rule) * (allRulesCount + 1));
|
realloc(allRules, sizeof(Rule) * (allRulesCount + 1));
|
||||||
if (!allRules) {
|
if (!allRules) {
|
||||||
PARSE_ERROR;
|
MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
allRules[allRulesCount].pattern = strdup(yytext);
|
allRules[allRulesCount].pattern = strdup(yytext);
|
||||||
if (!allRules[allRulesCount].pattern) {
|
if (!allRules[allRulesCount].pattern) {
|
||||||
PARSE_ERROR;
|
MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
allRules[allRulesCount].type = yy->isAuthAllow ? allowRule : denyRule;
|
allRules[allRulesCount].type = yy->isAuthAllow ? allowRule : denyRule;
|
||||||
if (seTotal > 0) {
|
if (seTotal > 0) {
|
||||||
@@ -106,7 +114,7 @@ logfile = "logfile" - < filename >
|
|||||||
{
|
{
|
||||||
logFileName = strdup(yytext);
|
logFileName = strdup(yytext);
|
||||||
if (!logFileName) {
|
if (!logFileName) {
|
||||||
PARSE_ERROR;
|
MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +122,7 @@ pidlogfile = "pidlogfile" - < filename >
|
|||||||
{
|
{
|
||||||
pidLogFileName = strdup(yytext);
|
pidLogFileName = strdup(yytext);
|
||||||
if (!pidLogFileName) {
|
if (!pidLogFileName) {
|
||||||
PARSE_ERROR;
|
MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +133,7 @@ logcommon = "logcommon"
|
|||||||
|
|
||||||
invalid_syntax = < (!eol .)+ > eol
|
invalid_syntax = < (!eol .)+ > eol
|
||||||
{
|
{
|
||||||
fprintf(stderr, "rinetd: invalid syntax at line %d: %s\n",
|
logError("invalid syntax at line %d: %s\n",
|
||||||
yy->currentLine, yytext);
|
yy->currentLine, yytext);
|
||||||
PARSE_ERROR; /* FIXME */
|
PARSE_ERROR; /* FIXME */
|
||||||
}
|
}
|
||||||
@@ -136,7 +144,8 @@ pattern = (hexdigit | '[' | ']' | ':' | '.' | [*?] )+
|
|||||||
number = digit+
|
number = digit+
|
||||||
|
|
||||||
ipv4 = number '.' number '.' number '.' number | '0'
|
ipv4 = number '.' number '.' number '.' number | '0'
|
||||||
ipv6 = (hexdigit | ':')+ | '[' (hexdigit | ':')+ ']'
|
ipv6 = '[' bare_ipv6 ']' | bare_ipv6
|
||||||
|
bare_ipv6 = hexdigit* ':' (hexdigit | ':')* # Must have at least one ':'
|
||||||
hostname = (label '.')* name '.'?
|
hostname = (label '.')* name '.'?
|
||||||
|
|
||||||
|
|
||||||
@@ -159,19 +168,17 @@ void parseConfiguration(char const *file)
|
|||||||
{
|
{
|
||||||
FILE *in = fopen(file, "r");
|
FILE *in = fopen(file, "r");
|
||||||
if (!in) {
|
if (!in) {
|
||||||
PARSE_ERROR;
|
logError("could not open configuration file %s.\n", file);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
yycontext ctx;
|
yycontext ctx;
|
||||||
memset(&ctx, 0, sizeof(yycontext));
|
memset(&ctx, 0, sizeof(yycontext));
|
||||||
ctx.fp = in;
|
ctx.fp = in;
|
||||||
if (!yyparse(&ctx)) {
|
if (!yyparse(&ctx)) {
|
||||||
syslog(LOG_ERR, "invalid syntax "
|
logError("invalid syntax in file %s, line %d.\n", file, -1);
|
||||||
"on file %s, line %d.\n", file, -1);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
free(ctx.sourceAddress);
|
|
||||||
free(ctx.tmpPort);
|
|
||||||
yyrelease(&ctx);
|
yyrelease(&ctx);
|
||||||
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|||||||
95
src/rinetd.c
95
src/rinetd.c
@@ -28,9 +28,11 @@
|
|||||||
# elif HAVE_SYS_TIME_H
|
# elif HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# endif
|
# endif
|
||||||
|
# include <syslog.h>
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -106,11 +108,13 @@ enum {
|
|||||||
logDenied,
|
logDenied,
|
||||||
};
|
};
|
||||||
|
|
||||||
RinetdOptions options = {
|
static RinetdOptions options = {
|
||||||
RINETD_CONFIG_FILE,
|
RINETD_CONFIG_FILE,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int forked = 0;
|
||||||
|
|
||||||
static void selectPass(void);
|
static void selectPass(void);
|
||||||
static void handleWrite(ConnectionInfo *cnx, Socket *socket, Socket *other_socket);
|
static void handleWrite(ConnectionInfo *cnx, Socket *socket, Socket *other_socket);
|
||||||
static void handleRead(ConnectionInfo *cnx, Socket *socket, Socket *other_socket);
|
static void handleRead(ConnectionInfo *cnx, Socket *socket, Socket *other_socket);
|
||||||
@@ -158,15 +162,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
readArgs(argc, argv, &options);
|
readArgs(argc, argv, &options);
|
||||||
|
|
||||||
|
if (!options.foreground) {
|
||||||
#if HAVE_DAEMON && !DEBUG
|
#if HAVE_DAEMON && !DEBUG
|
||||||
if (!options.foreground && daemon(0, 0) != 0) {
|
if (daemon(0, 0) != 0) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
forked = 1;
|
||||||
#elif HAVE_FORK && !DEBUG
|
#elif HAVE_FORK && !DEBUG
|
||||||
if (!options.foreground && fork() != 0) {
|
if (fork() != 0) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
forked = 1;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
@@ -188,7 +196,7 @@ int main(int argc, char *argv[])
|
|||||||
registerPID(pidLogFileName ? pidLogFileName : RINETD_PID_FILE);
|
registerPID(pidLogFileName ? pidLogFileName : RINETD_PID_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
syslog(LOG_INFO, "Starting redirections...\n");
|
logInfo("starting redirections...\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
selectPass();
|
selectPass();
|
||||||
}
|
}
|
||||||
@@ -196,6 +204,38 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logError(char const *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
#if !_WIN32
|
||||||
|
if (forked)
|
||||||
|
vsyslog(LOG_ERR, fmt, ap);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
fprintf(stderr, "rinetd error: ");
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logInfo(char const *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
#if !_WIN32
|
||||||
|
if (forked)
|
||||||
|
vsyslog(LOG_INFO, fmt, ap);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
fprintf(stderr, "rinetd: ");
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
static void clearConfiguration(void) {
|
static void clearConfiguration(void) {
|
||||||
/* Remove references to server information */
|
/* Remove references to server information */
|
||||||
for (int i = 0; i < coTotal; ++i) {
|
for (int i = 0; i < coTotal; ++i) {
|
||||||
@@ -250,7 +290,7 @@ static void readConfiguration(char const *file) {
|
|||||||
if (logFile) {
|
if (logFile) {
|
||||||
setvbuf(logFile, NULL, _IONBF, 0);
|
setvbuf(logFile, NULL, _IONBF, 0);
|
||||||
} else {
|
} else {
|
||||||
syslog(LOG_ERR, "could not open %s to append (%m).\n",
|
logError("could not open %s to append (%m).\n",
|
||||||
logFileName);
|
logFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,22 +301,21 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
|||||||
int serverTimeout, char *sourceAddress)
|
int serverTimeout, char *sourceAddress)
|
||||||
{
|
{
|
||||||
ServerInfo si = {
|
ServerInfo si = {
|
||||||
.fromHost = bindAddress,
|
.fromHost = strdup(bindAddress),
|
||||||
.toHost = connectAddress,
|
.toHost = strdup(connectAddress),
|
||||||
.serverTimeout = serverTimeout,
|
.serverTimeout = serverTimeout,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Make a server socket */
|
/* Make a server socket */
|
||||||
struct addrinfo hints = getAddrInfoHint(bindProtocol), *ai;
|
struct addrinfo *ai;
|
||||||
int ret = getaddrinfo(bindAddress, bindPort, &hints, &ai);
|
int ret = getAddrInfoWithProto(bindAddress, bindPort, bindProtocol, &ai);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
si.fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
si.fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
if (si.fd == INVALID_SOCKET) {
|
if (si.fd == INVALID_SOCKET) {
|
||||||
syslog(LOG_ERR, "couldn't create server socket! (%m)\n");
|
logError("couldn't create server socket! (%m)\n");
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -285,7 +324,7 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
|||||||
setsockopt(si.fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&tmp, sizeof(tmp));
|
setsockopt(si.fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
if (bind(si.fd, ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR) {
|
if (bind(si.fd, ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR) {
|
||||||
syslog(LOG_ERR, "couldn't bind to address %s port %s (%m)\n",
|
logError("couldn't bind to address %s port %s (%m)\n",
|
||||||
bindAddress, bindPort);
|
bindAddress, bindPort);
|
||||||
closesocket(si.fd);
|
closesocket(si.fd);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
@@ -295,7 +334,7 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
|||||||
if (bindProtocol == IPPROTO_TCP) {
|
if (bindProtocol == IPPROTO_TCP) {
|
||||||
if (listen(si.fd, RINETD_LISTEN_BACKLOG) == SOCKET_ERROR) {
|
if (listen(si.fd, RINETD_LISTEN_BACKLOG) == SOCKET_ERROR) {
|
||||||
/* Warn -- don't exit. */
|
/* Warn -- don't exit. */
|
||||||
syslog(LOG_ERR, "couldn't listen to address %s port %s (%m)\n",
|
logError("couldn't listen to address %s port %s (%m)\n",
|
||||||
bindAddress, bindPort);
|
bindAddress, bindPort);
|
||||||
/* XXX: check whether this is correct */
|
/* XXX: check whether this is correct */
|
||||||
closesocket(si.fd);
|
closesocket(si.fd);
|
||||||
@@ -308,10 +347,8 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
|||||||
si.fromAddrInfo = ai;
|
si.fromAddrInfo = ai;
|
||||||
|
|
||||||
/* Resolve destination address. */
|
/* Resolve destination address. */
|
||||||
hints = getAddrInfoHint(connectProtocol);
|
ret = getAddrInfoWithProto(connectAddress, connectPort, connectProtocol, &ai);
|
||||||
ret = getaddrinfo(connectAddress, connectPort, &hints, &ai);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
|
||||||
freeaddrinfo(si.fromAddrInfo);
|
freeaddrinfo(si.fromAddrInfo);
|
||||||
closesocket(si.fd);
|
closesocket(si.fd);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -320,10 +357,8 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
|||||||
|
|
||||||
/* Resolve source address if applicable. */
|
/* Resolve source address if applicable. */
|
||||||
if (sourceAddress) {
|
if (sourceAddress) {
|
||||||
hints = getAddrInfoHint(connectProtocol);
|
ret = getAddrInfoWithProto(sourceAddress, NULL, connectProtocol, &ai);
|
||||||
ret = getaddrinfo(sourceAddress, NULL, &hints, &ai);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
|
||||||
freeaddrinfo(si.fromAddrInfo);
|
freeaddrinfo(si.fromAddrInfo);
|
||||||
freeaddrinfo(si.toAddrInfo);
|
freeaddrinfo(si.toAddrInfo);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -413,7 +448,7 @@ static ConnectionInfo *findAvailableConnection(void)
|
|||||||
int oldTotal = coTotal;
|
int oldTotal = coTotal;
|
||||||
setConnectionCount(coTotal * 4 / 3 + 8);
|
setConnectionCount(coTotal * 4 / 3 + 8);
|
||||||
if (coTotal == oldTotal) {
|
if (coTotal == oldTotal) {
|
||||||
syslog(LOG_ERR, "not enough memory to add slots. "
|
logError("not enough memory to add slots. "
|
||||||
"Currently %d slots.\n", coTotal);
|
"Currently %d slots.\n", coTotal);
|
||||||
/* Go back to the previous total number of slots */
|
/* Go back to the previous total number of slots */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -650,7 +685,7 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
/* In TCP mode, get remote address using accept(). */
|
/* In TCP mode, get remote address using accept(). */
|
||||||
nfd = accept(srv->fd, (struct sockaddr *)&addr, &addrlen);
|
nfd = accept(srv->fd, (struct sockaddr *)&addr, &addrlen);
|
||||||
if (nfd == INVALID_SOCKET) {
|
if (nfd == INVALID_SOCKET) {
|
||||||
syslog(LOG_ERR, "accept(%llu): %m\n", (long long unsigned int)srv->fd);
|
logError("accept(%llu): %m\n", (long long unsigned int)srv->fd);
|
||||||
logEvent(NULL, srv, logAcceptFailed);
|
logEvent(NULL, srv, logAcceptFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -671,7 +706,7 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
if (GetLastError() == WSAEINPROGRESS) {
|
if (GetLastError() == WSAEINPROGRESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syslog(LOG_ERR, "recvfrom(%llu): %m\n", (long long unsigned int)srv->fd);
|
logError("recvfrom(%llu): %m\n", (long long unsigned int)srv->fd);
|
||||||
logEvent(NULL, srv, logAcceptFailed);
|
logEvent(NULL, srv, logAcceptFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -730,7 +765,7 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
struct addrinfo* to = srv->toAddrInfo;
|
struct addrinfo* to = srv->toAddrInfo;
|
||||||
cnx->local.fd = socket(to->ai_family, to->ai_socktype, to->ai_protocol);
|
cnx->local.fd = socket(to->ai_family, to->ai_socktype, to->ai_protocol);
|
||||||
if (cnx->local.fd == INVALID_SOCKET) {
|
if (cnx->local.fd == INVALID_SOCKET) {
|
||||||
syslog(LOG_ERR, "socket(): %m\n");
|
logError("socket(): %m\n");
|
||||||
if (cnx->remote.protocol == IPPROTO_TCP)
|
if (cnx->remote.protocol == IPPROTO_TCP)
|
||||||
closesocket(cnx->remote.fd);
|
closesocket(cnx->remote.fd);
|
||||||
cnx->remote.fd = INVALID_SOCKET;
|
cnx->remote.fd = INVALID_SOCKET;
|
||||||
@@ -746,7 +781,7 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
if (srv->sourceAddrInfo) {
|
if (srv->sourceAddrInfo) {
|
||||||
if (bind(cnx->local.fd, srv->sourceAddrInfo->ai_addr,
|
if (bind(cnx->local.fd, srv->sourceAddrInfo->ai_addr,
|
||||||
srv->sourceAddrInfo->ai_addrlen) == SOCKET_ERROR) {
|
srv->sourceAddrInfo->ai_addrlen) == SOCKET_ERROR) {
|
||||||
syslog(LOG_ERR, "bind(): %m\n");
|
logError("bind(): %m\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,7 +901,7 @@ RETSIGTYPE plumber(int s)
|
|||||||
RETSIGTYPE hup(int s)
|
RETSIGTYPE hup(int s)
|
||||||
{
|
{
|
||||||
(void)s;
|
(void)s;
|
||||||
syslog(LOG_INFO, "Received SIGHUP, reloading configuration...\n");
|
logInfo("received SIGHUP, reloading configuration...\n");
|
||||||
/* Learn the new rules */
|
/* Learn the new rules */
|
||||||
clearConfiguration();
|
clearConfiguration();
|
||||||
readConfiguration(options.conf_file);
|
readConfiguration(options.conf_file);
|
||||||
@@ -896,8 +931,6 @@ void registerPID(char const *pid_file_name)
|
|||||||
FILE *pid_file = fopen(pid_file_name, "w");
|
FILE *pid_file = fopen(pid_file_name, "w");
|
||||||
if (pid_file == NULL) {
|
if (pid_file == NULL) {
|
||||||
/* non-fatal, non-Linux may lack /var/run... */
|
/* non-fatal, non-Linux may lack /var/run... */
|
||||||
fprintf(stderr, "rinetd: Couldn't write to "
|
|
||||||
"%s. PID was not logged.\n", pid_file_name);
|
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
fprintf(pid_file, "%d\n", getpid());
|
fprintf(pid_file, "%d\n", getpid());
|
||||||
@@ -907,8 +940,8 @@ void registerPID(char const *pid_file_name)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
error:
|
error:
|
||||||
syslog(LOG_ERR, "Couldn't write to "
|
logError("couldn't write to %s. PID was not logged (%m).\n",
|
||||||
"%s. PID was not logged (%m).\n", pid_file_name);
|
pid_file_name);
|
||||||
#else
|
#else
|
||||||
/* add other systems with wherever they register processes */
|
/* add other systems with wherever they register processes */
|
||||||
(void)pid_file_name;
|
(void)pid_file_name;
|
||||||
@@ -947,7 +980,7 @@ static void logEvent(ConnectionInfo const *cnx, ServerInfo const *srv, int resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result==logNotAllowed || result==logDenied)
|
if (result==logNotAllowed || result==logDenied)
|
||||||
syslog(LOG_INFO, "%s %s\n"
|
logInfo("%s %s\n"
|
||||||
, addressText
|
, addressText
|
||||||
, logMessages[result]);
|
, logMessages[result]);
|
||||||
if (logFile) {
|
if (logFile) {
|
||||||
@@ -1014,7 +1047,7 @@ static int readArgs (int argc, char **argv, RinetdOptions *options)
|
|||||||
case 'c':
|
case 'c':
|
||||||
options->conf_file = optarg;
|
options->conf_file = optarg;
|
||||||
if (!options->conf_file) {
|
if (!options->conf_file) {
|
||||||
syslog(LOG_ERR, "Not enough memory to "
|
fprintf(stderr, "Not enough memory to "
|
||||||
"launch rinetd.\n");
|
"launch rinetd.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/rinetd.h
13
src/rinetd.h
@@ -8,17 +8,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* Syslog feature */
|
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
# include <stdio.h>
|
|
||||||
# define syslog fprintf
|
|
||||||
# define LOG_ERR stderr
|
|
||||||
# define LOG_INFO stdout
|
|
||||||
#else
|
|
||||||
# include <syslog.h>
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
@@ -46,6 +35,8 @@ extern FILE *logFile;
|
|||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
|
void logError(char const *fmt, ...);
|
||||||
|
void logInfo(char const *fmt, ...);
|
||||||
void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
||||||
char *connectAddress, char *connectPort, int connectProtocol,
|
char *connectAddress, char *connectPort, int connectProtocol,
|
||||||
int serverTimeout, char *sourceAddress);
|
int serverTimeout, char *sourceAddress);
|
||||||
|
|||||||
Reference in New Issue
Block a user