+void Communicator::prepare_protocol(const ActiveProtocol &proto)
+{
+ PrepareProtocol prepare;
+ prepare.hash = proto.hash;
+ prepare.base = proto.base;
+ /* Use send_data() directly because this function is called to prepare the
+ handshake protocol too and send() would fail readiness check. */
+ send_data(handshake->protocol.serialize(prepare, out_buf, buf_size));
+}
+
+void Communicator::accept_protocol(ActiveProtocol &proto)
+{
+ proto.accepted = true;
+
+ AcceptProtocol accept;
+ accept.hash = proto.hash;
+ send_data(handshake->protocol.serialize(accept, out_buf, buf_size));
+}
+
+
+Communicator::ActiveProtocol::ActiveProtocol(uint16_t b, const Protocol &p, ReceiverBase &r):
+ hash(p.get_hash()),
+ base(b),
+ last(base+p.get_max_packet_id()),
+ protocol(&p),
+ receiver(&r)
+{ }
+
+Communicator::ActiveProtocol::ActiveProtocol(uint16_t b, uint64_t h):
+ hash(h),
+ base(b),
+ last(base)
+{ }
+
+
+void Communicator::Handshake::receive(const PrepareProtocol &prepare)
+{
+ auto i = lower_bound_member(communicator.protocols, prepare.base, &ActiveProtocol::base);
+ if(i!=communicator.protocols.end() && i->base==prepare.base)
+ communicator.accept_protocol(*i);
+ else
+ communicator.protocols.emplace(i, prepare.base, prepare.hash);
+}
+
+void Communicator::Handshake::receive(const AcceptProtocol &accept)