Changeset 79818 in vbox for trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp
- Timestamp:
- Jul 16, 2019 7:00:06 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 132192
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/Dhcpd/Db.cpp
r79568 r79818 70 70 if (b->m_state == Binding::FREE) 71 71 cb += pfnOutput(pvArgOutput, RT_STR_TUPLE(" free")); 72 else if (b->m_fFixed) 73 cb += pfnOutput(pvArgOutput, RT_STR_TUPLE(" fixed")); 72 74 else 73 75 { … … 87 89 } 88 90 91 92 /** 93 * Used to update the client ID of a fixed address assignment. 94 * 95 * We only have the MAC address when prepraring the binding, so the full client 96 * ID must be supplied when the client requests it. 97 * 98 * @param a_ridClient The client ID. 99 * @throws std::bad_alloc 100 */ 101 void Binding::idUpdate(const ClientId &a_ridClient) 102 { 103 AssertReturnVoid(isFixed()); 104 m_id = a_ridClient; 105 } 106 107 108 /** 109 * Get the state as a string for the XML lease database. 110 */ 89 111 const char *Binding::stateName() const RT_NOEXCEPT 90 112 { … … 108 130 109 131 132 /** 133 * Sets the state by name (reverse of Binding::stateName()). 134 */ 110 135 Binding &Binding::setState(const char *pszStateName) RT_NOEXCEPT 111 136 { … … 139 164 bool Binding::expire(Timestamp tsDeadline) RT_NOEXCEPT 140 165 { 141 if (m_state <= Binding::EXPIRED )166 if (m_state <= Binding::EXPIRED || m_fFixed) 142 167 return false; 143 168 … … 338 363 m_pConfig = pConfig; 339 364 340 return m_pool.init(pConfig->getIPv4PoolFirst(), pConfig->getIPv4PoolLast()); 365 int rc = m_pool.init(pConfig->getIPv4PoolFirst(), pConfig->getIPv4PoolLast()); 366 if (RT_SUCCESS(rc)) 367 { 368 /* 369 * If the server IP is in the dynamic range, preallocate it like a fixed assignment. 370 */ 371 rc = i_enterFixedAddressAssignment(pConfig->getIPv4Address(), pConfig->getMacAddress()); 372 if (RT_SUCCESS(rc)) 373 { 374 /* 375 * Preallocate any fixed address assignments: 376 */ 377 Config::HostConfigVec vecHostConfigs; 378 rc = pConfig->getFixedAddressConfigs(vecHostConfigs); 379 for (Config::HostConfigVec::const_iterator it = vecHostConfigs.begin(); 380 it != vecHostConfigs.end() && RT_SUCCESS(rc); ++it) 381 rc = i_enterFixedAddressAssignment((*it)->getFixedAddress(), (*it)->getMACAddress()); 382 } 383 } 384 385 return rc; 386 } 387 388 389 /** 390 * Used by Db::init() to register a fixed address assignment. 391 * 392 * @returns IPRT status code. 393 * @param a_rAddress The IPv4 address assignment. 394 * @param a_rMACAddress The MAC address. 395 */ 396 int Db::i_enterFixedAddressAssignment(RTNETADDRIPV4 const &a_rAddress, RTMAC const &a_rMACAddress) RT_NOEXCEPT 397 { 398 LogRelFunc(("%RTmac: %RTnaipv4\n", &a_rMACAddress, a_rAddress)); 399 Assert(m_pConfig->isInIPv4Network(a_rAddress)); /* should've been checked elsewhere already */ 400 401 /* 402 * If the address is part of the pool, we have to allocate it to 403 * prevent it from being used again. 404 */ 405 if (m_pool.contains(a_rAddress)) 406 { 407 if (!m_pool.allocate(a_rAddress)) 408 { 409 LogRelFunc(("%RTnaipv4 already allocated?\n", a_rAddress)); 410 return VERR_ADDRESS_CONFLICT; 411 } 412 } 413 414 /* 415 * Create the binding. 416 */ 417 Binding *pBinding = NULL; 418 try 419 { 420 pBinding = new Binding(a_rAddress, a_rMACAddress, true /*fFixed*/); 421 m_bindings.push_front(pBinding); 422 } 423 catch (std::bad_alloc &) 424 { 425 if (pBinding) 426 delete pBinding; 427 return VERR_NO_MEMORY; 428 } 429 return VINF_SUCCESS; 341 430 } 342 431 … … 442 531 /* 443 532 * We've already seen this client, give it its old binding. 533 * 534 * If the client's MAC address is configured with a fixed 535 * address, give its preconfigured binding. Fixed bindings 536 * are always at the head of the m_bindings list, so we 537 * won't be confused by any old leases of the client. 444 538 */ 445 539 if (b->m_id == id) 446 540 { 447 541 LogRel(("> ... found existing binding %R[binding]\n", b)); 542 return b; 543 } 544 if (b->isFixed() && b->id().mac() == id.mac()) 545 { 546 b->idUpdate(id); 547 LogRel(("> ... found fixed binding %R[binding]\n", b)); 448 548 return b; 449 549 } … … 552 652 Binding *Db::allocateBinding(const DhcpClientMessage &req) 553 653 { 554 /** @todo XXX: handle fixed address assignments */654 const ClientId &id(req.clientId()); 555 655 556 656 /* 557 657 * Get and validate the requested address (if present). 658 * 659 * Fixed assignments are often outside the dynamic range, so we much detect 660 * those to make sure they aren't rejected based on IP range. ASSUMES fixed 661 * assignments are at the head of the binding list. 558 662 */ 559 663 OptRequestedAddress reqAddr(req); 560 664 if (reqAddr.present() && !addressBelongs(reqAddr.value())) 561 665 { 562 if (req.messageType() == RTNET_DHCP_MT_DISCOVER) 666 bool fIsFixed = false; 667 for (bindings_t::iterator it = m_bindings.begin(); it != m_bindings.end() && (*it)->isFixed(); ++it) 668 if (reqAddr.value().u == (*it)->addr().u) 669 { 670 if ( (*it)->id() == id 671 || (*it)->id().mac() == id.mac()) 672 { 673 fIsFixed = true; 674 break; 675 } 676 } 677 if (fIsFixed) 678 reqAddr = OptRequestedAddress(); 679 else if (req.messageType() == RTNET_DHCP_MT_DISCOVER) 563 680 { 564 681 LogRel(("DISCOVER: ignoring invalid requested address\n")); … … 572 689 * Allocate the address. 573 690 */ 574 const ClientId &id(req.clientId());575 576 691 Binding *b = i_allocateAddress(id, reqAddr.value()); 577 692 if (b != NULL) … … 668 783 { 669 784 LogRel2(("Db::cancelOffer: cancelling %R[binding]\n", b)); 670 b->setLeaseTime(0); 671 b->setState(Binding::RELEASED); 785 if (!b->isFixed()) 786 { 787 b->setLeaseTime(0); 788 b->setState(Binding::RELEASED); 789 } 790 else 791 b->setState(Binding::ACKED); 672 792 } 673 793 else … … 699 819 { 700 820 LogRel2(("Db::releaseBinding: releasing %R[binding]\n", b)); 701 b->setState(Binding::RELEASED); 702 return true; 821 if (!b->isFixed()) 822 { 823 b->setState(Binding::RELEASED); 824 return true; 825 } 826 b->setState(Binding::ACKED); 827 return false; 703 828 } 704 829 } … … 741 866 { 742 867 const Binding *b = *it; 743 b->toXML(pElmRoot); 868 if (!b->isFixed()) 869 b->toXML(pElmRoot); 744 870 } 745 871 }
Note:
See TracChangeset
for help on using the changeset viewer.