From df1b7561be0d4a57e964c783c01060c54864ec60 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 9 Oct 2016 18:03:24 +0300 Subject: [PATCH] Acutally implement Protocol::get_hash Also trigger an error in Communicator if the hashes don't match --- source/net/communicator.cpp | 13 ++++--- source/net/communicator.h | 7 ++++ source/net/protocol.cpp | 11 ++++-- source/net/protocol.h | 73 +++++++++++++++++++++++++++++++------ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/source/net/communicator.cpp b/source/net/communicator.cpp index 92279c2..07c3be4 100644 --- a/source/net/communicator.cpp +++ b/source/net/communicator.cpp @@ -10,7 +10,7 @@ using namespace Msp::Net; struct Handshake { - unsigned hash; + Msp::UInt64 hash; }; @@ -30,11 +30,11 @@ HandshakeProtocol::HandshakeProtocol(): class HandshakeReceiver: public PacketReceiver { private: - unsigned hash; + Msp::UInt64 hash; public: HandshakeReceiver(); - unsigned get_hash() const { return hash; } + Msp::UInt64 get_hash() const { return hash; } virtual void receive(const Handshake &); }; @@ -125,15 +125,16 @@ void Communicator::data_available() HandshakeReceiver hsrecv; if((more = receive_packet(hsproto, hsrecv))) { + if(handshake_status==0) + send_handshake(); + if(hsrecv.get_hash()==protocol.get_hash()) { - if(handshake_status==0) - send_handshake(); handshake_status = 2; signal_handshake_done.emit(); } else - good = false; + throw incompatible_protocol("hash mismatch"); } } } diff --git a/source/net/communicator.h b/source/net/communicator.h index af5ff58..63114fd 100644 --- a/source/net/communicator.h +++ b/source/net/communicator.h @@ -16,6 +16,13 @@ public: virtual ~sequence_error() throw() { } }; +class incompatible_protocol: public std::runtime_error +{ +public: + incompatible_protocol(const std::string &w): std::runtime_error(w) { } + virtual ~incompatible_protocol() throw() { } +}; + class Communicator { diff --git a/source/net/protocol.cpp b/source/net/protocol.cpp index d862ed8..4d3f962 100644 --- a/source/net/protocol.cpp +++ b/source/net/protocol.cpp @@ -1,12 +1,13 @@ #include #include +#include #include +#include #include #include "protocol.h" using namespace std; - namespace Msp { namespace Net { @@ -63,10 +64,12 @@ unsigned Protocol::get_packet_size(const char *buf, unsigned size) const return header.length; } -unsigned Protocol::get_hash() const +UInt64 Protocol::get_hash() const { - // TODO - return 123; + string description; + for(PacketMap::const_iterator i=packet_id_defs.begin(); i!=packet_id_defs.end(); ++i) + description += format("%d:%s\n", i->first, i->second->describe()); + return hash64(description); } diff --git a/source/net/protocol.h b/source/net/protocol.h index f6c382c..f722a76 100644 --- a/source/net/protocol.h +++ b/source/net/protocol.h @@ -40,6 +40,7 @@ private: { virtual ~CompoundTypeDef() { } + virtual std::string describe() const = 0; virtual char *serialize(const C &, char *, char *) const = 0; virtual const char *deserialize(C &, const char *, const char *) const = 0; }; @@ -52,6 +53,7 @@ private: CompoundDef(const S &); virtual ~CompoundDef(); + virtual std::string describe() const; virtual char *serialize(const C &, char *, char *) const; virtual const char *deserialize(C &, const char *, const char *) const; }; @@ -64,6 +66,7 @@ private: BasicSerializer(const Protocol &) { } + std::string describe() const { return get_type_signature(); } char *serialize(const T &, char *, char *) const; const char *deserialize(T &, const char *, const char *) const; }; @@ -79,6 +82,7 @@ private: public: StringSerializer(const Protocol &); + std::string describe() const { return get_type_signature(); } char *serialize(const std::string &, char *, char *) const; const char *deserialize(std::string &, const char *, const char *) const; }; @@ -96,6 +100,7 @@ private: public: ArraySerializer(const Protocol &); + std::string describe() const; char *serialize(const A &, char *, char *) const; const char *deserialize(A &, const char *, const char *) const; }; @@ -119,6 +124,7 @@ private: public: Serializer(const Head &, Pointer, const Protocol &); + std::string describe() const; char *serialize(const P &, char *, char *) const; const char *deserialize(P &, const char *, const char *) const; }; @@ -133,6 +139,7 @@ private: typedef Serializer::Serializer> Type; }; + std::string describe() const { return std::string(); } char *serialize(const P &, char *b, char *) const { return b; } const char *deserialize(P &, const char *b, const char *) const { return b; } }; @@ -149,6 +156,7 @@ private: virtual ~PacketDefBase() { } virtual unsigned get_class_id() const = 0; unsigned get_id() const { return id; } + virtual std::string describe() const = 0; virtual const char *dispatch(ReceiverBase &, const char *, const char *) const = 0; }; @@ -172,6 +180,7 @@ private: const CompoundTypeDef

