@@ -34,29 +34,35 @@ class full_node;
3434// / Declare a concrete instance of this type for client-server protocols built
3535// / on tcp/ip. session_base processing performs all connection management and
3636// / session tracking. This includes start/stop/disable/enable/black/whitelist.
37- // / Protocol must declare options_t and channel_t. This protocol is constructed
38- // / and attached to a constructed instance of channel_t. The protocol construct
39- // / and attachment can be overridden and/or augmented with other protocols.
40- template <typename Protocol>
37+ // / First protocol must declare options_t and channel_t. Each of the protocols
38+ // / are constructed and attached to a constructed instance of channel_t. The
39+ // / protocol construct and attachment can be overridden and/or augmented with
40+ // / other protocols.
41+ template <typename ...Protocols>
4142class session_server
4243 : public node::session,
4344 public network::session_server,
44- protected network::tracker<session_server<Protocol >>
45+ protected network::tracker<session_server<Protocols... >>
4546{
4647public:
47- typedef std::shared_ptr<session_server<Protocol >> ptr;
48+ typedef std::shared_ptr<session_server<Protocols... >> ptr;
4849
49- // / The protocol must define these public types.
50- using options_t = typename Protocol::options_t ;
51- using channel_t = typename Protocol::channel_t ;
50+ // / Extract the first protocol type from the pack.
51+ template <typename Protocol, typename ...>
52+ struct first_protocol { using type = Protocol; };
53+
54+ // / The first protocol must define these public types.
55+ using first = typename first_protocol<Protocols...>::type;
56+ using options_t = typename first::options_t ;
57+ using channel_t = typename first::channel_t ;
5258
5359 // / Construct an instance (network should be started).
5460 inline session_server (full_node& node, uint64_t identifier,
5561 const options_t & options) NOEXCEPT
5662 : node::session(node),
5763 network::session_server((network::net&)node, identifier, options),
5864 options_(options),
59- network::tracker<session_server<Protocol >>(node)
65+ network::tracker<session_server<Protocols... >>(node)
6066 {
6167 }
6268
@@ -68,7 +74,7 @@ class session_server
6874 // / Used instead of suspension because that has independent start/stop.
6975 inline bool enabled () const NOEXCEPT override
7076 {
71- return !config ().node .delay_inbound || is_recent ();
77+ return !this -> config ().node .delay_inbound || this -> is_recent ();
7278 }
7379
7480 // / Override to construct channel. This allows the implementation to pass
@@ -80,7 +86,7 @@ class session_server
8086 BC_ASSERT (stranded ());
8187
8288 const auto channel = std::make_shared<channel_t >(log, socket,
83- create_key (), config (), options_);
89+ this -> create_key (), this -> config (), options_);
8490
8591 return std::static_pointer_cast<network::channel>(channel);
8692 }
@@ -99,6 +105,16 @@ class session_server
99105 network::session_server::attach_handshake (channel, std::move (handler));
100106 }
101107
108+ template <typename ...Rest, bool_if<is_zero(sizeof ...(Rest))> = true >
109+ inline void attach_rest (const channel_ptr&, const ptr&) NOEXCEPT{}
110+
111+ template <typename Next, typename ...Rest>
112+ inline void attach_rest (const channel_ptr& channel, const ptr& self) NOEXCEPT
113+ {
114+ channel->attach <Next>(self, options_)->start ();
115+ attach_rest<Rest...>(channel, self);
116+ }
117+
102118 // / Overridden to set channel protocols. This allows the implementation to
103119 // / pass other values to protocol construction and/or select the desired
104120 // / protocol based on available factors (e.g. a distinct protocol version).
@@ -108,8 +124,8 @@ class session_server
108124 BC_ASSERT (channel->stranded ());
109125 BC_ASSERT (channel->paused ());
110126
111- const auto self = shared_from_base<session_server<Protocol >>();
112- channel-> attach <Protocol>(self, options_)-> start ( );
127+ const auto self = shared_from_base<session_server<Protocols... >>();
128+ attach_rest<Protocols...>(channel, self );
113129 }
114130
115131private:
0 commit comments