Ticket #2531: dhcp.4.diff
File dhcp.4.diff, 9.3 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: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n", system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 415 trace_dhcp_state(state); 386 416 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 387 if (socket < 0) 417 if (socket < 0) { 418 LND; 388 419 return errno; 420 } 389 421 390 422 sockaddr_in local; 391 423 memset(&local, 0, sizeof(struct sockaddr_in)); … … 396 428 397 429 if (bind(socket, (struct sockaddr *)&local, sizeof(local)) < 0) { 398 430 close(socket); 431 LND; 399 432 return errno; 400 433 } 401 434 … … 410 443 setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option)); 411 444 412 445 if (state == INIT) { 446 LND; 413 447 // The local interface does not have an address yet, bind the socket 414 448 // to the device directly. 415 449 int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0); 416 450 if (linkSocket >= 0) { 451 LND; 417 452 // we need to know the index of the device to be able to bind to it 418 453 ifreq request; 419 454 prepare_request(request, fDevice.String()); 420 455 if (ioctl(linkSocket, SIOCGIFINDEX, &request, sizeof(struct ifreq)) 421 456 == 0) { 457 LND; 422 458 setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, 423 459 &request.ifr_index, sizeof(int)); 424 460 } … … 448 484 state != RENEWAL ? broadcast : fServer); 449 485 if (status < B_OK) { 450 486 close(socket); 487 LND; 451 488 return status; 452 489 } 453 490 454 491 // receive loop until we've got an offer and acknowledged it 455 492 493 LND; 494 456 495 while (state != ACKNOWLEDGED) { 496 LND; 497 trace_dhcp_state(state); 457 498 char buffer[2048]; 458 499 ssize_t bytesReceived = recvfrom(socket, buffer, sizeof(buffer), 459 500 0, NULL, NULL); 460 501 if (bytesReceived < 0 && errno == B_TIMED_OUT) { 502 LND; 461 503 // depending on the state, we'll just try again 462 504 if (!_TimeoutShift(socket, timeout, tries)) { 505 LND; 463 506 close(socket); 464 507 return B_TIMED_OUT; 465 508 } … … 467 510 if (state == INIT) 468 511 status = _SendMessage(socket, discover, broadcast); 469 512 else { 513 LND; 470 514 status = _SendMessage(socket, request, state != RENEWAL 471 515 ? broadcast : fServer); 472 516 } 473 517 474 518 if (status < B_OK) 475 519 break; 520 LND; 476 521 } else if (bytesReceived < B_OK) 477 522 break; 523 LND; 478 524 479 525 dhcp_message *message = (dhcp_message *)buffer; 480 526 if (message->transaction_id != htonl(fTransactionID) 481 527 || !message->HasOptions() 482 528 || memcmp(message->mac_address, discover.mac_address, 483 529 discover.hardware_address_length)) { 530 LND; 484 531 // this message is not for us 485 532 continue; 486 533 } … … 488 535 switch (message->Type()) { 489 536 case DHCP_NONE: 490 537 default: 538 LND; 491 539 // ignore this message 492 540 break; 493 541 494 542 case DHCP_OFFER: 495 543 { 544 LND; 496 545 // first offer wins 497 546 if (state != INIT) 498 547 break; 548 LND; 499 549 500 550 // collect interface options 501 551 … … 516 566 517 567 _ResetTimeout(socket, timeout, tries); 518 568 state = REQUESTING; 569 trace_dhcp_state(state); 519 570 _PrepareMessage(request, state); 520 571 521 572 status = _SendMessage(socket, request, broadcast); … … 526 577 527 578 case DHCP_ACK: 528 579 { 580 LND; 581 trace_dhcp_state(state); 529 582 if (state != REQUESTING && state != REBINDING 530 583 && state != RENEWAL) 531 584 continue; 585 LND; 532 586 533 587 // TODO: we might want to configure the stuff, don't we? 534 588 BMessage address; … … 548 602 } 549 603 550 604 case DHCP_NACK: 605 LND; 551 606 if (state != REQUESTING) 552 607 continue; 608 LND; 553 609 554 610 // try again (maybe we should prefer other servers if this 555 611 // happens more than once) … … 559 615 break; 560 616 } 561 617 } 618 LND; 619 trace_dhcp_state(state); 562 620 563 621 close(socket); 564 622 565 623 if (status == B_OK && fLeaseTime > 0) { 624 LND; 566 625 // notify early enough when the lease is 567 626 if (fRenewalTime == 0) 568 627 fRenewalTime = fLeaseTime * 2/3; … … 577 636 fRebindingTime += now; 578 637 // make lease times absolute 579 638 } else { 639 LND; 640 ktrace_printf("DHCP: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n", system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 580 641 fLeaseTime = previousLeaseTime; 581 642 bigtime_t now = system_time(); 582 643 fRenewalTime = (fLeaseTime - now) * 2/3 + now; 583 644 fRebindingTime = (fLeaseTime - now) * 5/6 + now; 645 ktrace_printf("DHCP: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n", system_time(), fLeaseTime, fRebindingTime, fRenewalTime); 584 646 } 647 LND; 585 648 586 649 return status; 587 650 } … … 590 653 void 591 654 DHCPClient::_RestartLease(bigtime_t leaseTime) 592 655 { 656 LND; 593 657 if (leaseTime == 0) 594 658 return; 595 659 … … 798 862 DHCPClient::_CurrentState() const 799 863 { 800 864 bigtime_t now = system_time(); 865 866 ktrace_printf("DHCP: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n", now, fLeaseTime, fRebindingTime, fRenewalTime); 801 867 802 868 if (now > fLeaseTime || fStatus < B_OK) 803 869 return INIT; … … 819 885 dhcp_state state = _CurrentState(); 820 886 821 887 bigtime_t next; 888 LND; 889 trace_dhcp_state(state); 822 890 if (_Negotiate(state) == B_OK) { 823 891 switch (state) { 824 892 case RENEWAL: -
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);