From: Eric Dumazet <dada1@cosmosbay.com>
To: Brian Haley <brian.haley@hp.com>
Cc: Felix von Leitner <felix-kernel@fefe.de>, netdev@vger.kernel.org
Subject: Re: socket api problem: can't bind an ipv6 socket to ::ffff:0.0.0.0
Date: Tue, 17 Mar 2009 03:47:41 +0100 [thread overview]
Message-ID: <49BF0F4D.7000409@cosmosbay.com> (raw)
In-Reply-To: <49BF0A5A.2040501@hp.com>
Brian Haley a écrit :
> Felix von Leitner wrote:
>> Here's an strace:
>>
>> socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
>> fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
>> fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
>> setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
>> bind(3, {sa_family=AF_INET6, sin6_port=htons(6969), inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EADDRNOTAVAIL (Cannot assign requested address)
>>
>> This is supposed to work, and it works on other operating systems, even
>> on Mac OS X.
>>
>> I think it used to work on Linux, too.
>>
>> I'm using 2.6.29-rc7 right now, but others have reported this not
>> working on distro kernels, too.
>
> I don't think this ever worked on Linux, from the very beginning of inet6_bind():
>
> /* Check if the address belongs to the host. */
> if (addr_type == IPV6_ADDR_MAPPED) {
> v4addr = addr->sin6_addr.s6_addr32[3];
> if (inet_addr_type(net, v4addr) != RTN_LOCAL) {
> err = -EADDRNOTAVAIL;
> goto out;
> }
> } else {
>
> So if it's a mapped address, the lower 32-bits must contain a local address.
> RFC 3493 doesn't specifically mention what to do with ::ffff:0.0.0.0, so this
> looks like a gray area to me.
>
> So are you trying to get IPv4-only behavior out of this socket? Seems like the
> wrong way to go about it.
To me, section 3.7 of RFC 3493 is not gray. It is only refering to interoperate
with IPV4 applications.
Ie *sending* UDP messages to IPV4 nodes, or *connect* to TCP IPV4 nodes.
So "::ffff:0.0.0.0" has no meaning to contact an IPV4 node, since 0.0.0.0 is not
a valid IPV4 address.
RFC 2373 is also clear
Part of RFC 3493 :
Applications may use AF_INET6 sockets to open TCP connections to IPv4
nodes, or send UDP packets to IPv4 nodes, by simply encoding the
destination's IPv4 address as an IPv4-mapped IPv6 address, and
passing that address, within a sockaddr_in6 structure, in the
connect() or sendto() call. When applications use AF_INET6 sockets
to accept TCP connections from IPv4 nodes, or receive UDP packets
from IPv4 nodes, the system returns the peer's address to the
application in the accept(), recvfrom(), or getpeername() call using
a sockaddr_in6 structure encoded this way.
RFC 2373 states :
The IPv6 transition mechanisms [TRAN] include a technique for hosts
and routers to dynamically tunnel IPv6 packets over IPv4 routing
infrastructure. IPv6 nodes that utilize this technique are assigned
special IPv6 unicast addresses that carry an IPv4 address in the low-
order 32-bits. This type of address is termed an "IPv4-compatible
IPv6 address" and has the format:
| 80 bits | 16 | 32 bits |
+--------------------------------------+--------------------------+
|0000..............................0000|0000| IPv4 address |
+--------------------------------------+----+---------------------+
A second type of IPv6 address which holds an embedded IPv4 address is
also defined. This address is used to represent the addresses of
IPv4-only nodes (those that *do not* support IPv6) as IPv6 addresses.
This type of address is termed an "IPv4-mapped IPv6 address" and has
the format:
| 80 bits | 16 | 32 bits |
+--------------------------------------+--------------------------+
|0000..............................0000|FFFF| IPv4 address |
+--------------------------------------+----+---------------------+
So using the "::ffff:0.0.0.0" as a local address for an
IPv6 socket is a paradox, since "IPv4-mapped IPV6 address"
are for IPV4-only nodes.
If you want to accept only IPV4 connections, why use AF_INET6 in the first
place ?
Check how is implemented sctp_v6_cmp_addr() to see how expensive it
is to handle extensive ipv6 address comparisons...
/* Compare addresses exactly.
* v4-mapped-v6 is also in consideration.
*/
static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
const union sctp_addr *addr2)
{
if (addr1->sa.sa_family != addr2->sa.sa_family) {
if (addr1->sa.sa_family == AF_INET &&
addr2->sa.sa_family == AF_INET6 &&
ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
if (addr2->v6.sin6_port == addr1->v4.sin_port &&
addr2->v6.sin6_addr.s6_addr32[3] ==
addr1->v4.sin_addr.s_addr)
return 1;
}
if (addr2->sa.sa_family == AF_INET &&
addr1->sa.sa_family == AF_INET6 &&
ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
if (addr1->v6.sin6_port == addr2->v4.sin_port &&
addr1->v6.sin6_addr.s6_addr32[3] ==
addr2->v4.sin_addr.s_addr)
return 1;
}
return 0;
}
if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
return 0;
/* If this is a linklocal address, compare the scope_id. */
if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
(addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
return 0;
}
}
return 1;
}
next prev parent reply other threads:[~2009-03-17 2:48 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-16 23:48 socket api problem: can't bind an ipv6 socket to ::ffff:0.0.0.0 Felix von Leitner
2009-03-17 0:00 ` Stephen Hemminger
2009-03-17 0:18 ` Felix von Leitner
2009-03-17 2:26 ` Brian Haley
2009-03-17 2:47 ` Eric Dumazet [this message]
2009-03-17 8:51 ` Bjørn Mork
2009-03-17 16:00 ` Brian Haley
2009-03-17 12:58 ` Felix von Leitner
2009-03-17 13:47 ` Vlad Yasevich
2009-03-17 14:14 ` Felix von Leitner
2009-03-17 14:57 ` Vlad Yasevich
2009-03-17 17:51 ` Felix von Leitner
2009-03-17 15:21 ` Eric Dumazet
2009-03-17 18:01 ` Felix von Leitner
2009-03-17 15:59 ` Brian Haley
[not found] ` <20090317180840.GC13270@codeblau.de>
2009-03-17 19:21 ` Brian Haley
2009-03-17 19:31 ` David Miller
2009-03-17 21:05 ` Vlad Yasevich
2009-03-17 21:05 ` [RFC PATCH 1/4] ipv6: Disallow binding to v4-mapped address on v6-only socket Vlad Yasevich
2009-03-17 21:06 ` [RFC PATCH 2/4] ipv6: Allow ipv4 wildcard binds after ipv6 address binds Vlad Yasevich
2009-03-17 21:06 ` [RFC PATCH 3/4] ipv6: Make v4-mapped bindings consitant with IPv4 Vlad Yasevich
2009-03-17 21:06 ` [RFC PATCH 4/4] ipv6: Fix conflict resolutions during ipv6 binding Vlad Yasevich
2009-03-18 9:13 ` socket api problem: can't bind an ipv6 socket to ::ffff:0.0.0.0 Jarek Poplawski
2009-03-18 21:36 ` David Miller
2009-03-18 21:53 ` Jarek Poplawski
2009-03-19 0:32 ` David Miller
2009-03-17 9:03 ` Bjørn Mork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49BF0F4D.7000409@cosmosbay.com \
--to=dada1@cosmosbay.com \
--cc=brian.haley@hp.com \
--cc=felix-kernel@fefe.de \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).