diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2021-01-24 22:46:48 +0100 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2021-01-29 22:28:01 +0100 | 
| commit | a16b33031c7bcf2eabf1e0c3571000234b7740df (patch) | |
| tree | f012ff7814abe7fa22c5a610388faf4310d53772 /include | |
| parent | 3a3cce8eed7e43faa8c9f606e56bb43ba3bd9451 (diff) | |
Attach service
Diffstat (limited to 'include')
| -rw-r--r-- | include/erebos/attach.h | 49 | ||||
| -rw-r--r-- | include/erebos/identity.h | 1 | ||||
| -rw-r--r-- | include/erebos/network.h | 20 | ||||
| -rw-r--r-- | include/erebos/pairing.h | 104 | ||||
| -rw-r--r-- | include/erebos/storage.h | 9 | 
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: |