Changeset 13940 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 7, 2008 9:38:53 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r13840 r13940 59 59 60 60 #ifdef VBOX_WITH_SYNC_SLIRP 61 #include <unistd.h> /* should be in UNix version only*/ 61 62 #include <iprt/semaphore.h> 63 #include <errno.h> 62 64 #endif 63 65 … … 96 98 /*used for wakep of poling thread*/ 97 99 RTSEMEVENT semIOmutex; 100 PTMTIMER pNATFastTimer; 101 PTMTIMER pNATSlowTimer; 102 /** The write end of the control pipe. */ 103 RTFILE PipeWrite; 104 /** The read end of the control pipe. */ 105 RTFILE PipeRead; 98 106 #endif 99 107 } DRVNAT, *PDRVNAT; … … 168 176 #ifndef VBOX_WITH_SYNC_SLIRP 169 177 RTCritSectLeave(&pThis->CritSect); 178 #else 179 int ndfds = 0; 180 fd_set writefds; 181 FD_ZERO(&writefds); 182 slirp_send_fill(pThis->pNATState, &ndfds, &writefds); 183 struct timeval tv = {0,0}; /* no wait */ 184 185 int cWriteFDs = select(ndfds + 1, NULL, &writefds, NULL, &tv); 186 if (cWriteFDs >= 0) 187 slirp_send_trigger(pThis->pNATState, &ndfds, &writefds); 170 188 #endif 171 189 LogFlow(("drvNATSend: end\n")); … … 275 293 #else 276 294 295 static DECLCALLBACK(void) drvNATFastTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer) 296 { 297 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 298 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) 299 slirp_fasttmr(pThis->pNATState); 300 TMTimerSetMicro(pTimer, 2); 301 } 302 303 static DECLCALLBACK(void) drvNATSlowTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer) 304 { 305 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 306 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) 307 slirp_slowtmr(pThis->pNATState); 308 TMTimerSetMicro(pTimer, 500); 309 } 277 310 static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 278 311 { … … 301 334 slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs); 302 335 303 struct timeval tv = {0, 0}; /* no wait */ 304 305 int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv); 306 307 if (cReadFDs >= 0) 336 struct timeval tv = {1, 0}; /* no wait */ 337 338 FD_SET(pThis->PipeRead, &ReadFDs); /*Linux only*/ 339 cFDs = (pThis->PipeRead < cFDs ? cFDs:pThis->PipeRead); 340 int cReadFDs = select(cFDs + 1, &ReadFDs, NULL, &XcptFDs, &tv); 341 342 if (cReadFDs >= 0) { 308 343 slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs); 309 344 345 if (FD_ISSET(pThis->PipeRead, &ReadFDs)) { 346 /* drain the pipe */ 347 char ch; 348 size_t cbRead; 349 RTFileRead(pThis->PipeRead, &ch, 1, &cbRead); 350 } 351 } 310 352 #if 0 311 353 if (cReadFDs == 0) { … … 335 377 } 336 378 379 /*Callback from slirp to exit from select*/ 380 void slirp_socket_created(void* pvUser) 381 { 382 PDRVNAT pThis = (PDRVNAT)pvUser; 383 int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL); 384 AssertRC(rc); 385 } 337 386 #endif 338 387 … … 682 731 rc = RTSemEventCreate(&pThis->semIOmutex); 683 732 AssertReleaseRC(rc); 733 734 /* 735 * Create the control pipe. 736 * XXX: Linux only 737 */ 738 int fds[2]; 739 if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */ 740 { 741 int rc = RTErrConvertFromErrno(errno); 742 AssertRC(rc); 743 return rc; 744 } 745 pThis->PipeRead = fds[0]; 746 pThis->PipeWrite = fds[1]; 747 684 748 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT"); 685 749 AssertReleaseRC(rc); 750 rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_REAL, drvNATFastTimer, "NAT_fast_timer", &pThis->pNATFastTimer); 751 AssertReleaseRC(rc); 752 TMTimerSetMicro(pThis->pNATFastTimer, 1); 753 rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_REAL, drvNATSlowTimer, "NAT_slow_timer", &pThis->pNATSlowTimer); 754 AssertReleaseRC(rc); 755 TMTimerSetMicro(pThis->pNATSlowTimer, 500); 686 756 #endif 687 757 -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r8285 r13940 49 49 int guest_port); 50 50 51 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 52 61 #ifdef __cplusplus 53 62 } -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r13897 r13940 80 80 mbuf_max = mbuf_alloced; 81 81 VBOX_SLIRP_UNLOCK(pData->mbuf_alloced_mutex); 82 VBOX_SLIRP_LOCK_CREATE(&m->m_mutex); 83 VBOX_SLIRP_LOCK(m->m_mutex); 82 84 } else { 83 85 m = m_freelist.m_next; 86 VBOX_SLIRP_LOCK(m->m_mutex); 87 struct mbuf *n = m->m_next; 88 if (n != NULL) 89 VBOX_SLIRP_LOCK(n->m_mutex); 84 90 remque(pData, m); 91 if (m->m_next != NULL) 92 VBOX_SLIRP_UNLOCK(n->m_mutex); 85 93 } 86 94 … … 89 97 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex); 90 98 /* Insert it in the used list */ 99 struct mbuf *n = m_usedlist.m_next; 100 if (n != &m_usedlist) 101 VBOX_SLIRP_LOCK(n->m_mutex); 91 102 insque(pData, m,&m_usedlist); 92 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex); 103 if (n != &m_usedlist) 104 VBOX_SLIRP_LOCK(n->m_mutex); 105 VBOX_SLIRP_UNLOCK(m->m_mutex); 93 106 94 107 m->m_flags = (flags | M_USEDLIST); … … 117 130 if (m->m_flags & M_USEDLIST) { 118 131 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex); 132 struct mbuf *p, *n; 133 p = (m->m_prev); 134 n = (m->m_next); 135 VBOX_SLIRP_LOCK(m->m_next); 136 if (n != NULL) 137 VBOX_SLIRP_LOCK(n->m_next); 138 if (p != NULL) 139 VBOX_SLIRP_UNLOCK(p->m_next); 119 140 remque(pData, m); 141 if (n != NULL) 142 VBOX_SLIRP_UNLOCK(n->m_next); 143 if (p != NULL) 144 VBOX_SLIRP_LOCK(p->m_next); 120 145 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex); 121 146 } … … 130 155 if (m->m_flags & M_DOFREE) { 131 156 u32ptr_done(pData, ptr_to_u32(pData, m), m); 157 VBOX_SLIRP_UNLOCK(m->m_mutex); 158 VBOX_SLIRP_LOCK_DESTROY(m->m_mutex); 132 159 free(m); 133 160 #ifdef VBOX_WITH_SYNC_SLIRP -
trunk/src/VBox/Devices/Network/slirp/mbuf.h
r13897 r13940 76 76 caddr_t mh_data; /* Location of data */ 77 77 int mh_len; /* Amount of data in this mbuf */ 78 #ifdef VBOX_WITH_SYNC_SLIRP 79 RTSEMFASTMUTEX mh_mutex; 80 #endif 78 81 }; 79 82 -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r13897 r13940 362 362 * First, TCP sockets 363 363 */ 364 #ifndef VBOX_WITH_SYNC_SLIRP 364 365 do_slowtimo = 0; 366 #endif 365 367 if (link_up) { 366 368 /* … … 369 371 */ 370 372 VBOX_SLIRP_LOCK(pData->tcb_mutex); 373 #ifndef VBOX_WITH_SYNC_SLIRP 371 374 do_slowtimo = ((tcb.so_next != &tcb) || 372 375 ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *))); 376 #endif 373 377 374 378 so = tcb.so_next; … … 389 393 * See if we need a tcp_fasttimo 390 394 */ 395 #ifndef VBOX_SLIRP_UNLOCK 391 396 if (time_fasttimo == 0 392 397 && so->so_tcpcb 393 398 && so->so_tcpcb->t_flags & TF_DELACK) 394 399 time_fasttimo = curtime; /* Flag when we want a fasttimo */ 400 #endif 395 401 396 402 /* … … 409 415 goto before_loop_ends; 410 416 } 411 417 #ifndef VBOX_WITH_SYNC_SLIRP 412 418 /* 413 419 * Set for writing sockets which are connecting … … 427 433 UPD_NFDS(so->s); 428 434 } 435 #endif 429 436 430 437 /* … … 465 472 * See if it's timed out 466 473 */ 474 #ifndef VBOX_WITH_SYNC_SLIRP 467 475 if (so->so_expire) { 468 476 if (so->so_expire <= curtime) { … … 472 480 do_slowtimo = 1; /* Let socket expire */ 473 481 } 482 #endif 474 483 475 484 /* … … 499 508 */ 500 509 510 #ifndef VBOX_WITH_SYNC_SLIRP 501 511 /* 502 512 * First, see the timeout needed by *timo … … 528 538 } 529 539 } 540 #endif 530 541 *pnfds = nfds; 531 542 } … … 542 553 * See if anything has timed out 543 554 */ 555 #ifndef VBOX_WITH_SYNC_SLIRP 544 556 if (link_up) { 545 557 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) { … … 553 565 } 554 566 } 567 #endif 555 568 556 569 /* … … 610 623 } 611 624 625 #ifndef VBOX_WITH_SYNC_SLIRP 612 626 /* 613 627 * Check sockets for writing … … 655 669 */ 656 670 } 671 #endif 657 672 658 673 /* … … 914 929 memcpy(client_ethaddr, ethaddr, ETH_ALEN); 915 930 } 931 932 #ifdef VBOX_WITH_SYNC_SLIRP 933 void slirp_fasttmr(PNATState pData) 934 { 935 struct socket *so, *so_next; 936 updtime(pData); 937 time_fasttimo = 0; 938 #if 1 939 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 == 0 949 && so->so_tcpcb 950 && 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 #endif 956 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 1 968 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 #endif 996 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 writing 1061 */ 1062 if (FD_ISSET(so->s, writefds)) { 1063 /* 1064 * Check for non-blocking, still-connecting sockets 1065 */ 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 returns 1073 * EFAULT which causes the opened TCP socket to close right 1074 * after it has been opened and connected. 1075 */ 1076 #ifndef RT_OS_OS2 1077 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 #endif 1089 1090 /* 1091 * Continue tcp_input 1092 */ 1093 tcp_input(pData, (struct mbuf *)NULL, sizeof(struct ip), so); 1094 /* continue; */ 1095 } else 1096 ret = sowrite(pData, so); 1097 /* 1098 * XXXXX If we wrote something (a lot), there 1099 * could be a need for a window update. 1100 * In the worst case, the remote will send 1101 * a window probe to get things going again 1102 */ 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/tcp_subr.c
r13783 r13940 541 541 /*we use this field to identify cache socket to lock/unlock*/ 542 542 so->so_type = IPPROTO_TCP; 543 slirp_socket_created(pData->pvUser); 543 544 #endif 544 545 -
trunk/src/VBox/Devices/Network/slirp/udp.c
r13783 r13940 385 385 #ifdef VBOX_WITH_SYNC_SLIRP 386 386 so->so_type = IPPROTO_UDP; 387 slirp_socket_created(pData->pvUser); 387 388 #endif 388 389 return(so->s); … … 708 709 709 710 so->so_state = SS_ISFCONNECTED; 710 711 #ifdef VBOX_WITH_SYNC_SLIRP 712 slirp_socket_created(pData->pvUser); 713 #endif 711 714 return so; 712 715 }
Note:
See TracChangeset
for help on using the changeset viewer.