summaryrefslogtreecommitdiff
path: root/include/erebos
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2021-01-24 22:46:48 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2021-01-29 22:28:01 +0100
commita16b33031c7bcf2eabf1e0c3571000234b7740df (patch)
treef012ff7814abe7fa22c5a610388faf4310d53772 /include/erebos
parent3a3cce8eed7e43faa8c9f606e56bb43ba3bd9451 (diff)
Attach service
Diffstat (limited to 'include/erebos')
-rw-r--r--include/erebos/attach.h49
-rw-r--r--include/erebos/identity.h1
-rw-r--r--include/erebos/network.h20
-rw-r--r--include/erebos/pairing.h104
-rw-r--r--include/erebos/storage.h9
5 files changed, 182 insertions, 1 deletions
diff --git a/include/erebos/attach.h b/include/erebos/attach.h
new file mode 100644
index 0000000..14e6af3
--- /dev/null
+++ b/include/erebos/attach.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <erebos/pairing.h>
+
+#include <future>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace erebos {
+
+using std::mutex;
+using std::optional;
+using std::promise;
+using std::string;
+using std::vector;
+
+struct AttachIdentity;
+
+class AttachService : public PairingService<AttachIdentity>
+{
+public:
+ AttachService();
+ virtual ~AttachService();
+
+ UUID uuid() const override;
+
+ void attachTo(const Peer &);
+
+protected:
+ virtual Stored<AttachIdentity> handlePairingComplete(const Peer &) override;
+ virtual void handlePairingResult(Context &, Stored<AttachIdentity>) override;
+
+ mutex handlerLock;
+};
+
+template<class T> class Signed;
+
+struct AttachIdentity
+{
+ Stored<Signed<class IdentityData>> identity;
+ vector<vector<uint8_t>> keys;
+
+ static AttachIdentity load(const Ref &);
+ Ref store(const Storage &) const;
+};
+
+}
diff --git a/include/erebos/identity.h b/include/erebos/identity.h
index 66a4afb..aeddd08 100644
--- a/include/erebos/identity.h
+++ b/include/erebos/identity.h
@@ -20,6 +20,7 @@ public:
std::optional<Identity> owner() const;
const Identity & finalOwner() const;
+ Stored<class PublicKey> keyIdentity() const;
Stored<class PublicKey> keyMessage() const;
bool sameAs(const Identity &) const;
diff --git a/include/erebos/network.h b/include/erebos/network.h
index 8f3debe..5a1fca6 100644
--- a/include/erebos/network.h
+++ b/include/erebos/network.h
@@ -10,10 +10,15 @@ namespace erebos {
class Server
{
+ struct Priv;
public:
Server(const Head<LocalState> &, std::vector<std::unique_ptr<Service>> &&);
+ Server(const std::shared_ptr<Priv> &);
~Server();
+ const Head<LocalState> & localHead() const;
+
+ const Identity & identity() const;
template<class S> S & svc();
class PeerList & peerList() const;
@@ -22,7 +27,6 @@ public:
private:
Service & svcHelper(const std::type_info &);
- struct Priv;
const std::shared_ptr<Priv> p;
};
@@ -39,13 +43,27 @@ public:
Peer(const std::shared_ptr<Priv> & p);
~Peer();
+ Server server() const;
+
+ const Storage & tempStorage() const;
+ const PartialStorage & partialStorage() const;
+
std::string name() const;
std::optional<Identity> identity() const;
bool hasChannel() const;
bool send(UUID, const Ref &) const;
+ bool send(UUID, const Object &) const;
+
+ bool operator==(const Peer & other) const;
+ bool operator!=(const Peer & other) const;
+ bool operator<(const Peer & other) const;
+ bool operator<=(const Peer & other) const;
+ bool operator>(const Peer & other) const;
+ bool operator>=(const Peer & other) const;
private:
+ bool send(UUID, const Ref &, const Object &) const;
std::shared_ptr<Priv> p;
};
diff --git a/include/erebos/pairing.h b/include/erebos/pairing.h
new file mode 100644
index 0000000..f0952d8
--- /dev/null
+++ b/include/erebos/pairing.h
@@ -0,0 +1,104 @@
+#pragma once
+
+#include <erebos/identity.h>
+#include <erebos/network.h>
+#include <erebos/service.h>
+
+#include <future>
+#include <map>
+#include <mutex>
+#include <string>
+#include <variant>
+#include <vector>
+
+namespace erebos {
+
+using std::function;
+using std::future;
+using std::map;
+using std::mutex;
+using std::string;
+using std::variant;
+using std::vector;
+
+/**
+ * Template-less base class for the paring functionality that does not depend
+ * on the result parameter.
+ */
+class PairingServiceBase : public Service
+{
+public:
+ typedef function<void(const Peer &)> RequestInitHook;
+ void onRequestInit(RequestInitHook);
+
+ typedef function<future<bool>(const Peer &, string)> ConfirmHook;
+ void onResponse(ConfirmHook);
+ void onRequest(ConfirmHook);
+
+ typedef function<void(const Peer &)> RequestNonceFailedHook;
+ void onRequestNonceFailed(RequestNonceFailedHook);
+
+protected:
+ void requestPairing(UUID serviceId, const Peer & peer);
+ virtual void handle(Context &) override;
+ virtual Ref handlePairingCompleteRef(const Peer &) = 0;
+ virtual void handlePairingResult(Context &) = 0;
+
+private:
+ static vector<uint8_t> nonceDigest(const Identity & id1, const Identity & id2,
+ const vector<uint8_t> & nonce1, const vector<uint8_t> & nonce2);
+ static string confirmationNumber(const vector<uint8_t> &);
+ void waitForConfirmation(Peer peer, string confirm);
+
+ RequestInitHook requestInitHook;
+ ConfirmHook responseHook;
+ ConfirmHook requestHook;
+ RequestNonceFailedHook requestNonceFailedHook;
+
+ optional<Ref> result;
+
+ enum class StatePhase {
+ NoPairing,
+ OurRequest,
+ OurRequestConfirm,
+ OurRequestReady,
+ PeerRequest,
+ PeerRequestConfirm,
+ PairingDone,
+ PairingFailed
+ };
+
+ struct State {
+ StatePhase phase;
+ vector<uint8_t> nonce;
+ vector<uint8_t> peerCheck;
+ };
+
+ map<Peer, State> peerStates;
+ mutex stateLock;
+};
+
+template<class Result>
+class PairingService : public PairingServiceBase
+{
+protected:
+ virtual Stored<Result> handlePairingComplete(const Peer &) = 0;
+ virtual void handlePairingResult(Context &, Stored<Result>) = 0;
+
+ virtual Ref handlePairingCompleteRef(const Peer &) override final;
+ virtual void handlePairingResult(Context &) override final;
+};
+
+template<class Result>
+Ref PairingService<Result>::handlePairingCompleteRef(const Peer & peer)
+{
+ return handlePairingComplete(peer).ref();
+}
+
+template<class Result>
+void PairingService<Result>::handlePairingResult(Context & ctx)
+{
+ handlePairingResult(ctx, Stored<Result>::load(ctx.ref()));
+}
+
+}
diff --git a/include/erebos/storage.h b/include/erebos/storage.h
index 29eaa8f..4f67a4b 100644
--- a/include/erebos/storage.h
+++ b/include/erebos/storage.h
@@ -123,6 +123,9 @@ public:
explicit operator std::string() const;
bool isZero() const;
+ static Digest of(const std::vector<uint8_t> & content);
+ template<class S> static Digest of(const ObjectT<S> &);
+
const std::array<uint8_t, size> & arr() const { return value; }
bool operator==(const Digest & other) const { return value == other.value; }
@@ -136,6 +139,12 @@ private:
std::array<uint8_t, size> value;
};
+template<class S>
+Digest Digest::of(const ObjectT<S> & obj)
+{
+ return Digest::of(obj.encode());
+}
+
class PartialRef
{
public: