140 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <nano/node/endpoint.hpp>
 | |
| #include <nano/node/messages.hpp>
 | |
| #include <nano/node/transport/fwd.hpp>
 | |
| #include <nano/node/transport/tcp_socket.hpp>
 | |
| 
 | |
| #include <atomic>
 | |
| 
 | |
| namespace nano
 | |
| {
 | |
| class message;
 | |
| }
 | |
| 
 | |
| namespace nano::transport
 | |
| {
 | |
| class message_deserializer;
 | |
| class tcp_server;
 | |
| 
 | |
| class tcp_server final : public std::enable_shared_from_this<tcp_server>
 | |
| {
 | |
| public:
 | |
| 	tcp_server (std::shared_ptr<nano::transport::tcp_socket>, std::shared_ptr<nano::node>, bool allow_bootstrap = true);
 | |
| 	~tcp_server ();
 | |
| 
 | |
| 	void start ();
 | |
| 	void stop ();
 | |
| 
 | |
| 	void initiate_handshake ();
 | |
| 	void timeout ();
 | |
| 	void set_last_keepalive (nano::keepalive const & message);
 | |
| 	std::optional<nano::keepalive> pop_last_keepalive ();
 | |
| 
 | |
| 	std::shared_ptr<nano::transport::tcp_socket> const socket;
 | |
| 	std::weak_ptr<nano::node> const node;
 | |
| 	nano::mutex mutex;
 | |
| 	std::atomic<bool> stopped{ false };
 | |
| 	std::atomic<bool> handshake_received{ false };
 | |
| 	// Remote endpoint used to remove response channel even after socket closing
 | |
| 	nano::tcp_endpoint remote_endpoint{ boost::asio::ip::address_v6::any (), 0 };
 | |
| 	std::chrono::steady_clock::time_point last_telemetry_req{};
 | |
| 
 | |
| private:
 | |
| 	enum class process_result
 | |
| 	{
 | |
| 		abort,
 | |
| 		progress,
 | |
| 		pause,
 | |
| 	};
 | |
| 
 | |
| 	void receive_message ();
 | |
| 	void received_message (std::unique_ptr<nano::message> message);
 | |
| 	process_result process_message (std::unique_ptr<nano::message> message);
 | |
| 	void queue_realtime (std::unique_ptr<nano::message> message);
 | |
| 
 | |
| 	bool to_bootstrap_connection ();
 | |
| 	bool to_realtime_connection (nano::account const & node_id);
 | |
| 	bool is_undefined_connection () const;
 | |
| 	bool is_bootstrap_connection () const;
 | |
| 	bool is_realtime_connection () const;
 | |
| 
 | |
| 	enum class handshake_status
 | |
| 	{
 | |
| 		abort,
 | |
| 		handshake,
 | |
| 		realtime,
 | |
| 		bootstrap,
 | |
| 	};
 | |
| 
 | |
| 	handshake_status process_handshake (nano::node_id_handshake const & message);
 | |
| 	void send_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2);
 | |
| 
 | |
| private:
 | |
| 	bool const allow_bootstrap;
 | |
| 	std::shared_ptr<nano::transport::message_deserializer> message_deserializer;
 | |
| 	std::optional<nano::keepalive> last_keepalive;
 | |
| 
 | |
| 	// Every realtime connection must have an associated channel
 | |
| 	std::shared_ptr<nano::transport::tcp_channel> channel;
 | |
| 
 | |
| private: // Visitors
 | |
| 	class handshake_message_visitor : public nano::message_visitor
 | |
| 	{
 | |
| 	public:
 | |
| 		handshake_status result{ handshake_status::abort };
 | |
| 
 | |
| 		explicit handshake_message_visitor (tcp_server & server) :
 | |
| 			server{ server } {};
 | |
| 
 | |
| 		void node_id_handshake (nano::node_id_handshake const &) override;
 | |
| 		void bulk_pull (nano::bulk_pull const &) override;
 | |
| 		void bulk_pull_account (nano::bulk_pull_account const &) override;
 | |
| 		void bulk_push (nano::bulk_push const &) override;
 | |
| 		void frontier_req (nano::frontier_req const &) override;
 | |
| 
 | |
| 	private:
 | |
| 		tcp_server & server;
 | |
| 	};
 | |
| 
 | |
| 	class realtime_message_visitor : public nano::message_visitor
 | |
| 	{
 | |
| 	public:
 | |
| 		bool process{ false };
 | |
| 
 | |
| 		explicit realtime_message_visitor (tcp_server & server) :
 | |
| 			server{ server } {};
 | |
| 
 | |
| 		void keepalive (nano::keepalive const &) override;
 | |
| 		void publish (nano::publish const &) override;
 | |
| 		void confirm_req (nano::confirm_req const &) override;
 | |
| 		void confirm_ack (nano::confirm_ack const &) override;
 | |
| 		void frontier_req (nano::frontier_req const &) override;
 | |
| 		void telemetry_req (nano::telemetry_req const &) override;
 | |
| 		void telemetry_ack (nano::telemetry_ack const &) override;
 | |
| 		void asc_pull_req (nano::asc_pull_req const &) override;
 | |
| 		void asc_pull_ack (nano::asc_pull_ack const &) override;
 | |
| 
 | |
| 	private:
 | |
| 		tcp_server & server;
 | |
| 	};
 | |
| 
 | |
| 	class bootstrap_message_visitor : public nano::message_visitor
 | |
| 	{
 | |
| 	public:
 | |
| 		bool processed{ false };
 | |
| 
 | |
| 		explicit bootstrap_message_visitor (std::shared_ptr<tcp_server>);
 | |
| 
 | |
| 		void bulk_pull (nano::bulk_pull const &) override;
 | |
| 		void bulk_pull_account (nano::bulk_pull_account const &) override;
 | |
| 		void bulk_push (nano::bulk_push const &) override;
 | |
| 		void frontier_req (nano::frontier_req const &) override;
 | |
| 
 | |
| 	private:
 | |
| 		std::shared_ptr<tcp_server> server;
 | |
| 	};
 | |
| 
 | |
| 	friend class handshake_message_visitor;
 | |
| };
 | |
| }
 | 
