Ticket #2531: dhcp.5.2.diff
File dhcp.5.2.diff, 10.0 KB (added by , 16 years ago) |
---|
-
src/servers/net/DHCPClient.cpp
21 21 #include <sys/time.h> 22 22 23 23 24 #define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0) 25 26 void trace_dhcp_state(dhcp_state state) 27 { 28 char *state_name=NULL; 29 switch(state) 30 { 31 case INIT: state_name = "INIT"; break; 32 case REQUESTING: state_name = "REQUESTING"; break; 33 case BOUND: state_name = "BOUND"; break; 34 case RENEWAL: state_name="RENEWAL"; break; 35 case REBINDING: state_name="REBINDING"; break; 36 case ACKNOWLEDGED: state_name="ACKNOWLEDGED"; break; 37 default: break; 38 } 39 if (state_name == NULL) 40 ktrace_printf("DHCP: state 0x%x\n", (unsigned)state); 41 else 42 ktrace_printf("DHCP: state %s\n", state_name); 43 } 44 24 45 // See RFC 2131 for DHCP, see RFC 1533 for BOOTP/DHCP options 25 46 26 47 #define DHCP_CLIENT_PORT 68 … … 336 357 fRunner(NULL), 337 358 fLeaseTime(0) 338 359 { 360 LND; 339 361 fStartTime = system_time(); 340 362 fTransactionID = (uint32)fStartTime; 341 363 342 364 fStatus = get_mac_address(device, fMAC); 343 if (fStatus < B_OK) 365 if (fStatus < B_OK) { 366 LND; 344 367 return; 368 } 345 369 346 370 memset(&fServer, 0, sizeof(struct sockaddr_in)); 347 371 fServer.sin_family = AF_INET; 348 372 fServer.sin_len = sizeof(struct sockaddr_in); 349 373 fServer.sin_port = htons(DHCP_SERVER_PORT); 374 LND; 350 375 } 351 376 352 377 353 378 DHCPClient::~DHCPClient() 354 379 { 380 LND; 355 381 if (fStatus != B_OK) 356 382 return; 357 383 … … 374 400 status_t 375 401 DHCPClient::Initialize() 376 402 { 403 LND; 404 trace_dhcp_state(INIT); 377 405 fStatus = _Negotiate(INIT); 378 406 printf("DHCP for %s, status: %s\n", fDevice.String(), strerror(fStatus)); 379 407 return fStatus; 380 408 } 381 409 382 383 410 status_t 384 411 DHCPClient::_Negotiate(dhcp_state state) 385 412 { 413 LND; 414 ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 415 trace_dhcp_state(state); 416 if (state != INIT 417 && state != REBINDING 418 && state != RENEWAL) 419 fprintf(stderr, "DHCP client: negotiating: unexpected state %d\n", state); 420 386 421 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 387 if (socket < 0) 422 if (socket < 0) { 423 LND; 388 424 return errno; 425 } 389 426 390 427 sockaddr_in local; 391 428 memset(&local, 0, sizeof(struct sockaddr_in)); … … 396 433 397 434 if (bind(socket, (struct sockaddr *)&local, sizeof(local)) < 0) { 398 435 close(socket); 436 LND; 399 437 return errno; 400 438 } 401 439 … … 410 448 setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option)); 411 449 412 450 if (state == INIT) { 451 LND; 413 452 // The local interface does not have an address yet, bind the socket 414 453 // to the device directly. 415 454 int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0); 416 455 if (linkSocket >= 0) { 456 LND; 417 457 // we need to know the index of the device to be able to bind to it 418 458 ifreq request; 419 459 prepare_request(request, fDevice.String()); 420 460 if (ioctl(linkSocket, SIOCGIFINDEX, &request, sizeof(struct ifreq)) 421 461 == 0) { 462 LND; 422 463 setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, 423 464 &request.ifr_index, sizeof(int)); 424 465 } … … 448 489 state != RENEWAL ? broadcast : fServer); 449 490 if (status < B_OK) { 450 491 close(socket); 492 LND; 451 493 return status; 452 494 } 453 495 454 496 // receive loop until we've got an offer and acknowledged it 455 497 498 LND; 499 456 500 while (state != ACKNOWLEDGED) { 501 LND; 502 trace_dhcp_state(state); 457 503 char buffer[2048]; 458 504 ssize_t bytesReceived = recvfrom(socket, buffer, sizeof(buffer), 459 505 0, NULL, NULL); 460 506 if (bytesReceived < 0 && errno == B_TIMED_OUT) { 507 LND; 461 508 // depending on the state, we'll just try again 462 509 if (!_TimeoutShift(socket, timeout, tries)) { 510 LND; 463 511 close(socket); 464 512 return B_TIMED_OUT; 465 513 } … … 467 515 if (state == INIT) 468 516 status = _SendMessage(socket, discover, broadcast); 469 517 else { 518 LND; 470 519 status = _SendMessage(socket, request, state != RENEWAL 471 520 ? broadcast : fServer); 472 521 } 473 522 474 523 if (status < B_OK) 475 524 break; 525 LND; 476 526 } else if (bytesReceived < B_OK) 477 527 break; 528 LND; 478 529 479 530 dhcp_message *message = (dhcp_message *)buffer; 480 531 if (message->transaction_id != htonl(fTransactionID) 481 532 || !message->HasOptions() 482 533 || memcmp(message->mac_address, discover.mac_address, 483 534 discover.hardware_address_length)) { 535 LND; 484 536 // this message is not for us 485 537 continue; 486 538 } … … 488 540 switch (message->Type()) { 489 541 case DHCP_NONE: 490 542 default: 543 LND; 491 544 // ignore this message 492 545 break; 493 546 494 547 case DHCP_OFFER: 495 548 { 549 LND; 496 550 // first offer wins 497 551 if (state != INIT) 498 552 break; 553 LND; 499 554 500 555 // collect interface options 501 556 … … 516 571 517 572 _ResetTimeout(socket, timeout, tries); 518 573 state = REQUESTING; 574 trace_dhcp_state(state); 519 575 _PrepareMessage(request, state); 520 576 521 577 status = _SendMessage(socket, request, broadcast); … … 526 582 527 583 case DHCP_ACK: 528 584 { 585 LND; 586 trace_dhcp_state(state); 529 587 if (state != REQUESTING && state != REBINDING 530 588 && state != RENEWAL) 531 589 continue; 590 LND; 532 591 533 592 // TODO: we might want to configure the stuff, don't we? 534 593 BMessage address; … … 548 607 } 549 608 550 609 case DHCP_NACK: 610 LND; 551 611 if (state != REQUESTING) 552 612 continue; 613 LND; 553 614 554 615 // try again (maybe we should prefer other servers if this 555 616 // happens more than once) … … 559 620 break; 560 621 } 561 622 } 623 LND; 624 trace_dhcp_state(state); 562 625 563 626 close(socket); 564 627 565 628 if (status == B_OK && fLeaseTime > 0) { 629 LND; 566 630 // notify early enough when the lease is 567 631 if (fRenewalTime == 0) 568 632 fRenewalTime = fLeaseTime * 2/3; 569 633 if (fRebindingTime == 0) 570 634 fRebindingTime = fLeaseTime * 5/6; 571 635 636 LND; 572 637 _RestartLease(fRenewalTime); 573 638 574 639 bigtime_t now = system_time(); … … 577 642 fRebindingTime += now; 578 643 // make lease times absolute 579 644 } else { 645 LND; 646 ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 580 647 fLeaseTime = previousLeaseTime; 581 648 bigtime_t now = system_time(); 582 649 fRenewalTime = (fLeaseTime - now) * 2/3 + now; 583 650 fRebindingTime = (fLeaseTime - now) * 5/6 + now; 651 ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 584 652 } 653 LND; 585 654 586 655 return status; 587 656 } … … 590 659 void 591 660 DHCPClient::_RestartLease(bigtime_t leaseTime) 592 661 { 662 LND; 593 663 if (leaseTime == 0) 594 664 return; 665 ktrace_printf("DHCP: _RestartLease: leaseTime %lld\n", leaseTime); 595 666 596 667 BMessage lease(kMsgLeaseTime); 597 fRunner = new BMessageRunner(this, &lease, leaseTime , 1);668 fRunner = new BMessageRunner(this, &lease, leaseTime+1000, 1); 598 669 } 599 670 600 671 … … 798 869 DHCPClient::_CurrentState() const 799 870 { 800 871 bigtime_t now = system_time(); 872 873 ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 801 874 802 875 if (now > fLeaseTime || fStatus < B_OK) 803 876 return INIT; … … 819 892 dhcp_state state = _CurrentState(); 820 893 821 894 bigtime_t next; 895 LND; 896 trace_dhcp_state(state); 822 897 if (_Negotiate(state) == B_OK) { 823 898 switch (state) { 824 899 case RENEWAL: … … 841 916 } 842 917 } 843 918 919 LND; 844 920 _RestartLease(next - system_time()); 845 921 break; 846 922 } -
src/servers/net/NetServer.cpp
37 37 #include <string.h> 38 38 #include <unistd.h> 39 39 40 #define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0) 40 41 42 41 43 static const char *kSignature = "application/x-vnd.haiku-net_server"; 42 44 43 45 … … 315 317 if (socket < 0) 316 318 break; 317 319 320 LND; 318 321 status_t status = _ConfigureInterface(socket, *message, true); 319 322 320 323 BMessage reply(B_REPLY); … … 485 488 status_t 486 489 NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage) 487 490 { 491 LND; 492 488 493 const char *device; 489 494 if (interface.FindString("device", &device) != B_OK) 490 495 return B_BAD_VALUE; … … 675 680 } 676 681 } 677 682 683 LND; 678 684 if (startAutoConfig) { 679 685 // start auto configuration 686 LND; 680 687 AutoconfigLooper* looper = new AutoconfigLooper(this, device); 681 688 looper->Run(); 682 689 … … 725 732 address.AddBool("auto config", true); 726 733 interface.AddMessage("address", &address); 727 734 735 LND; 736 728 737 return _ConfigureInterface(socket, interface); 729 738 } 730 739 … … 746 755 continue; 747 756 748 757 if (S_ISBLK(stat.st_mode) || S_ISCHR(stat.st_mode)) { 758 LND; 749 759 if (suggestedInterface != NULL 750 760 && suggestedInterface->RemoveName("device") == B_OK 751 761 && suggestedInterface->AddString("device", path.Path()) == B_OK … … 782 792 } 783 793 } 784 794 795 LND; 785 796 _ConfigureInterface(socket, interface); 786 797 } 787 798 } … … 817 828 address.AddString("address", "127.0.0.1"); 818 829 interface.AddMessage("address", &address); 819 830 831 LND; 820 832 _ConfigureInterface(socket, interface); 821 833 } 822 834 -
src/servers/net/AutoconfigLooper.cpp
18 18 #include <sys/socket.h> 19 19 #include <sys/sockio.h> 20 20 21 #define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0) 21 22 23 22 24 static const uint32 kMsgReadyToRun = 'rdyr'; 23 25 24 26 … … 27 29 fTarget(target), 28 30 fDevice(device) 29 31 { 32 LND; 30 33 BMessage ready(kMsgReadyToRun); 31 34 PostMessage(&ready); 32 35 } … … 40 43 void 41 44 AutoconfigLooper::_ReadyToRun() 42 45 { 46 LND; 43 47 ifreq request; 44 48 if (!prepare_request(request, fDevice.String())) 45 49 return; 50 LND; 46 51 47 52 // set IFF_CONFIGURING flag on interface 48 53 … … 58 63 close(socket); 59 64 60 65 // start with DHCP 66 LND; 61 67 62 68 DHCPClient* client = new DHCPClient(fTarget, fDevice.String()); 63 69 AddHandler(client); … … 74 80 // TODO: have a look at zeroconf 75 81 // TODO: this could also be done add-on based 76 82 83 LND; 77 84 BMessage interface(kMsgConfigureInterface); 78 85 interface.AddString("device", fDevice.String()); 79 86 interface.AddBool("auto", true);