Closed
Bug 136913
Opened 23 years ago
Closed 3 years ago
PR_Bind() to PR_IpAddrLoopback fails if IPv6 not available
Categories
(NSPR :: NSPR, defect, P1)
Tracking
(Not tracked)
RESOLVED
WONTFIX
People
(Reporter: mcs, Unassigned)
References
(Blocks 1 open bug)
Details
Attachments
(1 file)
993 bytes,
text/plain
|
Details |
Calls to PR_Bind() with an IPv6 address based on PR_IpAddrLoopback fail on
Solaris machines where IPv6 is not available.
On a Solaris 2.6 machine (which does not support IPv6 at all), the error is
PR_NETWORK_UNREACHABLE_ERROR.
On a Solaris 8 machine that has no IPv6 interfaces configured, the error is
PR_ADDRESS_NOT_AVAILABLE_ERROR.
On a Solaris 8 machine that has IPv6 interfaces, it works fine.
I will attach a program that demonstrates the problem. Perhaps this is not
supposed to work. But then how can I write portable code that will work
regardless of whether IPv6 is configured?
Reporter | ||
Comment 1•23 years ago
|
||
Reporter | ||
Comment 2•23 years ago
|
||
I did some debugging inside NSPR. Two cases:
*** Case 1:
On a Solaris 8 machine without an IPv6 interface, the call stack looks like this:
bind() // system call
pt_Bind()
PR_Bind()
main()
The problem is that bind() is called with a PR_AF_INET6 address. But shouldn't
the code path be:
bind()
pt_Bind()
Ipv6ToIpv4SocketBind() // conversion layer
PR_Bind()
main()
? I set a breakpoint in _pr_init_ipv6() and found that it sets
_pr_ipv6_is_present to PR_TRUE. That seems wrong. But it looks like the socket()
call made inside _pr_test_ipv6_socket() returns a valid socket. So maybe the
IPv6 detection code does not work correctly?
*** Case 2: Solaris 2.6 (libc/OS does not support IPv6)
I don't have a NSPR build with source code available right now on a Solaris 2.6
machine, but truss shows that the bind() system call is never called. The stack
probably looks like this:
Ipv6ToIpv4SocketBind() // conversion layer
PR_Bind()
main()
because there is code in Ipv6ToIpv4SocketBind() that checks the address and
returns PR_NETWORK_UNREACHABLE_ERROR:
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
PR_IsNetAddrType(addr, PR_IpAddrAny)) {
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
tmp_addrp = &tmp_ipv4addr;
} else {
PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
return PR_FAILURE;
}
I think the basic question is whether it is safe to change NSPR to have a
special case for PR_IpAddrLoopback addresses. Functions like
Ipv6ToIpv4SocketConnect() already do. Note that if the IPv6 detection was fixed
to improve the behavior in case 1, then I would run into this problem (case 2)
on Solaris 8 anyway.
Comment 3•23 years ago
|
||
This is a known problem. It's time for me to resolve it.
> But then how can I write portable code that will work
> regardless of whether IPv6 is configured?
Maybe you can try binding your IPv6 socket to ::1 (the
IPv6 loopback address) first. If it fails, then try
binding to ::ffff:127.0.0.1 (the IPv4 loopback address
in IPv4-mapped IPv6 address format). (You would need
the PR_ConvertIPv4AddrToIPv6 function.)
It is not clear whether on an IPv4/IPv6 dual-stack
system PR_Bind should automatically retry with
::ffff:127.0.0.1 if the bind to ::1 fails, and whether
on an IPv4-only system PR_Bind should automatically
convert ::1 to 127.0.0.1. What do you guys think?
Status: NEW → ASSIGNED
Priority: -- → P1
Target Milestone: --- → 4.2.1
Reporter | ||
Comment 4•23 years ago
|
||
I don't know. Is the IPv6 loopback separate from the IPv4 one? It seems like
maybe it is on Solaris. So perhaps I just need to change my code to do something
different.
Comment 5•23 years ago
|
||
Mark,
The IPv6 loopback address is separate from the IPv4 one.
By default, Solaris 8 systems have an IPv6 stack but not
the IPv6 loopback address. NSPR's IPv6 detection code
detects the ability to open an AF_INET6 socket. This
is why NSPR considers Solaris 8 IPv6 enabled even though
the IPv6 loopback address may not exist.
On second thought, I think it is not a good idea to
automatically convert ::1 to 127.0.0.1 or fall back on
::ffff:127.0.0.1. I think we should treat ::1 and
127.0.0.1 (or ::ffff:127.0.0.1) as two different addresses.
That is, I want each application to decide whether they want
1. ::1 only; or
2. ::ffff:127.0.0.1 only; or
3. ::1 or ::ffff:127.0.0.1
when they want to bind an IPv6 NSPR socket to the "loopback
address".
This is actually what is currently implemented in NSPR.
Comment 6•23 years ago
|
||
On a dual-stack system, if you listen to ::1 I believe you would (also) get
connections to 127.0.0.1. Could someone test this?
Comment 7•23 years ago
|
||
It doesn't work this way in NES 6.x. If I specify the listen address to be ::1
then it only listens on ::1, not 127.0.0.1 as well.
Comment 8•23 years ago
|
||
Ok, they're different addresses then. It's just ::0 and ::FFFF:0.0.0.0 that
have the near equivalence.
Comment 9•23 years ago
|
||
Right now NSPR treats ::0 as a superset of ::ffff:0.0.0.0.
NSPR treats ::1 as distinct from ::ffff:127.0.0.1 in
PR_Bind but treats them as equivalent in PR_Connect and
PR_SendTo on IPv4-only systems. Should we fix this
inconsistency? Should PR_Connect and PR_SendTo treat
::1 and ::ffff:127.0.0.1 as different addresses too?
Comment 10•23 years ago
|
||
It would be good to fix the inconsistency.
Reporter | ||
Comment 11•23 years ago
|
||
I agree -- we should fix the inconsistency. The inconsistency is what led me to
file this bug, because (being somewhat naive about the behavior of dual stack
systems) I did not realize that the IPv6 loopback and the IPv4 loopback were
entirely separate (I knew they were implemented as separate network interfaces
on Solaris, so I should've realized).
Is the IPv6 detection problem I described in case 1 a bug? In the particular
code I am working on, it not longer matters as much to me because I have now
seen the light and I don't expect a listen on ::1 to work on a machine where the
IPv6 loopback is not present. But it seems like the IPv6 detection problem might
cause other problems... but it could be "as designed."
Comment 12•23 years ago
|
||
Mark,
Actually, "ifconfig -a" on a Solaris 8 system with the IPv6
loopback report both the IPv4 loopback and the IPv6 loopback
on the same network interface (lo0):
lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 10.169.36.144 netmask ffffff80 broadcast 10.169.36.255
lo0: flags=2000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6> mtu 8252 index 1
inet6 ::1/128
hme0: flags=2000841<UP,RUNNING,MULTICAST,IPv6> mtu 1500 index 2
inet6 fe80::a00:20ff:feae:460d/10
The IPv6 detection that you described in case 1, comment #2 is not
a bug. NSPR is detecting whether the IPv6 socket extension is present.
Reporter | ||
Comment 13•23 years ago
|
||
Thanks for the clarifications Wan-Teh. I will leave it to you to close this bug
(I am not sure if you want to open a different one to track the consistency
issue with PR_Bind(), PR_Connect(), and PR_SendTo().
Updated•19 years ago
|
QA Contact: wtchang → nspr
Comment 14•18 years ago
|
||
The target milestone is already released. Resetting target milestone.
Target Milestone: 4.2.1 → ---
Comment 15•18 years ago
|
||
This assigned "P1" bug is 5 years old. Maybe it's not really P1?
Reporter | ||
Comment 16•18 years ago
|
||
Definitely not a P1. Maybe this should be closed as "Won't Fix?"
Comment 17•3 years ago
|
||
The bug assignee didn't login in Bugzilla in the last 7 months.
:KaiE, could you have a look please?
For more information, please visit auto_nag documentation.
Assignee: wtc → nobody
Status: ASSIGNED → NEW
Flags: needinfo?(kaie)
Updated•3 years ago
|
Status: NEW → RESOLVED
Closed: 3 years ago
Flags: needinfo?(kaie)
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•