Changeset 105070 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jun 27, 2024 9:48:17 PM (7 months ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNATlibslirp.cpp
r105069 r105070 77 77 78 78 /** 79 * @callback_method_impl{FNPDMTHREADDRV}80 */81 static DECLCALLBACK(int) drvNATUrgRecv(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)82 {83 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);84 85 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)86 return VINF_SUCCESS;87 88 while (pThread->enmState == PDMTHREADSTATE_RUNNING)89 {90 RTReqQueueProcess(pThis->hUrgRecvReqQueue, 0);91 if (ASMAtomicReadU32(&pThis->cUrgPkts) == 0)92 {93 int rc = RTSemEventWait(pThis->EventUrgRecv, RT_INDEFINITE_WAIT);94 AssertRC(rc);95 }96 }97 return VINF_SUCCESS;98 }99 100 /**101 * @callback_method_impl{FNPDMTHREADWAKEUPDRV}102 */103 static DECLCALLBACK(int) drvNATUrgRecvWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)104 {105 RT_NOREF(pThread);106 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);107 int rc = RTSemEventSignal(pThis->EventUrgRecv);108 AssertRC(rc);109 110 return VINF_SUCCESS;111 }112 113 /**114 79 * @brief Processes incoming packet (to guest). 115 80 * … … 124 89 int rc; 125 90 STAM_PROFILE_START(&pThis->StatNATRecv, a); 126 127 while (ASMAtomicReadU32(&pThis->cUrgPkts) != 0)128 {129 rc = RTSemEventWait(pThis->EventRecv, RT_INDEFINITE_WAIT);130 if ( RT_FAILURE(rc)131 && ( rc == VERR_TIMEOUT132 || rc == VERR_INTERRUPTED))133 goto done_unlocked;134 }135 91 136 92 rc = RTCritSectEnter(&pThis->DevAccessLock); … … 156 112 rc = RTCritSectLeave(&pThis->DevAccessLock); 157 113 AssertRC(rc); 158 159 done_unlocked:160 114 ASMAtomicDecU32(&pThis->cPkts); 161 162 115 drvNATNotifyNATThread(pThis, "drvNATRecvWorker"); 163 164 RTMemFree(pBuf);165 pBuf = NULL;166 167 116 STAM_PROFILE_STOP(&pThis->StatNATRecv, a); 168 117 } … … 426 375 size_t cbIgnored; 427 376 rc = RTPipeWrite(pThis->hPipeWrite, "", 1, &cbIgnored); 428 #else429 /* kick WSAWaitForMultipleEvents */430 rc = WSASetEvent(pThis->hWakeupEvent);431 377 #endif 432 378 AssertRC(rc); … … 628 574 * @thread ? 629 575 */ 630 static int get_revents_cb(int idx, void *opaque)576 static int drvNAT_getREventsCb(int idx, void *opaque) 631 577 { 632 578 PDRVNAT pThis = (PDRVNAT)opaque; … … 706 652 707 653 708 slirp_pollfds_poll(pThis->pNATState->pSlirp, cChangedFDs < 0, get_revents_cb /* SlirpGetREventsCb */, pThis /* opaque */);654 slirp_pollfds_poll(pThis->pNATState->pSlirp, cChangedFDs < 0, drvNAT_getREventsCb /* SlirpGetREventsCb */, pThis /* opaque */); 709 655 if (pThis->pNATState->polls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND)) 710 656 { … … 751 697 { 752 698 /* only check for slow/fast timers */ 753 slirp_pollfds_poll(pThis->pNATState->pSlirp, false /*select error*/, get_revents_cb /* SlirpGetREventsCb */, pThis /* opaque */);699 slirp_pollfds_poll(pThis->pNATState->pSlirp, false /*select error*/, drvNAT_getREventsCb /* SlirpGetREventsCb */, pThis /* opaque */); 754 700 RTReqQueueProcess(pThis->hSlirpReqQueue, 0); 755 701 continue; … … 757 703 /* poll the sockets in any case */ 758 704 Log2(("%s: poll\n", __FUNCTION__)); 759 slirp_pollfds_poll(pThis->pNATState->pSlirp, cChangedFDs < 0 /*select error*/, get_revents_cb /* SlirpGetREventsCb */, pThis /* opaque */);705 slirp_pollfds_poll(pThis->pNATState->pSlirp, cChangedFDs < 0 /*select error*/, drvNAT_getREventsCb /* SlirpGetREventsCb */, pThis /* opaque */); 760 706 761 707 /* process _all_ outstanding requests but don't wait */ … … 831 777 * 832 778 * @returns VBox status code. 779 * @param uInstance ? 780 * @param pThis ? 833 781 * @param pCfg The configuration handle. 782 * @param pNetwork Unused. 783 * 784 * @thread ? 834 785 */ 835 786 static int drvNATConstructRedir(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pCfg, PRTNETADDRIPV4 pNetwork) 836 787 { 788 /** @todo r=jack: rewrite to support IPv6? */ 837 789 PPDMDRVINS pDrvIns = pThis->pDrvIns; 838 790 PCPDMDRVHLPR3 pHlp = pDrvIns->pHlpR3; … … 914 866 } 915 867 868 /** 869 * Applies port forwarding between guest and host. 870 * 871 * @param pThis Pointer to DRVNAT state for current context. 872 * @param fRemove Flag to remove port forward instead of create. 873 * @param fUdp Flag specifying if UDP. If false, TCP. 874 * @param pHostIp String of host IP address. 875 * @param u16HostPort Host port to forward to. 876 * @param pGuestIp String of guest IP address. 877 * @param u16GuestPort Guest port to forward. 878 * 879 * @thread ? 880 */ 916 881 static DECLCALLBACK(void) drvNATNotifyApplyPortForwardCommand(PDRVNAT pThis, bool fRemove, 917 882 bool fUdp, const char *pHostIp, 918 883 uint16_t u16HostPort, const char *pGuestIp, uint16_t u16GuestPort) 919 884 { 885 /** @todo r=jack: 886 * - rewrite for IPv6 887 * - do we want to lock the guestIp to the VMs IP? 888 */ 920 889 struct in_addr guestIp, hostIp; 921 890 … … 970 939 } 971 940 941 /** 942 * Update the timeout field in given list of Slirp timers. 943 * 944 * @param uTimeout Pointer to timeout value. 945 * @param opaque Pointer to NAT State context. 946 * 947 * @thread ? 948 */ 972 949 static void slirpUpdateTimeout(uint32_t *uTimeout, void *opaque) 973 950 { … … 994 971 } 995 972 973 /** 974 * Check if timeout has passed in given list of Slirp timers. 975 * 976 * @param opaque Pointer to NAT State context. 977 * 978 * @thread ? 979 */ 996 980 static void slirpCheckTimeout(void *opaque) 997 981 { … … 1019 1003 /** 1020 1004 * CALLBACKS 1005 */ 1006 1007 /** 1008 * Callback called by libslirp to send packet into guest. 1009 * 1010 * @param pBuf Pointer to packet buffer. 1011 * @param cb Size of packet. 1012 * @param opaque Pointer to NAT State context. 1013 * 1014 * @returns Size of packet received or -1 on error. 1015 * 1016 * @thread ? 1021 1017 */ 1022 1018 static DECLCALLBACK(ssize_t) slirpSendPacketCb(const void *pBuf, size_t cb, void *opaque /* PDRVNAT */) … … 1046 1042 } 1047 1043 1044 /** 1045 * Callback called by libslirp on an error from a guest. 1046 * 1047 * @param pMsg Error message string. 1048 * @param opaque Pointer to NAT State context. 1049 * 1050 * @thread ? 1051 */ 1048 1052 static DECLCALLBACK(void) slirpGuestErrorCb(const char *pMsg, void *opaque) 1049 1053 { … … 1056 1060 } 1057 1061 1062 /** 1063 * Callback called by libslirp to get the current timestamp in nanoseconds. 1064 * 1065 * @param opaque Pointer to NAT State context. 1066 * 1067 * @returns 64-bit signed integer representing time in nanoseconds. 1068 */ 1058 1069 static DECLCALLBACK(int64_t) slirpClockGetNsCb(void *opaque) 1059 1070 { … … 1064 1075 } 1065 1076 1077 1078 /** 1079 * Callback called by slirp to create a new timer and insert it into the given list. 1080 * 1081 * @param slirpTimeCb Callback function supplied to the new timer upon timer expiry. 1082 * Called later by the timeout handler. 1083 * @param cb_opaque Opaque object supplied to slirpTimeCb when called. Should be 1084 * Identical to the opaque parameter. 1085 * @param opaque Pointer to NAT State context. 1086 * 1087 * @returns Pointer to new timer. 1088 */ 1066 1089 static DECLCALLBACK(void *) slirpTimerNewCb(SlirpTimerCb slirpTimeCb, void *cb_opaque, void *opaque) 1067 1090 { … … 1082 1105 } 1083 1106 1107 /** 1108 * Callback called by slirp to free a timer. 1109 * 1110 * @param pTimer Pointer to slirpTimer object to be freed. 1111 * @param opaque Pointer to NAT State context. 1112 */ 1084 1113 static DECLCALLBACK(void) slirpTimerFreeCb(void *pTimer, void *opaque) 1085 1114 { … … 1101 1130 } 1102 1131 1132 /** 1133 * Callback called by slirp to modify a timer. 1134 * 1135 * @param pTimer Pointer to slirpTimer object to be modified. 1136 * @param expireTime Signed 64-bit integer representing the new expiry time. 1137 * @param opaque Pointer to NAT State context. 1138 */ 1103 1139 static DECLCALLBACK(void) slirpTimerModCb(void *pTimer, int64_t expireTime, void *opaque) 1104 1140 { … … 1109 1145 } 1110 1146 1147 /** 1148 * Callback called by slirp when there is I/O that needs to happen. 1149 * 1150 * @param opaque Pointer to NAT State context. 1151 */ 1111 1152 static DECLCALLBACK(void) slirpNotifyCb(void *opaque) 1112 1153 { … … 1144 1185 pThis->hSlirpReqQueue = NIL_RTREQQUEUE; 1145 1186 1146 RTReqQueueDestroy(pThis->hUrgRecvReqQueue);1147 pThis->hUrgRecvReqQueue = NIL_RTREQQUEUE;1148 1149 1187 RTReqQueueDestroy(pThis->hRecvReqQueue); 1150 1188 pThis->hRecvReqQueue = NIL_RTREQQUEUE; … … 1152 1190 RTSemEventDestroy(pThis->EventRecv); 1153 1191 pThis->EventRecv = NIL_RTSEMEVENT; 1154 1155 RTSemEventDestroy(pThis->EventUrgRecv);1156 pThis->EventUrgRecv = NIL_RTSEMEVENT;1157 1192 1158 1193 if (RTCritSectIsInitialized(&pThis->DevAccessLock)) … … 1165 1200 RTPipeClose(pThis->hPipeRead); 1166 1201 RTPipeClose(pThis->hPipeWrite); 1167 #endif1168 1169 #ifdef RT_OS_DARWIN1170 /* Cleanup the DNS watcher. */1171 if (pThis->hRunLoopSrcDnsWatcher != NULL)1172 {1173 CFRunLoopRef hRunLoopMain = CFRunLoopGetMain();1174 CFRetain(hRunLoopMain);1175 CFRunLoopRemoveSource(hRunLoopMain, pThis->hRunLoopSrcDnsWatcher, kCFRunLoopCommonModes);1176 CFRelease(hRunLoopMain);1177 CFRelease(pThis->hRunLoopSrcDnsWatcher);1178 pThis->hRunLoopSrcDnsWatcher = NULL;1179 }1180 1202 #endif 1181 1203 } … … 1202 1224 pThis->pNATState = (SlirpState *)RTMemAlloc(sizeof(SlirpState)); 1203 1225 if(pThis->pNATState == NULL) 1204 {1205 1226 return VERR_NO_MEMORY; 1206 }1207 1227 else 1208 1228 { … … 1213 1233 } 1214 1234 pThis->hSlirpReqQueue = NIL_RTREQQUEUE; 1215 pThis->hUrgRecvReqQueue = NIL_RTREQQUEUE;1216 1235 pThis->EventRecv = NIL_RTSEMEVENT; 1217 pThis->EventUrgRecv = NIL_RTSEMEVENT;1218 #ifdef RT_OS_DARWIN1219 pThis->hRunLoopSrcDnsWatcher = NULL;1220 #endif1221 1236 1222 1237 /* IBase */ … … 1367 1382 pSlirpCfg->if_mtu = MTU; 1368 1383 1369 #ifndef RT_OS_WINDOWS1370 1384 inet_pton(AF_INET6, "fd00::3", &pSlirpCfg->vnameserver6); 1371 #else1372 inet_pton(23, "fd00::3", &pSlirpCfg->vnameserver6);1373 #endif1374 1385 1375 1386 pSlirpCfg->vdnssearch = NULL; … … 1397 1408 pThis->pNATState->pSlirp = pSlirp; 1398 1409 1399 // pThis->pNATState->polls = NULL;1400 1401 1410 rc = drvNATConstructRedir(pDrvIns->iInstance, pThis, pCfg, &Network); 1402 1411 AssertLogRelRCReturn(rc, rc); … … 1409 1418 1410 1419 rc = RTReqQueueCreate(&pThis->hRecvReqQueue); 1411 AssertLogRelRCReturn(rc, rc);1412 1413 rc = RTReqQueueCreate(&pThis->hUrgRecvReqQueue);1414 1420 AssertLogRelRCReturn(rc, rc); 1415 1421 … … 1419 1425 1420 1426 rc = RTSemEventCreate(&pThis->EventRecv); 1421 AssertRCReturn(rc, rc);1422 1423 rc = RTSemEventCreate(&pThis->EventUrgRecv);1424 AssertRCReturn(rc, rc);1425 1426 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pUrgRecvThread, pThis, drvNATUrgRecv,1427 drvNATUrgRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATURGRX");1428 1427 AssertRCReturn(rc, rc); 1429 1428 … … 1445 1444 1446 1445 #ifndef RT_OS_WINDOWS 1447 /* 1448 1449 1446 /** 1447 * Create the control pipe. 1448 */ 1450 1449 rc = RTPipeCreate(&pThis->hPipeRead, &pThis->hPipeWrite, 0 /*fFlags*/); 1451 1450 AssertRCReturn(rc, rc); 1452 #else1453 pThis->hWakeupEvent = CreateEvent(NULL, FALSE, FALSE, NULL); /* auto-reset event */1454 pThis->pNATState->phEvents[VBOX_WAKEUP_EVENT_INDEX] = pThis->hWakeupEvent;1455 pThis->pNATState->phEvents[VBOX_SOCKET_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);1456 1451 #endif 1457 1452 -
trunk/src/VBox/Devices/Network/DrvNATlibslirp.h
r105069 r105070 103 103 #define VBOX_NAT_DELAY_HACK 104 104 105 /*106 * ICMP handle state change107 */108 # define VBOX_ICMP_EVENT_INDEX -1109 110 /**111 * This event is for112 * - slirp_input113 * - slirp_link_up114 * - slirp_link_down115 * - wakeup116 */117 # define VBOX_WAKEUP_EVENT_INDEX 0118 119 /*120 * UDP/TCP socket state change (socket ready to receive, to send, ...)121 */122 # define VBOX_SOCKET_EVENT_INDEX 1123 124 /*125 * The number of events for WSAWaitForMultipleEvents().126 */127 # define VBOX_EVENT_COUNT 2128 129 105 #define GET_EXTRADATA(pdrvins, node, name, rc, type, type_name, var) \ 130 106 do { \ … … 179 155 } while (0) 180 156 181 / / timer struct157 /** Slirp Timer */ 182 158 typedef struct slirpTimer { 183 159 struct slirpTimer *next; … … 193 169 { 194 170 unsigned int nsock; 195 # ifndef RT_OS_WINDOWS196 /* counter of sockets needed for allocation enough room to197 * process sockets with poll/epoll198 *199 * NSOCK_INC/DEC should be injected before every200 * operation on socket queue (tcb, udb)201 */202 # define NSOCK_INC() do {pData->nsock++;} while (0)203 # define NSOCK_DEC() do {pData->nsock--;} while (0)204 # define NSOCK_INC_EX(ex) do {ex->pData->nsock++;} while (0)205 # define NSOCK_DEC_EX(ex) do {ex->pData->nsock--;} while (0)206 # else207 # define NSOCK_INC() do {} while (0)208 # define NSOCK_DEC() do {} while (0)209 # define NSOCK_INC_EX(ex) do {} while (0)210 # define NSOCK_DEC_EX(ex) do {} while (0)211 # endif212 213 #if defined(RT_OS_WINDOWS)214 # define VBOX_SOCKET_EVENT (pData->phEvents[VBOX_SOCKET_EVENT_INDEX])215 HANDLE phEvents[VBOX_EVENT_COUNT];216 #endif217 171 218 172 Slirp *pSlirp; 219 173 struct pollfd *polls; 220 174 221 / / Num Polls (not bytes)175 /** Num Polls (not bytes) */ 222 176 unsigned int uPollCap = 0; 223 177 … … 280 234 /** thread delivering packets for receiving by the guest */ 281 235 PPDMTHREAD pRecvThread; 282 /** thread delivering urg packets for receiving by the guest */283 PPDMTHREAD pUrgRecvThread;284 236 /** event to wakeup the guest receive thread */ 285 237 RTSEMEVENT EventRecv; 286 /** event to wakeup the guest urgent receive thread */287 RTSEMEVENT EventUrgRecv;288 238 /** Receive Req queue (deliver packets to the guest) */ 289 239 RTREQQUEUE hRecvReqQueue; 290 /** Receive Urgent Req queue (deliver packets to the guest). */291 RTREQQUEUE hUrgRecvReqQueue;292 240 293 241 /** makes access to device func RecvAvail and Recv atomical. */ 294 242 RTCRITSECT DevAccessLock; 295 /** Number of in-flight urgent packets. */ 296 volatile uint32_t cUrgPkts; 297 /** Number of in-flight regular packets. */ 243 /** Number of in-flight packets. */ 298 244 volatile uint32_t cPkts; 299 245 … … 306 252 #endif /* !VBOX_INCLUDED_SRC_Network_DrvNATlibslirp_h */ 307 253 } DRVNAT; 308 //AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8);254 AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8); 309 255 /** Pointer to the NAT driver instance data. */ 310 256 typedef DRVNAT *PDRVNAT; … … 312 258 static DECLCALLBACK(int) drvNATRecv(PPDMDRVINS, PPDMTHREAD); 313 259 static DECLCALLBACK(int) drvNATRecvWakeup(PPDMDRVINS, PPDMTHREAD); 314 static DECLCALLBACK(int) drvNATUrgRecvWakeup(PPDMDRVINS, PPDMTHREAD);315 260 static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT, void *, int); 316 261 static void drvNATFreeSgBuf(PDRVNAT, PPDMSCATTERGATHER);
Note:
See TracChangeset
for help on using the changeset viewer.