Helper是Quagga的抓手,而Application是具体的实现。这从HOWTO_create_a_traffic_generator可以看出来。
QuaggaHelper 使用了DceApplicationHelper
ApplicationContainer QuaggaHelper::InstallPriv (Ptr<Node> node) { DceApplicationHelper process; ApplicationContainer apps; Ptr<QuaggaConfig> zebra_conf = node->GetObject<QuaggaConfig> (); if (!zebra_conf) { zebra_conf = new QuaggaConfig (); node->AggregateObject (zebra_conf); } GenerateConfigZebra (node); process.SetBinary ("zebra"); process.AddArguments ("-f", zebra_conf->GetFilename ()); process.AddArguments ("-i", "/usr/local/etc/zebra.pid"); process.SetStackSize (1 << 16); apps.Add (process.Install (node)); apps.Get (0)->SetStartTime (Seconds (1.0 + 0.01 * node->GetId ())); node->AddApplication (apps.Get (0)); Ptr<OspfConfig> ospf_conf = node->GetObject<OspfConfig> (); // OSPF if (ospf_conf) {
ApplicationContainer DceApplicationHelper::InstallInNode (Ptr<Node> node) { NS_LOG_FUNCTION (this); ApplicationContainer apps; Ptr<DceApplication> dce = CreateObject<DceApplication> (); dce->SetBinary (m_filename); dce->SetStackSize (m_stackSize); dce->SetArguments (m_args); dce->SetEnvironment (m_envs); dce->SetStdinFile (m_stdinFilename); dce->SetUid (m_uid); dce->SetEuid (m_euid); if (!m_finishedCallback.IsNull ()) { dce->SetFinishedCallback (m_finishedCallback); } node->AddApplication (dce); apps.Add (dce); return apps; }
void DceApplication::StartApplication (void) { NS_LOG_FUNCTION (this); Ptr<Node> node = GetNode (); Ptr<DceManager> manager = node->GetObject<DceManager> (); if (manager == 0) { NS_FATAL_ERROR ("You forgot to aggregate a DceManager to node=" << node->GetId ()); } if (m_stackSize != 0) { m_pid = manager->Start (m_filename, m_stdinFilename, m_stackSize, m_args, m_envs, m_uid, m_euid, m_gid, m_egid); } else { m_pid = manager->Start (m_filename, m_stdinFilename, m_args, m_envs, m_uid, m_euid, m_gid, m_egid); } if (!m_finishedCallback.IsNull ()) { manager->SetFinishedCallback (m_pid, m_finishedCallback); } m_dceStarted (m_pid); }
启动程序又调用到DceManager
uint16_t DceManager::Start (std::string name, std::string stdinfilename, std::vector<std::string> args, std::vector<std::pair<std::string,std::string> > envs, uid_t uid, uid_t euid, uid_t gid, uid_t egid) { NS_LOG_FUNCTION (this << name << args.size ()); struct Process *process = CreateProcess (name, stdinfilename, args, envs, 0); process->ruid = uid; process->euid = euid; process->rgid = gid; process->egid = egid; struct Thread *thread = CreateThread (process); Task *task = TaskManager::Current ()->Start (&DceManager::DoStartProcess, thread); task->SetContext (thread); task->SetSwitchNotifier (&DceManager::TaskSwitch, process); thread->task = task; return process->pid; }
DceManager::DoStartProcess
此后代码会一直走到
Manager::LoadMain