diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-16 20:53:58 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-16 21:49:39 +0200 |
commit | b09e73f0abcc386719a2235cc3ae61fb1cbfc5ca (patch) | |
tree | 462085ac8fb592f4a2c07446058a7e761b51dfac /src/network | |
parent | 2ed8103ff1c0fca7372b3c3888f590ba41c525e6 (diff) |
Move network header definitions to protocol module
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/protocol.cpp | 150 | ||||
-rw-r--r-- | src/network/protocol.h | 36 |
2 files changed, 186 insertions, 0 deletions
diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index c247bf0..c2c6c5d 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -7,7 +7,10 @@ #include <mutex> #include <system_error> +using std::holds_alternative; using std::move; +using std::nullopt; +using std::runtime_error; using std::scoped_lock; namespace erebos { @@ -122,6 +125,10 @@ void NetworkProtocol::shutdown() } +/******************************************************************************/ +/* Connection */ +/******************************************************************************/ + NetworkProtocol::Connection::Id NetworkProtocol::ConnectionPriv::id() const { return reinterpret_cast<uintptr_t>(this); @@ -195,4 +202,147 @@ void NetworkProtocol::Connection::close() p = nullptr; } + +/******************************************************************************/ +/* Header */ +/******************************************************************************/ + +bool NetworkProtocol::Header::Item::operator==(const Item & other) const +{ + if (type != other.type) + return false; + + if (value.index() != other.value.index()) + return false; + + if (holds_alternative<PartialRef>(value)) + return std::get<PartialRef>(value).digest() == + std::get<PartialRef>(other.value).digest(); + + if (holds_alternative<UUID>(value)) + return std::get<UUID>(value) == std::get<UUID>(other.value); + + throw runtime_error("unhandled network header item type"); +} + +optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialRef & ref) +{ + return load(*ref); +} + +optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialObject & obj) +{ + auto rec = obj.asRecord(); + if (!rec) + return nullopt; + + vector<Item> items; + for (const auto & item : rec->items()) { + if (item.name == "ACK") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::Acknowledged, + .value = *ref, + }); + } else if (item.name == "REQ") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::DataRequest, + .value = *ref, + }); + } else if (item.name == "RSP") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::DataResponse, + .value = *ref, + }); + } else if (item.name == "ANN") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::AnnounceSelf, + .value = *ref, + }); + } else if (item.name == "ANU") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::AnnounceUpdate, + .value = *ref, + }); + } else if (item.name == "CRQ") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ChannelRequest, + .value = *ref, + }); + } else if (item.name == "CAC") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ChannelAccept, + .value = *ref, + }); + } else if (item.name == "STP") { + if (auto val = item.asUUID()) + items.emplace_back(Item { + .type = Type::ServiceType, + .value = *val, + }); + } else if (item.name == "SRF") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ServiceRef, + .value = *ref, + }); + } + } + + return NetworkProtocol::Header(items); +} + +PartialObject NetworkProtocol::Header::toObject() const +{ + vector<PartialRecord::Item> ritems; + + for (const auto & item : items) { + switch (item.type) { + case Type::Acknowledged: + ritems.emplace_back("ACK", std::get<PartialRef>(item.value)); + break; + + case Type::DataRequest: + ritems.emplace_back("REQ", std::get<PartialRef>(item.value)); + break; + + case Type::DataResponse: + ritems.emplace_back("RSP", std::get<PartialRef>(item.value)); + break; + + case Type::AnnounceSelf: + ritems.emplace_back("ANN", std::get<PartialRef>(item.value)); + break; + + case Type::AnnounceUpdate: + ritems.emplace_back("ANU", std::get<PartialRef>(item.value)); + break; + + case Type::ChannelRequest: + ritems.emplace_back("CRQ", std::get<PartialRef>(item.value)); + break; + + case Type::ChannelAccept: + ritems.emplace_back("CAC", std::get<PartialRef>(item.value)); + break; + + case Type::ServiceType: + ritems.emplace_back("STP", std::get<UUID>(item.value)); + break; + + case Type::ServiceRef: + ritems.emplace_back("SRF", std::get<PartialRef>(item.value)); + break; + } + } + + return PartialObject(PartialRecord(std::move(ritems))); +} + } diff --git a/src/network/protocol.h b/src/network/protocol.h index a9bbaff..8aa22a2 100644 --- a/src/network/protocol.h +++ b/src/network/protocol.h @@ -1,5 +1,7 @@ #pragma once +#include <erebos/storage.h> + #include <netinet/in.h> #include <cstdint> @@ -7,10 +9,12 @@ #include <mutex> #include <variant> #include <vector> +#include <optional> namespace erebos { using std::mutex; +using std::optional; using std::unique_ptr; using std::variant; using std::vector; @@ -28,6 +32,8 @@ public: class Connection; + struct Header; + struct NewConnection; struct ConnectionReadReady; struct ProtocolClosed {}; @@ -85,4 +91,34 @@ private: struct NetworkProtocol::NewConnection { Connection conn; }; struct NetworkProtocol::ConnectionReadReady { Connection::Id id; }; +struct NetworkProtocol::Header +{ + enum class Type { + Acknowledged, + DataRequest, + DataResponse, + AnnounceSelf, + AnnounceUpdate, + ChannelRequest, + ChannelAccept, + ServiceType, + ServiceRef, + }; + + struct Item { + const Type type; + const variant<PartialRef, UUID> value; + + bool operator==(const Item &) const; + bool operator!=(const Item & other) const { return !(*this == other); } + }; + + Header(const vector<Item> & items): items(items) {} + static optional<Header> load(const PartialRef &); + static optional<Header> load(const PartialObject &); + PartialObject toObject() const; + + const vector<Item> items; +}; + } |