VirtualBox

Changeset 105726 in vbox for trunk


Ignore:
Timestamp:
Aug 19, 2024 2:05:15 PM (9 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164430
Message:

Devices/Network: cleaned up header file, memory leak fixes, search domains pushed to guest on host network change only. bugref:10268

Location:
trunk
Files:
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmnetifs.h

    r104525 r105726  
    433433
    434434
     435/**
     436 * DNS Setting Update Payload
     437 * @sa PGMINETWORKNATCONFIG::pfnNotifyDnsChanged
     438 */
     439typedef struct PDMINETWORKNATDNSCONFIG
     440{
     441    /** Domain name.
     442     * (The length is per RFC2821 plus null char.) */
     443    char                szDomainName[256];
     444    /** Number of entries in the ppszNameServers array.   */
     445    size_t              cNameServers;
     446    /** Name servers (NULL terminated array). */
     447    const char * const *papszNameServers;
     448    /** Number of entries in the ppszSearchDomains array. */
     449    size_t              cSearchDomains;
     450    /** Search domains (NULL terminated array). */
     451    const char * const *papszSearchDomains;
     452} PDMINETWORKNATDNSCONFIG;
     453/** Pointer to a const DNS settings update payload.
     454 * @sa PGMINETWORKNATCONFIG::pfnNotifyDnsChanged */
     455typedef PDMINETWORKNATDNSCONFIG const *PCPDMINETWORKNATDNSCONFIG;
     456
     457
    435458/** Pointer to a NAT configuration port.   */
    436459typedef struct PDMINETWORKNATCONFIG *PPDMINETWORKNATCONFIG;
     
    455478     * IHostNameResolutionConfigurationChangeEvent.
    456479     */
    457     DECLR3CALLBACKMEMBER(void, pfnNotifyDnsChanged, (PPDMINETWORKNATCONFIG pInterface));
     480    DECLR3CALLBACKMEMBER(void, pfnNotifyDnsChanged, (PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConfig));
    458481
    459482} PDMINETWORKNATCONFIG;
    460483/** PDMINETWORKNATCONFIG interface ID. */
    461 #define PDMINETWORKNATCONFIG_IID                "dc961028-3523-4b52-a93b-e38168a4a9fa"
     484#define PDMINETWORKNATCONFIG_IID                "16de6afe-e48f-4cad-abc0-f96507683376"
    462485/** @} */
    463486
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r105353 r105726  
    10971097 * information ourselves.
    10981098 */
    1099 static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface)
    1100 {
     1099static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConf)
     1100{
     1101    RT_NOREF(pDnsConf);
    11011102    PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
    11021103    drvNATUpdateDNS(pThis, /* fFlapLink */ true);
  • trunk/src/VBox/Devices/Network/DrvNATlibslirp.cpp

    r105429 r105726  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_DRV_NAT
    33 
    34 #include "DrvNATlibslirp.h"
    35 
    36 
    37 /**
     33#define RTNET_INCL_IN_ADDR
     34#include "VBoxDD.h"
     35
     36#ifdef RT_OS_WINDOWS
     37# include <iprt/win/winsock2.h>
     38# include <iprt/win/ws2tcpip.h>
     39#endif
     40
     41#include <libslirp.h>
     42
     43#include <VBox/vmm/dbgf.h>
     44#include <VBox/vmm/pdmdrv.h>
     45#include <VBox/vmm/pdmnetifs.h>
     46#include <VBox/vmm/pdmnetinline.h>
     47
     48#ifndef RT_OS_WINDOWS
     49# include <unistd.h>
     50# include <fcntl.h>
     51# include <poll.h>
     52# include <errno.h>
     53#endif
     54#ifdef RT_OS_FREEBSD
     55# include <netinet/in.h>
     56#endif
     57
     58#ifdef RT_OS_WINDOWS
     59# include <iprt/win/winsock2.h>
     60# define inet_aton(x, y) inet_pton(2, x, y)
     61# define AF_INET6 23
     62#endif
     63
     64#include <iprt/assert.h>
     65#include <iprt/critsect.h>
     66#include <iprt/cidr.h>
     67#include <iprt/file.h>
     68#include <iprt/mem.h>
     69#include <iprt/net.h>
     70#include <iprt/pipe.h>
     71#include <iprt/string.h>
     72#include <iprt/stream.h>
     73#include <iprt/time.h>
     74#include <iprt/uuid.h>
     75
     76#include <iprt/asm.h>
     77
     78#include <iprt/semaphore.h>
     79#include <iprt/req.h>
     80#ifdef RT_OS_DARWIN
     81# include <SystemConfiguration/SystemConfiguration.h>
     82# include <CoreFoundation/CoreFoundation.h>
     83#endif
     84
     85#define COUNTERS_INIT
     86#include "slirp/counters.h"
     87#include "slirp/resolv_conf_parser.h"
     88
     89
     90/*********************************************************************************************************************************
     91*   Defined Constants And Macros                                                                                                 *
     92*********************************************************************************************************************************/
     93#define DRVNAT_MAXFRAMESIZE (16 * 1024)
     94#define DRVNAT_DEFAULT_TIMEOUT (3600*1000)
     95
     96/**
     97 * @todo: This is a bad hack to prevent freezing the guest during high network
     98 *        activity. Windows host only. This needs to be fixed properly.
     99 */
     100#define VBOX_NAT_DELAY_HACK
     101
     102#define GET_EXTRADATA(pdrvins, node, name, rc, type, type_name, var)                                  \
     103    do {                                                                                                \
     104        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var));                                               \
     105        if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND)                                      \
     106            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     107                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     108                                       (pdrvins)->iInstance);                                    \
     109    } while (0)
     110
     111#define GET_ED_STRICT(pdrvins, node, name, rc, type, type_name, var)                                  \
     112    do {                                                                                                \
     113        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var));                                               \
     114        if (RT_FAILURE((rc)))                                                                           \
     115            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     116                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     117                                       (pdrvins)->iInstance);                                     \
     118    } while (0)
     119
     120#define GET_EXTRADATA_N(pdrvins, node, name, rc, type, type_name, var, var_size)                      \
     121    do {                                                                                                \
     122        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var), var_size);                                     \
     123        if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND)                                      \
     124            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     125                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     126                                       (pdrvins)->iInstance);                                     \
     127    } while (0)
     128
     129#define GET_BOOL(rc, pdrvins, node, name, var) \
     130    GET_EXTRADATA(pdrvins, node, name, (rc), Bool, bolean, (var))
     131#define GET_STRING(rc, pdrvins, node, name, var, var_size) \
     132    GET_EXTRADATA_N(pdrvins, node, name, (rc), String, string, (var), (var_size))
     133#define GET_STRING_ALLOC(rc, pdrvins, node, name, var) \
     134    GET_EXTRADATA(pdrvins, node, name, (rc), StringAlloc, string, (var))
     135#define GET_S32(rc, pdrvins, node, name, var) \
     136    GET_EXTRADATA(pdrvins, node, name, (rc), S32, int, (var))
     137#define GET_S32_STRICT(rc, pdrvins, node, name, var) \
     138    GET_ED_STRICT(pdrvins, node, name, (rc), S32, int, (var))
     139
     140#define DO_GET_IP(rc, node, instance, status, x)                                \
     141    do {                                                                            \
     142        char    sz##x[32];                                                          \
     143        GET_STRING((rc), (node), (instance), #x, sz ## x[0],  sizeof(sz ## x));     \
     144        if (rc != VERR_CFGM_VALUE_NOT_FOUND)                                        \
     145            (status) = inet_aton(sz ## x, &x);                                      \
     146    } while (0)
     147
     148#define GETIP_DEF(rc, node, instance, x, def)           \
     149    do                                                      \
     150    {                                                       \
     151        int status = 0;                                     \
     152        DO_GET_IP((rc), (node), (instance),  status, x);    \
     153        if (status == 0 || rc == VERR_CFGM_VALUE_NOT_FOUND) \
     154            x.s_addr = def;                                 \
     155    } while (0)
     156
     157
     158/*********************************************************************************************************************************
     159*   Structures and Typedefs                                                                                                      *
     160*********************************************************************************************************************************/
     161/** Slirp Timer */
     162typedef struct slirpTimer
     163{
     164    struct slirpTimer *next;
     165    uint32_t uTimeExpire;
     166    SlirpTimerCb pHandler;
     167    void *opaque;
     168} SlirpTimer;
     169
     170/**
     171 * Main state of Libslirp NAT
     172 */
     173typedef struct SlirpState
     174{
     175    unsigned int nsock;
     176
     177    Slirp *pSlirp;
     178    struct pollfd *polls;
     179
     180    /** Num Polls (not bytes) */
     181    unsigned int uPollCap = 0;
     182
     183    SlirpTimer *pTimerHead;
     184} SlirpState;
     185typedef SlirpState *pSlirpState;
     186
     187/**
     188 * NAT network transport driver instance data.
     189 *
     190 * @implements  PDMINETWORKUP
     191 */
     192typedef struct DRVNAT
     193{
     194    /** The network interface. */
     195    PDMINETWORKUP           INetworkUp;
     196    /** The network NAT Engine configuration. */
     197    PDMINETWORKNATCONFIG    INetworkNATCfg;
     198    /** The port we're attached to. */
     199    PPDMINETWORKDOWN        pIAboveNet;
     200    /** The network config of the port we're attached to. */
     201    PPDMINETWORKCONFIG      pIAboveConfig;
     202    /** Pointer to the driver instance. */
     203    PPDMDRVINS              pDrvIns;
     204    /** Link state */
     205    PDMNETWORKLINKSTATE     enmLinkState;
     206    /** NAT state */
     207    pSlirpState             pNATState;
     208    /** TFTP directory prefix. */
     209    char                   *pszTFTPPrefix;
     210    /** Boot file name to provide in the DHCP server response. */
     211    char                   *pszBootFile;
     212    /** tftp server name to provide in the DHCP server response. */
     213    char                   *pszNextServer;
     214    /** Polling thread. */
     215    PPDMTHREAD              pSlirpThread;
     216    /** Queue for NAT-thread-external events. */
     217    RTREQQUEUE              hSlirpReqQueue;
     218    /** The guest IP for port-forwarding. */
     219    uint32_t                GuestIP;
     220    /** Link state set when the VM is suspended. */
     221    PDMNETWORKLINKSTATE     enmLinkStateWant;
     222
     223#ifndef RT_OS_WINDOWS
     224    /** The write end of the control pipe. */
     225    RTPIPE                  hPipeWrite;
     226    /** The read end of the control pipe. */
     227    RTPIPE                  hPipeRead;
     228# if HC_ARCH_BITS == 32
     229    uint32_t                u32Padding;
     230# endif
     231#else
     232    /** for external notification */
     233    HANDLE                  hWakeupEvent;
     234#endif
     235
     236#define DRV_PROFILE_COUNTER(name, dsc)     STAMPROFILE Stat ## name
     237#define DRV_COUNTING_COUNTER(name, dsc)    STAMCOUNTER Stat ## name
     238#include "slirp/counters.h"
     239    /** thread delivering packets for receiving by the guest */
     240    PPDMTHREAD              pRecvThread;
     241    /** event to wakeup the guest receive thread */
     242    RTSEMEVENT              EventRecv;
     243    /** Receive Req queue (deliver packets to the guest) */
     244    RTREQQUEUE              hRecvReqQueue;
     245
     246    /** makes access to device func RecvAvail and Recv atomical. */
     247    RTCRITSECT              DevAccessLock;
     248    /** Number of in-flight packets. */
     249    volatile uint32_t       cPkts;
     250
     251    /** Transmit lock taken by BeginXmit and released by EndXmit. */
     252    RTCRITSECT              XmitLock;
     253
     254#ifdef RT_OS_DARWIN
     255    /* Handle of the DNS watcher runloop source. */
     256    CFRunLoopSourceRef      hRunLoopSrcDnsWatcher;
     257#endif
     258} DRVNAT;
     259AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8);
     260/** Pointer to the NAT driver instance data. */
     261typedef DRVNAT *PDRVNAT;
     262
     263
     264/*********************************************************************************************************************************
     265*   Internal Functions                                                                                                           *
     266*********************************************************************************************************************************/
     267static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho);
     268static void drvNAT_UpdateTimeout(uint32_t *uTimeout, void *opaque);
     269static void drvNAT_CheckTimeout(void *opaque);
     270static DECLCALLBACK(int) drvNAT_AddPollCb(int iFd, int iEvents, void *opaque);
     271static DECLCALLBACK(int64_t) drvNAT_ClockGetNsCb(void *opaque);
     272static DECLCALLBACK(int) drvNAT_GetREventsCb(int idx, void *opaque);
     273
     274
     275
     276/*
    38277 * PDM Function Implementations
    39278 */
     
    499738         */
    500739#ifndef RT_OS_WINDOWS
    501         uint32_t uTimeout = 0;
     740        uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT;
    502741        pThis->pNATState->nsock = 1;
    503742
     
    548787
    549788#else /* RT_OS_WINDOWS */
    550         uint32_t uTimeout = 0;
     789        uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT;
    551790        pThis->pNATState->nsock = 0;
    552791        slirp_pollfds_fill(pThis->pNATState->pSlirp, &uTimeout, drvNAT_AddPollCb /* SlirpAddPollCb */, pThis /* opaque */);
     
    7751014}
    7761015
     1016/**
     1017 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnRedirectRuleCommand}
     1018 */
    7771019static DECLCALLBACK(int) drvNATNetworkNatConfigRedirect(PPDMINETWORKNATCONFIG pInterface, bool fRemove,
    7781020                                                        bool fUdp, const char *pHostIp, uint16_t u16HostPort,
     
    8111053
    8121054/**
     1055 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnNotifyDnsChanged}
     1056 */
     1057static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConf)
     1058{
     1059    PDRVNAT const      pThis     = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
     1060    SlirpState * const pNATState = pThis->pNATState;
     1061    AssertReturnVoid(pNATState);
     1062    AssertReturnVoid(pNATState->pSlirp);
     1063
     1064    slirp_set_vdomainname(pNATState->pSlirp, pDnsConf->szDomainName);
     1065    slirp_set_vdnssearch(pNATState->pSlirp, pDnsConf->papszSearchDomains);
     1066    /** @todo Convert the papszNameServers entries to IP address and tell about
     1067     *        the first IPv4 and IPv6 ones. */
     1068}
     1069
     1070
     1071/*
    8131072 * Libslirp Utility Functions
    8141073 */
     
    8221081 */
    8231082static void drvNAT_UpdateTimeout(uint32_t *uTimeout, void *opaque)
     1083{
     1084    PDRVNAT pThis = (PDRVNAT)opaque;
     1085    Assert(pThis);
     1086
     1087    uint32_t currTime = drvNAT_ClockGetNsCb(pThis) / (1000 * 1000);
     1088    SlirpTimer *pCurrent = pThis->pNATState->pTimerHead;
     1089    while (pCurrent != NULL)
     1090    {
     1091        if (pCurrent->uTimeExpire != 0)
     1092        {
     1093            int64_t diff = pCurrent->uTimeExpire - currTime;
     1094
     1095            if (diff < 0)
     1096                diff = 0;
     1097
     1098            if (diff < *uTimeout)
     1099                *uTimeout = diff;
     1100        }
     1101
     1102        pCurrent = pCurrent->next;
     1103    }
     1104}
     1105
     1106/**
     1107 * Check if timeout has passed in given list of Slirp timers.
     1108 *
     1109 * @param   opaque  Pointer to NAT State context.
     1110 *
     1111 * @thread  ?
     1112 */
     1113static void drvNAT_CheckTimeout(void *opaque)
    8241114{
    8251115    PDRVNAT pThis = (PDRVNAT)opaque;
     
    8301120    while (pCurrent != NULL)
    8311121    {
    832         if (pCurrent->uTimeExpire != -1)
    833         {
    834             int64_t diff = pCurrent->uTimeExpire - currTime;
    835 
    836             if (diff < 0)
    837                 diff = 0;
    838 
    839             if (diff < *uTimeout)
    840                 *uTimeout = diff;
    841         }
    842 
    843         pCurrent = pCurrent->next;
    844     }
    845 }
    846 
    847 /**
    848  * Check if timeout has passed in given list of Slirp timers.
    849  *
    850  * @param   opaque  Pointer to NAT State context.
    851  *
    852  * @thread  ?
    853  */
    854 static void drvNAT_CheckTimeout(void *opaque)
    855 {
    856     PDRVNAT pThis = (PDRVNAT)opaque;
    857     Assert(pThis);
    858 
    859     int64_t currTime = drvNAT_ClockGetNsCb(pThis) / (1000 * 1000);
    860     SlirpTimer *pCurrent = pThis->pNATState->pTimerHead;
    861     while (pCurrent != NULL)
    862     {
    863         if (pCurrent->uTimeExpire != -1)
     1122        if (pCurrent->uTimeExpire != 0)
    8641123        {
    8651124            int64_t diff = pCurrent->uTimeExpire - currTime;
    8661125            if (diff <= 0)
    8671126            {
    868                 pCurrent->uTimeExpire = -1;
     1127                pCurrent->uTimeExpire = 0;
    8691128                pCurrent->pHandler(pCurrent->opaque);
    8701129            }
     
    9291188}
    9301189
    931 /**
     1190
     1191/*
    9321192 * Libslirp Callbacks
    9331193 */
     
    10291289
    10301290    pNewTimer->next = pThis->pNATState->pTimerHead;
    1031     pNewTimer->uTimeExpire = -1;
     1291    pNewTimer->uTimeExpire = -1; /** @todo r=bird: uTimeExpire is unsigned, not signed. Visual C++ barfs at this mixup. */
    10321292    pNewTimer->pHandler = slirpTimeCb;
    10331293    pNewTimer->opaque = cb_opaque;
     
    10941354 * Registers poll. Unused function (other than logging).
    10951355 */
    1096 static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque) {
     1356static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque)
     1357{
    10971358    RT_NOREF(fd, opaque);
    10981359    Log4(("Poll registered\n"));
     
    11021363 * Unregisters poll. Unused function (other than logging).
    11031364 */
    1104 static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque) {
     1365static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque)
     1366{
    11051367    RT_NOREF(fd, opaque);
    11061368    Log4(("Poll unregistered\n"));
     
    11271389        int cbNew = pThis->pNATState->uPollCap * 2 * sizeof(struct pollfd);
    11281390        struct pollfd *pvNew = (struct pollfd *)RTMemRealloc(pThis->pNATState->polls, cbNew);
    1129         if(pvNew)
     1391        if (pvNew)
    11301392        {
    11311393            pThis->pNATState->polls = pvNew;
     
    11821444    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    11831445
    1184     if (pThis->pNATState)
    1185     {
    1186         slirp_cleanup(pThis->pNATState->pSlirp);
     1446    SlirpState * const pNATState = pThis->pNATState;
     1447    if (pNATState)
     1448    {
     1449        slirp_cleanup(pNATState->pSlirp);
     1450
    11871451#ifdef VBOX_WITH_STATISTICS
    11881452# define DRV_PROFILE_COUNTER(name, dsc)     DEREGISTER_COUNTER(name, pThis)
     
    11901454# include "slirp/counters.h"
    11911455#endif
     1456        RTMemFree(pNATState->polls);
     1457        pNATState->polls = NULL;
     1458
     1459        RTMemFree(pNATState);
    11921460        pThis->pNATState = NULL;
    11931461    }
     
    12211489static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    12221490{
    1223     int rc = 0;
    1224 
    1225     /* Construct PDRVNAT */
    1226 
    12271491    RT_NOREF(fFlags);
    12281492    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    1229     PDRVNAT         pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     1493    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    12301494
    12311495    /*
     
    12331497     */
    12341498    pThis->pDrvIns                      = pDrvIns;
    1235     pThis->pNATState                    = (SlirpState *)RTMemAlloc(sizeof(SlirpState));
    1236     if(pThis->pNATState == NULL)
     1499
     1500    SlirpState * const pNATState = (SlirpState *)RTMemAllocZ(sizeof(*pNATState));
     1501    if (pNATState == NULL)
    12371502        return VERR_NO_MEMORY;
    1238     else
    1239     {
    1240         pThis->pNATState->nsock = 0;
    1241         pThis->pNATState->pTimerHead = NULL;
    1242         pThis->pNATState->polls = (struct pollfd *)RTMemAlloc(64 * sizeof(struct pollfd));
    1243         pThis->pNATState->uPollCap = 64;
    1244     }
     1503    pThis->pNATState                    = pNATState;
     1504    pNATState->nsock                    = 0;
     1505    pNATState->pTimerHead               = NULL;
     1506    pNATState->polls                    = (struct pollfd *)RTMemAllocZ(64 * sizeof(struct pollfd));
     1507    AssertReturn(pNATState->polls, VERR_NO_MEMORY);
     1508    pNATState->uPollCap                = 64;
     1509
    12451510    pThis->hSlirpReqQueue               = NIL_RTREQQUEUE;
    12461511    pThis->EventRecv                    = NIL_RTSEMEVENT;
     
    12601525    /* NAT engine configuration */
    12611526    pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfigRedirect;
    1262     pThis->INetworkNATCfg.pfnNotifyDnsChanged = NULL;
     1527    pThis->INetworkNATCfg.pfnNotifyDnsChanged    = drvNATNotifyDnsChanged;
    12631528
    12641529    /*
     
    12891554     * Get the configuration settings.
    12901555     */
     1556    int  rc;
    12911557    bool fPassDomain = true;
    12921558    GET_BOOL(rc, pDrvIns, pCfg, "PassDomain", fPassDomain);
     
    13351601
    13361602    RTNETADDRIPV4 Network, Netmask;
    1337 
    13381603    rc = RTCidrStrToIPv4(szNetwork, &Network, &Netmask);
    13391604    if (RT_FAILURE(rc))
     
    13441609    /* Construct Libslirp Config and Initialzie Slirp */
    13451610
    1346     LogFlow(("Here is what is coming out of the vbox config:\n \
    1347             Network: %lu\n \
    1348             Netmask: %lu\n", Network, Netmask));
    1349 
    1350 #ifndef RT_OS_WINDOWS
     1611    LogFlow(("Here is what is coming out of the vbox config:\n"
     1612             "  Network: %lu\n"
     1613             "  Netmask: %lu\n", Network, Netmask));
     1614
     1615#ifndef RT_OS_WINDOWS /** @todo r=bird: Why do we need special windows code here?!? */
    13511616    struct in_addr vnetwork = RTNetIPv4AddrHEToInAddr(&Network);
    13521617    struct in_addr vnetmask = RTNetIPv4AddrHEToInAddr(&Netmask);
     
    13711636#endif
    13721637
     1638    /** @todo r=bird: This is leaked.  It can be a stack structure since libslirp
     1639     *        only copies values from it and doesn't retain the pointer. */
    13731640    SlirpConfig *pSlirpCfg = new SlirpConfig { 0 };
    13741641
     
    13981665    pSlirpCfg->vdomainname = NULL;
    13991666
     1667    /** @todo r=bird: This is leaked.  It can be a static structure.   */
    14001668    SlirpCb *slirpCallbacks = (struct SlirpCb *)RTMemAlloc(sizeof(SlirpCb));
    14011669
     
    14321700
    14331701    rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pRecvThread, pThis, drvNATRecv,
    1434                                 drvNATRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATRX");
     1702                               drvNATRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATRX");
    14351703    AssertRCReturn(rc, rc);
    14361704
     
    14631731
    14641732    rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pSlirpThread, pThis, drvNATAsyncIoThread,
    1465                                 drvNATAsyncIoWakeup, 256 * _1K, RTTHREADTYPE_IO, "NAT");
     1733                               drvNATAsyncIoWakeup, 256 * _1K, RTTHREADTYPE_IO, "NAT");
    14661734    AssertRCReturn(rc, rc);
    14671735
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r105605 r105726  
    103103struct VUSBIRHCONFIG;
    104104typedef struct VUSBIRHCONFIG *PVUSBIRHCONFIG;
     105
     106struct PDMINETWORKNATDNSCONFIG;
    105107
    106108#include <list>
     
    437439    HRESULT clearAllEncryptionPasswords();
    438440
    439     void notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax);
     441    void notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax,
     442                            struct PDMINETWORKNATDNSCONFIG const *pDnsConfig);
    440443    Utf8Str VRDPServerErrorToMsg(int vrc);
    441444
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r105605 r105726  
    45124512
    45134513
    4514 /*
     4514/** Helper that converts a BSTR safe array into a C-string array. */
     4515static char **bstrSafeArrayToC(SafeArray<BSTR> const &a_rStrings, size_t *pcEntries) RT_NOEXCEPT
     4516{
     4517    if (pcEntries)
     4518        *pcEntries = 0;
     4519
     4520    /*
     4521     * The array is NULL terminated.
     4522     */
     4523    const size_t cStrings = a_rStrings.size();
     4524    char **papszRet = (char **)RTMemAllocZ((cStrings + 1) * sizeof(papszRet[0]));
     4525    AssertReturn(papszRet, NULL);
     4526
     4527    /*
     4528     * The individual strings.
     4529     */
     4530    for (size_t i = 0; i < cStrings; i++)
     4531    {
     4532        int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_rStrings[i], RTSTR_MAX, &papszRet[i], 0, NULL);
     4533        AssertRC(vrc);
     4534        if (RT_FAILURE(vrc))
     4535        {
     4536            while (i-- > 0)
     4537            {
     4538                RTStrFree(papszRet[i]);
     4539                papszRet[i] = NULL;
     4540            }
     4541            return NULL;
     4542        }
     4543
     4544    }
     4545        if (pcEntries)
     4546            *pcEntries = cStrings;
     4547    return papszRet;
     4548}
     4549
     4550
     4551/**
    45154552 * IHostNameResolutionConfigurationChangeEvent
    45164553 *
     
    45204557HRESULT Console::i_onNATDnsChanged()
    45214558{
    4522     HRESULT hrc;
    4523 
    45244559    AutoCaller autoCaller(this);
    45254560    AssertComRCReturnRC(autoCaller.hrc());
    45264561
    4527     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    4528 
    4529 #if 0 /* XXX: We don't yet pass this down to pfnNotifyDnsChanged */
    4530     ComPtr<IVirtualBox> pVirtualBox;
    4531     hrc = mMachine->COMGETTER(Parent)(pVirtualBox.asOutParam());
     4562    /* We wrap PDMINETWORKNATDNSCONFIG to simplify freeing memory allocations
     4563       in it (exceptions, AssertReturn, regular returns). */
     4564    struct DnsConfigCleanupWrapper
     4565    {
     4566        PDMINETWORKNATDNSCONFIG Core;
     4567
     4568        DnsConfigCleanupWrapper()
     4569        {
     4570            Core.szDomainName[0]    = '\0';
     4571            Core.cNameServers       = 0;
     4572            Core.papszNameServers   = NULL;
     4573            Core.cSearchDomains     = 0;
     4574            Core.papszSearchDomains = NULL;
     4575        }
     4576
     4577        void freeStrArray(char **papsz)
     4578        {
     4579            if (papsz)
     4580            {
     4581                for (size_t i = 0; papsz[i] != NULL; i++)
     4582                    RTStrFree(papsz[i]);
     4583                RTMemFree(papsz);
     4584            }
     4585        }
     4586
     4587        ~DnsConfigCleanupWrapper()
     4588        {
     4589            freeStrArray((char **)Core.papszNameServers);
     4590            Core.papszNameServers   = NULL;
     4591            freeStrArray((char **)Core.papszSearchDomains);
     4592            Core.papszSearchDomains = NULL;
     4593        }
     4594    } DnsConfig;
     4595
     4596
     4597    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /** @todo r=bird: Why a write lock? */
     4598
     4599    ComPtr<IVirtualBox> ptrVirtualBox;
     4600    HRESULT hrc = mMachine->COMGETTER(Parent)(ptrVirtualBox.asOutParam());
    45324601    if (FAILED(hrc))
    45334602        return S_OK;
    45344603
    4535     ComPtr<IHost> pHost;
    4536     hrc = pVirtualBox->COMGETTER(Host)(pHost.asOutParam());
     4604    ComPtr<IHost> ptrHost;
     4605    hrc = ptrVirtualBox->COMGETTER(Host)(ptrHost.asOutParam());
    45374606    if (FAILED(hrc))
    45384607        return S_OK;
    45394608
    4540     SafeArray<BSTR> aNameServers;
    4541     hrc = pHost->COMGETTER(NameServers)(ComSafeArrayAsOutParam(aNameServers));
    4542     if (FAILED(hrc))
    4543         return S_OK;
    4544 
    4545     const size_t cNameServers = aNameServers.size();
    4546     Log(("DNS change - %zu nameservers\n", cNameServers));
    4547 
    4548     for (size_t i = 0; i < cNameServers; ++i)
    4549     {
    4550         com::Utf8Str strNameServer(aNameServers[i]);
    4551         Log(("- nameserver[%zu] = \"%s\"\n", i, strNameServer.c_str()));
    4552     }
    4553 
    4554     com::Bstr domain;
    4555     pHost->COMGETTER(DomainName)(domain.asOutParam());
    4556     Log(("domain name = \"%s\"\n", com::Utf8Str(domain).c_str()));
    4557 #endif /* 0 */
    4558 
    4559     ComPtr<IPlatform> pPlatform;
    4560     hrc = mMachine->COMGETTER(Platform)(pPlatform.asOutParam());
     4609    /* Domain name: */
     4610    {
     4611        com::Bstr bstrDomain;
     4612        ptrHost->COMGETTER(DomainName)(bstrDomain.asOutParam());
     4613        com::Utf8Str const strDomainName(bstrDomain);
     4614        int vrc = RTStrCopy(DnsConfig.Core.szDomainName, sizeof(DnsConfig.Core.szDomainName), strDomainName.c_str());
     4615        AssertRC(vrc);
     4616    }
     4617    Log(("domain name = \"%s\"\n", DnsConfig.Core.szDomainName));
     4618
     4619    /* Name servers: */
     4620    {
     4621        SafeArray<BSTR> nameServers;
     4622        hrc = ptrHost->COMGETTER(NameServers)(ComSafeArrayAsOutParam(nameServers));
     4623        if (FAILED(hrc))
     4624            return S_OK;
     4625        DnsConfig.Core.papszNameServers = bstrSafeArrayToC(nameServers, &DnsConfig.Core.cNameServers);
     4626        if (!DnsConfig.Core.papszNameServers)
     4627            return E_OUTOFMEMORY;
     4628    }
     4629    Log(("DNS change - %zu nameservers\n", DnsConfig.Core.cNameServers));
     4630    for (size_t i = 0; i < DnsConfig.Core.cNameServers; i++)
     4631        Log(("- papszNameServers[%zu] = \"%s\"\n", i, DnsConfig.Core.papszNameServers[i]));
     4632
     4633    /* Search domains: */
     4634    {
     4635        SafeArray<BSTR> searchDomains;
     4636        hrc = ptrHost->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(searchDomains));
     4637        if (FAILED(hrc))
     4638            return S_OK;
     4639        DnsConfig.Core.papszSearchDomains = bstrSafeArrayToC(searchDomains, &DnsConfig.Core.cSearchDomains);
     4640        if (!DnsConfig.Core.papszSearchDomains)
     4641            return E_OUTOFMEMORY;
     4642    }
     4643    Log(("Search Domain change - %u domains\n", DnsConfig.Core.cSearchDomains));
     4644    for (size_t i = 0; i < DnsConfig.Core.cSearchDomains; i++)
     4645        Log(("- papszSearchDomain[%zu] = \"%s\"\n", i, DnsConfig.Core.papszSearchDomains[i]));
     4646
     4647    /*
     4648     * Notify all the NAT drivers.
     4649     */
     4650    /** @todo r=bird: This is the worst way of "enumerating" network devices
     4651     *        ever conceived. */
     4652    ComPtr<IPlatform> ptrPlatform;
     4653    hrc = mMachine->COMGETTER(Platform)(ptrPlatform.asOutParam());
    45614654    AssertComRCReturn(hrc, hrc);
    45624655
    45634656    ChipsetType_T enmChipsetType;
    4564     hrc = pPlatform->COMGETTER(ChipsetType)(&enmChipsetType);
     4657    hrc = ptrPlatform->COMGETTER(ChipsetType)(&enmChipsetType);
    45654658    AssertComRCReturn(hrc, hrc);
    45664659
     
    45704663        ULONG const ulInstanceMax = PlatformProperties::s_getMaxNetworkAdapters(enmChipsetType);
    45714664
    4572         notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "pcnet", ulInstanceMax);
    4573         notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "e1000", ulInstanceMax);
    4574         notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "virtio-net", ulInstanceMax);
     4665        notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "pcnet", ulInstanceMax, &DnsConfig.Core);
     4666        notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "e1000", ulInstanceMax, &DnsConfig.Core);
     4667        notifyNatDnsChange(ptrVM.rawUVM(), ptrVM.vtable(), "virtio-net", ulInstanceMax, &DnsConfig.Core);
    45754668    }
    45764669
     
    45794672
    45804673
    4581 /*
     4674/**
    45824675 * This routine walks over all network device instances, checking if
    45834676 * device instance has DrvNAT attachment and triggering DrvNAT DNS
    45844677 * change callback.
    45854678 */
    4586 void Console::notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax)
     4679void Console::notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax,
     4680                                 PCPDMINETWORKNATDNSCONFIG pDnsConfig)
    45874681{
    45884682    Log(("notifyNatDnsChange: looking for DrvNAT attachment on %s device instances\n", pszDevice));
     
    46004694            pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID);
    46014695            if (pNetNatCfg && pNetNatCfg->pfnNotifyDnsChanged)
    4602                 pNetNatCfg->pfnNotifyDnsChanged(pNetNatCfg);
     4696                pNetNatCfg->pfnNotifyDnsChanged(pNetNatCfg, pDnsConfig);
    46034697        }
    46044698    }
  • trunk/src/libs/libslirp-4.8.0/src/libslirp.h

    r105533 r105726  
    351351const char *slirp_version_string(void);
    352352
     353#ifdef VBOX
     354char *slirp_set_vdomainname(Slirp *, char const *);
     355char *slirp_get_vdomainname(Slirp *);
     356int slirp_set_vdnssearch(Slirp *, const char * const *);
     357#endif
     358
    353359#ifdef __cplusplus
    354360} /* extern "C" */
  • trunk/src/libs/libslirp-4.8.0/src/slirp.c

    r105533 r105726  
    16531653    }
    16541654}
     1655
     1656#ifdef VBOX
     1657
     1658char *slirp_set_vdomainname(Slirp *pSlirp, const char *vdomainname)
     1659{
     1660    pSlirp->vdomainname = g_strdup(vdomainname);
     1661    return pSlirp->vdomainname;
     1662}
     1663
     1664char *slirp_get_vdomainname(Slirp *pSlirp)
     1665{
     1666    return pSlirp->vdomainname;
     1667}
     1668
     1669int slirp_set_vdnssearch(Slirp *pSlirp, const char * const *ppszSearchDomains)
     1670{
     1671    return translate_dnssearch(pSlirp, (const char **)ppszSearchDomains);
     1672}
     1673
     1674#endif /* VBOX */
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