&get_compound() const { return *compound; } + virtual std::string describe() const; char *serialize(const P &, char *, char *) const; const char *deserialize(P &, const char *, const char *) const; virtual const char *dispatch(ReceiverBase &, const char *, const char *) const; @@ -233,7 +242,11 @@ public: unsigned get_packet_size(const char *, unsigned) const; unsigned dispatch(ReceiverBase &, const char *, unsigned) const; - unsigned get_hash() const; + UInt64 get_hash() const; + +private: + template + static std::string get_type_signature(); }; @@ -262,32 +275,46 @@ unsigned Protocol::serialize(const P &pkt, char *buf, unsigned size) const return size; } +template +std::string Protocol::get_type_signature() +{ + const UInt16 sig = Traits::signature; + std::string result; + result += sig&0xFF; + if(sig>=0x100) + result += '0'+(sig>>8); + return result; +} + template struct Protocol::BasicTraits { + static const UInt16 signature = K | (sizeof(T)<<8); typedef BasicSerializer Serializer; }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; -template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; +template<> struct Protocol::Traits: BasicTraits { }; template<> struct Protocol::Traits { + static const UInt16 signature = 'S'; typedef StringSerializer Serializer; }; template struct Protocol::Traits > { + static const UInt16 signature = 'A'; typedef ArraySerializer > Serializer; }; @@ -304,6 +331,12 @@ Protocol::CompoundDef::~CompoundDef() delete serializer; } +template +std::string Protocol::CompoundDef::describe() const +{ + return "{"+serializer->describe()+"}"; +} + template char *Protocol::CompoundDef::serialize(const C &com, char *buf, char *end) const { @@ -323,6 +356,12 @@ Protocol::ArraySerializer::ArraySerializer(const Protocol &proto): element_serializer(proto) { } +template +std::string Protocol::ArraySerializer::describe() const +{ + return "["+element_serializer.describe()+"]"; +} + template char *Protocol::ArraySerializer::serialize(const A &array, char *buf, char *end) const { @@ -351,6 +390,12 @@ Protocol::Serializer::Serializer(const Head &h, Pointer p, const Pro ser(proto) { } +template +std::string Protocol::Serializer::describe() const +{ + return Head::describe()+ser.describe(); +} + template char * Protocol::Serializer::serialize(const P &pkt, char *buf, char *end) const { @@ -392,6 +437,12 @@ void Protocol::PacketTypeDef

::set_serializer(const S &ser) compound = new CompoundDef(ser); } +template +std::string Protocol::PacketTypeDef

::describe() const +{ + return compound->describe(); +} + template char *Protocol::PacketTypeDef

::serialize(const P &pkt, char *buf, char *end) const { -- 2.43.0