File xinetd-2.3.14-ipv6-ipv4-fallback.patch of Package xinetd
--- xinetd/confparse.c
+++ xinetd/confparse.c
@@ -544,10 +544,9 @@
}
if( SC_IPV4( scp ) && SC_IPV6( scp ) ) {
- msg( LOG_ERR, func,
- "Service %s specified as both IPv4 and IPv6 - DISABLING",
+ msg( LOG_INFO, func,
+ "Service %s will use IPv6 or fallback to IPv4",
SC_NAME(scp));
- return FAILED ;
}
/*
--- xinetd/service.c
+++ xinetd/service.c
@@ -322,12 +322,29 @@
return( OK );
}
- if( SC_IPV4( scp ) ) {
+ if( SC_IPV4( scp ) && !SC_IPV6(scp) ) {
SVC_FD(sp) = socket( AF_INET,
SC_SOCKET_TYPE( scp ), SC_PROTOVAL( scp ) ) ;
} else if( SC_IPV6( scp ) ) {
SVC_FD(sp) = socket( AF_INET6,
SC_SOCKET_TYPE( scp ), SC_PROTOVAL( scp ) ) ;
+ /* service with IPv6-IPv4 fallback
+ * - if IPv6 succeeds, use IPv6 and clear the IPv4 flag
+ * - if IPv6 fails, use IPv4 socket and clear the IPv6 flag
+ */
+ if( SVC_FD(sp) == -1 ) {
+ if( SC_IPV4(scp) ) {
+ msg( LOG_INFO, func,
+ "IPv6 socket creation failed (%m), service = %s", SC_ID( scp ) );
+ msg( LOG_INFO, func,
+ "falling back to IPv4, service = %s", SC_ID( scp ) );
+ M_CLEAR(SC_XFLAGS(scp), SF_IPV6);
+ SVC_FD(sp) = socket( AF_INET,
+ SC_SOCKET_TYPE( scp ), SC_PROTOVAL( scp ) ) ;
+ }
+ } else {
+ M_CLEAR(SC_XFLAGS(scp), SF_IPV4);
+ }
}
if ( SVC_FD(sp) == -1 )
--- etc/xinetd.d/chargen
+++ etc/xinetd.d/chargen
@@ -10,4 +10,5 @@
user = root
wait = no
disable = yes
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/chargen-udp
+++ etc/xinetd.d/chargen-udp
@@ -11,4 +11,5 @@
wait = yes
disable = yes
port = 19
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/daytime
+++ etc/xinetd.d/daytime
@@ -10,4 +10,5 @@
user = root
wait = no
disable = yes
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/daytime-udp
+++ etc/xinetd.d/daytime-udp
@@ -11,4 +11,5 @@
wait = yes
disable = yes
port = 13
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/discard
+++ etc/xinetd.d/discard
@@ -10,4 +10,5 @@
user = root
wait = no
disable = yes
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/discard-udp
+++ etc/xinetd.d/discard-udp
@@ -11,4 +11,5 @@
wait = yes
disable = yes
port = 9
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/echo
+++ etc/xinetd.d/echo
@@ -10,4 +10,5 @@
user = root
wait = no
disable = yes
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/echo-udp
+++ etc/xinetd.d/echo-udp
@@ -11,4 +11,5 @@
wait = yes
disable = yes
port = 7
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/servers
+++ etc/xinetd.d/servers
@@ -10,4 +10,5 @@
wait = no
disable = yes
only_from = 127.0.0.1
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/services
+++ etc/xinetd.d/services
@@ -10,4 +10,5 @@
wait = no
disable = yes
only_from = 127.0.0.1
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/time
+++ etc/xinetd.d/time
@@ -11,4 +11,5 @@
user = root
wait = no
disable = yes
+ FLAGS = IPv6 IPv4
}
--- etc/xinetd.d/time-udp
+++ etc/xinetd.d/time-udp
@@ -11,4 +11,5 @@
wait = yes
disable = yes
port = 37
+ FLAGS = IPv6 IPv4
}
--- xinetd/xinetd.conf.man
+++ xinetd/xinetd.conf.man
@@ -142,6 +142,10 @@
.TP
.B IPv6
Sets the service to be an IPv6 service (AF_INET6), if IPv6 is available on the system.
+If you give both the IPv4 and IPv6 flag, then xinetd will first try to create
+an IPv6 service (wich can accept IPv4 connections by default), and if that
+fails (ie. the operating system doesn't have IPv6 support), it will create an
+IPv4 service.
.TP
.B REUSE
The REUSE flag is deprecated. All services now implicitly use the REUSE flag.