Changeset 57600 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Sep 2, 2015 4:42:05 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 102461
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r57442 r57600 575 575 PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_NETWORK); 576 576 577 578 RTREQQUEUE hQueue = pThis->hSlirpReqQueue; 579 580 rc = RTReqQueueCallEx(hQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 577 rc = RTReqQueueCallEx(pThis->hSlirpReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, 578 RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 581 579 (PFNRT)drvNATSendWorker, 2, pThis, pSgBuf); 582 580 if (RT_SUCCESS(rc)) … … 667 665 LogFlow(("drvNATNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); 668 666 669 /* Don't queue new requests when the NAT thread is about to stop.670 * But the VM could also be paused. So memorize the desired state. */667 /* Don't queue new requests if the NAT thread is not running (e.g. paused, 668 * stopping), otherwise we would deadlock. Memorize the change. */ 671 669 if (pThis->pSlirpThread->enmState != PDMTHREADSTATE_RUNNING) 672 670 { … … 678 676 int rc = RTReqQueueCallEx(pThis->hSlirpReqQueue, &pReq, 0 /*cMillies*/, RTREQFLAGS_VOID, 679 677 (PFNRT)drvNATNotifyLinkChangedWorker, 2, pThis, enmLinkState); 680 if ( RT_LIKELY(rc == VERR_TIMEOUT))678 if (rc == VERR_TIMEOUT) 681 679 { 682 680 drvNATNotifyNATThread(pThis, "drvNATNetworkUp_NotifyLinkChanged"); … … 714 712 } 715 713 716 static DECLCALLBACK(int) drvNATNetworkNatConfig _RedirectRuleCommand(PPDMINETWORKNATCONFIG pInterface, bool fRemove,717 bool fUdp, const char *pHostIp,718 uint16_t u16HostPort,const char *pGuestIp, uint16_t u16GuestPort)714 static DECLCALLBACK(int) drvNATNetworkNatConfigRedirect(PPDMINETWORKNATCONFIG pInterface, bool fRemove, 715 bool fUdp, const char *pHostIp, uint16_t u16HostPort, 716 const char *pGuestIp, uint16_t u16GuestPort) 719 717 { 720 718 LogFlowFunc(("fRemove=%d, fUdp=%d, pHostIp=%s, u16HostPort=%u, pGuestIp=%s, u16GuestPort=%u\n", 721 RT_BOOL(fRemove), RT_BOOL(fUdp), pHostIp, u16HostPort, pGuestIp, 722 u16GuestPort)); 719 RT_BOOL(fRemove), RT_BOOL(fUdp), pHostIp, u16HostPort, pGuestIp, u16GuestPort)); 723 720 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg); 724 PRTREQ pReq; 725 int rc = RTReqQueueCallEx(pThis->hSlirpReqQueue, &pReq, 0 /*cMillies*/, RTREQFLAGS_VOID, 721 /* Execute the command directly if the VM is not running. */ 722 int rc; 723 if (pThis->pSlirpThread->enmState != PDMTHREADSTATE_RUNNING) 724 { 725 drvNATNotifyApplyPortForwardCommand(pThis, fRemove, fUdp, pHostIp, 726 u16HostPort, pGuestIp,u16GuestPort); 727 rc = VINF_SUCCESS; 728 } 729 else 730 { 731 PRTREQ pReq; 732 rc = RTReqQueueCallEx(pThis->hSlirpReqQueue, &pReq, 0 /*cMillies*/, RTREQFLAGS_VOID, 726 733 (PFNRT)drvNATNotifyApplyPortForwardCommand, 7, pThis, fRemove, 727 734 fUdp, pHostIp, u16HostPort, pGuestIp, u16GuestPort); 728 if (RT_LIKELY(rc == VERR_TIMEOUT))729 {730 drvNATNotifyNATThread(pThis, "drvNATNetworkNatConfig_RedirectRuleCommand");731 rc = RTReqWait(pReq, RT_INDEFINITE_WAIT);732 AssertRC(rc);733 }734 else735 AssertRC(rc);736 737 RTReqRelease(pReq);738 port_forwarding_done:735 if (rc == VERR_TIMEOUT) 736 { 737 drvNATNotifyNATThread(pThis, "drvNATNetworkNatConfigRedirect"); 738 rc = RTReqWait(pReq, RT_INDEFINITE_WAIT); 739 AssertRC(rc); 740 } 741 else 742 AssertRC(rc); 743 744 RTReqRelease(pReq); 745 } 739 746 return rc; 740 747 } … … 1143 1150 switch (strategy) 1144 1151 { 1145 1146 1152 case VBOX_NAT_DNS_DNSPROXY: 1147 { 1148 /** 1149 * XXX: Here or in _strategy_selector we should deal with network change 1150 * in "network change" scenario domain name change we have to update guest lease 1151 * forcibly. 1152 * Note at that built-in dhcp also updates DNS information on NAT thread. 1153 */ 1154 /** 1155 * It's unsafe to to do it directly on non-NAT thread 1156 * so we schedule the worker and kick the NAT thread. 1157 */ 1158 RTREQQUEUE hQueue = pThis->hSlirpReqQueue; 1159 1160 int rc = RTReqQueueCallEx(hQueue, NULL /*ppReq*/, 0 /*cMillies*/, 1161 RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 1162 (PFNRT)drvNATReinitializeHostNameResolving, 1, pThis); 1163 if (RT_SUCCESS(rc)) 1164 drvNATNotifyNATThread(pThis, "drvNATUpdateDNS"); 1165 1166 return; 1167 } 1153 { 1154 /** 1155 * XXX: Here or in _strategy_selector we should deal with network change 1156 * in "network change" scenario domain name change we have to update guest lease 1157 * forcibly. 1158 * Note at that built-in dhcp also updates DNS information on NAT thread. 1159 */ 1160 /** 1161 * It's unsafe to to do it directly on non-NAT thread 1162 * so we schedule the worker and kick the NAT thread. 1163 */ 1164 int rc = RTReqQueueCallEx(pThis->hSlirpReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, 1165 RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 1166 (PFNRT)drvNATReinitializeHostNameResolving, 1, pThis); 1167 if (RT_SUCCESS(rc)) 1168 drvNATNotifyNATThread(pThis, "drvNATUpdateDNS"); 1169 1170 return; 1171 } 1168 1172 1169 1173 case VBOX_NAT_DNS_EXTERNAL: … … 1172 1176 * Disconnect the guest from the network temporarily to let it pick up the changes. 1173 1177 */ 1174 1175 1178 if (fFlapLink) 1176 1179 pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig, … … 1421 1424 1422 1425 /* NAT engine configuration */ 1423 pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfig _RedirectRuleCommand;1426 pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfigRedirect; 1424 1427 #if HAVE_NOTIFICATION_FOR_DNS_UPDATE && !defined(RT_OS_DARWIN) 1425 1428 /*
Note:
See TracChangeset
for help on using the changeset viewer.