Changeset 926 in vbox for trunk/src/VBox/Devices/Network/slirp
- Timestamp:
- Feb 15, 2007 3:34:02 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 18659
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/slirp.c
r530 r926 32 32 struct ex_list *exec_list; 33 33 34 #ifndef VBOX 34 35 /* XXX: suppress those select globals */ 35 36 fd_set *global_readfds, *global_writefds, *global_xfds; 37 #endif /* !VBOX */ 36 38 37 39 char slirp_hostname[33]; … … 57 59 FixedInfo = GlobalAlloc(GPTR, BufLen); 58 60 } 59 61 60 62 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { 61 63 #ifndef VBOX … … 322 324 { 323 325 gettimeofday(&tt, 0); 324 326 325 327 curtime = (u_int)tt.tv_sec * (u_int)1000; 326 328 curtime += (u_int)tt.tv_usec / (u_int)1000; 327 329 328 330 if ((tt.tv_usec % 1000) >= 500) 329 331 curtime++; … … 339 341 int tmp_time; 340 342 343 #ifndef VBOX 341 344 /* fail safe */ 342 345 global_readfds = NULL; 343 346 global_writefds = NULL; 344 347 global_xfds = NULL; 348 #endif /* !VBOX */ 345 349 346 350 nfds = *pnfds; … … 356 360 do_slowtimo = ((tcb.so_next != &tcb) || 357 361 ((struct ipasfrag *)&ipq != u32_to_ptr(ipq.next, struct ipasfrag *))); 358 362 359 363 for (so = tcb.so_next; so != &tcb; so = so_next) { 360 364 so_next = so->so_next; 361 365 362 366 /* 363 367 * See if we need a tcp_fasttimo … … 365 369 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) 366 370 time_fasttimo = curtime; /* Flag when we want a fasttimo */ 367 371 368 372 /* 369 373 * NOFDREF can include still connecting to local-host, … … 372 376 if (so->so_state & SS_NOFDREF || so->s == -1) 373 377 continue; 374 378 375 379 /* 376 380 * Set for reading sockets which are accepting … … 381 385 continue; 382 386 } 383 387 384 388 /* 385 389 * Set for writing sockets which are connecting … … 390 394 continue; 391 395 } 392 396 393 397 /* 394 398 * Set for writing if we are connected, can send more, and … … 399 403 UPD_NFDS(so->s); 400 404 } 401 405 402 406 /* 403 407 * Set for reading (and urgent data) if we are connected, can … … 410 414 } 411 415 } 412 416 413 417 /* 414 418 * UDP sockets … … 416 420 for (so = udb.so_next; so != &udb; so = so_next) { 417 421 so_next = so->so_next; 418 422 419 423 /* 420 424 * See if it's timed out … … 427 431 do_slowtimo = 1; /* Let socket expire */ 428 432 } 429 433 430 434 /* 431 435 * When UDP packets are received from over the … … 444 448 } 445 449 } 446 450 447 451 /* 448 452 * Setup timeout to use minimum CPU usage, especially when idle 449 453 */ 450 454 451 455 /* 452 456 * First, see the timeout needed by *timo … … 466 470 else if (timeout.tv_usec > 510000) 467 471 timeout.tv_usec = 510000; 468 472 469 473 /* Can only fasttimo if we also slowtimo */ 470 474 if (time_fasttimo) { … … 472 476 if (tmp_time < 0) 473 477 tmp_time = 0; 474 478 475 479 /* Choose the smallest of the 2 */ 476 480 if (tmp_time < timeout.tv_usec) … … 479 483 } 480 484 *pnfds = nfds; 481 } 485 } 482 486 483 487 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) … … 486 490 int ret; 487 491 492 #ifndef VBOX 488 493 global_readfds = readfds; 489 494 global_writefds = writefds; 490 495 global_xfds = xfds; 496 #endif /* !VBOX */ 491 497 492 498 /* Update time */ 493 499 updtime(); 494 500 495 501 /* 496 502 * See if anything has timed out … … 507 513 } 508 514 } 509 515 510 516 /* 511 517 * Check sockets … … 517 523 for (so = tcb.so_next; so != &tcb; so = so_next) { 518 524 so_next = so->so_next; 519 525 520 526 /* 521 527 * FD_ISSET is meaningless on these sockets … … 524 530 if (so->so_state & SS_NOFDREF || so->s == -1) 525 531 continue; 526 532 527 533 /* 528 534 * Check for URG data … … 544 550 } /* else */ 545 551 ret = soread(so); 546 552 547 553 /* Output it if we read something */ 548 554 if (ret > 0) 549 555 tcp_output(sototcpcb(so)); 550 556 } 551 557 552 558 /* 553 559 * Check sockets for writing … … 560 566 /* Connected */ 561 567 so->so_state &= ~SS_ISFCONNECTING; 562 568 563 569 ret = send(so->s, &ret, 0, 0); 564 570 if (ret < 0) { … … 567 573 errno == EINPROGRESS || errno == ENOTCONN) 568 574 continue; 569 575 570 576 /* else failed */ 571 577 so->so_state = SS_NOFDREF; 572 578 } 573 579 /* else so->so_state &= ~SS_ISFCONNECTING; */ 574 580 575 581 /* 576 582 * Continue tcp_input … … 587 593 */ 588 594 } 589 595 590 596 /* 591 597 * Probe a still-connecting, non-blocking socket … … 595 601 if (so->so_state & SS_ISFCONNECTING) { 596 602 ret = recv(so->s, (char *)&ret, 0,0); 597 603 598 604 if (ret < 0) { 599 605 /* XXX */ … … 601 607 errno == EINPROGRESS || errno == ENOTCONN) 602 608 continue; /* Still connecting, continue */ 603 609 604 610 /* else failed */ 605 611 so->so_state = SS_NOFDREF; 606 612 607 613 /* tcp_input will take care of it */ 608 614 } else { … … 617 623 } else 618 624 so->so_state &= ~SS_ISFCONNECTING; 619 625 620 626 } 621 627 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so); … … 623 629 #endif 624 630 } 625 631 626 632 /* 627 633 * Now UDP sockets. … … 631 637 for (so = udb.so_next; so != &udb; so = so_next) { 632 638 so_next = so->so_next; 633 639 634 640 if (so->s != -1 && FD_ISSET(so->s, readfds)) { 635 641 sorecvfrom(so); … … 637 643 } 638 644 } 639 645 640 646 /* 641 647 * See if we can start outputting … … 644 650 if_start(); 645 651 652 #ifndef VBOX 646 653 /* clear global file descriptor sets. 647 654 * these reside on the stack in vl.c … … 652 659 global_writefds = NULL; 653 660 global_xfds = NULL; 661 #endif /* !VBOX */ 654 662 } 655 663 -
trunk/src/VBox/Devices/Network/slirp/socket.c
r1 r926 1 1 /* 2 2 * Copyright (c) 1995 Danny Gasparovski. 3 * 4 * Please read the file COPYRIGHT for the 3 * 4 * Please read the file COPYRIGHT for the 5 5 * terms and conditions of the copyright. 6 6 */ … … 30 30 { 31 31 struct socket *so; 32 32 33 33 for (so = head->so_next; so != head; so = so->so_next) { 34 if (so->so_lport == lport && 34 if (so->so_lport == lport && 35 35 so->so_laddr.s_addr == laddr.s_addr && 36 36 so->so_faddr.s_addr == faddr.s_addr && … … 38 38 break; 39 39 } 40 40 41 41 if (so == head) 42 42 return (struct socket *)NULL; 43 43 return so; 44 44 45 45 } 46 46 … … 54 54 { 55 55 struct socket *so; 56 56 57 57 so = (struct socket *)malloc(sizeof(struct socket)); 58 58 if(so) { … … 79 79 else if (so == udp_last_so) 80 80 udp_last_so = &udb; 81 81 82 82 m_free(so->so_m); 83 84 if(so->so_next && so->so_prev) 83 84 if(so->so_next && so->so_prev) 85 85 remque(so); /* crashes if so is not in a queue */ 86 86 … … 102 102 struct iovec iov[2]; 103 103 int mss = so->so_tcpcb->t_maxseg; 104 104 105 105 DEBUG_CALL("soread"); 106 106 DEBUG_ARG("so = %lx", (long )so); 107 108 /* 107 108 /* 109 109 * No need to check if there's enough room to read. 110 110 * soread wouldn't have been called if there weren't 111 111 */ 112 112 113 113 len = sb->sb_datalen - sb->sb_cc; 114 114 115 115 iov[0].iov_base = sb->sb_wptr; 116 116 if (sb->sb_wptr < sb->sb_rptr) { … … 151 151 } 152 152 } 153 153 154 154 #ifdef HAVE_READV 155 155 nn = readv(so->s, (struct iovec *)iov, n); … … 157 157 #else 158 158 nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); 159 #endif 159 #endif 160 160 if (nn <= 0) { 161 161 if (nn < 0 && (errno == EINTR || errno == EAGAIN)) … … 168 168 } 169 169 } 170 170 171 171 #ifndef HAVE_READV 172 172 /* … … 185 185 nn += ret; 186 186 } 187 187 188 188 DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); 189 189 #endif 190 190 191 191 /* Update fields */ 192 192 sb->sb_cc += nn; … … 196 196 return nn; 197 197 } 198 198 199 199 /* 200 200 * Get urgent data 201 * 201 * 202 202 * When the socket is created, we set it SO_OOBINLINE, 203 203 * so when OOB data arrives, we soread() it and everything … … 212 212 DEBUG_CALL("sorecvoob"); 213 213 DEBUG_ARG("so = %lx", (long)so); 214 214 215 215 /* 216 216 * We take a guess at how much urgent data has arrived. … … 218 218 * read() should get all the urgent data. This guess will 219 219 * be wrong however if more data arrives just after the 220 * urgent data, or the read() doesn't return all the 220 * urgent data, or the read() doesn't return all the 221 221 * urgent data. 222 222 */ … … 238 238 struct sbuf *sb = &so->so_rcv; 239 239 char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ 240 240 241 241 int n, len; 242 242 243 243 DEBUG_CALL("sosendoob"); 244 244 DEBUG_ARG("so = %lx", (long)so); 245 245 DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); 246 246 247 247 if (so->so_urgc > 2048) 248 248 so->so_urgc = 2048; /* XXXX */ 249 249 250 250 if (sb->sb_rptr < sb->sb_wptr) { 251 251 /* We can send it directly */ 252 252 n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */ 253 253 so->so_urgc -= n; 254 254 255 255 DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); 256 256 } else { 257 /* 257 /* 258 258 * Since there's no sendv or sendtov like writev, 259 259 * we must copy all data to a linear buffer then … … 275 275 if (n != len) 276 276 DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n")); 277 #endif 277 #endif 278 278 DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); 279 279 } 280 280 281 281 sb->sb_cc -= n; 282 282 sb->sb_rptr += n; 283 283 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) 284 284 sb->sb_rptr -= sb->sb_datalen; 285 285 286 286 return n; 287 287 } 288 288 289 289 /* 290 * Write data from so_rcv to so's socket, 290 * Write data from so_rcv to so's socket, 291 291 * updating all sbuf field as necessary 292 292 */ … … 299 299 int len = sb->sb_cc; 300 300 struct iovec iov[2]; 301 301 302 302 DEBUG_CALL("sowrite"); 303 303 DEBUG_ARG("so = %lx", (long)so); 304 304 305 305 if (so->so_urgc) { 306 306 sosendoob(so); … … 313 313 * sowrite wouldn't have been called otherwise 314 314 */ 315 315 316 316 len = sb->sb_cc; 317 317 318 318 iov[0].iov_base = sb->sb_rptr; 319 319 if (sb->sb_rptr < sb->sb_wptr) { … … 338 338 #ifdef HAVE_READV 339 339 nn = writev(so->s, (const struct iovec *)iov, n); 340 340 341 341 DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); 342 342 #else … … 346 346 if (nn < 0 && (errno == EAGAIN || errno == EINTR)) 347 347 return 0; 348 348 349 349 if (nn <= 0) { 350 350 DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", … … 354 354 return -1; 355 355 } 356 356 357 357 #ifndef HAVE_READV 358 358 if (n == 2 && nn == iov[0].iov_len) { … … 364 364 DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); 365 365 #endif 366 366 367 367 /* Update sbuf */ 368 368 sb->sb_cc -= nn; … … 370 370 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) 371 371 sb->sb_rptr -= sb->sb_datalen; 372 372 373 373 /* 374 374 * If in DRAIN mode, and there's no more data, set … … 377 377 if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) 378 378 sofcantsendmore(so); 379 379 380 380 return nn; 381 381 } … … 394 394 socklen_t addrlen = sizeof(struct sockaddr_in); 395 395 #endif /* VBOX */ 396 396 397 397 DEBUG_CALL("sorecvfrom"); 398 398 DEBUG_ARG("so = %lx", (long)so); 399 399 400 400 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ 401 401 char buff[256]; 402 402 int len; 403 404 len = recvfrom(so->s, buff, 256, 0, 403 404 len = recvfrom(so->s, buff, 256, 0, 405 405 (struct sockaddr *)&addr, &addrlen); 406 406 /* XXX Check if reply is "correct"? */ 407 407 408 408 if(len == -1 || len == 0) { 409 409 u_char code=ICMP_UNREACH_PORT; … … 411 411 if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; 412 412 else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; 413 413 414 414 DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", 415 415 errno,strerror(errno))); … … 427 427 if (!(m = m_get())) return; 428 428 m->m_data += if_maxlinkhdr; 429 430 /* 429 430 /* 431 431 * XXX Shouldn't FIONREAD packets destined for port 53, 432 432 * but I don't know the max packet size for DNS lookups … … 435 435 /* if (so->so_fport != htons(53)) { */ 436 436 ioctlsocket(so->s, FIONREAD, &n); 437 437 438 438 if (n > len) { 439 439 n = (m->m_data - m->m_dat) + m->m_len + n + 1; … … 442 442 } 443 443 /* } */ 444 444 445 445 m->m_len = recvfrom(so->s, m->m_data, len, 0, 446 446 (struct sockaddr *)&addr, &addrlen); 447 DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", 447 DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", 448 448 m->m_len, errno,strerror(errno))); 449 449 if(m->m_len<0) { … … 452 452 if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; 453 453 else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; 454 454 455 455 DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); 456 456 icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); … … 475 475 * } 476 476 */ 477 478 /* 477 478 /* 479 479 * If this packet was destined for CTL_ADDR, 480 480 * make it look like that's where it came from, done by udp_output … … 499 499 DEBUG_ARG("so = %lx", (long)so); 500 500 DEBUG_ARG("m = %lx", (long)m); 501 501 502 502 addr.sin_family = AF_INET; 503 503 if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { … … 517 517 518 518 DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); 519 519 520 520 /* Don't care what port we get */ 521 521 ret = sendto(so->s, m->m_data, m->m_len, 0, … … 523 523 if (ret < 0) 524 524 return -1; 525 525 526 526 /* 527 527 * Kill the socket if there's no reply in 4 minutes, … … 558 558 DEBUG_ARG("lport = %d", lport); 559 559 DEBUG_ARG("flags = %x", flags); 560 560 561 561 if ((so = socreate()) == NULL) { 562 562 /* free(so); Not sofree() ??? free(NULL) == NOP */ 563 563 return NULL; 564 564 } 565 565 566 566 /* Don't tcp_attach... we don't need so_snd nor so_rcv */ 567 567 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { … … 570 570 } 571 571 insque(so,&tcb); 572 573 /* 572 573 /* 574 574 * SS_FACCEPTONCE sockets must time out. 575 575 */ 576 576 if (flags & SS_FACCEPTONCE) 577 577 so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; 578 578 579 579 so->so_state = (SS_FACCEPTCONN|flags); 580 580 so->so_lport = lport; /* Kept in network format */ 581 581 so->so_laddr.s_addr = laddr; /* Ditto */ 582 582 583 583 addr.sin_family = AF_INET; 584 584 addr.sin_addr.s_addr = INADDR_ANY; 585 585 addr.sin_port = port; 586 586 587 587 if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || 588 588 (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || … … 591 591 #ifndef VBOX 592 592 int tmperrno = errno; /* Don't clobber the real reason we failed */ 593 593 594 594 close(s); 595 595 sofree(so); … … 618 618 } 619 619 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 620 620 621 621 getsockname(s,(struct sockaddr *)&addr,&addrlen); 622 622 so->so_fport = addr.sin_port; … … 630 630 } 631 631 632 /* 632 /* 633 633 * Data is available in so_rcv 634 634 * Just write() the data to the socket … … 642 642 /* FD_CLR(so->s,&writefds); */ 643 643 } 644 644 645 645 /* 646 646 * Data has been freed in so_snd … … 684 684 if ((so->so_state & SS_NOFDREF) == 0) { 685 685 shutdown(so->s,0); 686 #ifndef VBOX 686 687 if(global_writefds) { 687 688 FD_CLR(so->s,global_writefds); 688 689 } 690 #endif /* !VBOX */ 689 691 } 690 692 so->so_state &= ~(SS_ISFCONNECTING); … … 701 703 if ((so->so_state & SS_NOFDREF) == 0) { 702 704 shutdown(so->s,1); /* send FIN to fhost */ 705 #ifndef VBOX 703 706 if (global_readfds) { 704 707 FD_CLR(so->s,global_readfds); … … 707 710 FD_CLR(so->s,global_xfds); 708 711 } 712 #endif /* !VBOX */ 709 713 } 710 714 so->so_state &= ~(SS_ISFCONNECTING);
Note:
See TracChangeset
for help on using the changeset viewer.