Changeset 47501 in vbox
- Timestamp:
- Aug 1, 2013 6:24:41 AM (11 years ago)
- Location:
- trunk/src/VBox/NetworkServices/DHCP
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/DHCP/Config.cpp
r47129 r47501 36 36 37 37 const NullConfigEntity *g_NullConfig = new NullConfigEntity(); 38 const RootConfigEntity *g_RootConfig = new RootConfigEntity(std::string("ROOT"));38 RootConfigEntity *g_RootConfig = new RootConfigEntity(std::string("ROOT"), 1200 /* 20 min. */); 39 39 const ClientMatchCriteria *g_AnyClient = new AnyClientMatchCriteria(); 40 40 41 static SessionManager *g_SessionManager = SessionManager::getSessionManager();42 41 static ConfigurationManager *g_ConfigurationManager = ConfigurationManager::getConfigurationManager(); 43 42 44 43 static NetworkManager *g_NetworkManager = NetworkManager::getNetworkManager(); 45 44 45 46 46 47 /* Client */ 47 48 48 Client::Client(const RTMAC& mac , uint32_t xid)49 Client::Client(const RTMAC& mac) 49 50 { 50 51 m_mac = mac; 51 // m_sessions.insert(Map2ClientSessionType(xid, Session(this, xid))); 52 } 53 54 /* Session */ 55 56 bool Session::operator < (const Session& s) const 57 { 58 return (m_u32Xid < s.m_u32Xid); 59 } 60 61 int Session::switchTo(CLIENTSESSIONSTATE enmState) 62 { 63 m_state = enmState; 64 return VINF_SUCCESS; 52 m_lease = NULL; 65 53 } 66 54 … … 74 62 static const RTNETADDRIPV4 g_AnyIpv4 = {0}; 75 63 static const RTNETADDRIPV4 g_AllIpv4 = {0xffffffff}; 76 RootConfigEntity::RootConfigEntity(std::string name ):64 RootConfigEntity::RootConfigEntity(std::string name, uint32_t expPeriod): 77 65 NetworkConfigEntity(name, g_NullConfig, g_AnyClient, g_AnyIpv4, g_AllIpv4) 78 66 { 79 67 m_MatchLevel = 2; 80 } 81 82 /* Session Manager */ 83 SessionManager *SessionManager::getSessionManager() 84 { 85 if (!g_SessionManager) 86 g_SessionManager = new SessionManager(); 87 return g_SessionManager; 88 } 89 90 /* 91 * XXX: it sounds like a hack, we use packet descriptor to get the session, 92 * instead use corresponding functions in NetworkManager to fetch client identification 93 * (note: it isn't only mac driven) and XID for the session. 94 */ 95 96 /** 97 * XXX: what about leases ... Lease is a committed Session.... 98 */ 99 Session& SessionManager::getClientSessionByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg) 68 m_u32ExpirationPeriod = expPeriod; 69 } 70 71 72 /* Configuration Manager */ 73 ConfigurationManager *ConfigurationManager::getConfigurationManager() 74 { 75 if (!g_ConfigurationManager) 76 g_ConfigurationManager = new ConfigurationManager(); 77 78 return g_ConfigurationManager; 79 } 80 81 82 int ConfigurationManager::extractRequestList(PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& rawOpt) 83 { 84 return ConfigurationManager::findOption(RTNET_DHCP_OPT_PARAM_REQ_LIST, pDhcpMsg, cbDhcpMsg, rawOpt); 85 } 86 87 88 Client *ConfigurationManager::getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg) 100 89 { 101 90 … … 103 92 bool fDhcpValid = false; 104 93 uint8_t uMsgType = 0; 105 94 106 95 fDhcpValid = RTNetIPv4IsDHCPValid(NULL, pDhcpMsg, cbDhcpMsg, &uMsgType); 107 Assert(fDhcpValid); 108 96 AssertReturn(fDhcpValid, NULL); 97 98 LogFlowFunc(("dhcp:mac:%RTmac\n", &pDhcpMsg->bp_chaddr.Mac)); 109 99 /* 1st. client IDs */ 110 100 for ( it = m_clients.begin(); … … 112 102 ++it) 113 103 { 114 /* OK. */ 115 if ((*it) == pDhcpMsg->bp_chaddr.Mac) 116 break; 117 } 118 119 const uint32_t xid = pDhcpMsg->bp_xid; 104 if (*(*it) == pDhcpMsg->bp_chaddr.Mac) 105 { 106 LogFlowFunc(("client:mac:%RTmac\n", &(*it)->m_mac)); 107 /* check timestamp that request wasn't expired. */ 108 return (*it); 109 } 110 } 111 120 112 if (it == m_clients.end()) 121 113 { 122 114 /* We hasn't got any session for this client */ 123 m_clients.push_back(Client(pDhcpMsg->bp_chaddr.Mac, 124 pDhcpMsg->bp_xid)); 125 Client& client = m_clients.back(); 126 client.m_sessions.insert(Map2ClientSessionType(xid, Session(&client, xid))); 127 Assert(client.m_sessions[xid].m_pClient); 128 return client.m_sessions[xid]; 129 } 130 131 Session& session = it->m_sessions[xid]; 132 session.m_pClient = &(*it); 133 session.m_u32Xid = xid; 134 135 RawOption opt; 136 int rc; 137 138 switch(uMsgType) 139 { 140 case RTNET_DHCP_MT_DISCOVER: 141 session.switchTo(DHCPDISCOVERRECEIEVED); 142 /* MAY */ 143 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_REQ_ADDR, pDhcpMsg, cbDhcpMsg, opt); 144 if (RT_SUCCESS(rc)) 145 { 146 /* hint for address allocation here */ 147 session.addressHint = *(PRTNETADDRIPV4)opt.au8RawOpt; 148 } 149 /* MAY: todo */ 150 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_LEASE_TIME, pDhcpMsg, cbDhcpMsg, opt); 151 152 /* MAY: not now */ 153 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_CLIENT_ID, pDhcpMsg, cbDhcpMsg, opt); 154 /* XXX: MAY 155 ConfigurationManager::findOption(RTNET_DHCP_OPT_VENDOR_CLASS_IDENTIFIER, pDhcpMsg, opt); 156 */ 157 /* MAY: well */ 158 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_PARAM_REQ_LIST, pDhcpMsg, cbDhcpMsg, opt); 159 if (RT_SUCCESS(rc)) 160 memcpy(&session.reqParamList, &opt, sizeof(RawOption)); 161 162 /* MAY: todo */ 163 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE, pDhcpMsg, cbDhcpMsg, opt); 164 165 break; 166 167 case RTNET_DHCP_MT_REQUEST: 168 session.switchTo(DHCPREQUESTRECEIVED); 169 /* MUST in (SELECTING. INIT-REBOOT) MUST NOT BOUND. RENEW MAY */ 170 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_REQ_ADDR, pDhcpMsg, cbDhcpMsg, opt); 171 if (RT_SUCCESS(rc)) 172 { 173 /* hint for address allocation here */ 174 session.addressHint = *(PRTNETADDRIPV4)opt.au8RawOpt; 175 } 176 177 /* MAY */ 178 ConfigurationManager::findOption(RTNET_DHCP_OPT_LEASE_TIME, pDhcpMsg, cbDhcpMsg, opt); 179 /* MAY */ 180 ConfigurationManager::findOption(RTNET_DHCP_OPT_CLIENT_ID, pDhcpMsg, cbDhcpMsg, opt); 181 /* XXX: MAY 182 ConfigurationManager::findOption(RTNET_DHCP_OPT_VENDOR_CLASS_IDENTIFIER, pDhcpMsg, opt); 183 */ 184 /* MAY */ 185 rc = ConfigurationManager::findOption(RTNET_DHCP_OPT_PARAM_REQ_LIST, pDhcpMsg, cbDhcpMsg, opt); 186 if (RT_SUCCESS(rc)) 187 memcpy(&session.reqParamList, &opt, sizeof(RawOption)); 188 189 /* MAY */ 190 ConfigurationManager::findOption(RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE, pDhcpMsg, cbDhcpMsg, opt); 191 192 break; 193 194 case RTNET_DHCP_MT_DECLINE: 195 case RTNET_DHCP_MT_OFFER: 196 case RTNET_DHCP_MT_ACK: 197 case RTNET_DHCP_MT_NAC: 198 case RTNET_DHCP_MT_RELEASE: 199 case RTNET_DHCP_MT_INFORM: 200 AssertMsgFailed(("unimplemented")); 201 } 202 203 Assert(session.m_pClient); 204 return session; 205 } 206 207 void SessionManager::releaseClientSession(Session& session) 208 { 209 } 210 211 void SessionManager::releaseClient(Client& client) 212 { 213 } 214 215 216 /* Configuration Manager */ 217 ConfigurationManager *ConfigurationManager::getConfigurationManager() 218 { 219 if (!g_ConfigurationManager) 220 g_ConfigurationManager = new ConfigurationManager(); 221 222 return g_ConfigurationManager; 223 } 224 115 m_clients.push_back(new Client(pDhcpMsg->bp_chaddr.Mac)); 116 return m_clients.back(); 117 } 118 119 return NULL; 120 } 225 121 226 122 /** … … 272 168 else 273 169 { 274 size_t 170 size_t cbCur = pb[1]; 275 171 if (cbCur > cbLeft - 2) 276 172 cbCur = cbLeft - 2; … … 294 190 295 191 /** 296 * We've find the config for session ... 297 * XXX: using Session's private members 298 */ 299 int ConfigurationManager::findConfiguration4Session(Session& session) 300 { 301 /* XXX: state switching broken? 302 * XXX: DHCPDECLINE and DHCPINFO should we support them. 303 */ 304 AssertReturn( session.m_state == DHCPDISCOVERRECEIEVED 305 || session.m_state == DHCPREQUESTRECEIVED, VERR_INTERNAL_ERROR); 306 307 if (session.m_pCfg) 308 return VINF_SUCCESS; 309 310 Assert(session.m_pClient); 311 if (g_RootConfig->match(*session.m_pClient, &session.m_pCfg) > 0) 312 return VINF_SUCCESS; 313 else 314 return VERR_INTERNAL_ERROR; /* XXX: is it really *internal* error? Perhaps some misconfiguration */ 315 316 } 317 318 /** 319 * What we are archieveing here is non commited lease () 320 */ 321 int ConfigurationManager::allocateConfiguration4Session(Session& session) 192 * We bind lease for client till it continue with it on DHCPREQUEST. 193 */ 194 Lease *ConfigurationManager::allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg) 322 195 { 323 196 /** 324 197 * Well, session hasn't get the config. 325 198 */ 326 AssertPtrReturn(session.m_pCfg, VERR_INTERNAL_ERROR); 327 328 bool fWithAddressHint = (session.addressHint.u != 0); 329 330 if (fWithAddressHint) 331 { 332 if (m_allocations[session].u == session.addressHint.u) 199 AssertPtrReturn(client, NULL); 200 201 /** 202 * This mean that client has already bound or commited lease. 203 * If we've it happens it means that we received DHCPDISCOVER twice. 204 */ 205 if (client->m_lease) 206 { 207 if (client->m_lease->isExpired()) 208 expireLease4Client(client); 209 else 333 210 { 334 /* Good, our hint matches allocation */335 return VINF_SUCCESS;211 AssertReturn(client->m_lease->m_address.u != 0,NULL); 212 return client->m_lease; 336 213 } 337 /** 338 * This definetly depends on client state ... 339 * AssertMsgFailed(("Debug Me")); 340 * Workaround #1 341 * clear and ignore. 342 */ 343 fWithAddressHint = false; 344 session.addressHint.u = 0; 345 } 346 347 /* 348 * We've received DHCPDISCOVER 349 */ 350 AssertReturn(session.m_state == DHCPDISCOVERRECEIEVED, VERR_INTERNAL_ERROR); 351 352 /** 353 * XXX: this is wrong allocation check... 354 * session initilized by client shouldn't be equal to lease in STL terms. 355 */ 356 MapSession2Ip4AddressIterator it = m_allocations.find(session); 357 358 if (it == m_allocations.end()) 359 { 360 /* XXX: not optimal allocation */ 361 const NetworkConfigEntity *pNetCfg = dynamic_cast<const NetworkConfigEntity *>(session.m_pCfg); 362 363 /** 364 * Check config class. 365 */ 366 AssertPtrReturn(pNetCfg, VERR_INTERNAL_ERROR); 367 368 uint32_t u32Address = RT_N2H_U32(pNetCfg->lowerIp().u); 369 while (u32Address < RT_N2H_U32(pNetCfg->upperIp().u)) 214 } 215 216 RTNETADDRIPV4 hintAddress; 217 RawOption opt; 218 Lease *please = NULL; 219 220 NetworkConfigEntity *pNetCfg; 221 222 AssertReturn(g_RootConfig->match(*client, (BaseConfigEntity **)&pNetCfg) > 0, NULL); 223 224 /* DHCPDISCOVER MAY contain request address */ 225 hintAddress.u = 0; 226 int rc = findOption(RTNET_DHCP_OPT_REQ_ADDR, pDhcpMsg, cbDhcpMsg, opt); 227 if (RT_SUCCESS(rc)) 228 { 229 hintAddress.u = *(uint32_t *)opt.au8RawOpt; 230 if ( !RT_H2N_U32(hintAddress.u) < RT_H2N_U32(pNetCfg->lowerIp().u) 231 || !RT_H2N_U32(hintAddress.u) > RT_H2N_U32(pNetCfg->upperIp().u)) 232 hintAddress.u = 0; /* clear hint */ 233 } 234 235 if ( hintAddress.u 236 && !isAddressTaken(hintAddress, NULL)) 237 { 238 please = new Lease(); 239 please->pCfg = pNetCfg; 240 please->m_client = client; 241 client->m_lease = please; 242 client->m_lease->m_address = hintAddress; 243 m_allocations[please] = hintAddress; 244 return please; 245 } 246 247 uint32_t u32 = 0; 248 for(u32 = RT_H2N_U32(pNetCfg->lowerIp().u); 249 u32 <= RT_H2N_U32(pNetCfg->upperIp().u); 250 ++u32) 251 { 252 RTNETADDRIPV4 address; 253 address.u = RT_H2N_U32(u32); 254 if (!isAddressTaken(address, NULL)) 370 255 { 371 372 /* u32Address in host format */ 373 MapSession2Ip4AddressIterator addressIterator; 374 bool fFound = false; 375 376 for (addressIterator = m_allocations.begin(); 377 addressIterator != m_allocations.end(); 378 ++addressIterator) 379 { 380 if (RT_N2H_U32(addressIterator->second.u) == u32Address) 381 { 382 /* 383 * This address is taken 384 * XXX: check if session isn't expired... if expired we can 385 * reuse it for this request 386 */ 387 /* XXX: fTakeAddress = true; owning session is expired */ 388 fFound = true; 389 break; 390 } 391 } /* end of for over allocations */ 392 393 if (!fFound) 394 { 395 RTNETADDRIPV4 address = { RT_H2N_U32_C(u32Address)}; 396 m_allocations.insert(MapSession2Ip4AddressPair(session, address)); 397 session.switchTo(DHCPOFFERPREPARED); 398 return VINF_SUCCESS; 399 } 400 401 u32Address ++; 402 } /* end of while over candidates */ 403 404 } 405 406 /* XXX: really??? */ 407 session.switchTo(DHCPOFFERPREPARED); 256 please = new Lease(); 257 please->pCfg = pNetCfg; 258 please->m_client = client; 259 client->m_lease = please; 260 client->m_lease->m_address = address; 261 m_allocations[please] = client->m_lease->m_address; 262 return please; 263 } 264 } 265 266 return NULL; 267 } 268 269 270 int ConfigurationManager::commitLease4Client(Client *client) 271 { 272 client->m_lease->u64TimestampBindingStarted = 0; 273 client->m_lease->u32LeaseExpirationPeriod = client->m_lease->pCfg->expirationPeriod(); 274 client->m_lease->u64TimestampLeasingStarted = RTTimeMilliTS(); 275 client->m_lease->fBinding = false; 408 276 return VINF_SUCCESS; 409 277 } 410 278 411 412 int ConfigurationManager::commitConfiguration4ClientSession(Session& session) 413 { 414 /**/ 415 session.switchTo(DHCPACKNAKPREPARED); 416 417 /* XXX: clean up the rest of the session, now this session LEASE!!! */ 279 int ConfigurationManager::expireLease4Client(Client *client) 280 { 281 MapLease2Ip4AddressIterator it = m_allocations.find(client->m_lease); 282 AssertReturn(it != m_allocations.end(), VERR_NOT_FOUND); 283 284 m_allocations.erase(it); 285 286 delete client->m_lease; 287 client->m_lease = NULL; 288 418 289 return VINF_SUCCESS; 419 290 } 420 291 421 RTNETADDRIPV4 ConfigurationManager::getSessionAddress(const Session& session) 422 { 423 return m_allocations[session]; 424 } 425 292 bool ConfigurationManager::isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease) 293 { 294 MapLease2Ip4AddressIterator it; 295 296 for (it = m_allocations.begin(); 297 it != m_allocations.end(); 298 ++it) 299 { 300 if (it->second.u == addr.u) 301 { 302 if (ppLease) 303 *ppLease = it->first; 304 305 return true; 306 } 307 } 308 return false; 309 } 426 310 427 311 NetworkConfigEntity *ConfigurationManager::addNetwork(NetworkConfigEntity *pCfg, … … 484 368 * Network manager creates DHCPOFFER datagramm 485 369 */ 486 int NetworkManager::offer4Session(Session& session) 487 { 488 AssertReturn(session.m_state == DHCPOFFERPREPARED, VERR_INTERNAL_ERROR); 489 490 prepareReplyPacket4Session(session); 491 492 RTNETADDRIPV4 address = ConfigurationManager::getConfigurationManager()->getSessionAddress(session); 370 int NetworkManager::offer4Client(Client *client, uint32_t u32Xid, 371 uint8_t *pu8ReqList, int cReqList) 372 { 373 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 374 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 375 376 prepareReplyPacket4Client(client, u32Xid); 377 378 379 RTNETADDRIPV4 address = client->m_lease->m_address; 493 380 BootPReplyMsg.BootPHeader.bp_yiaddr = address; 494 381 … … 505 392 506 393 /* XXX: can't store options per session */ 507 Client *client = unconst(session.m_pClient);508 394 AssertPtr(client); 509 395 … … 514 400 515 401 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME; 516 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32( ConfigurationManager::getConfigurationManager()->getLeaseTime());402 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->pCfg->expirationPeriod()); 517 403 opt.cbRawOpt = sizeof(RTNETADDRIPV4); 518 404 client->rawOptions.push_back(opt); 519 405 520 processParameterReqList( session);521 522 return doReply( session);406 processParameterReqList(client, pu8ReqList, cReqList); 407 408 return doReply(client); 523 409 } 524 410 … … 527 413 * Network manager creates DHCPACK 528 414 */ 529 int NetworkManager::ack(Session& session) 530 { 415 int NetworkManager::ack(Client *client, uint32_t u32Xid, 416 uint8_t *pu8ReqList, int cReqList) 417 { 418 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 419 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 420 531 421 RTNETADDRIPV4 address; 532 422 533 AssertReturn(session.m_state == DHCPACKNAKPREPARED, VERR_INTERNAL_ERROR); 534 prepareReplyPacket4Session(session); 535 536 address = ConfigurationManager::getConfigurationManager()->getSessionAddress(session); 423 prepareReplyPacket4Client(client, u32Xid); 424 425 address = client->m_lease->m_address; 537 426 BootPReplyMsg.BootPHeader.bp_ciaddr = address; 538 427 … … 542 431 * XXX: Using addressHint is not correct way to initialize [cy]iaddress... 543 432 */ 544 BootPReplyMsg.BootPHeader.bp_ciaddr = session.addressHint;545 BootPReplyMsg.BootPHeader.bp_yiaddr = session.addressHint;433 BootPReplyMsg.BootPHeader.bp_ciaddr = client->m_lease->m_address; 434 BootPReplyMsg.BootPHeader.bp_yiaddr = client->m_lease->m_address; 546 435 547 436 Assert(BootPReplyMsg.BootPHeader.bp_yiaddr.u); … … 555 444 RT_ZERO(opt); 556 445 557 /* XXX: can't store options per session */558 Client *client = unconst(session.m_pClient);559 AssertPtr(client);560 561 446 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE; 562 447 opt.au8RawOpt[0] = RTNET_DHCP_MT_ACK; … … 569 454 */ 570 455 opt.u8OptId = RTNET_DHCP_OPT_LEASE_TIME; 571 *(uint32_t *)opt.au8RawOpt = 572 RT_H2N_U32(ConfigurationManager::getConfigurationManager()->getLeaseTime()); 456 *(uint32_t *)opt.au8RawOpt = RT_H2N_U32(client->m_lease->u32LeaseExpirationPeriod); 573 457 opt.cbRawOpt = sizeof(RTNETADDRIPV4); 574 458 client->rawOptions.push_back(opt); 575 459 576 processParameterReqList(session); 577 578 return doReply(session); 579 460 processParameterReqList(client, pu8ReqList, cReqList); 461 462 return doReply(client); 580 463 } 581 464 … … 584 467 * Network manager creates DHCPNAK 585 468 */ 586 int NetworkManager::nak(Session& session) 587 { 588 AssertReturn(session.m_state == DHCPACKNAKPREPARED, VERR_INTERNAL_ERROR); 589 590 prepareReplyPacket4Session(session); 469 int NetworkManager::nak(Client* client, uint32_t u32Xid) 470 { 471 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 472 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 473 474 prepareReplyPacket4Client(client, u32Xid); 591 475 592 476 /* this field filed in prepareReplyPacket4Session, and … … 601 485 RawOption opt; 602 486 RT_ZERO(opt); 603 604 /* XXX: can't store options per session */605 Client *client = unconst(session.m_pClient);606 AssertPtr(client);607 487 608 488 opt.u8OptId = RTNET_DHCP_OPT_MSG_TYPE; … … 611 491 client->rawOptions.push_back(opt); 612 492 613 return doReply( session);493 return doReply(client); 614 494 } 615 495 … … 618 498 * 619 499 */ 620 int NetworkManager::prepareReplyPacket4Session(const Session& session) 621 { 500 int NetworkManager::prepareReplyPacket4Client(Client *client, uint32_t u32Xid) 501 { 502 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 503 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 504 622 505 memset(&BootPReplyMsg, 0, sizeof(BootPReplyMsg)); 623 506 … … 626 509 BootPReplyMsg.BootPHeader.bp_hlen = sizeof(RTMAC); 627 510 BootPReplyMsg.BootPHeader.bp_hops = 0; 628 BootPReplyMsg.BootPHeader.bp_xid = session.m_u32Xid;511 BootPReplyMsg.BootPHeader.bp_xid = u32Xid; 629 512 BootPReplyMsg.BootPHeader.bp_secs = 0; 630 513 /* XXX: bp_flags should be processed specially */ … … 633 516 BootPReplyMsg.BootPHeader.bp_giaddr.u = 0; 634 517 635 Assert(session.m_pClient); 636 BootPReplyMsg.BootPHeader.bp_chaddr.Mac = session.m_pClient->m_mac; 637 638 BootPReplyMsg.BootPHeader.bp_yiaddr = 639 ConfigurationManager::getConfigurationManager()->getSessionAddress(session); 640 518 BootPReplyMsg.BootPHeader.bp_chaddr.Mac = client->m_mac; 519 520 BootPReplyMsg.BootPHeader.bp_yiaddr = client->m_lease->m_address; 641 521 BootPReplyMsg.BootPHeader.bp_siaddr.u = 0; 642 522 … … 652 532 653 533 654 int NetworkManager::doReply( const Session& session)534 int NetworkManager::doReply(Client *client) 655 535 { 656 536 int rc; 537 538 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 539 AssertPtrReturn(client->m_lease, VERR_INTERNAL_ERROR); 657 540 658 541 /* … … 661 544 VBoxNetDhcpWriteCursor Cursor(&BootPReplyMsg.BootPHeader, RTNET_DHCP_NORMAL_SIZE); 662 545 663 /* XXX: unconst */664 Client *cl = unconst(session.m_pClient);665 AssertPtrReturn(cl, VERR_INTERNAL_ERROR);666 667 546 /* The basics */ 668 547 669 548 Cursor.optIPv4Addr(RTNET_DHCP_OPT_SERVER_ID, m_OurAddress); 670 549 671 while(!cl ->rawOptions.empty())672 { 673 RawOption opt = cl ->rawOptions.back();550 while(!client->rawOptions.empty()) 551 { 552 RawOption opt = client->rawOptions.back(); 674 553 if (!Cursor.begin(opt.u8OptId, opt.cbRawOpt)) 675 554 break; 676 555 Cursor.put(opt.au8RawOpt, opt.cbRawOpt); 677 556 678 cl ->rawOptions.pop_back();679 } 680 681 682 if (!cl ->rawOptions.empty())557 client->rawOptions.pop_back(); 558 } 559 560 561 if (!client->rawOptions.empty()) 683 562 { 684 563 Log(("Wasn't able to put all options\n")); 685 564 /* force clean up */ 686 cl ->rawOptions.clear();565 client->rawOptions.clear(); 687 566 } 688 567 689 568 Cursor.optEnd(); 690 691 switch (session.m_state)692 {693 case DHCPOFFERPREPARED:694 break;695 case DHCPACKNAKPREPARED:696 break;697 default:698 AssertMsgFailedReturn(("Unsupported state(%d)\n", session.m_state), VERR_INTERNAL_ERROR);699 }700 569 701 570 /* … … 732 601 733 602 734 int NetworkManager::processParameterReqList( Session& session)603 int NetworkManager::processParameterReqList(Client* client, uint8_t *pu8ReqList, int cReqList) 735 604 { 736 605 /* request parameter list */ … … 738 607 int idxParam = 0; 739 608 740 uint8_t *pReqList = session.reqParamList.au8RawOpt; 741 742 const NetworkConfigEntity *pNetCfg = dynamic_cast<const NetworkConfigEntity *>(session.m_pCfg); 743 744 /* XXX: can't store options per session */ 745 Client *client = unconst(session.m_pClient); 746 AssertPtr(client); 747 748 749 for (idxParam = 0; idxParam < session.reqParamList.cbRawOpt; ++idxParam) 609 AssertPtrReturn(client, VERR_INTERNAL_ERROR); 610 611 uint8_t *pReqList = pu8ReqList; 612 613 const NetworkConfigEntity *pNetCfg = client->m_lease->pCfg; 614 615 for (idxParam = 0; idxParam < cReqList; ++idxParam) 750 616 { 751 617 … … 762 628 case RTNET_DHCP_OPT_ROUTERS: 763 629 { 764 const Ipv4AddressContainer lst = g_ConfigurationManager->getAddressList(RTNET_DHCP_OPT_ROUTERS); 630 const Ipv4AddressContainer lst = 631 g_ConfigurationManager->getAddressList( 632 RTNET_DHCP_OPT_ROUTERS); 765 633 PRTNETADDRIPV4 pAddresses = (PRTNETADDRIPV4)&opt.au8RawOpt[0]; 766 634 -
trunk/src/VBox/NetworkServices/DHCP/Config.h
r47020 r47501 7 7 # define _CONFIG_H_ 8 8 9 #include <iprt/asm-math.h> 9 10 #include <iprt/cpp/utils.h> 10 11 … … 25 26 return (b < a); 26 27 } 27 28 29 typedef enum CLIENTSESSIONSTATE30 {31 /**32 * defult state, session isn't operable, not initialized an so on.33 */34 DHCPNONSENSE,35 /** We've received dhcp discover =>36 * we're starting new client and/or session.37 * Using XID (we record session)38 * and response with DHCPOFFER39 */40 DHCPDISCOVERRECEIEVED,41 /**42 * We're ready to send DHCPOFFER43 */44 DHCPOFFERPREPARED,45 /**46 * This more, session state, we responsed, to47 * client with DHCPOFFER using session's XID48 */49 DHCPOFFERSENT,50 /**51 * this is session's state, client's done DHCPREQUEST with (XID)52 */53 DHCPREQUESTRECEIVED,54 /**55 * We're ready to send DHCPACK or DHCPNAK56 */57 DHCPACKNAKPREPARED,58 /**59 * We've been able to furfill client's request for (XID) session, erased others Client60 * 's sessions ... and send DHCPACK (should be Lease bind at this point?)61 */62 DHCPACKSENT,63 /**64 * We couldn't furfill client's request -> destroy session.65 */66 DHCPNACKSENT,67 /**68 * real client, don't want our DHCPOFFER, we're delating our client representation,69 * and sessions objects.70 */71 DHCPDECLINERECEIVED,72 /**73 * nice to have, but not mandatory.74 */75 DHCPINFORMRECEIVED76 } CLIENTSESSIONSTATE;77 28 78 29 … … 87 38 88 39 class Client; 40 class Lease; 89 41 class BaseConfigEntity; 90 42 91 /** 92 * This class joins client and the lease ... 93 * at the begining client might request several address assignments... 94 * 95 * So session here is descriptor joining client to each of it's requests. 96 * When client finalizes its selection ... only single assignment is chosen, 97 * others are released. 98 */ 99 class Session 100 { 101 public: 102 Session(const Client *client = NULL, 103 uint32_t xid = 0, 104 CLIENTSESSIONSTATE enmState = DHCPNONSENSE): 105 m_pClient(client), 106 m_state(enmState), 107 m_u32Xid(xid), 108 m_pCfg(NULL) 109 { 110 /* XXX: state ? Which is acceptable on initialization ?! */ 111 addressHint.u = 0; 112 RT_ZERO(reqParamList); 113 } 114 115 bool operator < (const Session& s) const; 116 117 int switchTo(CLIENTSESSIONSTATE); 118 /* XXX private: */ 119 120 /**/ 121 const Client* m_pClient; 122 /* We don't store the state in the client, because client might initiate several 123 * sessions. 124 */ 125 CLIENTSESSIONSTATE m_state; 126 /** 127 * uniq identificator of session 128 */ 129 uint32_t m_u32Xid; 130 131 /* dhcp-opts: request address */ 132 RTNETADDRIPV4 addressHint; 133 134 /* dhcp-opts: request parameter list */ 135 RawOption reqParamList; 136 /* Config for this session */ 137 const BaseConfigEntity *m_pCfg; 138 139 /** 140 * times used for evaluating wherther Session/Lease could be expired. 141 */ 142 143 RTTIMESPEC creation; 144 RTTIMESPEC expiration; 145 }; 146 147 typedef std::map<uint32_t, Session> Map2ClientSession; 148 typedef Map2ClientSession::value_type Map2ClientSessionType; 149 typedef Map2ClientSession::iterator Map2ClientSessionIterator; 150 151 class Lease 152 { 153 public: 154 Lease(const Session& session):m_pClient(session.m_pClient){} 155 virtual ~Lease(){} 156 private: 157 const Client *m_pClient; 158 159 bool operator == (const Session& session) const 160 { 161 /* XXX: pointer comparison, perhaps not we really need */ 162 return (session.m_pClient == m_pClient); 163 } 164 }; 165 166 typedef std::map<Lease, RTNETADDRIPV4> MapLease2Ip4Address; 43 44 class NetworkConfigEntity; 45 class HostConfigEntity; 46 class ClientMatchCriteria; 47 48 typedef std::map<Lease *, RTNETADDRIPV4> MapLease2Ip4Address; 49 typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator; 167 50 typedef MapLease2Ip4Address::value_type MapLease2Ip4AddressPair; 168 typedef MapLease2Ip4Address::iterator MapLease2Ip4AddressIterator;169 51 170 52 /* … … 182 64 183 65 /* XXX: Option 60 and 61 */ 184 Client(const RTMAC& mac , uint32_t xid = 0);66 Client(const RTMAC& mac); 185 67 186 68 bool operator== (const RTMAC& mac) const … … 196 78 197 79 RTMAC m_mac; 198 Map2ClientSession m_sessions;199 /* XXX: it's logically per session object, but some client broke XIDness */ 200 /* XXX: we're using it as stack*/80 Lease *m_lease; 81 82 /* XXX: should be in lease */ 201 83 std::vector<RawOption> rawOptions; 202 84 }; 203 85 204 86 205 typedef std::vector<Client > VecClient;87 typedef std::vector<Client*> VecClient; 206 88 typedef VecClient::iterator VecClientIterator; 207 89 typedef VecClient::const_iterator VecClientConstIterator; 208 90 209 210 class SessionManager211 {212 public:213 214 static SessionManager* getSessionManager();215 216 /**217 * This method we call on every DHCP packet we've received.218 * 1. it finds/creates Client/and Session Object.219 */220 Session& getClientSessionByDhcpPacket(const RTNETBOOTP* pDhcpMsg, size_t cbPacket);221 222 /* XXX: DHCPDECLINE */223 void releaseClientSession(Session& session);224 /* XXX: DHCPRELEASE */225 void releaseClient(Client& client);226 227 private:228 229 VecClient m_clients;230 231 SessionManager(){}232 virtual ~SessionManager(){}233 };234 235 236 typedef std::map<Session, RTNETADDRIPV4> MapSession2Ip4Address;237 typedef MapSession2Ip4Address::iterator MapSession2Ip4AddressIterator;238 typedef MapSession2Ip4Address::value_type MapSession2Ip4AddressPair;239 240 class NetworkConfigEntity;241 class HostConfigEntity;242 class ClientMatchCriteria;243 244 class ConfigurationManager245 {246 public:247 static ConfigurationManager* getConfigurationManager();248 249 /**250 * We call this on DHCPDISCOVER251 */252 int findConfiguration4Session(Session& session);253 254 /**255 * XXX: it's could be done on DHCPOFFER or on DHCPACK (rfc2131 gives freedom here256 * 3.1.2, what is strict that allocation should do address check before real257 * allocation)...258 */259 int allocateConfiguration4Session(Session& session);260 261 /*262 * We call this before DHCPACK sent and after DHCPREQUEST received ...263 * when requested configuration is acceptable.264 */265 int commitConfiguration4ClientSession(Session& sesion);266 267 static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt);268 269 NetworkConfigEntity *addNetwork(NetworkConfigEntity *pCfg,270 const RTNETADDRIPV4& networkId,271 const RTNETADDRIPV4& netmask,272 RTNETADDRIPV4& UpperAddress,273 RTNETADDRIPV4& LowerAddress);274 275 HostConfigEntity *addHost(NetworkConfigEntity*, const RTNETADDRIPV4&, ClientMatchCriteria*);276 277 RTNETADDRIPV4 getSessionAddress(const Session& session);278 279 /* XXX: from config */280 uint32_t getLeaseTime() {return 600;}281 282 int addToAddressList(uint8_t u8OptId, RTNETADDRIPV4& address)283 {284 switch(u8OptId)285 {286 case RTNET_DHCP_OPT_DNS:287 m_nameservers.push_back(address);288 break;289 case RTNET_DHCP_OPT_ROUTERS:290 m_routers.push_back(address);291 break;292 default:293 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));294 }295 return VINF_SUCCESS;296 }297 298 int flushAddressList(uint8_t u8OptId)299 {300 switch(u8OptId)301 {302 case RTNET_DHCP_OPT_DNS:303 m_nameservers.clear();304 break;305 case RTNET_DHCP_OPT_ROUTERS:306 m_routers.clear();307 break;308 default:309 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));310 }311 return VINF_SUCCESS;312 }313 314 const Ipv4AddressContainer& getAddressList(uint8_t u8OptId)315 {316 switch(u8OptId)317 {318 case RTNET_DHCP_OPT_DNS:319 return m_nameservers;320 321 case RTNET_DHCP_OPT_ROUTERS:322 return m_routers;323 324 }325 /* XXX: Grrr !!! */326 return m_empty;327 }328 329 private:330 ConfigurationManager(){}331 virtual ~ConfigurationManager(){}332 MapSession2Ip4Address m_allocations;333 /*334 *335 */336 Ipv4AddressContainer m_nameservers;337 Ipv4AddressContainer m_routers;338 Ipv4AddressContainer m_empty;339 340 };341 342 343 class NetworkManager344 {345 public:346 static NetworkManager *getNetworkManager();347 348 int offer4Session(Session& ses);349 int ack(Session& ses);350 int nak(Session& ses);351 352 const RTNETADDRIPV4& getOurAddress(){ return m_OurAddress;}353 const RTNETADDRIPV4& getOurNetmask(){ return m_OurNetmask;}354 const RTMAC& getOurMac() {return m_OurMac;}355 356 void setOurAddress(const RTNETADDRIPV4& aAddress){ m_OurAddress = aAddress;}357 void setOurNetmask(const RTNETADDRIPV4& aNetmask){ m_OurNetmask = aNetmask;}358 void setOurMac(const RTMAC& aMac) {m_OurMac = aMac;}359 360 /* XXX: artifacts should be hidden or removed from here. */361 PSUPDRVSESSION m_pSession;362 INTNETIFHANDLE m_hIf;363 PINTNETBUF m_pIfBuf;364 365 private:366 int prepareReplyPacket4Session(const Session& session);367 int doReply(const Session& session);368 int processParameterReqList(Session& session);369 370 union {371 RTNETBOOTP BootPHeader;372 uint8_t au8Storage[1024];373 } BootPReplyMsg;374 int cbBooPReplyMsg;375 376 RTNETADDRIPV4 m_OurAddress;377 RTNETADDRIPV4 m_OurNetmask;378 RTMAC m_OurMac;379 380 NetworkManager(){}381 virtual ~NetworkManager(){}382 };383 91 384 92 /** … … 476 184 public: 477 185 BaseConfigEntity(const ClientMatchCriteria *criteria = NULL, 478 186 int matchingLevel = 0) 479 187 : m_criteria(criteria), 480 188 m_MatchLevel(matchingLevel){}; … … 488 196 489 197 /* Should return how strong matching */ 490 virtual int match( const Client& client, const BaseConfigEntity **cfg) const198 virtual int match(Client& client, BaseConfigEntity **cfg) 491 199 { 492 200 int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0); … … 503 211 *cfg = this; 504 212 /* XXX: hack */ 505 BaseConfigEntity const*matching = this;213 BaseConfigEntity *matching = this; 506 214 int matchingLevel = m_MatchLevel; 507 215 508 for (std::vector< const BaseConfigEntity *>::const_iterator it = m_children.begin();216 for (std::vector<BaseConfigEntity *>::iterator it = m_children.begin(); 509 217 it != m_children.end(); 510 218 ++it) … … 521 229 return iMatch; 522 230 } 523 231 virtual uint32_t expirationPeriod() const = 0; 524 232 protected: 525 233 const ClientMatchCriteria *m_criteria; 526 234 int m_MatchLevel; 527 std::vector< constBaseConfigEntity *> m_children;235 std::vector<BaseConfigEntity *> m_children; 528 236 }; 529 237 … … 538 246 return 0; 539 247 } 248 virtual uint32_t expirationPeriod() const {return 0;} 540 249 }; 541 250 … … 560 269 std::string m_name; 561 270 const BaseConfigEntity *m_parentCfg; 271 virtual uint32_t expirationPeriod() const 272 { 273 if (!m_u32ExpirationPeriod) 274 return m_parentCfg->expirationPeriod(); 275 else 276 return m_u32ExpirationPeriod; 277 } 278 279 /* XXX: private:*/ 280 uint32_t m_u32ExpirationPeriod; 562 281 }; 563 282 … … 646 365 { 647 366 public: 648 RootConfigEntity(std::string name );367 RootConfigEntity(std::string name, uint32_t expirationPeriod); 649 368 virtual ~RootConfigEntity(){}; 650 369 }; … … 675 394 #endif 676 395 396 class ConfigurationManager 397 { 398 public: 399 static ConfigurationManager* getConfigurationManager(); 400 static int extractRequestList(PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& rawOpt); 401 402 /** 403 * 404 */ 405 Client* getClientByDhcpPacket(const RTNETBOOTP *pDhcpMsg, size_t cbDhcpMsg); 406 407 /** 408 * XXX: it's could be done on DHCPOFFER or on DHCPACK (rfc2131 gives freedom here 409 * 3.1.2, what is strict that allocation should do address check before real 410 * allocation)... 411 */ 412 Lease* allocateLease4Client(Client *client, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg); 413 414 /** 415 * We call this before DHCPACK sent and after DHCPREQUEST received ... 416 * when requested configuration is acceptable. 417 */ 418 int commitLease4Client(Client *client); 419 420 /** 421 * Expires client lease. 422 */ 423 int expireLease4Client(Client *client); 424 425 static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt); 426 427 NetworkConfigEntity *addNetwork(NetworkConfigEntity *pCfg, 428 const RTNETADDRIPV4& networkId, 429 const RTNETADDRIPV4& netmask, 430 RTNETADDRIPV4& UpperAddress, 431 RTNETADDRIPV4& LowerAddress); 432 433 HostConfigEntity *addHost(NetworkConfigEntity*, const RTNETADDRIPV4&, ClientMatchCriteria*); 434 435 int addToAddressList(uint8_t u8OptId, RTNETADDRIPV4& address) 436 { 437 switch(u8OptId) 438 { 439 case RTNET_DHCP_OPT_DNS: 440 m_nameservers.push_back(address); 441 break; 442 case RTNET_DHCP_OPT_ROUTERS: 443 m_routers.push_back(address); 444 break; 445 default: 446 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId)); 447 } 448 return VINF_SUCCESS; 449 } 450 451 int flushAddressList(uint8_t u8OptId) 452 { 453 switch(u8OptId) 454 { 455 case RTNET_DHCP_OPT_DNS: 456 m_nameservers.clear(); 457 break; 458 case RTNET_DHCP_OPT_ROUTERS: 459 m_routers.clear(); 460 break; 461 default: 462 Log(("dhcp-opt: list (%d) unsupported\n", u8OptId)); 463 } 464 return VINF_SUCCESS; 465 } 466 467 const Ipv4AddressContainer& getAddressList(uint8_t u8OptId) 468 { 469 switch(u8OptId) 470 { 471 case RTNET_DHCP_OPT_DNS: 472 return m_nameservers; 473 474 case RTNET_DHCP_OPT_ROUTERS: 475 return m_routers; 476 477 } 478 /* XXX: Grrr !!! */ 479 return m_empty; 480 } 481 482 private: 483 ConfigurationManager(){} 484 virtual ~ConfigurationManager(){} 485 486 bool isAddressTaken(const RTNETADDRIPV4& addr, Lease** ppLease = NULL); 487 MapLease2Ip4Address m_allocations; 488 /** 489 * Here we can store expired Leases to do not re-allocate them latter. 490 */ 491 /* XXX: MapLease2Ip4Address m_freed; */ 492 /* 493 * 494 */ 495 Ipv4AddressContainer m_nameservers; 496 Ipv4AddressContainer m_routers; 497 Ipv4AddressContainer m_empty; 498 VecClient m_clients; 499 500 }; 501 502 503 class NetworkManager 504 { 505 public: 506 static NetworkManager *getNetworkManager(); 507 508 int offer4Client(Client* lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList); 509 int ack(Client *lease, uint32_t u32Xid, uint8_t *pu8ReqList, int cReqList); 510 int nak(Client *lease, uint32_t u32Xid); 511 512 const RTNETADDRIPV4& getOurAddress(){ return m_OurAddress;} 513 const RTNETADDRIPV4& getOurNetmask(){ return m_OurNetmask;} 514 const RTMAC& getOurMac() {return m_OurMac;} 515 516 void setOurAddress(const RTNETADDRIPV4& aAddress){ m_OurAddress = aAddress;} 517 void setOurNetmask(const RTNETADDRIPV4& aNetmask){ m_OurNetmask = aNetmask;} 518 void setOurMac(const RTMAC& aMac) {m_OurMac = aMac;} 519 520 /* XXX: artifacts should be hidden or removed from here. */ 521 PSUPDRVSESSION m_pSession; 522 INTNETIFHANDLE m_hIf; 523 PINTNETBUF m_pIfBuf; 524 525 private: 526 int prepareReplyPacket4Client(Client *client, uint32_t u32Xid); 527 int doReply(Client *client); 528 int processParameterReqList(Client *client, uint8_t *pu8ReqList, int cReqList); 529 530 union { 531 RTNETBOOTP BootPHeader; 532 uint8_t au8Storage[1024]; 533 } BootPReplyMsg; 534 int cbBooPReplyMsg; 535 536 RTNETADDRIPV4 m_OurAddress; 537 RTNETADDRIPV4 m_OurNetmask; 538 RTMAC m_OurMac; 539 540 NetworkManager(){} 541 virtual ~NetworkManager(){} 542 }; 543 544 545 546 class Lease 547 { 548 public: 549 Lease() 550 { 551 m_address.u = 0; 552 m_client = NULL; 553 fBinding = false; 554 u64TimestampBindingStarted = 0; 555 u64TimestampLeasingStarted = 0; 556 u32LeaseExpirationPeriod = 0; 557 u32BindExpirationPeriod = 0; 558 pCfg = NULL; 559 } 560 virtual ~Lease(){} 561 562 bool isExpired() 563 { 564 if (!fBinding) 565 return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - u64TimestampLeasingStarted, 1000) 566 > u32LeaseExpirationPeriod); 567 else 568 return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - u64TimestampBindingStarted, 1000) 569 > u32BindExpirationPeriod); 570 571 } 572 573 /* XXX private: */ 574 RTNETADDRIPV4 m_address; 575 576 /** lease isn't commited */ 577 bool fBinding; 578 579 /** Timestamp when lease commited. */ 580 uint64_t u64TimestampLeasingStarted; 581 /** Period when lease is expired in secs. */ 582 uint32_t u32LeaseExpirationPeriod; 583 584 /** timestamp when lease was bound */ 585 uint64_t u64TimestampBindingStarted; 586 /* Period when binding is expired in secs. */ 587 uint32_t u32BindExpirationPeriod; 588 589 NetworkConfigEntity *pCfg; 590 Client *m_client; 591 }; 592 593 594 595 677 596 678 597 extern const ClientMatchCriteria *g_AnyClient; 679 extern constRootConfigEntity *g_RootConfig;598 extern RootConfigEntity *g_RootConfig; 680 599 extern const NullConfigEntity *g_NullConfig; 681 600 -
trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
r47111 r47501 618 618 if (!m_DhcpServer.isNull()) 619 619 { 620 #if 0 620 621 HRESULT hrc; 621 622 com::SafeArray<BSTR> sf; … … 632 633 /* XXX: per-host configuration */ 633 634 } 634 635 SessionManager *sesionManager = SessionManager::getSessionManager(); 636 Session& session = sesionManager->getClientSessionByDhcpPacket(pDhcpMsg, cb); 637 /* XXX: switch -> private */ 638 session.switchTo(DHCPDISCOVERRECEIEVED); 639 635 #endif 636 RawOption opt; 637 memset(&opt, 0, sizeof(RawOption)); 638 /* 1. Find client */ 640 639 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager(); 641 int rc = confManager->findConfiguration4Session(session); 642 AssertRCReturn(rc, false); 643 644 rc = confManager->allocateConfiguration4Session(session); 645 AssertRCReturn(rc, false); 646 647 NetworkManager *netManager = NetworkManager::getNetworkManager(); 648 rc = netManager->offer4Session(session); 649 AssertRCReturn(rc, false); 650 651 640 Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb); 641 642 /* 2. Find/Bind lease for client */ 643 Lease *lease = confManager->allocateLease4Client(client, pDhcpMsg, cb); 644 AssertPtrReturn(lease, VINF_SUCCESS); 645 646 int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt); 647 648 /* 3. Send of offer */ 649 NetworkManager *networkManager = NetworkManager::getNetworkManager(); 650 651 lease->fBinding = true; 652 lease->u64TimestampBindingStarted = RTTimeMilliTS(); 653 lease->u32BindExpirationPeriod = 300; /* 3 min. */ 654 networkManager->offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt); 652 655 } /* end of if(!m_DhcpServer.isNull()) */ 653 656 … … 666 669 bool VBoxNetDhcp::handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb) 667 670 { 668 SessionManager *sesionManager = SessionManager::getSessionManager();669 Session& session = sesionManager->getClientSessionByDhcpPacket(pDhcpMsg, cb);670 /* XXX: switch -> private */671 session.switchTo(DHCPREQUESTRECEIVED);672 673 671 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager(); 674 int rc = confManager->findConfiguration4Session(session); 675 AssertRCReturn(rc, false); 676 677 rc = confManager->commitConfiguration4ClientSession(session); 678 679 NetworkManager *netManager = NetworkManager::getNetworkManager(); 680 if (RT_SUCCESS(rc)) 681 rc = netManager->ack(session); 672 NetworkManager *networkManager = NetworkManager::getNetworkManager(); 673 674 /* 1. find client */ 675 Client *client = confManager->getClientByDhcpPacket(pDhcpMsg, cb); 676 677 /* 2. find bound lease */ 678 if (client->m_lease) 679 { 680 681 if (client->m_lease->isExpired()) 682 { 683 /* send client to INIT state */ 684 networkManager->nak(client, pDhcpMsg->bp_xid); 685 confManager->expireLease4Client(client); 686 return true; 687 } 688 /* XXX: Validate request */ 689 RawOption opt; 690 memset((void *)&opt, 0, sizeof(RawOption)); 691 692 int rc = confManager->commitLease4Client(client); 693 AssertRCReturn(rc, false); 694 695 rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt); 696 AssertRCReturn(rc, false); 697 698 networkManager->ack(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt); 699 } 682 700 else 683 rc = netManager->nak(session); 684 685 AssertRCReturn(rc, false); 686 701 { 702 networkManager->nak(client, pDhcpMsg->bp_xid); 703 } 687 704 return true; 688 705 }
Note:
See TracChangeset
for help on using the changeset viewer.