void TSrvIfaceMgr::notifyScripts(const std::string& scriptName, SPtr<TMsg> question, SPtr<TMsg> answer) { TNotifyScriptParams* params = (TNotifyScriptParams*)answer->getNotifyScriptParams(); // add info about relays SPtr<TSrvMsg> reply = (Ptr*)answer; const vector<TSrvMsg::RelayInfo> relayInfo = reply->getRelayInfo(); stringstream relaysNum; relaysNum << relayInfo.size(); params->addParam("RELAYS", relaysNum.str()); int cnt = 1; for (vector<TSrvMsg::RelayInfo>::const_reverse_iterator relay = relayInfo.rbegin(); relay != relayInfo.rend(); ++relay) { stringstream peer; stringstream link; peer << "RELAY" << cnt << "_PEER"; link << "RELAY" << cnt << "_LINK"; params->addParam(peer.str(), relay->PeerAddr_->getPlain()); params->addParam(link.str(), relay->LinkAddr_->getPlain()); } TIfaceMgr::notifyScripts(scriptName, question, answer); }
/// @brief Generates parameters for notify script based on expired lease information /// /// @param params Notify parameters (all available info will be set here) /// @param exp expired lease details /// @param type type of lease (IA, TA or PD) void TSrvTransMgr::notifyExpireInfo(TNotifyScriptParams& params, const TSrvAddrMgr::TExpiredInfo& exp, TIAType type) { stringstream tmp; tmp << exp.ia->getIfindex(); params.addParam("IFINDEX", tmp.str()); SPtr<TIfaceIface> iface = SrvIfaceMgr().getIfaceByID(exp.ia->getIfindex()); if (iface) params.addParam("IFACE", iface->getName()); if (exp.ia->getSrvAddr()) params.addParam("REMOTE_ADDR", exp.ia->getSrvAddr()->getPlain()); switch (type) { case IATYPE_IA: case IATYPE_TA: { params.addAddr(exp.addr, 0, 0, ""); break; } case IATYPE_PD: { params.addPrefix(exp.addr, exp.prefixLen, 0, 0); break; } } tmp.str(""); tmp << exp.ia->getIAID(); params.addParam("IAID", tmp.str()); params.addParam("SRV_OPTION1", exp.client->getDUID()->getPlain()); // set client-id }
/** * this constructor is used to create REPLY message as a response for RELEASE message * * @param release */ TSrvMsgReply::TSrvMsgReply(SPtr<TSrvMsgRelease> release) :TSrvMsg(release->getIface(),release->getRemoteAddr(), REPLY_MSG, release->getTransID()) { getORO( (Ptr*) release ); copyClientID( (Ptr*) release ); copyRelayInfo((Ptr*)release); copyAAASPI((Ptr*)release); copyRemoteID((Ptr*)release); /// @todo When the server receives a Release message via unicast from a client /// to which the server has not sent a unicast option, the server /// discards the Release message and responds with a Reply message /// containing a Status Code option with value UseMulticast, a Server /// Identifier option containing the server's DUID, the Client Identifier /// option from the client message, and no other options. // for notify script TNotifyScriptParams* notifyParams = new TNotifyScriptParams(); SPtr<TOpt> opt, subOpt; SPtr<TAddrClient> client = SrvAddrMgr().getClient(ClientDUID); if (!client) { Log(Warning) << "Received RELEASE from unknown client DUID=" << ClientDUID->getPlain() << LogEnd; IsDone = true; return; } SPtr<TSrvCfgIface> ptrIface = SrvCfgMgr().getIfaceByID( this->Iface ); if (!ptrIface) { Log(Crit) << "Msg received through not configured interface. " "Somebody call an exorcist!" << LogEnd; IsDone = true; return; } appendMandatoryOptions(ORO); appendAuthenticationOption(ClientDUID); release->firstOption(); while(opt=release->getOption()) { switch (opt->getOptType()) { case OPTION_IA_NA: { SPtr<TSrvOptIA_NA> clntIA = (Ptr*) opt; SPtr<TSrvOptIAAddress> addr; bool anyDeleted=false; // does this client has IA? (iaid check) SPtr<TAddrIA> ptrIA = client->getIA(clntIA->getIAID() ); if (!ptrIA) { Log(Warning) << "No such IA (iaid=" << clntIA->getIAID() << ") found for client:" << ClientDUID->getPlain() << LogEnd; Options.push_back( new TSrvOptIA_NA(clntIA->getIAID(), 0, 0, STATUSCODE_NOBINDING,"No such IA is bound.",this) ); continue; } // if there was DNS Update performed, execute deleting Update SPtr<TFQDN> fqdn = ptrIA->getFQDN(); if (fqdn) { delFQDN(ptrIface, ptrIA, fqdn); } // let's verify each address clntIA->firstOption(); while(subOpt=clntIA->getOption()) { if (subOpt->getOptType()!=OPTION_IAADDR) continue; addr = (Ptr*) subOpt; if (SrvAddrMgr().delClntAddr(ClientDUID, clntIA->getIAID(), addr->getAddr(), false) ) { notifyParams->addAddr(addr->getAddr(), 0, 0, "SRV"); SrvCfgMgr().delClntAddr(this->Iface,addr->getAddr()); anyDeleted=true; } else { Log(Warning) << "No such binding found: client=" << ClientDUID->getPlain() << ", IA (iaid=" << clntIA->getIAID() << "), addr="<< addr->getAddr()->getPlain() << LogEnd; }; }; // send result to the client if (!anyDeleted) { SPtr<TSrvOptIA_NA> ansIA(new TSrvOptIA_NA(clntIA->getIAID(), clntIA->getT1(),clntIA->getT2(),this)); Options.push_back((Ptr*)ansIA); ansIA->addOption(new TOptStatusCode(STATUSCODE_NOBINDING, "Not every address had binding.",this)); }; break; } case OPTION_IA_TA: { SPtr<TSrvOptTA> ta = (Ptr*) opt; bool anyDeleted = false; SPtr<TAddrIA> ptrIA = client->getTA(ta->getIAID() ); if (!ptrIA) { Log(Warning) << "No such TA (iaid=" << ta->getIAID() << ") found for client:" << ClientDUID->getPlain() << LogEnd; Options.push_back( new TSrvOptTA(ta->getIAID(), STATUSCODE_NOBINDING, "No such IA is bound.", this) ); continue; } // let's verify each address ta->firstOption(); while ( subOpt = (Ptr*) ta->getOption() ) { if (subOpt->getOptType()!=OPTION_IAADDR) continue; SPtr<TSrvOptIAAddress> addr = (Ptr*) subOpt; if (SrvAddrMgr().delTAAddr(ClientDUID, ta->getIAID(), addr->getAddr(), false) ) { notifyParams->addAddr(addr->getAddr(), 0, 0 , ""); SrvCfgMgr().delTAAddr(this->Iface); anyDeleted=true; } else { Log(Warning) << "No such binding found: client=" << ClientDUID->getPlain() << ", TA (iaid=" << ta->getIAID() << "), addr="<< addr->getAddr()->getPlain() << LogEnd; }; } // send results to the client if (!anyDeleted) { SPtr<TSrvOptTA> answerTA = new TSrvOptTA(ta->getIAID(), STATUSCODE_NOBINDING, "Not every address had binding.", this); Options.push_back((Ptr*)answerTA); }; break; } case OPTION_IA_PD: { SPtr<TSrvOptIA_PD> pd = (Ptr*) opt; SPtr<TSrvOptIAPrefix> prefix; bool anyDeleted=false; // does this client has PD? (iaid check) SPtr<TAddrIA> ptrPD = client->getPD( pd->getIAID() ); if (!ptrPD) { Log(Warning) << "No such PD (iaid=" << pd->getIAID() << ") found for client:" << ClientDUID->getPlain() << LogEnd; Options.push_back( new TSrvOptIA_PD(pd->getIAID(), 0, 0, STATUSCODE_NOBINDING,"No such PD is bound.",this) ); continue; } // let's verify each address pd->firstOption(); while(subOpt=pd->getOption()) { if (subOpt->getOptType()!=OPTION_IAPREFIX) continue; prefix = (Ptr*) subOpt; if (SrvAddrMgr().delPrefix(ClientDUID, pd->getIAID(), prefix->getPrefix(), false) ) { notifyParams->addPrefix(prefix->getPrefix(), prefix->getPrefixLength(), 0, 0); SrvCfgMgr().decrPrefixCount(Iface, prefix->getPrefix()); anyDeleted=true; } else { Log(Warning) << "PD: No such binding found: client=" << ClientDUID->getPlain() << ", PD (iaid=" << pd->getIAID() << "), addr="<< prefix->getPrefix()->getPlain() << LogEnd; }; }; // send result to the client if (!anyDeleted) { Options.push_back(new TSrvOptIA_PD(pd->getIAID(), 0u, 0u, STATUSCODE_NOBINDING, "Not every address had binding.", this)); }; break; } default: handleDefaultOption(opt); break; }; // switch(...) } // while Options.push_back(new TOptStatusCode(STATUSCODE_SUCCESS, "All IAs in RELEASE message were processed.",this)); NotifyScripts = notifyParams; IsDone = false; MRT_ = 46; }