- Timestamp:
- Aug 19, 2024 2:05:15 PM (9 months ago)
- svn:sync-xref-src-repo-rev:
- 164430
- Location:
- trunk
- Files:
-
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmnetifs.h
r104525 r105726 433 433 434 434 435 /** 436 * DNS Setting Update Payload 437 * @sa PGMINETWORKNATCONFIG::pfnNotifyDnsChanged 438 */ 439 typedef 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 */ 455 typedef PDMINETWORKNATDNSCONFIG const *PCPDMINETWORKNATDNSCONFIG; 456 457 435 458 /** Pointer to a NAT configuration port. */ 436 459 typedef struct PDMINETWORKNATCONFIG *PPDMINETWORKNATCONFIG; … … 455 478 * IHostNameResolutionConfigurationChangeEvent. 456 479 */ 457 DECLR3CALLBACKMEMBER(void, pfnNotifyDnsChanged, (PPDMINETWORKNATCONFIG pInterface ));480 DECLR3CALLBACKMEMBER(void, pfnNotifyDnsChanged, (PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConfig)); 458 481 459 482 } PDMINETWORKNATCONFIG; 460 483 /** PDMINETWORKNATCONFIG interface ID. */ 461 #define PDMINETWORKNATCONFIG_IID " dc961028-3523-4b52-a93b-e38168a4a9fa"484 #define PDMINETWORKNATCONFIG_IID "16de6afe-e48f-4cad-abc0-f96507683376" 462 485 /** @} */ 463 486 -
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r105353 r105726 1097 1097 * information ourselves. 1098 1098 */ 1099 static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface) 1100 { 1099 static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConf) 1100 { 1101 RT_NOREF(pDnsConf); 1101 1102 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg); 1102 1103 drvNATUpdateDNS(pThis, /* fFlapLink */ true); -
trunk/src/VBox/Devices/Network/DrvNATlibslirp.cpp
r105429 r105726 31 31 *********************************************************************************************************************************/ 32 32 #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 */ 162 typedef 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 */ 173 typedef 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; 185 typedef SlirpState *pSlirpState; 186 187 /** 188 * NAT network transport driver instance data. 189 * 190 * @implements PDMINETWORKUP 191 */ 192 typedef 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; 259 AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8); 260 /** Pointer to the NAT driver instance data. */ 261 typedef DRVNAT *PDRVNAT; 262 263 264 /********************************************************************************************************************************* 265 * Internal Functions * 266 *********************************************************************************************************************************/ 267 static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho); 268 static void drvNAT_UpdateTimeout(uint32_t *uTimeout, void *opaque); 269 static void drvNAT_CheckTimeout(void *opaque); 270 static DECLCALLBACK(int) drvNAT_AddPollCb(int iFd, int iEvents, void *opaque); 271 static DECLCALLBACK(int64_t) drvNAT_ClockGetNsCb(void *opaque); 272 static DECLCALLBACK(int) drvNAT_GetREventsCb(int idx, void *opaque); 273 274 275 276 /* 38 277 * PDM Function Implementations 39 278 */ … … 499 738 */ 500 739 #ifndef RT_OS_WINDOWS 501 uint32_t uTimeout = 0;740 uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT; 502 741 pThis->pNATState->nsock = 1; 503 742 … … 548 787 549 788 #else /* RT_OS_WINDOWS */ 550 uint32_t uTimeout = 0;789 uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT; 551 790 pThis->pNATState->nsock = 0; 552 791 slirp_pollfds_fill(pThis->pNATState->pSlirp, &uTimeout, drvNAT_AddPollCb /* SlirpAddPollCb */, pThis /* opaque */); … … 775 1014 } 776 1015 1016 /** 1017 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnRedirectRuleCommand} 1018 */ 777 1019 static DECLCALLBACK(int) drvNATNetworkNatConfigRedirect(PPDMINETWORKNATCONFIG pInterface, bool fRemove, 778 1020 bool fUdp, const char *pHostIp, uint16_t u16HostPort, … … 811 1053 812 1054 /** 1055 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnNotifyDnsChanged} 1056 */ 1057 static 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 /* 813 1072 * Libslirp Utility Functions 814 1073 */ … … 822 1081 */ 823 1082 static 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 */ 1113 static void drvNAT_CheckTimeout(void *opaque) 824 1114 { 825 1115 PDRVNAT pThis = (PDRVNAT)opaque; … … 830 1120 while (pCurrent != NULL) 831 1121 { 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) 864 1123 { 865 1124 int64_t diff = pCurrent->uTimeExpire - currTime; 866 1125 if (diff <= 0) 867 1126 { 868 pCurrent->uTimeExpire = -1;1127 pCurrent->uTimeExpire = 0; 869 1128 pCurrent->pHandler(pCurrent->opaque); 870 1129 } … … 929 1188 } 930 1189 931 /** 1190 1191 /* 932 1192 * Libslirp Callbacks 933 1193 */ … … 1029 1289 1030 1290 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. */ 1032 1292 pNewTimer->pHandler = slirpTimeCb; 1033 1293 pNewTimer->opaque = cb_opaque; … … 1094 1354 * Registers poll. Unused function (other than logging). 1095 1355 */ 1096 static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque) { 1356 static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque) 1357 { 1097 1358 RT_NOREF(fd, opaque); 1098 1359 Log4(("Poll registered\n")); … … 1102 1363 * Unregisters poll. Unused function (other than logging). 1103 1364 */ 1104 static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque) { 1365 static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque) 1366 { 1105 1367 RT_NOREF(fd, opaque); 1106 1368 Log4(("Poll unregistered\n")); … … 1127 1389 int cbNew = pThis->pNATState->uPollCap * 2 * sizeof(struct pollfd); 1128 1390 struct pollfd *pvNew = (struct pollfd *)RTMemRealloc(pThis->pNATState->polls, cbNew); 1129 if (pvNew)1391 if (pvNew) 1130 1392 { 1131 1393 pThis->pNATState->polls = pvNew; … … 1182 1444 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns); 1183 1445 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 1187 1451 #ifdef VBOX_WITH_STATISTICS 1188 1452 # define DRV_PROFILE_COUNTER(name, dsc) DEREGISTER_COUNTER(name, pThis) … … 1190 1454 # include "slirp/counters.h" 1191 1455 #endif 1456 RTMemFree(pNATState->polls); 1457 pNATState->polls = NULL; 1458 1459 RTMemFree(pNATState); 1192 1460 pThis->pNATState = NULL; 1193 1461 } … … 1221 1489 static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 1222 1490 { 1223 int rc = 0;1224 1225 /* Construct PDRVNAT */1226 1227 1491 RT_NOREF(fFlags); 1228 1492 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 1229 PDRVNAT 1493 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 1230 1494 1231 1495 /* … … 1233 1497 */ 1234 1498 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) 1237 1502 return VERR_NO_MEMORY; 1238 else1239 {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 1245 1510 pThis->hSlirpReqQueue = NIL_RTREQQUEUE; 1246 1511 pThis->EventRecv = NIL_RTSEMEVENT; … … 1260 1525 /* NAT engine configuration */ 1261 1526 pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfigRedirect; 1262 pThis->INetworkNATCfg.pfnNotifyDnsChanged = NULL;1527 pThis->INetworkNATCfg.pfnNotifyDnsChanged = drvNATNotifyDnsChanged; 1263 1528 1264 1529 /* … … 1289 1554 * Get the configuration settings. 1290 1555 */ 1556 int rc; 1291 1557 bool fPassDomain = true; 1292 1558 GET_BOOL(rc, pDrvIns, pCfg, "PassDomain", fPassDomain); … … 1335 1601 1336 1602 RTNETADDRIPV4 Network, Netmask; 1337 1338 1603 rc = RTCidrStrToIPv4(szNetwork, &Network, &Netmask); 1339 1604 if (RT_FAILURE(rc)) … … 1344 1609 /* Construct Libslirp Config and Initialzie Slirp */ 1345 1610 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?!? */ 1351 1616 struct in_addr vnetwork = RTNetIPv4AddrHEToInAddr(&Network); 1352 1617 struct in_addr vnetmask = RTNetIPv4AddrHEToInAddr(&Netmask); … … 1371 1636 #endif 1372 1637 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. */ 1373 1640 SlirpConfig *pSlirpCfg = new SlirpConfig { 0 }; 1374 1641 … … 1398 1665 pSlirpCfg->vdomainname = NULL; 1399 1666 1667 /** @todo r=bird: This is leaked. It can be a static structure. */ 1400 1668 SlirpCb *slirpCallbacks = (struct SlirpCb *)RTMemAlloc(sizeof(SlirpCb)); 1401 1669 … … 1432 1700 1433 1701 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pRecvThread, pThis, drvNATRecv, 1434 1702 drvNATRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATRX"); 1435 1703 AssertRCReturn(rc, rc); 1436 1704 … … 1463 1731 1464 1732 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pSlirpThread, pThis, drvNATAsyncIoThread, 1465 1733 drvNATAsyncIoWakeup, 256 * _1K, RTTHREADTYPE_IO, "NAT"); 1466 1734 AssertRCReturn(rc, rc); 1467 1735 -
trunk/src/VBox/Main/include/ConsoleImpl.h
r105605 r105726 103 103 struct VUSBIRHCONFIG; 104 104 typedef struct VUSBIRHCONFIG *PVUSBIRHCONFIG; 105 106 struct PDMINETWORKNATDNSCONFIG; 105 107 106 108 #include <list> … … 437 439 HRESULT clearAllEncryptionPasswords(); 438 440 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); 440 443 Utf8Str VRDPServerErrorToMsg(int vrc); 441 444 -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r105605 r105726 4512 4512 4513 4513 4514 /* 4514 /** Helper that converts a BSTR safe array into a C-string array. */ 4515 static 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 /** 4515 4552 * IHostNameResolutionConfigurationChangeEvent 4516 4553 * … … 4520 4557 HRESULT Console::i_onNATDnsChanged() 4521 4558 { 4522 HRESULT hrc;4523 4524 4559 AutoCaller autoCaller(this); 4525 4560 AssertComRCReturnRC(autoCaller.hrc()); 4526 4561 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()); 4532 4601 if (FAILED(hrc)) 4533 4602 return S_OK; 4534 4603 4535 ComPtr<IHost> p Host;4536 hrc = p VirtualBox->COMGETTER(Host)(pHost.asOutParam());4604 ComPtr<IHost> ptrHost; 4605 hrc = ptrVirtualBox->COMGETTER(Host)(ptrHost.asOutParam()); 4537 4606 if (FAILED(hrc)) 4538 4607 return S_OK; 4539 4608 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()); 4561 4654 AssertComRCReturn(hrc, hrc); 4562 4655 4563 4656 ChipsetType_T enmChipsetType; 4564 hrc = p Platform->COMGETTER(ChipsetType)(&enmChipsetType);4657 hrc = ptrPlatform->COMGETTER(ChipsetType)(&enmChipsetType); 4565 4658 AssertComRCReturn(hrc, hrc); 4566 4659 … … 4570 4663 ULONG const ulInstanceMax = PlatformProperties::s_getMaxNetworkAdapters(enmChipsetType); 4571 4664 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); 4575 4668 } 4576 4669 … … 4579 4672 4580 4673 4581 /* 4674 /** 4582 4675 * This routine walks over all network device instances, checking if 4583 4676 * device instance has DrvNAT attachment and triggering DrvNAT DNS 4584 4677 * change callback. 4585 4678 */ 4586 void Console::notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax) 4679 void Console::notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax, 4680 PCPDMINETWORKNATDNSCONFIG pDnsConfig) 4587 4681 { 4588 4682 Log(("notifyNatDnsChange: looking for DrvNAT attachment on %s device instances\n", pszDevice)); … … 4600 4694 pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID); 4601 4695 if (pNetNatCfg && pNetNatCfg->pfnNotifyDnsChanged) 4602 pNetNatCfg->pfnNotifyDnsChanged(pNetNatCfg );4696 pNetNatCfg->pfnNotifyDnsChanged(pNetNatCfg, pDnsConfig); 4603 4697 } 4604 4698 } -
trunk/src/libs/libslirp-4.8.0/src/libslirp.h
r105533 r105726 351 351 const char *slirp_version_string(void); 352 352 353 #ifdef VBOX 354 char *slirp_set_vdomainname(Slirp *, char const *); 355 char *slirp_get_vdomainname(Slirp *); 356 int slirp_set_vdnssearch(Slirp *, const char * const *); 357 #endif 358 353 359 #ifdef __cplusplus 354 360 } /* extern "C" */ -
trunk/src/libs/libslirp-4.8.0/src/slirp.c
r105533 r105726 1653 1653 } 1654 1654 } 1655 1656 #ifdef VBOX 1657 1658 char *slirp_set_vdomainname(Slirp *pSlirp, const char *vdomainname) 1659 { 1660 pSlirp->vdomainname = g_strdup(vdomainname); 1661 return pSlirp->vdomainname; 1662 } 1663 1664 char *slirp_get_vdomainname(Slirp *pSlirp) 1665 { 1666 return pSlirp->vdomainname; 1667 } 1668 1669 int 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.