- Timestamp:
- Oct 30, 2013 4:45:35 AM (11 years ago)
- Location:
- trunk/src/VBox/NetworkServices/DHCP
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/DHCP/Config.cpp
r49065 r49327 15 15 #include <VBox/version.h> 16 16 17 #include <VBox/com/string.h> 18 19 #include <iprt/cpp/xml.h> 20 17 21 #include "../NetLib/VBoxNetLib.h" 22 #include "../NetLib/shared_ptr.h" 18 23 19 24 #include <list> … … 25 30 26 31 /* types */ 27 class Lease::Data32 class ClientData 28 33 { 29 34 public: 30 Data()35 ClientData() 31 36 { 32 37 m_address.u = 0; 33 m_client = NULL; 38 m_network.u = 0; 39 fHasLease = false; 40 fHasClient = false; 34 41 fBinding = true; 35 42 u64TimestampBindingStarted = 0; … … 40 47 41 48 } 42 ~ Data(){}49 ~ClientData(){} 43 50 51 /* client information */ 44 52 RTNETADDRIPV4 m_address; 45 53 RTNETADDRIPV4 m_network; 54 RTMAC m_mac; 55 56 bool fHasClient; 57 58 /* Lease part */ 59 bool fHasLease; 46 60 /** lease isn't commited */ 47 61 bool fBinding; … … 57 71 uint32_t u32BindExpirationPeriod; 58 72 73 MapOptionId2RawOption options; 74 59 75 NetworkConfigEntity *pCfg; 60 Client *m_client;61 76 }; 62 77 63 78 79 bool operator== (const Lease& lhs, const Lease& rhs) 80 { 81 return (lhs.m.get() == rhs.m.get()); 82 } 83 84 85 bool operator!= (const Lease& lhs, const Lease& rhs) 86 { 87 return !(lhs == rhs); 88 } 89 90 91 bool operator< (const Lease& lhs, const Lease& rhs) 92 { 93 return ( (lhs.getAddress() < rhs.getAddress()) 94 || (lhs.issued() < rhs.issued())); 95 } 64 96 /* consts */ 65 97 … … 74 106 int BaseConfigEntity::match(Client& client, BaseConfigEntity **cfg) 75 107 { 76 int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0); 77 if (m_children.empty()) 108 int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0); 109 if (m_children.empty()) 110 { 111 if (iMatch > 0) 78 112 { 79 if (iMatch > 0) 113 *cfg = this; 114 return iMatch; 115 } 116 } 117 else 118 { 119 *cfg = this; 120 /* XXX: hack */ 121 BaseConfigEntity *matching = this; 122 int matchingLevel = m_MatchLevel; 123 124 for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin(); 125 it != m_children.end(); 126 ++it) 127 { 128 iMatch = (*it)->match(client, &matching); 129 if (iMatch > matchingLevel) 80 130 { 81 *cfg = this;82 returniMatch;131 *cfg = matching; 132 matchingLevel = iMatch; 83 133 } 84 134 } 85 else 86 { 87 *cfg = this; 88 /* XXX: hack */ 89 BaseConfigEntity *matching = this; 90 int matchingLevel = m_MatchLevel; 91 92 for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin(); 93 it != m_children.end(); 94 ++it) 95 { 96 iMatch = (*it)->match(client, &matching); 97 if (iMatch > matchingLevel) 98 { 99 *cfg = matching; 100 matchingLevel = iMatch; 101 } 102 } 103 return matchingLevel; 104 } 105 return iMatch; 135 return matchingLevel; 136 } 137 return iMatch; 106 138 } 107 139 108 140 /* Client */ 109 110 Client::Client(const RTMAC& mac)111 {112 m_mac = mac;113 m_lease = NULL;114 }115 116 141 /* Configs 117 142 NetworkConfigEntity(std::string name, … … 130 155 } 131 156 132 133 157 /* Configuration Manager */ 158 struct ConfigurationManager::Data 159 { 160 Data():fFileExists(false){} 161 162 MapLease2Ip4Address m_allocations; 163 Ipv4AddressContainer m_nameservers; 164 Ipv4AddressContainer m_routers; 165 166 std::string m_domainName; 167 VecClient m_clients; 168 169 bool fFileExists; 170 }; 171 134 172 ConfigurationManager *ConfigurationManager::getConfigurationManager() 135 173 { 136 174 if (!g_ConfigurationManager) 175 { 137 176 g_ConfigurationManager = new ConfigurationManager(); 177 g_ConfigurationManager->init(); 178 } 138 179 139 180 return g_ConfigurationManager; … … 147 188 148 189 149 Client *ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg)190 Client ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg) 150 191 { 151 192 … … 155 196 156 197 fDhcpValid = RTNetIPv4IsDHCPValid(NULL, pDhcpMsg, cbDhcpMsg, &uMsgType); 157 AssertReturn(fDhcpValid, NULL);198 AssertReturn(fDhcpValid, Client::NullClient); 158 199 159 200 LogFlowFunc(("dhcp:mac:%RTmac\n", &pDhcpMsg->bp_chaddr.Mac)); 160 201 /* 1st. client IDs */ 161 for ( it = m _clients.begin();162 it != m _clients.end();202 for ( it = m->m_clients.begin(); 203 it != m->m_clients.end(); 163 204 ++it) 164 205 { 165 if ( *(*it) == pDhcpMsg->bp_chaddr.Mac)206 if ((*it) == pDhcpMsg->bp_chaddr.Mac) 166 207 { 167 LogFlowFunc(("client:mac:%RTmac\n", &(*it)->m_mac));208 LogFlowFunc(("client:mac:%RTmac\n", it->getMacAddress())); 168 209 /* check timestamp that request wasn't expired. */ 169 210 return (*it); … … 171 212 } 172 213 173 if (it == m _clients.end())214 if (it == m->m_clients.end()) 174 215 { 175 216 /* We hasn't got any session for this client */ 176 m_clients.push_back(new Client(pDhcpMsg->bp_chaddr.Mac)); 177 return m_clients.back(); 178 } 179 180 return NULL; 217 Client c; 218 c.initWithMac(pDhcpMsg->bp_chaddr.Mac); 219 m->m_clients.push_back(c); 220 return m->m_clients.back(); 221 } 222 223 return Client::NullClient; 181 224 } 182 225 … … 253 296 * We bind lease for client till it continue with it on DHCPREQUEST. 254 297 */ 255 Lease *ConfigurationManager::allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg) 256 { 257 /** 258 * Well, session hasn't get the config. 259 */ 260 AssertPtrReturn(client, NULL); 261 262 /** 263 * This mean that client has already bound or commited lease. 264 * If we've it happens it means that we received DHCPDISCOVER twice. 265 */ 266 if (client->m_lease) 267 { 268 if (client->m_lease->isExpired()) 269 expireLease4Client(client); 270 else 298 Lease ConfigurationManager::allocateLease4Client(const Client& client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg) 299 { 300 { 301 /** 302 * This mean that client has already bound or commited lease. 303 * If we've it happens it means that we received DHCPDISCOVER twice. 304 */ 305 const Lease l = client.lease(); 306 if (l != Lease::NullLease) 271 307 { 272 AssertReturn(client->m_lease->getAddress().u != 0,NULL); 273 return client->m_lease; 308 /* Here we should take lease from the m_allocation which was feed with leases 309 * on start 310 */ 311 if (l.isExpired()) 312 { 313 expireLease4Client(const_cast<Client&>(client)); 314 if (!l.isExpired()) 315 return l; 316 } 317 else 318 { 319 AssertReturn(l.getAddress().u != 0, Lease::NullLease); 320 return l; 321 } 274 322 } 275 323 } … … 277 325 RTNETADDRIPV4 hintAddress; 278 326 RawOption opt; 279 Lease *please = NULL;280 281 327 NetworkConfigEntity *pNetCfg; 282 328 283 AssertReturn(g_RootConfig->match(*client, (BaseConfigEntity **)&pNetCfg) > 0, NULL); 329 Client cl(client); 330 AssertReturn(g_RootConfig->match(cl, (BaseConfigEntity **)&pNetCfg) > 0, Lease::NullLease); 284 331 285 332 /* DHCPDISCOVER MAY contain request address */ … … 295 342 296 343 if ( hintAddress.u 297 && !isAddressTaken(hintAddress, NULL)) 298 { 299 please = new Lease(); 300 please->init(); 301 please->setConfig(pNetCfg); 302 please->setClient(client); 303 client->m_lease = please; 304 client->m_lease->setAddress(hintAddress); 305 m_allocations[please] = hintAddress; 306 return please; 344 && !isAddressTaken(hintAddress)) 345 { 346 Lease l(cl); 347 l.setConfig(pNetCfg); 348 l.setAddress(hintAddress); 349 m->m_allocations.insert(MapLease2Ip4AddressPair(l, hintAddress)); 350 return l; 307 351 } 308 352 … … 314 358 RTNETADDRIPV4 address; 315 359 address.u = RT_H2N_U32(u32); 316 if (!isAddressTaken(address , NULL))360 if (!isAddressTaken(address)) 317 361 { 318 please = new Lease(); 319 please->init(); 320 please->setConfig(pNetCfg); 321 please->setClient(client); 322 please->setAddress(address); 323 324 client->m_lease = please; 325 326 m_allocations[please] = address; 327 return please; 362 Lease l(cl); 363 l.setConfig(pNetCfg); 364 l.setAddress(address); 365 m->m_allocations.insert(MapLease2Ip4AddressPair(l, address)); 366 return l; 328 367 } 329 368 } 330 369 331 return NULL; 332 } 333 334 335 int ConfigurationManager::commitLease4Client(Client *client) 336 { 337 client->m_lease->bindingPhase(false); 338 339 client->m_lease->setExpiration(client->m_lease->getConfig()->expirationPeriod()); 340 client->m_lease->phaseStart(RTTimeMilliTS()); 370 return Lease::NullLease; 371 } 372 373 374 int ConfigurationManager::commitLease4Client(Client& client) 375 { 376 Lease l = client.lease(); 377 AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR); 378 379 l.bindingPhase(false); 380 const NetworkConfigEntity *pCfg = l.getConfig(); 381 382 AssertPtr(pCfg); 383 l.setExpiration(pCfg->expirationPeriod()); 384 l.phaseStart(RTTimeMilliTS()); 341 385 342 386 return VINF_SUCCESS; 343 387 } 344 388 345 int ConfigurationManager::expireLease4Client(Client *client) 346 { 347 MapLease2Ip4AddressIterator it = m_allocations.find(client->m_lease); 348 AssertReturn(it != m_allocations.end(), VERR_NOT_FOUND); 349 350 m_allocations.erase(it); 351 352 delete client->m_lease; 353 client->m_lease = NULL; 354 389 int ConfigurationManager::expireLease4Client(Client& client) 390 { 391 Lease l = client.lease(); 392 AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR); 393 394 if (l.isInBindingPhase()) 395 { 396 397 MapLease2Ip4AddressIterator it = m->m_allocations.find(l); 398 AssertReturn(it != m->m_allocations.end(), VERR_NOT_FOUND); 399 400 /* 401 * XXX: perhaps it better to keep this allocation ???? 402 */ 403 m->m_allocations.erase(it); 404 405 l.expire(); 406 return VINF_SUCCESS; 407 } 408 409 l = Lease(client); /* re-new */ 355 410 return VINF_SUCCESS; 356 411 } 357 412 358 bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease ** ppLease)413 bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease& lease) 359 414 { 360 415 MapLease2Ip4AddressIterator it; 361 416 362 for (it = m _allocations.begin();363 it != m _allocations.end();417 for (it = m->m_allocations.begin(); 418 it != m->m_allocations.end(); 364 419 ++it) 365 420 { 366 421 if (it->second.u == addr.u) 367 422 { 368 if ( ppLease)369 *ppLease = it->first;423 if (lease != Lease::NullLease) 424 lease = it->first; 370 425 371 426 return true; 372 427 } 373 428 } 429 lease = Lease::NullLease; 374 430 return false; 375 431 } 432 376 433 377 434 NetworkConfigEntity *ConfigurationManager::addNetwork(NetworkConfigEntity *, … … 424 481 { 425 482 case RTNET_DHCP_OPT_DNS: 426 m _nameservers.push_back(address);483 m->m_nameservers.push_back(address); 427 484 break; 428 485 case RTNET_DHCP_OPT_ROUTERS: 429 m _routers.push_back(address);486 m->m_routers.push_back(address); 430 487 break; 431 488 default: … … 435 492 } 436 493 494 437 495 int ConfigurationManager::flushAddressList(uint8_t u8OptId) 438 496 { … … 440 498 { 441 499 case RTNET_DHCP_OPT_DNS: 442 m _nameservers.clear();500 m->m_nameservers.clear(); 443 501 break; 444 502 case RTNET_DHCP_OPT_ROUTERS: 445 m _routers.clear();503 m->m_routers.clear(); 446 504 break; 447 505 default: … … 451 509 } 452 510 511 453 512 const Ipv4AddressContainer& ConfigurationManager::getAddressList(uint8_t u8OptId) 454 513 { … … 456 515 { 457 516 case RTNET_DHCP_OPT_DNS: 458 return m _nameservers;517 return m->m_nameservers; 459 518 460 519 case RTNET_DHCP_OPT_ROUTERS: 461 return m _routers;520 return m->m_routers; 462 521 463 522 } … … 466 525 } 467 526 527 468 528 int ConfigurationManager::setString(uint8_t u8OptId, const std::string& str) 469 529 { … … 471 531 { 472 532 case RTNET_DHCP_OPT_DOMAIN_NAME: 473 m _domainName = str;533 m->m_domainName = str; 474 534 break; 475 535 default: … … 480 540 } 481 541 542 482 543 const std::string& ConfigurationManager::getString(uint8_t u8OptId) 483 544 { … … 485 546 { 486 547 case RTNET_DHCP_OPT_DOMAIN_NAME: 487 if (m _domainName.length())488 return m _domainName;548 if (m->m_domainName.length()) 549 return m->m_domainName; 489 550 else 490 551 return m_noString; … … 496 557 } 497 558 559 560 void ConfigurationManager::init() 561 { 562 m = new ConfigurationManager::Data(); 563 } 564 565 566 ConfigurationManager::~ConfigurationManager() { if (m) delete m; } 567 498 568 /** 499 569 * Network manager … … 511 581 * Network manager creates DHCPOFFER datagramm 512 582 */ 513 int NetworkManager::offer4Client( Client *client, uint32_t u32Xid,583 int NetworkManager::offer4Client(const Client& client, uint32_t u32Xid, 514 584 uint8_t *pu8ReqList, int cReqList) 515 585 { 516 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 517 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 518 586 Lease l(client); /* XXX: oh, it looks badly, but now we have lease */ 519 587 prepareReplyPacket4Client(client, u32Xid); 520 588 521 522 RTNETADDRIPV4 address = client->m_lease->getAddress(); 589 RTNETADDRIPV4 address = l.getAddress(); 523 590 BootPReplyMsg.BootPHeader.bp_yiaddr = address; 524 591 … … 534 601 RT_ZERO(opt); 535 602 536 /* XXX: can't store options per session */ 537 AssertPtr(client); 538 603 std::vector<RawOption> extra(2); 539 604 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE; 540 605 opt.au8RawOpt[0] = RTNET_DHCP_MT_OFFER; 541 606 opt.cbRawOpt = 1; 542 client->rawOptions.push_back(opt);607 extra.push_back(opt); 543 608 544 609 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME; 545 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->getConfig()->expirationPeriod()); 610 611 const NetworkConfigEntity *pCfg = l.getConfig(); 612 AssertPtr(pCfg); 613 614 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(pCfg->expirationPeriod()); 546 615 opt.cbRawOpt = sizeof(RTNETADDRIPV4); 547 client->rawOptions.push_back(opt); 616 617 extra.push_back(opt); 548 618 549 619 processParameterReqList(client, pu8ReqList, cReqList); 550 620 551 return doReply(client );621 return doReply(client, extra); 552 622 } 553 623 … … 556 626 * Network manager creates DHCPACK 557 627 */ 558 int NetworkManager::ack( Client *client, uint32_t u32Xid,628 int NetworkManager::ack(const Client& client, uint32_t u32Xid, 559 629 uint8_t *pu8ReqList, int cReqList) 560 630 { 561 AssertPtrReturn(client, VERR_INTERNAL_ERROR);562 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);563 564 631 RTNETADDRIPV4 address; 565 632 566 633 prepareReplyPacket4Client(client, u32Xid); 567 568 address = client->m_lease->getAddress(); 634 635 Lease l = client.lease(); 636 address = l.getAddress(); 569 637 BootPReplyMsg.BootPHeader.bp_ciaddr = address; 570 638 … … 587 655 RT_ZERO(opt); 588 656 657 std::vector<RawOption> extra(2); 589 658 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE; 590 659 opt.au8RawOpt[0] = RTNET_DHCP_MT_ACK; 591 660 opt.cbRawOpt = 1; 592 client->rawOptions.push_back(opt);661 extra.push_back(opt); 593 662 594 663 /* … … 597 666 */ 598 667 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME; 599 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32( client->m_lease->getExpiration());668 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(l.getExpiration()); 600 669 opt.cbRawOpt = sizeof(RTNETADDRIPV4); 601 client->rawOptions.push_back(opt);670 extra.push_back(opt); 602 671 603 672 processParameterReqList(client, pu8ReqList, cReqList); 604 673 605 return doReply(client );674 return doReply(client, extra); 606 675 } 607 676 … … 610 679 * Network manager creates DHCPNAK 611 680 */ 612 int NetworkManager::nak( Client*client, uint32_t u32Xid)613 { 614 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 615 616 if ( !client->m_lease)681 int NetworkManager::nak(const Client& client, uint32_t u32Xid) 682 { 683 684 Lease l = client.lease(); 685 if (l == Lease::NullLease) 617 686 return VERR_INTERNAL_ERROR; 618 687 … … 629 698 */ 630 699 RawOption opt; 631 RT_ZERO(opt);700 std::vector<RawOption> extra; 632 701 633 702 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE; 634 703 opt.au8RawOpt[0] = RTNET_DHCP_MT_NAC; 635 704 opt.cbRawOpt = 1; 636 client->rawOptions.push_back(opt);637 638 return doReply(client );705 extra.push_back(opt); 706 707 return doReply(client, extra); 639 708 } 640 709 … … 643 712 * 644 713 */ 645 int NetworkManager::prepareReplyPacket4Client(Client *client, uint32_t u32Xid) 646 { 647 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 648 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 649 714 int NetworkManager::prepareReplyPacket4Client(const Client& client, uint32_t u32Xid) 715 { 650 716 memset(&BootPReplyMsg, 0, sizeof(BootPReplyMsg)); 651 717 … … 661 727 BootPReplyMsg.BootPHeader.bp_giaddr.u = 0; 662 728 663 BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client->m_mac; 664 665 BootPReplyMsg.BootPHeader.bp_yiaddr = client->m_lease->getAddress(); 729 BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client.getMacAddress(); 730 731 const Lease l = client.lease(); 732 BootPReplyMsg.BootPHeader.bp_yiaddr = l.getAddress(); 666 733 BootPReplyMsg.BootPHeader.bp_siaddr.u = 0; 667 734 … … 677 744 678 745 679 int NetworkManager::doReply( Client *client)746 int NetworkManager::doReply(const Client& client, const std::vector<RawOption>& extra) 680 747 { 681 748 int rc; 682 683 AssertPtrReturn(client, VERR_INTERNAL_ERROR);684 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR);685 749 686 750 /* … … 693 757 Cursor.optIPv4Addr(RTNET_DHCP_OPT_SERVER_ID, m_OurAddress); 694 758 695 while(!client->rawOptions.empty()) 696 { 697 RawOption opt = client->rawOptions.back(); 698 if (!Cursor.begin(opt.u8OptId, opt.cbRawOpt)) 759 const Lease l = client.lease(); 760 const std::map<uint8_t, RawOption>& options = l.options(); 761 762 for(std::vector<RawOption>::const_iterator it = extra.begin(); 763 it != extra.end(); ++it) 764 { 765 if (!Cursor.begin(it->u8OptId, it->cbRawOpt)) 699 766 break; 700 Cursor.put( opt.au8RawOpt, opt.cbRawOpt);701 702 client->rawOptions.pop_back();703 } 704 705 706 if (!client->rawOptions.empty())707 {708 Log(("Wasn't able to put all options\n"));709 /* force clean up */710 client->rawOptions.clear(); 767 Cursor.put(it->au8RawOpt, it->cbRawOpt); 768 769 } 770 771 for(std::map<uint8_t, RawOption>::const_iterator it = options.begin(); 772 it != options.end(); ++it) 773 { 774 if (!Cursor.begin(it->second.u8OptId, it->second.cbRawOpt)) 775 break; 776 Cursor.put(it->second.au8RawOpt, it->second.cbRawOpt); 777 711 778 } 712 779 … … 716 783 */ 717 784 #if 0 718 if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) /** @todo need to see someone set this flag to check that it's correct. */ 785 /** @todo need to see someone set this flag to check that it's correct. */ 786 if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) 719 787 { 720 788 rc = VBoxNetUDPUnicast(m_pSession, … … 746 814 747 815 748 int NetworkManager::processParameterReqList( Client*client, uint8_t *pu8ReqList, int cReqList)816 int NetworkManager::processParameterReqList(const Client& client, uint8_t *pu8ReqList, int cReqList) 749 817 { 750 818 /* request parameter list */ … … 752 820 int idxParam = 0; 753 821 754 AssertPtrReturn(client, VERR_INTERNAL_ERROR);755 756 822 uint8_t *pReqList = pu8ReqList; 757 758 const NetworkConfigEntity *pNetCfg = client->m_lease->getConfig(); 823 824 const Lease const_l = client.lease(); 825 Lease l = Lease(const_l); 826 827 const NetworkConfigEntity *pNetCfg = l.getConfig(); 759 828 760 829 for (idxParam = 0; idxParam < cReqList; ++idxParam) 761 830 { 762 831 832 bool fIgnore = false; 763 833 RT_ZERO(opt); 764 834 opt.u8OptId = pReqList[idxParam]; 835 765 836 switch(pReqList[idxParam]) 766 837 { … … 768 839 ((PRTNETADDRIPV4)opt.au8RawOpt)->u = pNetCfg->netmask().u; 769 840 opt.cbRawOpt = sizeof(RTNETADDRIPV4); 770 client->rawOptions.push_back(opt); 841 771 842 break; 772 843 … … 787 858 } 788 859 789 if ( !lst.empty())790 client->rawOptions.push_back(opt);860 if (lst.empty()) 861 fIgnore = true; 791 862 } 792 863 break; … … 795 866 std::string domainName = g_ConfigurationManager->getString(pReqList[idxParam]); 796 867 if (domainName == g_ConfigurationManager->m_noString) 868 { 869 fIgnore = true; 797 870 break; 871 } 798 872 799 873 char *pszDomainName = (char *)&opt.au8RawOpt[0]; … … 801 875 strcpy(pszDomainName, domainName.c_str()); 802 876 opt.cbRawOpt = domainName.length(); 803 client->rawOptions.push_back(opt);804 877 } 805 878 break; 806 879 default: 807 880 Log(("opt: %d is ignored\n", pReqList[idxParam])); 881 fIgnore = true; 808 882 break; 809 883 } 884 885 if (!fIgnore) 886 l.options().insert(std::map<uint8_t, RawOption>::value_type(opt.u8OptId, opt)); 887 810 888 } 811 889 … … 813 891 } 814 892 815 816 Lease::~Lease() 817 { 818 if (m) 819 delete m; 820 } 821 822 823 void Lease::init() 824 { 825 if (!m) 826 m = new Lease::Data(); 893 /* Utility */ 894 bool operator== (const RTMAC& lhs, const RTMAC& rhs) 895 { 896 return ( lhs.au16[0] == rhs.au16[0] 897 && lhs.au16[1] == rhs.au16[1] 898 && lhs.au16[2] == rhs.au16[2]); 899 } 900 901 902 /* Client */ 903 Client::Client() 904 { 905 m = SharedPtr<ClientData>(); 906 } 907 908 909 void Client::initWithMac(const RTMAC& mac) 910 { 911 m = SharedPtr<ClientData>(new ClientData()); 912 m->m_mac = mac; 913 } 914 915 916 bool Client::operator== (const RTMAC& mac) const 917 { 918 return (m.get() && m->m_mac == mac); 919 } 920 921 922 const RTMAC& Client::getMacAddress() const 923 { 924 return m->m_mac; 925 } 926 927 928 Lease Client::lease() 929 { 930 if (!m.get()) return Lease::NullLease; 931 932 if (m->fHasLease) 933 return Lease(*this); 934 else 935 return Lease::NullLease; 936 } 937 938 939 const Lease Client::lease() const 940 { 941 return const_cast<Client *>(this)->lease(); 942 } 943 944 945 Client::Client(ClientData *data):m(SharedPtr<ClientData>(data)){} 946 947 /* Lease */ 948 Lease::Lease() 949 { 950 m = SharedPtr<ClientData>(); 951 } 952 953 954 Lease::Lease (const Client& c) 955 { 956 m = SharedPtr<ClientData>(c.m); 957 if ( !m->fHasLease 958 || ( isExpired() 959 && !isInBindingPhase())) 960 { 961 m->fHasLease = true; 962 m->fBinding = true; 963 phaseStart(RTTimeMilliTS()); 964 } 827 965 } 828 966 … … 830 968 bool Lease::isExpired() const 831 969 { 832 AssertPtrReturn(m , false);970 AssertPtrReturn(m.get(), false); 833 971 834 972 if (!m->fBinding) … … 841 979 842 980 981 void Lease::expire() 982 { 983 /* XXX: TODO */ 984 } 985 986 843 987 void Lease::phaseStart(uint64_t u64Start) 844 988 { … … 862 1006 863 1007 1008 uint64_t Lease::issued() const 1009 { 1010 return m->u64TimestampLeasingStarted; 1011 } 1012 1013 864 1014 void Lease::setExpiration(uint32_t exp) 865 1015 { … … 904 1054 905 1055 906 Client *Lease::getClient() const 907 { 908 return m->m_client; 909 } 910 911 void Lease::setClient(Client *client) 912 { 913 m->m_client = client; 914 } 1056 const MapOptionId2RawOption& Lease::options() const 1057 { 1058 return m->options; 1059 } 1060 1061 1062 MapOptionId2RawOption& Lease::options() 1063 { 1064 return m->options; 1065 } 1066 1067 1068 Lease::Lease(ClientData *pd):m(SharedPtr<ClientData>(pd)){} 1069 1070 1071 const Lease Lease::NullLease; 1072 1073 1074 const Client Client::NullClient; -
trunk/src/VBox/NetworkServices/DHCP/Config.h
r49063 r49327 10 10 #include <iprt/cpp/utils.h> 11 11 12 typedef std::vector<RTMAC> MacAddressContainer;13 typedef MacAddressContainer::iterator MacAddressIterator;14 15 typedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer;16 typedef Ipv4AddressContainer::iterator Ipv4AddressIterator;17 typedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator;18 12 19 13 static bool operator <(const RTNETADDRIPV4& a, const RTNETADDRIPV4& b) … … 31 25 { 32 26 public: 27 RawOption() 28 { 29 RT_ZERO(*this); 30 } 33 31 uint8_t u8OptId; 34 32 uint8_t cbRawOpt; … … 36 34 }; 37 35 38 36 class ClientData; 39 37 class Client; 40 38 class Lease; 41 39 class BaseConfigEntity; 42 40 43 44 41 class NetworkConfigEntity; 45 42 class HostConfigEntity; 46 43 class ClientMatchCriteria; 47 48 typedef std::map<Lease *, RTNETADDRIPV4> MapLease2Ip4Address; 49 typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator; 50 typedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair; 44 class ConfigurationManager; 51 45 52 46 /* … … 61 55 class Client 62 56 { 57 friend class Lease; 58 friend class ConfigurationManager; 59 63 60 public: 64 65 /* XXX: Option 60 and 61 */ 66 Client(const RTMAC& mac); 67 68 bool operator== (const RTMAC& mac) const 69 { 70 return ( m_mac.au16[0] == mac.au16[0] 71 && m_mac.au16[1] == mac.au16[1] 72 && m_mac.au16[2] == mac.au16[2]); 73 } 61 Client(); 62 void initWithMac(const RTMAC& mac); 63 bool operator== (const RTMAC& mac) const; 64 const RTMAC& getMacAddress() const; 65 74 66 /** Dumps client query */ 75 67 void dump(); 76 68 77 /* XXX! private: */ 78 79 RTMAC m_mac; 80 Lease *m_lease; 81 82 /* XXX: should be in lease */ 83 std::vector<RawOption> rawOptions; 84 }; 85 86 87 typedef std::vector<Client*> VecClient; 69 Lease lease(); 70 const Lease lease() const; 71 72 public: 73 static const Client NullClient; 74 75 private: 76 Client(ClientData *); 77 SharedPtr<ClientData> m; 78 }; 79 80 81 bool operator== (const Lease&, const Lease&); 82 bool operator!= (const Lease&, const Lease&); 83 bool operator< (const Lease&, const Lease&); 84 85 86 typedef std::map<uint8_t, RawOption> MapOptionId2RawOption; 87 typedef MapOptionId2RawOption::iterator MapOptionId2RawOptionIterator; 88 typedef MapOptionId2RawOption::const_iterator MapOptionId2RawOptionConstIterator; 89 typedef MapOptionId2RawOption::value_type MapOptionId2RawOptionValue; 90 91 namespace xml { 92 class ElementNode; 93 } 94 95 class Lease 96 { 97 friend class Client; 98 friend bool operator== (const Lease&, const Lease&); 99 //friend int ConfigurationManager::loadFromFile(const std::string&); 100 friend class ConfigurationManager; 101 102 public: 103 Lease(); 104 Lease(const Client&); 105 106 bool isExpired() const; 107 void expire(); 108 109 /* Depending on phase *Expiration and phaseStart initialize different values. */ 110 void bindingPhase(bool); 111 void phaseStart(uint64_t u64Start); 112 bool isInBindingPhase() const; 113 /* returns 0 if in binding state */ 114 uint64_t issued() const; 115 116 void setExpiration(uint32_t); 117 uint32_t getExpiration() const; 118 119 RTNETADDRIPV4 getAddress() const; 120 void setAddress(RTNETADDRIPV4); 121 122 const NetworkConfigEntity *getConfig() const; 123 void setConfig(NetworkConfigEntity *); 124 125 const MapOptionId2RawOption& options() const; 126 MapOptionId2RawOption& options(); 127 128 129 public: 130 static const Lease NullLease; 131 132 private: 133 Lease(ClientData *); 134 SharedPtr<ClientData> m; 135 }; 136 137 138 typedef std::vector<Client> VecClient; 88 139 typedef VecClient::iterator VecClientIterator; 89 140 typedef VecClient::const_iterator VecClientConstIterator; 141 142 typedef std::vector<RTMAC> MacAddressContainer; 143 typedef MacAddressContainer::iterator MacAddressIterator; 144 145 typedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer; 146 typedef Ipv4AddressContainer::iterator Ipv4AddressIterator; 147 typedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator; 148 149 typedef std::map<Lease, RTNETADDRIPV4> MapLease2Ip4Address; 150 typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator; 151 typedef MapLease2Ip4Address::const_iterator MapLease2Ip4AddressConstIterator; 152 typedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair; 90 153 91 154 … … 130 193 return (m_left->check(client) && m_right->check(client)); 131 194 } 195 132 196 private: 133 197 ClientMatchCriteria* m_left; … … 156 220 return (client == m_mac); 157 221 } 222 158 223 private: 159 224 RTMAC m_mac; … … 185 250 class BaseConfigEntity 186 251 { 187 public:252 public: 188 253 BaseConfigEntity(const ClientMatchCriteria *criteria = NULL, 189 254 int matchingLevel = 0) … … 202 267 virtual uint32_t expirationPeriod() const = 0; 203 268 204 protected:269 protected: 205 270 const ClientMatchCriteria *m_criteria; 206 271 int m_MatchLevel; … … 211 276 class NullConfigEntity: public BaseConfigEntity 212 277 { 213 public:278 public: 214 279 NullConfigEntity(){} 215 280 virtual ~NullConfigEntity(){} 216 int add(BaseConfigEntity *) const 217 { 218 return 0; 219 } 281 int add(BaseConfigEntity *) const { return 0;} 220 282 virtual uint32_t expirationPeriod() const {return 0;} 221 283 }; … … 224 286 class ConfigEntity: public BaseConfigEntity 225 287 { 226 public:288 public: 227 289 /* range */ 228 290 /* match conditions */ … … 320 382 /* upper addr == lower addr */ 321 383 } 322 323 virtual int match(const Client& client) const324 {325 return (m_criteria->check(client) ? 10 : 0);326 }327 328 384 }; 329 385 … … 368 424 * 369 425 */ 370 Client *getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg);426 Client getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg); 371 427 372 428 /** … … 375 431 * allocation)... 376 432 */ 377 Lease * allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg);433 Lease allocateLease4Client(const Client& client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg); 378 434 379 435 /** … … 381 437 * when requested configuration is acceptable. 382 438 */ 383 int commitLease4Client(Client *client);439 int commitLease4Client(Client& client); 384 440 385 441 /** 386 442 * Expires client lease. 387 443 */ 388 int expireLease4Client(Client *client);444 int expireLease4Client(Client& client); 389 445 390 446 static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt); … … 404 460 405 461 private: 406 ConfigurationManager(){} 407 virtual ~ConfigurationManager(){} 408 bool isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease = NULL); 462 ConfigurationManager():m(NULL){} 463 void init(); 464 465 ~ConfigurationManager(); 466 bool isAddressTaken(const RTNETADDRIPV4& addr, Lease& lease); 467 bool isAddressTaken(const RTNETADDRIPV4& addr) 468 { 469 Lease ignore; 470 return isAddressTaken(addr, ignore); 471 } 409 472 410 473 public: … … 414 477 415 478 private: 416 MapLease2Ip4Address m_allocations; 417 /** 418 * Here we can store expired Leases to do not re-allocate them latter. 419 */ 420 421 /* XXX: MapLease2Ip4Address m_freed; */ 422 /* XXX: more universal storages are required. */ 423 Ipv4AddressContainer m_nameservers; 424 Ipv4AddressContainer m_routers; 425 426 std::string m_domainName; 427 VecClient m_clients; 479 struct Data; 480 Data *m; 428 481 }; 429 482 … … 434 487 static NetworkManager *getNetworkManager(); 435 488 436 int offer4Client( Client*lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);437 int ack( Client *lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList);438 int nak( Client *lease, uint32_t u32Xid);489 int offer4Client(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList); 490 int ack(const Client& lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList); 491 int nak(const Client& lease, uint32_t u32Xid); 439 492 440 493 const RTNETADDRIPV4& getOurAddress(){ return m_OurAddress;} … … 455 508 virtual ~NetworkManager(){} 456 509 457 int prepareReplyPacket4Client( Client *client, uint32_t u32Xid);458 int doReply( Client *client);459 int processParameterReqList( Client *client, uint8_t *pu8ReqList, int cReqList);510 int prepareReplyPacket4Client(const Client& client, uint32_t u32Xid); 511 int doReply(const Client& client, const std::vector<RawOption>& extra); 512 int processParameterReqList(const Client& client, uint8_t *pu8ReqList, int cReqList); 460 513 461 514 union { … … 469 522 RTMAC m_OurMac; 470 523 }; 471 472 473 474 class Lease475 {476 public:477 Lease():m(NULL){};478 ~Lease();479 void init();480 481 bool isExpired() const;482 483 /* Depending on phase *Expiration and phaseStart initialize different values. */484 void bindingPhase(bool);485 void phaseStart(uint64_t u64Start);486 bool isInBindingPhase() const;487 488 void setExpiration(uint32_t);489 uint32_t getExpiration() const;490 491 RTNETADDRIPV4 getAddress() const;492 void setAddress(RTNETADDRIPV4);493 494 const NetworkConfigEntity *getConfig() const;495 void setConfig(NetworkConfigEntity *);496 497 Client *getClient() const;498 void setClient(Client *);499 500 private:501 class Data;502 503 Data *m;504 };505 506 524 507 525 -
trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
r49113 r49327 56 56 57 57 #include "../NetLib/VBoxNetLib.h" 58 #include "../NetLib/shared_ptr.h" 58 59 59 60 #include <vector> … … 470 471 471 472 } 473 472 474 } 473 475 … … 725 727 /* 1. Find client */ 726 728 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager(); 727 Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);729 Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb); 728 730 729 731 /* 2. Find/Bind lease for client */ 730 Lease *lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);731 Assert PtrReturn(lease, VINF_SUCCESS);732 Lease lease = confManager->allocateLease4Client(client, pDhcpMsg, cb); 733 AssertReturn(lease != Lease::NullLease, VINF_SUCCESS); 732 734 733 735 int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt); … … 736 738 NetworkManager *networkManager = NetworkManager::getNetworkManager(); 737 739 738 lease ->bindingPhase(true);739 lease ->phaseStart(RTTimeMilliTS());740 lease ->setExpiration(300); /* 3 min. */740 lease.bindingPhase(true); 741 lease.phaseStart(RTTimeMilliTS()); 742 lease.setExpiration(300); /* 3 min. */ 741 743 networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt); 742 744 } /* end of if(!m_DhcpServer.isNull()) */ … … 760 762 761 763 /* 1. find client */ 762 Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);764 Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb); 763 765 764 766 /* 2. find bound lease */ 765 if (client->m_lease) 766 { 767 768 if (client->m_lease->isExpired()) 767 Lease l = client.lease(); 768 if (l != Lease::NullLease) 769 { 770 771 if (l.isExpired()) 769 772 { 770 773 /* send client to INIT state */ 774 Client c(client); 771 775 networkManager->nak(client, pDhcpMsg->bp_xid); 772 confManager->expireLease4Client(c lient);776 confManager->expireLease4Client(c); 773 777 return true; 774 778 } 775 /* XXX: Validate request */ 776 RawOption opt; 777 memset((void *)&opt, 0, sizeof(RawOption)); 778 779 int rc = confManager->commitLease4Client(client); 780 AssertRCReturn(rc, false); 781 782 rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt); 783 AssertRCReturn(rc, false); 784 785 networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt); 779 else { 780 /* XXX: Validate request */ 781 RawOption opt; 782 RT_ZERO(opt); 783 784 Client c(client); 785 int rc = confManager->commitLease4Client(c); 786 AssertRCReturn(rc, false); 787 788 rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt); 789 AssertRCReturn(rc, false); 790 791 networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt); 792 } 786 793 } 787 794 else
Note:
See TracChangeset
for help on using the changeset viewer.