diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/crimson/net/Connection.h | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/crimson/net/Connection.h')
-rw-r--r-- | src/crimson/net/Connection.h | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/crimson/net/Connection.h b/src/crimson/net/Connection.h new file mode 100644 index 000000000..6af12692e --- /dev/null +++ b/src/crimson/net/Connection.h @@ -0,0 +1,175 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 Red Hat, Inc + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#pragma once + +#include <queue> +#include <seastar/core/future.hh> +#include <seastar/core/shared_ptr.hh> + +#include "Fwd.h" + +namespace crimson::net { + +#ifdef UNIT_TESTS_BUILT +class Interceptor; +#endif + +using seq_num_t = uint64_t; + +class Connection : public seastar::enable_shared_from_this<Connection> { + entity_name_t peer_name = {0, entity_name_t::NEW}; + + protected: + entity_addr_t peer_addr; + + // which of the peer_addrs we're connecting to (as client) + // or should reconnect to (as peer) + entity_addr_t target_addr; + + using clock_t = seastar::lowres_system_clock; + clock_t::time_point last_keepalive; + clock_t::time_point last_keepalive_ack; + + void set_peer_type(entity_type_t peer_type) { + // it is not allowed to assign an unknown value when the current + // value is known + assert(!(peer_type == 0 && + peer_name.type() != 0)); + // it is not allowed to assign a different known value when the + // current value is also known. + assert(!(peer_type != 0 && + peer_name.type() != 0 && + peer_type != peer_name.type())); + peer_name._type = peer_type; + } + void set_peer_id(int64_t peer_id) { + // it is not allowed to assign an unknown value when the current + // value is known + assert(!(peer_id == entity_name_t::NEW && + peer_name.num() != entity_name_t::NEW)); + // it is not allowed to assign a different known value when the + // current value is also known. + assert(!(peer_id != entity_name_t::NEW && + peer_name.num() != entity_name_t::NEW && + peer_id != peer_name.num())); + peer_name._num = peer_id; + } + void set_peer_name(entity_name_t name) { + set_peer_type(name.type()); + set_peer_id(name.num()); + } + + public: + uint64_t peer_global_id = 0; + + protected: + uint64_t features = 0; + + public: + void set_features(uint64_t new_features) { + features = new_features; + } + auto get_features() const { + return features; + } + bool has_feature(uint64_t f) const { + return features & f; + } + + public: + Connection() {} + virtual ~Connection() {} + +#ifdef UNIT_TESTS_BUILT + Interceptor *interceptor = nullptr; +#endif + + virtual Messenger* get_messenger() const = 0; + const entity_addr_t& get_peer_addr() const { return peer_addr; } + const entity_addrvec_t get_peer_addrs() const { + return entity_addrvec_t(peer_addr); + } + const auto& get_peer_socket_addr() const { + return target_addr; + } + const entity_name_t& get_peer_name() const { return peer_name; } + entity_type_t get_peer_type() const { return peer_name.type(); } + int64_t get_peer_id() const { return peer_name.num(); } + + bool peer_is_mon() const { return peer_name.is_mon(); } + bool peer_is_mgr() const { return peer_name.is_mgr(); } + bool peer_is_mds() const { return peer_name.is_mds(); } + bool peer_is_osd() const { return peer_name.is_osd(); } + bool peer_is_client() const { return peer_name.is_client(); } + + /// true if the handshake has completed and no errors have been encountered + virtual bool is_connected() const = 0; + +#ifdef UNIT_TESTS_BUILT + virtual bool is_closed() const = 0; + + virtual bool is_closed_clean() const = 0; + + virtual bool peer_wins() const = 0; +#endif + + /// send a message over a connection that has completed its handshake + virtual seastar::future<> send(MessageRef msg) = 0; + + /// send a keepalive message over a connection that has completed its + /// handshake + virtual seastar::future<> keepalive() = 0; + + // close the connection and cancel any any pending futures from read/send, + // without dispatching any reset event + virtual void mark_down() = 0; + + virtual void print(ostream& out) const = 0; + + void set_last_keepalive(clock_t::time_point when) { + last_keepalive = when; + } + void set_last_keepalive_ack(clock_t::time_point when) { + last_keepalive_ack = when; + } + auto get_last_keepalive() const { return last_keepalive; } + auto get_last_keepalive_ack() const { return last_keepalive_ack; } + + struct user_private_t { + virtual ~user_private_t() = default; + }; +private: + unique_ptr<user_private_t> user_private; +public: + bool has_user_private() const { + return user_private != nullptr; + } + void set_user_private(unique_ptr<user_private_t> new_user_private) { + user_private = std::move(new_user_private); + } + user_private_t &get_user_private() { + ceph_assert(user_private); + return *user_private; + } +}; + +inline ostream& operator<<(ostream& out, const Connection& conn) { + out << "["; + conn.print(out); + out << "]"; + return out; +} + +} // namespace crimson::net |