[xinetd] IPv6 redirect patch
Cougar
cougar at random.ee
Sun Mar 16 01:25:27 PST 2003
Hi,
I found one logical error in redirect.c. I my case I tried to make
IPv6->IPv4 proxy. In config file I had such lines:
service proxy
{
port = 8000
bind = 2001:ad0::
socket_type = stream
protocol = tcp
redirect = 10.0.0.1 8000
[----]
Now when I connect to 2001:ad0:: port 8000, xinetd should connect to IPv4
address. Here is what it actually does:
accept(6, {sin_family=AF_INET6, sin6_port=htons(38638), inet_pton(AF_INET6, "2001:ad0:ff:6::2", &sin6_addr), sin6_flowinfo=htonl(0)}}, [28]) = 8
[----]
[pid 6809] socket(PF_INET6, SOCK_STREAM, 0) = 9
[pid 6809] connect(9, {sin_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("10.0.0.1")}}, 28) = -1 EAFNOSUPPORT (Address family not supported by protocol)
In redirect.c, xinetd creates socket with the same protocol which it
listened:
if( SC_IPV4(scp) ) {
sin_len = sizeof( struct sockaddr_in );
RedirServerFd = socket(AF_INET, SOCK_STREAM, 0);
} else if( SC_IPV6(scp) ) {
sin_len = sizeof( struct sockaddr_in6 );
RedirServerFd = socket(AF_INET6, SOCK_STREAM, 0);
The right proto is what getaddrinfo() gives for destination address. So,
the right code should be:
if( serveraddr.sa_in.sin_family == AF_INET ) {
sin_len = sizeof( struct sockaddr_in );
RedirServerFd = socket(AF_INET, SOCK_STREAM, 0);
} else if( serveraddr.sa_in.sin_family == AF_INET6 ) {
sin_len = sizeof( struct sockaddr_in6 );
RedirServerFd = socket(AF_INET6, SOCK_STREAM, 0);
This way it can redirect IPv6 sockets to both IPv4 and IPv6 addresses. t
works also with IPv4 sockets without any problem. I tested all four
situations.
I attached path to this mail. There are two places in redirect.c which
should be changed.
---
Cougar
-------------- next part --------------
--- xinetd-2.3.10.orig/xinetd/redirect.c Mon Sep 9 22:40:52 2002
+++ xinetd-2.3.10/xinetd/redirect.c Sun Mar 16 10:57:35 2003
@@ -72,10 +72,11 @@
if( scp->sc_protocol.value == IPPROTO_TCP )
{
char *foo = NULL;
+ memcpy(&serveraddr, scp->sc_redir_addr, sizeof(serveraddr));
- if( SC_IPV4(scp) ) {
+ if( serveraddr.sa_in.sin_family == AF_INET ) {
sin_len = sizeof( struct sockaddr_in );
RedirServerFd = socket(AF_INET, SOCK_STREAM, 0);
- } else if( SC_IPV6(scp) ) {
+ } else if( serveraddr.sa_in.sin_family == AF_INET6 ) {
sin_len = sizeof( struct sockaddr_in6 );
RedirServerFd = socket(AF_INET6, SOCK_STREAM, 0);
} else {
@@ -95,10 +96,9 @@
msg(LOG_ERR, func,
"setsockopt SO_KEEPALIVE RedirServerFd failed: %m");
- memcpy(&serveraddr, scp->sc_redir_addr, sizeof(serveraddr));
- if( SC_IPV4(scp) )
+ if( serveraddr.sa_in.sin_family == AF_INET )
serveraddr.sa_in.sin_port = htons(serveraddr.sa_in.sin_port);
- if( SC_IPV6(scp) )
+ if( serveraddr.sa_in.sin_family == AF_INET6 )
serveraddr.sa_in6.sin6_port = htons(serveraddr.sa_in6.sin6_port);
if( connect(RedirServerFd, &serveraddr.sa, sin_len) < 0 )
More information about the Xinetd
mailing list