VirtualBox

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


Ignore:
Timestamp:
Nov 15, 2011 6:59:33 AM (13 years ago)
Author:
vboxsync
Message:

NAT: clonning socket without creating real socket(2).

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

Legend:

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

    r39287 r39299  
    913913#endif
    914914        STAM_COUNTER_INC(&pData->StatTCP);
    915 
     915#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     916        /* TCP socket can't be cloned */
     917        Assert((!so->so_cloneOf));
     918#endif
    916919        /*
    917920         * See if we need a tcp_fasttimo
     
    995998#if !defined(RT_OS_WINDOWS)
    996999        so->so_poll_index = -1;
     1000#endif
     1001#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     1002        if (so->so_cloneOf)
     1003                CONTINUE_NO_UNLOCK(udp);
    9971004#endif
    9981005
     
    12011208        }
    12021209#endif
     1210        /* TCP socket can't be cloned */
     1211#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     1212        Assert((!so->so_cloneOf));
     1213#endif
    12031214        /*
    12041215         * FD_ISSET is meaningless on these sockets
     
    14031414        }
    14041415#endif
     1416#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     1417        if (so->so_cloneOf)
     1418            CONTINUE_NO_UNLOCK(udp);
     1419#endif
    14051420        POLL_UDP_EVENTS(rc, error, so, &NetworkEvents);
    14061421
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r39287 r39299  
    4242 *
    4343 */
    44 struct socket * soCloneUDPSocketWithForegnAddr(PNATState pData, const struct socket *pSo, uint32_t u32ForeignAddr)
     44struct socket * soCloneUDPSocketWithForegnAddr(PNATState pData, bool fBindSocket, struct socket *pSo, uint32_t u32ForeignAddr)
    4545{
    4646    struct socket *pNewSocket = NULL;
    47     LogFlowFunc(("Enter: so:%R[natsock], u32ForeignAddr:%RTnaipv4\n", pSo, u32ForeignAddr));
     47    LogFlowFunc(("Enter: fBindSocket:%RTbool, so:%R[natsock], u32ForeignAddr:%RTnaipv4\n", fBindSocket, pSo, u32ForeignAddr));
    4848    pNewSocket = socreate();
    4949    if (!pNewSocket)
     
    5353        return NULL;
    5454    }
    55     if (udp_attach(pData, pNewSocket, 0) <= 0)
    56     {
    57         sofree(pData, pNewSocket);
    58         LogFunc(("Can't attach fresh created socket\n"));
    59         return NULL;
     55    if (fBindSocket)
     56    {
     57        if (udp_attach(pData, pNewSocket, 0) <= 0)
     58        {
     59            sofree(pData, pNewSocket);
     60            LogFunc(("Can't attach fresh created socket\n"));
     61            return NULL;
     62        }
     63    }
     64    else
     65    {
     66        pNewSocket->so_cloneOf = (struct socket *)pSo;
     67        pNewSocket->s = pSo->s;
     68        insque(pData, pNewSocket, &udb);
    6069    }
    6170    pNewSocket->so_laddr = pSo->so_laddr;
     
    6372    pNewSocket->so_faddr.s_addr = u32ForeignAddr;
    6473    pNewSocket->so_fport = pSo->so_fport;
     74    pSo->so_cCloneCounter++;
     75    LogFlowFunc(("Leave: %R[natsock]\n", pNewSocket));
    6576    return pNewSocket;
     77}
     78
     79struct socket *soLookUpClonedUDPSocket(PNATState pData, const struct socket *pcSo, uint32_t u32ForeignAddress)
     80{
     81    struct socket *pSoClone = NULL;
     82    LogFlowFunc(("Enter: pcSo:%R[natsock], u32ForeignAddress:%RTnaipv4\n", pcSo, u32ForeignAddress));
     83    for (pSoClone = udb.so_next; pSoClone != &udb; pSoClone = pSoClone->so_next)
     84    {
     85        if (   pSoClone->so_cloneOf
     86            && pSoClone->so_cloneOf == pcSo
     87            && pSoClone->so_lport == pcSo->so_lport
     88            && pSoClone->so_fport == pcSo->so_fport
     89            && pSoClone->so_laddr.s_addr == pcSo->so_laddr.s_addr
     90            && pSoClone->so_faddr.s_addr == u32ForeignAddress)
     91            goto done;
     92    }
     93    pSoClone = NULL;
     94done:
     95    LogFlowFunc(("Leave: pSoClone: %R[natsock]\n", pSoClone));
     96    return pSoClone;
    6697}
    6798#endif
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r39287 r39299  
    106106    /* required for port-forwarding */
    107107    struct libalias *so_la;
     108#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     109    struct socket *so_cloneOf; /* pointer to master instance */
     110    int so_cCloneCounter;      /* number of clones */
     111#endif
    108112};
    109113
     
    194198/**
    195199 * Creates copy of UDP socket with specified addr
     200 * fBindSocket - in case we want bind a real socket.
    196201 * @return copy of the socket with f_addr equal to u32ForeignAddr
    197202 */
    198203#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
    199 struct socket * soCloneUDPSocketWithForegnAddr(PNATState pData, const struct socket *so, uint32_t u32ForeignAddr);
     204struct socket * soCloneUDPSocketWithForegnAddr(PNATState pData, bool fBindSocket, struct socket *pSo, uint32_t u32ForeignAddr);
     205struct socket *soLookUpClonedUDPSocket(PNATState pData, const struct socket *pcSo, uint32_t u32ForeignAddress);
    200206#endif
    201207
  • trunk/src/VBox/Devices/Network/slirp/udp.c

    r39287 r39299  
    395395{
    396396    struct sockaddr_in saddr, daddr;
     397#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     398    struct socket *pSocketClone = NULL;
     399#endif
    397400    LogFlowFunc(("ENTER: so = %R[natsock], m = %p, saddr = %RTnaipv4\n",
    398401                 so, (long)m, addr->sin_addr.s_addr));
     
    419422            /* we shouldn't override initial socket */
    420423#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
    421             so = soCloneUDPSocketWithForegnAddr(pData, so, addr->sin_addr.s_addr);
    422             Assert((so));
     424            if (so->so_cCloneCounter)
     425                pSocketClone = soLookUpClonedUDPSocket(pData, so, addr->sin_addr.s_addr);
     426            if (!pSocketClone)
     427                pSocketClone = soCloneUDPSocketWithForegnAddr(pData, false, so, addr->sin_addr.s_addr);
     428            Assert((pSocketClone));
     429            so = pSocketClone;
    423430#else
    424431            so->so_faddr.s_addr = addr->sin_addr.s_addr;
     
    484491    so->so_hlport = ((struct sockaddr_in *)&sa_addr)->sin_port;
    485492    so->so_hladdr.s_addr = ((struct sockaddr_in *)&sa_addr)->sin_addr.s_addr;
    486 #if 0
    487     so->so_state = SS_ISFCONNECTED; /* validly opened UDP socked always connected */
    488 #endif
     493
    489494    SOCKET_LOCK_CREATE(so);
    490495    QSOCKET_LOCK(udb);
     
    506511        SOCKET_LOCK(so);
    507512        QSOCKET_UNLOCK(udb);
     513#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
     514        if (so->so_cloneOf)
     515            so->so_cloneOf->so_cCloneCounter--;
     516        else if (so->so_cCloneCounter > 0)
     517        {
     518            /* we can't close socket yet */
     519            SOCKET_UNLOCK(so);
     520            return;
     521        }
     522#endif
    508523        closesocket(so->s);
    509524        sofree(pData, so);
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