X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FAvp.cpp;h=17ba00520cc78e2c250ce30c104e99ec168f1bec;hb=42f606f1c76bfbef24e7e772b6939d69d5ea970e;hp=aa52c5ff8cb518bf26ca3e338b46e1d725eb83bb;hpb=8808902f3d5e768a02f3936c4a1a8732da682895;p=anna.git diff --git a/source/diameter/codec/Avp.cpp b/source/diameter/codec/Avp.cpp index aa52c5f..17ba005 100644 --- a/source/diameter/codec/Avp.cpp +++ b/source/diameter/codec/Avp.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -686,7 +687,6 @@ void Avp::decodeDataPart(const char * buffer, int size, const parent_t & parent, int avpPos = 0; Avp* avp; anna::DataBlock db; - // Me as parent: parent_t me = parent; me.addAvp(a_id); @@ -785,13 +785,12 @@ void Avp::decode(const anna::DataBlock &db, const parent_t & parent, Message *an // a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected. // Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs. if(!getStackAvp() && mandatoryBit()) { + if(answer) { + answer->setResultCode(helpers::base::AVPVALUES__Result_Code::DIAMETER_AVP_UNSUPPORTED); + answer->setFailedAvp(parent, a_id); + } - if(answer) { - answer->setResultCode(helpers::base::AVPVALUES__Result_Code::DIAMETER_AVP_UNSUPPORTED); - answer->setFailedAvp(parent, a_id); - } - - unknownAvpWithMandatoryBit(); + unknownAvpWithMandatoryBit(); } // Avp Length @@ -1115,7 +1114,7 @@ bool Avp::valid(const parent_t & parent, Message *answer) const throw(anna::Runt if(answer) { answer->setResultCode(helpers::base::AVPVALUES__Result_Code::DIAMETER_INVALID_AVP_BITS); - answer->setFailedAvp(parent, a_id); // RFC 6733 says nothing about Failed-AVP in this case... + answer->setFailedAvp(parent, a_id, stackAvp->getName().c_str()); // RFC 6733 says nothing about Failed-AVP in this case... } getEngine()->validationAnomaly(anna::functions::asString("The AVP %s flags (%d) does not fulfill the defined flag rules: %s", STRING_WITH_QUOTATION_MARKS__C_STR(me.asString()), (int)a_flags, STRING_WITH_QUOTATION_MARKS__C_STR(stackAvp->getFlagRulesDescription()))); @@ -1133,7 +1132,7 @@ bool Avp::valid(const parent_t & parent, Message *answer) const throw(anna::Runt if(answer) { answer->setResultCode(helpers::base::AVPVALUES__Result_Code::DIAMETER_INVALID_AVP_VALUE); - answer->setFailedAvp(parent, a_id); + answer->setFailedAvp(parent, a_id, stackAvp->getName().c_str()); } getEngine()->validationAnomaly(anna::functions::asString("Enumerated AVP %s with value %d does not comply to restriction: %s", STRING_WITH_QUOTATION_MARKS__C_STR(me.asString()), a_Enumerated->getValue(), stackAvp->getEnums())); @@ -1313,6 +1312,16 @@ std::string Avp::getXMLdata(bool & isHex, const stack::Format *stackFormat) cons } +//------------------------------------------------------------------------------ +//---------------------------------------------------------------- Avp::decode() +//------------------------------------------------------------------------------ +void Avp::decode(const anna::DataBlock &db) throw(anna::RuntimeException) { + parent_t parent; + parent.setMessage(CommandId(0, false), "No-Parent"); + decode(db, parent, NULL); +} + + //------------------------------------------------------------------------------ //--------------------------------------------------------------- Avp::fromXML() //------------------------------------------------------------------------------ @@ -1351,13 +1360,33 @@ void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) // Check attributes exclusiveness if(name) { // compact mode - if(code || flags || vendorCode) { + bool allowFlagsField = ( stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::shouldnot + || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::shouldnot + /* umm, perhaps we could omit for bit P, whic is deprecated ... */ + /* || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::shouldnot*/ ); + if(code || (flags && !allowFlagsField) || vendorCode) { std::string msg = "Error processing avp getValue(); - msg += "'>: avp attributes <'code' + 'flags' + 'vendorCode'> are not allowed if <'name'> is provided"; + if (flags) msg += "'>: avp attributes <'code' + 'flags' + 'vendorCode'> are not allowed if <'name'> is provided (also flags is not permitted: no may, no shouldnot)"; + else msg += "'>: avp attributes <'code' + 'vendorCode'> are not allowed if <'name'> is provided"; throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } setId(stackAvp->getId()); + + if (flags && allowFlagsField) { + // Flags check + int i_aux = flags->getIntegerValue(); + + if(i_aux < 0 || i_aux > 256) { + std::string msg = "Error processing avp getValue(); + msg += "': out of range [0,256]"; + throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); + } + + a_flags = i_aux; + } + + } else { if(!code || !flags || !vendorCode) { std::string s_code = code ? code->getValue() : "?"; @@ -1556,6 +1585,12 @@ anna::xml::Node* Avp::asXML(anna::xml::Node* parent) const throw() { if(compactMode) { result->createAttribute("name", stackAvp->getName()); + // If may or shouldnot is present in AVP definition, we have to show flags to avoid uncertainty + if ( stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::shouldnot + || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::shouldnot + /* umm, perhaps we could omit for bit P, whic is deprecated ... */ + /* || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::shouldnot*/ ) + result->createAttribute("flags", (int)a_flags); } else { result->createAttribute("code", a_id.first); result->createAttribute("vendor-code", a_id.second); @@ -1585,6 +1620,7 @@ anna::xml::Node* Avp::asXML(anna::xml::Node* parent) const throw() { return result; } + //------------------------------------------------------------------------------ //----------------------------------------------------------- Avp::asXMLString() //------------------------------------------------------------------------------ @@ -1593,3 +1629,11 @@ std::string Avp::asXMLString() const throw() { return anna::xml::Compiler().apply(asXML(&root)); } + +//------------------------------------------------------------------------------ +//---------------------------------------------------------------- Avp::isLike() +//------------------------------------------------------------------------------ +bool Avp::isLike(const std::string &pattern) const throw() { + anna::RegularExpression re(pattern); + return re.isLike(asXMLString()); +}