VirtualBox

Changeset 34038 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Nov 12, 2010 6:49:22 PM (14 years ago)
Author:
vboxsync
Message:

NAT:UDP: fetch as much as possible at once and compose mbuf chain if required.

File:
1 edited

Legend:

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

    r33978 r34038  
    724724        int rc = 0;
    725725        static int signalled = 0;
     726        uint8_t *pu8Buffer = NULL;
     727        bool fWithTemporalBuffer = false;
    726728
    727729        QSOCKET_LOCK(udb);
     
    752754
    753755        len = sizeof(struct udpiphdr);
    754         if (n > (if_mtu - len))
    755         {
    756             n = if_mtu - len; /* can't read than we can put in the mbuf*/
    757         }
    758         len += n;
    759 
    760         size = MCLBYTES;
    761         if (len + if_maxlinkhdr < MSIZE)
    762             size = MCLBYTES;
    763         else if (len + if_maxlinkhdr < MCLBYTES)
    764             size = MCLBYTES;
    765         else if (len + if_maxlinkhdr < MJUM9BYTES)
    766             size = MJUM9BYTES;
    767         else if (len + if_maxlinkhdr < MJUM16BYTES)
    768             size = MJUM16BYTES;
    769         else
    770             AssertMsgFailed(("Unsupported size"));
    771 
    772         m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size);
     756        m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, slirp_size(pData));
    773757        if (m == NULL)
    774758            return;
    775759
     760        len += n;
    776761        m->m_data += ETH_HLEN;
    777762        m->m_pkthdr.header = mtod(m, void *);
    778763        m->m_data += sizeof(struct udpiphdr);
    779         ret = recvfrom(so->s, mtod(m, char *), n, 0,
     764
     765        pu8Buffer = mtod(m, uint8_t *);
     766        fWithTemporalBuffer = false;
     767        /*
     768         * Even if amounts of bytes on socket is greater than MTU value
     769         * Slirp will able fragment it, but we won't create temporal location
     770         * here.
     771         */
     772        if (n > (slirp_size(pData) - sizeof(struct udpiphdr)))
     773        {
     774            pu8Buffer = RTMemAlloc((n) * sizeof(uint8_t));
     775            if (!pu8Buffer)
     776            {
     777                m_freem(pData, m);
     778                return;
     779            }
     780            fWithTemporalBuffer = true;
     781        }
     782        ret = recvfrom(so->s, pu8Buffer, n, 0,
    780783                       (struct sockaddr *)&addr, &addrlen);
    781         /* @todo (vvl) check which flags and type should be passed */
    782         m->m_len = ret;
     784        if (fWithTemporalBuffer)
     785        {
     786            if (ret > 0)
     787            {
     788                m_copyback(pData, m, 0, ret, pu8Buffer);
     789                /*
     790                 * If we've met comporison below our size prediction was failed
     791                 * it's not fatal just we've allocated for nothing. (@todo add counter here
     792                 * to calculate how rare we here)
     793                 */
     794                if(ret < slirp_size(pData) && !m->m_next)
     795                    Log(("NAT:udp: Expected size(%d) lesser than real(%d) and less minimal mbuf size(%d) \n",
     796                         n, ret, slirp_size(pData)));
     797            }
     798            /* we're freeing buffer anyway */
     799            RTMemFree(pu8Buffer);
     800        }
     801        else
     802            m->m_len = ret;
     803
    783804        if (ret < 0)
    784805        {
     
    806827        else
    807828        {
     829            Assert((m_length(m,NULL) == ret));
    808830            /*
    809831             * Hack: domain name lookup will be used the most for UDP,
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