VirtualBox

Changeset 52650 in vbox


Ignore:
Timestamp:
Sep 9, 2014 3:52:47 AM (10 years ago)
Author:
vboxsync
Message:

NAT/Net: pxtcp_pmgr_connect: Solaris doesn't report either POLLERR or
POLLHUP for failed connect(2). Refactor code to always check SO_ERROR
on Solaris so that we can reject failed connection attempt immediately
instead of accepting it only to reset on the first socket operation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/pxtcp.c

    r52287 r52650  
    10891089    LWIP_ASSERT1(handler == &pxtcp->pmhdl);
    10901090    LWIP_ASSERT1(fd == pxtcp->sock);
    1091 
    1092     if (revents & (POLLNVAL | POLLHUP | POLLERR)) {
    1093         if (revents & POLLNVAL) {
    1094             pxtcp->sock = INVALID_SOCKET;
     1091    LWIP_ASSERT1(pxtcp->sockerr == 0);
     1092
     1093    if (revents & POLLNVAL) {
     1094        pxtcp->sock = INVALID_SOCKET;
     1095        pxtcp->sockerr = ETIMEDOUT;
     1096        return pxtcp_schedule_reject(pxtcp);
     1097    }
     1098
     1099    /*
     1100     * Solaris and NetBSD don't report either POLLERR or POLLHUP when
     1101     * connect(2) fails, just POLLOUT.  In that case we always need to
     1102     * check SO_ERROR.
     1103     */
     1104#if defined(RT_OS_SOLARIS) || defined(RT_OS_NETBSD)
     1105# define CONNECT_CHECK_ERROR POLLOUT
     1106#else
     1107# define CONNECT_CHECK_ERROR (POLLERR | POLLHUP)
     1108#endif
     1109
     1110    /*
     1111     * Check the cause of the failure so that pxtcp_pcb_reject() may
     1112     * behave accordingly.
     1113     */
     1114    if (revents & CONNECT_CHECK_ERROR) {
     1115        socklen_t optlen = (socklen_t)sizeof(pxtcp->sockerr);
     1116        int status;
     1117        SOCKET s;
     1118
     1119        status = getsockopt(pxtcp->sock, SOL_SOCKET, SO_ERROR,
     1120                            (char *)&pxtcp->sockerr, &optlen);
     1121        if (RT_UNLIKELY(status == SOCKET_ERROR)) { /* should not happen */
     1122            DPRINTF(("%s: sock %d: SO_ERROR failed: %R[sockerr]\n",
     1123                     __func__, fd, SOCKERRNO()));
    10951124            pxtcp->sockerr = ETIMEDOUT;
    10961125        }
    10971126        else {
    1098             socklen_t optlen = (socklen_t)sizeof(pxtcp->sockerr);
    1099             int status;
    1100             SOCKET s;
    1101 
    1102             status = getsockopt(pxtcp->sock, SOL_SOCKET, SO_ERROR,
    1103                                 (char *)&pxtcp->sockerr, &optlen);
    1104             if (status == SOCKET_ERROR) { /* should not happen */
    1105                 DPRINTF(("%s: sock %d: SO_ERROR failed: %R[sockerr]\n",
    1106                          __func__, fd, SOCKERRNO()));
    1107             }
    1108             else {
     1127            /* don't spam this log on successful connect(2) */
     1128            if ((revents & (POLLERR | POLLHUP)) /* we were told it's failed */
     1129                || pxtcp->sockerr != 0)         /* we determined it's failed */
     1130            {
    11091131                DPRINTF(("%s: sock %d: connect: %R[sockerr]\n",
    11101132                         __func__, fd, pxtcp->sockerr));
    11111133            }
     1134
     1135            if ((revents & (POLLERR | POLLHUP))
     1136                && RT_UNLIKELY(pxtcp->sockerr == 0))
     1137            {
     1138                /* if we're told it's failed, make sure it's marked as such */
     1139                pxtcp->sockerr = ETIMEDOUT;
     1140            }
     1141        }
     1142
     1143        if (pxtcp->sockerr != 0) {
    11121144            s = pxtcp->sock;
    11131145            pxtcp->sock = INVALID_SOCKET;
    11141146            closesocket(s);
    1115         }
    1116         return pxtcp_schedule_reject(pxtcp);
     1147            return pxtcp_schedule_reject(pxtcp);
     1148        }
    11171149    }
    11181150
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