Closed Bug 270784 Opened 15 years ago Closed 15 years ago

IPv6: retry socket connection on EACCES

Categories

(Core :: Networking, defect)

All
Linux
defect
Not set

Tracking

()

RESOLVED FIXED

People

(Reporter: lorenzo, Assigned: lorenzo)

Details

Attachments

(1 file, 1 obsolete file)

If a firewall prohibits a connection, it may generate an ICMP "administratively
prohibited" error to the sending host, who can then try to connect to another
address or inform the user.

When this happens in IPv4, connect() returns EHOSTUNREACH, but in IPv6 (at least
on Linux) it returns EACCES. However, because EACCES is mapped to
PR_NO_ACCESS_RIGHTS_ERROR:

http://lxr.mozilla.org/nspr/source/nsprpub/pr/include/prerr.h#150

which nsSocketTransport considers to be a hard error, the connection is
completely aborted and even fallback to IPv4 doesn't work.

We should change PR_NO_ACCESS_RIGHTS error to be a soft error, causing the
socket transport to try the next address in the list (and possibly fall back to
IPv4).
Oops, that wasn't quite accurate. Here's the code in nsSocketTransport which
decides what to do on an NSPR error:

http://lxr.mozilla.org/seamonkey/source/netwerk/base/src/nsSocketTransport2.cpp

and it appears that EACCES on connect() is mapped to
PR_ADDRESS_NOT_SUPPORTED_ERROR, not to PR_NO_ACCESS_RIGHTS_ERROR:

http://lxr.mozilla.org/nspr/source/nsprpub/pr/src/md/unix/unix_errors.c#559

so we need to teach nsSocketTransport about PR_ADDRESS_NOT_SUPPORTED.
Attached patch patch v1 (untested) (obsolete) — Splinter Review
Makes PR_ADDRESS_NOT_SUPPORTED_ERROR a soft error for the socket transport.

(note: untested)
Comment on attachment 166459 [details] [diff] [review]
patch v1 (untested)

r+sr=darin
Attachment #166459 - Flags: superreview+
Attachment #166459 - Flags: review+
It seems to be a Linux thing for connect() to fail
with EACCES in that case.  It is documented in the
Linux connect(2) man page:

    EACCES, EPERM
        The  user  tried  to connect to a broadcast address
        without having the socket broadcast flag enabled or
        the  connection  request  failed because of a local
        firewall rule.

The Single Unix Specification Version 3 says:
(http://www.opengroup.org/onlinepubs/009695399/functions/connect.html)

    The connect() function may fail if:

    [EACCES]
        Search permission is denied for a component of
        the path prefix; or write access to the named
        socket is denied.

This seems to apply to Unix domain sockets only.

I recommend that nsSocketTransport2.cpp also handle
PR_NO_ACCESS_RIGHTS_ERROR as a soft error.  I think
EACCES in this scenario should be mapped to
PR_NO_ACCESS_RIGHTS_ERROR (the default mapping) rather
than PR_ADDRESS_NOT_SUPPORTED_ERROR, but what is done
is done.
This patch also treats PR_NO_ACCESS_RIGHTS_ERROR as a soft error as suggested
by WTC. It also adds a comment referring to this bug.
Attachment #166459 - Attachment is obsolete: true
Comment on attachment 167286 [details] [diff] [review]
patch v2 as per wtc's suggestion

Darin, could you review this and possibly check it in?
Attachment #167286 - Flags: superreview?(darin)
Attachment #167286 - Flags: review?(darin)
Comment on attachment 167286 [details] [diff] [review]
patch v2 as per wtc's suggestion

r+sr=darin
Attachment #167286 - Flags: superreview?(darin)
Attachment #167286 - Flags: superreview+
Attachment #167286 - Flags: review?(darin)
Attachment #167286 - Flags: review+
fixed-on-trunk
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.