VirtualBox

Changeset 52663 in vbox


Ignore:
Timestamp:
Sep 9, 2014 9:53:53 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
95982
Message:

NAT: Redo detection of connect(2) failure taking into account various
poll(2) quirks. For now just reset the nascent connection. Later we
might want to restrict that to ECONNREFUSED only and to send ICMP or
just silently drop the connection for other errors, like NAT Network
does.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r52662 r52663  
    967967        LOG_NAT_SOCK(so, TCP, &NetworkEvents, readfds, writefds, xfds);
    968968
     969        if (so->so_state & SS_ISFCONNECTING)
     970        {
     971            bool reject = false;
     972#if !defined(RT_OS_WINDOWS)
     973            {
     974                /*
     975                 * Failed connect(2) is reported by poll(2) on
     976                 * different OSes with different combinations of
     977                 * POLLERR, POLLHUP, and POLLOUT.
     978                 */
     979                if (   CHECK_FD_SET(so, NetworkEvents, closefds) /* POLLHUP */
     980                    || CHECK_FD_SET(so, NetworkEvents, rderr))   /* POLLERR */
     981                {
     982                    reject = true;
     983                }
     984#if defined(RT_OS_SOLARIS) || defined(RT_OS_NETBSD)
     985                else if (CHECK_FD_SET(so, NetworkEvents, writefds)) /* POLLOUT */
     986                {
     987                    /* Solaris and NetBSD report plain POLLOUT even on error */
     988                    int sockerr;
     989                    socklen_t optlen = (socklen_t)sizeof(sockerr);
     990                    ret = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &sockerr, &optlen);
     991                    if (ret < 0)
     992                        sockerr = ENETDOWN;
     993                    if (sockerr != 0)
     994                        reject = true;
     995                }
     996#endif
     997            }
     998#else  /* RT_OS_WINDOWS */
     999            {
     1000                /*
     1001                 * XXX: CHECK_FD_SET is defined to return false when
     1002                 * there's an error pending, which makes it unusable
     1003                 * here.
     1004                 */
     1005                if (   (NetworkEvents.lNetworkEvents & FD_CONNECT)
     1006                    && NetworkEvents.iErrorCode[FD_CONNECT_BIT] != 0)
     1007                {
     1008                    reject = true;
     1009                }
     1010            }
     1011#endif
     1012            if (reject)
     1013            {
     1014                /* "continue" tcp_input() to reject connection from guest */
     1015                so->so_state = SS_NOFDREF;
     1016                TCP_INPUT(pData, NULL, 0, so);
     1017                ret = slirpVerifyAndFreeSocket(pData, so);
     1018                Assert(ret == 1); /* freed */
     1019                CONTINUE(tcp);
     1020            }
     1021
     1022            /*
     1023             * XXX: For now just fall through to the old code to
     1024             * handle successful connect(2).
     1025             */
     1026        }
    9691027
    9701028        /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette