VirtualBox

Changeset 48056 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 26, 2013 10:31:27 AM (11 years ago)
Author:
vboxsync
Message:

DrvNAT: Watch for DNS server changes on OS X and force a reconnect

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r47930 r48056  
    193193        -framework IOKit \
    194194        -framework Carbon \
    195         -framework DiskArbitration
     195        -framework DiskArbitration \
     196        -framework SystemConfiguration
    196197 VBoxDD_LDFLAGS.linux    = -Wl,--no-undefined
    197198
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r47506 r48056  
    5252#include <iprt/semaphore.h>
    5353#include <iprt/req.h>
     54#ifdef RT_OS_DARWIN
     55# include <SystemConfiguration/SystemConfiguration.h>
     56# include <CoreFoundation/CoreFoundation.h>
     57#endif
    5458
    5559#define COUNTERS_INIT
     
    197201    /** Transmit lock taken by BeginXmit and released by EndXmit. */
    198202    RTCRITSECT              XmitLock;
     203
     204#ifdef RT_OS_DARWIN
     205    /* Handle of the DNS watcher runloop source. */
     206    CFRunLoopSourceRef      hRunLoopSrcDnsWatcher;
     207#endif
    199208} DRVNAT;
    200209AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8);
     
    940949
    941950
     951#ifdef RT_OS_DARWIN
     952/**
     953 * Callback for the SystemConfiguration framework to notify us whenever the DNS
     954 * server changes.
     955 *
     956 * @returns nothing.
     957 * @param   hDynStor    The DynamicStore handle.
     958 * @param   hChangedKey Array of changed keys we watch for.
     959 * @param   pvUser      Opaque user data (NAT driver instance).
     960 */
     961static DECLCALLBACK(void) drvNatDnsChanged(SCDynamicStoreRef hDynStor, CFArrayRef hChangedKeys, void *pvUser)
     962{
     963    PDRVNAT pThis = (PDRVNAT)pvUser;
     964
     965    pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig, PDMNETWORKLINKSTATE_DOWN_RESUME);
     966}
     967#endif
     968
    942969/**
    943970 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     
    10101037             * Disconnect the guest from the network temporarily to let it pick up the changes.
    10111038             */
     1039#ifndef RT_OS_DARWIN
    10121040            pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig,
    10131041                                                  PDMNETWORKLINKSTATE_DOWN_RESUME);
     1042#endif
    10141043            return;
    10151044        default: /* Ignore every other resume reason. */
     
    12031232    if (RTCritSectIsInitialized(&pThis->XmitLock))
    12041233        RTCritSectDelete(&pThis->XmitLock);
     1234
     1235#ifdef RT_OS_DARWIN
     1236    /* Cleanup the DNS watcher. */
     1237    CFRunLoopRef hRunLoopMain = CFRunLoopGetMain();
     1238    CFRetain(hRunLoopMain);
     1239    CFRunLoopRemoveSource(hRunLoopMain, pThis->hRunLoopSrcDnsWatcher, kCFRunLoopCommonModes);
     1240    CFRelease(hRunLoopMain);
     1241    CFRelease(pThis->hRunLoopSrcDnsWatcher);
     1242    pThis->hRunLoopSrcDnsWatcher = NULL;
     1243#endif
    12051244}
    12061245
     
    12291268    pThis->EventRecv                    = NIL_RTSEMEVENT;
    12301269    pThis->EventUrgRecv                 = NIL_RTSEMEVENT;
     1270#ifdef RT_OS_DARWIN
     1271    pThis->hRunLoopSrcDnsWatcher        = NULL;
     1272#endif
    12311273
    12321274    /* IBase */
     
    14361478
    14371479            pThis->enmLinkState = pThis->enmLinkStateWant = PDMNETWORKLINKSTATE_UP;
     1480
     1481#ifdef RT_OS_DARWIN
     1482            /* Set up a watcher which notifies us everytime the DNS server changes. */
     1483            int rc2 = VINF_SUCCESS;
     1484            SCDynamicStoreContext SCDynStorCtx;
     1485
     1486            SCDynStorCtx.version = 0;
     1487            SCDynStorCtx.info = pThis;
     1488            SCDynStorCtx.retain = NULL;
     1489            SCDynStorCtx.release = NULL;
     1490            SCDynStorCtx.copyDescription = NULL;
     1491
     1492            SCDynamicStoreRef hDynStor = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.drvnat"), drvNatDnsChanged, &SCDynStorCtx);
     1493            if (hDynStor)
     1494            {
     1495                CFRunLoopSourceRef hRunLoopSrc = SCDynamicStoreCreateRunLoopSource(NULL, hDynStor, 0);
     1496                if (hRunLoopSrc)
     1497                {
     1498                    CFStringRef aWatchKeys[] =
     1499                    {
     1500                        CFSTR("State:/Network/Global/DNS")
     1501                    };
     1502                    CFArrayRef hArray = CFArrayCreate(NULL, (const void **)aWatchKeys, 1, &kCFTypeArrayCallBacks);
     1503
     1504                    if (hArray)
     1505                    {
     1506                        if (SCDynamicStoreSetNotificationKeys(hDynStor, hArray, NULL))
     1507                        {
     1508                            CFRunLoopRef hRunLoopMain = CFRunLoopGetMain();
     1509                            CFRetain(hRunLoopMain);
     1510                            CFRunLoopAddSource(hRunLoopMain, hRunLoopSrc, kCFRunLoopCommonModes);
     1511                            CFRelease(hRunLoopMain);
     1512                            pThis->hRunLoopSrcDnsWatcher = hRunLoopSrc;
     1513                        }
     1514                        else
     1515                            rc2 = VERR_NO_MEMORY;
     1516
     1517                        CFRelease(hArray);
     1518                    }
     1519                    else
     1520                        rc2 = VERR_NO_MEMORY;
     1521
     1522                    if (RT_FAILURE(rc2)) /* Keep the runloop source referenced for destruction. */
     1523                        CFRelease(hRunLoopSrc);
     1524                }
     1525                CFRelease(hDynStor);
     1526            }
     1527            else
     1528                rc2 = VERR_NO_MEMORY;
     1529
     1530            if (RT_FAILURE(rc2))
     1531                LogRel(("NAT#%d: Failed to install DNS change notifier. The guest might loose DNS access when switching networks on the host\n",
     1532                         pDrvIns->iInstance));
     1533#endif
    14381534
    14391535            /* might return VINF_NAT_DNS */
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