From: tho Date: Mon, 10 Jan 2011 16:58:02 +0000 (+0000) Subject: Packets/80221Bundle: extended MIHMessageType / MIHMessageRegistry to validate MIH... X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=ff305084cba283649a2c97e73d2608c3e4598683 Packets/80221Bundle: extended MIHMessageType / MIHMessageRegistry to validate MIH messages git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1758 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/80221Bundle/MIHMessageRegistry.cc b/senf/Packets/80221Bundle/MIHMessageRegistry.cc new file mode 100644 index 0000000..61fcb1e --- /dev/null +++ b/senf/Packets/80221Bundle/MIHMessageRegistry.cc @@ -0,0 +1,63 @@ +// $Id$ +// +// Copyright (C) 2011 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief MIH Message-Registry non-inline non-template implementation */ + +#include "MIHMessageRegistry.hh" +//#include "MIHMessageRegistry.ih" + +// Custom includes + +#define prefix_ +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHMessageRegistry + +#if BOOST_VERSION < 103400 +# define PTRMAP_GET_CONTENTS(v) (v) +#else +# define PTRMAP_GET_CONTENTS(v) (*(v).second) +#endif + +prefix_ std::pair senf::MIHMessageRegistry::validate(key_t messageId, senf::Packet message) +{ + Map::const_iterator i (map_.find( messageId)); + if (i != map_.end()) + return PTRMAP_GET_CONTENTS(*i).validate( message); + return std::make_pair(true, ""); +} + +#undef PTRMAP_GET_CONTENTS + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 +// End: diff --git a/senf/Packets/80221Bundle/MIHMessageRegistry.ct b/senf/Packets/80221Bundle/MIHMessageRegistry.ct new file mode 100644 index 0000000..4acf800 --- /dev/null +++ b/senf/Packets/80221Bundle/MIHMessageRegistry.ct @@ -0,0 +1,57 @@ +// $Id$ +// +// Copyright (C) 2011 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief MIH Message-Registry non-inline template implementation */ + +// Custom includes + +#define prefix_ +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHMessageRegistry + +template +prefix_ void senf::MIHMessageRegistry::registerMessageType() +{ + key_t key (MIHPacket::type::MESSAGE_ID+0); + map_.insert(key, new detail::MIHMessageRegistryEntry() ); +} + +template +prefix_ senf::MIHMessageRegistry::RegistrationProxy::RegistrationProxy() +{ + MIHMessageRegistry::instance().registerMessageType(); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Packets/80221Bundle/MIHMessageRegistry.hh b/senf/Packets/80221Bundle/MIHMessageRegistry.hh index 8db289e..cf125d6 100644 --- a/senf/Packets/80221Bundle/MIHMessageRegistry.hh +++ b/senf/Packets/80221Bundle/MIHMessageRegistry.hh @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2009 +// Copyright (C) 2010 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Thorsten Horstmann @@ -27,27 +27,96 @@ #define HH_SENF_Packets_80221Bundle_MIHMessageRegistry_ 1 // Custom includes +#include +#include #include -//#include "MIHPacket.mpp" +//#include "MIHMessageRegistry.mpp" //-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { - struct MIHMessageRegistry { - // MIH messages registry + namespace detail { + + template + struct has_static_validate_member + { + template + struct helper; + + template + static char test(helper<&U::validate> *); + + template + static char (&test(...))[2]; + + static const bool value = sizeof(test(0))==1; + }; + + struct MIHMessageRegistry_EntryBase { + virtual ~MIHMessageRegistry_EntryBase() {} + virtual std::pair validate(senf::Packet message) const = 0; + }; + + template (MIHPacket)>::value> + struct MIHMessageRegistryEntry : MIHMessageRegistry_EntryBase + { + virtual std::pair validate(senf::Packet message) const { + return std::make_pair(true, ""); + } + }; + + template + struct MIHMessageRegistryEntry : MIHMessageRegistry_EntryBase + { + virtual std::pair validate(senf::Packet message) const { + return MIHPacket::type::validate(message.as()); + } + }; + } + + + class MIHMessageRegistry + : public senf::singleton + { + public: typedef boost::uint16_t key_t; + + using senf::singleton::instance; + friend class senf::singleton; + + template + struct RegistrationProxy { + RegistrationProxy(); + }; + + template + void registerMessageType(); + + std::pair validate(key_t messageId, senf::Packet message); + + private: + typedef boost::ptr_map Map; + Map map_; + + MIHMessageRegistry() {}; }; -# define SENF_MIH_PACKET_REGISTRY_REGISTER( packet ) \ - SENF_PACKET_REGISTRY_REGISTER( \ - senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet ) + +# define SENF_MIH_PACKET_REGISTRY_REGISTER( packet ) \ + SENF_PACKET_REGISTRY_REGISTER( \ + senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet ) \ + namespace { \ + senf::MIHMessageRegistry::RegistrationProxy< packet > \ + BOOST_PP_CAT(mihPacketRegistration_, __LINE__); \ + } } //-///////////////////////////////////////////////////////////////////////////////////////////////// -//#include "MIHPacket.cci" -//#include "MIHPacket.ct" -//#include "MIHPacket.cti" +//#include "MIHMessageRegistry.cci" +#include "MIHMessageRegistry.ct" +//#include "MIHMessageRegistry.cti" #endif diff --git a/senf/Packets/80221Bundle/MIHMessageRegistry.test.cc b/senf/Packets/80221Bundle/MIHMessageRegistry.test.cc new file mode 100644 index 0000000..fa8dd62 --- /dev/null +++ b/senf/Packets/80221Bundle/MIHMessageRegistry.test.cc @@ -0,0 +1,134 @@ +// $Id$ +// +// Copyright (C) 2011 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief MIH Message-Registry unit tests */ + +//#include "MIHPacket.test.hh" +//#include "MIHPacket.test.ih" + +// Custom includes +#include "MIHMessageRegistry.hh" +#include "MIHPacket.hh" + +#include +#include + +#define prefix_ +//-///////////////////////////////////////////////////////////////////////////////////////////////// +using namespace senf; + +namespace { + + class TestMessagePacketParser + : public senf::PacketParserBase + { + # include SENF_PARSER() + SENF_PARSER_FIELD ( registerRequestCodeTLV, senf::MIHRegisterReqCodeTLVParser ); + SENF_PARSER_FINALIZE ( TestMessagePacketParser ); + }; + + + struct TestMessagePacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin + { + typedef senf::ConcretePacket packet; + typedef senf::PacketTypeMixin mixin; + typedef TestMessagePacketParser parser; + + using mixin::nextPacketRange; + using mixin::init; + using mixin::initSize; + + static const boost::uint16_t MESSAGE_ID; + }; + + struct ValidatedTestMessagePacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin + { + typedef senf::ConcretePacket packet; + typedef senf::PacketTypeMixin mixin; + typedef TestMessagePacketParser parser; + + using mixin::nextPacketRange; + using mixin::init; + using mixin::initSize; + + static const boost::uint16_t MESSAGE_ID; + + static std::pair validate(packet message) { + return std::make_pair(message->registerRequestCodeTLV().value() == 1, ""); + } + }; + + typedef senf::ConcretePacket TestMessagePacket; + typedef senf::ConcretePacket ValidatedTestMessagePacket; + + const boost::uint16_t TestMessagePacketType::MESSAGE_ID = 42; + const boost::uint16_t ValidatedTestMessagePacketType::MESSAGE_ID = 43; + + SENF_MIH_PACKET_REGISTRY_REGISTER( TestMessagePacket ); + SENF_MIH_PACKET_REGISTRY_REGISTER( ValidatedTestMessagePacket ); +} + + +SENF_AUTO_UNIT_TEST(MIHMessageRegistry_validate) +{ + MIHPacket mihPacket (MIHPacket::create()); + mihPacket->transactionId() = 21; + mihPacket->src_mihfId().value( "senf@berlios.de"); + mihPacket->dst_mihfId().value( "test"); + + BOOST_CHECK(! MIHPacketType::validate( mihPacket).first); + + mihPacket.finalizeThis(); + BOOST_CHECK( MIHPacketType::validate( mihPacket).first); + + { + TestMessagePacket testMessage (TestMessagePacket::createAfter(mihPacket)); + mihPacket.finalizeAll(); + BOOST_CHECK( MIHPacketType::validate( mihPacket).first); + } + { + ValidatedTestMessagePacket testMessage (ValidatedTestMessagePacket::createAfter(mihPacket)); + mihPacket.finalizeAll(); + BOOST_CHECK(! MIHPacketType::validate( mihPacket).first); + testMessage->registerRequestCodeTLV().value() << 1; + BOOST_CHECK( MIHPacketType::validate( mihPacket).first); + } +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 +// End: diff --git a/senf/Packets/80221Bundle/MIHPacket.cc b/senf/Packets/80221Bundle/MIHPacket.cc index 7046412..f4efbeb 100644 --- a/senf/Packets/80221Bundle/MIHPacket.cc +++ b/senf/Packets/80221Bundle/MIHPacket.cc @@ -28,6 +28,7 @@ // Custom includes #include +#include #include #define prefix_ @@ -77,6 +78,19 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::MIHPacketType::nextPacketTy return e ? e->factory() : MIHGenericPayloadPacket::factory(); } +prefix_ std::pair senf::MIHPacketType::validate(packet p) +{ + if (p.data().size() < initSize()) + return std::make_pair(false, "truncated MIH message"); + if (p->version() != 1) + return std::make_pair(false, "invalid MIH version: " + senf::str(p->version()) ); + if (p->payloadLength() != p.size()-8) + return std::make_pair(false, "wrong MIH length: " + senf::str(p->payloadLength()) ); + if (p.next(senf::nothrow)) + return MIHMessageRegistry::instance().validate( p->messageId(), p.next()); + return std::make_pair(true, ""); +} + //-///////////////////////////////////////////////////////////////////////////////////////////////// // MIHGenericPayloadPacketType diff --git a/senf/Packets/80221Bundle/MIHPacket.hh b/senf/Packets/80221Bundle/MIHPacket.hh index 8705a65..385b2ff 100644 --- a/senf/Packets/80221Bundle/MIHPacket.hh +++ b/senf/Packets/80221Bundle/MIHPacket.hh @@ -97,9 +97,7 @@ namespace senf { : public PacketTypeBase, public PacketTypeMixin { -#ifndef DOXYGEN typedef PacketTypeMixin mixin; -#endif typedef ConcretePacket packet; ///< MIH packet typedef typedef MIHPacketParser parser; ///< typedef to the parser of MIH packet @@ -111,6 +109,8 @@ namespace senf { static void dump(packet p, std::ostream &os); static void finalize(packet p); static factory_t nextPacketType(packet p); + + static std::pair validate(packet p); }; /** \brief MIH packet typedef @@ -130,9 +130,7 @@ namespace senf { : public PacketTypeBase, public PacketTypeMixin { -#ifndef DOXYGEN typedef PacketTypeMixin mixin; -#endif typedef ConcretePacket packet; ///< MIH Payload packet typedef typedef MIHGenericPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet diff --git a/senf/Packets/80221Bundle/TLVParser.cc b/senf/Packets/80221Bundle/TLVParser.cc index cf2e41d..ad14cb5 100644 --- a/senf/Packets/80221Bundle/TLVParser.cc +++ b/senf/Packets/80221Bundle/TLVParser.cc @@ -30,6 +30,7 @@ #include #include #include +#include #define prefix_ //-///////////////////////////////////////////////////////////////////////////////////////////////// @@ -233,6 +234,14 @@ prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os) os << " (???; invalid value!)" << std::endl; } +prefix_ std::pair senf::MIHRegisterReqCodeTLVParser::validate() + const +{ + if (length() != 1) return std::make_pair(false, "invalid length in MIHRegisterReqCodeTLV " + senf::str(length())); + if (value() >= 2) return std::make_pair(false, "invalid value in MIHRegisterReqCodeTLV " + senf::str(value())); + return std::make_pair(true, ""); +} + //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::MIHValidTimeIntervalTLVParser @@ -248,6 +257,13 @@ prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os) << ( value()==0 ? " (infinite)" : " seconds") << std::endl; } +prefix_ std::pair senf::MIHValidTimeIntervalTLVParser::validate() + const +{ + if (length() != 4) return std::make_pair(false, "invalid length in MIHValidTimeIntervalTLV " + senf::str(length())); + return std::make_pair(true, ""); +} + //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::MIHTLVLengthParser diff --git a/senf/Packets/80221Bundle/TLVParser.hh b/senf/Packets/80221Bundle/TLVParser.hh index 2c4fc7d..601207f 100644 --- a/senf/Packets/80221Bundle/TLVParser.hh +++ b/senf/Packets/80221Bundle/TLVParser.hh @@ -343,6 +343,7 @@ namespace senf { } static type_t::value_type const typeId = 11; void dump(std::ostream & os) const; ///< dump string representation to given stream + std::pair validate() const; enum RequestCode { Registration, ReRegistration }; }; @@ -361,6 +362,7 @@ namespace senf { } static type_t::value_type const typeId = 12; void dump(std::ostream & os) const; ///< dump string representation to given stream + std::pair validate() const; }; } diff --git a/senf/Packets/PacketRegistry.hh b/senf/Packets/PacketRegistry.hh index 491c738..f69d4f9 100644 --- a/senf/Packets/PacketRegistry.hh +++ b/senf/Packets/PacketRegistry.hh @@ -27,8 +27,6 @@ #define HH_SENF_Packets_PacketRegistry_ 1 // Custom includes -#include -#include // for boost::noncopyable #include #include #include diff --git a/senf/Packets/PacketRegistry.ih b/senf/Packets/PacketRegistry.ih index 382ff30..746281d 100644 --- a/senf/Packets/PacketRegistry.ih +++ b/senf/Packets/PacketRegistry.ih @@ -27,7 +27,6 @@ #define IH_SENF_Packets_PacketRegistry_ 1 // Custom includes -#include #include #include #include @@ -35,7 +34,7 @@ #include #include #include -#include +#include // for boost::noncopyable #include //-/////////////////////////////////////////////////////////////////////////////////////////////////