Changeset 13984 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 9, 2008 3:41:27 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r13967 r13984 28 28 #define __STDC_LIMIT_MACROS 29 29 #define __STDC_CONSTANT_MACROS 30 #ifndef VBOX_NAT_SOURCES 30 31 #include "Network/slirp/libslirp.h" 32 #else 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 36 #include <netinet/in.h> 37 38 #include <errno.h> 39 40 #include <unistd.h> 41 42 #include <fcntl.h> 43 44 #include <string.h> 45 46 #endif 31 47 #include <VBox/pdmdrv.h> 32 48 #include <iprt/assert.h> … … 38 54 #include "Builtins.h" 39 55 40 #ifdef VBOX_WITH_SYNC_SLIRP 41 #include <unistd.h> /* should be in UNix version only*/ 42 #include <iprt/semaphore.h> 56 #ifdef VBOX_NAT_SOURCES 57 #include "Network/nat/nat.h" 58 #endif 59 #ifdef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 60 #include <unistd.h> 43 61 #include <errno.h> 62 #include<iprt/semaphore.h> 44 63 #endif 45 64 … … 61 80 /** Pointer to the driver instance. */ 62 81 PPDMDRVINS pDrvIns; 82 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 63 83 /** Slirp critical section. */ 64 84 RTCRITSECT CritSect; 85 #endif 65 86 /** Link state */ 66 87 PDMNETWORKLINKSTATE enmLinkState; 67 88 /** NAT state for this instance. */ 89 #ifndef VBOX_NAT_SOURCES 68 90 PNATState pNATState; 91 #endif 69 92 /** TFTP directory prefix. */ 70 93 char *pszTFTPPrefix; 71 94 /** Boot file name to provide in the DHCP server response. */ 72 95 char *pszBootFile; 73 #ifdef VBOX_WITH_S YNC_SLIRP96 #ifdef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 74 97 /*polling thread*/ 75 98 PPDMTHREAD pThread; 76 99 /*used for wakep of poling thread*/ 77 RTSEMEVENT semIOmutex;78 PTMTIMER pNATFastTimer;79 PTMTIMER pNATSlowTimer; 100 RTSEMEVENT semIOmutex; 101 RTSEMEVENT semSndMutex; 102 #ifndef RT_OS_WINDOWS 80 103 /** The write end of the control pipe. */ 81 104 RTFILE PipeWrite; 82 105 /** The read end of the control pipe. */ 83 106 RTFILE PipeRead; 107 #else 108 #endif 109 char cBuffer[1600]; 110 size_t sBufferSize; 84 111 #endif 85 112 } DRVNAT, *PDRVNAT; … … 105 132 106 133 134 #ifdef VBOX_NAT_SOURCES 135 /* 136 * Sends data to guest called from NAT glue code 137 */ 138 static DECLCALLBACK(void) drvNATOutput(const void * data, const uint8_t *msg, int size) 139 { 140 PDRVNAT pThis = (PDRVNAT)(void *)data; 141 LogFlow(("output: pvBuf=%p cb=%#x\n", msg, size)); 142 int rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, 0); 143 if (RT_SUCCESS(rc)) 144 pThis->pPort->pfnReceive(pThis->pPort, msg, size); 145 LogFlow(("output: exit\n")); 146 } 147 148 #endif 149 107 150 /** 108 151 * Send data to the network. … … 120 163 LogFlow(("drvNATSend: pvBuf=%p cb=%#x\n", pvBuf, cb)); 121 164 Log2(("drvNATSend: pvBuf=%p cb=%#x\n" 122 "%.* Rhxd\n",165 "%.*Vhxd\n", 123 166 pvBuf, cb, cb, pvBuf)); 124 167 125 #ifndef VBOX_WITH_S YNC_SLIRP168 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 126 169 int rc = RTCritSectEnter(&pThis->CritSect); 127 170 AssertReleaseRC(rc); 128 #endif 129 171 #else 172 /*notify select to wakeup*/ 173 memcpy(pThis->cBuffer,pvBuf, cb); 174 pThis->sBufferSize = cb; 175 int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL); 176 AssertRC(rc); 177 RTSemEventWait(pThis->semSndMutex, RT_INDEFINITE_WAIT); 178 #endif 179 180 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 130 181 Assert(pThis->enmLinkState == PDMNETWORKLINKSTATE_UP); 131 182 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) { 183 #ifndef VBOX_NAT_SOURCES 132 184 slirp_input(pThis->pNATState, (uint8_t *)pvBuf, cb); 185 #else 186 ether_chk(pThis, pvBuf, cb); 187 #endif 133 188 } 134 #ifndef VBOX_WITH_SYNC_SLIRP135 189 RTCritSectLeave(&pThis->CritSect); 136 #else137 int ndfds = 0;138 fd_set writefds;139 FD_ZERO(&writefds);140 slirp_send_fill(pThis->pNATState, &ndfds, &writefds);141 struct timeval tv = {0,0}; /* no wait */142 143 int cWriteFDs = select(ndfds + 1, NULL, &writefds, NULL, &tv);144 if (cWriteFDs >= 0)145 slirp_send_trigger(pThis->pNATState, &ndfds, &writefds);146 190 #endif 147 191 LogFlow(("drvNATSend: end\n")); … … 180 224 LogFlow(("drvNATNotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); 181 225 182 #ifndef VBOX_WITH_S YNC_SLIRP226 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 183 227 int rc = RTCritSectEnter(&pThis->CritSect); 184 228 AssertReleaseRC(rc); … … 190 234 case PDMNETWORKLINKSTATE_UP: 191 235 LogRel(("NAT: link up\n")); 236 #ifndef VBOX_NAT_SOURCES 192 237 slirp_link_up(pThis->pNATState); 238 #endif 193 239 break; 194 240 … … 196 242 case PDMNETWORKLINKSTATE_DOWN_RESUME: 197 243 LogRel(("NAT: link down\n")); 244 #ifndef VBOX_NAT_SOURCES 198 245 slirp_link_down(pThis->pNATState); 246 #endif 199 247 break; 200 248 … … 202 250 AssertMsgFailed(("drvNATNotifyLinkChanged: unexpected link state %d\n", enmLinkState)); 203 251 } 204 #ifndef VBOX_WITH_S YNC_SLIRP252 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 205 253 RTCritSectLeave(&pThis->CritSect); 206 254 #endif … … 208 256 209 257 258 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 210 259 /** 211 260 * Poller callback. 212 261 */ 213 #ifndef VBOX_WITH_SYNC_SLIRP214 262 static DECLCALLBACK(void) drvNATPoller(PPDMDRVINS pDrvIns) 215 263 { … … 226 274 AssertReleaseRC(rc); 227 275 276 #ifndef VBOX_NAT_SOURCES 228 277 slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 278 #else 279 nat_select_fill(NULL, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 280 #endif 229 281 230 282 struct timeval tv = {0, 0}; /* no wait */ 231 283 int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv); 284 #ifndef VBOX_NAT_SOURCES 232 285 if (cReadFDs >= 0) 233 286 slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs); 287 #else 288 if (cReadFDs >= 0) { 289 nat_select_poll(pThis, &ReadFDs, &WriteFDs, &XcptFDs); 290 } 291 #endif 234 292 235 293 RTCritSectLeave(&pThis->CritSect); 236 294 } 237 295 #else 238 239 static DECLCALLBACK(void) drvNATFastTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer)240 {241 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);242 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP)243 slirp_fasttmr(pThis->pNATState);244 TMTimerSetMicro(pTimer, 2);245 }246 247 static DECLCALLBACK(void) drvNATSlowTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer)248 {249 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);250 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP)251 slirp_slowtmr(pThis->pNATState);252 TMTimerSetMicro(pTimer, 500);253 }254 296 255 297 static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) … … 263 305 264 306 LogFlow(("drvNATAsyncIoThread: pThis=%p\n", pThis)); 307 265 308 266 309 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) … … 276 319 cFDs = -1; 277 320 321 /* 322 * To prevent concurent execution of sending/receving threads 323 */ 278 324 slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 279 325 280 struct timeval tv = { 1, 0}; /* nowait */326 struct timeval tv = {0, 200}; /* 2 millis wait */ 281 327 282 328 FD_SET(pThis->PipeRead, &ReadFDs); /*Linux only*/ 283 329 cFDs = (pThis->PipeRead < cFDs ? cFDs:pThis->PipeRead); 284 int cReadFDs = select(cFDs + 1, &ReadFDs, NULL, &XcptFDs, &tv);330 int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv); 285 331 286 332 if (cReadFDs >= 0) { … … 292 338 size_t cbRead; 293 339 RTFileRead(pThis->PipeRead, &ch, 1, &cbRead); 340 slirp_input(pThis->pNATState, (uint8_t *)pThis->cBuffer, pThis->sBufferSize); 341 RTSemEventSignal(pThis->semSndMutex); 294 342 } 295 343 } … … 304 352 return VINF_SUCCESS; 305 353 } 354 306 355 /** 307 356 * Unblock the send thread so it can respond to a state change. … … 321 370 } 322 371 323 /*Callback from slirp to exit from select*/ 324 void slirp_socket_created(void* pvUser) 325 { 326 PDRVNAT pThis = (PDRVNAT)pvUser; 327 int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL); 328 AssertRC(rc); 329 } 330 #endif 331 372 #endif 373 374 #ifndef VBOX_NAT_SOURCES 332 375 /** 333 376 * Function called by slirp to check if it's possible to feed incoming data to the network port. … … 341 384 Assert(pThis); 342 385 343 #ifndef VBOX_WITH_S YNC_SLIRP386 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 344 387 /** Happens during termination */ 345 388 if (!RTCritSectIsOwner(&pThis->CritSect)) … … 361 404 LogFlow(("slirp_output BEGIN %x %d\n", pu8Buf, cb)); 362 405 Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n" 363 "%.* Rhxd\n",406 "%.*Vhxd\n", 364 407 pu8Buf, cb, pThis, 365 408 cb, pu8Buf)); … … 367 410 Assert(pThis); 368 411 369 #ifndef VBOX_WITH_S YNC_SLIRP412 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 370 413 /** Happens during termination */ 371 414 if (!RTCritSectIsOwner(&pThis->CritSect)) … … 377 420 LogFlow(("slirp_output END %x %d\n", pu8Buf, cb)); 378 421 } 422 #endif 379 423 380 424 /** … … 417 461 LogFlow(("drvNATDestruct:\n")); 418 462 463 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 419 464 int rc = RTCritSectEnter(&pThis->CritSect); 420 465 AssertReleaseRC(rc); 466 #endif 467 #ifndef VBOX_NAT_SOURCES 421 468 slirp_term(pThis->pNATState); 422 469 pThis->pNATState = NULL; 470 #endif 471 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 423 472 RTCritSectLeave(&pThis->CritSect); 424 473 425 474 RTCritSectDelete(&pThis->CritSect); 475 #else 476 RTSemEventDestroy(pThis->semSndMutex); 477 #endif 426 478 } 427 479 … … 435 487 static int drvNATConstructRedir(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pCfgHandle, RTIPV4ADDR Network) 436 488 { 489 #ifndef VBOX_NAT_SOURCES 437 490 /* 438 491 * Enumerate redirections. … … 501 554 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_SETUP, RT_SRC_POS, N_("NAT#%d: configuration error: failed to set up redirection of %d to %s:%d. Probably a conflict with existing services or other rules"), iInstance, iHostPort, szGuestIP, iGuestPort); 502 555 } /* for each redir rule */ 556 #endif 503 557 504 558 return VINF_SUCCESS; … … 510 564 static void drvNATSetMac(PDRVNAT pThis) 511 565 { 566 #ifndef VBOX_NAT_SOURCES 512 567 if (pThis->pConfig) 513 568 { … … 516 571 slirp_set_ethaddr(pThis->pNATState, Mac.au8); 517 572 } 573 #endif 518 574 } 519 575 … … 569 625 */ 570 626 pThis->pDrvIns = pDrvIns; 627 #ifndef VBOX_NAT_SOURCES 571 628 pThis->pNATState = NULL; 629 #endif 572 630 pThis->pszTFTPPrefix = NULL; 573 631 pThis->pszBootFile = NULL; … … 627 685 * The slirp lock.. 628 686 */ 687 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 629 688 rc = RTCritSectInit(&pThis->CritSect); 630 689 if (RT_FAILURE(rc)) 631 690 return rc; 691 #endif 632 692 #if 0 633 693 rc = RTSemEventCreate(&g_EventSem); … … 642 702 { 643 703 #endif 704 #ifndef VBOX_NAT_SOURCES 644 705 /* 645 706 * Initialize slirp. … … 659 720 NULL, NULL, NULL, NULL, NULL, drvNATLoadDone); 660 721 AssertRC(rc2); 661 #ifndef VBOX_WITH_S YNC_SLIRP722 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 662 723 pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvNATPoller); 663 724 #else 725 664 726 rc = RTSemEventCreate(&pThis->semIOmutex); 727 AssertReleaseRC(rc); 728 rc = RTSemEventCreate(&pThis->semSndMutex); 665 729 AssertReleaseRC(rc); 666 730 … … 681 745 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT"); 682 746 AssertReleaseRC(rc); 683 rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_REAL, drvNATFastTimer, "NAT_fast_timer", &pThis->pNATFastTimer);684 AssertReleaseRC(rc);685 TMTimerSetMicro(pThis->pNATFastTimer, 1);686 rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_REAL, drvNATSlowTimer, "NAT_slow_timer", &pThis->pNATSlowTimer);687 AssertReleaseRC(rc);688 TMTimerSetMicro(pThis->pNATSlowTimer, 500);689 747 #endif 690 748 … … 707 765 AssertMsgFailed(("Add error message for rc=%d (%Rrc)\n", rc, rc)); 708 766 } 767 #else 768 pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvNATPoller); 769 pThis->enmLinkState = PDMNETWORKLINKSTATE_UP; 770 struct nat_output_callbacks cb; 771 cb.noc_guest_out = drvNATOutput; 772 nat_init(&cb, pDrvIns); 773 #endif 709 774 #if 0 710 775 g_fThreadTerm = true; … … 716 781 } 717 782 #endif 783 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 718 784 RTCritSectDelete(&pThis->CritSect); 785 #endif 719 786 return rc; 720 787 } -
trunk/src/VBox/Devices/Network/slirp/debug.c
r13840 r13984 23 23 dump_packet(void *dat, int n) 24 24 { 25 Log(("nat: PACKET DUMPED:\n%.* Rhxd\n", n, dat));25 Log(("nat: PACKET DUMPED:\n%.*Vhxd\n", n, dat)); 26 26 } 27 27 #endif -
trunk/src/VBox/Devices/Network/slirp/if.c
r13958 r13984 48 48 if_comp = IF_AUTOCOMP; 49 49 if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; 50 51 VBOX_SLIRP_LOCK_CREATE(&pData->if_fastq_mutex);52 53 50 if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; 54 55 VBOX_SLIRP_LOCK_CREATE(&pData->if_batchq_mutex);56 57 51 /* sl_compress_init(&comp_s); */ 58 52 next_m = &if_batchq; … … 155 149 { 156 150 struct mbuf *ifq; 157 #ifdef VBOX_WITH_SYNC_SLIRP158 struct mbuf *ifqprev;159 #endif160 151 int on_fastq = 1; 161 152 … … 164 155 DEBUG_ARG("ifm = %lx", (long)ifm); 165 156 166 167 157 /* 168 158 * First remove the mbuf from m_usedlist, … … 170 160 * XXX Shouldn't need this, gotta change dtom() etc. 171 161 */ 172 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex);173 174 162 if (ifm->m_flags & M_USEDLIST) { 175 163 remque(pData, ifm); 176 164 ifm->m_flags &= ~M_USEDLIST; 177 165 } 178 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex);179 166 180 167 /* … … 185 172 * XXX add cache here? 186 173 */ 187 VBOX_SLIRP_LOCK(pData->if_batchq_mutex);188 #ifndef VBOX_WITH_SYNC_SLIRP189 174 for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { 190 #else 191 ifq = if_batchq.ifq_prev; 192 while(1){ 193 if (ifq == &if_batchq) { 194 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex); 195 break; 196 } 197 ifqprev = ifq->ifq_prev; 198 #endif 199 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex); 200 if (so == ifq->ifq_so) { 175 if (so == ifq->ifq_so) { 201 176 /* A match! */ 202 177 ifm->ifq_so = so; 203 178 ifs_insque(ifm, ifq->ifs_prev); 204 179 goto diddit; 205 } 206 VBOX_SLIRP_LOCK(pData->if_batchq_mutex); 207 #ifdef VBOX_WITH_SYNC_SLIRP 208 ifq = ifqprev; 209 #endif 180 } 210 181 } 211 182 212 183 /* No match, check which queue to put it on */ 213 184 if (so && (so->so_iptos & IPTOS_LOWDELAY)) { 214 VBOX_SLIRP_LOCK(pData->if_fastq_mutex);215 185 ifq = if_fastq.ifq_prev; 216 VBOX_SLIRP_UNLOCK(pData->if_fastq_mutex);217 186 on_fastq = 1; 218 187 /* … … 225 194 goto diddit; 226 195 } 227 } 228 else { 229 VBOX_SLIRP_LOCK(pData->if_batchq_mutex); 196 } else 230 197 ifq = if_batchq.ifq_prev; 231 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex);232 }233 198 234 199 /* Create a new doubly linked list for this session */ … … 238 203 239 204 diddit: 240 VBOX_SLIRP_LOCK(pData->if_queued_mutex);241 242 205 ++if_queued; 243 244 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex);245 206 246 207 if (so) { … … 258 219 (so->so_nqueued - so->so_queued) >= 3)) { 259 220 260 VBOX_SLIRP_LOCK(pData->if_fastq_mutex);261 221 /* Remove from current queue... */ 262 222 remque(pData, ifm->ifs_next); 263 223 264 VBOX_SLIRP_UNLOCK(pData->if_fastq_mutex);265 VBOX_SLIRP_LOCK(pData->if_batchq_mutex);266 267 224 /* ...And insert in the new. That'll teach ya! */ 268 225 insque(pData, ifm->ifs_next, &if_batchq); 269 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex);270 226 } 271 227 } … … 298 254 { 299 255 struct mbuf *ifm, *ifqt; 300 #ifdef VBOX_WITH_SYNC_SLIRP301 int on_fast = 0; /*required for correctness */302 struct mbuf *ifm_prev;303 #endif304 256 305 257 DEBUG_CALL("if_start"); 306 258 307 VBOX_SLIRP_LOCK(pData->if_queued_mutex); 308 if (if_queued <= 0) { 309 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex); 259 if (if_queued == 0) 310 260 return; /* Nothing to do */ 311 }312 261 313 262 again: 314 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex);315 316 263 /* check if we can really output */ 317 264 if (!slirp_can_output(pData->pvUser)) … … 322 269 * If there's something in the fastq, select it immediately 323 270 */ 324 VBOX_SLIRP_LOCK(pData->if_fastq_mutex);325 271 if (if_fastq.ifq_next != &if_fastq) { 326 272 ifm = if_fastq.ifq_next; 327 #ifdef VBOX_WITH_SYNC_SLIRP328 on_fast = 1;329 #endif330 VBOX_SLIRP_UNLOCK(pData->if_fastq_mutex);331 273 } else { 332 VBOX_SLIRP_UNLOCK(pData->if_fastq_mutex);333 334 VBOX_SLIRP_LOCK(pData->if_batchq_mutex);335 VBOX_SLIRP_LOCK(pData->next_m_mutex);336 274 /* Nothing on fastq, see if next_m is valid */ 337 275 if (next_m != &if_batchq) … … 342 280 /* Set which packet to send on next iteration */ 343 281 next_m = ifm->ifq_next; 344 VBOX_SLIRP_UNLOCK(pData->next_m_mutex); 345 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex); 346 } 347 VBOX_SLIRP_LOCK(pData->if_queued_mutex); 348 #ifdef VBOX_WITH_SYNC_SLIRP 349 if (if_queued == 0) { 350 if (on_fast) { 351 VBOX_SLIRP_LOCK(pData->if_fastq_mutex); 352 }else { 353 VBOX_SLIRP_LOCK(pData->if_batchq_mutex); 354 } 355 goto done; 356 } 357 #endif 282 } 358 283 /* Remove it from the queue */ 359 284 ifqt = ifm->ifq_prev; 360 #ifdef VBOX_WITH_SYNC_SLIRP 361 if (ifm->m_prev != ifm && ifm->m_prev != NULL) 362 #endif 363 remque(pData, ifm); 364 285 remque(pData, ifm); 365 286 --if_queued; 366 #ifdef VBOX_WITH_SYNC_SLIRP367 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex);368 if (on_fast == 1) {369 VBOX_SLIRP_UNLOCK(pData->if_fastq_mutex);370 }371 else {372 VBOX_SLIRP_UNLOCK(pData->if_batchq_mutex);373 }374 #endif375 287 376 288 /* If there are more packets for this session, re-queue them */ 377 if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm 378 #ifdef VBOX_WITH_SYNC_SLIRP 379 && ifm->ifs_next != NULL 380 #endif 381 ) { 289 if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { 382 290 insque(pData, ifm->ifs_next, ifqt); 383 291 ifs_remque(ifm); … … 396 304 m_free(pData, ifm); 397 305 398 VBOX_SLIRP_LOCK(pData->if_queued_mutex); 399 /*We release if_queued_mutex after again label and before return*/ 400 401 if (if_queued > 0) 306 if (if_queued) 402 307 goto again; 403 done: 404 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex); 405 } 308 } -
trunk/src/VBox/Devices/Network/slirp/ip_input.c
r13783 r13984 69 69 register struct ip *ip; 70 70 int hlen; 71 #ifdef VBOX_WITH_SYNC_SLIRP72 int rc;73 #endif74 71 75 72 DEBUG_CALL("ip_input"); 76 73 DEBUG_ARG("m = %lx", (long)m); 77 74 DEBUG_ARG("m_len = %d", m->m_len); 78 79 75 80 76 ipstat.ips_total++; … … 194 190 ipstat.ips_fragments++; 195 191 ip = ip_reass(pData, (struct ipasfrag *)ip, fp); 196 if (ip == 0) { 197 return; 198 } 192 if (ip == 0) 193 return; 199 194 ipstat.ips_reassembled++; 200 195 m = dtom(pData, ip); -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r13951 r13984 49 49 int guest_port); 50 50 51 #ifdef VBOX_WITH_SYNC_SLIRP 52 void slirp_fasttmr(PNATState pData); 53 void slirp_slowtmr(PNATState pData); 54 /*selects open and ready sockets for write*/ 55 void slirp_send_fill(PNATState pData, int *pnfds, fd_set *writeds); 56 /*triggers socket output */ 57 void slirp_send_trigger(PNATState pData, int *pnfds, fd_set *writeds); 58 /*should be implemented by client*/ 59 void slirp_socket_created(void* pvUser); 60 #endif 51 61 52 #ifdef __cplusplus 62 53 } -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r13951 r13984 25 25 m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; 26 26 mbuf_alloced = 0; 27 28 VBOX_SLIRP_LOCK_CREATE(&pData->m_usedlist_mutex);29 VBOX_SLIRP_LOCK_CREATE(&pData->m_freelist_mutex);30 VBOX_SLIRP_LOCK_CREATE(&pData->mbuf_alloced_mutex);31 32 27 msize_init(pData); 33 28 } … … 57 52 register struct mbuf *m; 58 53 int flags = 0; 59 #ifdef VBOX_WITH_SYNC_SLIRP60 int on_free_list = 0;61 struct mbuf *n;62 #endif63 54 64 55 DEBUG_CALL("m_get"); 65 66 VBOX_SLIRP_LOCK(pData->m_freelist_mutex);67 56 68 57 if (m_freelist.m_next == &m_freelist) { 69 58 m = (struct mbuf *)malloc(msize); 70 if (m == NULL) { 71 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex); 72 goto end_error; 73 } 74 75 VBOX_SLIRP_LOCK(pData->mbuf_alloced_mutex); 76 59 if (m == NULL) goto end_error; 77 60 mbuf_alloced++; 78 61 if (mbuf_alloced > mbuf_thresh) … … 80 63 if (mbuf_alloced > mbuf_max) 81 64 mbuf_max = mbuf_alloced; 82 VBOX_SLIRP_UNLOCK(pData->mbuf_alloced_mutex);83 VBOX_SLIRP_LOCK_CREATE(&m->m_mutex);84 VBOX_SLIRP_LOCK(m->m_mutex);85 65 } else { 86 66 m = m_freelist.m_next; 87 VBOX_SLIRP_LOCK(m->m_mutex);88 #ifdef VBOX_WITH_SYNC_SLIRP89 n = m->m_next;90 if (n != NULL)91 VBOX_SLIRP_LOCK(n->m_mutex);92 67 remque(pData, m); 93 if (n != NULL) 94 VBOX_SLIRP_UNLOCK(n->m_mutex); 95 #else 96 remque(pData, m); 97 #endif 98 } 99 100 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex); 101 102 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex); 68 } 69 103 70 /* Insert it in the used list */ 104 #ifdef VBOX_WITH_SYNC_SLIRP105 n = m_usedlist.m_next;106 if (n != &m_usedlist)107 VBOX_SLIRP_LOCK(n->m_mutex);108 #endif109 71 insque(pData, m,&m_usedlist); 110 #ifdef VBOX_WITH_SYNC_SLIRP111 if (n != &m_usedlist)112 VBOX_SLIRP_LOCK(n->m_mutex);113 #endif114 VBOX_SLIRP_UNLOCK(m->m_mutex);115 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex);116 117 72 m->m_flags = (flags | M_USEDLIST); 118 73 … … 123 78 m->m_nextpkt = 0; 124 79 m->m_prevpkt = 0; 125 126 80 end_error: 127 81 DEBUG_ARG("m = %lx", (long )m); … … 132 86 m_free(PNATState pData, struct mbuf *m) 133 87 { 134 #ifdef VBOX_WITH_SYNC_SLIRP135 struct mbuf *p, *n;136 #endif137 88 138 89 DEBUG_CALL("m_free"); … … 141 92 if(m) { 142 93 /* Remove from m_usedlist */ 143 if (m->m_flags & M_USEDLIST) { 144 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex); 145 #ifdef VBOX_WITH_SYNC_SLIRP 146 p = (m->m_prev); 147 n = (m->m_next); 148 VBOX_SLIRP_LOCK(m->m_mutex); 149 if (n != NULL) 150 VBOX_SLIRP_LOCK(n->m_mutex); 151 if (p != NULL) 152 VBOX_SLIRP_LOCK(p->m_mutex); 153 #endif 94 if (m->m_flags & M_USEDLIST) 154 95 remque(pData, m); 155 #ifdef VBOX_WITH_SYNC_SLIRP156 if (n != NULL)157 VBOX_SLIRP_UNLOCK(n->m_mutex);158 if (p != NULL)159 VBOX_SLIRP_UNLOCK(p->m_mutex);160 #endif161 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex);162 }163 96 164 97 /* If it's M_EXT, free() it */ … … 171 104 if (m->m_flags & M_DOFREE) { 172 105 u32ptr_done(pData, ptr_to_u32(pData, m), m); 173 VBOX_SLIRP_UNLOCK(m->m_mutex);174 VBOX_SLIRP_LOCK_DESTROY(m->m_mutex);175 106 free(m); 176 #ifdef VBOX_WITH_SYNC_SLIRP177 m = NULL;178 #endif179 VBOX_SLIRP_LOCK(pData->mbuf_alloced_mutex);180 107 mbuf_alloced--; 181 VBOX_SLIRP_UNLOCK(pData->mbuf_alloced_mutex);182 108 } else if ((m->m_flags & M_FREELIST) == 0) { 183 VBOX_SLIRP_LOCK(pData->m_freelist_mutex);184 109 insque(pData, m,&m_freelist); 185 110 m->m_flags = M_FREELIST; /* Clobber other flags */ 186 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex);187 111 } 188 112 } /* if(m) */ … … 200 124 * If there's no room, realloc 201 125 */ 202 203 126 if (M_FREEROOM(m) < n->m_len) 204 127 m_inc(m,m->m_size+MINCSIZE); … … 208 131 209 132 m_free(pData, n); 210 211 133 } 212 134 … … 221 143 222 144 /* some compiles throw up on gotos. This one we can fake. */ 223 if(m->m_size>size) { 224 return; 225 } 145 if(m->m_size>size) return; 226 146 227 147 if (m->m_flags & M_EXT) { … … 247 167 248 168 m->m_size = size; 169 249 170 } 250 171 … … 278 199 int off, len; 279 200 { 280 if (len > M_FREEROOM(n)) {201 if (len > M_FREEROOM(n)) 281 202 return -1; 282 }283 203 284 204 memcpy((n->m_data + n->m_len), (m->m_data + off), len); … … 302 222 303 223 /* bug corrected for M_EXT buffers */ 304 #ifndef VBOX_WITH_SYNC_SLIRP305 224 for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) { 306 #else307 struct mbuf *mnext;308 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex);309 m = m_usedlist.m_next;310 while(1) {311 mnext = m->m_next;312 #endif313 225 if (m->m_flags & M_EXT) { 314 if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) {226 if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) 315 227 return m; 316 }317 228 } else { 318 if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) {229 if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) 319 230 return m; 320 }321 231 } 322 #ifdef VBOX_WITH_SYNC_SLIRP323 m = mnext;324 #endif325 232 } 326 233 -
trunk/src/VBox/Devices/Network/slirp/mbuf.h
r13951 r13984 37 37 #ifndef _MBUF_H_ 38 38 #define _MBUF_H_ 39 #ifdef VBOX_WITH_SYNC_SLIRP40 #include <iprt/semaphore.h>41 #endif42 39 43 40 #define m_freem m_free … … 76 73 caddr_t mh_data; /* Location of data */ 77 74 int mh_len; /* Amount of data in this mbuf */ 78 #ifdef VBOX_WITH_SYNC_SLIRP79 RTSEMFASTMUTEX mh_mutex;80 #endif81 75 }; 82 76 … … 114 108 #define m_ext M_dat.m_ext_ 115 109 #define m_so m_hdr.mh_so 116 #ifdef VBOX_WITH_SYNC_SLIRP117 #define m_mutex m_hdr.mh_mutex118 #endif119 110 120 111 #define ifq_prev m_prev -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r13955 r13984 6 6 #include <VBox/err.h> 7 7 #include <iprt/assert.h> 8 #ifdef VBOX_WITH_SYNC_SLIRP9 #include <iprt/semaphore.h>10 #endif11 8 12 9 static const uint8_t special_ethaddr[6] = { … … 227 224 #endif 228 225 229 VBOX_SLIRP_LOCK_CREATE(&pData->tcb_mutex);230 VBOX_SLIRP_LOCK_CREATE(&pData->tcp_last_so_mutex);231 VBOX_SLIRP_LOCK_CREATE(&pData->udb_mutex);232 VBOX_SLIRP_LOCK_CREATE(&pData->udp_last_so_mutex);233 VBOX_SLIRP_LOCK_CREATE(&pData->if_queued_mutex);234 VBOX_SLIRP_LOCK_CREATE(&pData->next_m_mutex);235 236 226 Assert(sizeof(struct ip) == 20); 237 227 link_up = 1; … … 362 352 * First, TCP sockets 363 353 */ 364 #ifndef VBOX_WITH_SYNC_SLIRP365 354 do_slowtimo = 0; 366 #endif367 355 if (link_up) { 368 356 /* … … 370 358 * in the fragment queue, or there are TCP connections active 371 359 */ 372 VBOX_SLIRP_LOCK(pData->tcb_mutex);373 #ifndef VBOX_WITH_SYNC_SLIRP374 360 do_slowtimo = ((tcb.so_next != &tcb) || 375 361 ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *))); 376 #endif 377 378 so = tcb.so_next; 379 #ifndef VBOX_WITH_SYNC_SLIRP 362 380 363 for (so = tcb.so_next; so != &tcb; so = so_next) { 381 #else 382 while (1) { 383 tcp_loop_begin: 384 if (so == &tcb) { 385 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 386 break; 387 } 388 #endif 389 so_next = so->so_next; 390 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 364 so_next = so->so_next; 391 365 392 366 /* 393 367 * See if we need a tcp_fasttimo 394 368 */ 395 #ifndef VBOX_WITH_SYNC_SLIRP 396 if (time_fasttimo == 0 397 && so->so_tcpcb 398 && so->so_tcpcb->t_flags & TF_DELACK) 369 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) 399 370 time_fasttimo = curtime; /* Flag when we want a fasttimo */ 400 #endif401 371 402 372 /* … … 405 375 */ 406 376 if (so->so_state & SS_NOFDREF || so->s == -1) 407 goto before_loop_ends;377 continue; 408 378 409 379 /* … … 413 383 FD_SET(so->s, readfds); 414 384 UPD_NFDS(so->s); 415 goto before_loop_ends;385 continue; 416 386 } 417 #ifndef VBOX_WITH_SYNC_SLIRP 387 418 388 /* 419 389 * Set for writing sockets which are connecting … … 422 392 FD_SET(so->s, writefds); 423 393 UPD_NFDS(so->s); 424 goto before_loop_ends;394 continue; 425 395 } 426 396 … … 433 403 UPD_NFDS(so->s); 434 404 } 435 #endif436 405 437 406 /* … … 444 413 UPD_NFDS(so->s); 445 414 } 446 before_loop_ends:447 /*Release of global tcb mutex happens in the head of loop*/448 VBOX_SLIRP_LOCK(pData->tcb_mutex);449 #ifdef VBOX_WITH_SYNC_SLIRP450 so = so_next;451 #endif452 415 } 453 416 … … 455 418 * UDP sockets 456 419 */ 457 VBOX_SLIRP_LOCK(pData->udb_mutex);458 so = udb.so_next;459 #ifndef VBOX_WITH_SYNC_SLIRP460 420 for (so = udb.so_next; so != &udb; so = so_next) { 461 #else 462 while(1) { 463 if (so == &udb) { 464 VBOX_SLIRP_UNLOCK(pData->udb_mutex); 465 break; 466 } 467 #endif 468 so_next = so->so_next; 469 VBOX_SLIRP_UNLOCK(pData->udb_mutex); 421 so_next = so->so_next; 470 422 471 423 /* 472 424 * See if it's timed out 473 425 */ 474 #ifndef VBOX_WITH_SYNC_SLIRP475 426 if (so->so_expire) { 476 427 if (so->so_expire <= curtime) { 477 428 udp_detach(pData, so); 478 goto before_udp_loop_end;429 continue; 479 430 } else 480 431 do_slowtimo = 1; /* Let socket expire */ 481 432 } 482 #endif483 433 484 434 /* … … 496 446 UPD_NFDS(so->s); 497 447 } 498 before_udp_loop_end:499 VBOX_SLIRP_LOCK(pData->udb_mutex);500 #ifdef VBOX_WITH_SYNC_SLIRP501 so = so_next;502 #endif503 448 } 504 449 } … … 508 453 */ 509 454 510 #ifndef VBOX_WITH_SYNC_SLIRP511 455 /* 512 456 * First, see the timeout needed by *timo … … 538 482 } 539 483 } 540 #endif541 484 *pnfds = nfds; 542 485 } … … 553 496 * See if anything has timed out 554 497 */ 555 #ifndef VBOX_WITH_SYNC_SLIRP556 498 if (link_up) { 557 499 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) { … … 565 507 } 566 508 } 567 #endif568 509 569 510 /* … … 574 515 * Check TCP sockets 575 516 */ 576 VBOX_SLIRP_LOCK(pData->tcb_mutex);577 so = tcb.so_next;578 #ifndef VBOX_WITH_SYNC_SLIRP579 517 for (so = tcb.so_next; so != &tcb; so = so_next) { 580 #else 581 while (1) { 582 loop_begin: 583 if (so == &tcb) { 584 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 585 break; 586 } 587 #endif 588 so_next = so->so_next; 589 590 591 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 518 so_next = so->so_next; 592 519 593 520 /* … … 596 523 */ 597 524 if (so->so_state & SS_NOFDREF || so->s == -1) 598 goto before_loop_ends;525 continue; 599 526 600 527 /* … … 614 541 if (so->so_state & SS_FACCEPTCONN) { 615 542 tcp_connect(pData, so); 616 goto before_loop_ends;543 continue; 617 544 } /* else */ 618 545 ret = soread(pData, so); … … 623 550 } 624 551 625 #ifndef VBOX_WITH_SYNC_SLIRP626 552 /* 627 553 * Check sockets for writing … … 647 573 if (errno == EAGAIN || errno == EWOULDBLOCK || 648 574 errno == EINPROGRESS || errno == ENOTCONN) 649 goto before_loop_ends;575 continue; 650 576 651 577 /* else failed */ … … 669 595 */ 670 596 } 671 #endif672 597 673 598 /* … … 683 608 if (errno == EAGAIN || errno == EWOULDBLOCK || 684 609 errno == EINPROGRESS || errno == ENOTCONN) 685 goto before_loop_ends;/* Still connecting, continue */610 continue; /* Still connecting, continue */ 686 611 687 612 /* else failed */ … … 695 620 if (errno == EAGAIN || errno == EWOULDBLOCK || 696 621 errno == EINPROGRESS || errno == ENOTCONN) 697 goto before_loop_ends;622 continue; 698 623 /* else failed */ 699 624 so->so_state = SS_NOFDREF; … … 704 629 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so); 705 630 } /* SS_ISFCONNECTING */ 706 #endif707 before_loop_ends:708 VBOX_SLIRP_LOCK(pData->tcb_mutex);709 #ifdef VBOX_WITH_SYNC_SLIRP710 so = so_next;711 631 #endif 712 632 } … … 717 637 * Incoming UDP data isn't buffered either. 718 638 */ 719 VBOX_SLIRP_LOCK(pData->udb_mutex);720 so = udb.so_next;721 #ifndef VBOX_WITH_SYNC_SLIRP722 639 for (so = udb.so_next; so != &udb; so = so_next) { 723 #else 724 while(1) { 725 if (so == &udb) { 726 VBOX_SLIRP_UNLOCK(pData->udb_mutex); 727 break; 728 } 729 #endif 730 so_next = so->so_next; 731 VBOX_SLIRP_UNLOCK(pData->udb_mutex); 640 so_next = so->so_next; 732 641 733 642 if (so->s != -1 && FD_ISSET(so->s, readfds)) { 734 643 sorecvfrom(pData, so); 735 644 } 736 VBOX_SLIRP_LOCK(pData->udb_mutex);737 #ifdef VBOX_WITH_SYNC_SLIRP738 so = so_next;739 #endif740 645 } 741 646 } … … 744 649 * See if we can start outputting 745 650 */ 746 #ifndef VBOX_WITH_SYNC_SLIRP747 651 if (if_queued && link_up) 748 652 if_start(pData); 749 #else750 #if 0751 if (link_up) {752 VBOX_SLIRP_LOCK(pData->if_queued_mutex);753 if (if_queued > 0){754 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex);755 if_start(pData);756 }757 else {758 VBOX_SLIRP_UNLOCK(pData->if_queued_mutex);759 }760 }761 #endif762 #endif763 653 } 764 654 … … 929 819 memcpy(client_ethaddr, ethaddr, ETH_ALEN); 930 820 } 931 932 #ifdef VBOX_WITH_SYNC_SLIRP933 void slirp_fasttmr(PNATState pData)934 {935 struct socket *so, *so_next;936 updtime(pData);937 time_fasttimo = 0;938 #if 1939 VBOX_SLIRP_LOCK(pData->tcb_mutex);940 so = tcb.so_next;941 while(1) {942 if (so == &tcb) {943 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);944 break;945 }946 so_next = so->so_next;947 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);948 if (time_fasttimo == 0949 && so->so_tcpcb950 && so->so_tcpcb->t_flags & TF_DELACK)951 time_fasttimo = curtime; /* Flag when we want a fasttimo */952 VBOX_SLIRP_LOCK(pData->tcb_mutex);953 so = so_next;954 }955 #endif956 if (time_fasttimo) {957 tcp_fasttimo(pData);958 time_fasttimo = 0;959 }960 }961 962 void slirp_slowtmr(PNATState pData)963 {964 struct socket *so, *so_next;965 updtime(pData);966 do_slowtimo = 0;967 #if 1968 VBOX_SLIRP_LOCK(pData->tcb_mutex);969 do_slowtimo = ((tcb.so_next != &tcb) ||970 ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *)));971 972 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);973 974 VBOX_SLIRP_LOCK(pData->udb_mutex);975 so = udb.so_next;976 while(1) {977 if (so == &udb) {978 VBOX_SLIRP_UNLOCK(pData->udb_mutex);979 break;980 }981 so_next = so->so_next;982 VBOX_SLIRP_UNLOCK(pData->udb_mutex);983 984 if (so->so_expire) {985 if (so->so_expire <= curtime) {986 udp_detach(pData, so);987 goto before_loop_ends;988 }989 do_slowtimo = 1;990 }991 before_loop_ends:992 VBOX_SLIRP_LOCK(pData->udb_mutex);993 so = so_next;994 }995 #endif996 if (do_slowtimo) {997 tcp_slowtimo(pData);998 ip_slowtimo(pData);999 last_slowtimo = curtime;1000 }1001 }1002 1003 /*selects open and ready sockets for write*/1004 void slirp_send_fill(PNATState pData, int *pnfds, fd_set *writefds)1005 {1006 struct socket *so, *so_next;1007 int nfds = *pnfds;1008 1009 if (link_up == 0) return;1010 1011 VBOX_SLIRP_LOCK(pData->tcb_mutex);1012 so = tcb.so_next;1013 while (1) {1014 if (so == &tcb) {1015 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);1016 break;1017 }1018 so_next = so->so_next;1019 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);1020 1021 if (so->so_state & SS_NOFDREF || so->s == -1)1022 goto before_loop_ends;1023 1024 if (so->so_state & SS_ISFCONNECTING) {1025 FD_SET(so->s, writefds);1026 UPD_NFDS(so->s);1027 goto before_loop_ends;1028 }1029 1030 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {1031 FD_SET(so->s, writefds);1032 UPD_NFDS(so->s);1033 }1034 1035 before_loop_ends:1036 VBOX_SLIRP_LOCK(pData->tcb_mutex);1037 so = so_next;1038 }1039 *pnfds = nfds;1040 }1041 /*triggers socket output */1042 void slirp_send_trigger(PNATState pData, int *pnfds, fd_set *writefds)1043 {1044 struct socket *so, *so_next;1045 int nfds = *pnfds;1046 int ret;1047 1048 if (link_up == 0) return;1049 1050 VBOX_SLIRP_LOCK(pData->tcb_mutex);1051 so = tcb.so_next;1052 while (1) {1053 if (so == &tcb) {1054 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);1055 break;1056 }1057 so_next = so->so_next;1058 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);1059 /*1060 * Check sockets for writing1061 */1062 if (FD_ISSET(so->s, writefds)) {1063 /*1064 * Check for non-blocking, still-connecting sockets1065 */1066 if (so->so_state & SS_ISFCONNECTING) {1067 /* Connected */1068 so->so_state &= ~SS_ISFCONNECTING;1069 1070 /*1071 * This should be probably guarded by PROBE_CONN too. Anyway,1072 * we disable it on OS/2 because the below send call returns1073 * EFAULT which causes the opened TCP socket to close right1074 * after it has been opened and connected.1075 */1076 #ifndef RT_OS_OS21077 ret = send(so->s, (const char *)&ret, 0, 0);1078 if (ret < 0) {1079 /* XXXXX Must fix, zero bytes is a NOP */1080 if (errno == EAGAIN || errno == EWOULDBLOCK ||1081 errno == EINPROGRESS || errno == ENOTCONN)1082 goto before_loop_ends;1083 1084 /* else failed */1085 so->so_state = SS_NOFDREF;1086 }1087 /* else so->so_state &= ~SS_ISFCONNECTING; */1088 #endif1089 1090 /*1091 * Continue tcp_input1092 */1093 tcp_input(pData, (struct mbuf *)NULL, sizeof(struct ip), so);1094 /* continue; */1095 } else1096 ret = sowrite(pData, so);1097 /*1098 * XXXXX If we wrote something (a lot), there1099 * could be a need for a window update.1100 * In the worst case, the remote will send1101 * a window probe to get things going again1102 */1103 }1104 1105 before_loop_ends:1106 VBOX_SLIRP_LOCK(pData->tcb_mutex);1107 so = so_next;1108 }1109 }1110 #endif -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r13771 r13984 384 384 #endif 385 385 386 #ifdef VBOX_WITH_SYNC_SLIRP 387 #define VBOX_SLIRP_LOCK_SUFFIX _mutex 388 389 #define VBOX_SLIRP_LOCK(x) \ 390 do{ \ 391 int rc; \ 392 rc = RTSemFastMutexRequest((x)); \ 393 AssertReleaseRC(rc); \ 394 }while (0) 395 396 #define VBOX_SLIRP_UNLOCK(x) \ 397 do{ \ 398 int rc; \ 399 rc = RTSemFastMutexRelease((x)); \ 400 AssertReleaseRC(rc); \ 401 }while (0) 402 403 #define VBOX_SLIRP_LOCK_CREATE(x) \ 404 do{ \ 405 int rc; \ 406 rc = RTSemFastMutexCreate((x)); \ 407 AssertReleaseRC(rc); \ 408 }while (0) 409 410 #define VBOX_SLIRP_LOCK_DESTROY(x) \ 411 do{ \ 412 int rc; \ 413 rc = RTSemFastMutexDestroy((x)); \ 414 AssertReleaseRC(rc); \ 415 }while (0) 416 #else 417 #define VBOX_SLIRP_LOCK(x) do {} while (0) 418 #define VBOX_SLIRP_UNLOCK(x) do {} while (0) 419 #define VBOX_SLIRP_LOCK_DESTROY(x) do {} while (0) 420 #define VBOX_SLIRP_LOCK_CREATE(x) do {} while (0) 421 #endif 422 423 #endif 386 #endif -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r13738 r13984 21 21 #ifndef _slirp_state_h_ 22 22 #define _slirp_state_h_ 23 #ifdef VBOX_WITH_SYNC_SLIRP24 #include <iprt/semaphore.h>25 #endif26 23 27 24 /** Number of DHCP clients supported by NAT. */ … … 64 61 int if_maxlinkhdr; 65 62 int if_queued; 66 #ifdef VBOX_WITH_SYNC_SLIRP67 /* mutex for accessing if_queued flag which used in if_start function and68 * and understanding that we need call if_start to send anything we have to69 * send.70 */71 RTSEMFASTMUTEX if_queued_mutex;72 #endif73 63 int if_thresh; 74 64 struct mbuf if_fastq; 75 #ifdef VBOX_WITH_SYNC_SLIRP76 /*77 * if_fastq_mutex prevent concurrent adding/removing mbufs on78 * fast queue (mbufs) from this queue are processed in first order79 */80 RTSEMFASTMUTEX if_fastq_mutex;81 #endif82 65 struct mbuf if_batchq; 83 #ifdef VBOX_WITH_SYNC_SLIRP84 /*85 * if_batchq_mutex prevent concurent adding/removing mbufs on86 * batch queue mbufs from this queue used if no mbufs on fast queue87 * and next_m doesn't point on mbuf scheduled to be processesed88 */89 RTSEMFASTMUTEX if_batchq_mutex;90 #endif91 66 struct mbuf *next_m; 92 #ifdef VBOX_WITH_SYNC_SLIRP93 /*94 * next_m_mutex prevent concurrent assigning/reading95 * from pointer next_m, used for pointing next mbuf to be processed96 * it readed if no messages are not in fast queue, usually it assigned with97 * mbuf from batch queue98 */99 RTSEMFASTMUTEX next_m_mutex;100 #endif101 67 /* Stuff from icmp.c */ 102 68 struct icmpstat_t icmpstat; … … 107 73 /* Stuff from mbuf.c */ 108 74 int mbuf_alloced, mbuf_max; 109 #ifdef VBOX_WITH_SYNC_SLIRP110 /*111 * mbuf_alloced_mutex used to prevent concurent access to mbuf_alloced counter112 * which ticks on every allocation and readed to check it against limits113 */114 RTSEMFASTMUTEX mbuf_alloced_mutex;115 #endif116 75 int msize; 117 76 struct mbuf m_freelist, m_usedlist; 118 #ifdef VBOX_WITH_SYNC_SLIRP119 /*120 * m_freelist_mutex and m_usedlist_mutex are used to prevent concurrent access and modifications121 * of corresponded queues controlling allocation/utilization of mbufs122 */123 RTSEMFASTMUTEX m_freelist_mutex;124 RTSEMFASTMUTEX m_usedlist_mutex;125 #endif126 77 /* Stuff from slirp.c */ 127 78 void *pvUser; … … 147 98 struct socket *tcp_last_so; 148 99 tcp_seq tcp_iss; 149 #ifdef VBOX_WITH_SYNC_SLIRP150 /*151 * tcp_last_so_mutex used for control access to tcp_last_so pointer152 */153 RTSEMFASTMUTEX tcp_last_so_mutex;154 /*155 * tcb_mutex used for control access to tcb queue of sockets156 * servising TCP connections157 */158 RTSEMFASTMUTEX tcb_mutex;159 #endif160 100 #if ARCH_BITS == 64 161 101 /* Stuff from tcp_subr.c */ … … 176 116 struct socket udb; 177 117 struct socket *udp_last_so; 178 #ifdef VBOX_WITH_SYNC_SLIRP179 /*180 * udb_mutex used in similar to tcb_mutex way, but for handling udp connections181 */182 RTSEMFASTMUTEX udb_mutex;183 /*184 * used for access udp_last_so global pointer avoiding overusing of udb_mutex.185 */186 RTSEMFASTMUTEX udp_last_so_mutex;187 #endif188 118 } NATState; 189 119 -
trunk/src/VBox/Devices/Network/slirp/socket.c
r13783 r13984 12 12 #ifdef __sun__ 13 13 #include <sys/filio.h> 14 #endif15 16 #ifdef VBOX_WITH_SYNC_SLIRP17 #include <iprt/semaphore.h>18 14 #endif 19 15 … … 74 70 sofree(PNATState pData, struct socket *so) 75 71 { 76 #ifndef VBOX_WITH_SYNC_SLIRP77 72 if (so->so_emu==EMU_RSH && so->extra) { 78 73 sofree(pData, so->extra); … … 88 83 if(so->so_next && so->so_prev) 89 84 remque(pData, so); /* crashes if so is not in a queue */ 90 #else 91 /*Take global mutexes of udb and tcb, because we dont know which is mutex */ 92 /*XXX: don't forget to set correct so_type in corresponded attach operation */ 93 if (so->so_emu==EMU_RSH && so->extra) { 94 sofree(pData, so->extra); 95 so->extra=NULL; 96 } 97 98 if (so->so_type == IPPROTO_UDP) { 99 VBOX_SLIRP_LOCK(pData->udp_last_so_mutex); 100 } 101 else if (so->so_type == IPPROTO_TCP) { 102 VBOX_SLIRP_LOCK(pData->tcp_last_so_mutex); 103 } 104 else { 105 Assert(!"unknown type"); 106 } 107 108 if (so == tcp_last_so) 109 tcp_last_so = &tcb; 110 else if (so == udp_last_so) 111 udp_last_so = &udb; 112 113 if(so->so_next && so->so_prev) { 114 remque(pData, so); /* crashes if so is not in a queue */ 115 } 116 117 if (so->so_type == IPPROTO_UDP) { 118 VBOX_SLIRP_UNLOCK(pData->udp_last_so_mutex); 119 } 120 else if (so->so_type == IPPROTO_TCP) { 121 VBOX_SLIRP_UNLOCK(pData->tcp_last_so_mutex); 122 } 123 else { 124 Assert(!"unknown type"); 125 } 126 /* socket's mutex could be released because socket none accessible via queue anymore*/ 127 128 m_free(pData, so->so_m); 129 free(so); 130 131 132 #endif 133 134 #ifndef VBOX_WITH_SYNC_SLIRP 85 135 86 free(so); 136 #endif137 87 } 138 88 … … 146 96 { 147 97 int n, nn, lss, total; 148 struct sbuf *sb ;149 int len;98 struct sbuf *sb = &so->so_snd; 99 int len = sb->sb_datalen - sb->sb_cc; 150 100 struct iovec iov[2]; 151 int mss; 152 sb = &so->so_snd; 153 len = sb->sb_datalen - sb->sb_cc; 154 mss = so->so_tcpcb->t_maxseg; 101 int mss = so->so_tcpcb->t_maxseg; 155 102 156 103 DEBUG_CALL("soread"); … … 212 159 #endif 213 160 if (nn <= 0) { 214 if (nn < 0 && (errno == EINTR || errno == EAGAIN)) {161 if (nn < 0 && (errno == EINTR || errno == EAGAIN)) 215 162 return 0; 216 }217 163 else { 218 164 DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); … … 261 207 sorecvoob(PNATState pData, struct socket *so) 262 208 { 263 struct tcpcb *tp; 264 tp = sototcpcb(so); 209 struct tcpcb *tp = sototcpcb(so); 265 210 266 211 DEBUG_CALL("sorecvoob"); … … 290 235 struct socket *so; 291 236 { 292 struct sbuf *sb ;237 struct sbuf *sb = &so->so_rcv; 293 238 char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ 294 239 295 240 int n, len; 296 297 sb = &so->so_rcv;298 241 299 242 DEBUG_CALL("sosendoob"); … … 351 294 { 352 295 int n,nn; 353 struct sbuf *sb ;354 int len ;296 struct sbuf *sb = &so->so_rcv; 297 int len = sb->sb_cc; 355 298 struct iovec iov[2]; 356 sb = &so->so_rcv;357 len = sb->sb_cc;358 299 359 300 DEBUG_CALL("sowrite"); … … 362 303 if (so->so_urgc) { 363 304 sosendoob(so); 364 if (sb->sb_cc == 0) {305 if (sb->sb_cc == 0) 365 306 return 0; 366 }367 307 } 368 308 … … 404 344 #endif 405 345 /* This should never happen, but people tell me it does *shrug* */ 406 if (nn < 0 && (errno == EAGAIN || errno == EINTR)) {346 if (nn < 0 && (errno == EAGAIN || errno == EINTR)) 407 347 return 0; 408 }409 348 410 349 if (nn <= 0) { … … 453 392 DEBUG_CALL("sorecvfrom"); 454 393 DEBUG_ARG("so = %lx", (long)so); 455 456 394 457 395 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ … … 604 542 ret = sendto(so->s, m->m_data, m->m_len, 0, 605 543 (struct sockaddr *)&addr, sizeof (struct sockaddr)); 606 if (ret < 0) {544 if (ret < 0) 607 545 return -1; 608 }609 546 610 547 /* … … 643 580 if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) { 644 581 free(so); 645 #ifdef VBOX_SLIRP_UNLOCK646 so = NULL;647 #endif648 582 return NULL; 649 583 } 650 651 VBOX_SLIRP_LOCK(pData->tcb_mutex);652 584 insque(pData, so,&tcb); 653 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);654 585 655 586 /* … … 696 627 697 628 so->s = s; 698 699 629 return so; 700 630 } -
trunk/src/VBox/Devices/Network/slirp/socket.h
r13783 r13984 10 10 #ifndef _SLIRP_SOCKET_H_ 11 11 #define _SLIRP_SOCKET_H_ 12 #ifdef VBOX_WITH_SYNC_SLIRP13 #include <iprt/semaphore.h>14 #endif15 12 16 13 #define SO_EXPIRE 240000 -
trunk/src/VBox/Devices/Network/slirp/tcp_input.c
r13783 r13984 246 246 DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", 247 247 (long )m, iphlen, (long )inso )); 248 #ifdef VBOX_WITH_SYNC_SLIRP249 #if 0250 #define return \251 do { \252 fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); \253 return; \254 }while(0)255 #endif256 #endif257 248 258 249 /* … … 365 356 */ 366 357 findso: 367 VBOX_SLIRP_LOCK(pData->tcp_last_so_mutex);368 358 so = tcp_last_so; 369 /* this checking for making sure that we're not trying to hold mutex on head list*/370 VBOX_SLIRP_UNLOCK(pData->tcp_last_so_mutex);371 372 359 if (so->so_fport != ti->ti_dport || 373 360 so->so_lport != ti->ti_sport || 374 361 so->so_laddr.s_addr != ti->ti_src.s_addr || 375 362 so->so_faddr.s_addr != ti->ti_dst.s_addr) { 376 /*To make sure that we don't try to release mutex on head of the socket queue*/377 363 so = solookup(&tcb, ti->ti_src, ti->ti_sport, 378 364 ti->ti_dst, ti->ti_dport); 379 if (so) { 380 VBOX_SLIRP_LOCK(pData->tcp_last_so_mutex); 365 if (so) 381 366 tcp_last_so = so; 382 VBOX_SLIRP_UNLOCK(pData->tcp_last_so_mutex);383 }384 367 ++tcpstat.tcps_socachemiss; 385 368 } … … 404 387 if ((so = socreate()) == NULL) 405 388 goto dropwithreset; 406 407 389 if (tcp_attach(pData, so) < 0) { 408 390 free(so); /* Not sofree (if it failed, it's not insqued) */ 409 #ifdef VBOX_WITH_SYNC_SLIRP410 so = NULL;411 #endif412 391 goto dropwithreset; 413 392 } … … 556 535 if (so->so_snd.sb_cc) 557 536 (void) tcp_output(pData, tp); 537 558 538 return; 559 539 } … … 1464 1444 (void) tcp_output(pData, tp); 1465 1445 } 1466 1467 1446 return; 1468 1447 … … 1496 1475 */ 1497 1476 m_free(pData, m); 1477 1498 1478 return; 1499 #ifdef VBOX_WITH_SYNC_SLIRP1500 #undef return1501 #endif1502 1479 } 1503 1480 -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r13951 r13984 276 276 */ 277 277 /* free(tp, M_PCB); */ 278 279 278 u32ptr_done(pData, ptr_to_u32(pData, tp), tp); 280 279 free(tp); 281 280 so->so_tcpcb = 0; 282 281 soisfdisconnected(so); 283 VBOX_SLIRP_LOCK(pData->tcp_last_so_mutex);284 282 /* clobber input socket cache if we're closing the cached connection */ 285 283 if (so == tcp_last_so) 286 284 tcp_last_so = &tcb; 287 VBOX_SLIRP_UNLOCK(pData->tcp_last_so_mutex);288 285 closesocket(so->s); 289 286 sbfree(&so->so_rcv); … … 529 526 tcp_attach(PNATState pData, struct socket *so) 530 527 { 531 if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) {528 if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) 532 529 return -1; 533 } 534 535 536 VBOX_SLIRP_LOCK(pData->tcb_mutex); 530 537 531 insque(pData, so, &tcb); 538 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);539 540 #ifdef VBOX_WITH_SYNC_SLIRP541 /*we use this field to identify cache socket to lock/unlock*/542 so->so_type = IPPROTO_TCP;543 slirp_socket_created(pData->pvUser);544 #endif545 532 546 533 return 0; -
trunk/src/VBox/Devices/Network/slirp/tcp_timer.c
r13957 r13984 49 49 DEBUG_CALL("tcp_fasttimo"); 50 50 51 VBOX_SLIRP_LOCK(pData->tcb_mutex);52 51 so = tcb.so_next; 53 #ifndef VBOX_WITH_SYNC_SLIRP54 52 if (so) 55 53 for (; so != &tcb; so = so->so_next) … … 61 59 (void) tcp_output(pData, tp); 62 60 } 63 #else /* VBOX_WITH_SYNC_SLIRP */64 while(1)65 {66 struct socket *so_next;67 if (so == &tcb || so == NULL)68 {69 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);70 break;71 }72 so_next = so->so_next;73 VBOX_SLIRP_UNLOCK(pData->tcb_mutex);74 if ( (tp = (struct tcpcb *)so->so_tcpcb)75 && (tp->t_flags & TF_DELACK))76 {77 tp->t_flags &= ~TF_DELACK;78 tp->t_flags |= TF_ACKNOW;79 tcpstat.tcps_delack++;80 (void) tcp_output(pData, tp);81 }82 VBOX_SLIRP_LOCK(pData->tcb_mutex);83 so = so_next;84 }85 #endif /* VBOX_WITH_SYNC_SLIRP */86 61 } 87 62 … … 103 78 * Search through tcb's and update active timers. 104 79 */ 105 #ifndef VBOX_WITH_SYNC_SLIRP106 80 ip = tcb.so_next; 107 81 if (ip == 0) … … 111 85 tp = sototcpcb(ip); 112 86 if (tp == 0) 113 87 continue; 114 88 for (i = 0; i < TCPT_NTIMERS; i++) { 115 89 if (tp->t_timer[i] && --tp->t_timer[i] == 0) { … … 125 99 ; 126 100 } 127 #else /* VBOX_WITH_SYNC_SLIRP */ 128 VBOX_SLIRP_LOCK(pData->tcb_mutex); 129 ip = tcb.so_next; 130 if (ip == NULL) 131 { 132 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 133 return; 134 } 135 while (1) 136 { 137 if (ip == &tcb) 138 { 139 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 140 break; 141 } 142 ipnxt = ip->so_next; 143 VBOX_SLIRP_UNLOCK(pData->tcb_mutex); 144 ipnxt = ip->so_next; 145 tp = sototcpcb(ip); 146 if (tp == 0) 147 goto tpgone; 148 for (i = 0; i < TCPT_NTIMERS; i++) 149 { 150 if (tp->t_timer[i] && --tp->t_timer[i] == 0) 151 { 152 tcp_timers(pData, tp,i); 153 if (ipnxt->so_prev != ip) 154 goto tpgone; 155 } 156 } 157 tp->t_idle++; 158 if (tp->t_rtt) 159 tp->t_rtt++; 160 tpgone: 161 VBOX_SLIRP_LOCK(pData->tcb_mutex); 162 ip = ipnxt; 163 } 164 #endif /* VBOX_WITH_SYNC_SLIRP */ 165 166 tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ 101 tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ 167 102 #ifdef TCP_COMPAT_42 168 103 if ((int)tcp_iss < 0) -
trunk/src/VBox/Devices/Network/slirp/udp.c
r13951 r13984 78 78 DEBUG_ARG("iphlen = %d", iphlen); 79 79 80 81 80 udpstat.udps_ipackets++; 82 81 … … 157 156 * Locate pcb for datagram. 158 157 */ 159 VBOX_SLIRP_LOCK(pData->udp_last_so_mutex); 160 so = udp_last_so; 161 162 VBOX_SLIRP_UNLOCK(pData->udp_last_so_mutex); 163 158 so = udp_last_so; 164 159 if (so->so_lport != uh->uh_sport || 165 160 so->so_laddr.s_addr != ip->ip_src.s_addr) { 166 161 struct socket *tmp; 167 #ifndef VBOX_WITH_SYNC_SLIRP 162 168 163 for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { 169 #else170 171 struct socket *tmp_next;172 VBOX_SLIRP_LOCK(pData->udb_mutex);173 tmp = udb.so_next;174 175 while (1) {176 if (tmp == &udb) {177 VBOX_SLIRP_UNLOCK(pData->udb_mutex);178 break; /* end of loop*/179 }180 VBOX_SLIRP_UNLOCK(pData->udb_mutex);181 tmp_next = tmp->so_next;182 #endif183 164 if (tmp->so_lport == uh->uh_sport && 184 165 tmp->so_laddr.s_addr == ip->ip_src.s_addr) { … … 186 167 break; 187 168 } 188 VBOX_SLIRP_LOCK(pData->udb_mutex);189 #ifdef VBOX_WITH_SYNC_SLIRP190 tmp = tmp_next;191 #endif192 169 } 193 170 if (tmp == &udb) { … … 195 172 } else { 196 173 udpstat.udpps_pcbcachemiss++; 197 VBOX_SLIRP_LOCK(pData->udp_last_so_mutex);198 174 udp_last_so = so; 199 VBOX_SLIRP_UNLOCK(pData->udp_last_so_mutex); 200 } 201 } 202 203 #ifndef VBOX_WITH_SYNC_SLIRP 175 } 176 } 177 204 178 if (so == NULL) { 205 #else206 if (so == NULL || so == &udb) {207 #endif208 179 /* 209 180 * If there's no socket for this packet, … … 321 292 322 293 error = ip_output(pData, so, m); 294 323 295 return (error); 324 296 } … … 328 300 { 329 301 struct sockaddr_in saddr, daddr; 330 int status;331 302 332 303 saddr = *addr; … … 345 316 daddr.sin_port = so->so_lport; 346 317 347 status = udp_output2(pData, so, m, &saddr, &daddr, so->so_iptos); 348 return status; 318 return udp_output2(pData, so, m, &saddr, &daddr, so->so_iptos); 349 319 } 350 320 … … 378 348 /* enable broadcast for later use */ 379 349 setsockopt(so->s, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)); 380 VBOX_SLIRP_LOCK(pData->udb_mutex);381 350 insque(pData, so,&udb); 382 VBOX_SLIRP_UNLOCK(pData->udb_mutex);383 351 } 384 352 } 385 #ifdef VBOX_WITH_SYNC_SLIRP386 so->so_type = IPPROTO_UDP;387 slirp_socket_created(pData->pvUser);388 #endif389 353 return(so->s); 390 354 } … … 394 358 { 395 359 /* Correctly update list if detaching last socket in list. */ 396 VBOX_SLIRP_LOCK(pData->udp_last_so_mutex);397 360 if (so == udp_last_so) udp_last_so = &udb; 398 VBOX_SLIRP_UNLOCK(pData->udp_last_so_mutex);399 361 closesocket(so->s); 400 362 /* if (so->so_m) m_free(so->so_m); done by sofree */ 401 363 402 364 sofree(pData, so); 403 404 365 } 405 366 … … 470 431 uint16_t pkt_len; /* packet length */ 471 432 } *cu_head; 472 473 433 474 434 switch(so->so_emu) { … … 678 638 so->s = socket(AF_INET,SOCK_DGRAM,0); 679 639 so->so_expire = curtime + SO_EXPIRE; 680 VBOX_SLIRP_LOCK(pData->udb_mutex);681 640 insque(pData, so,&udb); 682 VBOX_SLIRP_UNLOCK(pData->udb_mutex);683 641 684 642 addr.sin_family = AF_INET; … … 709 667 710 668 so->so_state = SS_ISFCONNECTED; 711 #ifdef VBOX_WITH_SYNC_SLIRP 712 slirp_socket_created(pData->pvUser); 713 #endif 669 714 670 return so; 715 671 }
Note:
See TracChangeset
for help on using the changeset viewer.