/** * * Tryies to find interface in list of inactive interfaces which becames * ready. In positive case such an interface is moved back into standard list. * Only first matching interface is processed. * * @returns Interface that becomes ready and has been moved out of inactive list. * If no such interface exists, 0 will be returned. */ SPtr<TSrvCfgIface> TSrvCfgMgr::checkInactiveIfaces() { if (!InactiveLst.count()) return 0; SrvIfaceMgr().redetectIfaces(); SPtr<TSrvCfgIface> x; SPtr<TIfaceIface> iface; InactiveLst.first(); while (x = InactiveLst.get()) { iface = SrvIfaceMgr().getIfaceByID(x->getID()); if (!iface) { Log(Error) << "TSrvCfgMgr::checkInactiveIfaces(): " << "Unable to find interface with ifindex=" << x->getID() << LogEnd; continue; } iface->firstLLAddress(); if (iface->flagUp() && iface->flagRunning() && iface->getLLAddress()) { // check if its link-local address is not tentative char tmp[64]; iface->firstLLAddress(); inet_ntop6(iface->getLLAddress(), tmp); if (is_addr_tentative(iface->getName(), iface->getID(), tmp)==LOWLEVEL_TENTATIVE_YES) { Log(Debug) << "Interface " << iface->getFullName() << " is up and running, but link-scope address " << tmp << " is currently tentative." << LogEnd; continue; } makeInactiveIface(x->getID(), false); // move it to InactiveLst return x; } } return 0; }
void TDHCPServer::run() { bool silent = false; while ( (!isDone()) && (!SrvTransMgr().isDone()) ) { if (serviceShutdown) SrvTransMgr().shutdown(); SrvTransMgr().doDuties(); unsigned int timeout = SrvTransMgr().getTimeout(); if (timeout == 0) timeout = 1; if (serviceShutdown) timeout = 0; if (!silent) Log(Notice) << "Accepting connections. Next event in " << timeout << " second(s)." << LogEnd; #ifdef WIN32 // There's no easy way to break select under Windows, so just don't sleep for too long. if (timeout>5) { silent = true; timeout = 5; } #endif SPtr<TSrvMsg> msg=SrvIfaceMgr().select(timeout); if (!msg) continue; silent = false; int iface = msg->getIface(); SPtr<TIfaceIface> ptrIface; ptrIface = SrvIfaceMgr().getIfaceByID(iface); Log(Notice) << "Received " << msg->getName() << " on " << ptrIface->getName() << "/" << iface << hex << ",TransID=0x" << msg->getTransID() << dec << ", " << msg->countOption() << " opts:"; SPtr<TOpt> ptrOpt; msg->firstOption(); while (ptrOpt = msg->getOption() ) Log(Cont) << " " << ptrOpt->getOptType(); Log(Cont) << ", " << msg->getRelayCount() << " relay(s)." << LogEnd; if (SrvCfgMgr().stateless() && ( (msg->getType()!=INFORMATION_REQUEST_MSG) && (msg->getType()!=RELAY_FORW_MSG))) { Log(Warning) << "Stateful configuration related message received while running in the stateless mode. Message ignored." << LogEnd; continue; } SrvTransMgr().relayMsg(msg); } Log(Notice) << "Bye bye." << LogEnd; }
TSrvCfgMgr::TSrvCfgMgr(const std::string cfgFile, const std::string xmlFile) :TCfgMgr(), XmlFile(xmlFile), reconfigure(true) { setDefaults(); // load config file if (!this->parseConfigFile(cfgFile)) { IsDone = true; return; } // load or create DUID string duidFile = (string)SRVDUID_FILE; if (!setDUID(duidFile, SrvIfaceMgr())) { this->IsDone=true; return; } this->dump(); #ifndef MOD_DISABLE_AUTH AuthKeys = new KeyList(); #endif IsDone = false; }
bool TSrvCfgMgr::setupRelay(SPtr<TSrvCfgIface> cfgIface) { SPtr<TIfaceIface> iface; string name = cfgIface->getRelayName(); iface = SrvIfaceMgr().getIfaceByName(name); if (!iface) { Log(Crit) << "Underlaying interface for " << cfgIface->getName() << "/" << cfgIface->getID() << " with name " << name << " is missing." << LogEnd; return false; } cfgIface->setRelayID(iface->getID()); if (!SrvIfaceMgr().setupRelay(cfgIface->getName(), cfgIface->getID(), iface->getID(), cfgIface->getRelayInterfaceID())) { Log(Crit) << "Relay setup for " << cfgIface->getName() << "/" << cfgIface->getID() << " interface failed." << LogEnd; return false; } return true; }
TDHCPServer::TDHCPServer(string config) { serviceShutdown = 0; srand(now()); this->IsDone = false; TSrvIfaceMgr::instanceCreate(SRVIFACEMGR_FILE); if ( SrvIfaceMgr().isDone() ) { Log(Crit) << "Fatal error during IfaceMgr initialization." << LogEnd; this->IsDone = true; return; } SrvIfaceMgr().dump(); TSrvCfgMgr::instanceCreate(config, SRVCFGMGR_FILE); if ( SrvCfgMgr().isDone() ) { Log(Crit) << "Fatal error during CfgMgr initialization." << LogEnd; this->IsDone = true; return; } SrvCfgMgr().dump(); TSrvAddrMgr::instanceCreate(SRVADDRMGR_FILE, true /*always load DB*/ ); if ( SrvAddrMgr().isDone() ) { Log(Crit) << "Fatal error during AddrMgr initialization." << LogEnd; this->IsDone = true; return; } SrvAddrMgr().dump(); TSrvTransMgr::instanceCreate(SRVTRANSMGR_FILE); if ( SrvTransMgr().isDone() ) { Log(Crit) << "Fatal error during TransMgr initialization." << LogEnd; this->IsDone = true; return; } SrvCfgMgr().setCounters(); SrvCfgMgr().dump(); SrvIfaceMgr().dump(); // dump it once more (important, if relay interfaces were added) SrvTransMgr().dump(); }
bool TSrvCfgMgr::validateIface(SPtr<TSrvCfgIface> ptrIface) { bool dummyRelay = false; SPtr<TSrvIfaceIface> iface = (Ptr*)SrvIfaceMgr().getIfaceByID(ptrIface->getID()); if (iface && ptrIface->isRelay() && iface->getRelayCnt()) dummyRelay = true; if (ptrIface->countAddrClass() && stateless()) { Log(Crit) << "Config problem: Interface " << ptrIface->getFullName() << ": Class definitions present, but stateless mode set." << LogEnd; return false; } if (!ptrIface->countAddrClass() && !ptrIface->countPD() && !ptrIface->getTA() && !stateless()) { if (!dummyRelay) { Log(Crit) << "Config problem: Interface " << ptrIface->getName() << "/" << ptrIface->getID() << ": No class definitions (IA,TA or PD) present, but stateless mode not set." << LogEnd; return false; } else { Log(Warning) << "Interface " << ptrIface->getFullName() << " has no addrs defined, working as cascade relay interface." << LogEnd; } } if (ptrIface->supportFQDN() && !ptrIface->supportDNSServer()) { Log(Crit) << "FQDN defined on the " << ptrIface->getFullName() << ", but no DNS servers defined." << " Please disable FQDN support or add DNS servers." << LogEnd; return false; } SPtr<TSrvCfgAddrClass> ptrClass; ptrIface->firstAddrClass(); while(ptrClass=ptrIface->getAddrClass()) { if (!this->validateClass(ptrIface, ptrClass)) { Log(Crit) << "Config problem: Interface " << ptrIface->getName() << "/" << ptrIface->getID() << ": Invalid class defined." << LogEnd; return false; } } return true; }
/* * Now parsed information should be placed in config manager * in accordance with information provided by interface manager */ bool TSrvCfgMgr::matchParsedSystemInterfaces(SrvParser *parser) { int cfgIfaceCnt; cfgIfaceCnt = parser->SrvCfgIfaceLst.count(); Log(Debug) << cfgIfaceCnt << " interface(s) specified in " << SRVCONF_FILE << LogEnd; SPtr<TSrvCfgIface> cfgIface; SPtr<TIfaceIface> ifaceIface; parser->SrvCfgIfaceLst.first(); while(cfgIface=parser->SrvCfgIfaceLst.get()) { // for each interface from config file // map deny and allow list cfgIface->mapAllowDenyList(parser->SrvCfgClientClassLst); // relay interface if (cfgIface->isRelay()) { cfgIface->setID(this->NextRelayID++); if (!this->setupRelay(cfgIface)) { return false; } this->addIface(cfgIface); continue; // skip physical interface checking part } // physical interface if (cfgIface->getID()==-1) { // ID==-1 means that user referenced to interface by name ifaceIface = SrvIfaceMgr().getIfaceByName(cfgIface->getName()); } else { ifaceIface = SrvIfaceMgr().getIfaceByID(cfgIface->getID()); } if (!ifaceIface) { Log(Crit) << "Interface " << cfgIface->getFullName() << " is not present in the system or does not support IPv6." << LogEnd; return false; } // Complete name and ID (one of them usually misses depending on // identifier used in config file. /// @todo: Client's class uses setIface{Name,ID}(). We should unite the // method names. cfgIface->setName(ifaceIface->getName()); cfgIface->setID(ifaceIface->getID()); // Check for link scope address presence if (!ifaceIface->countLLAddress()) { if (this->inactiveMode()) { Log(Notice) << "Interface " << ifaceIface->getFullName() << " is not operational yet (does not have link scope address), skipping it for now." << LogEnd; this->addIface(cfgIface); this->makeInactiveIface(cfgIface->getID(), true); // move it to InactiveLst continue; } Log(Crit) << "Interface " << ifaceIface->getName() << "/" << ifaceIface->getID() << " is down or doesn't have any link scope address." << LogEnd; return false; } // Check if the interface is during bring-up phase (i.e. DAD procedure for link-local addr is not complete yet) char tmp[64]; ifaceIface->firstLLAddress(); inet_ntop6(ifaceIface->getLLAddress(), tmp); if (is_addr_tentative(ifaceIface->getName(), ifaceIface->getID(), tmp) == LOWLEVEL_TENTATIVE_YES) { Log(Notice) << "Interface " << ifaceIface->getFullName() << " has link-scope address " << tmp << ", but it is currently tentative." << LogEnd; if (this->inactiveMode()) { Log(Notice) << "Interface " << ifaceIface->getFullName() << " is not operational yet (link-scope address is not ready), skipping it for now." << LogEnd; addIface(cfgIface); makeInactiveIface(cfgIface->getID(), true); // move it to InactiveLst continue; } Log(Crit) << "Interface " << ifaceIface->getFullName() << " has tentative link-scope address (and inactive-mode is disabled)." << LogEnd; return false; } this->addIface(cfgIface); Log(Info) << "Interface " << cfgIface->getFullName() << " configuration has been loaded." << LogEnd; } return true; }