VirtualBox

Changeset 20170 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Jun 2, 2009 2:05:34 AM (16 years ago)
Author:
vboxsync
Message:

NAT: reading (less nesting)

File:
1 edited

Legend:

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

    r20164 r20170  
    10611061     * Check sockets
    10621062     */
    1063     if (link_up)
    1064     {
     1063    if (!link_up)
     1064        goto done;
    10651065#if defined(RT_OS_WINDOWS)
    1066         /*XXX: before renaming please make see define
    1067          * fIcmp in slirp_state.h
     1066    /*XXX: before renaming please make see define
     1067     * fIcmp in slirp_state.h
     1068     */
     1069    if (fIcmp)
     1070        sorecvfrom(pData, &pData->icmp_socket);
     1071#else
     1072    if (   (pData->icmp_socket.s != -1)
     1073        && CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
     1074        sorecvfrom(pData, &pData->icmp_socket);
     1075#endif
     1076    /*
     1077     * Check TCP sockets
     1078     */
     1079    QSOCKET_FOREACH(so, so_next, tcp)
     1080    /* { */
     1081
     1082#ifdef VBOX_WITH_SLIRP_MT
     1083        if (   so->so_state & SS_NOFDREF
     1084            && so->so_deleted == 1)
     1085        {
     1086            struct socket *son, *sop = NULL;
     1087            QSOCKET_LOCK(tcb);
     1088            if (so->so_next != NULL)
     1089            {
     1090                if (so->so_next != &tcb)
     1091                    SOCKET_LOCK(so->so_next);
     1092                son = so->so_next;
     1093            }
     1094            if (    so->so_prev != &tcb
     1095                && so->so_prev != NULL)
     1096            {
     1097                SOCKET_LOCK(so->so_prev);
     1098                sop = so->so_prev;
     1099            }
     1100            QSOCKET_UNLOCK(tcb);
     1101            remque(pData, so);
     1102            NSOCK_DEC();
     1103            SOCKET_UNLOCK(so);
     1104            SOCKET_LOCK_DESTROY(so);
     1105            RTMemFree(so);
     1106            so_next = son;
     1107            if (sop != NULL)
     1108                SOCKET_UNLOCK(sop);
     1109            CONTINUE_NO_UNLOCK(tcp);
     1110        }
     1111#endif
     1112        /*
     1113         * FD_ISSET is meaningless on these sockets
     1114         * (and they can crash the program)
    10681115         */
    1069         if (fIcmp)
    1070             sorecvfrom(pData, &pData->icmp_socket);
    1071 #else
    1072         if (   (pData->icmp_socket.s != -1)
    1073             && CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
    1074             sorecvfrom(pData, &pData->icmp_socket);
    1075 #endif
     1116        if (so->so_state & SS_NOFDREF || so->s == -1)
     1117            CONTINUE(tcp);
     1118       
     1119        POLL_TCP_EVENTS(rc, error, so, &NetworkEvents);
     1120       
     1121        LOG_NAT_SOCK(so, TCP, &NetworkEvents, readfds, writefds, xfds);
     1122       
     1123       
    10761124        /*
    1077          * Check TCP sockets
     1125         * Check for URG data
     1126         * This will soread as well, so no need to
     1127         * test for readfds below if this succeeds
    10781128         */
    1079         QSOCKET_FOREACH(so, so_next, tcp)
    1080         /* { */
    1081 
    1082 #ifdef VBOX_WITH_SLIRP_MT
    1083             if (   so->so_state & SS_NOFDREF
    1084                 && so->so_deleted == 1)
    1085             {
    1086                 struct socket *son, *sop = NULL;
    1087                 QSOCKET_LOCK(tcb);
    1088                 if (so->so_next != NULL)
    1089                 {
    1090                     if (so->so_next != &tcb)
    1091                         SOCKET_LOCK(so->so_next);
    1092                     son = so->so_next;
    1093                 }
    1094                 if (    so->so_prev != &tcb
    1095                     && so->so_prev != NULL)
    1096                 {
    1097                     SOCKET_LOCK(so->so_prev);
    1098                     sop = so->so_prev;
    1099                 }
    1100                 QSOCKET_UNLOCK(tcb);
    1101                 remque(pData, so);
    1102                 NSOCK_DEC();
    1103                 SOCKET_UNLOCK(so);
    1104                 SOCKET_LOCK_DESTROY(so);
    1105                 RTMemFree(so);
    1106                 so_next = son;
    1107                 if (sop != NULL)
    1108                     SOCKET_UNLOCK(sop);
    1109                 CONTINUE_NO_UNLOCK(tcp);
    1110             }
    1111 #endif
     1129       
     1130        /* out-of-band data */
     1131        if (CHECK_FD_SET(so, NetworkEvents, xfds))
     1132        {
     1133            sorecvoob(pData, so);
     1134        }
     1135       
     1136        /*
     1137         * Check sockets for reading
     1138         */
     1139        else if (   CHECK_FD_SET(so, NetworkEvents, readfds)
     1140                 || WIN_CHECK_FD_SET(so, NetworkEvents, acceptds))
     1141        {
    11121142            /*
    1113              * FD_ISSET is meaningless on these sockets
    1114              * (and they can crash the program)
     1143             * Check for incoming connections
    11151144             */
    1116             if (so->so_state & SS_NOFDREF || so->s == -1)
    1117                 CONTINUE(tcp);
    1118 
    1119             POLL_TCP_EVENTS(rc, error, so, &NetworkEvents);
    1120 
    1121             LOG_NAT_SOCK(so, TCP, &NetworkEvents, readfds, writefds, xfds);
    1122 
    1123 
     1145            if (so->so_state & SS_FACCEPTCONN)
     1146            {
     1147                TCP_CONNECT(pData, so);
     1148#if defined(RT_OS_WINDOWS)
     1149                if (!(NetworkEvents.lNetworkEvents & FD_CLOSE))
     1150#endif
     1151                    CONTINUE(tcp);
     1152            }
     1153       
     1154            ret = soread(pData, so);
     1155            /* Output it if we read something */
     1156            if (ret > 0)
     1157                TCP_OUTPUT(pData, sototcpcb(so));
     1158        }
     1159
     1160#if defined(RT_OS_WINDOWS)
     1161        /*
     1162         * Check for FD_CLOSE events.
     1163         * in some cases once FD_CLOSE engaged on socket it could be flashed latter (for some reasons)
     1164         */
     1165        if (    (NetworkEvents.lNetworkEvents & FD_CLOSE)
     1166            ||  (so->so_close == 1))
     1167        {
     1168            so->so_close = 1; /* mark it */
    11241169            /*
    1125              * Check for URG data
    1126              * This will soread as well, so no need to
    1127              * test for readfds below if this succeeds
     1170             * drain the socket
    11281171             */
    1129 
    1130             /* out-of-band data */
    1131             if (CHECK_FD_SET(so, NetworkEvents, xfds))
    1132             {
    1133                 sorecvoob(pData, so);
    1134             }
    1135 
    1136             /*
    1137              * Check sockets for reading
    1138              */
    1139             else if (   CHECK_FD_SET(so, NetworkEvents, readfds)
    1140                      || WIN_CHECK_FD_SET(so, NetworkEvents, acceptds))
    1141             {
    1142                 /*
    1143                  * Check for incoming connections
    1144                  */
    1145                 if (so->so_state & SS_FACCEPTCONN)
    1146                 {
    1147                     TCP_CONNECT(pData, so);
    1148 #if defined(RT_OS_WINDOWS)
    1149                     if (!(NetworkEvents.lNetworkEvents & FD_CLOSE))
    1150 #endif
    1151                         CONTINUE(tcp);
    1152                 }
    1153 
     1172            for (;;)
     1173            {
    11541174                ret = soread(pData, so);
    1155                 /* Output it if we read something */
    11561175                if (ret > 0)
    11571176                    TCP_OUTPUT(pData, sototcpcb(so));
    1158             }
    1159 
    1160 #if defined(RT_OS_WINDOWS)
     1177                else
     1178                    break;
     1179            }
     1180            CONTINUE(tcp);
     1181        }
     1182#endif
     1183       
     1184        /*
     1185         * Check sockets for writing
     1186         */
     1187        if (CHECK_FD_SET(so, NetworkEvents, writefds))
     1188        {
    11611189            /*
    1162              * Check for FD_CLOSE events.
    1163              * in some cases once FD_CLOSE engaged on socket it could be flashed latter (for some reasons)
     1190             * Check for non-blocking, still-connecting sockets
    11641191             */
    1165             if (    (NetworkEvents.lNetworkEvents & FD_CLOSE)
    1166                 ||  (so->so_close == 1))
    1167             {
    1168                 so->so_close = 1; /* mark it */
     1192            if (so->so_state & SS_ISFCONNECTING)
     1193            {
     1194                Log2(("connecting %R[natsock] catched\n", so));
     1195                /* Connected */
     1196                so->so_state &= ~SS_ISFCONNECTING;
     1197       
    11691198                /*
    1170                  * drain the socket
     1199                 * This should be probably guarded by PROBE_CONN too. Anyway,
     1200                 * we disable it on OS/2 because the below send call returns
     1201                 * EFAULT which causes the opened TCP socket to close right
     1202                 * after it has been opened and connected.
    11711203                 */
    1172                 for (;;)
     1204#ifndef RT_OS_OS2
     1205                ret = send(so->s, (const char *)&ret, 0, 0);
     1206                if (ret < 0)
    11731207                {
    1174                     ret = soread(pData, so);
    1175                     if (ret > 0)
    1176                         TCP_OUTPUT(pData, sototcpcb(so));
    1177                     else
    1178                         break;
     1208                    /* XXXXX Must fix, zero bytes is a NOP */
     1209                    if (   errno == EAGAIN
     1210                        || errno == EWOULDBLOCK
     1211                        || errno == EINPROGRESS
     1212                        || errno == ENOTCONN)
     1213                        CONTINUE(tcp);
     1214               
     1215                    /* else failed */
     1216                    so->so_state = SS_NOFDREF;
    11791217                }
    1180                 CONTINUE(tcp);
    1181             }
    1182 #endif
    1183 
     1218                /* else so->so_state &= ~SS_ISFCONNECTING; */
     1219#endif
     1220       
     1221                /*
     1222                 * Continue tcp_input
     1223                 */
     1224                TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
     1225                /* continue; */
     1226            }
     1227            else
     1228                SOWRITE(ret, pData, so);
    11841229            /*
    1185              * Check sockets for writing
     1230             * XXX If we wrote something (a lot), there could be the need
     1231             * for a window update. In the worst case, the remote will send
     1232             * a window probe to get things going again.
    11861233             */
    1187             if (CHECK_FD_SET(so, NetworkEvents, writefds))
    1188             {
    1189                 /*
    1190                  * Check for non-blocking, still-connecting sockets
    1191                  */
    1192                 if (so->so_state & SS_ISFCONNECTING)
     1234        }
     1235       
     1236        /*
     1237         * Probe a still-connecting, non-blocking socket
     1238         * to check if it's still alive
     1239         */
     1240#ifdef PROBE_CONN
     1241        if (so->so_state & SS_ISFCONNECTING)
     1242        {
     1243            ret = recv(so->s, (char *)&ret, 0, 0);
     1244       
     1245            if (ret < 0)
     1246            {
     1247                /* XXX */
     1248                if (   errno == EAGAIN
     1249                    || errno == EWOULDBLOCK
     1250                    || errno == EINPROGRESS
     1251                    || errno == ENOTCONN)
    11931252                {
    1194                     Log2(("connecting %R[natsock] catched\n", so));
    1195                     /* Connected */
    1196                     so->so_state &= ~SS_ISFCONNECTING;
    1197 
    1198                     /*
    1199                      * This should be probably guarded by PROBE_CONN too. Anyway,
    1200                      * we disable it on OS/2 because the below send call returns
    1201                      * EFAULT which causes the opened TCP socket to close right
    1202                      * after it has been opened and connected.
    1203                      */
    1204 #ifndef RT_OS_OS2
    1205                     ret = send(so->s, (const char *)&ret, 0, 0);
    1206                     if (ret < 0)
    1207                     {
    1208                         /* XXXXX Must fix, zero bytes is a NOP */
    1209                         if (   errno == EAGAIN
    1210                             || errno == EWOULDBLOCK
    1211                             || errno == EINPROGRESS
    1212                             || errno == ENOTCONN)
    1213                             CONTINUE(tcp);
    1214 
    1215                         /* else failed */
    1216                         so->so_state = SS_NOFDREF;
    1217                     }
    1218                     /* else so->so_state &= ~SS_ISFCONNECTING; */
    1219 #endif
    1220 
    1221                     /*
    1222                      * Continue tcp_input
    1223                      */
    1224                     TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
    1225                     /* continue; */
     1253                    CONTINUE(tcp); /* Still connecting, continue */
    12261254                }
    1227                 else
    1228                     SOWRITE(ret, pData, so);
    1229                 /*
    1230                  * XXX If we wrote something (a lot), there could be the need
    1231                  * for a window update. In the worst case, the remote will send
    1232                  * a window probe to get things going again.
    1233                  */
    1234             }
    1235 
    1236             /*
    1237              * Probe a still-connecting, non-blocking socket
    1238              * to check if it's still alive
    1239              */
    1240 #ifdef PROBE_CONN
    1241             if (so->so_state & SS_ISFCONNECTING)
    1242             {
    1243                 ret = recv(so->s, (char *)&ret, 0, 0);
    1244 
     1255       
     1256                /* else failed */
     1257                so->so_state = SS_NOFDREF;
     1258       
     1259                /* tcp_input will take care of it */
     1260            }
     1261            else
     1262            {
     1263                ret = send(so->s, &ret, 0, 0);
    12451264                if (ret < 0)
    12461265                {
     
    12511270                        || errno == ENOTCONN)
    12521271                    {
    1253                         CONTINUE(tcp); /* Still connecting, continue */
     1272                        CONTINUE(tcp);
    12541273                    }
    1255 
    12561274                    /* else failed */
    12571275                    so->so_state = SS_NOFDREF;
    1258 
    1259                     /* tcp_input will take care of it */
    12601276                }
    12611277                else
    1262                 {
    1263                     ret = send(so->s, &ret, 0, 0);
    1264                     if (ret < 0)
    1265                     {
    1266                         /* XXX */
    1267                         if (   errno == EAGAIN
    1268                             || errno == EWOULDBLOCK
    1269                             || errno == EINPROGRESS
    1270                             || errno == ENOTCONN)
    1271                         {
    1272                             CONTINUE(tcp);
    1273                         }
    1274                         /* else failed */
    1275                         so->so_state = SS_NOFDREF;
    1276                     }
    1277                     else
    1278                         so->so_state &= ~SS_ISFCONNECTING;
    1279 
    1280                 }
    1281                 TCP_INPUT((struct mbuf *)NULL, sizeof(struct ip),so);
    1282             } /* SS_ISFCONNECTING */
     1278                    so->so_state &= ~SS_ISFCONNECTING;
     1279       
     1280            }
     1281            TCP_INPUT((struct mbuf *)NULL, sizeof(struct ip),so);
     1282        } /* SS_ISFCONNECTING */
    12831283#endif
    12841284#ifndef RT_OS_WINDOWS
    1285             if (   UNIX_CHECK_FD_SET(so, NetworkEvents, rdhup)
    1286                 || UNIX_CHECK_FD_SET(so, NetworkEvents, rderr))
    1287             {
    1288                 int err;
    1289                 int inq, outq;
    1290                 int status;
    1291                 socklen_t optlen = sizeof(int);
    1292                 inq = outq = 0;
    1293                 status = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &optlen);
    1294                 if (status != 0)
    1295                     Log(("NAT: can't get error status from %R[natsock]\n", so));
     1285        if (   UNIX_CHECK_FD_SET(so, NetworkEvents, rdhup)
     1286            || UNIX_CHECK_FD_SET(so, NetworkEvents, rderr))
     1287        {
     1288            int err;
     1289            int inq, outq;
     1290            int status;
     1291            socklen_t optlen = sizeof(int);
     1292            inq = outq = 0;
     1293            status = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &optlen);
     1294            if (status != 0)
     1295                Log(("NAT: can't get error status from %R[natsock]\n", so));
    12961296#ifndef RT_OS_SOLARIS
    1297                 status = ioctl(so->s, FIONREAD, &inq); /* tcp(7) recommends SIOCINQ which is Linux specific */
    1298                 if (status != 0 || status != EINVAL)
    1299                 {
    1300                     /* EINVAL returned if socket in listen state tcp(7)*/
    1301                     Log(("NAT: can't get depth of IN queue status from %R[natsock]\n", so));
    1302                 }
    1303                 status = ioctl(so->s, TIOCOUTQ, &outq); /* SIOCOUTQ see previous comment */
    1304                 if (status != 0)
    1305                     Log(("NAT: can't get depth of OUT queue from %R[natsock]\n", so));
     1297            status = ioctl(so->s, FIONREAD, &inq); /* tcp(7) recommends SIOCINQ which is Linux specific */
     1298            if (status != 0 || status != EINVAL)
     1299            {
     1300                /* EINVAL returned if socket in listen state tcp(7)*/
     1301                Log(("NAT: can't get depth of IN queue status from %R[natsock]\n", so));
     1302            }
     1303            status = ioctl(so->s, TIOCOUTQ, &outq); /* SIOCOUTQ see previous comment */
     1304            if (status != 0)
     1305                Log(("NAT: can't get depth of OUT queue from %R[natsock]\n", so));
    13061306#else
    13071307                /*
     
    13101310                 */
    13111311#endif
    1312                 if (   so->so_state & SS_ISFCONNECTING
    1313                     || UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
     1312            if (   so->so_state & SS_ISFCONNECTING
     1313                || UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
     1314            {
     1315                /**
     1316                 * Check if we need here take care about gracefull connection
     1317                 * @todo try with proxy server
     1318                 */
     1319                if (UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
    13141320                {
    1315                     /**
    1316                      * Check if we need here take care about gracefull connection
    1317                      * @todo try with proxy server
     1321                    /*
     1322                     * Never meet inq != 0 or outq != 0, anyway let it stay for a while
     1323                     * in case it happens we'll able to detect it.
     1324                     * Give TCP/IP stack wait or expire the socket.
    13181325                     */
    1319                     if (UNIX_CHECK_FD_SET(so, NetworkEvents, readfds))
    1320                     {
    1321                         /*
    1322                          * Never meet inq != 0 or outq != 0, anyway let it stay for a while
    1323                          * in case it happens we'll able to detect it.
    1324                          * Give TCP/IP stack wait or expire the socket.
    1325                          */
    1326                         Log(("NAT: %R[natsock] err(%d:%s) s(in:%d,out:%d)happens on read I/O, "
    1327                             "other side close connection \n", so, err, strerror(err), inq, outq));
    1328                         CONTINUE(tcp);
    1329                     }
    1330                     goto tcp_input_close;
     1326                    Log(("NAT: %R[natsock] err(%d:%s) s(in:%d,out:%d)happens on read I/O, "
     1327                        "other side close connection \n", so, err, strerror(err), inq, outq));
     1328                    CONTINUE(tcp);
    13311329                }
    1332                 if (   !UNIX_CHECK_FD_SET(so, NetworkEvents, readfds)
    1333                     && !UNIX_CHECK_FD_SET(so, NetworkEvents, writefds)
    1334                     && !UNIX_CHECK_FD_SET(so, NetworkEvents, xfds))
    1335                 {
    1336                     Log(("NAT: system expires the socket %R[natsock] err(%d:%s) s(in:%d,out:%d) happens on non-I/O. ",
    1337                             so, err, strerror(err), inq, outq));
    1338                     goto tcp_input_close;
    1339                 }
    1340                 Log(("NAT: %R[natsock] we've met(%d:%s) s(in:%d, out:%d) unhandled combination hup (%d) "
    1341                     "rederr(%d) on (r:%d, w:%d, x:%d)\n",
    1342                         so, err, strerror(err),
    1343                         inq, outq,
    1344                         UNIX_CHECK_FD_SET(so, ign, rdhup),
    1345                         UNIX_CHECK_FD_SET(so, ign, rderr),
    1346                         UNIX_CHECK_FD_SET(so, ign, readfds),
    1347                         UNIX_CHECK_FD_SET(so, ign, writefds),
    1348                         UNIX_CHECK_FD_SET(so, ign, xfds)));
    1349                 /*
    1350                  * Give OS's TCP/IP stack a chance to resolve an issue or expire the socket.
    1351                  */
    1352                 CONTINUE(tcp);
     1330                goto tcp_input_close;
     1331            }
     1332            if (   !UNIX_CHECK_FD_SET(so, NetworkEvents, readfds)
     1333                && !UNIX_CHECK_FD_SET(so, NetworkEvents, writefds)
     1334                && !UNIX_CHECK_FD_SET(so, NetworkEvents, xfds))
     1335            {
     1336                Log(("NAT: system expires the socket %R[natsock] err(%d:%s) s(in:%d,out:%d) happens on non-I/O. ",
     1337                        so, err, strerror(err), inq, outq));
     1338                goto tcp_input_close;
     1339            }
     1340            Log(("NAT: %R[natsock] we've met(%d:%s) s(in:%d, out:%d) unhandled combination hup (%d) "
     1341                "rederr(%d) on (r:%d, w:%d, x:%d)\n",
     1342                    so, err, strerror(err),
     1343                    inq, outq,
     1344                    UNIX_CHECK_FD_SET(so, ign, rdhup),
     1345                    UNIX_CHECK_FD_SET(so, ign, rderr),
     1346                    UNIX_CHECK_FD_SET(so, ign, readfds),
     1347                    UNIX_CHECK_FD_SET(so, ign, writefds),
     1348                    UNIX_CHECK_FD_SET(so, ign, xfds)));
     1349            /*
     1350             * Give OS's TCP/IP stack a chance to resolve an issue or expire the socket.
     1351             */
     1352            CONTINUE(tcp);
    13531353tcp_input_close:
    1354                 so->so_state = SS_NOFDREF; /*cause connection valid tcp connection termination and socket closing */
    1355                 TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
    1356                 CONTINUE(tcp);
    1357             }
    1358 #endif
    1359             LOOP_LABEL(tcp, so, so_next);
    1360         }
    1361 
    1362         /*
    1363          * Now UDP sockets.
    1364          * Incoming packets are sent straight away, they're not buffered.
    1365          * Incoming UDP data isn't buffered either.
    1366          */
    1367          QSOCKET_FOREACH(so, so_next, udp)
    1368          /* { */
     1354            so->so_state = SS_NOFDREF; /*cause connection valid tcp connection termination and socket closing */
     1355            TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
     1356            CONTINUE(tcp);
     1357        }
     1358#endif
     1359        LOOP_LABEL(tcp, so, so_next);
     1360    }
     1361
     1362    /*
     1363     * Now UDP sockets.
     1364     * Incoming packets are sent straight away, they're not buffered.
     1365     * Incoming UDP data isn't buffered either.
     1366     */
     1367     QSOCKET_FOREACH(so, so_next, udp)
     1368     /* { */
    13691369#ifdef VBOX_WITH_SLIRP_MT
    1370             if (   so->so_state & SS_NOFDREF
    1371                 && so->so_deleted == 1)
    1372             {
    1373                 struct socket *son, *sop = NULL;
    1374                 QSOCKET_LOCK(udb);
    1375                 if (so->so_next != NULL)
    1376                 {
    1377                     if (so->so_next != &udb)
    1378                         SOCKET_LOCK(so->so_next);
    1379                     son = so->so_next;
    1380                 }
    1381                 if (   so->so_prev != &udb
    1382                     && so->so_prev != NULL)
    1383                 {
    1384                     SOCKET_LOCK(so->so_prev);
    1385                     sop = so->so_prev;
    1386                 }
    1387                 QSOCKET_UNLOCK(udb);
    1388                 remque(pData, so);
    1389                 NSOCK_DEC();
    1390                 SOCKET_UNLOCK(so);
    1391                 SOCKET_LOCK_DESTROY(so);
    1392                 RTMemFree(so);
    1393                 so_next = son;
    1394                 if (sop != NULL)
    1395                     SOCKET_UNLOCK(sop);
    1396                 CONTINUE_NO_UNLOCK(udp);
    1397             }
    1398 #endif
    1399             POLL_UDP_EVENTS(rc, error, so, &NetworkEvents);
    1400 
    1401             LOG_NAT_SOCK(so, UDP, &NetworkEvents, readfds, writefds, xfds);
    1402 
    1403             if (so->s != -1 && CHECK_FD_SET(so, NetworkEvents, readfds))
    1404             {
    1405                 SORECVFROM(pData, so);
    1406             }
    1407             LOOP_LABEL(udp, so, so_next);
    1408         }
    1409 
    1410     }
    1411 
     1370        if (   so->so_state & SS_NOFDREF
     1371            && so->so_deleted == 1)
     1372        {
     1373            struct socket *son, *sop = NULL;
     1374            QSOCKET_LOCK(udb);
     1375            if (so->so_next != NULL)
     1376            {
     1377                if (so->so_next != &udb)
     1378                    SOCKET_LOCK(so->so_next);
     1379                son = so->so_next;
     1380            }
     1381            if (   so->so_prev != &udb
     1382                && so->so_prev != NULL)
     1383            {
     1384                SOCKET_LOCK(so->so_prev);
     1385                sop = so->so_prev;
     1386            }
     1387            QSOCKET_UNLOCK(udb);
     1388            remque(pData, so);
     1389            NSOCK_DEC();
     1390            SOCKET_UNLOCK(so);
     1391            SOCKET_LOCK_DESTROY(so);
     1392            RTMemFree(so);
     1393            so_next = son;
     1394            if (sop != NULL)
     1395                SOCKET_UNLOCK(sop);
     1396            CONTINUE_NO_UNLOCK(udp);
     1397        }
     1398#endif
     1399        POLL_UDP_EVENTS(rc, error, so, &NetworkEvents);
     1400   
     1401        LOG_NAT_SOCK(so, UDP, &NetworkEvents, readfds, writefds, xfds);
     1402   
     1403        if (so->s != -1 && CHECK_FD_SET(so, NetworkEvents, readfds))
     1404        {
     1405            SORECVFROM(pData, so);
     1406        }
     1407        LOOP_LABEL(udp, so, so_next);
     1408    }
     1409
     1410done:
    14121411#ifndef VBOX_WITH_SLIRP_MT
    14131412    /*
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