Changeset 13986 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 9, 2008 8:49:02 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r13984 r13986 28 28 #define __STDC_LIMIT_MACROS 29 29 #define __STDC_CONSTANT_MACROS 30 #ifndef VBOX_NAT_SOURCES31 30 #include "Network/slirp/libslirp.h" 32 #else33 #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 #endif47 31 #include <VBox/pdmdrv.h> 48 32 #include <iprt/assert.h> … … 51 35 #include <iprt/critsect.h> 52 36 #include <iprt/cidr.h> 37 #include <iprt/stream.h> 53 38 54 39 #include "Builtins.h" 55 40 56 #ifdef VBOX_NAT_SOURCES57 #include "Network/nat/nat.h"58 #endif59 41 #ifdef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 60 # include <unistd.h>61 # include <errno.h>62 # include<iprt/semaphore.h>42 # include <unistd.h> 43 # include <errno.h> 44 # include<iprt/semaphore.h> 63 45 #endif 64 46 … … 87 69 PDMNETWORKLINKSTATE enmLinkState; 88 70 /** NAT state for this instance. */ 89 #ifndef VBOX_NAT_SOURCES90 71 PNATState pNATState; 91 #endif92 72 /** TFTP directory prefix. */ 93 73 char *pszTFTPPrefix; … … 98 78 PPDMTHREAD pThread; 99 79 /*used for wakep of poling thread*/ 100 RTSEMEVENT semIOmutex; 101 RTSEMEVENT semSndMutex; 80 RTSEMEVENT semSndMutex; 102 81 #ifndef RT_OS_WINDOWS 103 82 /** The write end of the control pipe. */ … … 107 86 #else 108 87 #endif 109 char cBuffer[1600]; 88 /** Send buffer */ 89 char cBuffer[1600]; 110 90 size_t sBufferSize; 111 91 #endif … … 116 96 117 97 118 /*******************************************************************************119 * Global Variables *120 *******************************************************************************/121 #if 0122 /** If set the thread should terminate. */123 static bool g_fThreadTerm = false;124 /** The thread id of the select thread (drvNATSelectThread()). */125 static RTTHREAD g_ThreadSelect;126 #endif127 128 129 /*******************************************************************************130 * Internal Functions *131 *******************************************************************************/132 133 134 #ifdef VBOX_NAT_SOURCES135 /*136 * Sends data to guest called from NAT glue code137 */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 #endif149 98 150 99 /** … … 162 111 163 112 LogFlow(("drvNATSend: pvBuf=%p cb=%#x\n", pvBuf, cb)); 164 Log2(("drvNATSend: pvBuf=%p cb=%#x\n" 165 "%.*Vhxd\n", 166 pvBuf, cb, cb, pvBuf)); 113 Log2(("drvNATSend: pvBuf=%p cb=%#x\n%.*Rhxd\n", pvBuf, cb, cb, pvBuf)); 167 114 168 115 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC … … 173 120 memcpy(pThis->cBuffer,pvBuf, cb); 174 121 pThis->sBufferSize = cb; 175 int rc = RTFileWrite(pThis->PipeWrite, " ", 1, NULL);122 int rc = RTFileWrite(pThis->PipeWrite, "1", 2, NULL); 176 123 AssertRC(rc); 177 124 RTSemEventWait(pThis->semSndMutex, RT_INDEFINITE_WAIT); … … 181 128 Assert(pThis->enmLinkState == PDMNETWORKLINKSTATE_UP); 182 129 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) { 183 #ifndef VBOX_NAT_SOURCES184 130 slirp_input(pThis->pNATState, (uint8_t *)pvBuf, cb); 185 #else186 ether_chk(pThis, pvBuf, cb);187 #endif188 131 } 189 132 RTCritSectLeave(&pThis->CritSect); … … 234 177 case PDMNETWORKLINKSTATE_UP: 235 178 LogRel(("NAT: link up\n")); 236 #ifndef VBOX_NAT_SOURCES237 179 slirp_link_up(pThis->pNATState); 238 #endif239 180 break; 240 181 … … 242 183 case PDMNETWORKLINKSTATE_DOWN_RESUME: 243 184 LogRel(("NAT: link down\n")); 244 #ifndef VBOX_NAT_SOURCES245 185 slirp_link_down(pThis->pNATState); 246 #endif247 186 break; 248 187 … … 274 213 AssertReleaseRC(rc); 275 214 276 #ifndef VBOX_NAT_SOURCES277 215 slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 278 #else279 nat_select_fill(NULL, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs);280 #endif281 216 282 217 struct timeval tv = {0, 0}; /* no wait */ 283 218 int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv); 284 #ifndef VBOX_NAT_SOURCES285 219 if (cReadFDs >= 0) 286 220 slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs); 287 #else288 if (cReadFDs >= 0) {289 nat_select_poll(pThis, &ReadFDs, &WriteFDs, &XcptFDs);290 }291 #endif292 221 293 222 RTCritSectLeave(&pThis->CritSect); … … 306 235 LogFlow(("drvNATAsyncIoThread: pThis=%p\n", pThis)); 307 236 308 309 237 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 310 238 return VINF_SUCCESS; 239 311 240 /* 312 241 * Polling loop. … … 324 253 slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 325 254 326 struct timeval tv = {0, 200 }; /* 2 millis wait*/327 328 FD_SET(pThis->PipeRead, &ReadFDs); /* Linux only*/329 cFDs = ( pThis->PipeRead < cFDs ? cFDs:pThis->PipeRead);255 struct timeval tv = {0, 2000}; /* 2ms for the fast timer */ 256 257 FD_SET(pThis->PipeRead, &ReadFDs); /* Linux only */ 258 cFDs = ((int)pThis->PipeRead < cFDs ? cFDs:pThis->PipeRead); 330 259 int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv); 331 332 if (cReadFDs >= 0){260 if (cReadFDs >= 0) 261 { 333 262 slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs); 334 263 335 if (FD_ISSET(pThis->PipeRead, &ReadFDs)) { 264 if (FD_ISSET(pThis->PipeRead, &ReadFDs)) 265 { 336 266 /* drain the pipe */ 337 char ch ;267 char ch[2]; 338 268 size_t cbRead; 339 RTFileRead(pThis->PipeRead, &ch, 1, &cbRead); 340 slirp_input(pThis->pNATState, (uint8_t *)pThis->cBuffer, pThis->sBufferSize); 341 RTSemEventSignal(pThis->semSndMutex); 269 RTFileRead(pThis->PipeRead, &ch, 2, &cbRead); 270 switch (ch[0]) 271 { 272 case '1': 273 slirp_input(pThis->pNATState, (uint8_t *)pThis->cBuffer, pThis->sBufferSize); 274 RTSemEventSignal(pThis->semSndMutex); 275 break; 276 case '2': 277 break; 278 } 342 279 } 343 280 } 344 #if 0345 if (cReadFDs == 0) {346 rc = RTSemEventWait(pThis->semIOmutex, RT_INDEFINITE_WAIT);347 AssertReleaseRC(rc);348 }349 #endif350 281 } 351 282 … … 362 293 static DECLCALLBACK(int) drvNATAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 363 294 { 364 #if 0365 295 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 366 int rc = RTSemEventSignal(pThis->semIOmutex); 367 AssertReleaseRC(rc);368 #endif 369 return (VINF_SUCCESS);370 } 371 372 #endif 373 374 #ifndef VBOX_NAT_SOURCES 296 297 int rc = RTFileWrite(pThis->PipeWrite, "2", 2, NULL); 298 AssertRC(rc); 299 RTSemEventSignal(pThis->semSndMutex); 300 return VINF_SUCCESS; 301 } 302 303 #endif 304 375 305 /** 376 306 * Function called by slirp to check if it's possible to feed incoming data to the network port. … … 403 333 404 334 LogFlow(("slirp_output BEGIN %x %d\n", pu8Buf, cb)); 405 Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n" 406 "%.*Vhxd\n", 407 pu8Buf, cb, pThis, 408 cb, pu8Buf)); 335 Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n%.*Rhxd\n", pu8Buf, cb, pThis, cb, pu8Buf)); 409 336 410 337 Assert(pThis); … … 420 347 LogFlow(("slirp_output END %x %d\n", pu8Buf, cb)); 421 348 } 422 #endif423 349 424 350 /** … … 465 391 AssertReleaseRC(rc); 466 392 #endif 467 #ifndef VBOX_NAT_SOURCES468 393 slirp_term(pThis->pNATState); 469 394 pThis->pNATState = NULL; 470 #endif471 395 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 472 396 RTCritSectLeave(&pThis->CritSect); … … 487 411 static int drvNATConstructRedir(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pCfgHandle, RTIPV4ADDR Network) 488 412 { 489 #ifndef VBOX_NAT_SOURCES490 413 /* 491 414 * Enumerate redirections. … … 545 468 struct in_addr GuestIP; 546 469 if (!inet_aton(szGuestIP, &GuestIP)) 547 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_GUEST_IP, RT_SRC_POS, N_("NAT#%d: configuration error: invalid \"GuestIP\"=\"%s\", inet_aton failed"), iInstance, szGuestIP); 470 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_GUEST_IP, RT_SRC_POS, 471 N_("NAT#%d: configuration error: invalid \"GuestIP\"=\"%s\", inet_aton failed"), iInstance, szGuestIP); 548 472 549 473 /* … … 552 476 Log(("drvNATConstruct: Redir %d -> %s:%d\n", iHostPort, szGuestIP, iGuestPort)); 553 477 if (slirp_redir(pThis->pNATState, fUDP, iHostPort, GuestIP, iGuestPort) < 0) 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); 478 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_SETUP, RT_SRC_POS, 479 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); 555 480 } /* for each redir rule */ 556 #endif557 481 558 482 return VINF_SUCCESS; … … 564 488 static void drvNATSetMac(PDRVNAT pThis) 565 489 { 566 #ifndef VBOX_NAT_SOURCES567 490 if (pThis->pConfig) 568 491 { … … 571 494 slirp_set_ethaddr(pThis->pNATState, Mac.au8); 572 495 } 573 #endif574 496 } 575 497 … … 625 547 */ 626 548 pThis->pDrvIns = pDrvIns; 627 #ifndef VBOX_NAT_SOURCES628 549 pThis->pNATState = NULL; 629 #endif630 550 pThis->pszTFTPPrefix = NULL; 631 551 pThis->pszBootFile = NULL; … … 690 610 return rc; 691 611 #endif 692 #if 0 693 rc = RTSemEventCreate(&g_EventSem); 612 /* 613 * Initialize slirp. 614 */ 615 rc = slirp_init(&pThis->pNATState, &szNetAddr[0], Netmask, fPassDomain, pThis->pszTFTPPrefix, pThis->pszBootFile, pThis); 694 616 if (RT_SUCCESS(rc)) 695 617 { 696 /* 697 * Start the select thread. (it'll block on the sem) 698 */ 699 g_fThreadTerm = false; 700 rc = RTThreadCreate(&g_ThreadSelect, drvNATSelectThread, 0, NULL, "NATSEL"); 701 if (RT_SUCCESS(rc)) 618 int rc2 = drvNATConstructRedir(pDrvIns->iInstance, pThis, pCfgHandle, Network); 619 if (RT_SUCCESS(rc2)) 702 620 { 703 #endif704 #ifndef VBOX_NAT_SOURCES705 621 /* 706 * Initialize slirp. 622 * Register a load done notification to get the MAC address into the slirp 623 * engine after we loaded a guest state. 707 624 */ 708 rc = slirp_init(&pThis->pNATState, &szNetAddr[0], Netmask, fPassDomain, pThis->pszTFTPPrefix, pThis->pszBootFile, pThis); 709 if (RT_SUCCESS(rc)) 625 rc2 = PDMDrvHlpSSMRegister(pDrvIns, pDrvIns->pDrvReg->szDriverName, 626 pDrvIns->iInstance, 0, 0, 627 NULL, NULL, NULL, NULL, NULL, drvNATLoadDone); 628 AssertRC(rc2); 629 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 630 pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvNATPoller); 631 #else 632 rc = RTSemEventCreate(&pThis->semSndMutex); 633 AssertReleaseRC(rc); 634 635 /* 636 * Create the control pipe. 637 * XXX: Linux only 638 */ 639 int fds[2]; 640 if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */ 710 641 { 711 int rc2 = drvNATConstructRedir(pDrvIns->iInstance, pThis, pCfgHandle, Network); 712 if (RT_SUCCESS(rc2)) 713 { 714 /* 715 * Register a load done notification to get the MAC address into the slirp 716 * engine after we loaded a guest state. 717 */ 718 rc2 = PDMDrvHlpSSMRegister(pDrvIns, pDrvIns->pDrvReg->szDriverName, 719 pDrvIns->iInstance, 0, 0, 720 NULL, NULL, NULL, NULL, NULL, drvNATLoadDone); 721 AssertRC(rc2); 722 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 723 pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvNATPoller); 724 #else 725 726 rc = RTSemEventCreate(&pThis->semIOmutex); 727 AssertReleaseRC(rc); 728 rc = RTSemEventCreate(&pThis->semSndMutex); 729 AssertReleaseRC(rc); 730 731 /* 732 * Create the control pipe. 733 * XXX: Linux only 734 */ 735 int fds[2]; 736 if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */ 737 { 738 int rc = RTErrConvertFromErrno(errno); 739 AssertRC(rc); 740 return rc; 741 } 742 pThis->PipeRead = fds[0]; 743 pThis->PipeWrite = fds[1]; 744 745 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT"); 746 AssertReleaseRC(rc); 747 #endif 748 749 pThis->enmLinkState = PDMNETWORKLINKSTATE_UP; 750 #if 0 751 RTSemEventSignal(g_EventSem); 752 RTThreadSleep(0); 753 #endif 754 /* might return VINF_NAT_DNS */ 755 return rc; 756 } 757 /* failure path */ 758 rc = rc2; 759 slirp_term(pThis->pNATState); 760 pThis->pNATState = NULL; 642 int rc = RTErrConvertFromErrno(errno); 643 AssertRC(rc); 644 return rc; 761 645 } 762 else 763 { 764 PDMDRV_SET_ERROR(pDrvIns, rc, N_("Unknown error during NAT networking setup: ")); 765 AssertMsgFailed(("Add error message for rc=%d (%Rrc)\n", rc, rc)); 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 774 #if 0 775 g_fThreadTerm = true; 776 RTSemEventSignal(g_EventSem); 777 RTThreadSleep(0); 646 pThis->PipeRead = fds[0]; 647 pThis->PipeWrite = fds[1]; 648 649 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT"); 650 AssertReleaseRC(rc); 651 #endif 652 653 pThis->enmLinkState = PDMNETWORKLINKSTATE_UP; 654 655 /* might return VINF_NAT_DNS */ 656 return rc; 778 657 } 779 RTSemEventDestroy(g_EventSem); 780 g_EventSem = NULL; 658 /* failure path */ 659 rc = rc2; 660 slirp_term(pThis->pNATState); 661 pThis->pNATState = NULL; 781 662 } 782 #endif 663 else 664 { 665 PDMDRV_SET_ERROR(pDrvIns, rc, N_("Unknown error during NAT networking setup: ")); 666 AssertMsgFailed(("Add error message for rc=%d (%Rrc)\n", rc, rc)); 667 } 668 783 669 #ifndef VBOX_WITH_SIMPLEFIED_SLIRP_SYNC 784 670 RTCritSectDelete(&pThis->CritSect); … … 786 672 return rc; 787 673 } 788 789 790 674 791 675
Note:
See TracChangeset
for help on using the changeset viewer.