VirtualBox

Changeset 60142 in vbox


Ignore:
Timestamp:
Mar 22, 2016 9:44:59 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
106161
Message:

NAT: Make host resolver asynchronous so that a blocked synchronous
lookup doesn't stop the whole tcp/ip stack.

Location:
trunk/src/VBox/Devices/Network
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r59312 r60142  
    211211    RTCRITSECT              XmitLock;
    212212
     213    /** Request queue for the async host resolver. */
     214    RTREQQUEUE               hHostResQueue;
     215    /** Async host resolver thread. */
     216    PPDMTHREAD               pHostResThread;
     217
    213218#ifdef RT_OS_DARWIN
    214219    /* Handle of the DNS watcher runloop source. */
     
    892897}
    893898
     899
     900static DECLCALLBACK(int) drvNATHostResThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     901{
     902    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     903
     904    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     905        return VINF_SUCCESS;
     906
     907    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     908    {
     909        RTReqQueueProcess(pThis->hHostResQueue, RT_INDEFINITE_WAIT);
     910    }
     911
     912    return VINF_SUCCESS;
     913}
     914
     915
     916static DECLCALLBACK(int) drvNATReqQueueInterrupt()
     917{
     918    /*
     919     * RTReqQueueProcess loops until request returns a warning or info
     920     * status code (other than VINF_SUCCESS).
     921     */
     922    return VINF_INTERRUPTED;
     923}
     924
     925
     926static DECLCALLBACK(int) drvNATHostResWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     927{
     928    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     929    Assert(pThis != NULL);
     930
     931    int rc;
     932    rc = RTReqQueueCallEx(pThis->hHostResQueue, NULL /*ppReq*/, 0 /*cMillies*/,
     933                          RTREQFLAGS_IPRT_STATUS | RTREQFLAGS_NO_WAIT,
     934                          (PFNRT)drvNATReqQueueInterrupt, 0);
     935    return rc;
     936}
     937
     938
    894939/**
    895940 * Function called by slirp to check if it's possible to feed incoming data to the network port.
     
    9631008    STAM_COUNTER_INC(&pThis->StatQueuePktSent);
    9641009    LogFlowFuncLeave();
     1010}
     1011
     1012
     1013/*
     1014 * Call a function on the slirp thread.
     1015 */
     1016int slirp_call(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies,
     1017               unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...)
     1018{
     1019    PDRVNAT pThis = (PDRVNAT)pvUser;
     1020    Assert(pThis);
     1021
     1022    int rc;
     1023
     1024    va_list va;
     1025    va_start(va, cArgs);
     1026
     1027    rc = RTReqQueueCallV(pThis->hSlirpReqQueue, ppReq, cMillies, fFlags, pfnFunction, cArgs, va);
     1028
     1029    va_end(va);
     1030
     1031    if (RT_SUCCESS(rc))
     1032        drvNATNotifyNATThread(pThis, "slirp_vcall");
     1033
     1034    return rc;
     1035}
     1036
     1037
     1038/*
     1039 * Call a function on the host resolver thread.
     1040 */
     1041int slirp_call_hostres(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies,
     1042                       unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...)
     1043{
     1044    PDRVNAT pThis = (PDRVNAT)pvUser;
     1045    Assert(pThis);
     1046
     1047    int rc;
     1048
     1049    AssertReturn((pThis->hHostResQueue != NIL_RTREQQUEUE), VERR_INVALID_STATE);
     1050    AssertReturn((pThis->pHostResThread != NULL), VERR_INVALID_STATE);
     1051
     1052    va_list va;
     1053    va_start(va, cArgs);
     1054
     1055    rc = RTReqQueueCallV(pThis->hHostResQueue, ppReq, cMillies, fFlags,
     1056                         pfnFunction, cArgs, va);
     1057
     1058    va_end(va);
     1059    return rc;
    9651060}
    9661061
     
    13451440    }
    13461441
     1442    RTReqQueueDestroy(pThis->hHostResQueue);
     1443    pThis->hHostResQueue = NIL_RTREQQUEUE;
     1444
    13471445    RTReqQueueDestroy(pThis->hSlirpReqQueue);
    13481446    pThis->hSlirpReqQueue = NIL_RTREQQUEUE;
     
    13961494    pThis->hSlirpReqQueue               = NIL_RTREQQUEUE;
    13971495    pThis->hUrgRecvReqQueue             = NIL_RTREQQUEUE;
     1496    pThis->hHostResQueue                = NIL_RTREQQUEUE;
    13981497    pThis->EventRecv                    = NIL_RTSEMEVENT;
    13991498    pThis->EventUrgRecv                 = NIL_RTSEMEVENT;
     
    15901689
    15911690            rc = RTSemEventCreate(&pThis->EventUrgRecv);
     1691            AssertRCReturn(rc, rc);
     1692
     1693            rc = RTReqQueueCreate(&pThis->hHostResQueue);
     1694            AssertRCReturn(rc, rc);
     1695
     1696            rc = PDMDrvHlpThreadCreate(pThis->pDrvIns, &pThis->pHostResThread,
     1697                                       pThis, drvNATHostResThread, drvNATHostResWakeup,
     1698                                       64 * _1K, RTTHREADTYPE_IO, "HOSTRES");
    15921699            AssertRCReturn(rc, rc);
    15931700
  • trunk/src/VBox/Devices/Network/slirp/hostres.c

    r59585 r60142  
    105105struct response
    106106{
     107    PNATState pData;
     108
     109    uint32_t src;
     110    uint16_t sport;
     111
    107112    struct label *labels;       /* already encoded in buf */
    108113    size_t qlen;                /* original question */
     
    115120
    116121static int verify_header(PNATState pData, struct mbuf **pMBuf);
    117 static struct mbuf *respond(PNATState pData, struct mbuf *m, struct response *res);
    118 struct mbuf *resolve(PNATState pData, struct mbuf *m, struct response *res,
    119                      uint16_t qtype, size_t qname);
    120 struct mbuf *resolve_reverse(PNATState pData, struct mbuf *m, struct response *res,
    121                              uint16_t qtype, size_t qname, struct in_addr addr);
    122 struct mbuf *refuse(PNATState pData, struct mbuf *m, unsigned int rcode);
     122static struct mbuf *refuse_mbuf(struct mbuf *m, unsigned int rcode);
     123
     124static int respond(struct response *res);
     125static int resolve(struct response *res, uint16_t qtype, size_t qname);
     126static int resolve_reverse(struct response *res, uint16_t qtype, size_t qname,
     127                            struct in_addr addr);
     128
     129static int refuse(struct response *res, unsigned int rcode);
     130
     131
    123132static ssize_t append_a(struct response *res, const char *name, struct in_addr addr);
    124133static ssize_t append_cname(struct response *res, const char *name, const char *cname);
     
    155164
    156165
     166static void hostres_async(struct response *res);
     167static void hostres_slirp_reply(struct response *res);
     168
     169
     170/*
     171 * Host resolver is called on slirp thread from udp.c
     172 */
    157173struct mbuf *
    158 hostresolver(PNATState pData, struct mbuf *m)
    159 {
    160     int error;
    161 
    162     struct response res;
    163 
    164     error = verify_header(pData, &m);
    165     if (error != 0)
     174hostresolver(PNATState pData, struct mbuf *m, uint32_t src, uint16_t sport)
     175{
     176    struct response *res;
     177    size_t mlen;
     178    int rc;
     179
     180    rc = verify_header(pData, &m);
     181    if (RT_FAILURE(rc))
    166182        return m;
    167183
    168     RT_ZERO(res);
    169 
    170     /*
    171      * Do the real work
    172      */
    173     m = respond(pData, m, &res);
    174 
    175     free_labels(res.labels);
    176     return m;
    177 }
    178 
    179 
    180 struct mbuf *
    181 refuse(PNATState pData, struct mbuf *m, unsigned int rcode)
    182 {
    183     struct dnsmsg_header *pHdr;
    184 
    185     pHdr = mtod(m, struct dnsmsg_header *);
    186     pHdr->qr = QR_Response;
    187     pHdr->rcode = rcode;
    188     pHdr->ra = 1;
    189     pHdr->aa = 0;
    190 
    191     return m;
    192 }
    193 
    194 
     184    res = RTMemAllocZ(sizeof(*res));
     185    if (res == NULL)
     186        return refuse_mbuf(m, RCode_ServFail);
     187
     188    res->pData = pData;
     189    res->src = src;
     190    res->sport = sport;
     191
     192    mlen = m_length(m, NULL);
     193    m_copydata(m, 0, mlen, (char *)res->buf);
     194    res->end = res->qlen = mlen;
     195
     196    rc = slirp_call_hostres(pData->pvUser, NULL, 0,
     197                            RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
     198                            (PFNRT)hostres_async, 1, res);
     199
     200    if (RT_FAILURE(rc))
     201    {
     202        LogErr(("NAT: hostres: failed to post async request: %Rrc\n", rc));
     203        RTMemFree(res);
     204        return refuse_mbuf(m, RCode_ServFail);
     205    }
     206
     207    m_freem(pData, m);
     208    return NULL;
     209}
     210
     211
     212/*
     213 * Do quick sanity-checks on the request before doing async
     214 * resolution.  If we don't like it, immediately drop or convert to
     215 * response in place and bounce back the mbuf.
     216 */
    195217static int
    196218verify_header(PNATState pData, struct mbuf **pMBuf)
     
    201223
    202224    m = *pMBuf;
     225    mlen = m_length(m, NULL);
    203226
    204227    /*
     
    215238    pHdr = mtod(m, struct dnsmsg_header *);
    216239
     240    if (RT_UNLIKELY(mlen < sizeof(*pHdr)))
     241    {
     242        LogErr(("NAT: hostres: packet too small: %zu bytes\n", mlen));
     243        goto drop;              /* can't even refuse it */
     244    }
     245
     246    if (RT_UNLIKELY(mlen > DNS_MAX_UDP_LEN))
     247    {
     248        LogErr(("NAT: hostres: packet too large: %zu bytes\n", mlen));
     249        goto drop;              /* don't echo back huge packets */
     250    }
     251
    217252    if (RT_UNLIKELY(pHdr->qr != QR_Query))
    218253    {
    219254        LogErr(("NAT: hostres: unexpected response\n"));
    220         goto drop;
    221     }
    222 
    223     mlen = m_length(m, NULL);
    224     if (RT_UNLIKELY(mlen > DNS_MAX_UDP_LEN))
    225     {
    226         LogErr(("NAT: hostres: packet too large\n"));
    227         refuse(pData, m, RCode_FormErr); /* or drop? */
    228         return 1;
     255        goto drop;              /* ignore */
    229256    }
    230257
    231258    if (RT_UNLIKELY(pHdr->opcode != OpCode_Query))
    232259    {
    233         LogErr(("NAT: hostres: unsupported opcode\n"));
    234         refuse(pData, m, RCode_NotImp);
    235         return 1;
     260        LogErr(("NAT: hostres: unsupported opcode %d\n", pHdr->opcode));
     261        refuse_mbuf(m, RCode_NotImp);
     262        return VERR_PARSE_ERROR;
    236263    }
    237264
     
    239266    {
    240267        LogErr(("NAT: hostres: multiple questions\n"));
    241         refuse(pData, m, RCode_NotImp);
    242         return 1;
     268        refuse_mbuf(m, RCode_NotImp);
     269        return VERR_PARSE_ERROR;
    243270    }
    244271
     
    246273    {
    247274        LogErr(("NAT: hostres: answers in query\n"));
    248         refuse(pData, m, RCode_NotImp);
    249         return 1;
    250     }
    251 
     275        refuse_mbuf(m, RCode_NotImp);
     276        return VERR_PARSE_ERROR;
     277    }
     278
     279    /* XXX: let it fail when we parse it? */
    252280    if (RT_UNLIKELY(mlen < sizeof(*pHdr)
    253281                             + /* qname  */ 1
     
    255283                             + /* qclass */ 2))
    256284    {
    257         LogErr(("NAT: hostres: packet too small\n"));
    258         refuse(pData, m, RCode_FormErr);
    259         return 1;
    260     }
    261 
    262     return 0;
     285        LogErr(("NAT: hostres: packet too small: %zu bytes\n", mlen));
     286        refuse_mbuf(m, RCode_FormErr);
     287        return VERR_PARSE_ERROR;
     288    }
     289
     290    return VINF_SUCCESS;
    263291
    264292  drop:
     
    266294        m_freem(pData, m);
    267295    *pMBuf = NULL;
    268     return 1;
    269 }
    270 
    271 
     296    return VERR_PARSE_ERROR;
     297}
     298
     299
     300/*
     301 * Turn the request in mbuf into an error response.  This is used on
     302 * slirp thread for pre-checks before we do async resolution.
     303 */
    272304static struct mbuf *
    273 respond(PNATState pData, struct mbuf *m, struct response *res)
     305refuse_mbuf(struct mbuf *m, unsigned int rcode)
     306{
     307    struct dnsmsg_header *pHdr;
     308
     309    pHdr = mtod(m, struct dnsmsg_header *);
     310    pHdr->qr = QR_Response;
     311    pHdr->rcode = rcode;
     312    pHdr->ra = 1;
     313    pHdr->aa = 0;
     314
     315    return m;
     316}
     317
     318
     319/*
     320 * Actuall resolution runs on the dedicated host resolver thread.
     321 */
     322static void
     323hostres_async(struct response *res)
     324{
     325    int rc;
     326
     327    /* build reply in res->buf[] */
     328    respond(res);
     329
     330    free_labels(res->labels);
     331
     332    rc = slirp_call(res->pData->pvUser, NULL, 0,
     333                    RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
     334                    (PFNRT)hostres_slirp_reply, 1, res);
     335
     336    if (RT_FAILURE(rc))
     337    {
     338        LogErr(("NAT: hostres: failed to post async reply: %Rrc\n", rc));
     339        RTMemFree(res);
     340    }
     341}
     342
     343
     344/*
     345 * We are  back to the slirp thread to send the reply.
     346 */
     347static void
     348hostres_slirp_reply(struct response *res)
     349{
     350    PNATState pData = res->pData;
     351    struct sockaddr_in src, dst;
     352    struct mbuf *m = NULL;
     353    size_t mlen;
     354    int ok;
     355
     356    mlen = if_maxlinkhdr + sizeof(struct ip) + sizeof(struct udphdr);
     357    mlen += res->end;
     358
     359    if (mlen <= MHLEN)
     360    {
     361        m = m_gethdr(pData, M_NOWAIT, MT_HEADER);
     362    }
     363    else
     364    {
     365        void *pvBuf;            /* ignored */
     366        size_t cbBuf;
     367
     368        m = slirp_ext_m_get(pData, mlen, &pvBuf, &cbBuf);
     369    }
     370
     371    if (m == NULL)
     372        goto out;
     373
     374    /* reserve leading space for ethernet header */
     375    m->m_data += if_maxlinkhdr;
     376
     377    /* reserve leading space for protocol headers */
     378    m->m_pkthdr.header = mtod(m, void *);
     379    m->m_data += sizeof(struct ip) + sizeof(struct udphdr);
     380
     381    m->m_len = 0;
     382    ok = m_append(pData, m, res->end, (c_caddr_t)res->buf);
     383    if (!ok)
     384    {
     385        m_freem(pData, m);
     386        goto out;
     387    }
     388
     389    src.sin_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_DNS);
     390    src.sin_port = RT_H2N_U16_C(53);
     391    dst.sin_addr.s_addr = res->src;
     392    dst.sin_port = res->sport;
     393
     394    udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY);
     395
     396  out:
     397    RTMemFree(res);
     398}
     399
     400
     401static int
     402respond(struct response *res)
    274403{
    275404    struct dnsmsg_header *pHdr;
     
    281410    struct label *l;
    282411
    283     /**
    284      * Copy the request into the contiguous buffer for the response
    285      * and parse the question.
    286      */
    287 
    288     mlen = m_length(m, NULL);
    289     m_copydata(m, 0, mlen, (char *)res->buf);
    290     res->end = res->qlen = mlen;
    291 
    292412    /* convert header to response */
    293413    pHdr = (struct dnsmsg_header *)res->buf;
     
    305425     * compression in the answer.
    306426     */
    307     while (off < mlen) {
     427    while (off < res->qlen) {
    308428        size_t loff, llen;
    309429        uint8_t c;
     
    319439        {
    320440            LogErr(("NAT: hostres: label pointer in the qname\n"));
    321             return refuse(pData, m, RCode_FormErr);
     441            return refuse(res, RCode_FormErr);
    322442        }
    323443
     
    325445        {
    326446            LogErr(("NAT: hostres: unexpected high bits\n"));
    327             return refuse(pData, m, RCode_FormErr);
     447            return refuse(res, RCode_FormErr);
    328448        }
    329449
     
    335455        ++off;
    336456
    337         if (loff + 1 + llen > mlen)
     457        if (loff + 1 + llen > res->qlen)
    338458        {
    339459            LogErr(("NAT: hostres: length byte points beyound packet boundary\n"));
    340             return refuse(pData, m, RCode_FormErr);
     460            return refuse(res, RCode_FormErr);
    341461        }
    342462
     
    355475            {
    356476                LogErr(("NAT: hostres: dot inside label\n"));
    357                 return refuse(pData, m, RCode_FormErr);
     477                return refuse(res, RCode_FormErr);
    358478            }
    359479
     
    361481            {
    362482                LogErr(("NAT: hostres: nul byte inside label\n"));
    363                 return refuse(pData, m, RCode_FormErr);
     483                return refuse(res, RCode_FormErr);
    364484            }
    365485        }
     
    375495     * QTYPE and QCLASS
    376496     */
    377     if (RT_UNLIKELY(off + 4 > mlen))
     497    if (RT_UNLIKELY(off + 4 > res->qlen))
    378498    {
    379499        LogErr(("NAT: hostres: question too short\n"));
    380         return refuse(pData, m, RCode_FormErr);
     500        return refuse(res, RCode_FormErr);
    381501    }
    382502
     
    393513    {
    394514        LogErr(("NAT: hostres: unsupported qclass %d\n", qclass));
    395         return refuse(pData, m, RCode_NotImp);
     515        return refuse(res, RCode_NotImp);
    396516    }
    397517
     
    402522    {
    403523        LogErr(("NAT: hostres: unsupported qtype %d\n", qtype));
    404         return refuse(pData, m, RCode_NotImp);
     524        return refuse(res, RCode_NotImp);
    405525    }
    406526
     
    415535     * pointers, so truncating the buffer is safe.
    416536     */
    417     if (off < mlen)
    418     {
    419         int trailer = mlen - off;
    420 
    421         LogDbg(("NAT: hostres: question %zu < mlen %zu\n", off, mlen));
     537    if (off < res->qlen)
     538    {
     539        int trailer = res->qlen - off;
     540
     541        LogDbg(("NAT: hostres: question %zu < mlen %zu\n", off, res->qlen));
    422542
    423543        if (pHdr->nscount == 0 && pHdr->arcount == 0)
    424544        {
    425545            LogErr(("NAT: hostres: unexpected %d bytes after the question\n", trailer));
    426             return refuse(pData, m, RCode_FormErr);
     546            return refuse(res, RCode_FormErr);
    427547        }
    428548
     
    433553                pHdr->arcount != 0 ? "additional" : ""));
    434554
    435         m_adj(m, -trailer);
    436         mlen -= trailer;
    437         res->end = res->qlen = mlen;
     555        res->qlen -= trailer;
     556        res->end = res->qlen;
    438557
    439558        pHdr->nscount = 0;
     
    448567     */
    449568    if (get_in_addr_arpa(&in_addr_arpa, res->labels))
    450         return resolve_reverse(pData, m, res, qtype, qname, in_addr_arpa);
     569        return resolve_reverse(res, qtype, qname, in_addr_arpa);
    451570    else
    452         return resolve(pData, m, res, qtype, qname);
    453 }
    454 
    455 
    456 struct mbuf *
    457 resolve(PNATState pData, struct mbuf *m, struct response *res,
    458         uint16_t qtype, size_t qname)
     571        return resolve(res, qtype, qname);
     572}
     573
     574
     575static int
     576resolve(struct response *res, uint16_t qtype, size_t qname)
    459577{
    460578    struct dnsmsg_header *pHdr;
     
    485603#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
    486604    {
    487         PDNSMAPPINGENTRY pDNSMapingEntry = getDNSMapByName(pData, name);
     605        PDNSMAPPINGENTRY pDNSMapingEntry = getDNSMapByName(res->pData, name);
    488606        if (pDNSMapingEntry != NULL)
    489607        {
     
    520638    {
    521639        /* LogErr: h_errno */
    522         return refuse(pData, m, RCode_NXDomain);
     640        return refuse(res, RCode_NXDomain);
    523641    }
    524642
     
    537655
    538656#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
    539     alterHostentWithDataFromDNSMap(pData, h);
     657    alterHostentWithDataFromDNSMap(res->pData, h);
    540658#endif
    541659
     
    557675                    name, h->h_name));
    558676            if (nbytes < 0)
    559                 return refuse(pData, m, RCode_ServFail);
     677                return refuse(res, RCode_ServFail);
    560678            else
    561679            {
     
    598716                    cname, addr.s_addr));
    599717            if (nbytes < 0)
    600                 return refuse(pData, m, RCode_ServFail);
     718                return refuse(res, RCode_ServFail);
    601719            else
    602720            {
     
    634752
    635753  out:
    636     if (nanswers > 0)
    637     {
    638         int ok = m_append(pData, m, res->end - oend, (caddr_t)&res->buf[oend]);
    639         if (!ok)
    640         {
    641             /* XXX: this may fail part way: restore old lenght, clear TC? */
    642             return refuse(pData, m, RCode_ServFail);
    643         }
    644         pHdr->ancount = RT_H2N_U16(nanswers);
    645     }
    646     memcpy(mtod(m, char *), res->buf, sizeof(struct dnsmsg_header));
    647     return m;
    648 }
    649 
    650 
    651 struct mbuf *
    652 resolve_reverse(PNATState pData, struct mbuf *m, struct response *res,
    653                 uint16_t qtype, size_t qname, struct in_addr in_addr_arpa)
     754    pHdr->ancount = RT_H2N_U16(nanswers);
     755    return VINF_SUCCESS;
     756}
     757
     758
     759static int
     760resolve_reverse(struct response *res, uint16_t qtype, size_t qname,
     761                struct in_addr in_addr_arpa)
    654762{
    655763    struct dnsmsg_header *pHdr;
     
    684792     */
    685793    {
    686         PDNSMAPPINGENTRY pReverseMapping = getDNSMapByAddr(pData, &in_addr_arpa.s_addr);
     794        PDNSMAPPINGENTRY pReverseMapping = getDNSMapByAddr(res->pData, &in_addr_arpa.s_addr);
    687795        if (pReverseMapping != NULL)
    688796        {
     
    712820    {
    713821        /* LogErr: h_errno */
    714         return refuse(pData, m, RCode_NXDomain);
     822        return refuse(res, RCode_NXDomain);
    715823    }
    716824
     
    731839                    name, h->h_name));
    732840            if (nbytes < 0)
    733                 return refuse(pData, m, RCode_ServFail);
     841                return refuse(res, RCode_ServFail);
    734842            else
    735843            {
     
    741849
    742850  out:
    743     if (nanswers > 0)
    744     {
    745         int ok = m_append(pData, m, res->end - oend, (caddr_t)&res->buf[oend]);
    746         if (!ok)
    747         {
    748             /* XXX: this may fail part way: restore old lenght, clear TC? */
    749             return refuse(pData, m, RCode_ServFail);
    750         }
    751         pHdr->ancount = RT_H2N_U16(nanswers);
    752     }
    753     memcpy(mtod(m, char *), res->buf, sizeof(struct dnsmsg_header));
    754     return m;
    755 }
    756 
     851    pHdr->ancount = RT_H2N_U16(nanswers);
     852    return VINF_SUCCESS;
     853}
     854
     855
     856static int
     857refuse(struct response *res, unsigned int rcode)
     858{
     859    struct dnsmsg_header *pHdr = (struct dnsmsg_header *)res->buf;
     860    pHdr->rcode = rcode;
     861
     862    return VINF_SUCCESS;
     863}
    757864
    758865
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r59219 r60142  
    3838
    3939#include <VBox/types.h>
     40#include <iprt/req.h>
    4041
    4142typedef struct NATState *PNATState;
     
    7172void slirp_urg_output(void *pvUser, struct mbuf *, const uint8_t *pu8Buf, int cb);
    7273void slirp_post_sent(PNATState pData, void *pvArg);
     74
     75int slirp_call(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies,
     76               unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
     77
     78int slirp_call_hostres(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies,
     79                       unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
     80
    7381
    7482void slirp_update_guest_addr_guess(PNATState pData, uint32_t guess, const char *msg);
  • trunk/src/VBox/Devices/Network/slirp/slirp.h

    r59142 r60142  
    352352
    353353/* hostres.c */
    354 struct mbuf *hostresolver(PNATState, struct mbuf *);
     354struct mbuf *hostresolver(PNATState, struct mbuf *, uint32_t src, uint16_t sport);
    355355
    356356/*slirp.c*/
  • trunk/src/VBox/Devices/Network/slirp/udp.c

    r59143 r60142  
    199199        m_adj(m, sizeof(struct udpiphdr));
    200200
    201         m = hostresolver(pData, m);
     201        m = hostresolver(pData, m, ip->ip_src.s_addr, uh->uh_sport);
    202202        if (m == NULL)
    203203            goto done_free_mbuf;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette