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);
}
Example #2
0
/// @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
}
Example #3
0
/**
 * 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;
}