forked from pool/libtirpc
63 lines
1.9 KiB
Diff
63 lines
1.9 KiB
Diff
From ea9f048761d0b9a2ab6310bffa07351f0b04d8c5 Mon Sep 17 00:00:00 2001
|
|
From: Olaf Kirch <okir@suse.de>
|
|
Date: Tue, 2 Sep 2008 12:11:15 -0400
|
|
Subject: [PATCH] Always make IPv6 sockets V6ONLY
|
|
|
|
Assume you have a netconfig file looking like this:
|
|
|
|
udp tpi_clts v inet udp - -
|
|
udp6 tpi_clts v inet6 udp - -
|
|
...
|
|
|
|
a call to svc_tli_create(... &someaddr, "udp") will fail to create an
|
|
IPv6 server socket. The problem is that on Linux, passive IPv6 sockets
|
|
will also accept packets/connections from IPv4, and will simply map
|
|
the sender's address to an IPv6 mapped IPv4 address. So if you want to
|
|
bind both a UDPv4 and UDPv6 socket to the same port, this will fail with
|
|
EADDRINUSE.
|
|
|
|
The way to avoid this behavior is to change the socket to V6ONLY,
|
|
which tells the kernel to avoid the autmatic mapping.
|
|
|
|
The change proposed in the patch below does this. I *think* this is
|
|
a good place to do this, as it will also fix applications that do not
|
|
use svc_tli_create() - such as rpcbind, which creates the sockets on
|
|
its own using __rpc_nconf2fd.
|
|
|
|
I think this also improves portability, as BSD code assumes BSD
|
|
behavior, where this mapping does not occur either.
|
|
|
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
---
|
|
src/rpc_generic.c | 9 ++++++++-
|
|
1 files changed, 8 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/src/rpc_generic.c b/src/rpc_generic.c
|
|
index 583aff0..ff4ba16 100644
|
|
--- a/src/rpc_generic.c
|
|
+++ b/src/rpc_generic.c
|
|
@@ -525,11 +525,18 @@ int
|
|
__rpc_nconf2fd(const struct netconfig *nconf)
|
|
{
|
|
struct __rpc_sockinfo si;
|
|
+ int fd;
|
|
|
|
if (!__rpc_nconf2sockinfo(nconf, &si))
|
|
return 0;
|
|
|
|
- return socket(si.si_af, si.si_socktype, si.si_proto);
|
|
+ if ((fd = socket(si.si_af, si.si_socktype, si.si_proto)) >= 0 &&
|
|
+ si.si_af == AF_INET6) {
|
|
+ int val = 1;
|
|
+
|
|
+ setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &val, sizeof(val));
|
|
+ }
|
|
+ return fd;
|
|
}
|
|
|
|
int
|
|
--
|
|
1.5.6
|
|
|