Skip to content

Commit 1c202e0

Browse files
committed
Make session_server capable of attaching multiple protocols per channel.
1 parent 36057b7 commit 1c202e0

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

include/bitcoin/node/sessions/session_server.hpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
4142
class 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
{
4647
public:
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

115131
private:

0 commit comments

Comments
 (0)