VirtualBox

Changeset 28023 in vbox


Ignore:
Timestamp:
Apr 7, 2010 2:52:04 AM (15 years ago)
Author:
vboxsync
Message:

NAT: FD_CLOSE(win) and POLLHUB(Unix) events are processed in common way.

Darwin specific in handling closing connection was added.

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
3 edited

Legend:

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

    r27986 r28023  
    5656# define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
    5757
    58 # define DO_CHECK_FD_SET(so, events, fdset)                        \
    59      (   ((so)->so_poll_index != -1)                               \
    60       && ((so)->so_poll_index <= ndfs)                             \
    61       && ((so)->s == polls[so->so_poll_index].fd)                  \
    62       && (polls[(so)->so_poll_index].revents & N_(fdset ## _poll)))
    63 
     58#  define DO_CHECK_FD_SET(so, events, fdset)                        \
     59      (   ((so)->so_poll_index != -1)                               \
     60       && ((so)->so_poll_index <= ndfs)                             \
     61       && ((so)->s == polls[so->so_poll_index].fd)                  \
     62       && (polls[(so)->so_poll_index].revents & N_(fdset ## _poll)) \
     63       && !(polls[(so)->so_poll_index].revents & (POLLERR|POLLNVAL)))
    6464  /* specific for Unix API */
    6565# define DO_UNIX_CHECK_FD_SET(so, events, fdset) DO_CHECK_FD_SET((so), (events), fdset)
     
    131131# define xfds_win_bit     FD_OOB_BIT
    132132# define closefds_win     FD_CLOSE
     133# define closefds_win_bit FD_CLOSE_BIT
     134
     135# define closefds_win FD_CLOSE
    133136# define closefds_win_bit FD_CLOSE_BIT
    134137
     
    11251128
    11261129        /* out-of-band data */
    1127         if (CHECK_FD_SET(so, NetworkEvents, xfds))
     1130        if (    CHECK_FD_SET(so, NetworkEvents, xfds)
     1131#ifdef RT_OS_DARWIN
     1132            /* Darwin and probably BSD hosts generates POLLPRI|POLLHUB event on receiving TCP.flags.{ACK|URG|FIN} this
     1133             * combination on other Unixs hosts doesn't enter to this branch
     1134             */
     1135            &&  !CHECK_FD_SET(so, NetworkEvents, closefds)
     1136#endif
     1137        )
    11281138        {
    11291139            sorecvoob(pData, so);
     
    11421152            {
    11431153                TCP_CONNECT(pData, so);
    1144 #if defined(RT_OS_WINDOWS)
    11451154                if (!CHECK_FD_SET(so, NetworkEvents, closefds))
    1146 #endif
    11471155                    CONTINUE(tcp);
    11481156            }
     
    11541162        }
    11551163
    1156 #if defined(RT_OS_WINDOWS)
    11571164        /*
    11581165         * Check for FD_CLOSE events.
     
    11711178                    TCP_OUTPUT(pData, sototcpcb(so));
    11721179                else
     1180                {
     1181                    Log2(("%R[natsock] errno %d:%s\n", so, errno, strerror(errno)));
    11731182                    break;
     1183                }
    11741184            }
    11751185            /* mark the socket for termination _after_ it was drained */
     
    11771187            CONTINUE(tcp);
    11781188        }
    1179 #endif
    11801189
    11811190        /*
     
    12781287            TCP_INPUT((struct mbuf *)NULL, sizeof(struct ip),so);
    12791288        } /* SS_ISFCONNECTING */
    1280 #endif
    1281 #ifndef RT_OS_WINDOWS
    1282         if (   UNIX_CHECK_FD_SET(so, NetworkEvents, rdhup)
    1283             || UNIX_CHECK_FD_SET(so, NetworkEvents, rderr))
    1284         {
    1285             int err;
    1286             int inq, outq;
    1287             int status;
    1288             socklen_t optlen = sizeof(int);
    1289             inq = outq = 0;
    1290             status = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &optlen);
    1291             if (status != 0)
    1292                 Log(("NAT: can't get error status from %R[natsock]\n", so));
    1293 #ifndef RT_OS_SOLARIS
    1294             status = ioctl(so->s, FIONREAD, &inq); /* tcp(7) recommends SIOCINQ which is Linux specific */
    1295             if (status != 0 || status != EINVAL)
    1296             {
    1297                 /* EINVAL returned if socket in listen state tcp(7)*/
    1298                 Log(("NAT: can't get depth of IN queue status from %R[natsock]\n", so));
    1299             }
    1300             status = ioctl(so->s, TIOCOUTQ, &outq); /* SIOCOUTQ see previous comment */
    1301             if (status != 0)
    1302                 Log(("NAT: can't get depth of OUT queue from %R[natsock]\n", so));
    1303 #else
    1304                 /*
    1305                  * Solaris has bit different ioctl commands and its handlings
    1306                  * hint: streamio(7) I_NREAD
    1307                  */
    1308 #endif
    1309             if (   so->so_state & SS_ISFCONNECTING
    1310                 || UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
    1311             {
    1312                 /**
    1313                  * Check if we need here take care about gracefull connection
    1314                  * @todo try with proxy server
    1315                  */
    1316                 if (UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
    1317                 {
    1318                     /*
    1319                      * Never meet inq != 0 or outq != 0, anyway let it stay for a while
    1320                      * in case it happens we'll able to detect it.
    1321                      * Give TCP/IP stack wait or expire the socket.
    1322                      */
    1323                     Log(("NAT: %R[natsock] err(%d:%s) s(in:%d,out:%d)happens on read I/O, "
    1324                         "other side close connection \n", so, err, strerror(err), inq, outq));
    1325                     CONTINUE(tcp);
    1326                 }
    1327                 goto tcp_input_close;
    1328             }
    1329             if (   !UNIX_CHECK_FD_SET(so, NetworkEvents, readfds)
    1330                 && !UNIX_CHECK_FD_SET(so, NetworkEvents, writefds)
    1331                 && !UNIX_CHECK_FD_SET(so, NetworkEvents, xfds))
    1332             {
    1333                 Log(("NAT: system expires the socket %R[natsock] err(%d:%s) s(in:%d,out:%d) happens on non-I/O. ",
    1334                         so, err, strerror(err), inq, outq));
    1335                 goto tcp_input_close;
    1336             }
    1337             Log(("NAT: %R[natsock] we've met(%d:%s) s(in:%d, out:%d) unhandled combination hup (%d) "
    1338                 "rederr(%d) on (r:%d, w:%d, x:%d)\n",
    1339                     so, err, strerror(err),
    1340                     inq, outq,
    1341                     UNIX_CHECK_FD_SET(so, ign, rdhup),
    1342                     UNIX_CHECK_FD_SET(so, ign, rderr),
    1343                     UNIX_CHECK_FD_SET(so, ign, readfds),
    1344                     UNIX_CHECK_FD_SET(so, ign, writefds),
    1345                     UNIX_CHECK_FD_SET(so, ign, xfds)));
    1346             /*
    1347              * Give OS's TCP/IP stack a chance to resolve an issue or expire the socket.
    1348              */
    1349             CONTINUE(tcp);
    1350 tcp_input_close:
    1351             so->so_state = SS_NOFDREF; /*cause connection valid tcp connection termination and socket closing */
    1352             TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
    1353             CONTINUE(tcp);
    1354         }
    13551289#endif
    13561290        LOOP_LABEL(tcp, so, so_next);
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r26423 r28023  
    7373#ifndef RT_OS_WINDOWS
    7474    int so_poll_index;
    75 #else /* !RT_OS_WINDOWS */
     75#endif /* !RT_OS_WINDOWS */
    7676    /*
    77      * FD_CLOSE event has been occurred on socket
     77     * FD_CLOSE/POLLHUP event has been occurred on socket
    7878     */
    7979    int so_close;
    80 #endif /* RT_OS_WINDOWS */
    8180
    8281    void (* so_timeout)(PNATState pData, struct socket *so, void *arg);
  • trunk/src/VBox/Devices/Network/slirp/tcp_subr.c

    r25822 r28023  
    369369     * (see slirp.c for details about setting so_close member).
    370370     */
    371     if (   tp
    372 #ifdef RT_OS_WINDOWS
    373         && tp->t_socket
    374         && !tp->t_socket->so_close
    375 #endif
    376         )
     371    if (   tp
     372        && tp->t_socket
     373        && !tp->t_socket->so_close)
    377374        tcp_output(pData, tp);
    378375}
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