mirror of
https://github.com/samhocevar/rinetd.git
synced 2026-08-23 14:53:28 +08:00
Compare commits
8 Commits
feature-ip
...
v0.71
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
432aa4d230 | ||
|
|
b00f175fa4 | ||
|
|
6a1e7e75a3 | ||
|
|
7f76652af9 | ||
|
|
bb0d64ed5d | ||
|
|
3b33f45925 | ||
|
|
878c804d32 | ||
|
|
f9f5aeda80 |
@@ -1,3 +1,12 @@
|
||||
## Version 0.71
|
||||
|
||||
* IPv6 support
|
||||
* fix a display overflow in data usage statistics
|
||||
* 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).
|
||||
* create the log file if it does not exist
|
||||
* new Visual Studio project file
|
||||
|
||||
## Version 0.70
|
||||
|
||||
* UDP support
|
||||
|
||||
@@ -3,13 +3,17 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2
|
||||
|
||||
SUBDIRS = src
|
||||
|
||||
EXTRA_DIST = bootstrap COPYING CHANGES.md README.md index.html \
|
||||
EXTRA_DIST = bootstrap COPYING CHANGES.md README.md index.html rinetd.vcxproj \
|
||||
$(man_MANS) $(sysconf_DATA)
|
||||
|
||||
man_MANS = rinetd.8
|
||||
sysconf_DATA = rinetd.conf
|
||||
noinst_DATA = index.html
|
||||
|
||||
# If roffit is available, regenerate index.html
|
||||
index.html: rinetd.8
|
||||
if which roffit >/dev/null 2>&1; then roffit < $^ > $@; else touch $@; fi
|
||||
|
||||
# This is for Travis CI; we don’t have a testsuite yet.
|
||||
test:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.52)
|
||||
AC_INIT(rinetd, 0.70, sam@hocevar.net)
|
||||
AC_INIT(rinetd, 0.71, sam@hocevar.net)
|
||||
AC_CONFIG_AUX_DIR(.auto)
|
||||
AC_CONFIG_SRCDIR([src/rinetd.c])
|
||||
AC_CONFIG_HEADER([src/config.h])
|
||||
|
||||
@@ -79,7 +79,7 @@ p.roffit {
|
||||
<p class="level0">Ports default to TCP. To specify the protocol, append <span Class="emphasis">/udp</span> or <span Class="emphasis">/tcp</span> to the port number:
|
||||
<p class="level0"><span Class="bold"> 206.125.69.81 80/tcp 10.1.1.2 8000/udp</span>
|
||||
<p class="level0">Service names can be specified instead of port numbers. On most systems, service names are defined in the file <span Class="emphasis">/etc/services</span>.
|
||||
<p class="level0">Both IP addresses and hostnames are accepted for bindaddress and connectaddress.
|
||||
<p class="level0">Both IP addresses and hostnames are accepted for bindaddress and connectaddress, including IPv6.
|
||||
<p class="level0">
|
||||
<p class="level0"><a name="UDP"></a><h2 class="nroffsh">UDP timeout option</h2>
|
||||
<p class="level0">Since UDP is a connectionless protocol, a timeout is necessary or forwarding connections may accumulate with time and exhaust resources. By default, if no data is sent or received on a UDP connection for 72 seconds, the other connection is closed. This value can be changed using the <span Class="emphasis">timeout</span> option:
|
||||
@@ -87,8 +87,8 @@ p.roffit {
|
||||
<p class="level0">This rule will forward all data received on UDP port 8000 to host 10.1.1.2 on TCP port 80, and will close the connection after no data is received on the UDP port for 3600 seconds.
|
||||
<p class="level0"><a name="Source"></a><h2 class="nroffsh">Source address option</h2>
|
||||
<p class="level0">A forwarding rule option allows to bind to a specific local address when sending data to the other end. This is done using the <span Class="emphasis">src</span> option:
|
||||
<p class="level0"><span Class="bold"> 192.168.1.1 80 10.1.1.2 80 [src=192.168.1.2]</span>
|
||||
<p class="level0">Assuming the local host has two IP addresses, 192.168.1.1 and 192.168.1.2, this rule ensures that forwarded packets are sent using source address 192.168.1.2.
|
||||
<p class="level0"><span Class="bold"> 192.168.1.1 80 10.1.1.127 80 [src=10.1.1.2]</span>
|
||||
<p class="level0">Assuming the local host has two IP addresses, 10.1.1.1 and 10.1.1.2, this rule ensures that forwarded packets are sent using source address 10.1.1.2.
|
||||
<p class="level0"><a name="ALLOW"></a><h2 class="nroffsh">ALLOW AND DENY RULES</h2>
|
||||
<p class="level0">Configuration files can also contain allow and deny rules.
|
||||
<p class="level0">Allow rules which appear before the first forwarding rule are applied globally: if at least one global allow rule exists, and the address of a new connection does not satisfy at least one of the global allow rules, that connection is immediately rejected, regardless of any other rules.
|
||||
@@ -130,7 +130,7 @@ p.roffit {
|
||||
<p class="level0">The server redirected to is not able to identify the host the client really came from. This cannot be corrected; however, the log produced by <span Class="bold">rinetd</span> provides a way to obtain this information. Under Unix, Sockets would theoretically lose data when closed with SO_LINGER turned off, but in Linux this is not the case (kernel source comments support this belief on my part). On non-Linux Unix platforms, alternate code which uses a different trick to work around blocking close() is provided, but this code is untested.
|
||||
<p class="level0">The logging is inadequate. The duration of each connection should be logged. <a name="LICENSE"></a><h2 class="nroffsh">LICENSE</h2>
|
||||
<p class="level0">Copyright (c) 1997, 1998, 1999, Thomas Boutell and Boutell.Com, Inc.
|
||||
<p class="level0">Copyright (c) 2003-2017 Sam Hocevar
|
||||
<p class="level0">Copyright (c) 2003-2021 Sam Hocevar
|
||||
<p class="level0">This software is released for free use under the terms of the GNU General Public License, version 2 or higher. NO WARRANTY IS EXPRESSED OR IMPLIED. USE THIS SOFTWARE AT YOUR OWN RISK. <a name="CONTACT"></a><h2 class="nroffsh">CONTACT INFORMATION</h2>
|
||||
<p class="level0">See https://github.com/samhocevar/rinetd/releases for the latest release.
|
||||
<p class="level0">Thomas Boutell can be reached by email: boutell@boutell.com
|
||||
|
||||
12
rinetd.8
12
rinetd.8
@@ -1,4 +1,4 @@
|
||||
.TH rinetd 8 "2017-09-09" "rinetd 0.70"
|
||||
.TH rinetd 8 "2021-02-14" "rinetd 0.71"
|
||||
|
||||
.SH NAME
|
||||
rinetd \- internet redirection server
|
||||
@@ -80,7 +80,7 @@ Service names can be specified instead of port numbers. On most systems,
|
||||
service names are defined in the file \fI/etc/services\fR.
|
||||
.PP
|
||||
Both IP addresses and hostnames are accepted for
|
||||
bindaddress and connectaddress.
|
||||
bindaddress and connectaddress, including IPv6.
|
||||
.PP
|
||||
|
||||
.SS UDP timeout option
|
||||
@@ -99,10 +99,10 @@ the UDP port for 3600 seconds.
|
||||
A forwarding rule option allows to bind to a specific local address when
|
||||
sending data to the other end. This is done using the \fIsrc\fR option:
|
||||
.PP
|
||||
\fB 192.168.1.1 80 10.1.1.2 80 [src=192.168.1.2]\fR
|
||||
\fB 192.168.1.1 80 10.1.1.127 80 [src=10.1.1.2]\fR
|
||||
.PP
|
||||
Assuming the local host has two IP addresses, 192.168.1.1 and 192.168.1.2, this
|
||||
rule ensures that forwarded packets are sent using source address 192.168.1.2.
|
||||
Assuming the local host has two IP addresses, 10.1.1.1 and 10.1.1.2, this
|
||||
rule ensures that forwarded packets are sent using source address 10.1.1.2.
|
||||
|
||||
.SH ALLOW AND DENY RULES
|
||||
Configuration files can also contain allow and deny rules.
|
||||
@@ -216,7 +216,7 @@ The logging is inadequate. The duration of each connection should be logged.
|
||||
.SH LICENSE
|
||||
Copyright (c) 1997, 1998, 1999, Thomas Boutell and Boutell.Com, Inc.
|
||||
.PP
|
||||
Copyright (c) 2003\-2017 Sam Hocevar
|
||||
Copyright (c) 2003\-2021 Sam Hocevar
|
||||
.PP
|
||||
This software is released for free use under the terms of
|
||||
the GNU General Public License, version 2 or higher. NO WARRANTY
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#
|
||||
# allow 192.168.2.*
|
||||
# deny 192.168.2.1?
|
||||
# allow fe80:*
|
||||
# deny 2001:618:*:e43f
|
||||
|
||||
|
||||
#
|
||||
@@ -17,6 +19,8 @@
|
||||
#
|
||||
# bindadress bindport connectaddress connectport options...
|
||||
# 0.0.0.0 80 192.168.1.2 80
|
||||
# ::1 80 192.168.1.2 80
|
||||
# 0.0.0.0 80 fe80::1 80
|
||||
# 127.0.0.1 4000 127.0.0.1 3000
|
||||
# 127.0.0.1 4000/udp 127.0.0.1 22 [timeout=1200]
|
||||
# 127.0.0.1 8000/udp 192.168.1.2 8000/udp [src=192.168.1.2,timeout=1200]
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PreprocessorDefinitions>_CONSOLE;PACKAGE_VERSION="0.70";_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CONSOLE;PACKAGE_VERSION="0.71";_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
@@ -14,10 +14,6 @@ BUILT_SOURCES = parse.c
|
||||
parse.c: parse.peg
|
||||
if which leg >/dev/null 2>&1; then leg -o $@ $^; else touch $@; fi
|
||||
|
||||
# If roffit is available, regenerate index.html
|
||||
index.html: rinetd.8
|
||||
if which roffit >/dev/null 2>&1; then roffit < $^ > $@; else touch $@; fi
|
||||
|
||||
# _POSIX_C_SOURCE is for SA_RESTART and others
|
||||
# _XOPEN_SOURCE is for struct sigaction
|
||||
# _GNU_SOURCE is for h_errno and gethostbyname-related macros
|
||||
|
||||
@@ -32,8 +32,13 @@ void setSocketDefaults(SOCKET fd) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int getSocketType(int protocol) {
|
||||
return protocol == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
struct addrinfo getAddrInfoHint(int protocol) {
|
||||
return (struct addrinfo) {
|
||||
.ai_family = AF_UNSPEC,
|
||||
.ai_protocol = protocol,
|
||||
.ai_socktype = protocol == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM,
|
||||
.ai_flags = AI_PASSIVE,
|
||||
};
|
||||
}
|
||||
|
||||
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b) {
|
||||
|
||||
@@ -63,6 +63,10 @@
|
||||
# ifndef WSAEAGAIN
|
||||
# define WSAEAGAIN WSAEWOULDBLOCK
|
||||
# endif
|
||||
# ifdef gai_strerror
|
||||
# undef gai_strerror
|
||||
# define gai_strerror gai_strerrorA
|
||||
# endif
|
||||
#else
|
||||
/* Windows sockets compatibility defines */
|
||||
# define INVALID_SOCKET (-1)
|
||||
@@ -81,6 +85,6 @@ static inline int GetLastError(void) {
|
||||
#endif /* _WIN32 */
|
||||
|
||||
void setSocketDefaults(SOCKET fd);
|
||||
int getSocketType(int protocol);
|
||||
struct addrinfo getAddrInfoHint(int protocol);
|
||||
int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b);
|
||||
uint16_t getPort(struct addrinfo* ai);
|
||||
|
||||
33
src/parse.c
33
src/parse.c
@@ -356,7 +356,7 @@ YY_ACTION(void) yy_1_sol(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_sol\n"));
|
||||
{
|
||||
#line 150
|
||||
#line 152
|
||||
++yy->currentLine; ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
@@ -370,7 +370,7 @@ YY_ACTION(void) yy_1_invalid_syntax(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_invalid_syntax\n"));
|
||||
{
|
||||
#line 125
|
||||
#line 127
|
||||
|
||||
fprintf(stderr, "rinetd: invalid syntax at line %d: %s\n",
|
||||
yy->currentLine, yytext);
|
||||
@@ -388,7 +388,7 @@ YY_ACTION(void) yy_1_logcommon(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_logcommon\n"));
|
||||
{
|
||||
#line 120
|
||||
#line 122
|
||||
|
||||
logFormatCommon = 1;
|
||||
;
|
||||
@@ -404,7 +404,7 @@ YY_ACTION(void) yy_1_pidlogfile(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_pidlogfile\n"));
|
||||
{
|
||||
#line 112
|
||||
#line 114
|
||||
|
||||
pidLogFileName = strdup(yytext);
|
||||
if (!pidLogFileName) {
|
||||
@@ -423,7 +423,7 @@ YY_ACTION(void) yy_1_logfile(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_logfile\n"));
|
||||
{
|
||||
#line 104
|
||||
#line 106
|
||||
|
||||
logFileName = strdup(yytext);
|
||||
if (!logFileName) {
|
||||
@@ -442,7 +442,7 @@ YY_ACTION(void) yy_1_auth_key(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_auth_key\n"));
|
||||
{
|
||||
#line 101
|
||||
#line 103
|
||||
yy->isAuthAllow = (yytext[0] == 'a'); ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
@@ -456,7 +456,7 @@ YY_ACTION(void) yy_1_auth_rule(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_auth_rule\n"));
|
||||
{
|
||||
#line 79
|
||||
#line 81
|
||||
|
||||
allRules = (Rule *)
|
||||
realloc(allRules, sizeof(Rule) * (allRulesCount + 1));
|
||||
@@ -490,7 +490,7 @@ YY_ACTION(void) yy_3_proto(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_3_proto\n"));
|
||||
{
|
||||
#line 76
|
||||
#line 78
|
||||
yy->tmpProto = IPPROTO_TCP; ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
@@ -504,7 +504,7 @@ YY_ACTION(void) yy_2_proto(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_2_proto\n"));
|
||||
{
|
||||
#line 75
|
||||
#line 77
|
||||
yy->tmpProto = IPPROTO_UDP; ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
@@ -518,7 +518,7 @@ YY_ACTION(void) yy_1_proto(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_proto\n"));
|
||||
{
|
||||
#line 74
|
||||
#line 76
|
||||
yy->tmpProto = IPPROTO_TCP; ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
@@ -532,8 +532,9 @@ YY_ACTION(void) yy_1_port(yycontext *yy, char *yytext, int yyleng)
|
||||
#define yythunkpos yy->__thunkpos
|
||||
yyprintf((stderr, "do yy_1_port\n"));
|
||||
{
|
||||
#line 73
|
||||
yy->tmpPort = strdup(yytext); ;
|
||||
#line 74
|
||||
free(yy->tmpPort);
|
||||
yy->tmpPort = strdup(yytext); ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
#undef yypos
|
||||
@@ -547,7 +548,8 @@ YY_ACTION(void) yy_1_option_source(yycontext *yy, char *yytext, int yyleng)
|
||||
yyprintf((stderr, "do yy_1_option_source\n"));
|
||||
{
|
||||
#line 69
|
||||
yy->sourceAddress = strdup(yytext); ;
|
||||
free(yy->sourceAddress);
|
||||
yy->sourceAddress = strdup(yytext); ;
|
||||
}
|
||||
#undef yythunkpos
|
||||
#undef yypos
|
||||
@@ -1394,7 +1396,7 @@ YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx)
|
||||
}
|
||||
|
||||
#endif
|
||||
#line 154 "parse.peg"
|
||||
#line 156 "parse.peg"
|
||||
|
||||
|
||||
void parseConfiguration(char const *file)
|
||||
@@ -1412,6 +1414,9 @@ void parseConfiguration(char const *file)
|
||||
"on file %s, line %d.\n", file, -1);
|
||||
exit(1);
|
||||
}
|
||||
free(ctx.sourceAddress);
|
||||
free(ctx.tmpPort);
|
||||
yyrelease(&ctx);
|
||||
|
||||
fclose(in);
|
||||
|
||||
|
||||
@@ -66,11 +66,13 @@ server-options = "[" -? option-list -? "]"
|
||||
option-list = option (-? ',' -? option-list)?
|
||||
option = (option-timeout | option-source)
|
||||
option-timeout = "timeout" -? "=" -? < number > { yy->serverTimeout = atoi(yytext); }
|
||||
option-source = "src" -? "=" -? < address > { yy->sourceAddress = strdup(yytext); }
|
||||
option-source = "src" -? "=" -? < address > { free(yy->sourceAddress);
|
||||
yy->sourceAddress = strdup(yytext); }
|
||||
|
||||
full-port = port proto
|
||||
|
||||
port = < (number | service) > { yy->tmpPort = strdup(yytext); }
|
||||
port = < (number | service) > { free(yy->tmpPort);
|
||||
yy->tmpPort = strdup(yytext); }
|
||||
proto = '/tcp' { yy->tmpProto = IPPROTO_TCP; }
|
||||
| '/udp' { yy->tmpProto = IPPROTO_UDP; }
|
||||
| '' { yy->tmpProto = IPPROTO_TCP; }
|
||||
@@ -168,6 +170,9 @@ void parseConfiguration(char const *file)
|
||||
"on file %s, line %d.\n", file, -1);
|
||||
exit(1);
|
||||
}
|
||||
free(ctx.sourceAddress);
|
||||
free(ctx.tmpPort);
|
||||
yyrelease(&ctx);
|
||||
|
||||
fclose(in);
|
||||
|
||||
|
||||
103
src/rinetd.c
103
src/rinetd.c
@@ -267,87 +267,68 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
|
||||
};
|
||||
|
||||
/* Make a server socket */
|
||||
struct addrinfo hints =
|
||||
{
|
||||
.ai_family = AF_UNSPEC,
|
||||
.ai_protocol = bindProtocol,
|
||||
.ai_socktype = getSocketType(bindProtocol),
|
||||
.ai_flags = AI_PASSIVE,
|
||||
};
|
||||
struct addrinfo *servinfo;
|
||||
int ret = getaddrinfo(bindAddress, bindPort, &hints, &servinfo);
|
||||
struct addrinfo hints = getAddrInfoHint(bindProtocol), *ai;
|
||||
int ret = getaddrinfo(bindAddress, bindPort, &hints, &ai);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerrorA(ret));
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (struct addrinfo *it = servinfo; it; it = it->ai_next) {
|
||||
si.fd = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
|
||||
if (si.fd == INVALID_SOCKET) {
|
||||
syslog(LOG_ERR, "couldn't create server socket! (%m)\n");
|
||||
freeaddrinfo(servinfo);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int tmp = 1;
|
||||
setsockopt(si.fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&tmp, sizeof(tmp));
|
||||
|
||||
if (bind(si.fd, it->ai_addr, it->ai_addrlen) == SOCKET_ERROR) {
|
||||
syslog(LOG_ERR, "couldn't bind to address %s port %s (%m)\n",
|
||||
bindAddress, bindPort);
|
||||
closesocket(si.fd);
|
||||
freeaddrinfo(servinfo);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bindProtocol == IPPROTO_TCP) {
|
||||
if (listen(si.fd, RINETD_LISTEN_BACKLOG) == SOCKET_ERROR) {
|
||||
/* Warn -- don't exit. */
|
||||
syslog(LOG_ERR, "couldn't listen to address %s port %s (%m)\n",
|
||||
bindAddress, bindPort);
|
||||
/* XXX: check whether this is correct */
|
||||
closesocket(si.fd);
|
||||
}
|
||||
|
||||
/* Make socket nonblocking in TCP mode only, otherwise
|
||||
we may miss some data. */
|
||||
setSocketDefaults(si.fd);
|
||||
}
|
||||
|
||||
si.fromAddrInfo = it;
|
||||
break;
|
||||
si.fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (si.fd == INVALID_SOCKET) {
|
||||
syslog(LOG_ERR, "couldn't create server socket! (%m)\n");
|
||||
freeaddrinfo(ai);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int tmp = 1;
|
||||
setsockopt(si.fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&tmp, sizeof(tmp));
|
||||
|
||||
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",
|
||||
bindAddress, bindPort);
|
||||
closesocket(si.fd);
|
||||
freeaddrinfo(ai);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bindProtocol == IPPROTO_TCP) {
|
||||
if (listen(si.fd, RINETD_LISTEN_BACKLOG) == SOCKET_ERROR) {
|
||||
/* Warn -- don't exit. */
|
||||
syslog(LOG_ERR, "couldn't listen to address %s port %s (%m)\n",
|
||||
bindAddress, bindPort);
|
||||
/* XXX: check whether this is correct */
|
||||
closesocket(si.fd);
|
||||
}
|
||||
|
||||
/* Make socket nonblocking in TCP mode only, otherwise
|
||||
we may miss some data. */
|
||||
setSocketDefaults(si.fd);
|
||||
}
|
||||
si.fromAddrInfo = ai;
|
||||
|
||||
/* Resolve destination address. */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_protocol = connectProtocol;
|
||||
hints.ai_socktype = getSocketType(connectProtocol);
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
ret = getaddrinfo(connectAddress, connectPort, &hints, &servinfo);
|
||||
hints = getAddrInfoHint(connectProtocol);
|
||||
ret = getaddrinfo(connectAddress, connectPort, &hints, &ai);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerrorA(ret));
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
||||
freeaddrinfo(si.fromAddrInfo);
|
||||
closesocket(si.fd);
|
||||
exit(1);
|
||||
}
|
||||
si.toAddrInfo = servinfo;
|
||||
si.toAddrInfo = ai;
|
||||
|
||||
/* Resolve source address if applicable. */
|
||||
if (sourceAddress) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC,
|
||||
hints.ai_protocol = connectProtocol,
|
||||
hints.ai_socktype = getSocketType(connectProtocol),
|
||||
|
||||
ret = getaddrinfo(sourceAddress, NULL, &hints, &servinfo);
|
||||
hints = getAddrInfoHint(connectProtocol);
|
||||
ret = getaddrinfo(sourceAddress, NULL, &hints, &ai);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerrorA(ret));
|
||||
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
|
||||
freeaddrinfo(si.fromAddrInfo);
|
||||
freeaddrinfo(si.toAddrInfo);
|
||||
exit(1);
|
||||
}
|
||||
si.sourceAddrInfo = servinfo;
|
||||
si.sourceAddrInfo = ai;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
Reference in New Issue
Block a user