netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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;
}


  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).